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.
- package/README.md +12 -5
- 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/capability_system.py +184 -9
- package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
- package/src/zexus/cli/main.py +383 -34
- 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/bytecode.py +124 -7
- package/src/zexus/compiler/compat_runtime.py +6 -2
- package/src/zexus/compiler/lexer.py +16 -5
- package/src/zexus/compiler/parser.py +108 -7
- package/src/zexus/compiler/semantic.py +18 -19
- package/src/zexus/compiler/zexus_ast.py +26 -1
- 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 +112 -9
- 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 +457 -37
- package/src/zexus/evaluator/core.py +644 -50
- package/src/zexus/evaluator/expressions.py +358 -62
- package/src/zexus/evaluator/functions.py +458 -20
- package/src/zexus/evaluator/resource_limiter.py +4 -4
- package/src/zexus/evaluator/statements.py +774 -122
- package/src/zexus/evaluator/unified_execution.py +573 -72
- package/src/zexus/evaluator/utils.py +14 -2
- package/src/zexus/evaluator_original.py +1 -1
- package/src/zexus/event_loop.py +186 -0
- package/src/zexus/lexer.py +742 -458
- 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 +239 -9
- package/src/zexus/module_manager.py +129 -1
- package/src/zexus/object.py +76 -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 +1349 -408
- package/src/zexus/parser/strategy_context.py +755 -58
- package/src/zexus/parser/strategy_structural.py +121 -21
- package/src/zexus/persistence.py +15 -1
- package/src/zexus/renderer/__init__.py +61 -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/backend.py +261 -0
- package/src/zexus/renderer/canvas.py +78 -0
- package/src/zexus/renderer/color_system.py +201 -0
- package/src/zexus/renderer/graphics.py +31 -0
- package/src/zexus/renderer/layout.py +222 -0
- package/src/zexus/renderer/main_renderer.py +66 -0
- package/src/zexus/renderer/painter.py +30 -0
- package/src/zexus/renderer/tk_backend.py +208 -0
- package/src/zexus/renderer/web_backend.py +260 -0
- package/src/zexus/runtime/__init__.py +10 -2
- 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/runtime/load_manager.py +368 -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 +80 -6
- package/src/zexus/vm/binary_bytecode.py +659 -0
- package/src/zexus/vm/bytecode.py +59 -11
- 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 +561 -17
- package/src/zexus/vm/compiler.py +818 -51
- 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 +364 -20
- 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 +140 -45
- 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 +3581 -531
- package/src/zexus/vm/wasm_compiler.py +658 -0
- package/src/zexus/zexus_ast.py +137 -11
- package/src/zexus/zexus_token.py +16 -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 +16 -6
- package/src/zexus.egg-info/SOURCES.txt +129 -17
- package/src/zexus.egg-info/entry_points.txt +1 -0
- 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
|
|
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
|
-
|
|
146
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
366
|
-
|
|
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
|
-
|
|
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
|
-
|
|
705
|
-
|
|
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
|
-
|
|
1545
|
+
Uses file-based cache for repeat runs, then tries VM for beneficial nodes.
|
|
997
1546
|
"""
|
|
998
|
-
#
|
|
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
|
-
|
|
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
|
|