Move stdlib out of spec — clean spec/library boundary

spec/ now contains only the language definition (5 files):
  evaluator.sx, parser.sx, primitives.sx, render.sx, special-forms.sx

lib/ contains code written IN the language (8 files):
  stdlib.sx, types.sx, freeze.sx, content.sx,
  bytecode.sx, compiler.sx, vm.sx, callcc.sx

Test files follow source: spec/tests/ for core language tests,
lib/tests/ for library tests (continuations, freeze, types, vm).

Updated all consumers:
- JS/Python/OCaml bootstrappers: added lib/ to source search paths
- OCaml bridge: spec_dir for parser/render, lib_dir for compiler/freeze
- JS test runner: scans spec/tests/ (always) + lib/tests/ (--full)
- OCaml test runner: scans spec/tests/, lib tests via explicit request
- Docker dev mounts: added ./lib:/app/lib:ro

Tests: 1041 JS standard, 1322 JS full, 1101 OCaml — all pass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-24 23:18:30 +00:00
parent 50871780a3
commit f3f70cc00b
26 changed files with 109 additions and 64 deletions

View File

@@ -14,7 +14,7 @@
// =========================================================================
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
var SX_VERSION = "2026-03-24T22:31:01Z";
var SX_VERSION = "2026-03-24T22:56:21Z";
function isNil(x) { return x === NIL || x === null || x === undefined; }
function isSxTruthy(x) { return x !== false && !isNil(x); }

View File

@@ -367,17 +367,24 @@ class OcamlBridge:
# Collect files to load
all_files: list[str] = []
# Spec files needed by aser + bytecode compiler
# Core spec files
spec_dir = os.path.join(os.path.dirname(__file__), "../../spec")
for spec_file in ["parser.sx", "render.sx", "bytecode.sx", "compiler.sx"]:
for spec_file in ["parser.sx", "render.sx"]:
path = os.path.normpath(os.path.join(spec_dir, spec_file))
if os.path.isfile(path):
all_files.append(path)
# Library files (compiler, vm, freeze — written in the language)
lib_dir = os.path.join(os.path.dirname(__file__), "../../lib")
for lib_file in ["bytecode.sx", "compiler.sx"]:
path = os.path.normpath(os.path.join(lib_dir, lib_file))
if os.path.isfile(path):
all_files.append(path)
# All directories loaded into the Python env
all_dirs = list(set(_watched_dirs) | _dirs_from_cache)
# Isomorphic libraries: signals, rendering, freeze scopes, web forms
# Isomorphic libraries: signals, rendering, web forms
web_dir = os.path.join(os.path.dirname(__file__), "../../web")
if os.path.isdir(web_dir):
for web_file in ["signals.sx", "adapter-html.sx", "adapter-sx.sx",
@@ -385,9 +392,9 @@ class OcamlBridge:
path = os.path.normpath(os.path.join(web_dir, web_file))
if os.path.isfile(path):
all_files.append(path)
# Spec library files (loaded after adapters)
for spec_lib in ["freeze.sx"]:
path = os.path.normpath(os.path.join(spec_dir, spec_lib))
# Library files loaded after adapters (depend on scope primitives)
for lib_file in ["freeze.sx"]:
path = os.path.normpath(os.path.join(lib_dir, lib_file))
if os.path.isfile(path):
all_files.append(path)