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.
- package/README.md +3 -3
- package/package.json +1 -1
- package/src/__init__.py +7 -0
- package/src/zexus/__init__.py +1 -1
- package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/debug_sanitizer.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/environment.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/error_reporter.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/input_validation.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/module_manager.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/security_enforcement.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/zexus_token.cpython-312.pyc +0 -0
- package/src/zexus/access_control_system/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/access_control_system/__pycache__/access_control.cpython-312.pyc +0 -0
- package/src/zexus/advanced_types.py +17 -2
- package/src/zexus/blockchain/__init__.py +411 -0
- package/src/zexus/blockchain/accelerator.py +1160 -0
- package/src/zexus/blockchain/chain.py +660 -0
- package/src/zexus/blockchain/consensus.py +821 -0
- package/src/zexus/blockchain/contract_vm.py +1019 -0
- package/src/zexus/blockchain/crypto.py +79 -14
- package/src/zexus/blockchain/events.py +526 -0
- package/src/zexus/blockchain/loadtest.py +721 -0
- package/src/zexus/blockchain/monitoring.py +350 -0
- package/src/zexus/blockchain/mpt.py +716 -0
- package/src/zexus/blockchain/multichain.py +951 -0
- package/src/zexus/blockchain/multiprocess_executor.py +338 -0
- package/src/zexus/blockchain/network.py +886 -0
- package/src/zexus/blockchain/node.py +666 -0
- package/src/zexus/blockchain/rpc.py +1203 -0
- package/src/zexus/blockchain/rust_bridge.py +421 -0
- package/src/zexus/blockchain/storage.py +423 -0
- package/src/zexus/blockchain/tokens.py +750 -0
- package/src/zexus/blockchain/upgradeable.py +1004 -0
- package/src/zexus/blockchain/verification.py +1602 -0
- package/src/zexus/blockchain/wallet.py +621 -0
- package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
- package/src/zexus/cli/main.py +300 -20
- package/src/zexus/cli/zpm.py +1 -1
- package/src/zexus/compiler/__pycache__/bytecode.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/semantic.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/compiler/lexer.py +10 -5
- package/src/zexus/concurrency_system.py +79 -0
- package/src/zexus/config.py +54 -0
- package/src/zexus/crypto_bridge.py +244 -8
- package/src/zexus/dap/__init__.py +10 -0
- package/src/zexus/dap/__main__.py +4 -0
- package/src/zexus/dap/dap_server.py +391 -0
- package/src/zexus/dap/debug_engine.py +298 -0
- package/src/zexus/environment.py +10 -1
- package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/resource_limiter.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/unified_execution.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/bytecode_compiler.py +441 -37
- package/src/zexus/evaluator/core.py +560 -49
- package/src/zexus/evaluator/expressions.py +122 -49
- package/src/zexus/evaluator/functions.py +417 -16
- package/src/zexus/evaluator/statements.py +521 -118
- package/src/zexus/evaluator/unified_execution.py +573 -72
- package/src/zexus/evaluator/utils.py +14 -2
- package/src/zexus/event_loop.py +186 -0
- package/src/zexus/lexer.py +742 -486
- package/src/zexus/lsp/__init__.py +1 -1
- package/src/zexus/lsp/definition_provider.py +163 -9
- package/src/zexus/lsp/server.py +22 -8
- package/src/zexus/lsp/symbol_provider.py +182 -9
- package/src/zexus/module_cache.py +237 -9
- package/src/zexus/object.py +64 -6
- package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
- package/src/zexus/parser/parser.py +786 -285
- package/src/zexus/parser/strategy_context.py +407 -66
- package/src/zexus/parser/strategy_structural.py +117 -19
- package/src/zexus/persistence.py +15 -1
- package/src/zexus/renderer/__init__.py +15 -0
- package/src/zexus/renderer/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/renderer/__pycache__/backend.cpython-312.pyc +0 -0
- package/src/zexus/renderer/__pycache__/canvas.cpython-312.pyc +0 -0
- package/src/zexus/renderer/__pycache__/color_system.cpython-312.pyc +0 -0
- package/src/zexus/renderer/__pycache__/layout.cpython-312.pyc +0 -0
- package/src/zexus/renderer/__pycache__/main_renderer.cpython-312.pyc +0 -0
- package/src/zexus/renderer/__pycache__/painter.cpython-312.pyc +0 -0
- package/src/zexus/renderer/tk_backend.py +208 -0
- package/src/zexus/renderer/web_backend.py +260 -0
- package/src/zexus/runtime/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/runtime/__pycache__/async_runtime.cpython-312.pyc +0 -0
- package/src/zexus/runtime/__pycache__/load_manager.cpython-312.pyc +0 -0
- package/src/zexus/runtime/file_flags.py +137 -0
- package/src/zexus/safety/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/safety/__pycache__/memory_safety.cpython-312.pyc +0 -0
- package/src/zexus/security.py +424 -34
- package/src/zexus/stdlib/fs.py +23 -18
- package/src/zexus/stdlib/http.py +289 -186
- package/src/zexus/stdlib/sockets.py +207 -163
- package/src/zexus/stdlib/websockets.py +282 -0
- package/src/zexus/stdlib_integration.py +369 -2
- package/src/zexus/strategy_recovery.py +6 -3
- package/src/zexus/type_checker.py +423 -0
- package/src/zexus/virtual_filesystem.py +189 -2
- package/src/zexus/vm/__init__.py +113 -3
- package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/bytecode_converter.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/compiler.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/gas_metering.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/async_optimizer.py +14 -1
- package/src/zexus/vm/binary_bytecode.py +659 -0
- package/src/zexus/vm/bytecode.py +28 -1
- package/src/zexus/vm/bytecode_converter.py +26 -12
- package/src/zexus/vm/cabi.c +1985 -0
- package/src/zexus/vm/cabi.cpython-312-x86_64-linux-gnu.so +0 -0
- package/src/zexus/vm/cabi.h +127 -0
- package/src/zexus/vm/cache.py +557 -17
- package/src/zexus/vm/compiler.py +703 -5
- package/src/zexus/vm/fastops.c +15743 -0
- package/src/zexus/vm/fastops.cpython-312-x86_64-linux-gnu.so +0 -0
- package/src/zexus/vm/fastops.pyx +288 -0
- package/src/zexus/vm/gas_metering.py +50 -9
- package/src/zexus/vm/jit.py +83 -2
- package/src/zexus/vm/native_jit_backend.py +1816 -0
- package/src/zexus/vm/native_runtime.cpp +1388 -0
- package/src/zexus/vm/native_runtime.cpython-312-x86_64-linux-gnu.so +0 -0
- package/src/zexus/vm/optimizer.py +161 -11
- package/src/zexus/vm/parallel_vm.py +118 -42
- package/src/zexus/vm/peephole_optimizer.py +82 -4
- package/src/zexus/vm/profiler.py +38 -18
- package/src/zexus/vm/register_allocator.py +16 -5
- package/src/zexus/vm/register_vm.py +8 -5
- package/src/zexus/vm/vm.py +3411 -573
- package/src/zexus/vm/wasm_compiler.py +658 -0
- package/src/zexus/zexus_ast.py +63 -11
- package/src/zexus/zexus_token.py +13 -5
- package/src/zexus/zpm/installer.py +55 -15
- package/src/zexus/zpm/package_manager.py +1 -1
- package/src/zexus/zpm/registry.py +257 -28
- package/src/zexus.egg-info/PKG-INFO +7 -4
- package/src/zexus.egg-info/SOURCES.txt +116 -9
- package/src/zexus.egg-info/entry_points.txt +1 -0
- package/src/zexus.egg-info/requires.txt +4 -0
|
@@ -4,8 +4,9 @@ import asyncio
|
|
|
4
4
|
import os
|
|
5
5
|
import sys
|
|
6
6
|
from .. import zexus_ast
|
|
7
|
-
from ..object import Environment, EvaluationError, Null, Boolean as BooleanObj, Map, EmbeddedCode, List, Action, LambdaFunction, String, ReturnValue, Builtin
|
|
7
|
+
from ..object import Environment, EvaluationError, Null, Boolean as BooleanObj, Map, EmbeddedCode, List, Action, LambdaFunction, String, ReturnValue, Builtin, Integer, Float
|
|
8
8
|
from .utils import is_error, debug_log, EVAL_SUMMARY, NULL
|
|
9
|
+
from ..config import config as zexus_config
|
|
9
10
|
from .expressions import ExpressionEvaluatorMixin
|
|
10
11
|
from .statements import StatementEvaluatorMixin
|
|
11
12
|
from .functions import FunctionEvaluatorMixin
|
|
@@ -105,8 +106,14 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
105
106
|
pass
|
|
106
107
|
|
|
107
108
|
def _initialize_dispatch_table(self):
|
|
108
|
-
"""Precompute handlers for
|
|
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
|
+
"""
|
|
109
115
|
try:
|
|
116
|
+
# Core hot-path nodes with dedicated handler methods
|
|
110
117
|
self._node_handlers = {
|
|
111
118
|
zexus_ast.Program: self._handle_program_node,
|
|
112
119
|
zexus_ast.ExpressionStatement: self._handle_expression_statement,
|
|
@@ -127,9 +134,120 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
127
134
|
zexus_ast.InfixExpression: self._handle_infix_expression,
|
|
128
135
|
zexus_ast.PrefixExpression: self._handle_prefix_expression,
|
|
129
136
|
zexus_ast.CallExpression: self._handle_call_expression,
|
|
137
|
+
zexus_ast.PropertyAccessExpression: self._handle_property_access_expression,
|
|
130
138
|
zexus_ast.MethodCallExpression: self._handle_method_call_expression,
|
|
131
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',
|
|
132
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
|
+
|
|
133
251
|
except AttributeError:
|
|
134
252
|
# AST variants may omit certain nodes; keep table empty in that case
|
|
135
253
|
self._node_handlers = {}
|
|
@@ -174,24 +292,18 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
174
292
|
|
|
175
293
|
def _handle_function_statement(self, node, env, stack_trace):
|
|
176
294
|
debug_log(" FunctionStatement node", f"function {node.name.value}")
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
print(f"[CORE] FunctionStatement result: {result}", flush=True)
|
|
180
|
-
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)
|
|
181
297
|
|
|
182
298
|
def _handle_identifier(self, node, env, stack_trace):
|
|
183
299
|
debug_log(" Identifier node", node.value)
|
|
184
300
|
return self.eval_identifier(node, env)
|
|
185
301
|
|
|
186
302
|
def _handle_integer_literal(self, node, env, stack_trace):
|
|
187
|
-
debug_log(" IntegerLiteral node", node.value)
|
|
188
|
-
from ..object import Integer
|
|
189
303
|
return Integer(node.value)
|
|
190
304
|
|
|
191
305
|
def _handle_boolean_literal(self, node, env, stack_trace):
|
|
192
|
-
|
|
193
|
-
from ..object import Boolean
|
|
194
|
-
return Boolean(node.value)
|
|
306
|
+
return BooleanObj(node.value)
|
|
195
307
|
|
|
196
308
|
def _handle_null_literal(self, node, env, stack_trace):
|
|
197
309
|
debug_log(" NullLiteral node")
|
|
@@ -213,43 +325,182 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
213
325
|
debug_log("🚀 CallExpression node", f"Calling {node.function}")
|
|
214
326
|
return self.eval_call_expression(node, env, stack_trace)
|
|
215
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
|
+
|
|
216
332
|
def _handle_method_call_expression(self, node, env, stack_trace):
|
|
217
333
|
debug_log(" MethodCallExpression node", f"{node.object}.{node.method}")
|
|
218
334
|
return self.eval_method_call_expression(node, env, stack_trace)
|
|
219
335
|
|
|
220
336
|
def _handle_list_literal(self, node, env, stack_trace):
|
|
221
|
-
debug_log(" ListLiteral node", f"{len(node.elements)} elements")
|
|
222
337
|
elems = self.eval_expressions(node.elements, env)
|
|
223
338
|
if is_error(elems):
|
|
224
339
|
return elems
|
|
225
340
|
return List(elems)
|
|
226
|
-
|
|
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
|
+
|
|
227
480
|
def eval_node(self, node, env, stack_trace=None):
|
|
228
481
|
if node is None:
|
|
229
|
-
debug_log("eval_node", "Node is None, returning NULL")
|
|
230
482
|
return NULL
|
|
231
|
-
|
|
232
|
-
|
|
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
|
+
|
|
233
492
|
node_type = type(node)
|
|
234
|
-
|
|
235
|
-
# Add to stack trace for better error reporting
|
|
236
|
-
current_frame = f" at {node_type.__name__}"
|
|
237
|
-
if hasattr(node, 'token') and node.token:
|
|
238
|
-
current_frame += f" (line {node.token.line})"
|
|
239
|
-
stack_trace.append(current_frame)
|
|
240
|
-
|
|
241
|
-
debug_log("eval_node", f"Processing {node_type.__name__}")
|
|
242
493
|
|
|
243
494
|
handler = self._node_handlers.get(node_type)
|
|
244
495
|
if handler:
|
|
245
496
|
return handler(node, env, stack_trace)
|
|
246
|
-
|
|
497
|
+
|
|
247
498
|
try:
|
|
248
499
|
# === STATEMENTS ===
|
|
249
500
|
if isinstance(node, zexus_ast.Program):
|
|
250
501
|
debug_log(" Program node", f"{len(node.statements)} statements")
|
|
251
502
|
return self.ceval_program(node.statements, env)
|
|
252
|
-
|
|
503
|
+
|
|
253
504
|
elif isinstance(node, zexus_ast.ExpressionStatement):
|
|
254
505
|
debug_log(" ExpressionStatement node")
|
|
255
506
|
return self.eval_node(node.expression, env, stack_trace)
|
|
@@ -414,10 +665,8 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
414
665
|
|
|
415
666
|
elif isinstance(node, zexus_ast.FunctionStatement):
|
|
416
667
|
debug_log(" FunctionStatement node", f"function {node.name.value}")
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
print(f"[CORE] FunctionStatement result: {result}", flush=True)
|
|
420
|
-
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)
|
|
421
670
|
|
|
422
671
|
elif isinstance(node, zexus_ast.NativeStatement):
|
|
423
672
|
debug_log(" NativeStatement node", f"native {node.function_name}")
|
|
@@ -579,12 +828,10 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
579
828
|
|
|
580
829
|
elif isinstance(node, zexus_ast.IntegerLiteral):
|
|
581
830
|
debug_log(" IntegerLiteral node", node.value)
|
|
582
|
-
from ..object import Integer
|
|
583
831
|
return Integer(node.value)
|
|
584
832
|
|
|
585
833
|
elif node_type == zexus_ast.FloatLiteral or isinstance(node, zexus_ast.FloatLiteral):
|
|
586
834
|
debug_log(" FloatLiteral node", getattr(node, 'value', 'unknown'))
|
|
587
|
-
from ..object import Float
|
|
588
835
|
try:
|
|
589
836
|
val = getattr(node, 'value', None)
|
|
590
837
|
return Float(val)
|
|
@@ -593,7 +840,6 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
593
840
|
|
|
594
841
|
elif isinstance(node, zexus_ast.StringLiteral):
|
|
595
842
|
debug_log(" StringLiteral node", node.value)
|
|
596
|
-
from ..object import String
|
|
597
843
|
# Process escape sequences in the string
|
|
598
844
|
value = node.value
|
|
599
845
|
value = value.replace('\\n', '\n')
|
|
@@ -605,10 +851,12 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
605
851
|
# String literals are trusted (not from external input)
|
|
606
852
|
return String(value, is_trusted=True)
|
|
607
853
|
|
|
854
|
+
elif isinstance(node, zexus_ast.StringInterpolationExpression):
|
|
855
|
+
return self._handle_string_interpolation(node, env, stack_trace)
|
|
856
|
+
|
|
608
857
|
elif isinstance(node, zexus_ast.Boolean):
|
|
609
858
|
debug_log(" Boolean node", f"value: {node.value}")
|
|
610
|
-
|
|
611
|
-
return Boolean(node.value)
|
|
859
|
+
return BooleanObj(node.value)
|
|
612
860
|
|
|
613
861
|
elif isinstance(node, zexus_ast.NullLiteral):
|
|
614
862
|
debug_log(" NullLiteral node")
|
|
@@ -754,22 +1002,23 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
754
1002
|
restriction = None
|
|
755
1003
|
|
|
756
1004
|
# Handle Builtin objects (for static methods like TypeName.default())
|
|
757
|
-
from ..object import Builtin
|
|
758
1005
|
if isinstance(obj, Builtin):
|
|
759
1006
|
if hasattr(obj, 'static_methods') and property_name in obj.static_methods:
|
|
760
1007
|
return obj.static_methods[property_name]
|
|
761
1008
|
return NULL
|
|
762
1009
|
|
|
763
1010
|
# Handle Module objects
|
|
764
|
-
|
|
765
|
-
|
|
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):
|
|
766
1016
|
val = obj.get(property_name)
|
|
767
1017
|
if val is None:
|
|
768
1018
|
return NULL
|
|
769
1019
|
if restriction:
|
|
770
1020
|
rule = restriction.get('restriction')
|
|
771
1021
|
if rule == 'redact':
|
|
772
|
-
from ..object import String
|
|
773
1022
|
return String('***REDACTED***')
|
|
774
1023
|
if rule == 'admin-only':
|
|
775
1024
|
is_admin = bool(env.get('__is_admin__')) if env and hasattr(env, 'get') else False
|
|
@@ -779,8 +1028,6 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
779
1028
|
|
|
780
1029
|
# Handle Map objects
|
|
781
1030
|
if isinstance(obj, Map):
|
|
782
|
-
from ..object import String
|
|
783
|
-
|
|
784
1031
|
# Try string key first
|
|
785
1032
|
val = obj.pairs.get(property_name, NULL)
|
|
786
1033
|
if val == NULL:
|
|
@@ -812,7 +1059,6 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
812
1059
|
if restriction:
|
|
813
1060
|
rule = restriction.get('restriction')
|
|
814
1061
|
if rule == 'redact':
|
|
815
|
-
from ..object import String
|
|
816
1062
|
return String('***REDACTED***')
|
|
817
1063
|
if rule == 'admin-only':
|
|
818
1064
|
# check environment flag for admin
|
|
@@ -829,7 +1075,6 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
829
1075
|
if restriction:
|
|
830
1076
|
rule = restriction.get('restriction')
|
|
831
1077
|
if rule == 'redact':
|
|
832
|
-
from ..object import String
|
|
833
1078
|
return String('***REDACTED***')
|
|
834
1079
|
if rule == 'admin-only':
|
|
835
1080
|
is_admin = bool(env.get('__is_admin__')) if env and hasattr(env, 'get') else False
|
|
@@ -842,7 +1087,6 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
842
1087
|
if restriction:
|
|
843
1088
|
rule = restriction.get('restriction')
|
|
844
1089
|
if rule == 'redact':
|
|
845
|
-
from ..object import String
|
|
846
1090
|
return String('***REDACTED***')
|
|
847
1091
|
if rule == 'admin-only':
|
|
848
1092
|
is_admin = bool(env.get('__is_admin__')) if env and hasattr(env, 'get') else False
|
|
@@ -850,6 +1094,35 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
850
1094
|
return EvaluationError('Access denied: admin required')
|
|
851
1095
|
return val
|
|
852
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
|
+
|
|
853
1126
|
return NULL
|
|
854
1127
|
|
|
855
1128
|
# === BLOCKCHAIN EXPRESSIONS ===
|
|
@@ -920,10 +1193,11 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
920
1193
|
# Use external heuristics
|
|
921
1194
|
return should_use_vm_for_node(node)
|
|
922
1195
|
|
|
923
|
-
def _execute_via_vm(self, node, env, debug_mode=False):
|
|
1196
|
+
def _execute_via_vm(self, node, env, debug_mode=False, file_path=None):
|
|
924
1197
|
"""
|
|
925
1198
|
Compile node to bytecode and execute via VM.
|
|
926
1199
|
Falls back to direct evaluation on error.
|
|
1200
|
+
Stores compiled bytecode in file cache if file_path is provided.
|
|
927
1201
|
"""
|
|
928
1202
|
try:
|
|
929
1203
|
debug_log("VM Execution", f"Compiling {type(node).__name__} to bytecode")
|
|
@@ -933,11 +1207,21 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
933
1207
|
|
|
934
1208
|
if bytecode is None or self.bytecode_compiler.errors:
|
|
935
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
|
+
)
|
|
936
1216
|
self.vm_stats['vm_fallbacks'] += 1
|
|
937
1217
|
return None # Signal fallback
|
|
938
1218
|
|
|
939
1219
|
self.vm_stats['bytecode_compiles'] += 1
|
|
940
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
|
+
|
|
941
1225
|
# Convert environment to dict for VM
|
|
942
1226
|
vm_env = self._env_to_dict(env)
|
|
943
1227
|
|
|
@@ -975,8 +1259,50 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
975
1259
|
|
|
976
1260
|
except Exception as e:
|
|
977
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
|
+
)
|
|
978
1267
|
self.vm_stats['vm_fallbacks'] += 1
|
|
979
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
|
|
980
1306
|
|
|
981
1307
|
def _create_vm_keyword_builtins(self, env):
|
|
982
1308
|
"""Expose keyword helpers to the VM so bytecode can reuse evaluator logic"""
|
|
@@ -986,9 +1312,157 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
986
1312
|
def _vm_load(node_ref):
|
|
987
1313
|
return self.eval_load_expression(node_ref, env, stack_trace=[])
|
|
988
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
|
+
|
|
989
1454
|
return {
|
|
990
1455
|
"__keyword_find__": Builtin(_vm_find, "__keyword_find__"),
|
|
991
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__"),
|
|
992
1466
|
}
|
|
993
1467
|
|
|
994
1468
|
def _env_to_dict(self, env):
|
|
@@ -1068,11 +1542,46 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
1068
1542
|
def eval_with_vm_support(self, node, env, stack_trace=None, debug_mode=False):
|
|
1069
1543
|
"""
|
|
1070
1544
|
Evaluate node with optional VM execution.
|
|
1071
|
-
|
|
1545
|
+
Uses file-based cache for repeat runs, then tries VM for beneficial nodes.
|
|
1072
1546
|
"""
|
|
1073
|
-
#
|
|
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
|
|
1074
1583
|
if self._should_use_vm(node):
|
|
1075
|
-
result = self._execute_via_vm(node, env, debug_mode)
|
|
1584
|
+
result = self._execute_via_vm(node, env, debug_mode, file_path)
|
|
1076
1585
|
if result is not None:
|
|
1077
1586
|
return result
|
|
1078
1587
|
# Fall through to direct evaluation
|
|
@@ -1092,7 +1601,8 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
1092
1601
|
'evaluator': self.vm_stats.copy(),
|
|
1093
1602
|
'cache': None,
|
|
1094
1603
|
'jit': None,
|
|
1095
|
-
'optimizer': None
|
|
1604
|
+
'optimizer': None,
|
|
1605
|
+
'fast_loop': None
|
|
1096
1606
|
}
|
|
1097
1607
|
|
|
1098
1608
|
# Cache statistics
|
|
@@ -1102,6 +1612,7 @@ class Evaluator(ExpressionEvaluatorMixin, StatementEvaluatorMixin, FunctionEvalu
|
|
|
1102
1612
|
# JIT statistics
|
|
1103
1613
|
if self.vm_instance:
|
|
1104
1614
|
stats['jit'] = self.vm_instance.get_jit_stats()
|
|
1615
|
+
stats['fast_loop'] = getattr(self.vm_instance, "_fast_loop_stats", None)
|
|
1105
1616
|
|
|
1106
1617
|
return stats
|
|
1107
1618
|
|