silicon.py 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ Metadata-Version: 2.4
2
+ Name: silicon.py
3
+ Version: 0.2.2
4
+ Summary: Silicon: A new language made with Python.
5
+ Author: qwertydev
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
File without changes
File without changes
@@ -0,0 +1,337 @@
1
+ import sys
2
+ import re
3
+
4
+ # --- TOKEN TYPES ---
5
+ TT_INT = 'INT'
6
+ TT_STRING = 'STRING'
7
+ TT_IDENTIFIER = 'IDENTIFIER'
8
+ TT_COLON = 'COLON'
9
+ TT_LPAREN = 'LPAREN'
10
+ TT_RPAREN = 'RPAREN'
11
+ TT_DOT = 'DOT'
12
+ TT_EQUALS = 'EQUALS'
13
+ TT_COMMA = 'COMMA'
14
+ TT_LBRACKET = 'LBRACKET'
15
+ TT_RBRACKET = 'RBRACKET'
16
+ TT_PLUS = 'PLUS'
17
+ TT_MINUS = 'MINUS'
18
+ TT_BOOL = 'BOOL'
19
+ TT_SEMICOLON = 'SEMICOLON' # For alt; also; not;
20
+ # Comparison
21
+ TT_EE = 'EE'
22
+ TT_LTE = 'LTE'
23
+ TT_GTE = 'GTE'
24
+ TT_LT = 'LT'
25
+ TT_GT = 'GT'
26
+
27
+ class Token:
28
+ def __init__(self, type_, value=None):
29
+ self.type = type_
30
+ self.value = value
31
+ def __repr__(self):
32
+ return f'{self.type}:{self.value}' if self.value is not None else f'{self.type}'
33
+
34
+ # --- LEXER ---
35
+ class Lexer:
36
+ def __init__(self, text):
37
+ text = re.sub(r'~~.*?~~', '', text)
38
+ text = re.sub(r'~~.*', '', text)
39
+ self.text = text
40
+ self.pos = -1
41
+ self.current_char = None
42
+ self.advance()
43
+
44
+ def advance(self):
45
+ self.pos += 1
46
+ self.current_char = self.text[self.pos] if self.pos < len(self.text) else None
47
+
48
+ def peek(self):
49
+ peek_pos = self.pos + 1
50
+ return self.text[peek_pos] if peek_pos < len(self.text) else None
51
+
52
+ def make_tokens(self):
53
+ tokens = []
54
+ while self.current_char is not None:
55
+ if self.current_char in ' \t\n\r': self.advance()
56
+ elif self.current_char.isdigit(): tokens.append(self.make_number())
57
+ elif self.current_char.isalpha(): tokens.append(self.make_identifier())
58
+ elif self.current_char in ('"', "'"): tokens.append(self.make_string())
59
+ elif self.current_char == '+': tokens.append(Token(TT_PLUS)); self.advance()
60
+ elif self.current_char == '-': tokens.append(Token(TT_MINUS)); self.advance()
61
+ elif self.current_char == ';': tokens.append(Token(TT_SEMICOLON)); self.advance()
62
+ elif self.current_char == '=':
63
+ if self.peek() == '=':
64
+ self.advance(); tokens.append(Token(TT_EE)); self.advance()
65
+ elif self.peek() == '>': # Support => for GTE
66
+ self.advance(); tokens.append(Token(TT_GTE)); self.advance()
67
+ else: tokens.append(Token(TT_EQUALS)); self.advance()
68
+ elif self.current_char == '<':
69
+ if self.peek() == '=':
70
+ self.advance(); tokens.append(Token(TT_LTE)); self.advance()
71
+ else: tokens.append(Token(TT_LT)); self.advance()
72
+ elif self.current_char == '>':
73
+ if self.peek() == '=':
74
+ self.advance(); tokens.append(Token(TT_GTE)); self.advance()
75
+ else: tokens.append(Token(TT_GT)); self.advance()
76
+ elif self.current_char == ':': tokens.append(Token(TT_COLON)); self.advance()
77
+ elif self.current_char == '(': tokens.append(Token(TT_LPAREN)); self.advance()
78
+ elif self.current_char == ')': tokens.append(Token(TT_RPAREN)); self.advance()
79
+ elif self.current_char == '[': tokens.append(Token(TT_LBRACKET)); self.advance()
80
+ elif self.current_char == ']': tokens.append(Token(TT_RBRACKET)); self.advance()
81
+ elif self.current_char == '.': tokens.append(Token(TT_DOT)); self.advance()
82
+ elif self.current_char == ',': tokens.append(Token(TT_COMMA)); self.advance()
83
+ else: self.advance()
84
+ return tokens, None
85
+
86
+ def make_number(self):
87
+ num_str = ''
88
+ while self.current_char is not None and self.current_char.isdigit():
89
+ num_str += self.current_char
90
+ self.advance()
91
+ return Token(TT_INT, int(num_str))
92
+
93
+ def make_string(self):
94
+ string = ''
95
+ quote_type = self.current_char
96
+ self.advance()
97
+ while self.current_char is not None and self.current_char != quote_type:
98
+ string += self.current_char
99
+ self.advance()
100
+ self.advance()
101
+ return Token(TT_STRING, string)
102
+
103
+ def make_identifier(self):
104
+ id_str = ''
105
+ while self.current_char is not None and (self.current_char.isalnum() or self.current_char == '_'):
106
+ id_str += self.current_char
107
+ self.advance()
108
+ if id_str == 'true': return Token(TT_BOOL, True)
109
+ if id_str == 'false': return Token(TT_BOOL, False)
110
+ return Token(TT_IDENTIFIER, id_str)
111
+
112
+ # --- NODES ---
113
+ class CondNode:
114
+ def __init__(self, mode, condition_tokens, body):
115
+ self.mode = mode # 'if' or 'during'
116
+ self.condition_tokens = condition_tokens
117
+ self.body = body
118
+
119
+ # (Other nodes like DefineNode, SetNode, etc. remain the same as previous)
120
+ class DefineNode:
121
+ def __init__(self, dtype, name, args=None, body=None):
122
+ self.dtype, self.name, self.args, self.body = dtype, name, args, body
123
+
124
+ class SetNode:
125
+ def __init__(self, library, name, expression):
126
+ self.library, self.name, self.expression = library, name, expression
127
+
128
+ class LogNode:
129
+ def __init__(self, lib, name, index=None, raw_val=None):
130
+ self.lib, self.name, self.index, self.raw_val = lib, name, index, raw_val
131
+
132
+ class FuncExecuteNode:
133
+ def __init__(self, name, args):
134
+ self.name, self.args = name, args
135
+
136
+ # --- PARSER ---
137
+ class Parser:
138
+ def __init__(self, tokens):
139
+ self.tokens, self.tok_idx = tokens, -1
140
+ self.advance()
141
+
142
+ def advance(self):
143
+ self.tok_idx += 1
144
+ self.current_tok = self.tokens[self.tok_idx] if self.tok_idx < len(self.tokens) else None
145
+
146
+ def get_block(self):
147
+ body = []
148
+ while self.current_tok:
149
+ if self.current_tok.type == TT_COLON:
150
+ if self.tok_idx + 1 < len(self.tokens) and self.tokens[self.tok_idx+1].value == 'end':
151
+ self.advance(); self.advance()
152
+ break
153
+ stmt = self.statement()
154
+ if stmt: body.append(stmt)
155
+ return body
156
+
157
+ def statement(self):
158
+ if not self.current_tok: return None
159
+
160
+ # --- NEW COND() SYNTAX ---
161
+ if self.current_tok.value == 'cond':
162
+ self.advance(); self.advance() # cond (
163
+ mode = self.current_tok.value # 'if' or 'during'
164
+ self.advance()
165
+ expr = []
166
+ while self.current_tok.type != TT_RPAREN:
167
+ expr.append(self.current_tok); self.advance()
168
+ self.advance(); self.advance() # ) :
169
+ return CondNode(mode, expr, self.get_block())
170
+
171
+ # (Rest of definitions like define, log, vars. stay identical to previous version)
172
+ if self.current_tok.value == 'define':
173
+ self.advance(); self.advance(); self.advance(); self.advance()
174
+ dtype = self.current_tok.value
175
+ self.advance(); self.advance()
176
+ name = self.current_tok.value
177
+ self.advance(); self.advance()
178
+ if dtype == 'Func':
179
+ self.advance(); self.advance()
180
+ args = []
181
+ while self.current_tok.type != TT_RBRACKET:
182
+ if self.current_tok.type == TT_IDENTIFIER and self.current_tok.value != 'None':
183
+ args.append(self.current_tok.value)
184
+ self.advance()
185
+ self.advance(); self.advance()
186
+ return DefineNode(dtype, name, args, self.get_block())
187
+ return DefineNode(dtype, name)
188
+
189
+ if self.current_tok.value in ('vars', 'arrs', 'funcs'):
190
+ lib = self.current_tok.value
191
+ self.advance(); self.advance()
192
+ name = self.current_tok.value
193
+ self.advance(); self.advance()
194
+ action = self.current_tok.value
195
+ self.advance(); self.advance()
196
+ expr = []
197
+ while self.current_tok and self.current_tok.type != TT_RPAREN:
198
+ expr.append(self.current_tok); self.advance()
199
+ if self.current_tok and self.current_tok.type == TT_COMMA: self.advance()
200
+ if self.current_tok: self.advance()
201
+ if action == 'Set': return SetNode(lib, name, expr)
202
+ if action == 'Execute': return FuncExecuteNode(name, expr)
203
+
204
+ if self.current_tok.value == 'log':
205
+ self.advance(); self.advance(); self.advance(); self.advance()
206
+ if self.current_tok.type == TT_IDENTIFIER and self.current_tok.value in ('vars', 'arrs'):
207
+ lib = self.current_tok.value
208
+ self.advance(); self.advance()
209
+ name = self.current_tok.value
210
+ self.advance()
211
+ idx = None
212
+ if self.current_tok and self.current_tok.type == TT_LBRACKET:
213
+ self.advance(); idx = self.current_tok.value; self.advance(); self.advance()
214
+ if self.current_tok: self.advance()
215
+ return LogNode(lib, name, index=idx)
216
+ else:
217
+ val = self.current_tok.value; self.advance(); self.advance()
218
+ return LogNode(None, None, raw_val=val)
219
+ return None
220
+
221
+ def parse(self):
222
+ ast = []
223
+ while self.current_tok is not None:
224
+ stmt = self.statement()
225
+ if stmt: ast.append(stmt)
226
+ else: self.advance()
227
+ return ast
228
+
229
+ # --- INTERPRETER ---
230
+ class Interpreter:
231
+ def __init__(self):
232
+ self.vars, self.arrs, self.funcs, self.temp_vars = {}, {}, {}, {}
233
+
234
+ def resolve_value(self, tokens):
235
+ if not isinstance(tokens, list):
236
+ if tokens.type in (TT_INT, TT_STRING, TT_BOOL): return tokens.value
237
+ if tokens.value == 'input':
238
+ val = input(">> "); return int(val) if val.isdigit() else val
239
+ if tokens.value in self.temp_vars: return self.temp_vars[tokens.value]
240
+ return tokens.value
241
+ if len(tokens) >= 3 and tokens[1].type == TT_DOT:
242
+ lib, var_name = tokens[0].value, tokens[2].value
243
+ if lib == 'vars': return self.temp_vars.get(var_name, self.vars.get(var_name, 0))
244
+ if lib == 'arrs': return self.arrs.get(var_name, [])
245
+ return self.resolve_value(tokens[0])
246
+
247
+ def evaluate_complex_logic(self, tokens):
248
+ # Handle "not;"
249
+ negate = False
250
+ if tokens[0].value == 'not' and tokens[1].type == TT_SEMICOLON:
251
+ negate = True
252
+ tokens = tokens[2:]
253
+
254
+ # Split by "alt;" or "also;"
255
+ # For v0.2.2 we'll do a simple check for these keywords
256
+ for i, tok in enumerate(tokens):
257
+ if tok.value == 'alt' and self.peek_token_type(i+1) == TT_SEMICOLON:
258
+ left = self.evaluate_expression(tokens[:i])
259
+ right = self.evaluate_complex_logic(tokens[i+2:])
260
+ res = left or right
261
+ return not res if negate else res
262
+ if tok.value == 'also' and self.peek_token_type(i+1) == TT_SEMICOLON:
263
+ left = self.evaluate_expression(tokens[:i])
264
+ right = self.evaluate_complex_logic(tokens[i+2:])
265
+ res = left and right
266
+ return not res if negate else res
267
+
268
+ res = self.evaluate_expression(tokens)
269
+ return not res if negate else res
270
+
271
+ def peek_token_type(self, idx):
272
+ # Helper for evaluate_complex_logic
273
+ return None # Simplified for this snippet
274
+
275
+ def evaluate_expression(self, expr_tokens):
276
+ for i, tok in enumerate(expr_tokens):
277
+ if tok.type in (TT_EE, TT_LTE, TT_GTE, TT_LT, TT_GT, TT_PLUS, TT_MINUS):
278
+ v1 = self.resolve_value(expr_tokens[:i])
279
+ v2 = self.resolve_value(expr_tokens[i+1:])
280
+ if tok.type == TT_EE: return v1 == v2
281
+ if tok.type == TT_LTE: return v1 <= v2
282
+ if tok.type == TT_GTE: return v1 >= v2
283
+ if tok.type == TT_LT: return v1 < v2
284
+ if tok.type == TT_GT: return v1 > v2
285
+ if tok.type == TT_PLUS: return v1 + v2
286
+ if tok.type == TT_MINUS: return v1 - v2
287
+ return self.resolve_value(expr_tokens)
288
+
289
+ def visit(self, node):
290
+ if isinstance(node, CondNode):
291
+ if node.mode == 'if':
292
+ if self.evaluate_complex_logic(node.condition_tokens):
293
+ for s in node.body: self.visit(s)
294
+ elif node.mode == 'during':
295
+ while self.evaluate_complex_logic(node.condition_tokens):
296
+ for s in node.body: self.visit(s)
297
+ elif isinstance(node, DefineNode):
298
+ if node.dtype == 'Var': self.vars[node.name] = None
299
+ elif node.dtype == 'Arr': self.arrs[node.name] = []
300
+ elif node.dtype == 'Func': self.funcs[node.name] = (node.args, node.body)
301
+ elif isinstance(node, SetNode):
302
+ val = self.evaluate_expression(node.expression)
303
+ if node.library == 'vars': self.vars[node.name] = val
304
+ else: self.arrs[node.name] = val
305
+ elif isinstance(node, LogNode):
306
+ if node.raw_val is not None: print(f"[NEXUS CONSOLE]: {node.raw_val}")
307
+ else: print(f"[NEXUS CONSOLE]: {self.vars.get(node.name, self.arrs.get(node.name))}")
308
+ elif isinstance(node, FuncExecuteNode):
309
+ args_n, body = self.funcs[node.name]
310
+ for s in body: self.visit(s)
311
+
312
+ def run_file(filename):
313
+ with open(filename, 'r') as f: script = f.read()
314
+ lexer = Lexer(script)
315
+ tokens, _ = lexer.make_tokens()
316
+ parser = Parser(tokens)
317
+ ast = parser.parse()
318
+ interpreter = Interpreter()
319
+ for node in ast: interpreter.visit(node)
320
+
321
+ if __name__ == "__main__":
322
+ if len(sys.argv) > 1: run_file(sys.argv[1])
323
+
324
+ def main_cli():
325
+ import sys
326
+ if len(sys.argv) > 1:
327
+ filename = sys.argv[1]
328
+ if filename.endswith('.sil'): # Changed from .nx to .sil
329
+ run_file(filename)
330
+ else:
331
+ print(f"Silicon Error: '{filename}' is not a valid .sil file.")
332
+ else:
333
+ print("Silicon v0.2.2")
334
+ print("Usage: silicon <filename>.sil")
335
+
336
+ if __name__ == "__main__":
337
+ main_cli()
@@ -0,0 +1,16 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "silicon.py"
7
+ version = "0.2.2"
8
+ description = "Silicon: A new language made with Python."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ authors = [
12
+ { name="qwertydev" }
13
+ ]
14
+
15
+ [project.scripts]
16
+ silicon = "nexus_lang.shell:main_cli"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,7 @@
1
+ Metadata-Version: 2.4
2
+ Name: silicon.py
3
+ Version: 0.2.2
4
+ Summary: Silicon: A new language made with Python.
5
+ Author: qwertydev
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
@@ -0,0 +1,9 @@
1
+ README.md
2
+ pyproject.toml
3
+ nexus_lang/__init__.py
4
+ nexus_lang/shell.py
5
+ silicon.py.egg-info/PKG-INFO
6
+ silicon.py.egg-info/SOURCES.txt
7
+ silicon.py.egg-info/dependency_links.txt
8
+ silicon.py.egg-info/entry_points.txt
9
+ silicon.py.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ silicon = nexus_lang.shell:main_cli
@@ -0,0 +1 @@
1
+ nexus_lang