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.
- package/LICENSE +0 -0
- package/README.md +2513 -0
- package/bin/zexus +2 -0
- package/bin/zpics +2 -0
- package/bin/zpm +2 -0
- package/bin/zx +2 -0
- package/bin/zx-deploy +2 -0
- package/bin/zx-dev +2 -0
- package/bin/zx-run +2 -0
- package/package.json +66 -0
- package/scripts/README.md +24 -0
- package/scripts/postinstall.js +44 -0
- package/shared_config.json +24 -0
- package/src/README.md +1525 -0
- package/src/tests/run_zexus_tests.py +117 -0
- package/src/tests/test_all_phases.zx +346 -0
- package/src/tests/test_blockchain_features.zx +306 -0
- package/src/tests/test_complexity_features.zx +321 -0
- package/src/tests/test_core_integration.py +185 -0
- package/src/tests/test_phase10_ecosystem.zx +177 -0
- package/src/tests/test_phase1_modifiers.zx +87 -0
- package/src/tests/test_phase2_plugins.zx +80 -0
- package/src/tests/test_phase3_security.zx +97 -0
- package/src/tests/test_phase4_vfs.zx +116 -0
- package/src/tests/test_phase5_types.zx +117 -0
- package/src/tests/test_phase6_metaprogramming.zx +125 -0
- package/src/tests/test_phase7_optimization.zx +132 -0
- package/src/tests/test_phase9_advanced_types.zx +157 -0
- package/src/tests/test_security_features.py +419 -0
- package/src/tests/test_security_features.zx +276 -0
- package/src/tests/test_simple_zx.zx +1 -0
- package/src/tests/test_verification_simple.zx +69 -0
- package/src/zexus/__init__.py +28 -0
- package/src/zexus/__main__.py +5 -0
- package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/advanced_types.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/builtin_modules.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/complexity_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/concurrency_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/config.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/dependency_injection.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/ecosystem.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__/hybrid_orchestrator.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/metaprogramming.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/optimization.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/plugin_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/policy_engine.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/stdlib_integration.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/strategy_recovery.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/type_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/virtual_filesystem.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/advanced_types.py +401 -0
- package/src/zexus/blockchain/__init__.py +40 -0
- package/src/zexus/blockchain/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/crypto.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/ledger.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/transaction.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/crypto.py +463 -0
- package/src/zexus/blockchain/ledger.py +255 -0
- package/src/zexus/blockchain/transaction.py +267 -0
- package/src/zexus/builtin_modules.py +284 -0
- package/src/zexus/builtin_plugins.py +317 -0
- package/src/zexus/capability_system.py +372 -0
- package/src/zexus/cli/__init__.py +2 -0
- package/src/zexus/cli/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
- package/src/zexus/cli/main.py +707 -0
- package/src/zexus/cli/zpm.py +203 -0
- package/src/zexus/compare_interpreter_compiler.py +146 -0
- package/src/zexus/compiler/__init__.py +169 -0
- package/src/zexus/compiler/__pycache__/__init__.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__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/compiler/bytecode.py +266 -0
- package/src/zexus/compiler/compat_runtime.py +277 -0
- package/src/zexus/compiler/lexer.py +257 -0
- package/src/zexus/compiler/parser.py +779 -0
- package/src/zexus/compiler/semantic.py +118 -0
- package/src/zexus/compiler/zexus_ast.py +454 -0
- package/src/zexus/complexity_system.py +575 -0
- package/src/zexus/concurrency_system.py +493 -0
- package/src/zexus/config.py +201 -0
- package/src/zexus/crypto_bridge.py +19 -0
- package/src/zexus/dependency_injection.py +423 -0
- package/src/zexus/ecosystem.py +434 -0
- package/src/zexus/environment.py +101 -0
- package/src/zexus/environment_manager.py +119 -0
- package/src/zexus/error_reporter.py +314 -0
- package/src/zexus/evaluator/__init__.py +12 -0
- package/src/zexus/evaluator/__pycache__/__init__.cpython-312.pyc +0 -0
- 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__/integration.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/bytecode_compiler.py +700 -0
- package/src/zexus/evaluator/core.py +891 -0
- package/src/zexus/evaluator/expressions.py +827 -0
- package/src/zexus/evaluator/functions.py +3989 -0
- package/src/zexus/evaluator/integration.py +396 -0
- package/src/zexus/evaluator/statements.py +4303 -0
- package/src/zexus/evaluator/utils.py +126 -0
- package/src/zexus/evaluator_original.py +2041 -0
- package/src/zexus/external_bridge.py +16 -0
- package/src/zexus/find_affected_imports.sh +155 -0
- package/src/zexus/hybrid_orchestrator.py +152 -0
- package/src/zexus/input_validation.py +259 -0
- package/src/zexus/lexer.py +571 -0
- package/src/zexus/logging.py +89 -0
- package/src/zexus/lsp/__init__.py +9 -0
- package/src/zexus/lsp/completion_provider.py +207 -0
- package/src/zexus/lsp/definition_provider.py +22 -0
- package/src/zexus/lsp/hover_provider.py +71 -0
- package/src/zexus/lsp/server.py +269 -0
- package/src/zexus/lsp/symbol_provider.py +31 -0
- package/src/zexus/metaprogramming.py +321 -0
- package/src/zexus/module_cache.py +89 -0
- package/src/zexus/module_manager.py +107 -0
- package/src/zexus/object.py +973 -0
- package/src/zexus/optimization.py +424 -0
- package/src/zexus/parser/__init__.py +31 -0
- package/src/zexus/parser/__pycache__/__init__.cpython-312.pyc +0 -0
- 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/integration.py +86 -0
- package/src/zexus/parser/parser.py +3977 -0
- package/src/zexus/parser/strategy_context.py +7254 -0
- package/src/zexus/parser/strategy_structural.py +1033 -0
- package/src/zexus/persistence.py +391 -0
- package/src/zexus/plugin_system.py +290 -0
- package/src/zexus/policy_engine.py +365 -0
- package/src/zexus/profiler/__init__.py +5 -0
- package/src/zexus/profiler/profiler.py +233 -0
- package/src/zexus/purity_system.py +398 -0
- package/src/zexus/runtime/__init__.py +20 -0
- package/src/zexus/runtime/async_runtime.py +324 -0
- package/src/zexus/search_old_imports.sh +65 -0
- package/src/zexus/security.py +1407 -0
- package/src/zexus/stack_trace.py +233 -0
- package/src/zexus/stdlib/__init__.py +27 -0
- package/src/zexus/stdlib/blockchain.py +341 -0
- package/src/zexus/stdlib/compression.py +167 -0
- package/src/zexus/stdlib/crypto.py +124 -0
- package/src/zexus/stdlib/datetime.py +163 -0
- package/src/zexus/stdlib/db_mongo.py +199 -0
- package/src/zexus/stdlib/db_mysql.py +162 -0
- package/src/zexus/stdlib/db_postgres.py +163 -0
- package/src/zexus/stdlib/db_sqlite.py +133 -0
- package/src/zexus/stdlib/encoding.py +230 -0
- package/src/zexus/stdlib/fs.py +195 -0
- package/src/zexus/stdlib/http.py +219 -0
- package/src/zexus/stdlib/http_server.py +248 -0
- package/src/zexus/stdlib/json_module.py +61 -0
- package/src/zexus/stdlib/math.py +360 -0
- package/src/zexus/stdlib/os_module.py +265 -0
- package/src/zexus/stdlib/regex.py +148 -0
- package/src/zexus/stdlib/sockets.py +253 -0
- package/src/zexus/stdlib/test_framework.zx +208 -0
- package/src/zexus/stdlib/test_runner.zx +119 -0
- package/src/zexus/stdlib_integration.py +341 -0
- package/src/zexus/strategy_recovery.py +256 -0
- package/src/zexus/syntax_validator.py +356 -0
- package/src/zexus/testing/zpics.py +407 -0
- package/src/zexus/testing/zpics_runtime.py +369 -0
- package/src/zexus/type_system.py +374 -0
- package/src/zexus/validation_system.py +569 -0
- package/src/zexus/virtual_filesystem.py +355 -0
- package/src/zexus/vm/__init__.py +8 -0
- package/src/zexus/vm/__pycache__/__init__.cpython-312.pyc +0 -0
- 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__/cache.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/memory_manager.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/memory_pool.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/peephole_optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/profiler.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/register_allocator.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/register_vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/ssa_converter.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/async_optimizer.py +420 -0
- package/src/zexus/vm/bytecode.py +428 -0
- package/src/zexus/vm/bytecode_converter.py +297 -0
- package/src/zexus/vm/cache.py +532 -0
- package/src/zexus/vm/jit.py +720 -0
- package/src/zexus/vm/memory_manager.py +520 -0
- package/src/zexus/vm/memory_pool.py +511 -0
- package/src/zexus/vm/optimizer.py +478 -0
- package/src/zexus/vm/parallel_vm.py +899 -0
- package/src/zexus/vm/peephole_optimizer.py +452 -0
- package/src/zexus/vm/profiler.py +527 -0
- package/src/zexus/vm/register_allocator.py +462 -0
- package/src/zexus/vm/register_vm.py +520 -0
- package/src/zexus/vm/ssa_converter.py +757 -0
- package/src/zexus/vm/vm.py +1392 -0
- package/src/zexus/zexus_ast.py +1782 -0
- package/src/zexus/zexus_token.py +253 -0
- package/src/zexus/zpm/__init__.py +15 -0
- package/src/zexus/zpm/installer.py +116 -0
- package/src/zexus/zpm/package_manager.py +208 -0
- package/src/zexus/zpm/publisher.py +98 -0
- package/src/zexus/zpm/registry.py +110 -0
- package/src/zexus.egg-info/PKG-INFO +2235 -0
- package/src/zexus.egg-info/SOURCES.txt +876 -0
- package/src/zexus.egg-info/dependency_links.txt +1 -0
- package/src/zexus.egg-info/entry_points.txt +3 -0
- package/src/zexus.egg-info/not-zip-safe +1 -0
- package/src/zexus.egg-info/requires.txt +14 -0
- package/src/zexus.egg-info/top_level.txt +2 -0
- package/zexus.json +14 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Stack-to-Register Bytecode Converter
|
|
3
|
+
|
|
4
|
+
Converts stack-based bytecode to register-based bytecode for
|
|
5
|
+
improved arithmetic performance (1.5-3x speedup).
|
|
6
|
+
|
|
7
|
+
Strategy:
|
|
8
|
+
1. Identify arithmetic patterns in stack code
|
|
9
|
+
2. Allocate virtual registers for temporaries
|
|
10
|
+
3. Convert stack operations to 3-address register code
|
|
11
|
+
4. Keep complex operations on stack (hybrid mode)
|
|
12
|
+
|
|
13
|
+
Example conversion:
|
|
14
|
+
Stack: LOAD_CONST 10, LOAD_CONST 20, ADD, STORE_NAME "x"
|
|
15
|
+
Register: LOAD_REG r0, 10; LOAD_REG r1, 20; ADD_REG r2, r0, r1; STORE_REG r2, "x"
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from typing import List, Tuple, Dict, Any, Optional
|
|
19
|
+
from .bytecode import Opcode, Bytecode
|
|
20
|
+
from .register_vm import RegisterOpcode, RegisterAllocator
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class BytecodeConverter:
|
|
24
|
+
"""
|
|
25
|
+
Converts stack-based bytecode to register-based bytecode.
|
|
26
|
+
|
|
27
|
+
Optimizes arithmetic-heavy code by using registers instead of stack,
|
|
28
|
+
reducing memory access overhead.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, num_registers: int = 16, aggressive: bool = False, debug: bool = False):
|
|
32
|
+
"""
|
|
33
|
+
Initialize converter
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
num_registers: Number of virtual registers available
|
|
37
|
+
aggressive: Aggressively convert all operations (not just arithmetic)
|
|
38
|
+
debug: Enable debug output
|
|
39
|
+
"""
|
|
40
|
+
self.num_registers = num_registers
|
|
41
|
+
self.aggressive = aggressive
|
|
42
|
+
self.debug = debug
|
|
43
|
+
self.allocator = RegisterAllocator(num_registers)
|
|
44
|
+
|
|
45
|
+
# Next available temporary register
|
|
46
|
+
self.next_temp_reg = 0
|
|
47
|
+
|
|
48
|
+
# Conversion statistics
|
|
49
|
+
self.stats = {
|
|
50
|
+
'stack_instructions': 0,
|
|
51
|
+
'register_instructions': 0,
|
|
52
|
+
'conversions': 0,
|
|
53
|
+
'skipped': 0,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
def convert(self, bytecode: Bytecode) -> Bytecode:
|
|
57
|
+
"""
|
|
58
|
+
Convert stack bytecode to register bytecode.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
bytecode: Stack-based bytecode
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
Hybrid bytecode (registers for arithmetic, stack for rest)
|
|
65
|
+
"""
|
|
66
|
+
self.stats['stack_instructions'] = len(bytecode.instructions)
|
|
67
|
+
|
|
68
|
+
# Reset state
|
|
69
|
+
self.allocator.clear()
|
|
70
|
+
self.next_temp_reg = 0
|
|
71
|
+
|
|
72
|
+
converted_instructions = []
|
|
73
|
+
constants = bytecode.constants.copy()
|
|
74
|
+
|
|
75
|
+
i = 0
|
|
76
|
+
while i < len(bytecode.instructions):
|
|
77
|
+
inst = bytecode.instructions[i]
|
|
78
|
+
opcode = inst[0] if isinstance(inst, tuple) else inst
|
|
79
|
+
|
|
80
|
+
# Try to convert arithmetic patterns
|
|
81
|
+
pattern, advance = self._detect_arithmetic_pattern(bytecode.instructions, i)
|
|
82
|
+
|
|
83
|
+
if pattern:
|
|
84
|
+
# Convert pattern to register ops
|
|
85
|
+
register_insts = self._convert_pattern(pattern, constants)
|
|
86
|
+
converted_instructions.extend(register_insts)
|
|
87
|
+
self.stats['conversions'] += 1
|
|
88
|
+
i += advance
|
|
89
|
+
else:
|
|
90
|
+
# Keep as stack instruction
|
|
91
|
+
converted_instructions.append(inst)
|
|
92
|
+
self.stats['skipped'] += 1
|
|
93
|
+
i += 1
|
|
94
|
+
|
|
95
|
+
self.stats['register_instructions'] = len(converted_instructions)
|
|
96
|
+
|
|
97
|
+
# Create new bytecode with converted instructions
|
|
98
|
+
result = Bytecode(converted_instructions, constants)
|
|
99
|
+
if bytecode.metadata:
|
|
100
|
+
result.metadata.update(bytecode.metadata)
|
|
101
|
+
result.set_metadata('converted_to_register', True)
|
|
102
|
+
result.set_metadata('conversion_stats', self.stats.copy())
|
|
103
|
+
|
|
104
|
+
if self.debug:
|
|
105
|
+
print(f"Conversion: {self.stats['stack_instructions']} → {self.stats['register_instructions']} instructions")
|
|
106
|
+
print(f" Converted: {self.stats['conversions']}, Skipped: {self.stats['skipped']}")
|
|
107
|
+
|
|
108
|
+
return result
|
|
109
|
+
|
|
110
|
+
def _detect_arithmetic_pattern(
|
|
111
|
+
self,
|
|
112
|
+
instructions: List[Tuple],
|
|
113
|
+
start: int
|
|
114
|
+
) -> Tuple[Optional[Dict], int]:
|
|
115
|
+
"""
|
|
116
|
+
Detect arithmetic patterns that can be converted to register ops.
|
|
117
|
+
|
|
118
|
+
Patterns:
|
|
119
|
+
1. Binary arithmetic: LOAD_CONST a, LOAD_CONST b, ADD/SUB/MUL/DIV
|
|
120
|
+
2. Variable arithmetic: LOAD_NAME x, LOAD_CONST y, ADD
|
|
121
|
+
3. Chains: a + b * c → multiple register ops
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
(pattern_dict, num_instructions_consumed) or (None, 0)
|
|
125
|
+
"""
|
|
126
|
+
if start >= len(instructions):
|
|
127
|
+
return None, 0
|
|
128
|
+
|
|
129
|
+
# Pattern 1: Constant arithmetic (LOAD_CONST, LOAD_CONST, BINARY_OP)
|
|
130
|
+
if start + 2 < len(instructions):
|
|
131
|
+
inst1, inst2, inst3 = instructions[start:start+3]
|
|
132
|
+
|
|
133
|
+
if (inst1[0] == Opcode.LOAD_CONST and
|
|
134
|
+
inst2[0] == Opcode.LOAD_CONST and
|
|
135
|
+
inst3[0] in [Opcode.ADD, Opcode.SUB, Opcode.MUL, Opcode.DIV, Opcode.MOD, Opcode.POW]):
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
'type': 'const_binary_op',
|
|
139
|
+
'const1': inst1[1],
|
|
140
|
+
'const2': inst2[1],
|
|
141
|
+
'operation': inst3[0],
|
|
142
|
+
}, 3
|
|
143
|
+
|
|
144
|
+
# Pattern 2: Variable arithmetic (LOAD_NAME, LOAD_CONST, BINARY_OP)
|
|
145
|
+
if start + 2 < len(instructions):
|
|
146
|
+
inst1, inst2, inst3 = instructions[start:start+3]
|
|
147
|
+
|
|
148
|
+
if (inst1[0] == Opcode.LOAD_NAME and
|
|
149
|
+
inst2[0] == Opcode.LOAD_CONST and
|
|
150
|
+
inst3[0] in [Opcode.ADD, Opcode.SUB, Opcode.MUL, Opcode.DIV]):
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
'type': 'var_const_binary_op',
|
|
154
|
+
'var_name': inst1[1],
|
|
155
|
+
'const': inst2[1],
|
|
156
|
+
'operation': inst3[0],
|
|
157
|
+
}, 3
|
|
158
|
+
|
|
159
|
+
# Pattern 3: Two variables (LOAD_NAME x, LOAD_NAME y, BINARY_OP)
|
|
160
|
+
if start + 2 < len(instructions):
|
|
161
|
+
inst1, inst2, inst3 = instructions[start:start+3]
|
|
162
|
+
|
|
163
|
+
if (inst1[0] == Opcode.LOAD_NAME and
|
|
164
|
+
inst2[0] == Opcode.LOAD_NAME and
|
|
165
|
+
inst3[0] in [Opcode.ADD, Opcode.SUB, Opcode.MUL, Opcode.DIV]):
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
'type': 'var_var_binary_op',
|
|
169
|
+
'var1': inst1[1],
|
|
170
|
+
'var2': inst2[1],
|
|
171
|
+
'operation': inst3[0],
|
|
172
|
+
}, 3
|
|
173
|
+
|
|
174
|
+
# Pattern 4: Store result (... STORE_NAME)
|
|
175
|
+
# This is an extension pattern, not standalone
|
|
176
|
+
|
|
177
|
+
return None, 0
|
|
178
|
+
|
|
179
|
+
def _convert_pattern(self, pattern: Dict, constants: List[Any]) -> List[Tuple]:
|
|
180
|
+
"""
|
|
181
|
+
Convert detected pattern to register instructions.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
pattern: Pattern dictionary from _detect_arithmetic_pattern
|
|
185
|
+
constants: Constants table
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
List of register-based instructions
|
|
189
|
+
"""
|
|
190
|
+
instructions = []
|
|
191
|
+
|
|
192
|
+
if pattern['type'] == 'const_binary_op':
|
|
193
|
+
# LOAD_CONST a, LOAD_CONST b, ADD
|
|
194
|
+
# → LOAD_REG r0, a; LOAD_REG r1, b; ADD_REG r2, r0, r1
|
|
195
|
+
const1_idx = pattern['const1']
|
|
196
|
+
const2_idx = pattern['const2']
|
|
197
|
+
operation = pattern['operation']
|
|
198
|
+
|
|
199
|
+
# Allocate temporary registers
|
|
200
|
+
r0 = self._alloc_temp_reg()
|
|
201
|
+
r1 = self._alloc_temp_reg()
|
|
202
|
+
r2 = self._alloc_temp_reg()
|
|
203
|
+
|
|
204
|
+
# Load constants to registers
|
|
205
|
+
instructions.append((RegisterOpcode.LOAD_REG, r0, const1_idx))
|
|
206
|
+
instructions.append((RegisterOpcode.LOAD_REG, r1, const2_idx))
|
|
207
|
+
|
|
208
|
+
# Perform operation
|
|
209
|
+
reg_op = self._map_stack_op_to_register_op(operation)
|
|
210
|
+
instructions.append((reg_op, r2, r0, r1))
|
|
211
|
+
|
|
212
|
+
# Push result back to stack (hybrid mode)
|
|
213
|
+
instructions.append((RegisterOpcode.PUSH_REG, r2))
|
|
214
|
+
|
|
215
|
+
elif pattern['type'] == 'var_const_binary_op':
|
|
216
|
+
# LOAD_NAME x, LOAD_CONST y, ADD
|
|
217
|
+
# → LOAD_VAR_REG r0, "x"; LOAD_REG r1, y; ADD_REG r2, r0, r1; PUSH_REG r2
|
|
218
|
+
var_name = pattern['var_name']
|
|
219
|
+
const_idx = pattern['const']
|
|
220
|
+
operation = pattern['operation']
|
|
221
|
+
|
|
222
|
+
r0 = self._alloc_temp_reg()
|
|
223
|
+
r1 = self._alloc_temp_reg()
|
|
224
|
+
r2 = self._alloc_temp_reg()
|
|
225
|
+
|
|
226
|
+
instructions.append((RegisterOpcode.LOAD_VAR_REG, r0, var_name))
|
|
227
|
+
instructions.append((RegisterOpcode.LOAD_REG, r1, const_idx))
|
|
228
|
+
|
|
229
|
+
reg_op = self._map_stack_op_to_register_op(operation)
|
|
230
|
+
instructions.append((reg_op, r2, r0, r1))
|
|
231
|
+
|
|
232
|
+
instructions.append((RegisterOpcode.PUSH_REG, r2))
|
|
233
|
+
|
|
234
|
+
elif pattern['type'] == 'var_var_binary_op':
|
|
235
|
+
# LOAD_NAME x, LOAD_NAME y, ADD
|
|
236
|
+
# → LOAD_VAR_REG r0, "x"; LOAD_VAR_REG r1, "y"; ADD_REG r2, r0, r1; PUSH_REG r2
|
|
237
|
+
var1 = pattern['var1']
|
|
238
|
+
var2 = pattern['var2']
|
|
239
|
+
operation = pattern['operation']
|
|
240
|
+
|
|
241
|
+
r0 = self._alloc_temp_reg()
|
|
242
|
+
r1 = self._alloc_temp_reg()
|
|
243
|
+
r2 = self._alloc_temp_reg()
|
|
244
|
+
|
|
245
|
+
instructions.append((RegisterOpcode.LOAD_VAR_REG, r0, var1))
|
|
246
|
+
instructions.append((RegisterOpcode.LOAD_VAR_REG, r1, var2))
|
|
247
|
+
|
|
248
|
+
reg_op = self._map_stack_op_to_register_op(operation)
|
|
249
|
+
instructions.append((reg_op, r2, r0, r1))
|
|
250
|
+
|
|
251
|
+
instructions.append((RegisterOpcode.PUSH_REG, r2))
|
|
252
|
+
|
|
253
|
+
return instructions
|
|
254
|
+
|
|
255
|
+
def _map_stack_op_to_register_op(self, stack_op: Opcode) -> RegisterOpcode:
|
|
256
|
+
"""Map stack opcode to register opcode"""
|
|
257
|
+
mapping = {
|
|
258
|
+
Opcode.ADD: RegisterOpcode.ADD_REG,
|
|
259
|
+
Opcode.SUB: RegisterOpcode.SUB_REG,
|
|
260
|
+
Opcode.MUL: RegisterOpcode.MUL_REG,
|
|
261
|
+
Opcode.DIV: RegisterOpcode.DIV_REG,
|
|
262
|
+
Opcode.MOD: RegisterOpcode.MOD_REG,
|
|
263
|
+
Opcode.POW: RegisterOpcode.POW_REG,
|
|
264
|
+
Opcode.NEG: RegisterOpcode.NEG_REG,
|
|
265
|
+
Opcode.EQ: RegisterOpcode.EQ_REG,
|
|
266
|
+
Opcode.NEQ: RegisterOpcode.NEQ_REG,
|
|
267
|
+
Opcode.LT: RegisterOpcode.LT_REG,
|
|
268
|
+
Opcode.GT: RegisterOpcode.GT_REG,
|
|
269
|
+
Opcode.LTE: RegisterOpcode.LTE_REG,
|
|
270
|
+
Opcode.GTE: RegisterOpcode.GTE_REG,
|
|
271
|
+
Opcode.AND: RegisterOpcode.AND_REG,
|
|
272
|
+
Opcode.OR: RegisterOpcode.OR_REG,
|
|
273
|
+
Opcode.NOT: RegisterOpcode.NOT_REG,
|
|
274
|
+
}
|
|
275
|
+
return mapping.get(stack_op, stack_op)
|
|
276
|
+
|
|
277
|
+
def _alloc_temp_reg(self) -> int:
|
|
278
|
+
"""Allocate next temporary register"""
|
|
279
|
+
reg = self.next_temp_reg
|
|
280
|
+
self.next_temp_reg = (self.next_temp_reg + 1) % self.num_registers
|
|
281
|
+
return reg
|
|
282
|
+
|
|
283
|
+
def get_stats(self) -> Dict[str, Any]:
|
|
284
|
+
"""Get conversion statistics"""
|
|
285
|
+
if self.stats['stack_instructions'] > 0:
|
|
286
|
+
reduction = ((self.stats['stack_instructions'] - self.stats['register_instructions']) /
|
|
287
|
+
self.stats['stack_instructions']) * 100
|
|
288
|
+
else:
|
|
289
|
+
reduction = 0
|
|
290
|
+
|
|
291
|
+
return {
|
|
292
|
+
**self.stats,
|
|
293
|
+
'reduction_pct': reduction,
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
def __repr__(self) -> str:
|
|
297
|
+
return f"<BytecodeConverter regs={self.num_registers} conversions={self.stats['conversions']}>"
|