zexus 1.7.1 → 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 (159) hide show
  1. package/README.md +3 -3
  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/cli/__pycache__/main.cpython-312.pyc +0 -0
  45. package/src/zexus/cli/main.py +300 -20
  46. package/src/zexus/cli/zpm.py +1 -1
  47. package/src/zexus/compiler/__pycache__/bytecode.cpython-312.pyc +0 -0
  48. package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
  49. package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
  50. package/src/zexus/compiler/__pycache__/semantic.cpython-312.pyc +0 -0
  51. package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  52. package/src/zexus/compiler/lexer.py +10 -5
  53. package/src/zexus/concurrency_system.py +79 -0
  54. package/src/zexus/config.py +54 -0
  55. package/src/zexus/crypto_bridge.py +244 -8
  56. package/src/zexus/dap/__init__.py +10 -0
  57. package/src/zexus/dap/__main__.py +4 -0
  58. package/src/zexus/dap/dap_server.py +391 -0
  59. package/src/zexus/dap/debug_engine.py +298 -0
  60. package/src/zexus/environment.py +10 -1
  61. package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
  62. package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
  63. package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
  64. package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
  65. package/src/zexus/evaluator/__pycache__/resource_limiter.cpython-312.pyc +0 -0
  66. package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
  67. package/src/zexus/evaluator/__pycache__/unified_execution.cpython-312.pyc +0 -0
  68. package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
  69. package/src/zexus/evaluator/bytecode_compiler.py +441 -37
  70. package/src/zexus/evaluator/core.py +560 -49
  71. package/src/zexus/evaluator/expressions.py +122 -49
  72. package/src/zexus/evaluator/functions.py +417 -16
  73. package/src/zexus/evaluator/statements.py +521 -118
  74. package/src/zexus/evaluator/unified_execution.py +573 -72
  75. package/src/zexus/evaluator/utils.py +14 -2
  76. package/src/zexus/event_loop.py +186 -0
  77. package/src/zexus/lexer.py +742 -486
  78. package/src/zexus/lsp/__init__.py +1 -1
  79. package/src/zexus/lsp/definition_provider.py +163 -9
  80. package/src/zexus/lsp/server.py +22 -8
  81. package/src/zexus/lsp/symbol_provider.py +182 -9
  82. package/src/zexus/module_cache.py +237 -9
  83. package/src/zexus/object.py +64 -6
  84. package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
  85. package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
  86. package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
  87. package/src/zexus/parser/parser.py +786 -285
  88. package/src/zexus/parser/strategy_context.py +407 -66
  89. package/src/zexus/parser/strategy_structural.py +117 -19
  90. package/src/zexus/persistence.py +15 -1
  91. package/src/zexus/renderer/__init__.py +15 -0
  92. package/src/zexus/renderer/__pycache__/__init__.cpython-312.pyc +0 -0
  93. package/src/zexus/renderer/__pycache__/backend.cpython-312.pyc +0 -0
  94. package/src/zexus/renderer/__pycache__/canvas.cpython-312.pyc +0 -0
  95. package/src/zexus/renderer/__pycache__/color_system.cpython-312.pyc +0 -0
  96. package/src/zexus/renderer/__pycache__/layout.cpython-312.pyc +0 -0
  97. package/src/zexus/renderer/__pycache__/main_renderer.cpython-312.pyc +0 -0
  98. package/src/zexus/renderer/__pycache__/painter.cpython-312.pyc +0 -0
  99. package/src/zexus/renderer/tk_backend.py +208 -0
  100. package/src/zexus/renderer/web_backend.py +260 -0
  101. package/src/zexus/runtime/__pycache__/__init__.cpython-312.pyc +0 -0
  102. package/src/zexus/runtime/__pycache__/async_runtime.cpython-312.pyc +0 -0
  103. package/src/zexus/runtime/__pycache__/load_manager.cpython-312.pyc +0 -0
  104. package/src/zexus/runtime/file_flags.py +137 -0
  105. package/src/zexus/safety/__pycache__/__init__.cpython-312.pyc +0 -0
  106. package/src/zexus/safety/__pycache__/memory_safety.cpython-312.pyc +0 -0
  107. package/src/zexus/security.py +424 -34
  108. package/src/zexus/stdlib/fs.py +23 -18
  109. package/src/zexus/stdlib/http.py +289 -186
  110. package/src/zexus/stdlib/sockets.py +207 -163
  111. package/src/zexus/stdlib/websockets.py +282 -0
  112. package/src/zexus/stdlib_integration.py +369 -2
  113. package/src/zexus/strategy_recovery.py +6 -3
  114. package/src/zexus/type_checker.py +423 -0
  115. package/src/zexus/virtual_filesystem.py +189 -2
  116. package/src/zexus/vm/__init__.py +113 -3
  117. package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
  118. package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
  119. package/src/zexus/vm/__pycache__/bytecode_converter.cpython-312.pyc +0 -0
  120. package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
  121. package/src/zexus/vm/__pycache__/compiler.cpython-312.pyc +0 -0
  122. package/src/zexus/vm/__pycache__/gas_metering.cpython-312.pyc +0 -0
  123. package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
  124. package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
  125. package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
  126. package/src/zexus/vm/async_optimizer.py +14 -1
  127. package/src/zexus/vm/binary_bytecode.py +659 -0
  128. package/src/zexus/vm/bytecode.py +28 -1
  129. package/src/zexus/vm/bytecode_converter.py +26 -12
  130. package/src/zexus/vm/cabi.c +1985 -0
  131. package/src/zexus/vm/cabi.cpython-312-x86_64-linux-gnu.so +0 -0
  132. package/src/zexus/vm/cabi.h +127 -0
  133. package/src/zexus/vm/cache.py +557 -17
  134. package/src/zexus/vm/compiler.py +703 -5
  135. package/src/zexus/vm/fastops.c +15743 -0
  136. package/src/zexus/vm/fastops.cpython-312-x86_64-linux-gnu.so +0 -0
  137. package/src/zexus/vm/fastops.pyx +288 -0
  138. package/src/zexus/vm/gas_metering.py +50 -9
  139. package/src/zexus/vm/jit.py +83 -2
  140. package/src/zexus/vm/native_jit_backend.py +1816 -0
  141. package/src/zexus/vm/native_runtime.cpp +1388 -0
  142. package/src/zexus/vm/native_runtime.cpython-312-x86_64-linux-gnu.so +0 -0
  143. package/src/zexus/vm/optimizer.py +161 -11
  144. package/src/zexus/vm/parallel_vm.py +118 -42
  145. package/src/zexus/vm/peephole_optimizer.py +82 -4
  146. package/src/zexus/vm/profiler.py +38 -18
  147. package/src/zexus/vm/register_allocator.py +16 -5
  148. package/src/zexus/vm/register_vm.py +8 -5
  149. package/src/zexus/vm/vm.py +3411 -573
  150. package/src/zexus/vm/wasm_compiler.py +658 -0
  151. package/src/zexus/zexus_ast.py +63 -11
  152. package/src/zexus/zexus_token.py +13 -5
  153. package/src/zexus/zpm/installer.py +55 -15
  154. package/src/zexus/zpm/package_manager.py +1 -1
  155. package/src/zexus/zpm/registry.py +257 -28
  156. package/src/zexus.egg-info/PKG-INFO +7 -4
  157. package/src/zexus.egg-info/SOURCES.txt +116 -9
  158. package/src/zexus.egg-info/entry_points.txt +1 -0
  159. package/src/zexus.egg-info/requires.txt +4 -0
@@ -68,12 +68,13 @@ except ModuleNotFoundError: # Fallback to minimal console utilities when rich i
68
68
  from ..lexer import Lexer
69
69
  from ..parser import Parser
70
70
  # UPDATED: Import evaluate from evaluator package
71
- from ..evaluator import evaluate
71
+ from ..evaluator import evaluate, Evaluator
72
72
  # UPDATED: Import Environment and String from object module
73
73
  from ..object import Environment, String
74
74
  from ..syntax_validator import SyntaxValidator
75
75
  from ..hybrid_orchestrator import orchestrator
76
76
  from ..config import config
77
+ from ..runtime.file_flags import parse_file_flags, apply_vm_config
77
78
  # Import error handling
78
79
  from ..error_reporter import get_error_reporter, ZexusError, print_error
79
80
  # VM and Compiler for high-performance execution
@@ -92,6 +93,7 @@ def show_all_commands():
92
93
 
93
94
  commands = [
94
95
  ("zx run <file>", "Execute a Zexus program"),
96
+ ("zx -r \"<code>\"", "Run inline Zexus code (like python -c)"),
95
97
  ("zx run --zexus", "Show this command list"),
96
98
  ("zx check <file>", "Check syntax with detailed validation"),
97
99
  ("zx validate <file>", "Validate and auto-fix syntax errors"),
@@ -106,7 +108,9 @@ def show_all_commands():
106
108
  ("--syntax-style=<style>", "universal, tolerable, or auto (default)"),
107
109
  ("--execution-mode=<mode>", "interpreter, compiler, or auto (default)"),
108
110
  ("--advanced-parsing", "Enable multi-strategy parsing (default: on)"),
109
- ("--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"),
110
114
  ("--version", "Show Zexus version"),
111
115
  ("--help", "Show detailed help"),
112
116
  ("", ""),
@@ -122,6 +126,8 @@ def show_all_commands():
122
126
  ("zx check --debug program.zx", "Check syntax with debug info"),
123
127
  ("zx profile myapp.zx", "Profile with memory tracking"),
124
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"),
125
131
  ("", ""),
126
132
  ("[bold]Built-in Functions:[/bold]", "100+ functions available"),
127
133
  ("", "Memory: persist_set, persist_get, track_memory"),
@@ -150,54 +156,189 @@ def show_all_commands():
150
156
  console.print("\n[bold green]💡 Tip:[/bold green] Use 'zx <command> --help' for detailed command options\n")
151
157
 
152
158
  @click.group(invoke_without_command=True)
153
- @click.version_option(version="1.7.1", prog_name="Zexus")
159
+ @click.version_option(version="1.7.2", prog_name="Zexus")
154
160
  @click.option('--syntax-style', type=click.Choice(['universal', 'tolerable', 'auto']),
155
161
  default='auto', help='Syntax style to use (universal=strict, tolerable=flexible)')
156
162
  @click.option('--advanced-parsing', is_flag=True, default=True,
157
163
  help='Enable advanced multi-strategy parsing (recommended)')
158
164
  @click.option('--execution-mode', type=click.Choice(['interpreter', 'compiler', 'auto']),
159
165
  default='auto', help='Execution engine to use')
160
- @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')
161
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)')
162
172
  @click.pass_context
163
- 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):
164
174
  """Zexus Programming Language - Hybrid Interpreter/Compiler
165
175
 
166
176
  Use 'zx run --zexus' or 'zx --zexus' to see all available commands.
177
+ Use 'zx -r "<code>"' to execute inline Zexus code.
167
178
  """
168
179
 
169
180
  if zexus:
170
181
  show_all_commands()
171
182
  sys.exit(0)
172
183
 
173
- # If no command provided, show help
174
- if ctx.invoked_subcommand is None:
175
- click.echo(ctx.get_help())
176
- return
177
-
178
184
  ctx.ensure_object(dict)
179
185
  ctx.obj['SYNTAX_STYLE'] = syntax_style
180
186
  ctx.obj['ADVANCED_PARSING'] = advanced_parsing
181
187
  ctx.obj['EXECUTION_MODE'] = execution_mode
182
- ctx.obj['DEBUG'] = debug
188
+ ctx.obj['DEBUG'] = False
183
189
 
184
190
  # Update config based on CLI flags
185
- 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')
197
+ config.enable_debug_logs = True
198
+ ctx.obj['DEBUG'] = True
199
+ elif debug == 'minimal':
200
+ config.enable_debug('minimal')
186
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
187
213
  if execution_mode == 'compiler':
188
214
  config.use_hybrid_compiler = True
189
215
  elif execution_mode == 'interpreter':
190
216
  config.use_hybrid_compiler = False
191
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
+
192
331
  @cli.command()
193
332
  @click.argument('file', type=click.Path(exists=True))
194
333
  @click.argument('args', nargs=-1) # Accept any number of additional arguments
195
- @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)')
196
335
  @click.option('--vm-mode', type=click.Choice(['auto', 'stack', 'register', 'parallel']),
197
336
  default='auto', help='VM execution mode (auto=best performance)')
198
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')
199
340
  @click.pass_context
200
- 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):
201
342
  """Run a Zexus program with hybrid execution"""
202
343
  # Register source for error reporting
203
344
  error_reporter = get_error_reporter()
@@ -208,6 +349,37 @@ def run(ctx, file, args, use_vm, vm_mode, no_optimize):
208
349
 
209
350
  # Register source with error reporter
210
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]")
211
383
 
212
384
  syntax_style = ctx.obj['SYNTAX_STYLE']
213
385
  advanced_parsing = ctx.obj['ADVANCED_PARSING']
@@ -256,7 +428,36 @@ def run(ctx, file, args, use_vm, vm_mode, no_optimize):
256
428
  for error in parser.errors:
257
429
  console.print(f" ❌ {error}")
258
430
  sys.exit(1)
259
-
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
+
260
461
  # Use the evaluator package
261
462
  env = Environment()
262
463
 
@@ -287,6 +488,11 @@ def run(ctx, file, args, use_vm, vm_mode, no_optimize):
287
488
  env.set("__PACKAGE__", package_name)
288
489
 
289
490
  # Execute based on mode
491
+ if not use_vm:
492
+ try:
493
+ env.disable_vm = True
494
+ except Exception:
495
+ pass
290
496
  bytecode = None
291
497
  fallback_reason = None
292
498
 
@@ -313,20 +519,41 @@ def run(ctx, file, args, use_vm, vm_mode, no_optimize):
313
519
  fallback_reason = str(e)
314
520
 
315
521
  if bytecode is not None and fallback_reason is None:
316
- vm_mode_enum = {
522
+ vm_mode_map = {
317
523
  'auto': VMMode.AUTO,
318
524
  'stack': VMMode.STACK,
319
525
  'register': VMMode.REGISTER,
320
526
  'parallel': VMMode.PARALLEL
321
- }[vm_mode]
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 = {}
322
537
 
323
538
  console.print(f"[dim]Initializing VM ({vm_mode} mode)...[/dim]", end="")
324
539
  vm = VM(
325
540
  mode=vm_mode_enum,
326
541
  use_jit=not no_optimize,
327
542
  max_heap_mb=1000, # 1GB heap limit
328
- debug=ctx.obj.get('DEBUG', False)
543
+ debug=ctx.obj.get('DEBUG', False),
544
+ gas_limit=100000000 # 100M instructions for heavy checks
329
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
330
557
  console.print(" [green]done[/green]")
331
558
 
332
559
  console.print("[dim]Executing on VM...[/dim]")
@@ -341,10 +568,10 @@ def run(ctx, file, args, use_vm, vm_mode, no_optimize):
341
568
 
342
569
  if fallback_reason is not None:
343
570
  console.print("[bold yellow]🔄 Falling back to interpreter execution...[/bold yellow]")
344
- result = evaluate(program, env, debug_mode=ctx.obj['DEBUG'])
571
+ result = evaluate(program, env, debug_mode=ctx.obj['DEBUG'], use_vm=False)
345
572
  elif bytecode is None:
346
573
  # No bytecode generated but VM not requested or compile skipped
347
- result = evaluate(program, env, debug_mode=ctx.obj['DEBUG'])
574
+ result = evaluate(program, env, debug_mode=ctx.obj['DEBUG'], use_vm=False)
348
575
 
349
576
  if result and hasattr(result, 'inspect') and result.inspect() != 'null':
350
577
  console.print(f"\n✅ [bold green]Result:[/bold green] {result.inspect()}")
@@ -428,6 +655,59 @@ def check(ctx, file):
428
655
  console.print(f"[bold red]Error:[/bold red] {str(e)}")
429
656
  sys.exit(1)
430
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
+
431
711
  @cli.command()
432
712
  @click.argument('file', type=click.Path(exists=True))
433
713
  @click.pass_context
@@ -18,7 +18,7 @@ console = Console()
18
18
 
19
19
 
20
20
  @click.group()
21
- @click.version_option(version="1.7.1", 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
 
@@ -39,12 +39,17 @@ class Lexer:
39
39
  return self.input[self.read_position]
40
40
 
41
41
  def next_token(self):
42
- self.skip_whitespace()
42
+ # Avoid recursion: long files can contain thousands of consecutive
43
+ # comments/blank lines.
44
+ while True:
45
+ self.skip_whitespace()
46
+
47
+ # Skip single line comments
48
+ if self.ch == '#' and self.peek_char() != '{':
49
+ self.skip_comment()
50
+ continue
43
51
 
44
- # Skip single line comments
45
- if self.ch == '#' and self.peek_char() != '{':
46
- self.skip_comment()
47
- return self.next_token()
52
+ break
48
53
 
49
54
  tok = None
50
55
  current_line = self.line
@@ -468,6 +468,85 @@ class ConcurrencyManager:
468
468
  f"tasks={stats['tasks_completed']}/{stats['tasks_total']})")
469
469
 
470
470
 
471
+ # ---------------------------------------------------------------------------
472
+ # AsyncChannel — asyncio-native channel for the shared event loop
473
+ # ---------------------------------------------------------------------------
474
+
475
+ class AsyncChannel:
476
+ """
477
+ Async-native channel backed by :class:`asyncio.Queue`.
478
+
479
+ Unlike :class:`Channel` (which uses ``threading`` primitives), this
480
+ channel is designed to be used inside coroutines running on the shared
481
+ Zexus event loop. ``send`` and ``receive`` are ``async`` methods.
482
+
483
+ Example (inside a Zexus ``async action``)::
484
+
485
+ ch = AsyncChannel("numbers", capacity=10)
486
+ await ch.send(42)
487
+ val = await ch.receive() # 42
488
+ ch.close()
489
+ """
490
+
491
+ def __init__(self, name: str, element_type: Optional[str] = None,
492
+ capacity: int = 0):
493
+ self.name = name
494
+ self.element_type = element_type
495
+ self.capacity = capacity
496
+ self._closed = False
497
+
498
+ import asyncio as _asyncio
499
+ if capacity > 0:
500
+ self._queue: _asyncio.Queue = _asyncio.Queue(maxsize=capacity)
501
+ else:
502
+ self._queue = _asyncio.Queue()
503
+
504
+ @property
505
+ def is_open(self) -> bool:
506
+ return not self._closed
507
+
508
+ async def send(self, value, *, timeout: Optional[float] = None):
509
+ """Send *value* into the channel (async, may block if full)."""
510
+ if self._closed:
511
+ raise RuntimeError(f"Cannot send on closed async channel '{self.name}'")
512
+ import asyncio as _asyncio
513
+ if timeout is not None:
514
+ await _asyncio.wait_for(self._queue.put(value), timeout=timeout)
515
+ else:
516
+ await self._queue.put(value)
517
+
518
+ async def receive(self, *, timeout: Optional[float] = None):
519
+ """Receive a value from the channel (async, may block if empty)."""
520
+ if self._closed and self._queue.empty():
521
+ return None
522
+ import asyncio as _asyncio
523
+ try:
524
+ if timeout is not None:
525
+ value = await _asyncio.wait_for(self._queue.get(), timeout=timeout)
526
+ else:
527
+ value = await self._queue.get()
528
+ if isinstance(value, _ChannelClosedSentinel):
529
+ return None
530
+ return value
531
+ except _asyncio.TimeoutError:
532
+ if self._closed:
533
+ return None
534
+ raise RuntimeError(f"Timeout receiving from async channel '{self.name}'")
535
+
536
+ def close(self):
537
+ """Close the channel. Pending receivers will get ``None``."""
538
+ self._closed = True
539
+ try:
540
+ self._queue.put_nowait(_CHANNEL_CLOSED_SENTINEL)
541
+ except Exception:
542
+ pass
543
+
544
+ def __repr__(self) -> str:
545
+ mode = f"buffered({self.capacity})" if self.capacity > 0 else "unbuffered"
546
+ status = "closed" if self._closed else "open"
547
+ return f"AsyncChannel<{self.element_type}>({self.name}, {mode}, {status})"
548
+
549
+
471
550
  # Global singleton instance
472
551
  _concurrency_manager: Optional[ConcurrencyManager] = None
473
552
 
@@ -28,6 +28,11 @@ DEFAULT_RUNTIME = {
28
28
  'enable_advanced_parsing': True,
29
29
  'enable_debug_logs': False,
30
30
  'enable_parser_debug': False, # OPTIMIZATION: Disable parser debug output for speed
31
+ # Large-file stability: advanced parsing does extra analysis and can be
32
+ # significantly heavier on very large sources. For big files, we prefer the
33
+ # traditional streaming parser for stability.
34
+ 'advanced_parsing_max_lines': 2000,
35
+ 'advanced_parsing_max_tokens': 50000,
31
36
  # Legacy runtime flags expected by older modules
32
37
  'use_hybrid_compiler': True,
33
38
  'fallback_to_interpreter': True,
@@ -40,8 +45,15 @@ class Config:
40
45
  def __init__(self):
41
46
  self.config_dir = Path.home() / ".zexus"
42
47
  self.config_file = self.config_dir / "config.json"
48
+
49
+ # Fast caching attribute for hot paths
50
+ self.fast_debug_enabled = False
51
+
43
52
  self._data = DEFAULT_CONFIG.copy()
44
53
  self._ensure_loaded()
54
+
55
+ # Update cache from initial loaded data
56
+ self.fast_debug_enabled = (self.debug_level != 'none')
45
57
 
46
58
  # ensure runtime defaults exist for backward compatibility
47
59
  self._data.setdefault('runtime', {})
@@ -93,6 +105,7 @@ class Config:
93
105
  raise ValueError('Invalid debug level')
94
106
  self._data.setdefault('debug', {})['level'] = value
95
107
  self._data['debug']['enabled'] = (value != 'none')
108
+ self.fast_debug_enabled = (value != 'none')
96
109
  self._write()
97
110
 
98
111
  def enable_debug(self, level='full'):
@@ -143,6 +156,47 @@ class Config:
143
156
  self.debug_level = 'none'
144
157
 
145
158
  # Legacy runtime properties
159
+ @property
160
+ def enable_parser_debug(self):
161
+ return bool(self._data.get('runtime', {}).get('enable_parser_debug', False))
162
+
163
+ @enable_parser_debug.setter
164
+ def enable_parser_debug(self, value):
165
+ self._data.setdefault('runtime', {})['enable_parser_debug'] = bool(value)
166
+ self._write()
167
+
168
+ @property
169
+ def advanced_parsing_max_lines(self):
170
+ try:
171
+ return int(self._data.get('runtime', {}).get('advanced_parsing_max_lines', 2000))
172
+ except Exception:
173
+ return 2000
174
+
175
+ @advanced_parsing_max_lines.setter
176
+ def advanced_parsing_max_lines(self, value):
177
+ try:
178
+ v = int(value)
179
+ except Exception:
180
+ v = 2000
181
+ self._data.setdefault('runtime', {})['advanced_parsing_max_lines'] = v
182
+ self._write()
183
+
184
+ @property
185
+ def advanced_parsing_max_tokens(self):
186
+ try:
187
+ return int(self._data.get('runtime', {}).get('advanced_parsing_max_tokens', 50000))
188
+ except Exception:
189
+ return 50000
190
+
191
+ @advanced_parsing_max_tokens.setter
192
+ def advanced_parsing_max_tokens(self, value):
193
+ try:
194
+ v = int(value)
195
+ except Exception:
196
+ v = 50000
197
+ self._data.setdefault('runtime', {})['advanced_parsing_max_tokens'] = v
198
+ self._write()
199
+
146
200
  @property
147
201
  def use_hybrid_compiler(self):
148
202
  return self._data.get('runtime', {}).get('use_hybrid_compiler', True)