bxz-lang 1.0.0__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.
bxz_lang-1.0.0/LICENSE ADDED
File without changes
@@ -0,0 +1,33 @@
1
+ Metadata-Version: 2.4
2
+ Name: bxz-lang
3
+ Version: 1.0.0
4
+ Summary: BXZ - A Cross-Platform Polyglot Programming Language
5
+ Author: BXZ Language Team
6
+ Keywords: programming language interpreter polyglot
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: 3.6
9
+ Classifier: Programming Language :: Python :: 3.7
10
+ Classifier: Programming Language :: Python :: 3.8
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Environment :: Console
17
+ Classifier: Topic :: Software Development :: Interpreters
18
+ Requires-Python: >=3.6
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Dynamic: author
22
+ Dynamic: classifier
23
+ Dynamic: description
24
+ Dynamic: description-content-type
25
+ Dynamic: keywords
26
+ Dynamic: license-file
27
+ Dynamic: requires-python
28
+ Dynamic: summary
29
+
30
+ go to your cmd and type this
31
+ cd Desktop\bxz-lang
32
+ and type tis
33
+ run_bxz.bat --some-argument --another-flag
@@ -0,0 +1,4 @@
1
+ go to your cmd and type this
2
+ cd Desktop\bxz-lang
3
+ and type tis
4
+ run_bxz.bat --some-argument --another-flag
bxz_lang-1.0.0/bxz.py ADDED
@@ -0,0 +1,962 @@
1
+ #!/usr/bin/env python3
2
+ # bxz.py - BXZ Language v4.0 - Stable Version
3
+
4
+ import sys
5
+ import os
6
+ import re
7
+ import math
8
+ import json
9
+ import time
10
+ import random
11
+ import hashlib
12
+ import base64
13
+ import sqlite3
14
+ import threading
15
+ import subprocess
16
+ import tempfile
17
+ import webbrowser
18
+ from datetime import datetime
19
+ from pathlib import Path
20
+ from typing import Any, Dict, List, Optional, Tuple, Callable
21
+
22
+ # ============ VERSION ============
23
+ __version__ = "1.1.5"
24
+
25
+ # ============ TOKEN TYPES ============
26
+ class TokenType:
27
+ # Keywords
28
+ LET = "let"
29
+ CONST = "const"
30
+ FUNC = "func"
31
+ IF = "if"
32
+ ELSE = "else"
33
+ ELIF = "elif"
34
+ FOR = "for"
35
+ WHILE = "while"
36
+ BREAK = "break"
37
+ CONTINUE = "continue"
38
+ RETURN = "return"
39
+ TRY = "try"
40
+ CATCH = "catch"
41
+ FINALLY = "finally"
42
+ THROW = "throw"
43
+ IMPORT = "import"
44
+ FROM = "from"
45
+ AS = "as"
46
+ IN = "in"
47
+ IS = "is"
48
+ # Types
49
+ INT = "int"
50
+ FLOAT = "float"
51
+ STR = "str"
52
+ BOOL = "bool"
53
+ LIST = "list"
54
+ DICT = "dict"
55
+ # Literals
56
+ NUMBER = "NUMBER"
57
+ STRING = "STRING"
58
+ BOOLEAN = "BOOLEAN"
59
+ NULL = "NULL"
60
+ IDENTIFIER = "IDENTIFIER"
61
+ # Operators
62
+ PLUS = "+"
63
+ MINUS = "-"
64
+ MUL = "*"
65
+ DIV = "/"
66
+ MOD = "%"
67
+ POW = "**"
68
+ ASSIGN = "="
69
+ EQ = "=="
70
+ NE = "!="
71
+ LT = "<"
72
+ GT = ">"
73
+ LE = "<="
74
+ GE = ">="
75
+ AND = "&&"
76
+ OR = "||"
77
+ NOT = "!"
78
+ # Symbols
79
+ LPAREN = "("
80
+ RPAREN = ")"
81
+ LBRACE = "{"
82
+ RBRACE = "}"
83
+ LBRACK = "["
84
+ RBRACK = "]"
85
+ COMMA = ","
86
+ DOT = "."
87
+ COLON = ":"
88
+ SEMICOLON = ";"
89
+ ARROW = "->"
90
+ EOF = "EOF"
91
+
92
+ class Token:
93
+ def __init__(self, type_, value, line, col):
94
+ self.type = type_
95
+ self.value = value
96
+ self.line = line
97
+ self.col = col
98
+
99
+ def __repr__(self):
100
+ return f"Token({self.type}, {self.value})"
101
+
102
+ # ============ AST NODES ============
103
+ class ASTNode: pass
104
+
105
+ class Program(ASTNode):
106
+ def __init__(self, statements): self.statements = statements
107
+
108
+ class LetStatement(ASTNode):
109
+ def __init__(self, name, value, is_const=False): self.name = name; self.value = value; self.is_const = is_const
110
+
111
+ class PrintStatement(ASTNode):
112
+ def __init__(self, value): self.value = value
113
+
114
+ class IfStatement(ASTNode):
115
+ def __init__(self, condition, then_branch, else_branch=None): self.condition = condition; self.then_branch = then_branch; self.else_branch = else_branch
116
+
117
+ class WhileStatement(ASTNode):
118
+ def __init__(self, condition, body): self.condition = condition; self.body = body
119
+
120
+ class ForStatement(ASTNode):
121
+ def __init__(self, variable, iterable, body): self.variable = variable; self.iterable = iterable; self.body = body
122
+
123
+ class FunctionStatement(ASTNode):
124
+ def __init__(self, name, params, body): self.name = name; self.params = params; self.body = body
125
+
126
+ class ReturnStatement(ASTNode):
127
+ def __init__(self, value): self.value = value
128
+
129
+ class BreakStatement(ASTNode): pass
130
+ class ContinueStatement(ASTNode): pass
131
+
132
+ class TryStatement(ASTNode):
133
+ def __init__(self, try_body, catch_var, catch_body, finally_body): self.try_body = try_body; self.catch_var = catch_var; self.catch_body = catch_body; self.finally_body = finally_body
134
+
135
+ class ThrowStatement(ASTNode):
136
+ def __init__(self, value): self.value = value
137
+
138
+ class BlockStatement(ASTNode):
139
+ def __init__(self, statements): self.statements = statements
140
+
141
+ class ExpressionStatement(ASTNode):
142
+ def __init__(self, expression): self.expression = expression
143
+
144
+ class NumberLiteral(ASTNode):
145
+ def __init__(self, value): self.value = value
146
+
147
+ class StringLiteral(ASTNode):
148
+ def __init__(self, value): self.value = value
149
+
150
+ class BooleanLiteral(ASTNode):
151
+ def __init__(self, value): self.value = value
152
+
153
+ class Identifier(ASTNode):
154
+ def __init__(self, name): self.name = name
155
+
156
+ class BinaryOp(ASTNode):
157
+ def __init__(self, left, operator, right): self.left = left; self.operator = operator; self.right = right
158
+
159
+ class UnaryOp(ASTNode):
160
+ def __init__(self, operator, operand): self.operator = operator; self.operand = operand
161
+
162
+ class CallExpression(ASTNode):
163
+ def __init__(self, name, arguments): self.name = name; self.arguments = arguments
164
+
165
+ class ArrayLiteral(ASTNode):
166
+ def __init__(self, elements): self.elements = elements
167
+
168
+ class ObjectLiteral(ASTNode):
169
+ def __init__(self, properties): self.properties = properties
170
+
171
+ class LambdaExpression(ASTNode):
172
+ def __init__(self, params, body): self.params = params; self.body = body
173
+
174
+ # ============ LEXER ============
175
+ class Lexer:
176
+ def __init__(self, source):
177
+ self.source = source
178
+ self.pos = 0
179
+ self.line = 1
180
+ self.col = 1
181
+
182
+ self.keywords = {
183
+ 'let': TokenType.LET, 'const': TokenType.CONST, 'func': TokenType.FUNC,
184
+ 'if': TokenType.IF, 'else': TokenType.ELSE, 'elif': TokenType.ELIF,
185
+ 'for': TokenType.FOR, 'while': TokenType.WHILE, 'break': TokenType.BREAK,
186
+ 'continue': TokenType.CONTINUE, 'return': TokenType.RETURN, 'try': TokenType.TRY,
187
+ 'catch': TokenType.CATCH, 'finally': TokenType.FINALLY, 'throw': TokenType.THROW,
188
+ 'import': TokenType.IMPORT, 'from': TokenType.FROM, 'as': TokenType.AS,
189
+ 'in': TokenType.IN, 'is': TokenType.IS,
190
+ 'int': TokenType.INT, 'float': TokenType.FLOAT, 'str': TokenType.STR,
191
+ 'bool': TokenType.BOOL, 'list': TokenType.LIST, 'dict': TokenType.DICT,
192
+ 'true': TokenType.BOOLEAN, 'false': TokenType.BOOLEAN, 'null': TokenType.NULL,
193
+ }
194
+
195
+ def tokenize(self):
196
+ tokens = []
197
+ while self.pos < len(self.source):
198
+ ch = self.source[self.pos]
199
+
200
+ if ch in ' \t\r':
201
+ self._advance()
202
+ elif ch == '\n':
203
+ self.line += 1
204
+ self.col = 1
205
+ self.pos += 1
206
+ elif ch.isdigit():
207
+ tokens.append(self._read_number())
208
+ elif ch.isalpha() or ch == '_':
209
+ tokens.append(self._read_identifier())
210
+ elif ch == '"' or ch == "'":
211
+ tokens.append(self._read_string())
212
+ elif ch == '+':
213
+ self._advance()
214
+ tokens.append(Token(TokenType.PLUS, '+', self.line, self.col-1))
215
+ elif ch == '-':
216
+ self._advance()
217
+ tokens.append(Token(TokenType.MINUS, '-', self.line, self.col-1))
218
+ elif ch == '*':
219
+ self._advance()
220
+ tokens.append(Token(TokenType.MUL, '*', self.line, self.col-1))
221
+ elif ch == '/':
222
+ self._advance()
223
+ tokens.append(Token(TokenType.DIV, '/', self.line, self.col-1))
224
+ elif ch == '%':
225
+ self._advance()
226
+ tokens.append(Token(TokenType.MOD, '%', self.line, self.col-1))
227
+ elif ch == '=':
228
+ self._advance()
229
+ if self._peek() == '=':
230
+ self._advance()
231
+ tokens.append(Token(TokenType.EQ, '==', self.line, self.col-2))
232
+ else:
233
+ tokens.append(Token(TokenType.ASSIGN, '=', self.line, self.col-1))
234
+ elif ch == '!':
235
+ self._advance()
236
+ if self._peek() == '=':
237
+ self._advance()
238
+ tokens.append(Token(TokenType.NE, '!=', self.line, self.col-2))
239
+ else:
240
+ tokens.append(Token(TokenType.NOT, '!', self.line, self.col-1))
241
+ elif ch == '<':
242
+ self._advance()
243
+ if self._peek() == '=':
244
+ self._advance()
245
+ tokens.append(Token(TokenType.LE, '<=', self.line, self.col-2))
246
+ else:
247
+ tokens.append(Token(TokenType.LT, '<', self.line, self.col-1))
248
+ elif ch == '>':
249
+ self._advance()
250
+ if self._peek() == '=':
251
+ self._advance()
252
+ tokens.append(Token(TokenType.GE, '>=', self.line, self.col-2))
253
+ else:
254
+ tokens.append(Token(TokenType.GT, '>', self.line, self.col-1))
255
+ elif ch == '&':
256
+ self._advance()
257
+ if self._peek() == '&':
258
+ self._advance()
259
+ tokens.append(Token(TokenType.AND, '&&', self.line, self.col-2))
260
+ else:
261
+ tokens.append(Token(TokenType.BIT_AND, '&', self.line, self.col-1))
262
+ elif ch == '|':
263
+ self._advance()
264
+ if self._peek() == '|':
265
+ self._advance()
266
+ tokens.append(Token(TokenType.OR, '||', self.line, self.col-2))
267
+ else:
268
+ tokens.append(Token(TokenType.BIT_OR, '|', self.line, self.col-1))
269
+ elif ch == '(':
270
+ self._advance()
271
+ tokens.append(Token(TokenType.LPAREN, '(', self.line, self.col-1))
272
+ elif ch == ')':
273
+ self._advance()
274
+ tokens.append(Token(TokenType.RPAREN, ')', self.line, self.col-1))
275
+ elif ch == '{':
276
+ self._advance()
277
+ tokens.append(Token(TokenType.LBRACE, '{', self.line, self.col-1))
278
+ elif ch == '}':
279
+ self._advance()
280
+ tokens.append(Token(TokenType.RBRACE, '}', self.line, self.col-1))
281
+ elif ch == '[':
282
+ self._advance()
283
+ tokens.append(Token(TokenType.LBRACK, '[', self.line, self.col-1))
284
+ elif ch == ']':
285
+ self._advance()
286
+ tokens.append(Token(TokenType.RBRACK, ']', self.line, self.col-1))
287
+ elif ch == ',':
288
+ self._advance()
289
+ tokens.append(Token(TokenType.COMMA, ',', self.line, self.col-1))
290
+ elif ch == '.':
291
+ self._advance()
292
+ tokens.append(Token(TokenType.DOT, '.', self.line, self.col-1))
293
+ elif ch == ':':
294
+ self._advance()
295
+ tokens.append(Token(TokenType.COLON, ':', self.line, self.col-1))
296
+ elif ch == ';':
297
+ self._advance()
298
+ tokens.append(Token(TokenType.SEMICOLON, ';', self.line, self.col-1))
299
+ else:
300
+ raise SyntaxError(f"Unknown character '{ch}' at line {self.line}, col {self.col}")
301
+
302
+ tokens.append(Token(TokenType.EOF, None, self.line, self.col))
303
+ return tokens
304
+
305
+ def _advance(self):
306
+ self.pos += 1
307
+ self.col += 1
308
+
309
+ def _peek(self):
310
+ return self.source[self.pos] if self.pos < len(self.source) else None
311
+
312
+ def _read_number(self):
313
+ start = self.pos
314
+ has_dot = False
315
+ while self.pos < len(self.source) and (self.source[self.pos].isdigit() or self.source[self.pos] == '.'):
316
+ if self.source[self.pos] == '.':
317
+ has_dot = True
318
+ self._advance()
319
+ num_str = self.source[start:self.pos]
320
+ if has_dot:
321
+ value = float(num_str)
322
+ else:
323
+ value = int(num_str)
324
+ return Token(TokenType.NUMBER, value, self.line, self.col - (self.pos - start))
325
+
326
+ def _read_identifier(self):
327
+ start = self.pos
328
+ while self.pos < len(self.source) and (self.source[self.pos].isalnum() or self.source[self.pos] == '_'):
329
+ self._advance()
330
+ ident = self.source[start:self.pos]
331
+ token_type = self.keywords.get(ident, TokenType.IDENTIFIER)
332
+ if token_type == TokenType.BOOLEAN:
333
+ value = True if ident == 'true' else False
334
+ return Token(token_type, value, self.line, self.col - (self.pos - start))
335
+ return Token(token_type, ident, self.line, self.col - (self.pos - start))
336
+
337
+ def _read_string(self):
338
+ quote = self.source[self.pos]
339
+ self._advance()
340
+ start = self.pos
341
+ while self.pos < len(self.source) and self.source[self.pos] != quote:
342
+ if self.source[self.pos] == '\n':
343
+ raise SyntaxError("Unterminated string")
344
+ self._advance()
345
+ value = self.source[start:self.pos]
346
+ self._advance()
347
+ return Token(TokenType.STRING, value, self.line, self.col - (self.pos - start))
348
+
349
+ # ============ PARSER ============
350
+ class Parser:
351
+ def __init__(self, tokens):
352
+ self.tokens = tokens
353
+ self.pos = 0
354
+
355
+ def current(self):
356
+ return self.tokens[self.pos] if self.pos < len(self.tokens) else Token(TokenType.EOF, None, 0, 0)
357
+
358
+ def eat(self, token_type):
359
+ token = self.current()
360
+ if token.type == token_type:
361
+ self.pos += 1
362
+ return token
363
+ raise SyntaxError(f"Expected {token_type}, got {token.type}")
364
+
365
+ def parse(self):
366
+ statements = []
367
+ while self.current().type != TokenType.EOF:
368
+ stmt = self.parse_statement()
369
+ if stmt:
370
+ statements.append(stmt)
371
+ return Program(statements)
372
+
373
+ def parse_statement(self):
374
+ token = self.current()
375
+
376
+ if token.type == TokenType.LET:
377
+ return self.parse_let(False)
378
+ elif token.type == TokenType.CONST:
379
+ return self.parse_let(True)
380
+ elif token.type == TokenType.PRINT:
381
+ return self.parse_print()
382
+ elif token.type == TokenType.IF:
383
+ return self.parse_if()
384
+ elif token.type == TokenType.WHILE:
385
+ return self.parse_while()
386
+ elif token.type == TokenType.FOR:
387
+ return self.parse_for()
388
+ elif token.type == TokenType.FUNC:
389
+ return self.parse_function()
390
+ elif token.type == TokenType.RETURN:
391
+ return self.parse_return()
392
+ elif token.type == TokenType.BREAK:
393
+ self.eat(TokenType.BREAK)
394
+ return BreakStatement()
395
+ elif token.type == TokenType.CONTINUE:
396
+ self.eat(TokenType.CONTINUE)
397
+ return ContinueStatement()
398
+ elif token.type == TokenType.TRY:
399
+ return self.parse_try()
400
+ elif token.type == TokenType.THROW:
401
+ return self.parse_throw()
402
+ elif token.type == TokenType.LBRACE:
403
+ return self.parse_block()
404
+ else:
405
+ expr = self.parse_expression()
406
+ if self.current().type == TokenType.SEMICOLON:
407
+ self.eat(TokenType.SEMICOLON)
408
+ return ExpressionStatement(expr)
409
+
410
+ def parse_let(self, is_const):
411
+ self.eat(TokenType.LET if not is_const else TokenType.CONST)
412
+ name = self.eat(TokenType.IDENTIFIER).value
413
+ self.eat(TokenType.ASSIGN)
414
+ value = self.parse_expression()
415
+ if self.current().type == TokenType.SEMICOLON:
416
+ self.eat(TokenType.SEMICOLON)
417
+ return LetStatement(name, value, is_const)
418
+
419
+ def parse_print(self):
420
+ self.eat(TokenType.PRINT)
421
+ value = self.parse_expression()
422
+ if self.current().type == TokenType.SEMICOLON:
423
+ self.eat(TokenType.SEMICOLON)
424
+ return PrintStatement(value)
425
+
426
+ def parse_if(self):
427
+ self.eat(TokenType.IF)
428
+ self.eat(TokenType.LPAREN)
429
+ condition = self.parse_expression()
430
+ self.eat(TokenType.RPAREN)
431
+ then_branch = self.parse_block().statements
432
+
433
+ else_branch = None
434
+ if self.current().type == TokenType.ELSE:
435
+ self.eat(TokenType.ELSE)
436
+ else_branch = self.parse_block().statements
437
+
438
+ return IfStatement(condition, then_branch, else_branch)
439
+
440
+ def parse_while(self):
441
+ self.eat(TokenType.WHILE)
442
+ self.eat(TokenType.LPAREN)
443
+ condition = self.parse_expression()
444
+ self.eat(TokenType.RPAREN)
445
+ body = self.parse_block().statements
446
+ return WhileStatement(condition, body)
447
+
448
+ def parse_for(self):
449
+ self.eat(TokenType.FOR)
450
+ self.eat(TokenType.LPAREN)
451
+ var = self.eat(TokenType.IDENTIFIER).value
452
+ self.eat(TokenType.IN)
453
+ iterable = self.parse_expression()
454
+ self.eat(TokenType.RPAREN)
455
+ body = self.parse_block().statements
456
+ return ForStatement(var, iterable, body)
457
+
458
+ def parse_function(self):
459
+ self.eat(TokenType.FUNC)
460
+ name = self.eat(TokenType.IDENTIFIER).value
461
+ self.eat(TokenType.LPAREN)
462
+
463
+ params = []
464
+ if self.current().type != TokenType.RPAREN:
465
+ params.append(self.eat(TokenType.IDENTIFIER).value)
466
+ while self.current().type == TokenType.COMMA:
467
+ self.eat(TokenType.COMMA)
468
+ params.append(self.eat(TokenType.IDENTIFIER).value)
469
+
470
+ self.eat(TokenType.RPAREN)
471
+ body = self.parse_block().statements
472
+ return FunctionStatement(name, params, body)
473
+
474
+ def parse_return(self):
475
+ self.eat(TokenType.RETURN)
476
+ value = None
477
+ if self.current().type != TokenType.SEMICOLON:
478
+ value = self.parse_expression()
479
+ if self.current().type == TokenType.SEMICOLON:
480
+ self.eat(TokenType.SEMICOLON)
481
+ return ReturnStatement(value)
482
+
483
+ def parse_try(self):
484
+ self.eat(TokenType.TRY)
485
+ try_body = self.parse_block().statements
486
+
487
+ catch_var = None
488
+ catch_body = None
489
+ if self.current().type == TokenType.CATCH:
490
+ self.eat(TokenType.CATCH)
491
+ self.eat(TokenType.LPAREN)
492
+ catch_var = self.eat(TokenType.IDENTIFIER).value
493
+ self.eat(TokenType.RPAREN)
494
+ catch_body = self.parse_block().statements
495
+
496
+ finally_body = None
497
+ if self.current().type == TokenType.FINALLY:
498
+ self.eat(TokenType.FINALLY)
499
+ finally_body = self.parse_block().statements
500
+
501
+ return TryStatement(try_body, catch_var, catch_body, finally_body)
502
+
503
+ def parse_throw(self):
504
+ self.eat(TokenType.THROW)
505
+ value = self.parse_expression()
506
+ if self.current().type == TokenType.SEMICOLON:
507
+ self.eat(TokenType.SEMICOLON)
508
+ return ThrowStatement(value)
509
+
510
+ def parse_block(self):
511
+ self.eat(TokenType.LBRACE)
512
+ statements = []
513
+ while self.current().type != TokenType.RBRACE:
514
+ statements.append(self.parse_statement())
515
+ self.eat(TokenType.RBRACE)
516
+ return BlockStatement(statements)
517
+
518
+ def parse_expression(self):
519
+ return self.parse_assignment()
520
+
521
+ def parse_assignment(self):
522
+ left = self.parse_logical_or()
523
+
524
+ if self.current().type == TokenType.ASSIGN:
525
+ self.eat(TokenType.ASSIGN)
526
+ right = self.parse_assignment()
527
+ return BinaryOp(left, '=', right)
528
+
529
+ return left
530
+
531
+ def parse_logical_or(self):
532
+ left = self.parse_logical_and()
533
+
534
+ while self.current().type == TokenType.OR:
535
+ self.eat(TokenType.OR)
536
+ right = self.parse_logical_and()
537
+ left = BinaryOp(left, '||', right)
538
+
539
+ return left
540
+
541
+ def parse_logical_and(self):
542
+ left = self.parse_comparison()
543
+
544
+ while self.current().type == TokenType.AND:
545
+ self.eat(TokenType.AND)
546
+ right = self.parse_comparison()
547
+ left = BinaryOp(left, '&&', right)
548
+
549
+ return left
550
+
551
+ def parse_comparison(self):
552
+ left = self.parse_addition()
553
+
554
+ while self.current().type in [TokenType.EQ, TokenType.NE, TokenType.LT,
555
+ TokenType.GT, TokenType.LE, TokenType.GE]:
556
+ op = self.current()
557
+ self.eat(op.type)
558
+ right = self.parse_addition()
559
+ left = BinaryOp(left, op.value, right)
560
+
561
+ return left
562
+
563
+ def parse_addition(self):
564
+ left = self.parse_multiplication()
565
+
566
+ while self.current().type in [TokenType.PLUS, TokenType.MINUS]:
567
+ op = self.current()
568
+ self.eat(op.type)
569
+ right = self.parse_multiplication()
570
+ left = BinaryOp(left, op.value, right)
571
+
572
+ return left
573
+
574
+ def parse_multiplication(self):
575
+ left = self.parse_primary()
576
+
577
+ while self.current().type in [TokenType.MUL, TokenType.DIV, TokenType.MOD]:
578
+ op = self.current()
579
+ self.eat(op.type)
580
+ right = self.parse_primary()
581
+ left = BinaryOp(left, op.value, right)
582
+
583
+ return left
584
+
585
+ def parse_primary(self):
586
+ token = self.current()
587
+
588
+ if token.type == TokenType.NUMBER:
589
+ self.eat(TokenType.NUMBER)
590
+ return NumberLiteral(token.value)
591
+ elif token.type == TokenType.STRING:
592
+ self.eat(TokenType.STRING)
593
+ return StringLiteral(token.value)
594
+ elif token.type == TokenType.BOOLEAN:
595
+ self.eat(TokenType.BOOLEAN)
596
+ return BooleanLiteral(token.value)
597
+ elif token.type == TokenType.NULL:
598
+ self.eat(TokenType.NULL)
599
+ return None
600
+ elif token.type == TokenType.IDENTIFIER:
601
+ name = token.value
602
+ self.eat(TokenType.IDENTIFIER)
603
+ if self.current().type == TokenType.LPAREN:
604
+ return self.parse_call(name)
605
+ return Identifier(name)
606
+ elif token.type == TokenType.LPAREN:
607
+ self.eat(TokenType.LPAREN)
608
+ expr = self.parse_expression()
609
+ self.eat(TokenType.RPAREN)
610
+ return expr
611
+ elif token.type == TokenType.LBRACK:
612
+ return self.parse_array()
613
+ elif token.type == TokenType.LBRACE:
614
+ return self.parse_object()
615
+
616
+ raise SyntaxError(f"Unexpected token: {token.type}")
617
+
618
+ def parse_call(self, name):
619
+ self.eat(TokenType.LPAREN)
620
+ args = []
621
+ if self.current().type != TokenType.RPAREN:
622
+ args.append(self.parse_expression())
623
+ while self.current().type == TokenType.COMMA:
624
+ self.eat(TokenType.COMMA)
625
+ args.append(self.parse_expression())
626
+ self.eat(TokenType.RPAREN)
627
+ return CallExpression(name, args)
628
+
629
+ def parse_array(self):
630
+ self.eat(TokenType.LBRACK)
631
+ elements = []
632
+ if self.current().type != TokenType.RBRACK:
633
+ elements.append(self.parse_expression())
634
+ while self.current().type == TokenType.COMMA:
635
+ self.eat(TokenType.COMMA)
636
+ elements.append(self.parse_expression())
637
+ self.eat(TokenType.RBRACK)
638
+ return ArrayLiteral(elements)
639
+
640
+ def parse_object(self):
641
+ self.eat(TokenType.LBRACE)
642
+ properties = {}
643
+ if self.current().type != TokenType.RBRACE:
644
+ key = self.eat(TokenType.IDENTIFIER).value
645
+ self.eat(TokenType.COLON)
646
+ value = self.parse_expression()
647
+ properties[key] = value
648
+ while self.current().type == TokenType.COMMA:
649
+ self.eat(TokenType.COMMA)
650
+ key = self.eat(TokenType.IDENTIFIER).value
651
+ self.eat(TokenType.COLON)
652
+ value = self.parse_expression()
653
+ properties[key] = value
654
+ self.eat(TokenType.RBRACE)
655
+ return ObjectLiteral(properties)
656
+
657
+ # ============ INTERPRETER ============
658
+ class Interpreter:
659
+ def __init__(self, debug=False):
660
+ self.vars = {}
661
+ self.funcs = {}
662
+ self.debug = debug
663
+ self.return_val = None
664
+ self.break_flag = False
665
+ self.continue_flag = False
666
+
667
+ def log(self, msg):
668
+ if self.debug:
669
+ print(f"[DEBUG] {msg}")
670
+
671
+ def evaluate(self, node):
672
+ if isinstance(node, NumberLiteral):
673
+ return node.value
674
+ elif isinstance(node, StringLiteral):
675
+ return node.value
676
+ elif isinstance(node, BooleanLiteral):
677
+ return node.value
678
+ elif isinstance(node, Identifier):
679
+ if node.name in self.vars:
680
+ return self.vars[node.name]
681
+ raise RuntimeError(f"Undefined variable: {node.name}")
682
+ elif isinstance(node, BinaryOp):
683
+ left = self.evaluate(node.left)
684
+ right = self.evaluate(node.right)
685
+
686
+ ops = {
687
+ '+': lambda: left + right,
688
+ '-': lambda: left - right,
689
+ '*': lambda: left * right,
690
+ '/': lambda: left / right if right != 0 else 0,
691
+ '%': lambda: left % right,
692
+ '**': lambda: left ** right,
693
+ '==': lambda: left == right,
694
+ '!=': lambda: left != right,
695
+ '<': lambda: left < right,
696
+ '>': lambda: left > right,
697
+ '<=': lambda: left <= right,
698
+ '>=': lambda: left >= right,
699
+ '&&': lambda: left and right,
700
+ '||': lambda: left or right,
701
+ '=': lambda: right,
702
+ }
703
+
704
+ if node.operator in ops:
705
+ result = ops[node.operator]()
706
+ return result
707
+ raise RuntimeError(f"Unknown operator: {node.operator}")
708
+ elif isinstance(node, UnaryOp):
709
+ operand = self.evaluate(node.operand)
710
+ if node.operator == '!':
711
+ return not operand
712
+ elif node.operator == '-':
713
+ return -operand
714
+ return operand
715
+ elif isinstance(node, CallExpression):
716
+ if node.name == 'print':
717
+ args = [self.evaluate(arg) for arg in node.arguments]
718
+ print(*args)
719
+ return None
720
+ elif node.name == 'len':
721
+ return len(self.evaluate(node.arguments[0]))
722
+ elif node.name == 'range':
723
+ start = self.evaluate(node.arguments[0]) if len(node.arguments) > 0 else 0
724
+ end = self.evaluate(node.arguments[1]) if len(node.arguments) > 1 else start
725
+ step = self.evaluate(node.arguments[2]) if len(node.arguments) > 2 else 1
726
+ return list(range(start, end, step))
727
+ elif node.name == 'input':
728
+ prompt = self.evaluate(node.arguments[0]) if node.arguments else ""
729
+ return input(prompt)
730
+ elif node.name == 'int':
731
+ return int(self.evaluate(node.arguments[0]))
732
+ elif node.name == 'float':
733
+ return float(self.evaluate(node.arguments[0]))
734
+ elif node.name == 'str':
735
+ return str(self.evaluate(node.arguments[0]))
736
+ elif node.name == 'type':
737
+ return type(self.evaluate(node.arguments[0])).__name__
738
+ elif node.name in self.funcs:
739
+ return self._call_function(node.name, node.arguments)
740
+ elif node.name == 'server':
741
+ port = self.evaluate(node.arguments[0]) if node.arguments else 8080
742
+ self.start_server(port)
743
+ return None
744
+ elif node.name == 'json':
745
+ return json.dumps(self.evaluate(node.arguments[0]))
746
+ elif node.name == 'parse_json':
747
+ return json.loads(self.evaluate(node.arguments[0]))
748
+ raise RuntimeError(f"Undefined function: {node.name}")
749
+ elif isinstance(node, ArrayLiteral):
750
+ return [self.evaluate(elem) for elem in node.elements]
751
+ elif isinstance(node, ObjectLiteral):
752
+ result = {}
753
+ for key, value in node.properties.items():
754
+ result[key] = self.evaluate(value)
755
+ return result
756
+ return None
757
+
758
+ def _call_function(self, name, args_nodes):
759
+ func = self.funcs[name]
760
+ old_vars = self.vars.copy()
761
+
762
+ for i, param in enumerate(func.params):
763
+ if i < len(args_nodes):
764
+ self.vars[param] = self.evaluate(args_nodes[i])
765
+
766
+ self.return_val = None
767
+ for stmt in func.body:
768
+ self.execute(stmt)
769
+ if self.return_val is not None:
770
+ break
771
+
772
+ result = self.return_val
773
+ self.vars = old_vars
774
+ self.return_val = None
775
+ return result
776
+
777
+ def start_server(self, port):
778
+ try:
779
+ from http.server import HTTPServer, SimpleHTTPRequestHandler
780
+ server = HTTPServer(('localhost', port), SimpleHTTPRequestHandler)
781
+ url = f'http://localhost:{port}'
782
+ print(f"\n{'='*40}")
783
+ print(f"🚀 Server: {url}")
784
+ print(f"{'='*40}")
785
+ webbrowser.open(url)
786
+ server.serve_forever()
787
+ except KeyboardInterrupt:
788
+ print("\n👋 Server stopped")
789
+
790
+ def execute(self, node):
791
+ if isinstance(node, Program):
792
+ for stmt in node.statements:
793
+ self.execute(stmt)
794
+ if self.return_val is not None:
795
+ break
796
+ elif isinstance(node, LetStatement):
797
+ value = self.evaluate(node.value)
798
+ if node.is_const:
799
+ self.vars[node.name] = value
800
+ else:
801
+ self.vars[node.name] = value
802
+ elif isinstance(node, PrintStatement):
803
+ value = self.evaluate(node.value)
804
+ print(value)
805
+ elif isinstance(node, IfStatement):
806
+ condition = self.evaluate(node.condition)
807
+ if condition:
808
+ for stmt in node.then_branch:
809
+ self.execute(stmt)
810
+ elif node.else_branch:
811
+ for stmt in node.else_branch:
812
+ self.execute(stmt)
813
+ elif isinstance(node, WhileStatement):
814
+ self.break_flag = False
815
+ while self.evaluate(node.condition) and not self.break_flag:
816
+ for stmt in node.body:
817
+ self.execute(stmt)
818
+ if self.continue_flag:
819
+ self.continue_flag = False
820
+ break
821
+ elif isinstance(node, ForStatement):
822
+ iterable = self.evaluate(node.iterable)
823
+ self.break_flag = False
824
+ for item in iterable:
825
+ if self.break_flag:
826
+ break
827
+ if self.continue_flag:
828
+ self.continue_flag = False
829
+ continue
830
+ self.vars[node.variable] = item
831
+ for stmt in node.body:
832
+ self.execute(stmt)
833
+ elif isinstance(node, FunctionStatement):
834
+ self.funcs[node.name] = node
835
+ elif isinstance(node, ReturnStatement):
836
+ self.return_val = self.evaluate(node.value) if node.value else None
837
+ elif isinstance(node, BreakStatement):
838
+ self.break_flag = True
839
+ elif isinstance(node, ContinueStatement):
840
+ self.continue_flag = True
841
+ elif isinstance(node, TryStatement):
842
+ try:
843
+ for stmt in node.try_body:
844
+ self.execute(stmt)
845
+ except Exception as e:
846
+ if node.catch_var:
847
+ self.vars[node.catch_var] = str(e)
848
+ for stmt in node.catch_body:
849
+ self.execute(stmt)
850
+ else:
851
+ raise
852
+ finally:
853
+ if node.finally_body:
854
+ for stmt in node.finally_body:
855
+ self.execute(stmt)
856
+ elif isinstance(node, ThrowStatement):
857
+ raise RuntimeError(str(self.evaluate(node.value)))
858
+ elif isinstance(node, ExpressionStatement):
859
+ self.evaluate(node.expression)
860
+ elif isinstance(node, BlockStatement):
861
+ for stmt in node.statements:
862
+ self.execute(stmt)
863
+
864
+ # ============ MAIN ============
865
+ def run_file(filename, debug=False):
866
+ if not os.path.exists(filename):
867
+ print(f"Error: File '{filename}' not found!")
868
+ return False
869
+
870
+ try:
871
+ with open(filename, 'r', encoding='utf-8') as f:
872
+ source = f.read()
873
+
874
+ lexer = Lexer(source)
875
+ tokens = lexer.tokenize()
876
+ parser = Parser(tokens)
877
+ ast = parser.parse()
878
+ interpreter = Interpreter(debug)
879
+ interpreter.execute(ast)
880
+ return True
881
+ except Exception as e:
882
+ print(f"Error: {e}")
883
+ if debug:
884
+ import traceback
885
+ traceback.print_exc()
886
+ return False
887
+
888
+ def repl(debug=False):
889
+ print("=" * 60)
890
+ print(f"⚡ BXZ Language v{__version__}")
891
+ print("Commands: print(), len(), range(), input(), server()")
892
+ print("Type 'exit' to quit, 'help' for commands")
893
+ print("=" * 60)
894
+
895
+ interpreter = Interpreter(debug)
896
+
897
+ while True:
898
+ try:
899
+ code = input("\n>>> ")
900
+ if code.strip() in ['exit', 'quit']:
901
+ print("Goodbye!")
902
+ break
903
+ if code.strip() == 'help':
904
+ print("""
905
+ Available commands:
906
+ print("text") - Print text
907
+ let x = value - Create variable
908
+ x + y, x * y - Math operations
909
+ func name(p) {} - Define function
910
+ if (cond) {} - Conditional
911
+ while (cond) {} - Loop
912
+ for item in arr {} - For-each loop
913
+ server(port) - Start web server
914
+ json(obj) - Convert to JSON
915
+ parse_json(str) - Parse JSON
916
+ len(arr) - Get length
917
+ range(start, end) - Create range
918
+ input(prompt) - Get user input
919
+ int(), float(), str(), type()
920
+ """)
921
+ continue
922
+ if code.strip():
923
+ lexer = Lexer(code)
924
+ tokens = lexer.tokenize()
925
+ parser = Parser(tokens)
926
+ ast = parser.parse()
927
+ interpreter.execute(ast)
928
+ except KeyboardInterrupt:
929
+ print("\nGoodbye!")
930
+ break
931
+ except Exception as e:
932
+ print(f"Error: {e}")
933
+ if debug:
934
+ import traceback
935
+ traceback.print_exc()
936
+
937
+ def main():
938
+ import argparse
939
+ parser = argparse.ArgumentParser(description=f"BXZ Language v{__version__}")
940
+ parser.add_argument("file", nargs="?", help="BXZ file to execute")
941
+ parser.add_argument("-i", "--interactive", action="store_true", help="Interactive REPL")
942
+ parser.add_argument("-d", "--debug", action="store_true", help="Debug mode")
943
+ parser.add_argument("-v", "--version", action="store_true", help="Show version")
944
+ parser.add_argument("-s", "--server", action="store_true", help="Start web server")
945
+ parser.add_argument("-p", "--port", type=int, default=8080, help="Server port")
946
+
947
+ args = parser.parse_args()
948
+
949
+ if args.version:
950
+ print(f"BXZ Language v{__version__}")
951
+ return
952
+
953
+ if args.server:
954
+ Interpreter().start_server(args.port)
955
+ elif args.interactive or not args.file:
956
+ repl(args.debug)
957
+ else:
958
+ success = run_file(args.file, args.debug)
959
+ sys.exit(0 if success else 1)
960
+
961
+ if __name__ == "__main__":
962
+ main()
@@ -0,0 +1,33 @@
1
+ Metadata-Version: 2.4
2
+ Name: bxz-lang
3
+ Version: 1.0.0
4
+ Summary: BXZ - A Cross-Platform Polyglot Programming Language
5
+ Author: BXZ Language Team
6
+ Keywords: programming language interpreter polyglot
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: 3.6
9
+ Classifier: Programming Language :: Python :: 3.7
10
+ Classifier: Programming Language :: Python :: 3.8
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Environment :: Console
17
+ Classifier: Topic :: Software Development :: Interpreters
18
+ Requires-Python: >=3.6
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Dynamic: author
22
+ Dynamic: classifier
23
+ Dynamic: description
24
+ Dynamic: description-content-type
25
+ Dynamic: keywords
26
+ Dynamic: license-file
27
+ Dynamic: requires-python
28
+ Dynamic: summary
29
+
30
+ go to your cmd and type this
31
+ cd Desktop\bxz-lang
32
+ and type tis
33
+ run_bxz.bat --some-argument --another-flag
@@ -0,0 +1,9 @@
1
+ LICENSE
2
+ README.md
3
+ bxz.py
4
+ setup.py
5
+ bxz_lang.egg-info/PKG-INFO
6
+ bxz_lang.egg-info/SOURCES.txt
7
+ bxz_lang.egg-info/dependency_links.txt
8
+ bxz_lang.egg-info/entry_points.txt
9
+ bxz_lang.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ bxz = bxz:main
@@ -0,0 +1 @@
1
+ bxz
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,38 @@
1
+ # setup.py - Python package installer
2
+ from setuptools import setup
3
+ import sys
4
+ import platform
5
+
6
+ with open("README.md", "r", encoding="utf-8") as f:
7
+ long_description = f.read()
8
+
9
+ setup(
10
+ name="bxz-lang",
11
+ version="1.0.0",
12
+ author="BXZ Language Team",
13
+ description="BXZ - A Cross-Platform Polyglot Programming Language",
14
+ long_description=long_description,
15
+ long_description_content_type="text/markdown",
16
+ py_modules=["bxz"],
17
+ entry_points={
18
+ "console_scripts": [
19
+ "bxz=bxz:main",
20
+ ],
21
+ },
22
+ install_requires=[],
23
+ python_requires=">=3.6",
24
+ classifiers=[
25
+ "Programming Language :: Python :: 3",
26
+ "Programming Language :: Python :: 3.6",
27
+ "Programming Language :: Python :: 3.7",
28
+ "Programming Language :: Python :: 3.8",
29
+ "Programming Language :: Python :: 3.9",
30
+ "Programming Language :: Python :: 3.10",
31
+ "Programming Language :: Python :: 3.11",
32
+ "License :: OSI Approved :: MIT License",
33
+ "Operating System :: OS Independent",
34
+ "Environment :: Console",
35
+ "Topic :: Software Development :: Interpreters",
36
+ ],
37
+ keywords="programming language interpreter polyglot",
38
+ )