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,321 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Metaprogramming system for Zexus.
|
|
3
|
+
|
|
4
|
+
Provides AST manipulation hooks and code generation capabilities.
|
|
5
|
+
Enables macros, compile-time transformations, and reflection.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Any, Dict, List, Optional, Callable, Set
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from enum import Enum
|
|
11
|
+
import inspect
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MetaOperationType(Enum):
|
|
15
|
+
"""Types of metaprogramming operations."""
|
|
16
|
+
MACRO = "macro"
|
|
17
|
+
TRANSFORM = "transform"
|
|
18
|
+
REFLECTION = "reflection"
|
|
19
|
+
CODE_GEN = "code_gen"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class ASTNode:
|
|
24
|
+
"""Simplified AST node representation."""
|
|
25
|
+
type: str # Node type (statement, expression, etc.)
|
|
26
|
+
value: Any = None # Node value
|
|
27
|
+
children: List['ASTNode'] = field(default_factory=list)
|
|
28
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
29
|
+
|
|
30
|
+
def clone(self) -> 'ASTNode':
|
|
31
|
+
"""Create a deep copy of the node."""
|
|
32
|
+
new_children = [child.clone() for child in self.children]
|
|
33
|
+
return ASTNode(
|
|
34
|
+
type=self.type,
|
|
35
|
+
value=self.value,
|
|
36
|
+
children=new_children,
|
|
37
|
+
metadata=self.metadata.copy()
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def find_nodes(self, node_type: str) -> List['ASTNode']:
|
|
41
|
+
"""Find all nodes of a given type."""
|
|
42
|
+
results = []
|
|
43
|
+
if self.type == node_type:
|
|
44
|
+
results.append(self)
|
|
45
|
+
for child in self.children:
|
|
46
|
+
results.extend(child.find_nodes(node_type))
|
|
47
|
+
return results
|
|
48
|
+
|
|
49
|
+
def walk(self, visitor: Callable[['ASTNode'], None]):
|
|
50
|
+
"""Walk tree and call visitor for each node."""
|
|
51
|
+
visitor(self)
|
|
52
|
+
for child in self.children:
|
|
53
|
+
child.walk(visitor)
|
|
54
|
+
|
|
55
|
+
def replace_node(self, old: 'ASTNode', new: 'ASTNode') -> bool:
|
|
56
|
+
"""Replace a node in the tree."""
|
|
57
|
+
for i, child in enumerate(self.children):
|
|
58
|
+
if child is old:
|
|
59
|
+
self.children[i] = new
|
|
60
|
+
return True
|
|
61
|
+
if child.replace_node(old, new):
|
|
62
|
+
return True
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
def __str__(self) -> str:
|
|
66
|
+
"""String representation."""
|
|
67
|
+
if self.value:
|
|
68
|
+
return f"{self.type}({self.value})"
|
|
69
|
+
return f"{self.type}[{len(self.children)}]"
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class Macro:
|
|
73
|
+
"""A macro for compile-time code transformation."""
|
|
74
|
+
|
|
75
|
+
def __init__(self, name: str, pattern: str, transformer: Callable[[ASTNode], ASTNode]):
|
|
76
|
+
"""
|
|
77
|
+
Initialize macro.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
name: Macro name
|
|
81
|
+
pattern: Pattern to match (e.g., "action:foo")
|
|
82
|
+
transformer: Function that transforms matching AST
|
|
83
|
+
"""
|
|
84
|
+
self.name = name
|
|
85
|
+
self.pattern = pattern
|
|
86
|
+
self.transformer = transformer
|
|
87
|
+
|
|
88
|
+
def matches(self, node: ASTNode) -> bool:
|
|
89
|
+
"""Check if AST node matches macro pattern."""
|
|
90
|
+
# Simple pattern matching
|
|
91
|
+
if ":" in self.pattern:
|
|
92
|
+
node_type, node_name = self.pattern.split(":", 1)
|
|
93
|
+
return node.type == node_type and node.value == node_name
|
|
94
|
+
return node.type == self.pattern
|
|
95
|
+
|
|
96
|
+
def apply(self, node: ASTNode) -> ASTNode:
|
|
97
|
+
"""Apply macro transformation to node."""
|
|
98
|
+
if self.matches(node):
|
|
99
|
+
return self.transformer(node)
|
|
100
|
+
return node
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class MetaRegistry:
|
|
104
|
+
"""
|
|
105
|
+
Registry for metaprogramming hooks.
|
|
106
|
+
|
|
107
|
+
Manages macros, transformers, and code generators.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
def __init__(self):
|
|
111
|
+
"""Initialize metaprogramming registry."""
|
|
112
|
+
self.macros: Dict[str, Macro] = {}
|
|
113
|
+
self.transformers: Dict[str, Callable] = {}
|
|
114
|
+
self.generators: Dict[str, Callable] = {}
|
|
115
|
+
self.reflection_hooks: List[Callable] = []
|
|
116
|
+
|
|
117
|
+
def register_macro(self, macro: Macro):
|
|
118
|
+
"""Register a macro."""
|
|
119
|
+
self.macros[macro.name] = macro
|
|
120
|
+
|
|
121
|
+
def register_transformer(self, name: str, transformer: Callable[[ASTNode], ASTNode]):
|
|
122
|
+
"""Register an AST transformer."""
|
|
123
|
+
self.transformers[name] = transformer
|
|
124
|
+
|
|
125
|
+
def register_generator(self, name: str, generator: Callable[..., str]):
|
|
126
|
+
"""Register a code generator."""
|
|
127
|
+
self.generators[name] = generator
|
|
128
|
+
|
|
129
|
+
def register_reflection_hook(self, hook: Callable[[Any], Dict]):
|
|
130
|
+
"""Register a reflection hook."""
|
|
131
|
+
self.reflection_hooks.append(hook)
|
|
132
|
+
|
|
133
|
+
def apply_macros(self, ast: ASTNode) -> ASTNode:
|
|
134
|
+
"""Apply all registered macros to AST."""
|
|
135
|
+
result = ast.clone()
|
|
136
|
+
|
|
137
|
+
def apply_to_node(node: ASTNode) -> None:
|
|
138
|
+
# Apply each macro to the node
|
|
139
|
+
for macro in self.macros.values():
|
|
140
|
+
if macro.matches(node):
|
|
141
|
+
transformed = macro.apply(node)
|
|
142
|
+
# Update the node in place with transformed metadata
|
|
143
|
+
node.metadata.update(transformed.metadata)
|
|
144
|
+
|
|
145
|
+
# Walk tree and apply macros
|
|
146
|
+
result.walk(apply_to_node)
|
|
147
|
+
return result
|
|
148
|
+
|
|
149
|
+
def apply_transformers(self, ast: ASTNode, name: str) -> Optional[ASTNode]:
|
|
150
|
+
"""Apply a specific transformer."""
|
|
151
|
+
if name in self.transformers:
|
|
152
|
+
return self.transformers[name](ast)
|
|
153
|
+
return None
|
|
154
|
+
|
|
155
|
+
def generate_code(self, name: str, *args, **kwargs) -> Optional[str]:
|
|
156
|
+
"""Generate code using a registered generator."""
|
|
157
|
+
if name in self.generators:
|
|
158
|
+
return self.generators[name](*args, **kwargs)
|
|
159
|
+
return None
|
|
160
|
+
|
|
161
|
+
def reflect(self, obj: Any) -> Dict[str, Any]:
|
|
162
|
+
"""Get metadata about an object via reflection."""
|
|
163
|
+
info = {
|
|
164
|
+
"type": type(obj).__name__,
|
|
165
|
+
"callable": callable(obj),
|
|
166
|
+
"methods": [],
|
|
167
|
+
"attributes": []
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
# Get methods and attributes
|
|
171
|
+
if hasattr(obj, "__dict__"):
|
|
172
|
+
for name, value in obj.__dict__.items():
|
|
173
|
+
if callable(value):
|
|
174
|
+
info["methods"].append(name)
|
|
175
|
+
else:
|
|
176
|
+
info["attributes"].append({
|
|
177
|
+
"name": name,
|
|
178
|
+
"type": type(value).__name__
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
# Apply reflection hooks
|
|
182
|
+
for hook in self.reflection_hooks:
|
|
183
|
+
try:
|
|
184
|
+
extra_info = hook(obj)
|
|
185
|
+
info.update(extra_info)
|
|
186
|
+
except Exception:
|
|
187
|
+
pass
|
|
188
|
+
|
|
189
|
+
return info
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class MacroBuilder:
|
|
193
|
+
"""Builder for creating macros."""
|
|
194
|
+
|
|
195
|
+
def __init__(self, name: str, pattern: str):
|
|
196
|
+
"""Initialize macro builder."""
|
|
197
|
+
self.name = name
|
|
198
|
+
self.pattern = pattern
|
|
199
|
+
self.transformations: List[Callable[[ASTNode], ASTNode]] = []
|
|
200
|
+
|
|
201
|
+
def add_transformation(self, func: Callable[[ASTNode], ASTNode]) -> 'MacroBuilder':
|
|
202
|
+
"""Add a transformation step."""
|
|
203
|
+
self.transformations.append(func)
|
|
204
|
+
return self
|
|
205
|
+
|
|
206
|
+
def replace_value(self, old_value: Any, new_value: Any) -> 'MacroBuilder':
|
|
207
|
+
"""Add a value replacement transformation."""
|
|
208
|
+
def transform(node: ASTNode) -> ASTNode:
|
|
209
|
+
if node.value == old_value:
|
|
210
|
+
node.value = new_value
|
|
211
|
+
return node
|
|
212
|
+
return self.add_transformation(transform)
|
|
213
|
+
|
|
214
|
+
def add_metadata(self, key: str, value: Any) -> 'MacroBuilder':
|
|
215
|
+
"""Add metadata to matched nodes."""
|
|
216
|
+
def transform(node: ASTNode) -> ASTNode:
|
|
217
|
+
node.metadata[key] = value
|
|
218
|
+
return node
|
|
219
|
+
return self.add_transformation(transform)
|
|
220
|
+
|
|
221
|
+
def build(self) -> Macro:
|
|
222
|
+
"""Build the macro."""
|
|
223
|
+
def combined_transformer(node: ASTNode) -> ASTNode:
|
|
224
|
+
result = node.clone()
|
|
225
|
+
for transform in self.transformations:
|
|
226
|
+
result = transform(result)
|
|
227
|
+
return result
|
|
228
|
+
|
|
229
|
+
return Macro(self.name, self.pattern, combined_transformer)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
# Common macro patterns
|
|
233
|
+
|
|
234
|
+
class CommonMacros:
|
|
235
|
+
"""Pre-defined common macros."""
|
|
236
|
+
|
|
237
|
+
@staticmethod
|
|
238
|
+
def once(pattern: str) -> Macro:
|
|
239
|
+
"""Macro that marks code to run only once."""
|
|
240
|
+
return MacroBuilder(f"{pattern}_once", pattern) \
|
|
241
|
+
.add_metadata("run_once", True) \
|
|
242
|
+
.build()
|
|
243
|
+
|
|
244
|
+
@staticmethod
|
|
245
|
+
def inline(pattern: str) -> Macro:
|
|
246
|
+
"""Macro that marks code for inlining."""
|
|
247
|
+
return MacroBuilder(f"{pattern}_inline", pattern) \
|
|
248
|
+
.add_metadata("inline", True) \
|
|
249
|
+
.build()
|
|
250
|
+
|
|
251
|
+
@staticmethod
|
|
252
|
+
def deprecated(pattern: str, message: str = "") -> Macro:
|
|
253
|
+
"""Macro that marks code as deprecated."""
|
|
254
|
+
return MacroBuilder(f"{pattern}_deprecated", pattern) \
|
|
255
|
+
.add_metadata("deprecated", True) \
|
|
256
|
+
.add_metadata("deprecation_message", message) \
|
|
257
|
+
.build()
|
|
258
|
+
|
|
259
|
+
@staticmethod
|
|
260
|
+
def optimize(pattern: str) -> Macro:
|
|
261
|
+
"""Macro that marks code for optimization."""
|
|
262
|
+
return MacroBuilder(f"{pattern}_optimize", pattern) \
|
|
263
|
+
.add_metadata("optimize", True) \
|
|
264
|
+
.build()
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class ReflectionAPI:
|
|
268
|
+
"""API for runtime reflection."""
|
|
269
|
+
|
|
270
|
+
@staticmethod
|
|
271
|
+
def get_signature(func: Callable) -> Dict[str, Any]:
|
|
272
|
+
"""Get function signature."""
|
|
273
|
+
try:
|
|
274
|
+
sig = inspect.signature(func)
|
|
275
|
+
return {
|
|
276
|
+
"params": list(sig.parameters.keys()),
|
|
277
|
+
"return_annotation": str(sig.return_annotation) if sig.return_annotation else None
|
|
278
|
+
}
|
|
279
|
+
except Exception:
|
|
280
|
+
return {"params": [], "return_annotation": None}
|
|
281
|
+
|
|
282
|
+
@staticmethod
|
|
283
|
+
def get_source(func: Callable) -> Optional[str]:
|
|
284
|
+
"""Get function source code."""
|
|
285
|
+
try:
|
|
286
|
+
return inspect.getsource(func)
|
|
287
|
+
except Exception:
|
|
288
|
+
return None
|
|
289
|
+
|
|
290
|
+
@staticmethod
|
|
291
|
+
def get_docstring(obj: Any) -> Optional[str]:
|
|
292
|
+
"""Get object docstring."""
|
|
293
|
+
return inspect.getdoc(obj)
|
|
294
|
+
|
|
295
|
+
@staticmethod
|
|
296
|
+
def get_members(obj: Any) -> List[str]:
|
|
297
|
+
"""Get all members of an object."""
|
|
298
|
+
try:
|
|
299
|
+
return [name for name, _ in inspect.getmembers(obj)]
|
|
300
|
+
except Exception:
|
|
301
|
+
return []
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
# Global metaprogramming registry
|
|
305
|
+
|
|
306
|
+
_global_meta_registry = MetaRegistry()
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def get_meta_registry() -> MetaRegistry:
|
|
310
|
+
"""Get the global metaprogramming registry."""
|
|
311
|
+
return _global_meta_registry
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def register_macro(macro: Macro):
|
|
315
|
+
"""Register a macro globally."""
|
|
316
|
+
_global_meta_registry.register_macro(macro)
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def apply_all_macros(ast: ASTNode) -> ASTNode:
|
|
320
|
+
"""Apply all registered macros."""
|
|
321
|
+
return _global_meta_registry.apply_macros(ast)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module cache for Zexus interpreter.
|
|
3
|
+
|
|
4
|
+
This module provides caching functionality for loaded Zexus modules to avoid
|
|
5
|
+
re-parsing and re-evaluating modules that have already been loaded.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import threading
|
|
10
|
+
from typing import Dict, Optional
|
|
11
|
+
from .object import Environment
|
|
12
|
+
|
|
13
|
+
_MODULE_CACHE: Dict[str, Environment] = {}
|
|
14
|
+
_MODULE_CACHE_LOCK = threading.Lock()
|
|
15
|
+
|
|
16
|
+
def get_cached_module(module_path: str) -> Optional[Environment]:
|
|
17
|
+
"""Get a cached module environment if available"""
|
|
18
|
+
with _MODULE_CACHE_LOCK:
|
|
19
|
+
return _MODULE_CACHE.get(module_path)
|
|
20
|
+
|
|
21
|
+
def cache_module(module_path: str, module_env: Environment) -> None:
|
|
22
|
+
"""Cache a loaded module environment"""
|
|
23
|
+
with _MODULE_CACHE_LOCK:
|
|
24
|
+
_MODULE_CACHE[module_path] = module_env
|
|
25
|
+
|
|
26
|
+
def clear_module_cache() -> None:
|
|
27
|
+
"""Clear the entire module cache"""
|
|
28
|
+
with _MODULE_CACHE_LOCK:
|
|
29
|
+
_MODULE_CACHE.clear()
|
|
30
|
+
|
|
31
|
+
def invalidate_module(module_path: str) -> None:
|
|
32
|
+
"""Invalidate a single module entry from the cache (if present)"""
|
|
33
|
+
norm = normalize_path(module_path)
|
|
34
|
+
with _MODULE_CACHE_LOCK:
|
|
35
|
+
if norm in _MODULE_CACHE:
|
|
36
|
+
del _MODULE_CACHE[norm]
|
|
37
|
+
|
|
38
|
+
def list_cached_modules() -> list[str]:
|
|
39
|
+
"""Return a list of normalized module paths currently cached"""
|
|
40
|
+
with _MODULE_CACHE_LOCK:
|
|
41
|
+
return list(_MODULE_CACHE.keys())
|
|
42
|
+
|
|
43
|
+
def get_module_candidates(file_path: str, importer_file: str = None) -> list[str]:
|
|
44
|
+
"""Get candidate paths for a module, checking zpm_modules etc.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
file_path: The module path to import
|
|
48
|
+
importer_file: The absolute path of the file doing the importing (for relative imports)
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
List of candidate absolute paths to check
|
|
52
|
+
"""
|
|
53
|
+
candidates = []
|
|
54
|
+
|
|
55
|
+
if os.path.isabs(file_path):
|
|
56
|
+
# Absolute path - use as-is
|
|
57
|
+
candidates.append(file_path)
|
|
58
|
+
else:
|
|
59
|
+
# Relative path - resolve based on importer's directory
|
|
60
|
+
if importer_file and file_path.startswith('./'):
|
|
61
|
+
# Relative to the importing file's directory
|
|
62
|
+
importer_dir = os.path.dirname(importer_file)
|
|
63
|
+
resolved_path = os.path.join(importer_dir, file_path[2:]) # Remove './'
|
|
64
|
+
candidates.append(resolved_path)
|
|
65
|
+
elif importer_file and file_path.startswith('../'):
|
|
66
|
+
# Parent directory relative to importing file
|
|
67
|
+
importer_dir = os.path.dirname(importer_file)
|
|
68
|
+
resolved_path = os.path.join(importer_dir, file_path)
|
|
69
|
+
candidates.append(resolved_path)
|
|
70
|
+
else:
|
|
71
|
+
# Relative to current working directory
|
|
72
|
+
candidates.append(os.path.join(os.getcwd(), file_path))
|
|
73
|
+
|
|
74
|
+
# Also check zpm_modules directory
|
|
75
|
+
candidates.append(os.path.join(os.getcwd(), 'zpm_modules', file_path))
|
|
76
|
+
|
|
77
|
+
# Try adding typical extensions (.zx, .zexus)
|
|
78
|
+
extended_candidates = []
|
|
79
|
+
for candidate in candidates:
|
|
80
|
+
extended_candidates.append(candidate)
|
|
81
|
+
if not candidate.endswith(('.zx', '.zexus')):
|
|
82
|
+
extended_candidates.append(candidate + '.zx')
|
|
83
|
+
extended_candidates.append(candidate + '.zexus')
|
|
84
|
+
|
|
85
|
+
return extended_candidates
|
|
86
|
+
|
|
87
|
+
def normalize_path(path: str) -> str:
|
|
88
|
+
"""Normalize a path for consistent cache keys"""
|
|
89
|
+
return os.path.abspath(os.path.expanduser(path))
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# module_manager.py
|
|
2
|
+
import os
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
class ModuleManager:
|
|
6
|
+
def __init__(self, base_path=None):
|
|
7
|
+
self.base_path = Path(base_path or os.getcwd())
|
|
8
|
+
self.module_cache = {}
|
|
9
|
+
self.search_paths = [
|
|
10
|
+
self.base_path,
|
|
11
|
+
self.base_path / "zpm_modules", # Keep existing zpm_modules path
|
|
12
|
+
self.base_path / "modules",
|
|
13
|
+
self.base_path / "lib"
|
|
14
|
+
]
|
|
15
|
+
self._debug = False
|
|
16
|
+
|
|
17
|
+
def normalize_path(self, path):
|
|
18
|
+
"""Normalize a module path"""
|
|
19
|
+
return str(Path(path).resolve()).replace("\\", "/").strip()
|
|
20
|
+
|
|
21
|
+
def resolve_module_path(self, path, current_dir=""):
|
|
22
|
+
"""Resolve a module path to an absolute path"""
|
|
23
|
+
# Support existing behavior
|
|
24
|
+
if isinstance(current_dir, str) and current_dir:
|
|
25
|
+
base = Path(current_dir)
|
|
26
|
+
else:
|
|
27
|
+
base = self.base_path
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
if path.startswith("./"):
|
|
31
|
+
# Relative path
|
|
32
|
+
resolved = (base / path[2:]).resolve()
|
|
33
|
+
elif path.startswith("/"):
|
|
34
|
+
# Absolute path
|
|
35
|
+
resolved = Path(path).resolve()
|
|
36
|
+
else:
|
|
37
|
+
# Try zpm_modules first (existing behavior)
|
|
38
|
+
zpm_path = (self.base_path / "zpm_modules" / path).resolve()
|
|
39
|
+
if zpm_path.exists():
|
|
40
|
+
return self.normalize_path(zpm_path)
|
|
41
|
+
|
|
42
|
+
# Search in other paths
|
|
43
|
+
for search_path in self.search_paths:
|
|
44
|
+
test_path = (search_path / path).resolve()
|
|
45
|
+
if test_path.exists():
|
|
46
|
+
return self.normalize_path(test_path)
|
|
47
|
+
|
|
48
|
+
# Try with .zx extension
|
|
49
|
+
test_path_zx = (search_path / f"{path}.zx").resolve()
|
|
50
|
+
if test_path_zx.exists():
|
|
51
|
+
return self.normalize_path(test_path_zx)
|
|
52
|
+
|
|
53
|
+
# Default to zpm_modules (maintain compatibility)
|
|
54
|
+
resolved = zpm_path
|
|
55
|
+
|
|
56
|
+
return self.normalize_path(resolved)
|
|
57
|
+
except (TypeError, ValueError):
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
def get_module(self, path):
|
|
61
|
+
"""Get a cached module or None"""
|
|
62
|
+
return self.module_cache.get(self.normalize_path(path))
|
|
63
|
+
|
|
64
|
+
def cache_module(self, path, module_env):
|
|
65
|
+
"""Cache a module environment"""
|
|
66
|
+
self.module_cache[self.normalize_path(path)] = module_env
|
|
67
|
+
|
|
68
|
+
def clear_cache(self):
|
|
69
|
+
"""Clear the module cache"""
|
|
70
|
+
self.module_cache.clear()
|
|
71
|
+
if self._debug:
|
|
72
|
+
print("[MOD] Module cache cleared")
|
|
73
|
+
|
|
74
|
+
def add_search_path(self, path):
|
|
75
|
+
"""Add a directory to module search paths"""
|
|
76
|
+
path = Path(path).resolve()
|
|
77
|
+
if path not in self.search_paths:
|
|
78
|
+
self.search_paths.append(path)
|
|
79
|
+
if self._debug:
|
|
80
|
+
print(f"[MOD] Added search path: {path}")
|
|
81
|
+
|
|
82
|
+
def enable_debug(self):
|
|
83
|
+
"""Enable debug logging"""
|
|
84
|
+
self._debug = True
|
|
85
|
+
|
|
86
|
+
def disable_debug(self):
|
|
87
|
+
"""Disable debug logging"""
|
|
88
|
+
self._debug = False
|
|
89
|
+
|
|
90
|
+
# Create a default instance for backwards compatibility
|
|
91
|
+
_default_manager = ModuleManager()
|
|
92
|
+
|
|
93
|
+
# Expose existing API through default instance
|
|
94
|
+
def normalize_path(path):
|
|
95
|
+
return _default_manager.normalize_path(path)
|
|
96
|
+
|
|
97
|
+
def resolve_module_path(path, current_dir=""):
|
|
98
|
+
return _default_manager.resolve_module_path(path, current_dir)
|
|
99
|
+
|
|
100
|
+
def get_module(path):
|
|
101
|
+
return _default_manager.get_module(path)
|
|
102
|
+
|
|
103
|
+
def cache_module(path, module_env):
|
|
104
|
+
return _default_manager.cache_module(path, module_env)
|
|
105
|
+
|
|
106
|
+
def clear_cache():
|
|
107
|
+
return _default_manager.clear_cache()
|