zexus 1.6.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 (227) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +2513 -0
  3. package/bin/zexus +2 -0
  4. package/bin/zpics +2 -0
  5. package/bin/zpm +2 -0
  6. package/bin/zx +2 -0
  7. package/bin/zx-deploy +2 -0
  8. package/bin/zx-dev +2 -0
  9. package/bin/zx-run +2 -0
  10. package/package.json +66 -0
  11. package/scripts/README.md +24 -0
  12. package/scripts/postinstall.js +44 -0
  13. package/shared_config.json +24 -0
  14. package/src/README.md +1525 -0
  15. package/src/tests/run_zexus_tests.py +117 -0
  16. package/src/tests/test_all_phases.zx +346 -0
  17. package/src/tests/test_blockchain_features.zx +306 -0
  18. package/src/tests/test_complexity_features.zx +321 -0
  19. package/src/tests/test_core_integration.py +185 -0
  20. package/src/tests/test_phase10_ecosystem.zx +177 -0
  21. package/src/tests/test_phase1_modifiers.zx +87 -0
  22. package/src/tests/test_phase2_plugins.zx +80 -0
  23. package/src/tests/test_phase3_security.zx +97 -0
  24. package/src/tests/test_phase4_vfs.zx +116 -0
  25. package/src/tests/test_phase5_types.zx +117 -0
  26. package/src/tests/test_phase6_metaprogramming.zx +125 -0
  27. package/src/tests/test_phase7_optimization.zx +132 -0
  28. package/src/tests/test_phase9_advanced_types.zx +157 -0
  29. package/src/tests/test_security_features.py +419 -0
  30. package/src/tests/test_security_features.zx +276 -0
  31. package/src/tests/test_simple_zx.zx +1 -0
  32. package/src/tests/test_verification_simple.zx +69 -0
  33. package/src/zexus/__init__.py +28 -0
  34. package/src/zexus/__main__.py +5 -0
  35. package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
  36. package/src/zexus/__pycache__/advanced_types.cpython-312.pyc +0 -0
  37. package/src/zexus/__pycache__/builtin_modules.cpython-312.pyc +0 -0
  38. package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
  39. package/src/zexus/__pycache__/complexity_system.cpython-312.pyc +0 -0
  40. package/src/zexus/__pycache__/concurrency_system.cpython-312.pyc +0 -0
  41. package/src/zexus/__pycache__/config.cpython-312.pyc +0 -0
  42. package/src/zexus/__pycache__/dependency_injection.cpython-312.pyc +0 -0
  43. package/src/zexus/__pycache__/ecosystem.cpython-312.pyc +0 -0
  44. package/src/zexus/__pycache__/environment.cpython-312.pyc +0 -0
  45. package/src/zexus/__pycache__/error_reporter.cpython-312.pyc +0 -0
  46. package/src/zexus/__pycache__/hybrid_orchestrator.cpython-312.pyc +0 -0
  47. package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
  48. package/src/zexus/__pycache__/metaprogramming.cpython-312.pyc +0 -0
  49. package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
  50. package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
  51. package/src/zexus/__pycache__/optimization.cpython-312.pyc +0 -0
  52. package/src/zexus/__pycache__/plugin_system.cpython-312.pyc +0 -0
  53. package/src/zexus/__pycache__/policy_engine.cpython-312.pyc +0 -0
  54. package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
  55. package/src/zexus/__pycache__/stdlib_integration.cpython-312.pyc +0 -0
  56. package/src/zexus/__pycache__/strategy_recovery.cpython-312.pyc +0 -0
  57. package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
  58. package/src/zexus/__pycache__/type_system.cpython-312.pyc +0 -0
  59. package/src/zexus/__pycache__/virtual_filesystem.cpython-312.pyc +0 -0
  60. package/src/zexus/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  61. package/src/zexus/__pycache__/zexus_token.cpython-312.pyc +0 -0
  62. package/src/zexus/advanced_types.py +401 -0
  63. package/src/zexus/blockchain/__init__.py +40 -0
  64. package/src/zexus/blockchain/__pycache__/__init__.cpython-312.pyc +0 -0
  65. package/src/zexus/blockchain/__pycache__/crypto.cpython-312.pyc +0 -0
  66. package/src/zexus/blockchain/__pycache__/ledger.cpython-312.pyc +0 -0
  67. package/src/zexus/blockchain/__pycache__/transaction.cpython-312.pyc +0 -0
  68. package/src/zexus/blockchain/crypto.py +463 -0
  69. package/src/zexus/blockchain/ledger.py +255 -0
  70. package/src/zexus/blockchain/transaction.py +267 -0
  71. package/src/zexus/builtin_modules.py +284 -0
  72. package/src/zexus/builtin_plugins.py +317 -0
  73. package/src/zexus/capability_system.py +372 -0
  74. package/src/zexus/cli/__init__.py +2 -0
  75. package/src/zexus/cli/__pycache__/__init__.cpython-312.pyc +0 -0
  76. package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
  77. package/src/zexus/cli/main.py +707 -0
  78. package/src/zexus/cli/zpm.py +203 -0
  79. package/src/zexus/compare_interpreter_compiler.py +146 -0
  80. package/src/zexus/compiler/__init__.py +169 -0
  81. package/src/zexus/compiler/__pycache__/__init__.cpython-312.pyc +0 -0
  82. package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
  83. package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
  84. package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  85. package/src/zexus/compiler/bytecode.py +266 -0
  86. package/src/zexus/compiler/compat_runtime.py +277 -0
  87. package/src/zexus/compiler/lexer.py +257 -0
  88. package/src/zexus/compiler/parser.py +779 -0
  89. package/src/zexus/compiler/semantic.py +118 -0
  90. package/src/zexus/compiler/zexus_ast.py +454 -0
  91. package/src/zexus/complexity_system.py +575 -0
  92. package/src/zexus/concurrency_system.py +493 -0
  93. package/src/zexus/config.py +201 -0
  94. package/src/zexus/crypto_bridge.py +19 -0
  95. package/src/zexus/dependency_injection.py +423 -0
  96. package/src/zexus/ecosystem.py +434 -0
  97. package/src/zexus/environment.py +101 -0
  98. package/src/zexus/environment_manager.py +119 -0
  99. package/src/zexus/error_reporter.py +314 -0
  100. package/src/zexus/evaluator/__init__.py +12 -0
  101. package/src/zexus/evaluator/__pycache__/__init__.cpython-312.pyc +0 -0
  102. package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
  103. package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
  104. package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
  105. package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
  106. package/src/zexus/evaluator/__pycache__/integration.cpython-312.pyc +0 -0
  107. package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
  108. package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
  109. package/src/zexus/evaluator/bytecode_compiler.py +700 -0
  110. package/src/zexus/evaluator/core.py +891 -0
  111. package/src/zexus/evaluator/expressions.py +827 -0
  112. package/src/zexus/evaluator/functions.py +3989 -0
  113. package/src/zexus/evaluator/integration.py +396 -0
  114. package/src/zexus/evaluator/statements.py +4303 -0
  115. package/src/zexus/evaluator/utils.py +126 -0
  116. package/src/zexus/evaluator_original.py +2041 -0
  117. package/src/zexus/external_bridge.py +16 -0
  118. package/src/zexus/find_affected_imports.sh +155 -0
  119. package/src/zexus/hybrid_orchestrator.py +152 -0
  120. package/src/zexus/input_validation.py +259 -0
  121. package/src/zexus/lexer.py +571 -0
  122. package/src/zexus/logging.py +89 -0
  123. package/src/zexus/lsp/__init__.py +9 -0
  124. package/src/zexus/lsp/completion_provider.py +207 -0
  125. package/src/zexus/lsp/definition_provider.py +22 -0
  126. package/src/zexus/lsp/hover_provider.py +71 -0
  127. package/src/zexus/lsp/server.py +269 -0
  128. package/src/zexus/lsp/symbol_provider.py +31 -0
  129. package/src/zexus/metaprogramming.py +321 -0
  130. package/src/zexus/module_cache.py +89 -0
  131. package/src/zexus/module_manager.py +107 -0
  132. package/src/zexus/object.py +973 -0
  133. package/src/zexus/optimization.py +424 -0
  134. package/src/zexus/parser/__init__.py +31 -0
  135. package/src/zexus/parser/__pycache__/__init__.cpython-312.pyc +0 -0
  136. package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
  137. package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
  138. package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
  139. package/src/zexus/parser/integration.py +86 -0
  140. package/src/zexus/parser/parser.py +3977 -0
  141. package/src/zexus/parser/strategy_context.py +7254 -0
  142. package/src/zexus/parser/strategy_structural.py +1033 -0
  143. package/src/zexus/persistence.py +391 -0
  144. package/src/zexus/plugin_system.py +290 -0
  145. package/src/zexus/policy_engine.py +365 -0
  146. package/src/zexus/profiler/__init__.py +5 -0
  147. package/src/zexus/profiler/profiler.py +233 -0
  148. package/src/zexus/purity_system.py +398 -0
  149. package/src/zexus/runtime/__init__.py +20 -0
  150. package/src/zexus/runtime/async_runtime.py +324 -0
  151. package/src/zexus/search_old_imports.sh +65 -0
  152. package/src/zexus/security.py +1407 -0
  153. package/src/zexus/stack_trace.py +233 -0
  154. package/src/zexus/stdlib/__init__.py +27 -0
  155. package/src/zexus/stdlib/blockchain.py +341 -0
  156. package/src/zexus/stdlib/compression.py +167 -0
  157. package/src/zexus/stdlib/crypto.py +124 -0
  158. package/src/zexus/stdlib/datetime.py +163 -0
  159. package/src/zexus/stdlib/db_mongo.py +199 -0
  160. package/src/zexus/stdlib/db_mysql.py +162 -0
  161. package/src/zexus/stdlib/db_postgres.py +163 -0
  162. package/src/zexus/stdlib/db_sqlite.py +133 -0
  163. package/src/zexus/stdlib/encoding.py +230 -0
  164. package/src/zexus/stdlib/fs.py +195 -0
  165. package/src/zexus/stdlib/http.py +219 -0
  166. package/src/zexus/stdlib/http_server.py +248 -0
  167. package/src/zexus/stdlib/json_module.py +61 -0
  168. package/src/zexus/stdlib/math.py +360 -0
  169. package/src/zexus/stdlib/os_module.py +265 -0
  170. package/src/zexus/stdlib/regex.py +148 -0
  171. package/src/zexus/stdlib/sockets.py +253 -0
  172. package/src/zexus/stdlib/test_framework.zx +208 -0
  173. package/src/zexus/stdlib/test_runner.zx +119 -0
  174. package/src/zexus/stdlib_integration.py +341 -0
  175. package/src/zexus/strategy_recovery.py +256 -0
  176. package/src/zexus/syntax_validator.py +356 -0
  177. package/src/zexus/testing/zpics.py +407 -0
  178. package/src/zexus/testing/zpics_runtime.py +369 -0
  179. package/src/zexus/type_system.py +374 -0
  180. package/src/zexus/validation_system.py +569 -0
  181. package/src/zexus/virtual_filesystem.py +355 -0
  182. package/src/zexus/vm/__init__.py +8 -0
  183. package/src/zexus/vm/__pycache__/__init__.cpython-312.pyc +0 -0
  184. package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
  185. package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
  186. package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
  187. package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
  188. package/src/zexus/vm/__pycache__/memory_manager.cpython-312.pyc +0 -0
  189. package/src/zexus/vm/__pycache__/memory_pool.cpython-312.pyc +0 -0
  190. package/src/zexus/vm/__pycache__/optimizer.cpython-312.pyc +0 -0
  191. package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
  192. package/src/zexus/vm/__pycache__/peephole_optimizer.cpython-312.pyc +0 -0
  193. package/src/zexus/vm/__pycache__/profiler.cpython-312.pyc +0 -0
  194. package/src/zexus/vm/__pycache__/register_allocator.cpython-312.pyc +0 -0
  195. package/src/zexus/vm/__pycache__/register_vm.cpython-312.pyc +0 -0
  196. package/src/zexus/vm/__pycache__/ssa_converter.cpython-312.pyc +0 -0
  197. package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
  198. package/src/zexus/vm/async_optimizer.py +420 -0
  199. package/src/zexus/vm/bytecode.py +428 -0
  200. package/src/zexus/vm/bytecode_converter.py +297 -0
  201. package/src/zexus/vm/cache.py +532 -0
  202. package/src/zexus/vm/jit.py +720 -0
  203. package/src/zexus/vm/memory_manager.py +520 -0
  204. package/src/zexus/vm/memory_pool.py +511 -0
  205. package/src/zexus/vm/optimizer.py +478 -0
  206. package/src/zexus/vm/parallel_vm.py +899 -0
  207. package/src/zexus/vm/peephole_optimizer.py +452 -0
  208. package/src/zexus/vm/profiler.py +527 -0
  209. package/src/zexus/vm/register_allocator.py +462 -0
  210. package/src/zexus/vm/register_vm.py +520 -0
  211. package/src/zexus/vm/ssa_converter.py +757 -0
  212. package/src/zexus/vm/vm.py +1392 -0
  213. package/src/zexus/zexus_ast.py +1782 -0
  214. package/src/zexus/zexus_token.py +253 -0
  215. package/src/zexus/zpm/__init__.py +15 -0
  216. package/src/zexus/zpm/installer.py +116 -0
  217. package/src/zexus/zpm/package_manager.py +208 -0
  218. package/src/zexus/zpm/publisher.py +98 -0
  219. package/src/zexus/zpm/registry.py +110 -0
  220. package/src/zexus.egg-info/PKG-INFO +2235 -0
  221. package/src/zexus.egg-info/SOURCES.txt +876 -0
  222. package/src/zexus.egg-info/dependency_links.txt +1 -0
  223. package/src/zexus.egg-info/entry_points.txt +3 -0
  224. package/src/zexus.egg-info/not-zip-safe +1 -0
  225. package/src/zexus.egg-info/requires.txt +14 -0
  226. package/src/zexus.egg-info/top_level.txt +2 -0
  227. package/zexus.json +14 -0
@@ -0,0 +1,520 @@
1
+ """
2
+ Register-Based Virtual Machine for Zexus
3
+
4
+ A register-based VM that provides 1.5-3x faster arithmetic operations
5
+ compared to the stack-based VM. Uses virtual registers for intermediate
6
+ values, reducing memory access and stack manipulation overhead.
7
+
8
+ Architecture:
9
+ - 16 virtual registers (r0-r15)
10
+ - Register allocation for variables and temporaries
11
+ - Hybrid mode: registers for arithmetic, stack for complex operations
12
+ - Automatic spilling when registers are exhausted
13
+
14
+ Performance:
15
+ - Target: 1.5-3x speedup for arithmetic-heavy code
16
+ - Best for: loops, mathematical computations, nested expressions
17
+ - Compatible with existing stack-based bytecode via converter
18
+ """
19
+
20
+ from typing import Any, Dict, List, Optional, Tuple, Union
21
+ from .bytecode import Opcode, Bytecode
22
+ from enum import IntEnum
23
+
24
+
25
+ class RegisterOpcode(IntEnum):
26
+ """Register-based opcodes (200-299 range to avoid conflicts)"""
27
+ # Register load/store
28
+ LOAD_REG = 200 # Load constant to register: LOAD_REG r1, 42
29
+ LOAD_VAR_REG = 201 # Load variable to register: LOAD_VAR_REG r1, "x"
30
+ STORE_REG = 202 # Store register to variable: STORE_REG r1, "x"
31
+ MOV_REG = 203 # Move between registers: MOV_REG r2, r1
32
+
33
+ # Register arithmetic (3-address code: dest, src1, src2)
34
+ ADD_REG = 210 # r3 = r1 + r2
35
+ SUB_REG = 211 # r3 = r1 - r2
36
+ MUL_REG = 212 # r3 = r1 * r2
37
+ DIV_REG = 213 # r3 = r1 / r2
38
+ MOD_REG = 214 # r3 = r1 % r2
39
+ POW_REG = 215 # r3 = r1 ** r2
40
+ NEG_REG = 216 # r2 = -r1 (unary)
41
+
42
+ # Register comparisons
43
+ EQ_REG = 220 # r3 = (r1 == r2)
44
+ NEQ_REG = 221 # r3 = (r1 != r2)
45
+ LT_REG = 222 # r3 = (r1 < r2)
46
+ GT_REG = 223 # r3 = (r1 > r2)
47
+ LTE_REG = 224 # r3 = (r1 <= r2)
48
+ GTE_REG = 225 # r3 = (r1 >= r2)
49
+
50
+ # Register logical operations
51
+ AND_REG = 230 # r3 = r1 && r2
52
+ OR_REG = 231 # r3 = r1 || r2
53
+ NOT_REG = 232 # r2 = !r1
54
+
55
+ # Stack interop (for hybrid mode)
56
+ PUSH_REG = 240 # Push register value to stack
57
+ POP_REG = 241 # Pop stack value to register
58
+
59
+
60
+ class RegisterFile:
61
+ """
62
+ Virtual register file with 16 general-purpose registers.
63
+
64
+ Registers r0-r15:
65
+ - r0-r7: General purpose temporaries
66
+ - r8-r11: Function argument passing
67
+ - r12-r14: Saved registers (callee-saved)
68
+ - r15: Special purpose (return value)
69
+ """
70
+
71
+ def __init__(self, num_registers: int = 16):
72
+ self.num_registers = num_registers
73
+ self.registers: List[Any] = [None] * num_registers
74
+ self.dirty: List[bool] = [False] * num_registers # Track modified registers
75
+
76
+ def read(self, reg_num: int) -> Any:
77
+ """Read value from register"""
78
+ if not (0 <= reg_num < self.num_registers):
79
+ raise ValueError(f"Invalid register number: r{reg_num}")
80
+ return self.registers[reg_num]
81
+
82
+ def write(self, reg_num: int, value: Any) -> None:
83
+ """Write value to register"""
84
+ if not (0 <= reg_num < self.num_registers):
85
+ raise ValueError(f"Invalid register number: r{reg_num}")
86
+ self.registers[reg_num] = value
87
+ self.dirty[reg_num] = True
88
+
89
+ def clear(self, reg_num: int) -> None:
90
+ """Clear register (set to None)"""
91
+ self.registers[reg_num] = None
92
+ self.dirty[reg_num] = False
93
+
94
+ def clear_all(self) -> None:
95
+ """Clear all registers"""
96
+ self.registers = [None] * self.num_registers
97
+ self.dirty = [False] * self.num_registers
98
+
99
+ def is_dirty(self, reg_num: int) -> bool:
100
+ """Check if register has been modified"""
101
+ return self.dirty[reg_num]
102
+
103
+ def get_free_register(self) -> Optional[int]:
104
+ """Find first available (clean, None) register"""
105
+ for i in range(self.num_registers):
106
+ if self.registers[i] is None and not self.dirty[i]:
107
+ return i
108
+ return None
109
+
110
+ def __repr__(self) -> str:
111
+ active = [f"r{i}={v}" for i, v in enumerate(self.registers) if v is not None]
112
+ return f"<RegisterFile [{', '.join(active)}]>"
113
+
114
+
115
+ class RegisterAllocator:
116
+ """
117
+ Register allocation strategy for mapping variables to registers.
118
+
119
+ Strategies:
120
+ 1. Linear scan allocation (simple, fast)
121
+ 2. Graph coloring (optimal, slower)
122
+ 3. Live range splitting for spilling
123
+
124
+ When all registers are full, spills to memory (stack/variables).
125
+ """
126
+
127
+ def __init__(self, num_registers: int = 16, reserved: int = 2):
128
+ """
129
+ Initialize register allocator
130
+
131
+ Args:
132
+ num_registers: Total registers available
133
+ reserved: Number of reserved registers (e.g., r15 for return)
134
+ """
135
+ self.num_registers = num_registers
136
+ self.reserved = reserved
137
+ self.available = num_registers - reserved
138
+
139
+ # Variable → register mapping
140
+ self.var_to_reg: Dict[str, int] = {}
141
+
142
+ # Register → variable mapping (reverse lookup)
143
+ self.reg_to_var: Dict[int, str] = {}
144
+
145
+ # Track register usage
146
+ self.allocated_regs: set = set()
147
+
148
+ # Spilled variables (couldn't fit in registers)
149
+ self.spilled_vars: set = set()
150
+
151
+ def allocate(self, var_name: str) -> int:
152
+ """
153
+ Allocate a register for variable.
154
+
155
+ Returns:
156
+ Register number, or -1 if must spill
157
+ """
158
+ # Check if already allocated
159
+ if var_name in self.var_to_reg:
160
+ return self.var_to_reg[var_name]
161
+
162
+ # Find free register
163
+ for reg in range(self.available):
164
+ if reg not in self.allocated_regs:
165
+ self.var_to_reg[var_name] = reg
166
+ self.reg_to_var[reg] = var_name
167
+ self.allocated_regs.add(reg)
168
+ return reg
169
+
170
+ # No free registers - must spill
171
+ self.spilled_vars.add(var_name)
172
+ return -1
173
+
174
+ def free(self, var_name: str) -> None:
175
+ """Free register allocated to variable"""
176
+ if var_name in self.var_to_reg:
177
+ reg = self.var_to_reg[var_name]
178
+ del self.var_to_reg[var_name]
179
+ del self.reg_to_var[reg]
180
+ self.allocated_regs.discard(reg)
181
+
182
+ def get_register(self, var_name: str) -> Optional[int]:
183
+ """Get register allocated to variable (None if not allocated)"""
184
+ return self.var_to_reg.get(var_name)
185
+
186
+ def get_variable(self, reg_num: int) -> Optional[str]:
187
+ """Get variable allocated to register (None if not allocated)"""
188
+ return self.reg_to_var.get(reg_num)
189
+
190
+ def clear(self) -> None:
191
+ """Reset allocator state"""
192
+ self.var_to_reg.clear()
193
+ self.reg_to_var.clear()
194
+ self.allocated_regs.clear()
195
+ self.spilled_vars.clear()
196
+
197
+ def __repr__(self) -> str:
198
+ allocs = [f"{var}→r{reg}" for var, reg in self.var_to_reg.items()]
199
+ return f"<RegisterAllocator [{', '.join(allocs)}] spilled={len(self.spilled_vars)}>"
200
+
201
+
202
+ class RegisterVM:
203
+ """
204
+ Register-based Virtual Machine for Zexus.
205
+
206
+ Features:
207
+ - 16 virtual registers (r0-r15)
208
+ - Register-based arithmetic (1.5-3x faster)
209
+ - Hybrid execution (registers + stack)
210
+ - Automatic register allocation
211
+ - Register spilling when needed
212
+
213
+ Usage:
214
+ vm = RegisterVM()
215
+ result = vm.execute(bytecode)
216
+
217
+ Performance:
218
+ Best for: arithmetic loops, mathematical computations
219
+ Speedup: 1.5-3x vs stack-based VM
220
+ """
221
+
222
+ def __init__(
223
+ self,
224
+ num_registers: int = 16,
225
+ use_allocator: bool = True,
226
+ hybrid_mode: bool = True,
227
+ debug: bool = False
228
+ ):
229
+ """
230
+ Initialize Register VM
231
+
232
+ Args:
233
+ num_registers: Number of virtual registers (default 16)
234
+ use_allocator: Use automatic register allocation
235
+ hybrid_mode: Use hybrid stack+register execution
236
+ debug: Enable debug output
237
+ """
238
+ self.registers = RegisterFile(num_registers)
239
+ self.allocator = RegisterAllocator(num_registers) if use_allocator else None
240
+ self.hybrid_mode = hybrid_mode
241
+ self.debug = debug
242
+
243
+ # Stack for hybrid mode and complex operations
244
+ self.stack: List[Any] = []
245
+
246
+ # Environment for variables
247
+ self.env: Dict[str, Any] = {}
248
+
249
+ # Constants table
250
+ self.constants: List[Any] = []
251
+
252
+ # Execution stats
253
+ self.stats = {
254
+ 'instructions_executed': 0,
255
+ 'register_ops': 0,
256
+ 'stack_ops': 0,
257
+ 'spills': 0,
258
+ }
259
+
260
+ def execute(self, bytecode: Union[Bytecode, List[Tuple]]) -> Any:
261
+ """
262
+ Execute register-based or hybrid bytecode.
263
+
264
+ Args:
265
+ bytecode: Bytecode object or instruction list
266
+
267
+ Returns:
268
+ Execution result (typically top of stack or r15 register)
269
+ """
270
+ # Extract instructions and constants
271
+ if isinstance(bytecode, Bytecode):
272
+ instructions = bytecode.instructions
273
+ self.constants = bytecode.constants
274
+ else:
275
+ instructions = bytecode
276
+ self.constants = []
277
+
278
+ # Reset state
279
+ self.registers.clear_all()
280
+ self.stack.clear()
281
+ if self.allocator:
282
+ self.allocator.clear()
283
+
284
+ # Execute instruction stream
285
+ pc = 0 # Program counter
286
+ while pc < len(instructions):
287
+ inst = instructions[pc]
288
+ opcode = inst[0] if isinstance(inst, tuple) else inst
289
+
290
+ # Dispatch to handler
291
+ if opcode in RegisterOpcode.__members__.values():
292
+ pc = self._execute_register_instruction(inst, pc)
293
+ elif self.hybrid_mode:
294
+ pc = self._execute_stack_instruction(inst, pc)
295
+ else:
296
+ raise ValueError(f"Stack opcode {opcode} in register-only mode")
297
+
298
+ self.stats['instructions_executed'] += 1
299
+ pc += 1
300
+
301
+ # Return result (r15 or top of stack)
302
+ if self.registers.read(15) is not None:
303
+ return self.registers.read(15)
304
+ elif self.stack:
305
+ return self.stack[-1]
306
+ return None
307
+
308
+ def _execute_register_instruction(self, inst: Tuple, pc: int) -> int:
309
+ """Execute register-based instruction"""
310
+ opcode = inst[0]
311
+ self.stats['register_ops'] += 1
312
+
313
+ # LOAD_REG r1, const_idx
314
+ if opcode == RegisterOpcode.LOAD_REG:
315
+ reg, const_idx = inst[1], inst[2]
316
+ value = self.constants[const_idx]
317
+ self.registers.write(reg, value)
318
+ if self.debug:
319
+ print(f" LOAD_REG r{reg}, {value}")
320
+
321
+ # LOAD_VAR_REG r1, "x"
322
+ elif opcode == RegisterOpcode.LOAD_VAR_REG:
323
+ reg, var_name = inst[1], inst[2]
324
+ value = self.env.get(var_name)
325
+ self.registers.write(reg, value)
326
+ if self.debug:
327
+ print(f" LOAD_VAR_REG r{reg}, {var_name} ({value})")
328
+
329
+ # STORE_REG r1, "x"
330
+ elif opcode == RegisterOpcode.STORE_REG:
331
+ reg, var_name = inst[1], inst[2]
332
+ value = self.registers.read(reg)
333
+ self.env[var_name] = value
334
+ if self.debug:
335
+ print(f" STORE_REG r{reg}, {var_name} ({value})")
336
+
337
+ # MOV_REG r2, r1
338
+ elif opcode == RegisterOpcode.MOV_REG:
339
+ dest, src = inst[1], inst[2]
340
+ value = self.registers.read(src)
341
+ self.registers.write(dest, value)
342
+ if self.debug:
343
+ print(f" MOV_REG r{dest}, r{src} ({value})")
344
+
345
+ # Arithmetic: ADD_REG r3, r1, r2
346
+ elif opcode == RegisterOpcode.ADD_REG:
347
+ dest, src1, src2 = inst[1], inst[2], inst[3]
348
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
349
+ self.registers.write(dest, v1 + v2)
350
+ if self.debug:
351
+ print(f" ADD_REG r{dest}, r{src1}, r{src2} ({v1} + {v2} = {v1+v2})")
352
+
353
+ elif opcode == RegisterOpcode.SUB_REG:
354
+ dest, src1, src2 = inst[1], inst[2], inst[3]
355
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
356
+ self.registers.write(dest, v1 - v2)
357
+ if self.debug:
358
+ print(f" SUB_REG r{dest}, r{src1}, r{src2} ({v1} - {v2} = {v1-v2})")
359
+
360
+ elif opcode == RegisterOpcode.MUL_REG:
361
+ dest, src1, src2 = inst[1], inst[2], inst[3]
362
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
363
+ self.registers.write(dest, v1 * v2)
364
+ if self.debug:
365
+ print(f" MUL_REG r{dest}, r{src1}, r{src2} ({v1} * {v2} = {v1*v2})")
366
+
367
+ elif opcode == RegisterOpcode.DIV_REG:
368
+ dest, src1, src2 = inst[1], inst[2], inst[3]
369
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
370
+ self.registers.write(dest, v1 / v2)
371
+ if self.debug:
372
+ print(f" DIV_REG r{dest}, r{src1}, r{src2} ({v1} / {v2} = {v1/v2})")
373
+
374
+ elif opcode == RegisterOpcode.MOD_REG:
375
+ dest, src1, src2 = inst[1], inst[2], inst[3]
376
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
377
+ self.registers.write(dest, v1 % v2)
378
+
379
+ elif opcode == RegisterOpcode.POW_REG:
380
+ dest, src1, src2 = inst[1], inst[2], inst[3]
381
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
382
+ self.registers.write(dest, v1 ** v2)
383
+
384
+ elif opcode == RegisterOpcode.NEG_REG:
385
+ dest, src = inst[1], inst[2]
386
+ value = self.registers.read(src)
387
+ self.registers.write(dest, -value)
388
+
389
+ # Comparisons
390
+ elif opcode == RegisterOpcode.EQ_REG:
391
+ dest, src1, src2 = inst[1], inst[2], inst[3]
392
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
393
+ self.registers.write(dest, v1 == v2)
394
+
395
+ elif opcode == RegisterOpcode.NEQ_REG:
396
+ dest, src1, src2 = inst[1], inst[2], inst[3]
397
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
398
+ self.registers.write(dest, v1 != v2)
399
+
400
+ elif opcode == RegisterOpcode.LT_REG:
401
+ dest, src1, src2 = inst[1], inst[2], inst[3]
402
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
403
+ self.registers.write(dest, v1 < v2)
404
+
405
+ elif opcode == RegisterOpcode.GT_REG:
406
+ dest, src1, src2 = inst[1], inst[2], inst[3]
407
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
408
+ self.registers.write(dest, v1 > v2)
409
+
410
+ elif opcode == RegisterOpcode.LTE_REG:
411
+ dest, src1, src2 = inst[1], inst[2], inst[3]
412
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
413
+ self.registers.write(dest, v1 <= v2)
414
+
415
+ elif opcode == RegisterOpcode.GTE_REG:
416
+ dest, src1, src2 = inst[1], inst[2], inst[3]
417
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
418
+ self.registers.write(dest, v1 >= v2)
419
+
420
+ # Logical operations
421
+ elif opcode == RegisterOpcode.AND_REG:
422
+ dest, src1, src2 = inst[1], inst[2], inst[3]
423
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
424
+ self.registers.write(dest, v1 and v2)
425
+
426
+ elif opcode == RegisterOpcode.OR_REG:
427
+ dest, src1, src2 = inst[1], inst[2], inst[3]
428
+ v1, v2 = self.registers.read(src1), self.registers.read(src2)
429
+ self.registers.write(dest, v1 or v2)
430
+
431
+ elif opcode == RegisterOpcode.NOT_REG:
432
+ dest, src = inst[1], inst[2]
433
+ value = self.registers.read(src)
434
+ self.registers.write(dest, not value)
435
+
436
+ # Stack interop (hybrid mode)
437
+ elif opcode == RegisterOpcode.PUSH_REG:
438
+ reg = inst[1]
439
+ value = self.registers.read(reg)
440
+ self.stack.append(value)
441
+ if self.debug:
442
+ print(f" PUSH_REG r{reg} ({value})")
443
+
444
+ elif opcode == RegisterOpcode.POP_REG:
445
+ reg = inst[1]
446
+ value = self.stack.pop()
447
+ self.registers.write(reg, value)
448
+ if self.debug:
449
+ print(f" POP_REG r{reg} ({value})")
450
+
451
+ else:
452
+ raise ValueError(f"Unknown register opcode: {opcode}")
453
+
454
+ return pc
455
+
456
+ def _execute_stack_instruction(self, inst: Tuple, pc: int) -> int:
457
+ """Execute stack-based instruction (hybrid mode)"""
458
+ opcode = inst[0]
459
+ self.stats['stack_ops'] += 1
460
+
461
+ # Implement minimal stack operations for hybrid mode
462
+ if opcode == "LOAD_CONST" or opcode == Opcode.LOAD_CONST:
463
+ const_idx = inst[1]
464
+ self.stack.append(self.constants[const_idx])
465
+
466
+ elif opcode == "STORE_NAME" or opcode == Opcode.STORE_NAME:
467
+ var_name = inst[1]
468
+ value = self.stack.pop()
469
+ self.env[var_name] = value
470
+
471
+ elif opcode == "LOAD_NAME" or opcode == Opcode.LOAD_NAME:
472
+ var_name = inst[1]
473
+ self.stack.append(self.env.get(var_name))
474
+
475
+ elif opcode == "ADD" or opcode == Opcode.ADD:
476
+ b, a = self.stack.pop(), self.stack.pop()
477
+ self.stack.append(a + b)
478
+
479
+ elif opcode == "SUB" or opcode == Opcode.SUB:
480
+ b, a = self.stack.pop(), self.stack.pop()
481
+ self.stack.append(a - b)
482
+
483
+ elif opcode == "MUL" or opcode == Opcode.MUL:
484
+ b, a = self.stack.pop(), self.stack.pop()
485
+ self.stack.append(a * b)
486
+
487
+ elif opcode == "DIV" or opcode == Opcode.DIV:
488
+ b, a = self.stack.pop(), self.stack.pop()
489
+ self.stack.append(a / b)
490
+
491
+ elif opcode == "PRINT" or opcode == Opcode.PRINT:
492
+ value = self.stack.pop() if self.stack else None
493
+ print(value)
494
+
495
+ elif opcode == "RETURN" or opcode == Opcode.RETURN:
496
+ # Store return value in r15 for consistency
497
+ if self.stack:
498
+ self.registers.write(15, self.stack.pop())
499
+
500
+ else:
501
+ if self.debug:
502
+ print(f" Unimplemented stack opcode: {opcode}")
503
+
504
+ return pc
505
+
506
+ def get_stats(self) -> Dict[str, int]:
507
+ """Get execution statistics"""
508
+ total = self.stats['register_ops'] + self.stats['stack_ops']
509
+ if total > 0:
510
+ register_pct = (self.stats['register_ops'] / total) * 100
511
+ else:
512
+ register_pct = 0
513
+
514
+ return {
515
+ **self.stats,
516
+ 'register_percentage': register_pct,
517
+ }
518
+
519
+ def __repr__(self) -> str:
520
+ return f"<RegisterVM regs={self.registers.num_registers} stack={len(self.stack)}>"