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
@@ -2,9 +2,11 @@
2
2
  import traceback
3
3
  import asyncio
4
4
  import os
5
+ import sys
5
6
  from .. import zexus_ast
6
- from ..object import Environment, EvaluationError, Null, Boolean as BooleanObj, Map, EmbeddedCode, List, Action, LambdaFunction, String, ReturnValue
7
+ from ..object import Environment, EvaluationError, Null, Boolean as BooleanObj, Map, EmbeddedCode, List, Action, LambdaFunction, String, ReturnValue, Builtin, Integer, Float
7
8
  from .utils import is_error, debug_log, EVAL_SUMMARY, NULL
9
+ from ..config import config as zexus_config
8
10
  from .expressions import ExpressionEvaluatorMixin
9
11
  from .statements import StatementEvaluatorMixin
10
12
  from .functions import FunctionEvaluatorMixin
@@ -27,6 +29,8 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
27
29
  def __init__(self, trusted: bool = False, use_vm: bool = True, resource_limiter=None):
28
30
  # Initialize mixins (FunctionEvaluatorMixin sets up builtins)
29
31
  FunctionEvaluatorMixin.__init__(self)
32
+
33
+ self._ensure_recursion_headroom()
30
34
 
31
35
  # Initialize 10-phase integration
32
36
  self.integration_context = EvaluationContext("evaluator")
@@ -72,9 +76,44 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
72
76
  if self.use_vm and VM_AVAILABLE:
73
77
  self._initialize_vm()
74
78
 
79
+ # ------------------------------------------------------------------
80
+ # Backward compatible entrypoints
81
+ # ------------------------------------------------------------------
82
+
83
+ def eval(self, program, env, *, debug_mode: bool = False, use_vm: bool | None = None):
84
+ """Evaluate an AST node, mirroring the legacy Evaluator API."""
85
+ previous_use_vm = self.use_vm
86
+ try:
87
+ if use_vm is not None:
88
+ self.use_vm = bool(use_vm) and VM_AVAILABLE
89
+
90
+ if debug_mode and hasattr(env, "enable_debug"):
91
+ env.enable_debug()
92
+
93
+ return self.eval_with_vm_support(program, env, debug_mode=debug_mode)
94
+ finally:
95
+ if debug_mode and hasattr(env, "disable_debug"):
96
+ env.disable_debug()
97
+ self.use_vm = previous_use_vm
98
+
99
+ def _ensure_recursion_headroom(self, minimum: int = 5000):
100
+ """Ensure Python's recursion limit can accommodate deep language recursion."""
101
+ try:
102
+ current = sys.getrecursionlimit()
103
+ if current < minimum:
104
+ sys.setrecursionlimit(minimum)
105
+ except Exception:
106
+ pass
107
+
75
108
  def _initialize_dispatch_table(self):
76
- """Precompute handlers for hot node types to reduce isinstance overhead."""
109
+ """Precompute handlers for ALL node types to eliminate isinstance overhead.
110
+
111
+ Every AST node type gets an O(1) dict lookup instead of walking
112
+ a ~117-branch isinstance chain. This yields ~28%+ faster evaluation
113
+ on typical programs.
114
+ """
77
115
  try:
116
+ # Core hot-path nodes with dedicated handler methods
78
117
  self._node_handlers = {
79
118
  zexus_ast.Program: self._handle_program_node,
80
119
  zexus_ast.ExpressionStatement: self._handle_expression_statement,
@@ -95,9 +134,120 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
95
134
  zexus_ast.InfixExpression: self._handle_infix_expression,
96
135
  zexus_ast.PrefixExpression: self._handle_prefix_expression,
97
136
  zexus_ast.CallExpression: self._handle_call_expression,
137
+ zexus_ast.PropertyAccessExpression: self._handle_property_access_expression,
98
138
  zexus_ast.MethodCallExpression: self._handle_method_call_expression,
99
139
  zexus_ast.ListLiteral: self._handle_list_literal,
140
+ zexus_ast.StringLiteral: self._handle_string_literal,
141
+ zexus_ast.StringInterpolationExpression: self._handle_string_interpolation,
142
+ zexus_ast.FloatLiteral: self._handle_float_literal,
143
+ zexus_ast.MapLiteral: self._handle_map_literal,
144
+ zexus_ast.LambdaExpression: self._handle_lambda_expression,
145
+ zexus_ast.ActionLiteral: self._handle_action_literal,
146
+ zexus_ast.ForEachStatement: self._handle_foreach_statement,
147
+ zexus_ast.PrintStatement: self._handle_print_statement,
148
+ zexus_ast.DataStatement: self._handle_data_statement,
149
+ zexus_ast.TryCatchStatement: self._handle_try_catch_statement,
150
+ zexus_ast.ThrowStatement: self._handle_throw_statement,
151
+ zexus_ast.ContractStatement: self._handle_contract_statement,
152
+ zexus_ast.ExportStatement: self._handle_export_statement,
153
+ zexus_ast.UseStatement: self._handle_use_statement,
154
+ zexus_ast.FromStatement: self._handle_from_statement,
155
+ zexus_ast.IfExpression: self._handle_if_expression,
156
+ zexus_ast.TernaryExpression: self._handle_ternary_expression,
157
+ zexus_ast.ContinueStatement: self._handle_continue_statement,
158
+ zexus_ast.BreakStatement: self._handle_break_statement,
159
+ }
160
+
161
+ # Extend with ALL remaining node types — each delegates to its
162
+ # corresponding eval_* method, eliminating the isinstance fallback.
163
+ _extended_dispatch = {
164
+ # Security statements
165
+ zexus_ast.SealStatement: 'eval_seal_statement',
166
+ zexus_ast.RestrictStatement: 'eval_restrict_statement',
167
+ zexus_ast.SandboxStatement: 'eval_sandbox_statement',
168
+ zexus_ast.TrailStatement: 'eval_trail_statement',
169
+ zexus_ast.CapabilityStatement: 'eval_capability_statement',
170
+ zexus_ast.GrantStatement: 'eval_grant_statement',
171
+ zexus_ast.RevokeStatement: 'eval_revoke_statement',
172
+ zexus_ast.ValidateStatement: 'eval_validate_statement',
173
+ zexus_ast.SanitizeStatement: 'eval_sanitize_statement',
174
+ zexus_ast.InjectStatement: 'eval_inject_statement',
175
+ zexus_ast.ImmutableStatement: 'eval_immutable_statement',
176
+ zexus_ast.ProtectStatement: 'eval_protect_statement',
177
+ zexus_ast.VerifyStatement: 'eval_verify_statement',
178
+ # Blockchain / state
179
+ zexus_ast.TxStatement: 'eval_tx_statement',
180
+ zexus_ast.EntityStatement: 'eval_entity_statement',
181
+ zexus_ast.LedgerStatement: 'eval_ledger_statement',
182
+ zexus_ast.StateStatement: 'eval_state_statement',
183
+ zexus_ast.RequireStatement: 'eval_require_statement',
184
+ zexus_ast.RevertStatement: 'eval_revert_statement',
185
+ zexus_ast.LimitStatement: 'eval_limit_statement',
186
+ zexus_ast.ProtocolStatement: 'eval_protocol_statement',
187
+ zexus_ast.PersistentStatement: 'eval_persistent_statement',
188
+ zexus_ast.EmitStatement: 'eval_emit_statement',
189
+ zexus_ast.ModifierDeclaration: 'eval_modifier_declaration',
190
+ # UI
191
+ zexus_ast.ScreenStatement: 'eval_screen_statement',
192
+ zexus_ast.ColorStatement: 'eval_color_statement',
193
+ zexus_ast.CanvasStatement: 'eval_canvas_statement',
194
+ zexus_ast.GraphicsStatement: 'eval_graphics_statement',
195
+ zexus_ast.AnimationStatement: 'eval_animation_statement',
196
+ zexus_ast.ClockStatement: 'eval_clock_statement',
197
+ zexus_ast.ComponentStatement: 'eval_component_statement',
198
+ zexus_ast.ThemeStatement: 'eval_theme_statement',
199
+ # Concurrency
200
+ zexus_ast.ChannelStatement: 'eval_channel_statement',
201
+ zexus_ast.SendStatement: 'eval_send_statement',
202
+ zexus_ast.ReceiveStatement: 'eval_receive_statement',
203
+ zexus_ast.AtomicStatement: 'eval_atomic_statement',
204
+ # Language features
205
+ zexus_ast.WatchStatement: 'eval_watch_statement',
206
+ zexus_ast.DeferStatement: 'eval_defer_statement',
207
+ zexus_ast.PatternStatement: 'eval_pattern_statement',
208
+ zexus_ast.EnumStatement: 'eval_enum_statement',
209
+ zexus_ast.StreamStatement: 'eval_stream_statement',
210
+ zexus_ast.DebugStatement: 'eval_debug_statement',
211
+ zexus_ast.LogStatement: 'eval_log_statement',
212
+ zexus_ast.ImportLogStatement: 'eval_import_log_statement',
213
+ zexus_ast.ExternalDeclaration: 'eval_external_declaration',
214
+ zexus_ast.ExactlyStatement: 'eval_exactly_statement',
215
+ zexus_ast.NativeStatement: 'eval_native_statement',
216
+ zexus_ast.GCStatement: 'eval_gc_statement',
217
+ zexus_ast.InlineStatement: 'eval_inline_statement',
218
+ zexus_ast.BufferStatement: 'eval_buffer_statement',
219
+ zexus_ast.SIMDStatement: 'eval_simd_statement',
220
+ zexus_ast.EmbeddedCodeStatement: 'eval_embedded_code_statement',
221
+ zexus_ast.MiddlewareStatement: 'eval_middleware_statement',
222
+ zexus_ast.AuthStatement: 'eval_auth_statement',
223
+ zexus_ast.ThrottleStatement: 'eval_throttle_statement',
224
+ zexus_ast.CacheStatement: 'eval_cache_statement',
225
+ zexus_ast.InterfaceStatement: 'eval_interface_statement',
226
+ zexus_ast.TypeAliasStatement: 'eval_type_alias_statement',
227
+ zexus_ast.ModuleStatement: 'eval_module_statement',
228
+ zexus_ast.PackageStatement: 'eval_package_statement',
229
+ zexus_ast.UsingStatement: 'eval_using_statement',
230
+ # Expressions
231
+ zexus_ast.MatchExpression: 'eval_match_expression',
232
+ zexus_ast.AwaitExpression: 'eval_await_expression',
233
+ zexus_ast.AsyncExpression: 'eval_async_expression',
234
+ zexus_ast.FindExpression: 'eval_find_expression',
235
+ zexus_ast.LoadExpression: 'eval_load_expression',
236
+ zexus_ast.FileImportExpression: 'eval_file_import_expression',
237
+ zexus_ast.NullishExpression: 'eval_nullish_expression',
238
+ zexus_ast.SliceExpression: 'eval_slice_expression',
239
+ zexus_ast.EmbeddedLiteral: 'eval_embedded_literal',
240
+ zexus_ast.TXExpression: 'eval_tx_expression',
241
+ zexus_ast.HashExpression: 'eval_hash_expression',
242
+ zexus_ast.SignatureExpression: 'eval_signature_expression',
243
+ zexus_ast.VerifySignatureExpression: 'eval_verify_signature_expression',
244
+ zexus_ast.GasExpression: 'eval_gas_expression',
100
245
  }
246
+ for ast_type, method_name in _extended_dispatch.items():
247
+ method = getattr(self, method_name, None)
248
+ if method:
249
+ self._node_handlers[ast_type] = lambda node, env, st, m=method: m(node, env, st)
250
+
101
251
  except AttributeError:
102
252
  # AST variants may omit certain nodes; keep table empty in that case
103
253
  self._node_handlers = {}
@@ -142,24 +292,18 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
142
292
 
143
293
  def _handle_function_statement(self, node, env, stack_trace):
144
294
  debug_log(" FunctionStatement node", f"function {node.name.value}")
145
- print(f"[CORE] Evaluating FunctionStatement: {node.name.value}, modifiers: {getattr(node, 'modifiers', [])}", flush=True)
146
- result = self.eval_function_statement(node, env, stack_trace)
147
- print(f"[CORE] FunctionStatement result: {result}", flush=True)
148
- return result
295
+ debug_log(" FunctionStatement evaluate", f"{node.name.value} modifiers={getattr(node, 'modifiers', [])}")
296
+ return self.eval_function_statement(node, env, stack_trace)
149
297
 
150
298
  def _handle_identifier(self, node, env, stack_trace):
151
299
  debug_log(" Identifier node", node.value)
152
300
  return self.eval_identifier(node, env)
153
301
 
154
302
  def _handle_integer_literal(self, node, env, stack_trace):
155
- debug_log(" IntegerLiteral node", node.value)
156
- from ..object import Integer
157
303
  return Integer(node.value)
158
304
 
159
305
  def _handle_boolean_literal(self, node, env, stack_trace):
160
- debug_log(" Boolean node", f"value: {node.value}")
161
- from ..object import Boolean
162
- return Boolean(node.value)
306
+ return BooleanObj(node.value)
163
307
 
164
308
  def _handle_null_literal(self, node, env, stack_trace):
165
309
  debug_log(" NullLiteral node")
@@ -181,43 +325,182 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
181
325
  debug_log("🚀 CallExpression node", f"Calling {node.function}")
182
326
  return self.eval_call_expression(node, env, stack_trace)
183
327
 
328
+ def _handle_property_access_expression(self, node, env, stack_trace):
329
+ debug_log(" PropertyAccessExpression node")
330
+ return self.eval_property_access_expression(node, env, stack_trace)
331
+
184
332
  def _handle_method_call_expression(self, node, env, stack_trace):
185
333
  debug_log(" MethodCallExpression node", f"{node.object}.{node.method}")
186
334
  return self.eval_method_call_expression(node, env, stack_trace)
187
335
 
188
336
  def _handle_list_literal(self, node, env, stack_trace):
189
- debug_log(" ListLiteral node", f"{len(node.elements)} elements")
190
337
  elems = self.eval_expressions(node.elements, env)
191
338
  if is_error(elems):
192
339
  return elems
193
340
  return List(elems)
194
-
341
+
342
+ # --- VM statement wrappers (moved out of eval_node for performance) ---
343
+
344
+ @staticmethod
345
+ def _wrap_vm_statement(statement, expected_type):
346
+ if isinstance(statement, expected_type):
347
+ return statement
348
+ if isinstance(statement, dict):
349
+ try:
350
+ if expected_type is zexus_ast.GCStatement:
351
+ return zexus_ast.GCStatement(statement.get("action"))
352
+ if expected_type is zexus_ast.InlineStatement:
353
+ return zexus_ast.InlineStatement(statement.get("function_name") or statement.get("name"))
354
+ if expected_type is zexus_ast.DeferStatement:
355
+ return zexus_ast.DeferStatement(statement.get("code"))
356
+ if expected_type is zexus_ast.NativeStatement:
357
+ return zexus_ast.NativeStatement(
358
+ statement.get("library_name") or statement.get("library"),
359
+ statement.get("function_name") or statement.get("function"),
360
+ args=statement.get("args"),
361
+ alias=statement.get("alias")
362
+ )
363
+ if expected_type is zexus_ast.BufferStatement:
364
+ return zexus_ast.BufferStatement(
365
+ statement.get("buffer_name") or statement.get("name"),
366
+ statement.get("operation"),
367
+ statement.get("arguments"),
368
+ )
369
+ if expected_type is zexus_ast.SIMDStatement:
370
+ return zexus_ast.SIMDStatement(
371
+ statement.get("operation"),
372
+ operands=statement.get("operands")
373
+ )
374
+ if expected_type is zexus_ast.PatternStatement:
375
+ return zexus_ast.PatternStatement(
376
+ statement.get("expression"),
377
+ statement.get("cases") or []
378
+ )
379
+ except Exception as exc:
380
+ return EvaluationError(str(exc))
381
+ return EvaluationError(f"Invalid payload for {expected_type.__name__}")
382
+
383
+ # --- Extended dispatch handlers (avoid isinstance chain) ---
384
+
385
+ def _handle_string_literal(self, node, env, stack_trace):
386
+ value = node.value
387
+ value = value.replace('\\n', '\n')
388
+ value = value.replace('\\t', '\t')
389
+ value = value.replace('\\r', '\r')
390
+ value = value.replace('\\\\', '\\')
391
+ value = value.replace('\\"', '"')
392
+ value = value.replace("\\'", "'")
393
+ return String(value, is_trusted=True)
394
+
395
+ def _handle_string_interpolation(self, node, env, stack_trace):
396
+ """Evaluate string interpolation: "hello ${name}" """
397
+ result_parts = []
398
+ for part_type, part_value in node.parts:
399
+ if part_type == "str":
400
+ result_parts.append(part_value)
401
+ elif part_type == "expr":
402
+ val = self.eval_node(part_value, env, stack_trace)
403
+ if is_error(val):
404
+ return val
405
+ if hasattr(val, 'value'):
406
+ result_parts.append(str(val.value))
407
+ elif val is None:
408
+ result_parts.append("null")
409
+ else:
410
+ result_parts.append(str(val))
411
+ return String(''.join(result_parts))
412
+
413
+ def _handle_float_literal(self, node, env, stack_trace):
414
+ try:
415
+ return Float(node.value)
416
+ except Exception:
417
+ return EvaluationError(f"Invalid float literal: {getattr(node, 'value', None)}")
418
+
419
+ def _handle_map_literal(self, node, env, stack_trace):
420
+ pairs = {}
421
+ for k, v in node.pairs:
422
+ if isinstance(k, zexus_ast.Identifier):
423
+ key_str = k.value
424
+ else:
425
+ key = self.eval_node(k, env, stack_trace)
426
+ if is_error(key):
427
+ return key
428
+ key_str = key.inspect()
429
+ val = self.eval_node(v, env, stack_trace)
430
+ if is_error(val):
431
+ return val
432
+ pairs[key_str] = val
433
+ return Map(pairs)
434
+
435
+ def _handle_lambda_expression(self, node, env, stack_trace):
436
+ return LambdaFunction(node.parameters, node.body, env)
437
+
438
+ def _handle_action_literal(self, node, env, stack_trace):
439
+ return Action(node.parameters, node.body, env)
440
+
441
+ def _handle_foreach_statement(self, node, env, stack_trace):
442
+ return self.eval_foreach_statement(node, env, stack_trace)
443
+
444
+ def _handle_print_statement(self, node, env, stack_trace):
445
+ return self.eval_print_statement(node, env, stack_trace)
446
+
447
+ def _handle_data_statement(self, node, env, stack_trace):
448
+ return self.eval_data_statement(node, env, stack_trace)
449
+
450
+ def _handle_try_catch_statement(self, node, env, stack_trace):
451
+ return self.eval_try_catch_statement(node, env, stack_trace)
452
+
453
+ def _handle_throw_statement(self, node, env, stack_trace):
454
+ return self.eval_throw_statement(node, env, stack_trace)
455
+
456
+ def _handle_contract_statement(self, node, env, stack_trace):
457
+ return self.eval_contract_statement(node, env, stack_trace)
458
+
459
+ def _handle_export_statement(self, node, env, stack_trace):
460
+ return self.eval_export_statement(node, env, stack_trace)
461
+
462
+ def _handle_use_statement(self, node, env, stack_trace):
463
+ return self.eval_use_statement(node, env, stack_trace)
464
+
465
+ def _handle_from_statement(self, node, env, stack_trace):
466
+ return self.eval_from_statement(node, env, stack_trace)
467
+
468
+ def _handle_if_expression(self, node, env, stack_trace):
469
+ return self.eval_if_expression(node, env, stack_trace)
470
+
471
+ def _handle_ternary_expression(self, node, env, stack_trace):
472
+ return self.eval_ternary_expression(node, env, stack_trace)
473
+
474
+ def _handle_continue_statement(self, node, env, stack_trace):
475
+ return self.eval_continue_statement(node, env, stack_trace)
476
+
477
+ def _handle_break_statement(self, node, env, stack_trace):
478
+ return self.eval_break_statement(node, env, stack_trace)
479
+
195
480
  def eval_node(self, node, env, stack_trace=None):
196
481
  if node is None:
197
- debug_log("eval_node", "Node is None, returning NULL")
198
482
  return NULL
199
-
200
- stack_trace = stack_trace or []
483
+
484
+ # DAP debug hook — check breakpoints / stepping before dispatch
485
+ _dbg = getattr(self, "_debug_engine", None)
486
+ if _dbg is not None and hasattr(node, "__class__"):
487
+ _line = getattr(node, "line", None) or getattr(node, "token_line", 0)
488
+ if _line:
489
+ _file = getattr(self, "_debug_file", "<unknown>")
490
+ _dbg.check(_file, _line, env)
491
+
201
492
  node_type = type(node)
202
-
203
- # Add to stack trace for better error reporting
204
- current_frame = f" at {node_type.__name__}"
205
- if hasattr(node, 'token') and node.token:
206
- current_frame += f" (line {node.token.line})"
207
- stack_trace.append(current_frame)
208
-
209
- debug_log("eval_node", f"Processing {node_type.__name__}")
210
493
 
211
494
  handler = self._node_handlers.get(node_type)
212
495
  if handler:
213
496
  return handler(node, env, stack_trace)
214
-
497
+
215
498
  try:
216
499
  # === STATEMENTS ===
217
500
  if isinstance(node, zexus_ast.Program):
218
501
  debug_log(" Program node", f"{len(node.statements)} statements")
219
502
  return self.ceval_program(node.statements, env)
220
-
503
+
221
504
  elif isinstance(node, zexus_ast.ExpressionStatement):
222
505
  debug_log(" ExpressionStatement node")
223
506
  return self.eval_node(node.expression, env, stack_trace)
@@ -335,6 +618,26 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
335
618
  elif isinstance(node, zexus_ast.EmbeddedCodeStatement):
336
619
  debug_log(" EmbeddedCodeStatement node", node.name.value)
337
620
  return self.eval_embedded_code_statement(node, env, stack_trace)
621
+
622
+ elif isinstance(node, zexus_ast.ColorStatement):
623
+ debug_log(" ColorStatement node", node.name.value)
624
+ return self.eval_color_statement(node, env, stack_trace)
625
+
626
+ elif isinstance(node, zexus_ast.CanvasStatement):
627
+ debug_log(" CanvasStatement node", node.name.value)
628
+ return self.eval_canvas_statement(node, env, stack_trace)
629
+
630
+ elif isinstance(node, zexus_ast.GraphicsStatement):
631
+ debug_log(" GraphicsStatement node", node.name.value)
632
+ return self.eval_graphics_statement(node, env, stack_trace)
633
+
634
+ elif isinstance(node, zexus_ast.AnimationStatement):
635
+ debug_log(" AnimationStatement node", node.name.value)
636
+ return self.eval_animation_statement(node, env, stack_trace)
637
+
638
+ elif isinstance(node, zexus_ast.ClockStatement):
639
+ debug_log(" ClockStatement node", node.name.value)
640
+ return self.eval_clock_statement(node, env, stack_trace)
338
641
 
339
642
  elif isinstance(node, zexus_ast.ComponentStatement):
340
643
  debug_log(" ComponentStatement node", node.name.value)
@@ -362,10 +665,8 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
362
665
 
363
666
  elif isinstance(node, zexus_ast.FunctionStatement):
364
667
  debug_log(" FunctionStatement node", f"function {node.name.value}")
365
- print(f"[CORE] Evaluating FunctionStatement: {node.name.value}, modifiers: {getattr(node, 'modifiers', [])}", flush=True)
366
- result = self.eval_function_statement(node, env, stack_trace)
367
- print(f"[CORE] FunctionStatement result: {result}", flush=True)
368
- return result
668
+ debug_log(" FunctionStatement evaluate", f"{node.name.value} modifiers={getattr(node, 'modifiers', [])}")
669
+ return self.eval_function_statement(node, env, stack_trace)
369
670
 
370
671
  elif isinstance(node, zexus_ast.NativeStatement):
371
672
  debug_log(" NativeStatement node", f"native {node.function_name}")
@@ -527,12 +828,10 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
527
828
 
528
829
  elif isinstance(node, zexus_ast.IntegerLiteral):
529
830
  debug_log(" IntegerLiteral node", node.value)
530
- from ..object import Integer
531
831
  return Integer(node.value)
532
832
 
533
833
  elif node_type == zexus_ast.FloatLiteral or isinstance(node, zexus_ast.FloatLiteral):
534
834
  debug_log(" FloatLiteral node", getattr(node, 'value', 'unknown'))
535
- from ..object import Float
536
835
  try:
537
836
  val = getattr(node, 'value', None)
538
837
  return Float(val)
@@ -541,7 +840,6 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
541
840
 
542
841
  elif isinstance(node, zexus_ast.StringLiteral):
543
842
  debug_log(" StringLiteral node", node.value)
544
- from ..object import String
545
843
  # Process escape sequences in the string
546
844
  value = node.value
547
845
  value = value.replace('\\n', '\n')
@@ -553,10 +851,12 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
553
851
  # String literals are trusted (not from external input)
554
852
  return String(value, is_trusted=True)
555
853
 
854
+ elif isinstance(node, zexus_ast.StringInterpolationExpression):
855
+ return self._handle_string_interpolation(node, env, stack_trace)
856
+
556
857
  elif isinstance(node, zexus_ast.Boolean):
557
858
  debug_log(" Boolean node", f"value: {node.value}")
558
- from ..object import Boolean
559
- return Boolean(node.value)
859
+ return BooleanObj(node.value)
560
860
 
561
861
  elif isinstance(node, zexus_ast.NullLiteral):
562
862
  debug_log(" NullLiteral node")
@@ -590,6 +890,14 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
590
890
  debug_log(" AwaitExpression node")
591
891
  return self.eval_await_expression(node, env, stack_trace)
592
892
 
893
+ elif isinstance(node, zexus_ast.FindExpression):
894
+ debug_log(" FindExpression node")
895
+ return self.eval_find_expression(node, env, stack_trace)
896
+
897
+ elif isinstance(node, zexus_ast.LoadExpression):
898
+ debug_log(" LoadExpression node")
899
+ return self.eval_load_expression(node, env, stack_trace)
900
+
593
901
  elif isinstance(node, zexus_ast.FileImportExpression):
594
902
  debug_log(" FileImportExpression node", "<< file import")
595
903
  return self.eval_file_import_expression(node, env, stack_trace)
@@ -694,22 +1002,23 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
694
1002
  restriction = None
695
1003
 
696
1004
  # Handle Builtin objects (for static methods like TypeName.default())
697
- from ..object import Builtin
698
1005
  if isinstance(obj, Builtin):
699
1006
  if hasattr(obj, 'static_methods') and property_name in obj.static_methods:
700
1007
  return obj.static_methods[property_name]
701
1008
  return NULL
702
1009
 
703
1010
  # Handle Module objects
704
- from ..complexity_system import Module
705
- if isinstance(obj, Module):
1011
+ try:
1012
+ from ..complexity_system import Module as _Module
1013
+ except ImportError:
1014
+ _Module = None
1015
+ if _Module is not None and isinstance(obj, _Module):
706
1016
  val = obj.get(property_name)
707
1017
  if val is None:
708
1018
  return NULL
709
1019
  if restriction:
710
1020
  rule = restriction.get('restriction')
711
1021
  if rule == 'redact':
712
- from ..object import String
713
1022
  return String('***REDACTED***')
714
1023
  if rule == 'admin-only':
715
1024
  is_admin = bool(env.get('__is_admin__')) if env and hasattr(env, 'get') else False
@@ -719,8 +1028,6 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
719
1028
 
720
1029
  # Handle Map objects
721
1030
  if isinstance(obj, Map):
722
- from ..object import String
723
-
724
1031
  # Try string key first
725
1032
  val = obj.pairs.get(property_name, NULL)
726
1033
  if val == NULL:
@@ -752,7 +1059,6 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
752
1059
  if restriction:
753
1060
  rule = restriction.get('restriction')
754
1061
  if rule == 'redact':
755
- from ..object import String
756
1062
  return String('***REDACTED***')
757
1063
  if rule == 'admin-only':
758
1064
  # check environment flag for admin
@@ -769,7 +1075,6 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
769
1075
  if restriction:
770
1076
  rule = restriction.get('restriction')
771
1077
  if rule == 'redact':
772
- from ..object import String
773
1078
  return String('***REDACTED***')
774
1079
  if rule == 'admin-only':
775
1080
  is_admin = bool(env.get('__is_admin__')) if env and hasattr(env, 'get') else False
@@ -782,7 +1087,6 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
782
1087
  if restriction:
783
1088
  rule = restriction.get('restriction')
784
1089
  if rule == 'redact':
785
- from ..object import String
786
1090
  return String('***REDACTED***')
787
1091
  if rule == 'admin-only':
788
1092
  is_admin = bool(env.get('__is_admin__')) if env and hasattr(env, 'get') else False
@@ -790,6 +1094,35 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
790
1094
  return EvaluationError('Access denied: admin required')
791
1095
  return val
792
1096
 
1097
+ elif isinstance(node, zexus_ast.SliceExpression):
1098
+ debug_log(" SliceExpression node", f"{node.object}[{node.start}:{node.end}]")
1099
+ obj = self.eval_node(node.object, env, stack_trace)
1100
+ if is_error(obj):
1101
+ return obj
1102
+
1103
+ start_val = None
1104
+ end_val = None
1105
+ if node.start is not None:
1106
+ start_val = self.eval_node(node.start, env, stack_trace)
1107
+ if is_error(start_val):
1108
+ return start_val
1109
+ start_val = start_val.value if hasattr(start_val, 'value') else start_val
1110
+ if node.end is not None:
1111
+ end_val = self.eval_node(node.end, env, stack_trace)
1112
+ if is_error(end_val):
1113
+ return end_val
1114
+ end_val = end_val.value if hasattr(end_val, 'value') else end_val
1115
+
1116
+ if isinstance(obj, List):
1117
+ return List(obj.elements[start_val:end_val])
1118
+ if isinstance(obj, String):
1119
+ return String(obj.value[start_val:end_val])
1120
+ if isinstance(obj, list):
1121
+ return obj[start_val:end_val]
1122
+ if isinstance(obj, str):
1123
+ return obj[start_val:end_val]
1124
+ return NULL
1125
+
793
1126
  return NULL
794
1127
 
795
1128
  # === BLOCKCHAIN EXPRESSIONS ===
@@ -860,10 +1193,11 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
860
1193
  # Use external heuristics
861
1194
  return should_use_vm_for_node(node)
862
1195
 
863
- def _execute_via_vm(self, node, env, debug_mode=False):
1196
+ def _execute_via_vm(self, node, env, debug_mode=False, file_path=None):
864
1197
  """
865
1198
  Compile node to bytecode and execute via VM.
866
1199
  Falls back to direct evaluation on error.
1200
+ Stores compiled bytecode in file cache if file_path is provided.
867
1201
  """
868
1202
  try:
869
1203
  debug_log("VM Execution", f"Compiling {type(node).__name__} to bytecode")
@@ -873,11 +1207,21 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
873
1207
 
874
1208
  if bytecode is None or self.bytecode_compiler.errors:
875
1209
  debug_log("VM Execution", f"Compilation failed: {self.bytecode_compiler.errors}")
1210
+ if os.environ.get("ZEXUS_VM_FALLBACK_DEBUG"):
1211
+ print(
1212
+ "[VM FALLBACK] compile_failed "
1213
+ f"node={type(node).__name__} file={file_path} "
1214
+ f"errors={self.bytecode_compiler.errors}"
1215
+ )
876
1216
  self.vm_stats['vm_fallbacks'] += 1
877
1217
  return None # Signal fallback
878
1218
 
879
1219
  self.vm_stats['bytecode_compiles'] += 1
880
1220
 
1221
+ # Store in file cache for faster repeat runs
1222
+ if file_path and self.bytecode_compiler.cache:
1223
+ self.bytecode_compiler.cache.put_by_file(file_path, [bytecode])
1224
+
881
1225
  # Convert environment to dict for VM
882
1226
  vm_env = self._env_to_dict(env)
883
1227
 
@@ -885,6 +1229,8 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
885
1229
  vm_builtins = {}
886
1230
  if hasattr(self, 'builtins') and self.builtins:
887
1231
  vm_builtins = {k: v for k, v in self.builtins.items()}
1232
+
1233
+ vm_builtins.update(self._create_vm_keyword_builtins(env))
888
1234
 
889
1235
  # Use shared VM instance (has JIT, optimizer, etc.)
890
1236
  if not self.vm_instance:
@@ -913,9 +1259,212 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
913
1259
 
914
1260
  except Exception as e:
915
1261
  debug_log("VM Execution", f"VM execution error: {e}")
1262
+ if os.environ.get("ZEXUS_VM_FALLBACK_DEBUG"):
1263
+ print(
1264
+ "[VM FALLBACK] execute_failed "
1265
+ f"node={type(node).__name__} file={file_path} error={e}"
1266
+ )
916
1267
  self.vm_stats['vm_fallbacks'] += 1
917
1268
  return None # Signal fallback
1269
+
1270
+ def _execute_bytecode_sequence(self, bytecodes, env, debug_mode=False):
1271
+ """Execute a sequence of bytecode objects in the VM for cached file runs."""
1272
+ try:
1273
+ if not bytecodes:
1274
+ return None
1275
+
1276
+ # Convert environment to dict for VM
1277
+ vm_env = self._env_to_dict(env)
1278
+
1279
+ # Add builtins to VM environment
1280
+ vm_builtins = {}
1281
+ if hasattr(self, 'builtins') and self.builtins:
1282
+ vm_builtins = {k: v for k, v in self.builtins.items()}
1283
+ vm_builtins.update(self._create_vm_keyword_builtins(env))
1284
+
1285
+ if not self.vm_instance:
1286
+ self.vm_instance = VM(use_jit=True, jit_threshold=100)
1287
+
1288
+ self.vm_instance.builtins = vm_builtins
1289
+ self.vm_instance.env = vm_env
1290
+
1291
+ result = None
1292
+ for bc in bytecodes:
1293
+ if bc is None:
1294
+ continue
1295
+ result = self.vm_instance.execute(bc, debug=debug_mode)
1296
+
1297
+ self.vm_stats['vm_executions'] += 1
1298
+ self._update_env_from_dict(env, self.vm_instance.env)
1299
+ return self._vm_result_to_evaluator(result)
1300
+ except Exception as e:
1301
+ debug_log("VM Execution", f"VM cached execution error: {e}")
1302
+ if os.environ.get("ZEXUS_VM_FALLBACK_DEBUG"):
1303
+ print(f"[VM FALLBACK] cached_execute_failed error={e}")
1304
+ self.vm_stats['vm_fallbacks'] += 1
1305
+ return None
918
1306
 
1307
+ def _create_vm_keyword_builtins(self, env):
1308
+ """Expose keyword helpers to the VM so bytecode can reuse evaluator logic"""
1309
+ def _vm_find(node_ref):
1310
+ return self.eval_find_expression(node_ref, env, stack_trace=[])
1311
+
1312
+ def _vm_load(node_ref):
1313
+ return self.eval_load_expression(node_ref, env, stack_trace=[])
1314
+
1315
+ def _vm_use_module(spec):
1316
+ if spec is None:
1317
+ return NULL
1318
+ try:
1319
+ from .. import zexus_ast
1320
+
1321
+ file_path = spec.get("file", "") if isinstance(spec, dict) else ""
1322
+ alias_raw = spec.get("alias") if isinstance(spec, dict) else None
1323
+ names_raw = spec.get("names") if isinstance(spec, dict) else []
1324
+ is_named = bool(spec.get("is_named")) if isinstance(spec, dict) else False
1325
+
1326
+ alias_node = zexus_ast.Identifier(alias_raw) if alias_raw else None
1327
+ name_nodes = []
1328
+ if isinstance(names_raw, list):
1329
+ for name in names_raw:
1330
+ if name:
1331
+ name_nodes.append(zexus_ast.Identifier(name))
1332
+
1333
+ use_node = zexus_ast.UseStatement(
1334
+ file_path,
1335
+ alias=alias_node,
1336
+ names=name_nodes,
1337
+ is_named_import=is_named
1338
+ )
1339
+ return self.eval_use_statement(use_node, env, stack_trace=[])
1340
+ except Exception as exc:
1341
+ return EvaluationError(str(exc))
1342
+
1343
+ def _vm_from_module(spec):
1344
+ if spec is None:
1345
+ return NULL
1346
+ try:
1347
+ from .. import zexus_ast
1348
+
1349
+ file_path = spec.get("file", "") if isinstance(spec, dict) else ""
1350
+ raw_imports = spec.get("imports") if isinstance(spec, dict) else []
1351
+
1352
+ imports = []
1353
+ if isinstance(raw_imports, list):
1354
+ for entry in raw_imports:
1355
+ if isinstance(entry, dict):
1356
+ name = entry.get("name")
1357
+ alias = entry.get("alias")
1358
+ elif isinstance(entry, (list, tuple)):
1359
+ name = entry[0] if len(entry) > 0 else None
1360
+ alias = entry[1] if len(entry) > 1 else None
1361
+ else:
1362
+ name = entry
1363
+ alias = None
1364
+
1365
+ name_node = zexus_ast.Identifier(name) if name else None
1366
+ alias_node = zexus_ast.Identifier(alias) if alias else None
1367
+ imports.append((name_node, alias_node))
1368
+
1369
+ from_node = zexus_ast.FromStatement(file_path, imports=imports)
1370
+ return self.eval_from_statement(from_node, env, stack_trace=[])
1371
+ except Exception as exc:
1372
+ return EvaluationError(str(exc))
1373
+
1374
+ def _wrap_statement(statement, expected_type):
1375
+ if isinstance(statement, expected_type):
1376
+ return statement
1377
+ if isinstance(statement, dict):
1378
+ try:
1379
+ if expected_type is zexus_ast.GCStatement:
1380
+ return zexus_ast.GCStatement(statement.get("action"))
1381
+ if expected_type is zexus_ast.InlineStatement:
1382
+ return zexus_ast.InlineStatement(statement.get("function_name") or statement.get("name"))
1383
+ if expected_type is zexus_ast.DeferStatement:
1384
+ return zexus_ast.DeferStatement(statement.get("code"))
1385
+ if expected_type is zexus_ast.NativeStatement:
1386
+ return zexus_ast.NativeStatement(
1387
+ statement.get("library_name") or statement.get("library"),
1388
+ statement.get("function_name") or statement.get("function"),
1389
+ args=statement.get("args"),
1390
+ alias=statement.get("alias")
1391
+ )
1392
+ if expected_type is zexus_ast.BufferStatement:
1393
+ return zexus_ast.BufferStatement(
1394
+ statement.get("buffer_name") or statement.get("name"),
1395
+ statement.get("operation"),
1396
+ statement.get("arguments"),
1397
+ )
1398
+ if expected_type is zexus_ast.SIMDStatement:
1399
+ return zexus_ast.SIMDStatement(
1400
+ statement.get("operation"),
1401
+ operands=statement.get("operands")
1402
+ )
1403
+ if expected_type is zexus_ast.PatternStatement:
1404
+ return zexus_ast.PatternStatement(
1405
+ statement.get("expression"),
1406
+ statement.get("cases") or []
1407
+ )
1408
+ except Exception as exc:
1409
+ return EvaluationError(str(exc))
1410
+ return EvaluationError(f"Invalid payload for {expected_type.__name__}")
1411
+
1412
+ def _vm_native_statement(node, _env=env):
1413
+ stmt = _wrap_statement(node, zexus_ast.NativeStatement)
1414
+ if isinstance(stmt, EvaluationError):
1415
+ return stmt
1416
+ return self.eval_native_statement(stmt, _env, stack_trace=[])
1417
+
1418
+ def _vm_gc_statement(node, _env=env):
1419
+ stmt = _wrap_statement(node, zexus_ast.GCStatement)
1420
+ if isinstance(stmt, EvaluationError):
1421
+ return stmt
1422
+ return self.eval_gc_statement(stmt, _env, stack_trace=[])
1423
+
1424
+ def _vm_inline_statement(node, _env=env):
1425
+ stmt = _wrap_statement(node, zexus_ast.InlineStatement)
1426
+ if isinstance(stmt, EvaluationError):
1427
+ return stmt
1428
+ return self.eval_inline_statement(stmt, _env, stack_trace=[])
1429
+
1430
+ def _vm_buffer_statement(node, _env=env):
1431
+ stmt = _wrap_statement(node, zexus_ast.BufferStatement)
1432
+ if isinstance(stmt, EvaluationError):
1433
+ return stmt
1434
+ return self.eval_buffer_statement(stmt, _env, stack_trace=[])
1435
+
1436
+ def _vm_simd_statement(node, _env=env):
1437
+ stmt = _wrap_statement(node, zexus_ast.SIMDStatement)
1438
+ if isinstance(stmt, EvaluationError):
1439
+ return stmt
1440
+ return self.eval_simd_statement(stmt, _env, stack_trace=[])
1441
+
1442
+ def _vm_defer_statement(node, _env=env):
1443
+ stmt = _wrap_statement(node, zexus_ast.DeferStatement)
1444
+ if isinstance(stmt, EvaluationError):
1445
+ return stmt
1446
+ return self.eval_defer_statement(stmt, _env, stack_trace=[])
1447
+
1448
+ def _vm_pattern_statement(node, _env=env):
1449
+ stmt = _wrap_statement(node, zexus_ast.PatternStatement)
1450
+ if isinstance(stmt, EvaluationError):
1451
+ return stmt
1452
+ return self.eval_pattern_statement(stmt, _env, stack_trace=[])
1453
+
1454
+ return {
1455
+ "__keyword_find__": Builtin(_vm_find, "__keyword_find__"),
1456
+ "__keyword_load__": Builtin(_vm_load, "__keyword_load__"),
1457
+ "__vm_use_module__": Builtin(_vm_use_module, "__vm_use_module__"),
1458
+ "__vm_from_module__": Builtin(_vm_from_module, "__vm_from_module__"),
1459
+ "__vm_native_statement__": Builtin(_vm_native_statement, "__vm_native_statement__"),
1460
+ "__vm_gc_statement__": Builtin(_vm_gc_statement, "__vm_gc_statement__"),
1461
+ "__vm_inline_statement__": Builtin(_vm_inline_statement, "__vm_inline_statement__"),
1462
+ "__vm_buffer_statement__": Builtin(_vm_buffer_statement, "__vm_buffer_statement__"),
1463
+ "__vm_simd_statement__": Builtin(_vm_simd_statement, "__vm_simd_statement__"),
1464
+ "__vm_defer_statement__": Builtin(_vm_defer_statement, "__vm_defer_statement__"),
1465
+ "__vm_pattern_statement__": Builtin(_vm_pattern_statement, "__vm_pattern_statement__"),
1466
+ }
1467
+
919
1468
  def _env_to_dict(self, env):
920
1469
  """Convert Environment object to dict for VM"""
921
1470
  result = {}
@@ -993,11 +1542,46 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
993
1542
  def eval_with_vm_support(self, node, env, stack_trace=None, debug_mode=False):
994
1543
  """
995
1544
  Evaluate node with optional VM execution.
996
- Tries VM first if beneficial, falls back to direct evaluation.
1545
+ Uses file-based cache for repeat runs, then tries VM for beneficial nodes.
997
1546
  """
998
- # Check if we should use VM
1547
+ # Try file-based cache first for whole-file acceleration
1548
+ file_path = None
1549
+ try:
1550
+ file_obj = env.get("__file__")
1551
+ if file_obj and hasattr(file_obj, 'value'):
1552
+ file_path = file_obj.value
1553
+ except Exception:
1554
+ pass
1555
+
1556
+ # For program nodes with file context, try cached execution
1557
+ if (
1558
+ self.use_vm
1559
+ and VM_AVAILABLE
1560
+ and file_path
1561
+ and self.bytecode_compiler
1562
+ and type(node).__name__ == 'Program'
1563
+ and self.bytecode_compiler.cache
1564
+ ):
1565
+ cached_bytecodes = None
1566
+ if self.bytecode_compiler.cache.is_file_cached(file_path):
1567
+ cached_bytecodes = self.bytecode_compiler.cache.get_by_file(file_path)
1568
+ if cached_bytecodes:
1569
+ debug_log("VM Execution", f"Using cached bytecode for {file_path}")
1570
+ result = self._execute_bytecode_sequence(cached_bytecodes, env, debug_mode)
1571
+ if result is not None:
1572
+ return result
1573
+
1574
+ # Cache miss or invalid - compile full file and store
1575
+ compiled = self.bytecode_compiler.compile_file(file_path, node, optimize=True)
1576
+ if compiled:
1577
+ debug_log("VM Execution", f"Cached compilation for {file_path} ({len(compiled)} bytecodes)")
1578
+ result = self._execute_bytecode_sequence(compiled, env, debug_mode)
1579
+ if result is not None:
1580
+ return result
1581
+
1582
+ # Check if we should use VM for this node
999
1583
  if self._should_use_vm(node):
1000
- result = self._execute_via_vm(node, env, debug_mode)
1584
+ result = self._execute_via_vm(node, env, debug_mode, file_path)
1001
1585
  if result is not None:
1002
1586
  return result
1003
1587
  # Fall through to direct evaluation
@@ -1017,7 +1601,8 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
1017
1601
  'evaluator': self.vm_stats.copy(),
1018
1602
  'cache': None,
1019
1603
  'jit': None,
1020
- 'optimizer': None
1604
+ 'optimizer': None,
1605
+ 'fast_loop': None
1021
1606
  }
1022
1607
 
1023
1608
  # Cache statistics
@@ -1027,6 +1612,7 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
1027
1612
  # JIT statistics
1028
1613
  if self.vm_instance:
1029
1614
  stats['jit'] = self.vm_instance.get_jit_stats()
1615
+ stats['fast_loop'] = getattr(self.vm_instance, "_fast_loop_stats", None)
1030
1616
 
1031
1617
  return stats
1032
1618
 
@@ -1042,7 +1628,15 @@ def evaluate(program, env, debug_mode=False, use_vm=True):
1042
1628
  try:
1043
1629
  from . import builtins as injected_builtins
1044
1630
  if isinstance(injected_builtins, dict):
1045
- evaluator.builtins.update(injected_builtins)
1631
+ from ..object import Builtin
1632
+
1633
+ for name, value in injected_builtins.items():
1634
+ if isinstance(value, Builtin):
1635
+ evaluator.builtins[name] = value
1636
+ elif callable(value):
1637
+ evaluator.builtins[name] = Builtin(value, name)
1638
+ else:
1639
+ evaluator.builtins[name] = value
1046
1640
  except Exception:
1047
1641
  pass
1048
1642