Self-hosted z3.sx translator, prove.sx prover, parser unicode, auto reader macros
- z3.sx: SX-to-SMT-LIB translator written in SX (359 lines), replaces Python translation logic - prove.sx: SMT-LIB satisfiability checker in SX — proves all 91 primitives sat by construction - Parser: support unicode characters (em-dash, accented letters) in symbols - Auto-resolve reader macros: #name finds name-translate in component env, no Python registration - Platform primitives: type-of, symbol-name, keyword-name, sx-parse registered in primitives.py - Cond heuristic: predicates ending in ? recognized as Clojure-style tests - Library loading: z3.sx loaded at startup with reload callbacks for hot-reload ordering - reader_z3.py: rewritten as thin shell delegating to z3.sx - Split monolithic .sx files: essays (22), plans (13), reactive-islands (6) into separate files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -98,7 +98,7 @@ def load_sx_dir(directory: str) -> None:
|
||||
Skips boundary.sx — those are parsed separately by the boundary validator.
|
||||
"""
|
||||
for filepath in sorted(
|
||||
glob.glob(os.path.join(directory, "*.sx"))
|
||||
glob.glob(os.path.join(directory, "**", "*.sx"), recursive=True)
|
||||
):
|
||||
if os.path.basename(filepath) == "boundary.sx":
|
||||
continue
|
||||
@@ -112,6 +112,12 @@ def load_sx_dir(directory: str) -> None:
|
||||
|
||||
_watched_dirs: list[str] = []
|
||||
_file_mtimes: dict[str, float] = {}
|
||||
_reload_callbacks: list[Any] = []
|
||||
|
||||
|
||||
def register_reload_callback(fn: Any) -> None:
|
||||
"""Register a function to call after hot-reload clears and reloads components."""
|
||||
_reload_callbacks.append(fn)
|
||||
|
||||
|
||||
def watch_sx_dir(directory: str) -> None:
|
||||
@@ -119,7 +125,7 @@ def watch_sx_dir(directory: str) -> None:
|
||||
_watched_dirs.append(directory)
|
||||
# Seed mtimes
|
||||
for fp in sorted(
|
||||
glob.glob(os.path.join(directory, "*.sx"))
|
||||
glob.glob(os.path.join(directory, "**", "*.sx"), recursive=True)
|
||||
):
|
||||
_file_mtimes[fp] = os.path.getmtime(fp)
|
||||
|
||||
@@ -129,7 +135,7 @@ def reload_if_changed() -> None:
|
||||
changed = False
|
||||
for directory in _watched_dirs:
|
||||
for fp in sorted(
|
||||
glob.glob(os.path.join(directory, "*.sx"))
|
||||
glob.glob(os.path.join(directory, "**", "*.sx"), recursive=True)
|
||||
):
|
||||
mtime = os.path.getmtime(fp)
|
||||
if fp not in _file_mtimes or _file_mtimes[fp] != mtime:
|
||||
@@ -137,6 +143,9 @@ def reload_if_changed() -> None:
|
||||
changed = True
|
||||
if changed:
|
||||
_COMPONENT_ENV.clear()
|
||||
# Reload SX libraries first (e.g. z3.sx) so reader macros resolve
|
||||
for cb in _reload_callbacks:
|
||||
cb()
|
||||
for directory in _watched_dirs:
|
||||
load_sx_dir(directory)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user