zexus 1.6.8 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/README.md +12 -5
  2. package/package.json +1 -1
  3. package/src/__init__.py +7 -0
  4. package/src/zexus/__init__.py +1 -1
  5. package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
  6. package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
  7. package/src/zexus/__pycache__/debug_sanitizer.cpython-312.pyc +0 -0
  8. package/src/zexus/__pycache__/environment.cpython-312.pyc +0 -0
  9. package/src/zexus/__pycache__/error_reporter.cpython-312.pyc +0 -0
  10. package/src/zexus/__pycache__/input_validation.cpython-312.pyc +0 -0
  11. package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
  12. package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
  13. package/src/zexus/__pycache__/module_manager.cpython-312.pyc +0 -0
  14. package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
  15. package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
  16. package/src/zexus/__pycache__/security_enforcement.cpython-312.pyc +0 -0
  17. package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
  18. package/src/zexus/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  19. package/src/zexus/__pycache__/zexus_token.cpython-312.pyc +0 -0
  20. package/src/zexus/access_control_system/__pycache__/__init__.cpython-312.pyc +0 -0
  21. package/src/zexus/access_control_system/__pycache__/access_control.cpython-312.pyc +0 -0
  22. package/src/zexus/advanced_types.py +17 -2
  23. package/src/zexus/blockchain/__init__.py +411 -0
  24. package/src/zexus/blockchain/accelerator.py +1160 -0
  25. package/src/zexus/blockchain/chain.py +660 -0
  26. package/src/zexus/blockchain/consensus.py +821 -0
  27. package/src/zexus/blockchain/contract_vm.py +1019 -0
  28. package/src/zexus/blockchain/crypto.py +79 -14
  29. package/src/zexus/blockchain/events.py +526 -0
  30. package/src/zexus/blockchain/loadtest.py +721 -0
  31. package/src/zexus/blockchain/monitoring.py +350 -0
  32. package/src/zexus/blockchain/mpt.py +716 -0
  33. package/src/zexus/blockchain/multichain.py +951 -0
  34. package/src/zexus/blockchain/multiprocess_executor.py +338 -0
  35. package/src/zexus/blockchain/network.py +886 -0
  36. package/src/zexus/blockchain/node.py +666 -0
  37. package/src/zexus/blockchain/rpc.py +1203 -0
  38. package/src/zexus/blockchain/rust_bridge.py +421 -0
  39. package/src/zexus/blockchain/storage.py +423 -0
  40. package/src/zexus/blockchain/tokens.py +750 -0
  41. package/src/zexus/blockchain/upgradeable.py +1004 -0
  42. package/src/zexus/blockchain/verification.py +1602 -0
  43. package/src/zexus/blockchain/wallet.py +621 -0
  44. package/src/zexus/capability_system.py +184 -9
  45. package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
  46. package/src/zexus/cli/main.py +383 -34
  47. package/src/zexus/cli/zpm.py +1 -1
  48. package/src/zexus/compiler/__pycache__/bytecode.cpython-312.pyc +0 -0
  49. package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
  50. package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
  51. package/src/zexus/compiler/__pycache__/semantic.cpython-312.pyc +0 -0
  52. package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  53. package/src/zexus/compiler/bytecode.py +124 -7
  54. package/src/zexus/compiler/compat_runtime.py +6 -2
  55. package/src/zexus/compiler/lexer.py +16 -5
  56. package/src/zexus/compiler/parser.py +108 -7
  57. package/src/zexus/compiler/semantic.py +18 -19
  58. package/src/zexus/compiler/zexus_ast.py +26 -1
  59. package/src/zexus/concurrency_system.py +79 -0
  60. package/src/zexus/config.py +54 -0
  61. package/src/zexus/crypto_bridge.py +244 -8
  62. package/src/zexus/dap/__init__.py +10 -0
  63. package/src/zexus/dap/__main__.py +4 -0
  64. package/src/zexus/dap/dap_server.py +391 -0
  65. package/src/zexus/dap/debug_engine.py +298 -0
  66. package/src/zexus/environment.py +112 -9
  67. package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
  68. package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
  69. package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
  70. package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
  71. package/src/zexus/evaluator/__pycache__/resource_limiter.cpython-312.pyc +0 -0
  72. package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
  73. package/src/zexus/evaluator/__pycache__/unified_execution.cpython-312.pyc +0 -0
  74. package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
  75. package/src/zexus/evaluator/bytecode_compiler.py +457 -37
  76. package/src/zexus/evaluator/core.py +644 -50
  77. package/src/zexus/evaluator/expressions.py +358 -62
  78. package/src/zexus/evaluator/functions.py +458 -20
  79. package/src/zexus/evaluator/resource_limiter.py +4 -4
  80. package/src/zexus/evaluator/statements.py +774 -122
  81. package/src/zexus/evaluator/unified_execution.py +573 -72
  82. package/src/zexus/evaluator/utils.py +14 -2
  83. package/src/zexus/evaluator_original.py +1 -1
  84. package/src/zexus/event_loop.py +186 -0
  85. package/src/zexus/lexer.py +742 -458
  86. package/src/zexus/lsp/__init__.py +1 -1
  87. package/src/zexus/lsp/definition_provider.py +163 -9
  88. package/src/zexus/lsp/server.py +22 -8
  89. package/src/zexus/lsp/symbol_provider.py +182 -9
  90. package/src/zexus/module_cache.py +239 -9
  91. package/src/zexus/module_manager.py +129 -1
  92. package/src/zexus/object.py +76 -6
  93. package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
  94. package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
  95. package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
  96. package/src/zexus/parser/parser.py +1349 -408
  97. package/src/zexus/parser/strategy_context.py +755 -58
  98. package/src/zexus/parser/strategy_structural.py +121 -21
  99. package/src/zexus/persistence.py +15 -1
  100. package/src/zexus/renderer/__init__.py +61 -0
  101. package/src/zexus/renderer/__pycache__/__init__.cpython-312.pyc +0 -0
  102. package/src/zexus/renderer/__pycache__/backend.cpython-312.pyc +0 -0
  103. package/src/zexus/renderer/__pycache__/canvas.cpython-312.pyc +0 -0
  104. package/src/zexus/renderer/__pycache__/color_system.cpython-312.pyc +0 -0
  105. package/src/zexus/renderer/__pycache__/layout.cpython-312.pyc +0 -0
  106. package/src/zexus/renderer/__pycache__/main_renderer.cpython-312.pyc +0 -0
  107. package/src/zexus/renderer/__pycache__/painter.cpython-312.pyc +0 -0
  108. package/src/zexus/renderer/backend.py +261 -0
  109. package/src/zexus/renderer/canvas.py +78 -0
  110. package/src/zexus/renderer/color_system.py +201 -0
  111. package/src/zexus/renderer/graphics.py +31 -0
  112. package/src/zexus/renderer/layout.py +222 -0
  113. package/src/zexus/renderer/main_renderer.py +66 -0
  114. package/src/zexus/renderer/painter.py +30 -0
  115. package/src/zexus/renderer/tk_backend.py +208 -0
  116. package/src/zexus/renderer/web_backend.py +260 -0
  117. package/src/zexus/runtime/__init__.py +10 -2
  118. package/src/zexus/runtime/__pycache__/__init__.cpython-312.pyc +0 -0
  119. package/src/zexus/runtime/__pycache__/async_runtime.cpython-312.pyc +0 -0
  120. package/src/zexus/runtime/__pycache__/load_manager.cpython-312.pyc +0 -0
  121. package/src/zexus/runtime/file_flags.py +137 -0
  122. package/src/zexus/runtime/load_manager.py +368 -0
  123. package/src/zexus/safety/__pycache__/__init__.cpython-312.pyc +0 -0
  124. package/src/zexus/safety/__pycache__/memory_safety.cpython-312.pyc +0 -0
  125. package/src/zexus/security.py +424 -34
  126. package/src/zexus/stdlib/fs.py +23 -18
  127. package/src/zexus/stdlib/http.py +289 -186
  128. package/src/zexus/stdlib/sockets.py +207 -163
  129. package/src/zexus/stdlib/websockets.py +282 -0
  130. package/src/zexus/stdlib_integration.py +369 -2
  131. package/src/zexus/strategy_recovery.py +6 -3
  132. package/src/zexus/type_checker.py +423 -0
  133. package/src/zexus/virtual_filesystem.py +189 -2
  134. package/src/zexus/vm/__init__.py +113 -3
  135. package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
  136. package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
  137. package/src/zexus/vm/__pycache__/bytecode_converter.cpython-312.pyc +0 -0
  138. package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
  139. package/src/zexus/vm/__pycache__/compiler.cpython-312.pyc +0 -0
  140. package/src/zexus/vm/__pycache__/gas_metering.cpython-312.pyc +0 -0
  141. package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
  142. package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
  143. package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
  144. package/src/zexus/vm/async_optimizer.py +80 -6
  145. package/src/zexus/vm/binary_bytecode.py +659 -0
  146. package/src/zexus/vm/bytecode.py +59 -11
  147. package/src/zexus/vm/bytecode_converter.py +26 -12
  148. package/src/zexus/vm/cabi.c +1985 -0
  149. package/src/zexus/vm/cabi.cpython-312-x86_64-linux-gnu.so +0 -0
  150. package/src/zexus/vm/cabi.h +127 -0
  151. package/src/zexus/vm/cache.py +561 -17
  152. package/src/zexus/vm/compiler.py +818 -51
  153. package/src/zexus/vm/fastops.c +15743 -0
  154. package/src/zexus/vm/fastops.cpython-312-x86_64-linux-gnu.so +0 -0
  155. package/src/zexus/vm/fastops.pyx +288 -0
  156. package/src/zexus/vm/gas_metering.py +50 -9
  157. package/src/zexus/vm/jit.py +364 -20
  158. package/src/zexus/vm/native_jit_backend.py +1816 -0
  159. package/src/zexus/vm/native_runtime.cpp +1388 -0
  160. package/src/zexus/vm/native_runtime.cpython-312-x86_64-linux-gnu.so +0 -0
  161. package/src/zexus/vm/optimizer.py +161 -11
  162. package/src/zexus/vm/parallel_vm.py +140 -45
  163. package/src/zexus/vm/peephole_optimizer.py +82 -4
  164. package/src/zexus/vm/profiler.py +38 -18
  165. package/src/zexus/vm/register_allocator.py +16 -5
  166. package/src/zexus/vm/register_vm.py +8 -5
  167. package/src/zexus/vm/vm.py +3581 -531
  168. package/src/zexus/vm/wasm_compiler.py +658 -0
  169. package/src/zexus/zexus_ast.py +137 -11
  170. package/src/zexus/zexus_token.py +16 -5
  171. package/src/zexus/zpm/installer.py +55 -15
  172. package/src/zexus/zpm/package_manager.py +1 -1
  173. package/src/zexus/zpm/registry.py +257 -28
  174. package/src/zexus.egg-info/PKG-INFO +16 -6
  175. package/src/zexus.egg-info/SOURCES.txt +129 -17
  176. package/src/zexus.egg-info/entry_points.txt +1 -0
  177. package/src/zexus.egg-info/requires.txt +4 -0
@@ -0,0 +1,282 @@
1
+ """WebSocket client & server module for Zexus standard library.
2
+
3
+ Provides ``WebSocketServer`` and ``WebSocketClient`` backed by the
4
+ ``websockets`` library running on the shared asyncio background loop
5
+ (same one used by the async TCP sockets module).
6
+ """
7
+
8
+ import asyncio
9
+ import threading
10
+ from typing import Callable, Optional, Dict, Any, List
11
+
12
+ # Re-use the background event loop from sockets module
13
+ from .sockets import _get_bg_loop, _run_async
14
+
15
+
16
+ # ---------------------------------------------------------------------------
17
+ # Optional dependency guard
18
+ # ---------------------------------------------------------------------------
19
+ try:
20
+ import websockets
21
+ import websockets.server
22
+ import websockets.client
23
+ _WS_AVAILABLE = True
24
+ except ImportError:
25
+ _WS_AVAILABLE = False
26
+
27
+
28
+ def _require_ws():
29
+ if not _WS_AVAILABLE:
30
+ raise RuntimeError(
31
+ "WebSocket support requires the 'websockets' package. "
32
+ "Install with: pip install websockets"
33
+ )
34
+
35
+
36
+ # ---------------------------------------------------------------------------
37
+ # WebSocket Module (factory)
38
+ # ---------------------------------------------------------------------------
39
+
40
+ class WebSocketModule:
41
+ """Factory for WebSocket servers and clients."""
42
+
43
+ @staticmethod
44
+ def create_server(host: str, port: int, handler: Callable,
45
+ path: Optional[str] = None) -> 'WebSocketServer':
46
+ """Create a WebSocket server.
47
+
48
+ Args:
49
+ host: Host address to bind (e.g. '0.0.0.0').
50
+ port: Port number.
51
+ handler: Callback ``action(ws)`` invoked for each connection.
52
+ ``ws`` is a *WebSocketConnection* with ``send`` /
53
+ ``receive`` / ``close`` methods.
54
+ path: Optional URL path filter (not enforced; for documentation).
55
+
56
+ Returns:
57
+ WebSocketServer instance (call ``.start()`` to begin listening).
58
+ """
59
+ _require_ws()
60
+ return WebSocketServer(host, port, handler, path)
61
+
62
+ @staticmethod
63
+ def connect(url: str, timeout: float = 10.0) -> 'WebSocketClient':
64
+ """Open a WebSocket client connection.
65
+
66
+ Args:
67
+ url: WebSocket URL, e.g. ``ws://localhost:8080/path``.
68
+ timeout: Connection timeout in seconds.
69
+
70
+ Returns:
71
+ WebSocketClient with ``send`` / ``receive`` / ``close``.
72
+ """
73
+ _require_ws()
74
+ return WebSocketClient(url, timeout)
75
+
76
+
77
+ # ---------------------------------------------------------------------------
78
+ # WebSocket Server
79
+ # ---------------------------------------------------------------------------
80
+
81
+ class WebSocketServer:
82
+ """WebSocket server backed by ``websockets.serve``."""
83
+
84
+ def __init__(self, host: str, port: int, handler: Callable,
85
+ path: Optional[str] = None):
86
+ _require_ws()
87
+ self.host = host
88
+ self.port = port
89
+ self.handler = handler
90
+ self.path = path
91
+ self.running = False
92
+ self._server = None
93
+ self._loop = _get_bg_loop()
94
+
95
+ def start(self) -> None:
96
+ if self.running:
97
+ raise RuntimeError("WebSocket server is already running")
98
+ _run_async(self._async_start())
99
+
100
+ def stop(self) -> None:
101
+ if not self.running:
102
+ return
103
+ self.running = False
104
+ if self._server:
105
+ asyncio.run_coroutine_threadsafe(
106
+ self._async_stop(), self._loop
107
+ ).result(timeout=5)
108
+
109
+ def is_running(self) -> bool:
110
+ return self.running
111
+
112
+ def get_address(self) -> Dict[str, Any]:
113
+ return {
114
+ 'host': self.host,
115
+ 'port': self.port,
116
+ 'running': self.running,
117
+ 'path': self.path or '/',
118
+ }
119
+
120
+ # -- async internals ---------------------------------------------------
121
+
122
+ async def _async_start(self):
123
+ self._server = await websockets.server.serve(
124
+ self._async_handle,
125
+ self.host,
126
+ self.port,
127
+ )
128
+ self.running = True
129
+
130
+ async def _async_stop(self):
131
+ if self._server:
132
+ self._server.close()
133
+ await self._server.wait_closed()
134
+ self.running = False
135
+
136
+ async def _async_handle(self, ws):
137
+ """Per-connection handler coroutine."""
138
+ conn = WebSocketConnection(ws)
139
+ loop = asyncio.get_running_loop()
140
+ try:
141
+ # Run sync handler in thread executor to avoid deadlock
142
+ await loop.run_in_executor(None, self.handler, conn)
143
+ except Exception as e:
144
+ print(f"WebSocket handler error: {e}")
145
+ finally:
146
+ conn._closed = True
147
+
148
+
149
+ # ---------------------------------------------------------------------------
150
+ # WebSocket Client
151
+ # ---------------------------------------------------------------------------
152
+
153
+ class WebSocketClient:
154
+ """WebSocket client connection."""
155
+
156
+ def __init__(self, url: str, timeout: float = 10.0):
157
+ _require_ws()
158
+ self.url = url
159
+ self._ws = None
160
+ self._closed = False
161
+
162
+ async def _connect():
163
+ return await asyncio.wait_for(
164
+ websockets.client.connect(url), timeout=timeout
165
+ )
166
+
167
+ self._ws = _run_async(_connect())
168
+
169
+ def send(self, message: str) -> None:
170
+ """Send a text message."""
171
+ if self._closed:
172
+ raise RuntimeError("WebSocket is closed")
173
+
174
+ async def _send():
175
+ await self._ws.send(message)
176
+
177
+ _run_async(_send())
178
+
179
+ def send_bytes(self, data: bytes) -> None:
180
+ """Send binary data."""
181
+ if self._closed:
182
+ raise RuntimeError("WebSocket is closed")
183
+
184
+ async def _send():
185
+ await self._ws.send(data)
186
+
187
+ _run_async(_send())
188
+
189
+ def receive(self, timeout: float = 30.0) -> str:
190
+ """Receive a text message."""
191
+ if self._closed:
192
+ raise RuntimeError("WebSocket is closed")
193
+
194
+ async def _recv():
195
+ return await asyncio.wait_for(self._ws.recv(), timeout=timeout)
196
+
197
+ return _run_async(_recv())
198
+
199
+ def receive_bytes(self, timeout: float = 30.0) -> bytes:
200
+ """Receive binary data."""
201
+ return self.receive(timeout) # websockets handles both
202
+
203
+ def close(self) -> None:
204
+ if self._closed:
205
+ return
206
+ self._closed = True
207
+ try:
208
+ async def _close():
209
+ await self._ws.close()
210
+ _run_async(_close(), timeout=5)
211
+ except Exception:
212
+ pass
213
+
214
+ def is_connected(self) -> bool:
215
+ return not self._closed and self._ws is not None
216
+
217
+ def get_address(self) -> Dict[str, Any]:
218
+ return {'url': self.url, 'connected': self.is_connected()}
219
+
220
+
221
+ # ---------------------------------------------------------------------------
222
+ # WebSocket Connection (server-side wrapper)
223
+ # ---------------------------------------------------------------------------
224
+
225
+ class WebSocketConnection:
226
+ """Wraps a server-side websocket for use in synchronous Zexus handlers."""
227
+
228
+ def __init__(self, ws):
229
+ self._ws = ws
230
+ self._closed = False
231
+
232
+ def send(self, message: str) -> None:
233
+ """Send a text message to the client."""
234
+ if self._closed:
235
+ raise RuntimeError("WebSocket is closed")
236
+
237
+ async def _send():
238
+ await self._ws.send(message)
239
+
240
+ _run_async(_send())
241
+
242
+ def send_bytes(self, data: bytes) -> None:
243
+ """Send binary data to the client."""
244
+ if self._closed:
245
+ raise RuntimeError("WebSocket is closed")
246
+
247
+ async def _send():
248
+ await self._ws.send(data)
249
+
250
+ _run_async(_send())
251
+
252
+ def receive(self, timeout: float = 30.0) -> str:
253
+ """Receive a message from the client."""
254
+ if self._closed:
255
+ raise RuntimeError("WebSocket is closed")
256
+
257
+ async def _recv():
258
+ return await asyncio.wait_for(self._ws.recv(), timeout=timeout)
259
+
260
+ return _run_async(_recv())
261
+
262
+ def close(self) -> None:
263
+ if self._closed:
264
+ return
265
+ self._closed = True
266
+ try:
267
+ async def _close():
268
+ await self._ws.close()
269
+ _run_async(_close(), timeout=5)
270
+ except Exception:
271
+ pass
272
+
273
+ def is_connected(self) -> bool:
274
+ return not self._closed
275
+
276
+ def get_address(self) -> Dict[str, Any]:
277
+ remote = getattr(self._ws, 'remote_address', None) or ('unknown', 0)
278
+ return {
279
+ 'host': remote[0] if isinstance(remote, tuple) else str(remote),
280
+ 'port': remote[1] if isinstance(remote, tuple) and len(remote) > 1 else 0,
281
+ 'connected': self.is_connected(),
282
+ }
@@ -234,10 +234,208 @@ def create_stdlib_module(module_name, evaluator=None):
234
234
  except Exception as e:
235
235
  return EvaluationError(f"pbkdf2 error: {str(e)}")
236
236
 
237
+ # generate_keypair(algorithm?) and derive_address(public_key, [prefix])
238
+ try:
239
+ from .blockchain.crypto import CryptoPlugin as _BCPlugin
240
+
241
+ def _crypto_generate_keypair(*args):
242
+ algorithm = args[0].value if len(args) > 0 and hasattr(args[0], 'value') else 'ECDSA'
243
+ try:
244
+ private_key, public_key = _BCPlugin.generate_keypair(algorithm)
245
+ return Map({
246
+ String('private_key'): String(private_key),
247
+ String('public_key'): String(public_key)
248
+ })
249
+ except Exception as e:
250
+ return EvaluationError(f"Keypair generation error: {str(e)}")
251
+
252
+ def _crypto_derive_address(*args):
253
+ if len(args) < 1 or len(args) > 2:
254
+ return EvaluationError("derive_address() expects 1 or 2 arguments: public_key, [prefix]")
255
+ public_key = args[0].value if hasattr(args[0], 'value') else str(args[0])
256
+ prefix = None
257
+ if len(args) > 1:
258
+ prefix = args[1].value if hasattr(args[1], 'value') else str(args[1])
259
+ try:
260
+ result = _BCPlugin.derive_address(public_key, prefix=prefix)
261
+ return String(result)
262
+ except Exception as e:
263
+ return EvaluationError(f"Address derivation error: {str(e)}")
264
+
265
+ env.set("generate_keypair", Builtin(_crypto_generate_keypair))
266
+ env.set("derive_address", Builtin(_crypto_derive_address))
267
+ # Also register camelCase aliases used by demo files
268
+ env.set("generateKeypair", Builtin(_crypto_generate_keypair))
269
+ env.set("deriveAddress", Builtin(_crypto_derive_address))
270
+ except ImportError:
271
+ pass # blockchain.crypto not available
272
+
237
273
  env.set("hash_sha256", Builtin(_crypto_hash_sha256))
238
274
  env.set("keccak256", Builtin(_crypto_keccak256))
239
275
  env.set("random_bytes", Builtin(_crypto_random_bytes))
240
276
  env.set("pbkdf2", Builtin(_crypto_pbkdf2))
277
+
278
+ elif module_name == "perf" or module_name == "stdlib/perf":
279
+ def _perf_vm_stats(*args):
280
+ if evaluator is None or not hasattr(evaluator, "unified_executor") or not evaluator.unified_executor:
281
+ return EvaluationError("perf.vm_stats() requires unified executor")
282
+ stats = evaluator.unified_executor.get_statistics()
283
+ return _python_to_zexus(stats)
284
+
285
+ def _perf_set_vm_thresholds(*args):
286
+ if evaluator is None or not hasattr(evaluator, "unified_executor") or not evaluator.unified_executor:
287
+ return EvaluationError("perf.set_vm_thresholds() requires unified executor")
288
+ workload = evaluator.unified_executor.workload
289
+ if len(args) >= 1:
290
+ val = _zexus_to_python(args[0])
291
+ if isinstance(val, int):
292
+ workload.vm_threshold = val
293
+ if len(args) >= 2:
294
+ val = _zexus_to_python(args[1])
295
+ if isinstance(val, int):
296
+ workload.jit_threshold = val
297
+ if len(args) >= 3:
298
+ val = _zexus_to_python(args[2])
299
+ if isinstance(val, int):
300
+ workload.parallel_threshold = val
301
+ return Boolean(True)
302
+
303
+ def _perf_enable_vm(*args):
304
+ if evaluator is None:
305
+ return EvaluationError("perf.enable_vm() requires evaluator")
306
+ flag = True
307
+ if len(args) >= 1:
308
+ val = _zexus_to_python(args[0])
309
+ flag = bool(val)
310
+ evaluator.use_vm = flag
311
+ if evaluator.unified_executor:
312
+ evaluator.unified_executor.vm_enabled = flag
313
+ return Boolean(True)
314
+
315
+ def _perf_collect_gc(*args):
316
+ if evaluator is None or not hasattr(evaluator, "unified_executor") or not evaluator.unified_executor:
317
+ return EvaluationError("perf.collect_gc() requires unified executor")
318
+ vm = evaluator.unified_executor.vm
319
+ if vm is None:
320
+ return EvaluationError("perf.collect_gc() requires VM initialization")
321
+ force = False
322
+ if len(args) >= 1:
323
+ force = bool(_zexus_to_python(args[0]))
324
+ result = vm.collect_garbage(force=force)
325
+ return _python_to_zexus(result)
326
+
327
+ def _perf_memory_stats(*args):
328
+ if evaluator is None or not hasattr(evaluator, "unified_executor") or not evaluator.unified_executor:
329
+ return EvaluationError("perf.memory_stats() requires unified executor")
330
+ vm = evaluator.unified_executor.vm
331
+ if vm is None:
332
+ return EvaluationError("perf.memory_stats() requires VM initialization")
333
+ stats = vm.get_memory_stats()
334
+ return _python_to_zexus(stats)
335
+
336
+ def _perf_warmup(*args):
337
+ if evaluator is None or not hasattr(evaluator, "unified_executor") or not evaluator.unified_executor:
338
+ return EvaluationError("perf.warmup() requires unified executor")
339
+ workload = evaluator.unified_executor.workload
340
+ vm_threshold = 1
341
+ jit_threshold = workload.jit_threshold
342
+ if len(args) >= 1:
343
+ val = _zexus_to_python(args[0])
344
+ if isinstance(val, int):
345
+ vm_threshold = val
346
+ if len(args) >= 2:
347
+ val = _zexus_to_python(args[1])
348
+ if isinstance(val, int):
349
+ jit_threshold = val
350
+ workload.vm_threshold = vm_threshold
351
+ workload.jit_threshold = jit_threshold
352
+ return Boolean(True)
353
+
354
+ def _perf_profile_start(*args):
355
+ if evaluator is None or not hasattr(evaluator, "unified_executor") or not evaluator.unified_executor:
356
+ return EvaluationError("perf.profile_start() requires unified executor")
357
+ evaluator.unified_executor.ensure_vm(profile_active=True)
358
+ vm = evaluator.unified_executor.vm
359
+ if vm is None:
360
+ return EvaluationError("perf.profile_start() requires VM initialization")
361
+ vm.start_profiling()
362
+ return Boolean(True)
363
+
364
+ def _perf_profile_stop(*args):
365
+ if evaluator is None or not hasattr(evaluator, "unified_executor") or not evaluator.unified_executor:
366
+ return EvaluationError("perf.profile_stop() requires unified executor")
367
+ vm = evaluator.unified_executor.vm
368
+ if vm is None:
369
+ return EvaluationError("perf.profile_stop() requires VM initialization")
370
+ vm.stop_profiling()
371
+ return Boolean(True)
372
+
373
+ def _perf_profile_report(*args):
374
+ if evaluator is None or not hasattr(evaluator, "unified_executor") or not evaluator.unified_executor:
375
+ return EvaluationError("perf.profile_report() requires unified executor")
376
+ evaluator.unified_executor.ensure_vm(profile_active=True)
377
+ vm = evaluator.unified_executor.vm
378
+ if vm is None:
379
+ return EvaluationError("perf.profile_report() requires VM initialization")
380
+ report_format = "text"
381
+ top_n = 20
382
+ if len(args) >= 1:
383
+ report_format = str(_zexus_to_python(args[0]))
384
+ if len(args) >= 2:
385
+ val = _zexus_to_python(args[1])
386
+ if isinstance(val, int):
387
+ top_n = val
388
+ report = vm.get_profiling_report(format=report_format, top_n=top_n)
389
+ return String(report)
390
+
391
+ def _perf_set_vm_config(*args):
392
+ if evaluator is None or not hasattr(evaluator, "unified_executor") or not evaluator.unified_executor:
393
+ return EvaluationError("perf.set_vm_config() requires unified executor")
394
+ if len(args) < 1:
395
+ return EvaluationError("perf.set_vm_config() requires 1 argument: config map")
396
+ config = _zexus_to_python(args[0])
397
+ if not isinstance(config, dict):
398
+ return EvaluationError("perf.set_vm_config() expects a map")
399
+ evaluator.unified_executor.configure_vm(config)
400
+ return Boolean(True)
401
+
402
+ def _perf_set_vm_mode(*args):
403
+ if evaluator is None or not hasattr(evaluator, "unified_executor") or not evaluator.unified_executor:
404
+ return EvaluationError("perf.set_vm_mode() requires unified executor")
405
+ if len(args) < 1:
406
+ return EvaluationError("perf.set_vm_mode() requires 1 argument: mode")
407
+ mode_value = _zexus_to_python(args[0])
408
+ evaluator.unified_executor.configure_vm({"mode": mode_value})
409
+ return Boolean(True)
410
+
411
+ def _perf_force_vm_loops(*args):
412
+ if evaluator is None or not hasattr(evaluator, "unified_executor") or not evaluator.unified_executor:
413
+ return EvaluationError("perf.force_vm_loops() requires unified executor")
414
+ flag = True
415
+ if len(args) >= 1:
416
+ flag = bool(_zexus_to_python(args[0]))
417
+ evaluator.unified_executor.set_force_vm_loops(flag)
418
+ return Boolean(True)
419
+
420
+ def _perf_reset_vm(*args):
421
+ if evaluator is None or not hasattr(evaluator, "unified_executor") or not evaluator.unified_executor:
422
+ return EvaluationError("perf.reset_vm() requires unified executor")
423
+ evaluator.unified_executor.reset_vm()
424
+ return Boolean(True)
425
+
426
+ env.set("vm_stats", Builtin(_perf_vm_stats))
427
+ env.set("set_vm_thresholds", Builtin(_perf_set_vm_thresholds))
428
+ env.set("enable_vm", Builtin(_perf_enable_vm))
429
+ env.set("collect_gc", Builtin(_perf_collect_gc))
430
+ env.set("memory_stats", Builtin(_perf_memory_stats))
431
+ env.set("warmup", Builtin(_perf_warmup))
432
+ env.set("profile_start", Builtin(_perf_profile_start))
433
+ env.set("profile_stop", Builtin(_perf_profile_stop))
434
+ env.set("profile_report", Builtin(_perf_profile_report))
435
+ env.set("set_vm_config", Builtin(_perf_set_vm_config))
436
+ env.set("set_vm_mode", Builtin(_perf_set_vm_mode))
437
+ env.set("force_vm_loops", Builtin(_perf_force_vm_loops))
438
+ env.set("reset_vm", Builtin(_perf_reset_vm))
241
439
 
242
440
  elif module_name == "blockchain" or module_name == "stdlib/blockchain":
243
441
  from .stdlib.blockchain import BlockchainModule
@@ -283,11 +481,180 @@ def create_stdlib_module(module_name, evaluator=None):
283
481
  except Exception as e:
284
482
  return EvaluationError(f"create_genesis_block error: {str(e)}")
285
483
 
484
+ def _blockchain_create_block(*args):
485
+ if len(args) < 4:
486
+ return EvaluationError("create_block() requires 4 args: index, timestamp, data, previous_hash")
487
+ index = int(args[0].value if hasattr(args[0], 'value') else args[0])
488
+ timestamp = float(args[1].value if hasattr(args[1], 'value') else args[1])
489
+ data = args[2].value if hasattr(args[2], 'value') else str(args[2])
490
+ prev_hash = args[3].value if hasattr(args[3], 'value') else str(args[3])
491
+ nonce = int(args[4].value if hasattr(args[4], 'value') else args[4]) if len(args) > 4 else 0
492
+ try:
493
+ result = BlockchainModule.create_block(index, timestamp, data, prev_hash, nonce)
494
+ return _python_to_zexus(result)
495
+ except Exception as e:
496
+ return EvaluationError(f"create_block error: {str(e)}")
497
+
498
+ def _blockchain_hash_block(*args):
499
+ if len(args) < 1:
500
+ return EvaluationError("hash_block() requires 1 argument: block (map)")
501
+ block_obj = args[0]
502
+ block = {}
503
+ if isinstance(block_obj, Map):
504
+ for k, v in block_obj.pairs.items():
505
+ key = k.value if hasattr(k, 'value') else str(k)
506
+ val = v.value if hasattr(v, 'value') else str(v)
507
+ block[key] = val
508
+ try:
509
+ result = BlockchainModule.hash_block(block)
510
+ return String(result)
511
+ except Exception as e:
512
+ return EvaluationError(f"hash_block error: {str(e)}")
513
+
514
+ def _blockchain_validate_block(*args):
515
+ if len(args) < 1:
516
+ return EvaluationError("validate_block() requires 1 argument: block")
517
+ block_obj = args[0]
518
+ block = {}
519
+ if isinstance(block_obj, Map):
520
+ for k, v in block_obj.pairs.items():
521
+ key = k.value if hasattr(k, 'value') else str(k)
522
+ val = v.value if hasattr(v, 'value') else str(v)
523
+ block[key] = val
524
+ prev = None
525
+ if len(args) > 1 and isinstance(args[1], Map):
526
+ prev = {}
527
+ for k, v in args[1].pairs.items():
528
+ key = k.value if hasattr(k, 'value') else str(k)
529
+ val = v.value if hasattr(v, 'value') else str(v)
530
+ prev[key] = val
531
+ try:
532
+ result = BlockchainModule.validate_block(block, prev)
533
+ return Boolean(result)
534
+ except Exception as e:
535
+ return EvaluationError(f"validate_block error: {str(e)}")
536
+
537
+ def _blockchain_proof_of_work(*args):
538
+ if len(args) < 1:
539
+ return EvaluationError("proof_of_work() requires 1 argument: block_data")
540
+ block_data = args[0].value if hasattr(args[0], 'value') else str(args[0])
541
+ difficulty = int(args[1].value if hasattr(args[1], 'value') else args[1]) if len(args) > 1 else 4
542
+ max_iter = int(args[2].value if hasattr(args[2], 'value') else args[2]) if len(args) > 2 else 1000000
543
+ try:
544
+ nonce, hash_val = BlockchainModule.proof_of_work(block_data, difficulty, max_iter)
545
+ return _python_to_zexus({"nonce": nonce, "hash": hash_val})
546
+ except Exception as e:
547
+ return EvaluationError(f"proof_of_work error: {str(e)}")
548
+
549
+ def _blockchain_create_transaction(*args):
550
+ if len(args) < 3:
551
+ return EvaluationError("create_transaction() requires 3 args: sender, recipient, amount")
552
+ sender = args[0].value if hasattr(args[0], 'value') else str(args[0])
553
+ recipient = args[1].value if hasattr(args[1], 'value') else str(args[1])
554
+ amount = float(args[2].value if hasattr(args[2], 'value') else args[2])
555
+ timestamp = float(args[3].value if hasattr(args[3], 'value') else args[3]) if len(args) > 3 else None
556
+ try:
557
+ result = BlockchainModule.create_transaction(sender, recipient, amount, timestamp)
558
+ return _python_to_zexus(result)
559
+ except Exception as e:
560
+ return EvaluationError(f"create_transaction error: {str(e)}")
561
+
562
+ def _blockchain_hash_transaction(*args):
563
+ if len(args) < 1:
564
+ return EvaluationError("hash_transaction() requires 1 argument: transaction")
565
+ tx_obj = args[0]
566
+ tx = {}
567
+ if isinstance(tx_obj, Map):
568
+ for k, v in tx_obj.pairs.items():
569
+ key = k.value if hasattr(k, 'value') else str(k)
570
+ val = v.value if hasattr(v, 'value') else str(v)
571
+ tx[key] = val
572
+ try:
573
+ result = BlockchainModule.hash_transaction(tx)
574
+ return String(result)
575
+ except Exception as e:
576
+ return EvaluationError(f"hash_transaction error: {str(e)}")
577
+
578
+ def _blockchain_validate_chain(*args):
579
+ if len(args) < 1:
580
+ return EvaluationError("validate_chain() requires 1 argument: chain (list of blocks)")
581
+ if not isinstance(args[0], ListObj):
582
+ return EvaluationError("validate_chain() expects a list of block maps")
583
+ chain = []
584
+ for block_obj in args[0].elements:
585
+ block = {}
586
+ if isinstance(block_obj, Map):
587
+ for k, v in block_obj.pairs.items():
588
+ key = k.value if hasattr(k, 'value') else str(k)
589
+ val = v.value if hasattr(v, 'value') else str(v)
590
+ block[key] = val
591
+ chain.append(block)
592
+ try:
593
+ result = BlockchainModule.validate_chain(chain)
594
+ return Boolean(result)
595
+ except Exception as e:
596
+ return EvaluationError(f"validate_chain error: {str(e)}")
597
+
286
598
  env.set("create_address", Builtin(_blockchain_create_address))
287
599
  env.set("validate_address", Builtin(_blockchain_validate_address))
288
600
  env.set("calculate_merkle_root", Builtin(_blockchain_calculate_merkle_root))
289
601
  env.set("create_genesis_block", Builtin(_blockchain_create_genesis_block))
290
-
602
+ env.set("create_block", Builtin(_blockchain_create_block))
603
+ env.set("hash_block", Builtin(_blockchain_hash_block))
604
+ env.set("validate_block", Builtin(_blockchain_validate_block))
605
+ env.set("proof_of_work", Builtin(_blockchain_proof_of_work))
606
+ env.set("create_transaction", Builtin(_blockchain_create_transaction))
607
+ env.set("hash_transaction", Builtin(_blockchain_hash_transaction))
608
+ env.set("validate_chain", Builtin(_blockchain_validate_chain))
609
+
610
+ elif module_name == "websocket" or module_name == "stdlib/websocket":
611
+ try:
612
+ from .stdlib.websockets import WebSocketModule
613
+ except ImportError:
614
+ return env # websockets package not installed
615
+
616
+ def _ws_create_server(*args):
617
+ if len(args) < 3:
618
+ return EvaluationError("ws_create_server() requires 3 args: host, port, handler")
619
+ host = args[0].value if hasattr(args[0], 'value') else str(args[0])
620
+ port = int(args[1].value if hasattr(args[1], 'value') else args[1])
621
+ handler = args[2] # Zexus Action/Builtin — caller wraps
622
+ path = args[3].value if len(args) > 3 and hasattr(args[3], 'value') else None
623
+ try:
624
+ server = WebSocketModule.create_server(host, port, handler, path)
625
+ server.start()
626
+ stop_fn = Builtin(lambda *_a: (server.stop(), Boolean(True))[1])
627
+ is_running_fn = Builtin(lambda *_a: Boolean(server.is_running()))
628
+ return Map({
629
+ String("stop"): stop_fn,
630
+ String("is_running"): is_running_fn,
631
+ })
632
+ except Exception as e:
633
+ return EvaluationError(f"ws_create_server error: {e}")
634
+
635
+ def _ws_connect(*args):
636
+ if len(args) < 1:
637
+ return EvaluationError("ws_connect() requires 1 arg: url")
638
+ url = args[0].value if hasattr(args[0], 'value') else str(args[0])
639
+ timeout = float(args[1].value if len(args) > 1 and hasattr(args[1], 'value') else 10)
640
+ try:
641
+ client = WebSocketModule.connect(url, timeout)
642
+ send_fn = Builtin(lambda *a: (client.send(a[0].value if hasattr(a[0], 'value') else str(a[0])), Boolean(True))[1])
643
+ recv_fn = Builtin(lambda *a: String(client.receive(float(a[0].value) if a else 30)))
644
+ close_fn = Builtin(lambda *_a: (client.close(), Boolean(True))[1])
645
+ connected_fn = Builtin(lambda *_a: Boolean(client.is_connected()))
646
+ return Map({
647
+ String("send"): send_fn,
648
+ String("receive"): recv_fn,
649
+ String("close"): close_fn,
650
+ String("is_connected"): connected_fn,
651
+ })
652
+ except Exception as e:
653
+ return EvaluationError(f"ws_connect error: {e}")
654
+
655
+ env.set("create_server", Builtin(_ws_create_server))
656
+ env.set("connect", Builtin(_ws_connect))
657
+
291
658
  return env
292
659
 
293
660
 
@@ -323,7 +690,7 @@ def _zexus_to_python(obj):
323
690
 
324
691
  def is_stdlib_module(module_name):
325
692
  """Check if a module name refers to a stdlib module."""
326
- stdlib_modules = ['fs', 'http', 'json', 'datetime', 'crypto', 'blockchain']
693
+ stdlib_modules = ['fs', 'http', 'json', 'datetime', 'crypto', 'blockchain', 'perf', 'websocket']
327
694
 
328
695
  # Handle both "fs" and "stdlib/fs" formats
329
696
  if module_name in stdlib_modules: