zexus 1.6.8 → 1.7.2

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.
Files changed (177) hide show
  1. package/README.md +12 -5
  2. package/package.json +1 -1
  3. package/src/__init__.py +7 -0
  4. package/src/zexus/__init__.py +1 -1
  5. package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
  6. package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
  7. package/src/zexus/__pycache__/debug_sanitizer.cpython-312.pyc +0 -0
  8. package/src/zexus/__pycache__/environment.cpython-312.pyc +0 -0
  9. package/src/zexus/__pycache__/error_reporter.cpython-312.pyc +0 -0
  10. package/src/zexus/__pycache__/input_validation.cpython-312.pyc +0 -0
  11. package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
  12. package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
  13. package/src/zexus/__pycache__/module_manager.cpython-312.pyc +0 -0
  14. package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
  15. package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
  16. package/src/zexus/__pycache__/security_enforcement.cpython-312.pyc +0 -0
  17. package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
  18. package/src/zexus/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  19. package/src/zexus/__pycache__/zexus_token.cpython-312.pyc +0 -0
  20. package/src/zexus/access_control_system/__pycache__/__init__.cpython-312.pyc +0 -0
  21. package/src/zexus/access_control_system/__pycache__/access_control.cpython-312.pyc +0 -0
  22. package/src/zexus/advanced_types.py +17 -2
  23. package/src/zexus/blockchain/__init__.py +411 -0
  24. package/src/zexus/blockchain/accelerator.py +1160 -0
  25. package/src/zexus/blockchain/chain.py +660 -0
  26. package/src/zexus/blockchain/consensus.py +821 -0
  27. package/src/zexus/blockchain/contract_vm.py +1019 -0
  28. package/src/zexus/blockchain/crypto.py +79 -14
  29. package/src/zexus/blockchain/events.py +526 -0
  30. package/src/zexus/blockchain/loadtest.py +721 -0
  31. package/src/zexus/blockchain/monitoring.py +350 -0
  32. package/src/zexus/blockchain/mpt.py +716 -0
  33. package/src/zexus/blockchain/multichain.py +951 -0
  34. package/src/zexus/blockchain/multiprocess_executor.py +338 -0
  35. package/src/zexus/blockchain/network.py +886 -0
  36. package/src/zexus/blockchain/node.py +666 -0
  37. package/src/zexus/blockchain/rpc.py +1203 -0
  38. package/src/zexus/blockchain/rust_bridge.py +421 -0
  39. package/src/zexus/blockchain/storage.py +423 -0
  40. package/src/zexus/blockchain/tokens.py +750 -0
  41. package/src/zexus/blockchain/upgradeable.py +1004 -0
  42. package/src/zexus/blockchain/verification.py +1602 -0
  43. package/src/zexus/blockchain/wallet.py +621 -0
  44. package/src/zexus/capability_system.py +184 -9
  45. package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
  46. package/src/zexus/cli/main.py +383 -34
  47. package/src/zexus/cli/zpm.py +1 -1
  48. package/src/zexus/compiler/__pycache__/bytecode.cpython-312.pyc +0 -0
  49. package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
  50. package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
  51. package/src/zexus/compiler/__pycache__/semantic.cpython-312.pyc +0 -0
  52. package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  53. package/src/zexus/compiler/bytecode.py +124 -7
  54. package/src/zexus/compiler/compat_runtime.py +6 -2
  55. package/src/zexus/compiler/lexer.py +16 -5
  56. package/src/zexus/compiler/parser.py +108 -7
  57. package/src/zexus/compiler/semantic.py +18 -19
  58. package/src/zexus/compiler/zexus_ast.py +26 -1
  59. package/src/zexus/concurrency_system.py +79 -0
  60. package/src/zexus/config.py +54 -0
  61. package/src/zexus/crypto_bridge.py +244 -8
  62. package/src/zexus/dap/__init__.py +10 -0
  63. package/src/zexus/dap/__main__.py +4 -0
  64. package/src/zexus/dap/dap_server.py +391 -0
  65. package/src/zexus/dap/debug_engine.py +298 -0
  66. package/src/zexus/environment.py +112 -9
  67. package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
  68. package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
  69. package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
  70. package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
  71. package/src/zexus/evaluator/__pycache__/resource_limiter.cpython-312.pyc +0 -0
  72. package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
  73. package/src/zexus/evaluator/__pycache__/unified_execution.cpython-312.pyc +0 -0
  74. package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
  75. package/src/zexus/evaluator/bytecode_compiler.py +457 -37
  76. package/src/zexus/evaluator/core.py +644 -50
  77. package/src/zexus/evaluator/expressions.py +358 -62
  78. package/src/zexus/evaluator/functions.py +458 -20
  79. package/src/zexus/evaluator/resource_limiter.py +4 -4
  80. package/src/zexus/evaluator/statements.py +774 -122
  81. package/src/zexus/evaluator/unified_execution.py +573 -72
  82. package/src/zexus/evaluator/utils.py +14 -2
  83. package/src/zexus/evaluator_original.py +1 -1
  84. package/src/zexus/event_loop.py +186 -0
  85. package/src/zexus/lexer.py +742 -458
  86. package/src/zexus/lsp/__init__.py +1 -1
  87. package/src/zexus/lsp/definition_provider.py +163 -9
  88. package/src/zexus/lsp/server.py +22 -8
  89. package/src/zexus/lsp/symbol_provider.py +182 -9
  90. package/src/zexus/module_cache.py +239 -9
  91. package/src/zexus/module_manager.py +129 -1
  92. package/src/zexus/object.py +76 -6
  93. package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
  94. package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
  95. package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
  96. package/src/zexus/parser/parser.py +1349 -408
  97. package/src/zexus/parser/strategy_context.py +755 -58
  98. package/src/zexus/parser/strategy_structural.py +121 -21
  99. package/src/zexus/persistence.py +15 -1
  100. package/src/zexus/renderer/__init__.py +61 -0
  101. package/src/zexus/renderer/__pycache__/__init__.cpython-312.pyc +0 -0
  102. package/src/zexus/renderer/__pycache__/backend.cpython-312.pyc +0 -0
  103. package/src/zexus/renderer/__pycache__/canvas.cpython-312.pyc +0 -0
  104. package/src/zexus/renderer/__pycache__/color_system.cpython-312.pyc +0 -0
  105. package/src/zexus/renderer/__pycache__/layout.cpython-312.pyc +0 -0
  106. package/src/zexus/renderer/__pycache__/main_renderer.cpython-312.pyc +0 -0
  107. package/src/zexus/renderer/__pycache__/painter.cpython-312.pyc +0 -0
  108. package/src/zexus/renderer/backend.py +261 -0
  109. package/src/zexus/renderer/canvas.py +78 -0
  110. package/src/zexus/renderer/color_system.py +201 -0
  111. package/src/zexus/renderer/graphics.py +31 -0
  112. package/src/zexus/renderer/layout.py +222 -0
  113. package/src/zexus/renderer/main_renderer.py +66 -0
  114. package/src/zexus/renderer/painter.py +30 -0
  115. package/src/zexus/renderer/tk_backend.py +208 -0
  116. package/src/zexus/renderer/web_backend.py +260 -0
  117. package/src/zexus/runtime/__init__.py +10 -2
  118. package/src/zexus/runtime/__pycache__/__init__.cpython-312.pyc +0 -0
  119. package/src/zexus/runtime/__pycache__/async_runtime.cpython-312.pyc +0 -0
  120. package/src/zexus/runtime/__pycache__/load_manager.cpython-312.pyc +0 -0
  121. package/src/zexus/runtime/file_flags.py +137 -0
  122. package/src/zexus/runtime/load_manager.py +368 -0
  123. package/src/zexus/safety/__pycache__/__init__.cpython-312.pyc +0 -0
  124. package/src/zexus/safety/__pycache__/memory_safety.cpython-312.pyc +0 -0
  125. package/src/zexus/security.py +424 -34
  126. package/src/zexus/stdlib/fs.py +23 -18
  127. package/src/zexus/stdlib/http.py +289 -186
  128. package/src/zexus/stdlib/sockets.py +207 -163
  129. package/src/zexus/stdlib/websockets.py +282 -0
  130. package/src/zexus/stdlib_integration.py +369 -2
  131. package/src/zexus/strategy_recovery.py +6 -3
  132. package/src/zexus/type_checker.py +423 -0
  133. package/src/zexus/virtual_filesystem.py +189 -2
  134. package/src/zexus/vm/__init__.py +113 -3
  135. package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
  136. package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
  137. package/src/zexus/vm/__pycache__/bytecode_converter.cpython-312.pyc +0 -0
  138. package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
  139. package/src/zexus/vm/__pycache__/compiler.cpython-312.pyc +0 -0
  140. package/src/zexus/vm/__pycache__/gas_metering.cpython-312.pyc +0 -0
  141. package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
  142. package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
  143. package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
  144. package/src/zexus/vm/async_optimizer.py +80 -6
  145. package/src/zexus/vm/binary_bytecode.py +659 -0
  146. package/src/zexus/vm/bytecode.py +59 -11
  147. package/src/zexus/vm/bytecode_converter.py +26 -12
  148. package/src/zexus/vm/cabi.c +1985 -0
  149. package/src/zexus/vm/cabi.cpython-312-x86_64-linux-gnu.so +0 -0
  150. package/src/zexus/vm/cabi.h +127 -0
  151. package/src/zexus/vm/cache.py +561 -17
  152. package/src/zexus/vm/compiler.py +818 -51
  153. package/src/zexus/vm/fastops.c +15743 -0
  154. package/src/zexus/vm/fastops.cpython-312-x86_64-linux-gnu.so +0 -0
  155. package/src/zexus/vm/fastops.pyx +288 -0
  156. package/src/zexus/vm/gas_metering.py +50 -9
  157. package/src/zexus/vm/jit.py +364 -20
  158. package/src/zexus/vm/native_jit_backend.py +1816 -0
  159. package/src/zexus/vm/native_runtime.cpp +1388 -0
  160. package/src/zexus/vm/native_runtime.cpython-312-x86_64-linux-gnu.so +0 -0
  161. package/src/zexus/vm/optimizer.py +161 -11
  162. package/src/zexus/vm/parallel_vm.py +140 -45
  163. package/src/zexus/vm/peephole_optimizer.py +82 -4
  164. package/src/zexus/vm/profiler.py +38 -18
  165. package/src/zexus/vm/register_allocator.py +16 -5
  166. package/src/zexus/vm/register_vm.py +8 -5
  167. package/src/zexus/vm/vm.py +3581 -531
  168. package/src/zexus/vm/wasm_compiler.py +658 -0
  169. package/src/zexus/zexus_ast.py +137 -11
  170. package/src/zexus/zexus_token.py +16 -5
  171. package/src/zexus/zpm/installer.py +55 -15
  172. package/src/zexus/zpm/package_manager.py +1 -1
  173. package/src/zexus/zpm/registry.py +257 -28
  174. package/src/zexus.egg-info/PKG-INFO +16 -6
  175. package/src/zexus.egg-info/SOURCES.txt +129 -17
  176. package/src/zexus.egg-info/entry_points.txt +1 -0
  177. package/src/zexus.egg-info/requires.txt +4 -0
@@ -3,26 +3,83 @@ import click
3
3
  import sys
4
4
  import os
5
5
  from pathlib import Path
6
- from rich.console import Console
7
- from rich.syntax import Syntax
8
- from rich.panel import Panel
9
- from rich.table import Table
6
+
7
+ try: # Optional rich dependency for colorful CLI output
8
+ from rich.console import Console
9
+ from rich.syntax import Syntax
10
+ from rich.panel import Panel
11
+ from rich.table import Table
12
+ _RICH_AVAILABLE = True
13
+ except ModuleNotFoundError: # Fallback to minimal console utilities when rich is missing
14
+ _RICH_AVAILABLE = False
15
+
16
+ class Console: # pragma: no cover - straightforward fallback
17
+ def print(self, *args, **kwargs):
18
+ sep = kwargs.get("sep", " ")
19
+ end = kwargs.get("end", "\n")
20
+ text = sep.join(str(arg) for arg in args)
21
+ sys.stdout.write(text)
22
+ if end is not None:
23
+ sys.stdout.write(end)
24
+
25
+ def rule(self, title=""):
26
+ line = "-" * 40
27
+ if title:
28
+ line = f"{line} {title} {line}"
29
+ self.print(line)
30
+
31
+ class Syntax: # pragma: no cover - fallback keeps interface compatible
32
+ def __init__(self, code, *_args, **_kwargs):
33
+ self.code = code
34
+
35
+ def __str__(self):
36
+ return self.code
37
+
38
+ class Panel: # pragma: no cover
39
+ def __init__(self, renderable, title=None):
40
+ self.renderable = renderable
41
+ self.title = title
42
+
43
+ def __str__(self):
44
+ if self.title:
45
+ return f"[{self.title}] {self.renderable}"
46
+ return str(self.renderable)
47
+
48
+ class Table: # pragma: no cover
49
+ def __init__(self, **_kwargs):
50
+ self.columns = []
51
+ self.rows = []
52
+
53
+ def add_column(self, header, **_kwargs):
54
+ self.columns.append(header)
55
+
56
+ def add_row(self, *columns):
57
+ self.rows.append(columns)
58
+
59
+ def __str__(self):
60
+ lines = []
61
+ if self.columns:
62
+ lines.append(" | ".join(self.columns))
63
+ for row in self.rows:
64
+ lines.append(" | ".join(str(col) for col in row))
65
+ return "\n".join(lines)
10
66
 
11
67
  # Import your existing modules - UPDATED IMPORTS
12
68
  from ..lexer import Lexer
13
69
  from ..parser import Parser
14
70
  # UPDATED: Import evaluate from evaluator package
15
- from ..evaluator import evaluate
71
+ from ..evaluator import evaluate, Evaluator
16
72
  # UPDATED: Import Environment and String from object module
17
73
  from ..object import Environment, String
18
74
  from ..syntax_validator import SyntaxValidator
19
75
  from ..hybrid_orchestrator import orchestrator
20
76
  from ..config import config
77
+ from ..runtime.file_flags import parse_file_flags, apply_vm_config
21
78
  # Import error handling
22
79
  from ..error_reporter import get_error_reporter, ZexusError, print_error
23
80
  # VM and Compiler for high-performance execution
24
81
  from ..vm.vm import VM, VMMode
25
- from ..vm.compiler import compile_ast_to_bytecode
82
+ from ..vm.compiler import compile_ast_to_bytecode, UnsupportedNodeError
26
83
 
27
84
  console = Console()
28
85
 
@@ -36,6 +93,7 @@ def show_all_commands():
36
93
 
37
94
  commands = [
38
95
  ("zx run <file>", "Execute a Zexus program"),
96
+ ("zx -r \"<code>\"", "Run inline Zexus code (like python -c)"),
39
97
  ("zx run --zexus", "Show this command list"),
40
98
  ("zx check <file>", "Check syntax with detailed validation"),
41
99
  ("zx validate <file>", "Validate and auto-fix syntax errors"),
@@ -50,7 +108,9 @@ def show_all_commands():
50
108
  ("--syntax-style=<style>", "universal, tolerable, or auto (default)"),
51
109
  ("--execution-mode=<mode>", "interpreter, compiler, or auto (default)"),
52
110
  ("--advanced-parsing", "Enable multi-strategy parsing (default: on)"),
53
- ("--debug", "Enable debug output"),
111
+ ("--debug <on|off|minimal|full>", "Enable/disable debug output"),
112
+ ("--no-debug", "Disable debug output"),
113
+ ("--no-vm", "Disable VM execution for run"),
54
114
  ("--version", "Show Zexus version"),
55
115
  ("--help", "Show detailed help"),
56
116
  ("", ""),
@@ -66,6 +126,8 @@ def show_all_commands():
66
126
  ("zx check --debug program.zx", "Check syntax with debug info"),
67
127
  ("zx profile myapp.zx", "Profile with memory tracking"),
68
128
  ("zx profile --no-memory --top 10 app.zx", "Profile without memory, show top 10"),
129
+ ("zx -r \"print(42)\"", "Execute inline code directly"),
130
+ ("zx -r \"let x = 10; print(x * 2)\"", "Run multi-statement inline code"),
69
131
  ("", ""),
70
132
  ("[bold]Built-in Functions:[/bold]", "100+ functions available"),
71
133
  ("", "Memory: persist_set, persist_get, track_memory"),
@@ -94,54 +156,189 @@ def show_all_commands():
94
156
  console.print("\n[bold green]šŸ’” Tip:[/bold green] Use 'zx <command> --help' for detailed command options\n")
95
157
 
96
158
  @click.group(invoke_without_command=True)
97
- @click.version_option(version="1.6.8", prog_name="Zexus")
159
+ @click.version_option(version="1.7.2", prog_name="Zexus")
98
160
  @click.option('--syntax-style', type=click.Choice(['universal', 'tolerable', 'auto']),
99
161
  default='auto', help='Syntax style to use (universal=strict, tolerable=flexible)')
100
162
  @click.option('--advanced-parsing', is_flag=True, default=True,
101
163
  help='Enable advanced multi-strategy parsing (recommended)')
102
164
  @click.option('--execution-mode', type=click.Choice(['interpreter', 'compiler', 'auto']),
103
165
  default='auto', help='Execution engine to use')
104
- @click.option('--debug', is_flag=True, help='Enable debug logging')
166
+ @click.option('--debug', type=click.Choice(['on', 'off', 'minimal', 'full', 'none']),
167
+ help='Enable/disable debug logging (on/off/minimal/full)')
168
+ @click.option('--no-debug', is_flag=True, help='Disable debug logging')
105
169
  @click.option('--zexus', is_flag=True, help='Show all available Zexus commands')
170
+ @click.option('-r', '--run-code', type=str, default=None,
171
+ help='Execute inline Zexus code (like python -c)')
106
172
  @click.pass_context
107
- def cli(ctx, syntax_style, advanced_parsing, execution_mode, debug, zexus):
173
+ def cli(ctx, syntax_style, advanced_parsing, execution_mode, debug, no_debug, zexus, run_code):
108
174
  """Zexus Programming Language - Hybrid Interpreter/Compiler
109
175
 
110
176
  Use 'zx run --zexus' or 'zx --zexus' to see all available commands.
177
+ Use 'zx -r "<code>"' to execute inline Zexus code.
111
178
  """
112
179
 
113
180
  if zexus:
114
181
  show_all_commands()
115
182
  sys.exit(0)
116
183
 
117
- # If no command provided, show help
118
- if ctx.invoked_subcommand is None:
119
- click.echo(ctx.get_help())
120
- return
121
-
122
184
  ctx.ensure_object(dict)
123
185
  ctx.obj['SYNTAX_STYLE'] = syntax_style
124
186
  ctx.obj['ADVANCED_PARSING'] = advanced_parsing
125
187
  ctx.obj['EXECUTION_MODE'] = execution_mode
126
- ctx.obj['DEBUG'] = debug
188
+ ctx.obj['DEBUG'] = False
127
189
 
128
190
  # Update config based on CLI flags
129
- if debug:
191
+ if no_debug or debug in ('off', 'none'):
192
+ config.disable_debug()
193
+ config.enable_debug_logs = False
194
+ ctx.obj['DEBUG'] = False
195
+ elif debug in ('on', 'full'):
196
+ config.enable_debug('full')
130
197
  config.enable_debug_logs = True
198
+ ctx.obj['DEBUG'] = True
199
+ elif debug == 'minimal':
200
+ config.enable_debug('minimal')
201
+ config.enable_debug_logs = True
202
+ ctx.obj['DEBUG'] = True
203
+
204
+ # Handle inline code execution: zx -r "<code>"
205
+ if run_code is not None:
206
+ _execute_inline_code(ctx, run_code)
207
+ return
208
+
209
+ # If no command provided, show help
210
+ if ctx.invoked_subcommand is None:
211
+ click.echo(ctx.get_help())
212
+ return
131
213
  if execution_mode == 'compiler':
132
214
  config.use_hybrid_compiler = True
133
215
  elif execution_mode == 'interpreter':
134
216
  config.use_hybrid_compiler = False
135
217
 
218
+
219
+ def _execute_inline_code(ctx, source_code):
220
+ """Execute inline Zexus code passed via -r flag.
221
+
222
+ Examples:
223
+ zx -r "print(42)"
224
+ zx -r "let x = 10; print(x * 2)"
225
+ zx -r "action greet(name) { print(\"Hello \" + name) }; greet(\"World\")"
226
+ """
227
+ error_reporter = get_error_reporter()
228
+
229
+ try:
230
+ # Register source for error reporting
231
+ error_reporter.register_source("<inline>", source_code)
232
+
233
+ syntax_style = ctx.obj['SYNTAX_STYLE']
234
+ advanced_parsing = ctx.obj['ADVANCED_PARSING']
235
+ debug_mode = ctx.obj.get('DEBUG', False)
236
+ validator = SyntaxValidator()
237
+
238
+ # Auto-detect syntax style if needed
239
+ if syntax_style == 'auto':
240
+ syntax_style = validator.suggest_syntax_style(source_code)
241
+
242
+ # Parse the program
243
+ lexer = Lexer(source_code, filename="<inline>")
244
+ parser = Parser(lexer, syntax_style, enable_advanced_strategies=advanced_parsing)
245
+ program = parser.parse_program()
246
+
247
+ if parser.errors and any("critical" in e.lower() for e in parser.errors):
248
+ console.print("[bold red]āŒ Parse error in inline code:[/bold red]")
249
+ for error in parser.errors:
250
+ console.print(f" āŒ {error}")
251
+ sys.exit(1)
252
+
253
+ # Set up environment
254
+ env = Environment()
255
+ env.set("__file__", String("<inline>"))
256
+ env.set("__FILE__", String("<inline>"))
257
+ env.set("__MODULE__", String("__main__"))
258
+ env.set("__DIR__", String(os.getcwd()))
259
+
260
+ from ..object import List as ZList
261
+ env.set("__ARGS__", ZList([]))
262
+ env.set("__ARGV__", ZList([]))
263
+ env.set("__PACKAGE__", String(""))
264
+
265
+ # Attempt VM execution first, fall back to interpreter
266
+ bytecode = None
267
+ fallback_reason = None
268
+
269
+ try:
270
+ bytecode = compile_ast_to_bytecode(program, optimize=True)
271
+ except UnsupportedNodeError as e:
272
+ fallback_reason = str(e)
273
+ except Exception as e:
274
+ fallback_reason = str(e)
275
+
276
+ if bytecode is not None and fallback_reason is None:
277
+ vm = VM(
278
+ mode=VMMode.AUTO,
279
+ use_jit=True,
280
+ max_heap_mb=512,
281
+ debug=debug_mode,
282
+ gas_limit=10000000
283
+ )
284
+ # Load builtins into VM
285
+ try:
286
+ builtin_evaluator = Evaluator(use_vm=False)
287
+ vm.builtins.update(dict(builtin_evaluator.builtins))
288
+ except Exception:
289
+ pass
290
+
291
+ vm.env["__file__"] = "<inline>"
292
+ vm.env["__FILE__"] = "<inline>"
293
+ vm.env["__MODULE__"] = "__main__"
294
+ vm.env["__DIR__"] = os.getcwd()
295
+ vm.env["__ARGS__"] = ()
296
+ vm.env["__ARGV__"] = ()
297
+ vm.env["__PACKAGE__"] = ""
298
+
299
+ try:
300
+ result = vm.execute(bytecode, debug=debug_mode)
301
+ except Exception as e:
302
+ if debug_mode:
303
+ import traceback
304
+ traceback.print_exc()
305
+ fallback_reason = str(e)
306
+
307
+ if fallback_reason is not None:
308
+ result = evaluate(program, env, debug_mode=debug_mode, use_vm=False)
309
+ elif bytecode is None:
310
+ result = evaluate(program, env, debug_mode=debug_mode, use_vm=False)
311
+
312
+ # Print result if meaningful
313
+ if result and hasattr(result, 'inspect') and result.inspect() != 'null':
314
+ console.print(result.inspect())
315
+ elif isinstance(result, str) and result:
316
+ console.print(result)
317
+ elif hasattr(result, 'value') and result.value is not None:
318
+ console.print(str(result.value))
319
+
320
+ except ZexusError as e:
321
+ print_error(e)
322
+ sys.exit(1)
323
+ except Exception as e:
324
+ console.print(f"[bold red]Error:[/bold red] {str(e)}")
325
+ if ctx.obj.get('DEBUG'):
326
+ import traceback
327
+ traceback.print_exc()
328
+ sys.exit(1)
329
+
330
+
136
331
  @cli.command()
137
332
  @click.argument('file', type=click.Path(exists=True))
138
333
  @click.argument('args', nargs=-1) # Accept any number of additional arguments
139
- @click.option('--use-vm', is_flag=True, default=True, help='Use VM for execution (default: enabled for performance)')
334
+ @click.option('--use-vm/--no-vm', default=True, help='Use VM for execution (default: enabled for performance)')
140
335
  @click.option('--vm-mode', type=click.Choice(['auto', 'stack', 'register', 'parallel']),
141
336
  default='auto', help='VM execution mode (auto=best performance)')
142
337
  @click.option('--no-optimize', is_flag=True, default=False, help='Disable bytecode optimizations')
338
+ @click.option('--precompile-modules', is_flag=True, default=False,
339
+ help='Pre-parse and cache all imported modules before execution')
143
340
  @click.pass_context
144
- def run(ctx, file, args, use_vm, vm_mode, no_optimize):
341
+ def run(ctx, file, args, use_vm, vm_mode, no_optimize, precompile_modules):
145
342
  """Run a Zexus program with hybrid execution"""
146
343
  # Register source for error reporting
147
344
  error_reporter = get_error_reporter()
@@ -152,6 +349,37 @@ def run(ctx, file, args, use_vm, vm_mode, no_optimize):
152
349
 
153
350
  # Register source with error reporter
154
351
  error_reporter.register_source(file, source_code)
352
+
353
+ # Apply in-file execution flags (if any)
354
+ file_flags = parse_file_flags(source_code)
355
+ vm_config = {}
356
+ if file_flags:
357
+ if 'use_vm' in file_flags:
358
+ use_vm = bool(file_flags.get('use_vm'))
359
+ if 'vm_mode' in file_flags:
360
+ vm_mode = str(file_flags.get('vm_mode')).lower()
361
+ if 'no_optimize' in file_flags:
362
+ no_optimize = bool(file_flags.get('no_optimize'))
363
+ if 'precompile_modules' in file_flags:
364
+ precompile_modules = bool(file_flags.get('precompile_modules'))
365
+ if 'syntax_style' in file_flags:
366
+ ctx.obj['SYNTAX_STYLE'] = str(file_flags.get('syntax_style'))
367
+ if 'advanced_parsing' in file_flags:
368
+ ctx.obj['ADVANCED_PARSING'] = bool(file_flags.get('advanced_parsing'))
369
+ if 'execution_mode' in file_flags:
370
+ ctx.obj['EXECUTION_MODE'] = str(file_flags.get('execution_mode'))
371
+ if 'debug' in file_flags:
372
+ dbg = file_flags.get('debug')
373
+ if isinstance(dbg, str):
374
+ config.debug_level = dbg
375
+ ctx.obj['DEBUG'] = dbg != 'none'
376
+ else:
377
+ ctx.obj['DEBUG'] = bool(dbg)
378
+ config.enable_debug_logs = ctx.obj['DEBUG']
379
+ if 'vm_config' in file_flags and isinstance(file_flags.get('vm_config'), dict):
380
+ vm_config = dict(file_flags.get('vm_config'))
381
+
382
+ console.print("[dim]Applied file flags (@zexus) overrides[/dim]")
155
383
 
156
384
  syntax_style = ctx.obj['SYNTAX_STYLE']
157
385
  advanced_parsing = ctx.obj['ADVANCED_PARSING']
@@ -200,7 +428,36 @@ def run(ctx, file, args, use_vm, vm_mode, no_optimize):
200
428
  for error in parser.errors:
201
429
  console.print(f" āŒ {error}")
202
430
  sys.exit(1)
203
-
431
+
432
+ # Pre-compile imported modules (parse + optional bytecode) before execution
433
+ if precompile_modules:
434
+ console.print("[dim]Pre-compiling imported modules...[/dim]", end="")
435
+ try:
436
+ from ..module_cache import precompile_modules as _precompile
437
+ import os as _os
438
+ _abs = _os.path.abspath(file)
439
+ precompiled = _precompile(program, _abs, compile_bytecode=use_vm)
440
+ if precompiled:
441
+ console.print(f" [green]done[/green] ({len(precompiled)} module(s) cached)")
442
+ else:
443
+ console.print(" [green]done[/green] (no external modules)")
444
+ except Exception as e:
445
+ console.print(f" [yellow]warning:[/yellow] {e}")
446
+
447
+ # Static type checking pass
448
+ try:
449
+ from ..type_checker import StaticTypeChecker
450
+ _tc = StaticTypeChecker()
451
+ _type_diags = _tc.check(program)
452
+ if _type_diags:
453
+ for _d in _type_diags:
454
+ if _d.level == "error":
455
+ console.print(f" [bold red]āœ— {_d}[/bold red]")
456
+ else:
457
+ console.print(f" [yellow]⚠ {_d}[/yellow]")
458
+ except Exception:
459
+ pass # type checker should never block execution
460
+
204
461
  # Use the evaluator package
205
462
  env = Environment()
206
463
 
@@ -231,6 +488,14 @@ def run(ctx, file, args, use_vm, vm_mode, no_optimize):
231
488
  env.set("__PACKAGE__", package_name)
232
489
 
233
490
  # Execute based on mode
491
+ if not use_vm:
492
+ try:
493
+ env.disable_vm = True
494
+ except Exception:
495
+ pass
496
+ bytecode = None
497
+ fallback_reason = None
498
+
234
499
  if use_vm:
235
500
  # VM EXECUTION PATH (High Performance)
236
501
  console.print("[dim]Compiling to bytecode...[/dim]", end="")
@@ -238,32 +503,59 @@ def run(ctx, file, args, use_vm, vm_mode, no_optimize):
238
503
  bytecode = compile_ast_to_bytecode(program, optimize=not no_optimize)
239
504
  console.print(" [green]done[/green]")
240
505
  console.print(f"[dim]Bytecode: {len(bytecode.instructions)} instructions, {len(bytecode.constants)} constants[/dim]")
506
+ except UnsupportedNodeError as e:
507
+ console.print(" [yellow]unsupported[/yellow]")
508
+ console.print(f"[bold yellow]āš ļø VM fallback:[/bold yellow] {e}")
509
+ if ctx.obj.get('DEBUG'):
510
+ import traceback
511
+ traceback.print_exc()
512
+ fallback_reason = str(e)
241
513
  except Exception as e:
242
- console.print(f" [red]failed[/red]")
514
+ console.print(" [red]failed[/red]")
243
515
  console.print(f"[bold red]Bytecode compilation error:[/bold red] {str(e)}")
244
516
  if ctx.obj.get('DEBUG'):
245
517
  import traceback
246
518
  traceback.print_exc()
247
- sys.exit(1)
248
-
249
- # Initialize VM
250
- vm_mode_enum = {
519
+ fallback_reason = str(e)
520
+
521
+ if bytecode is not None and fallback_reason is None:
522
+ vm_mode_map = {
251
523
  'auto': VMMode.AUTO,
252
524
  'stack': VMMode.STACK,
253
525
  'register': VMMode.REGISTER,
254
526
  'parallel': VMMode.PARALLEL
255
- }[vm_mode]
256
-
527
+ }
528
+ vm_mode_value = vm_mode if vm_mode in vm_mode_map else 'auto'
529
+ vm_mode_enum = vm_mode_map[vm_mode_value]
530
+
531
+ vm_builtins = {}
532
+ try:
533
+ builtin_evaluator = Evaluator(use_vm=False)
534
+ vm_builtins = dict(builtin_evaluator.builtins)
535
+ except Exception:
536
+ vm_builtins = {}
537
+
257
538
  console.print(f"[dim]Initializing VM ({vm_mode} mode)...[/dim]", end="")
258
539
  vm = VM(
259
540
  mode=vm_mode_enum,
260
541
  use_jit=not no_optimize,
261
542
  max_heap_mb=1000, # 1GB heap limit
262
- debug=ctx.obj.get('DEBUG', False)
543
+ debug=ctx.obj.get('DEBUG', False),
544
+ gas_limit=100000000 # 100M instructions for heavy checks
263
545
  )
546
+ if vm_builtins:
547
+ vm.builtins.update(vm_builtins)
548
+ apply_vm_config(vm, vm_config)
549
+ # Mirror interpreter module context for relative imports in VM
550
+ vm.env["__file__"] = abs_file
551
+ vm.env["__FILE__"] = abs_file
552
+ vm.env["__MODULE__"] = "__main__"
553
+ vm.env["__DIR__"] = os.path.dirname(abs_file)
554
+ vm.env["__ARGS__"] = args
555
+ vm.env["__ARGV__"] = args
556
+ vm.env["__PACKAGE__"] = package_name.value if hasattr(package_name, "value") else package_name
264
557
  console.print(" [green]done[/green]")
265
-
266
- # Execute on VM
558
+
267
559
  console.print("[dim]Executing on VM...[/dim]")
268
560
  try:
269
561
  result = vm.execute(bytecode, debug=ctx.obj.get('DEBUG', False))
@@ -272,10 +564,14 @@ def run(ctx, file, args, use_vm, vm_mode, no_optimize):
272
564
  if ctx.obj.get('DEBUG'):
273
565
  import traceback
274
566
  traceback.print_exc()
275
- sys.exit(1)
276
- else:
277
- # INTERPRETER EXECUTION PATH (Standard)
278
- result = evaluate(program, env, debug_mode=ctx.obj['DEBUG'])
567
+ fallback_reason = str(e)
568
+
569
+ if fallback_reason is not None:
570
+ console.print("[bold yellow]šŸ”„ Falling back to interpreter execution...[/bold yellow]")
571
+ result = evaluate(program, env, debug_mode=ctx.obj['DEBUG'], use_vm=False)
572
+ elif bytecode is None:
573
+ # No bytecode generated but VM not requested or compile skipped
574
+ result = evaluate(program, env, debug_mode=ctx.obj['DEBUG'], use_vm=False)
279
575
 
280
576
  if result and hasattr(result, 'inspect') and result.inspect() != 'null':
281
577
  console.print(f"\nāœ… [bold green]Result:[/bold green] {result.inspect()}")
@@ -359,6 +655,59 @@ def check(ctx, file):
359
655
  console.print(f"[bold red]Error:[/bold red] {str(e)}")
360
656
  sys.exit(1)
361
657
 
658
+
659
+ @cli.command()
660
+ @click.argument('file', type=click.Path(exists=True))
661
+ @click.option('--target', '-t', type=click.Choice(['wasm']), default='wasm',
662
+ help='Compilation target (default: wasm)')
663
+ @click.option('-o', '--output', type=click.Path(), default=None,
664
+ help='Output file path (default: <input>.wasm)')
665
+ @click.pass_context
666
+ def compile(ctx, file, target, output):
667
+ """Compile a Zexus file to a target format (e.g. WebAssembly)."""
668
+ import os
669
+ try:
670
+ with open(file, 'r') as f:
671
+ source_code = f.read()
672
+
673
+ syntax_style = ctx.obj['SYNTAX_STYLE']
674
+ advanced_parsing = ctx.obj['ADVANCED_PARSING']
675
+
676
+ lexer = Lexer(source_code)
677
+ parser = Parser(lexer, syntax_style, enable_advanced_strategies=advanced_parsing)
678
+ program = parser.parse_program()
679
+
680
+ if parser.errors:
681
+ console.print("[bold red]āŒ Parse errors — cannot compile:[/bold red]")
682
+ for err in parser.errors:
683
+ console.print(f" 🚫 {err}")
684
+ sys.exit(1)
685
+
686
+ # Compile AST → bytecode
687
+ from ..vm.compiler import BytecodeCompiler as BCCompiler
688
+ bc_compiler = BCCompiler()
689
+ bytecode = bc_compiler.compile(program)
690
+
691
+ if target == 'wasm':
692
+ from ..vm.wasm_compiler import WasmCompiler
693
+ wasm = WasmCompiler().compile(bytecode)
694
+
695
+ out_path = output or os.path.splitext(file)[0] + '.wasm'
696
+ with open(out_path, 'wb') as wf:
697
+ wf.write(wasm)
698
+
699
+ console.print(f"[bold green]āœ… Compiled to WASM:[/bold green] {out_path} ({len(wasm)} bytes)")
700
+ else:
701
+ console.print(f"[bold red]Unknown target: {target}[/bold red]")
702
+ sys.exit(1)
703
+
704
+ except Exception as e:
705
+ console.print(f"[bold red]Compile error:[/bold red] {str(e)}")
706
+ import traceback
707
+ traceback.print_exc()
708
+ sys.exit(1)
709
+
710
+
362
711
  @cli.command()
363
712
  @click.argument('file', type=click.Path(exists=True))
364
713
  @click.pass_context
@@ -18,7 +18,7 @@ console = Console()
18
18
 
19
19
 
20
20
  @click.group()
21
- @click.version_option(version="1.6.8", prog_name="ZPM")
21
+ @click.version_option(version="1.7.2", prog_name="ZPM")
22
22
  def cli():
23
23
  """ZPM - Zexus Package Manager
24
24