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,148 @@
1
+ """Regex module for Zexus standard library."""
2
+
3
+ import re
4
+ from typing import List, Dict, Any, Optional
5
+
6
+
7
+ class RegexModule:
8
+ """Provides regular expression operations."""
9
+
10
+ @staticmethod
11
+ def match(pattern: str, text: str, flags: int = 0) -> Optional[Dict[str, Any]]:
12
+ """Match pattern at start of text."""
13
+ m = re.match(pattern, text, flags)
14
+ if m:
15
+ return {
16
+ 'matched': True,
17
+ 'groups': list(m.groups()),
18
+ 'group_dict': m.groupdict(),
19
+ 'span': m.span(),
20
+ 'start': m.start(),
21
+ 'end': m.end()
22
+ }
23
+ return None
24
+
25
+ @staticmethod
26
+ def search(pattern: str, text: str, flags: int = 0) -> Optional[Dict[str, Any]]:
27
+ """Search for pattern in text."""
28
+ m = re.search(pattern, text, flags)
29
+ if m:
30
+ return {
31
+ 'matched': True,
32
+ 'groups': list(m.groups()),
33
+ 'group_dict': m.groupdict(),
34
+ 'span': m.span(),
35
+ 'start': m.start(),
36
+ 'end': m.end()
37
+ }
38
+ return None
39
+
40
+ @staticmethod
41
+ def findall(pattern: str, text: str, flags: int = 0) -> List[str]:
42
+ """Find all occurrences of pattern."""
43
+ return re.findall(pattern, text, flags)
44
+
45
+ @staticmethod
46
+ def finditer(pattern: str, text: str, flags: int = 0) -> List[Dict[str, Any]]:
47
+ """Find all matches as iterator."""
48
+ matches = []
49
+ for m in re.finditer(pattern, text, flags):
50
+ matches.append({
51
+ 'matched': True,
52
+ 'groups': list(m.groups()),
53
+ 'group_dict': m.groupdict(),
54
+ 'span': m.span(),
55
+ 'start': m.start(),
56
+ 'end': m.end()
57
+ })
58
+ return matches
59
+
60
+ @staticmethod
61
+ def sub(pattern: str, replacement: str, text: str, count: int = 0, flags: int = 0) -> str:
62
+ """Replace pattern with replacement."""
63
+ return re.sub(pattern, replacement, text, count, flags)
64
+
65
+ @staticmethod
66
+ def subn(pattern: str, replacement: str, text: str, count: int = 0, flags: int = 0) -> tuple:
67
+ """Replace pattern and return (new_string, number_of_subs)."""
68
+ return re.subn(pattern, replacement, text, count, flags)
69
+
70
+ @staticmethod
71
+ def split(pattern: str, text: str, maxsplit: int = 0, flags: int = 0) -> List[str]:
72
+ """Split text by pattern."""
73
+ return re.split(pattern, text, maxsplit, flags)
74
+
75
+ @staticmethod
76
+ def escape(pattern: str) -> str:
77
+ """Escape special characters in pattern."""
78
+ return re.escape(pattern)
79
+
80
+ @staticmethod
81
+ def compile(pattern: str, flags: int = 0) -> str:
82
+ """Compile regex pattern (returns pattern string for Zexus)."""
83
+ # In Zexus, we can't return compiled pattern objects
84
+ # Just validate and return the pattern
85
+ re.compile(pattern, flags) # Validate
86
+ return pattern
87
+
88
+ @staticmethod
89
+ def is_match(pattern: str, text: str, flags: int = 0) -> bool:
90
+ """Check if pattern matches text."""
91
+ return re.match(pattern, text, flags) is not None
92
+
93
+ @staticmethod
94
+ def is_search(pattern: str, text: str, flags: int = 0) -> bool:
95
+ """Check if pattern exists in text."""
96
+ return re.search(pattern, text, flags) is not None
97
+
98
+ @staticmethod
99
+ def count_matches(pattern: str, text: str, flags: int = 0) -> int:
100
+ """Count number of matches."""
101
+ return len(re.findall(pattern, text, flags))
102
+
103
+ @staticmethod
104
+ def extract_groups(pattern: str, text: str, flags: int = 0) -> List[str]:
105
+ """Extract all groups from first match."""
106
+ m = re.search(pattern, text, flags)
107
+ if m:
108
+ return list(m.groups())
109
+ return []
110
+
111
+ @staticmethod
112
+ def extract_all_groups(pattern: str, text: str, flags: int = 0) -> List[List[str]]:
113
+ """Extract groups from all matches."""
114
+ matches = []
115
+ for m in re.finditer(pattern, text, flags):
116
+ matches.append(list(m.groups()))
117
+ return matches
118
+
119
+ # Flag constants
120
+ IGNORECASE = re.IGNORECASE
121
+ MULTILINE = re.MULTILINE
122
+ DOTALL = re.DOTALL
123
+ VERBOSE = re.VERBOSE
124
+ ASCII = re.ASCII
125
+ UNICODE = re.UNICODE
126
+
127
+
128
+ # Export functions for easy access
129
+ match = RegexModule.match
130
+ search = RegexModule.search
131
+ findall = RegexModule.findall
132
+ finditer = RegexModule.finditer
133
+ sub = RegexModule.sub
134
+ subn = RegexModule.subn
135
+ split = RegexModule.split
136
+ escape = RegexModule.escape
137
+ compile = RegexModule.compile
138
+ is_match = RegexModule.is_match
139
+ is_search = RegexModule.is_search
140
+ count_matches = RegexModule.count_matches
141
+ extract_groups = RegexModule.extract_groups
142
+ extract_all_groups = RegexModule.extract_all_groups
143
+ IGNORECASE = RegexModule.IGNORECASE
144
+ MULTILINE = RegexModule.MULTILINE
145
+ DOTALL = RegexModule.DOTALL
146
+ VERBOSE = RegexModule.VERBOSE
147
+ ASCII = RegexModule.ASCII
148
+ UNICODE = RegexModule.UNICODE
@@ -0,0 +1,253 @@
1
+ """Socket/TCP primitives module for Zexus standard library."""
2
+
3
+ import socket
4
+ import threading
5
+ import time
6
+ from typing import Callable, Optional, Dict, Any
7
+
8
+
9
+ class SocketModule:
10
+ """Provides socket and TCP operations."""
11
+
12
+ @staticmethod
13
+ def create_server(host: str, port: int, handler: Callable, backlog: int = 5) -> 'TCPServer':
14
+ """Create a TCP server that listens for connections.
15
+
16
+ Args:
17
+ host: Host address to bind to (e.g., '0.0.0.0', 'localhost')
18
+ port: Port number to listen on
19
+ handler: Callback function called for each connection
20
+ backlog: Maximum number of queued connections
21
+
22
+ Returns:
23
+ TCPServer instance
24
+ """
25
+ return TCPServer(host, port, handler, backlog)
26
+
27
+ @staticmethod
28
+ def create_connection(host: str, port: int, timeout: float = 5.0) -> 'TCPConnection':
29
+ """Create a TCP client connection.
30
+
31
+ Args:
32
+ host: Remote host to connect to
33
+ port: Remote port to connect to
34
+ timeout: Connection timeout in seconds
35
+
36
+ Returns:
37
+ TCPConnection instance
38
+ """
39
+ return TCPConnection(host, port, timeout)
40
+
41
+
42
+ class TCPServer:
43
+ """TCP server that accepts connections and handles them with a callback."""
44
+
45
+ def __init__(self, host: str, port: int, handler: Callable, backlog: int = 5):
46
+ self.host = host
47
+ self.port = port
48
+ self.handler = handler
49
+ self.backlog = backlog
50
+ self.socket: Optional[socket.socket] = None
51
+ self.running = False
52
+ self.thread: Optional[threading.Thread] = None
53
+
54
+ def start(self) -> None:
55
+ """Start the server in a background thread."""
56
+ if self.running:
57
+ raise RuntimeError("Server is already running")
58
+
59
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
60
+ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
61
+ self.socket.bind((self.host, self.port))
62
+ self.socket.listen(self.backlog)
63
+ self.running = True
64
+
65
+ # Start accept loop in background thread
66
+ self.thread = threading.Thread(target=self._accept_loop, daemon=True)
67
+ self.thread.start()
68
+
69
+ def _accept_loop(self):
70
+ """Accept connections and spawn handler threads."""
71
+ while self.running:
72
+ try:
73
+ self.socket.settimeout(1.0) # Allow checking self.running
74
+ client_socket, address = self.socket.accept()
75
+
76
+ # Spawn handler in new thread
77
+ handler_thread = threading.Thread(
78
+ target=self._handle_connection,
79
+ args=(client_socket, address),
80
+ daemon=True
81
+ )
82
+ handler_thread.start()
83
+
84
+ except socket.timeout:
85
+ continue
86
+ except Exception as e:
87
+ if self.running: # Only log if we're not shutting down
88
+ print(f"Server accept error: {e}")
89
+ break
90
+
91
+ def _handle_connection(self, client_socket: socket.socket, address: tuple):
92
+ """Handle a single client connection."""
93
+ try:
94
+ connection = TCPConnection.from_socket(client_socket, address)
95
+ self.handler(connection)
96
+ except Exception as e:
97
+ print(f"Connection handler error: {e}")
98
+ finally:
99
+ try:
100
+ client_socket.close()
101
+ except:
102
+ pass
103
+
104
+ def stop(self) -> None:
105
+ """Stop the server."""
106
+ self.running = False
107
+ if self.socket:
108
+ try:
109
+ self.socket.close()
110
+ except:
111
+ pass
112
+ if self.thread:
113
+ self.thread.join(timeout=2.0)
114
+
115
+ def is_running(self) -> bool:
116
+ """Check if server is running."""
117
+ return self.running
118
+
119
+ def get_address(self) -> Dict[str, Any]:
120
+ """Get server address info."""
121
+ return {
122
+ 'host': self.host,
123
+ 'port': self.port,
124
+ 'running': self.running
125
+ }
126
+
127
+
128
+ class TCPConnection:
129
+ """Represents a TCP connection (client or server-side)."""
130
+
131
+ def __init__(self, host: str, port: int, timeout: float = 5.0):
132
+ """Create a new client connection."""
133
+ self.host = host
134
+ self.port = port
135
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
136
+ self.socket.settimeout(timeout)
137
+ self.socket.connect((host, port))
138
+ self.connected = True
139
+
140
+ @classmethod
141
+ def from_socket(cls, sock: socket.socket, address: tuple):
142
+ """Create TCPConnection from existing socket (for server-side)."""
143
+ conn = cls.__new__(cls)
144
+ conn.socket = sock
145
+ conn.host = address[0]
146
+ conn.port = address[1]
147
+ conn.connected = True
148
+ return conn
149
+
150
+ def send(self, data: bytes) -> int:
151
+ """Send data over the connection.
152
+
153
+ Args:
154
+ data: Bytes to send
155
+
156
+ Returns:
157
+ Number of bytes sent
158
+ """
159
+ if not self.connected:
160
+ raise RuntimeError("Connection is closed")
161
+ return self.socket.sendall(data) or len(data)
162
+
163
+ def send_string(self, text: str, encoding: str = 'utf-8') -> int:
164
+ """Send string over the connection.
165
+
166
+ Args:
167
+ text: String to send
168
+ encoding: Text encoding
169
+
170
+ Returns:
171
+ Number of bytes sent
172
+ """
173
+ return self.send(text.encode(encoding))
174
+
175
+ def receive(self, buffer_size: int = 4096) -> bytes:
176
+ """Receive data from the connection.
177
+
178
+ Args:
179
+ buffer_size: Maximum bytes to receive
180
+
181
+ Returns:
182
+ Received bytes (empty if connection closed)
183
+ """
184
+ if not self.connected:
185
+ raise RuntimeError("Connection is closed")
186
+
187
+ try:
188
+ data = self.socket.recv(buffer_size)
189
+ if not data:
190
+ self.connected = False
191
+ return data
192
+ except socket.timeout:
193
+ return b''
194
+
195
+ def receive_string(self, buffer_size: int = 4096, encoding: str = 'utf-8') -> str:
196
+ """Receive string from the connection.
197
+
198
+ Args:
199
+ buffer_size: Maximum bytes to receive
200
+ encoding: Text encoding
201
+
202
+ Returns:
203
+ Received string
204
+ """
205
+ data = self.receive(buffer_size)
206
+ return data.decode(encoding) if data else ''
207
+
208
+ def receive_all(self, timeout: float = 5.0) -> bytes:
209
+ """Receive all available data until connection closes or timeout.
210
+
211
+ Args:
212
+ timeout: Maximum time to wait
213
+
214
+ Returns:
215
+ All received bytes
216
+ """
217
+ chunks = []
218
+ start_time = time.time()
219
+ self.socket.settimeout(0.1) # Small timeout for checking
220
+
221
+ while time.time() - start_time < timeout:
222
+ try:
223
+ chunk = self.socket.recv(4096)
224
+ if not chunk:
225
+ break
226
+ chunks.append(chunk)
227
+ except socket.timeout:
228
+ if chunks: # If we got some data, we're done
229
+ break
230
+ continue
231
+
232
+ return b''.join(chunks)
233
+
234
+ def close(self) -> None:
235
+ """Close the connection."""
236
+ if self.connected:
237
+ try:
238
+ self.socket.close()
239
+ except:
240
+ pass
241
+ self.connected = False
242
+
243
+ def is_connected(self) -> bool:
244
+ """Check if connection is still open."""
245
+ return self.connected
246
+
247
+ def get_address(self) -> Dict[str, Any]:
248
+ """Get connection address info."""
249
+ return {
250
+ 'host': self.host,
251
+ 'port': self.port,
252
+ 'connected': self.connected
253
+ }
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env zexus
2
+ # Zexus Testing Framework
3
+ # Provides assertion functions and test utilities
4
+
5
+ # Global test state - using individual variables instead of map
6
+ let _total = 0
7
+ let _passed = 0
8
+ let _failed = 0
9
+ let _current_suite = ""
10
+ let _failures = []
11
+
12
+ # Reset test statistics
13
+ action reset_test_stats() {
14
+ _total = 0
15
+ _passed = 0
16
+ _failed = 0
17
+ _current_suite = ""
18
+ _failures = []
19
+ }
20
+
21
+ # Start a test suite
22
+ action describe(suite_name) {
23
+ _current_suite = suite_name
24
+ print("\n" + suite_name)
25
+ print("=" + string_repeat("=", len(suite_name)))
26
+ }
27
+
28
+ # Helper to repeat string
29
+ action string_repeat(str, count) {
30
+ let result = ""
31
+ let i = 0
32
+ while i < count {
33
+ result = result + str
34
+ i = i + 1
35
+ }
36
+ return result
37
+ }
38
+
39
+ # Individual test case
40
+ action it(description, test_func) {
41
+ _total = _total + 1
42
+
43
+ try {
44
+ test_func()
45
+ _passed = _passed + 1
46
+ print(" ✓ " + description)
47
+ return true
48
+ } catch (e) {
49
+ _failed = _failed + 1
50
+ let failure = {
51
+ "suite": _current_suite,
52
+ "test": description,
53
+ "error": string(e)
54
+ }
55
+ _failures = push(_failures, failure)
56
+ print(" ✗ " + description)
57
+ print(" Error: " + string(e))
58
+ return false
59
+ }
60
+ }
61
+
62
+ # Assertion: equality
63
+ action assert_eq(actual, expected, message) {
64
+ if actual != expected {
65
+ let error_msg = "Assertion failed: " + message
66
+ error_msg = error_msg + "\n Expected: " + string(expected)
67
+ error_msg = error_msg + "\n Got: " + string(actual)
68
+ throw error_msg
69
+ }
70
+ }
71
+
72
+ # Assertion: not equal
73
+ action assert_ne(actual, expected, message) {
74
+ if actual == expected {
75
+ let error_msg = "Assertion failed: " + message
76
+ error_msg = error_msg + "\n Expected NOT to equal: " + string(expected)
77
+ error_msg = error_msg + "\n But got: " + string(actual)
78
+ throw error_msg
79
+ }
80
+ }
81
+
82
+ # Assertion: true
83
+ action assert_true(value, message) {
84
+ if !value {
85
+ throw "Assertion failed: " + message + " (expected true, got false)"
86
+ }
87
+ }
88
+
89
+ # Assertion: false
90
+ action assert_false(value, message) {
91
+ if value {
92
+ throw "Assertion failed: " + message + " (expected false, got true)"
93
+ }
94
+ }
95
+
96
+ # Assertion: null
97
+ action assert_null(value, message) {
98
+ if value != null {
99
+ throw "Assertion failed: " + message + " (expected null, got " + string(value) + ")"
100
+ }
101
+ }
102
+
103
+ # Assertion: not null
104
+ action assert_not_null(value, message) {
105
+ if value == null {
106
+ throw "Assertion failed: " + message + " (expected non-null value)"
107
+ }
108
+ }
109
+
110
+ # Assertion: type check
111
+ action assert_type(value, expected_type, message) {
112
+ let actual_type = type(value)
113
+ if actual_type != expected_type {
114
+ let error_msg = "Assertion failed: " + message
115
+ error_msg = error_msg + "\n Expected type: " + expected_type
116
+ error_msg = error_msg + "\n Got type: " + actual_type
117
+ throw error_msg
118
+ }
119
+ }
120
+
121
+ # Assertion: throws error
122
+ action assert_throws(func, expected_error, message) {
123
+ let did_throw = false
124
+ let error_msg = ""
125
+
126
+ try {
127
+ func()
128
+ } catch (e) {
129
+ did_throw = true
130
+ error_msg = string(e)
131
+ }
132
+
133
+ if !did_throw {
134
+ throw "Assertion failed: " + message + " (expected function to throw)"
135
+ }
136
+ }
137
+
138
+ # Assertion: greater than
139
+ action assert_gt(actual, expected, message) {
140
+ if actual <= expected {
141
+ let error_msg = "Assertion failed: " + message
142
+ error_msg = error_msg + "\n Expected > " + string(expected)
143
+ error_msg = error_msg + "\n Got: " + string(actual)
144
+ throw error_msg
145
+ }
146
+ }
147
+
148
+ # Assertion: greater than or equal
149
+ action assert_gte(actual, expected, message) {
150
+ if actual < expected {
151
+ let error_msg = "Assertion failed: " + message
152
+ error_msg = error_msg + "\n Expected >= " + string(expected)
153
+ error_msg = error_msg + "\n Got: " + string(actual)
154
+ throw error_msg
155
+ }
156
+ }
157
+
158
+ # Assertion: less than
159
+ action assert_lt(actual, expected, message) {
160
+ if actual >= expected {
161
+ let error_msg = "Assertion failed: " + message
162
+ error_msg = error_msg + "\n Expected < " + string(expected)
163
+ error_msg = error_msg + "\n Got: " + string(actual)
164
+ throw error_msg
165
+ }
166
+ }
167
+
168
+ # Assertion: less than or equal
169
+ action assert_lte(actual, expected, message) {
170
+ if actual > expected {
171
+ let error_msg = "Assertion failed: " + message
172
+ error_msg = error_msg + "\n Expected <= " + string(expected)
173
+ error_msg = error_msg + "\n Got: " + string(actual)
174
+ throw error_msg
175
+ }
176
+ }
177
+
178
+ # Print test summary
179
+ action print_test_summary() {
180
+ print("\n" + string_repeat("=", 50))
181
+ print("TEST SUMMARY")
182
+ print(string_repeat("=", 50))
183
+ print("Total tests: " + string(_total))
184
+ print("Passed: " + string(_passed) + " ✓")
185
+ print("Failed: " + string(_failed) + " ✗")
186
+
187
+ if _failed > 0 {
188
+ print("\nFailed Tests:")
189
+ let i = 0
190
+ while i < len(_failures) {
191
+ let failure = _failures[i]
192
+ print(" " + string(i + 1) + ". " + failure["suite"] + " > " + failure["test"])
193
+ print(" " + failure["error"])
194
+ i = i + 1
195
+ }
196
+ }
197
+
198
+ print(string_repeat("=", 50))
199
+
200
+ if _failed == 0 {
201
+ print("🎉 ALL TESTS PASSED!")
202
+ return 0
203
+ } else {
204
+ print("❌ SOME TESTS FAILED")
205
+ return 1
206
+ }
207
+ }
208
+