Commit Graph

1450 Commits

Author SHA1 Message Date
4591ac530b erlang: wire cid:from_bytes/1 + cid:to_string/1 against cid-from-bytes/cid-from-sx (Phase 8, +7 ffi tests) 2026-05-18 22:00:41 +00:00
250d0511c0 erlang: wire crypto:hash/2 against crypto-sha256/512/sha3-256 (Phase 8, +6 ffi tests) 2026-05-18 22:00:17 +00:00
77f17cc796 Merge loops/erlang into architecture: Phases 7-10 (hot reload, FFI BIFs, BIF registry, VM opcode extension + erlang_ext); fixes cyclic-env identity hang
# Conflicts:
#	hosts/ocaml/bin/run_tests.ml
#	plans/sx-vm-opcode-extension.md
2026-05-18 20:46:04 +00:00
857fae1331 erlang: fix er-env-derived-from? to use identical? not = (cyclic-env hang on structural-= evaluators) 2026-05-18 17:33:48 +00:00
a341041627 datalog: scoreboard bump (preserve before loops/erlang merge) 2026-05-18 14:48:00 +00:00
33725de03b erlang: Phase 9g — ring bench on integrated binary (no regression); scope Phase 10 2026-05-15 08:36:05 +00:00
5fd358a7a7 erlang: Phase 9i — SX dispatcher consults extension-opcode-id (+6 vm tests, 715/715) 2026-05-15 08:30:52 +00:00
64b7263c5f erlang: Phase 9g — log perf-bench blocker on 9a; conformance half clean at 709/709 2026-05-14 21:28:10 +00:00
e8a5c2e1ba erlang: Phase 9f — hot-BIF opcode table (+18 vm tests) 2026-05-14 21:26:51 +00:00
3efd735283 erlang: Phase 9e — OP_SPAWN / OP_SEND + VM-process registry (+16 vm tests) 2026-05-14 21:20:37 +00:00
10623da0b0 erlang: Phase 9d — OP_RECEIVE_SCAN stub (+10 vm tests) 2026-05-14 21:13:40 +00:00
528b24a1cd erlang: Phase 9c — OP_PERFORM / OP_HANDLE stubs (+9 vm tests) 2026-05-14 21:08:12 +00:00
25924d6212 erlang: Phase 9b — stub VM dispatcher + 3 pattern opcodes (+19 vm tests) 2026-05-14 20:52:26 +00:00
6636f9c170 erlang: extract ffi test suite (637/637, ffi 14/14) 2026-05-14 20:21:51 +00:00
a76d072d3f lua: re-apply arch's GUEST-lex prefix-rename refactor on top of merged loops/lua
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 32s
Lua now joins tcl/ocaml/kernel/common-lisp in consuming lib/guest/lex.sx via
prefix-rename. Removes 28 lines of duplicated character-class helpers
(lua-make-token, lua-digit?, lua-hex-digit?, lua-letter?, lua-ident-start?,
lua-ident-char?, lua-ws?) and replaces with the 8-line prefix-rename block.

The byte-table additions from loops/lua (__ascii-tok, __lua-127-255-tok,
lua-byte-to-char) are preserved at the top of tokenizer.sx — those provide
Lua's 8-bit-clean string semantics on top of the shared lex layer.

test.sh updated to preload lib/guest/lex.sx + lib/guest/prefix.sx before
lua sources, matching the load order arch's pre-merge test.sh used.

393/395 maintained. The 2 pre-existing failures are unrelated:
- math.random(n) primitive arity issue
- os.clock returns rational instead of number (SX division semantics)

Skipped from the planned follow-up: delay/force port. Arch's lua-force was
defined but never referenced anywhere — dead code, not worth porting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 20:21:18 +00:00
97c800a36b Merge lib/guest/test-runner into architecture: test-runner.sx + Kernel migration (POC) 2026-05-14 20:18:03 +00:00
0526f796f4 Merge lib/guest/quoting into architecture: quoting.sx + Kernel/Scheme migrations 2026-05-14 20:17:58 +00:00
e5d751c5fb Merge lib/guest/method-chain into architecture: class-chain.sx + Smalltalk/CLOS migrations 2026-05-14 20:17:50 +00:00
29fd70f17a erlang: file:read_file/write_file/delete BIFs (+10 eval tests, 633/633) 2026-05-14 20:14:31 +00:00
8525165594 Merge loops/minikanren into architecture: Phase 5 disequality + Phase 6 FD constraints + Phase 7 SLG tabling
Phase 5: =/= disequality with constraint store.
Phase 6: bounds-consistency for fd-plus/fd-times, send-more-money, Sudoku 4x4, N-queens FD.
Phase 7: SLG-style tabling with in-progress sentinel + fixed-point iteration (Fibonacci + Ackermann canaries green).
2026-05-14 20:11:18 +00:00
f62df8d64e Merge hs-f into architecture: JIT Phase 2/3 + native unwrap sweep + dict-eq fix
JIT Phase 2 (LRU eviction) + Phase 3 (manual reset), lib/jit.sx convenience layer,
21 host-* natives ABI-compatible with WASM kernel handles, dict-eq fix (structural
eq for plain dicts + Integer/Number in equal?), io-wait-event interceptor fix,
HS test runner unwrap shim for post-JIT-P1 value handles.

Conflicts resolved:
- tests/hs-run-filtered.js: combined arch's fake-timer block (for socket RPC tests)
  with hs-f's auto-unwrap shim
- shared/static/wasm/sx_browser.bc.js: took hs-f's regenerated bundle
2026-05-14 20:10:49 +00:00
3d092dd78e erlang: er-to-sx / er-of-sx term marshalling (+23 runtime tests) 2026-05-14 20:07:35 +00:00
2ee5e45515 erlang: migrate BIFs onto registry, delete cond dispatchers (600/600) 2026-05-14 19:41:30 +00:00
498d2533d8 erlang: Phase 8 BIF registry foundation (+18 runtime tests, 600/600) 2026-05-14 19:34:30 +00:00
925bbd0d42 erlang: Phase 7 capstone — full hot-reload ladder green (+5 eval tests) 2026-05-14 19:29:15 +00:00
b5e93df82e erlang: verify hot-reload call dispatch semantics (+6 eval tests) 2026-05-14 19:17:59 +00:00
582baf5bfd erlang: code:which/is_loaded/all_loaded introspection (+10 eval tests) 2026-05-14 19:08:34 +00:00
cd45ebcc7a erlang: code:purge/1 + code:soft_purge/1 (+10 eval tests) 2026-05-14 19:02:24 +00:00
89a6b30501 erlang: code:load_binary/3 hot-reload BIF (+8 eval tests) 2026-05-14 18:52:45 +00:00
0c389d4696 erlang: module-version slot (Phase 7 step 1, +13 runtime tests) 2026-05-14 17:35:02 +00:00
ca8e6f4da3 Merge loops/scheme into architecture: R7RS-small port, 296 tests across 11 phases 2026-05-14 16:12:50 +00:00
885943c5ae Merge lib/smalltalk/refl-env into architecture: Smalltalk frame as third consumer for lib/guest/reflective/env.sx 2026-05-14 15:32:16 +00:00
818e68a2f8 reflective: extract quoting.sx — Kernel + Scheme share quasiquote walker
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 31s
lib/guest/reflective/quoting.sx — quasiquote walker with adapter cfg.
Three forms:
- refl-quasi-walk-with CFG FORM ENV       (top-level)
- refl-quasi-walk-list-with CFG FORMS ENV (list walker, splice-aware)
- refl-quasi-list-concat XS YS            (pure-SX helper)

Adapter cfg keys:
- :unquote-name           — string keyword ("$unquote" or "unquote")
- :unquote-splicing-name  — string keyword
- :eval                   — fn (form env) → value

The shared algorithm is identical in Kernel and Scheme; the only
divergences are the keyword names (`$unquote` vs `unquote`) and
which host evaluator runs at unquote points (`kernel-eval` vs
`scheme-eval`). Both surface through the cfg.

Migrations:
- lib/kernel/runtime.sx: knl-quasi-walk reduces to a 3-line wrapper
  that builds knl-quasi-cfg and delegates. Removed knl-quasi-walk-
  list + knl-list-concat (~40 LoC) — now provided by the kit.
- lib/scheme/eval.sx: scm-quasi-walk reduces to a 3-line wrapper
  around scm-quasi-cfg. Removed scm-quasi-walk-list + scm-list-
  concat. scm-collect-exports (module impl) was a hidden consumer
  of scm-list-concat — rewired to refl-quasi-list-concat.

lib/scheme/test.sh — loads lib/guest/reflective/quoting.sx before
lib/scheme/parser.sx so the kit is available when eval.sx loads.

Both consumers' tests green:
- Kernel: 322 tests across 7 suites
- Scheme: 296 tests across 9 suites

**Second reflective-kit extraction landed.** The kit-extraction
playbook from env.sx and class-chain.sx — adapter-cfg pattern from
lib/guest/match.sx, same algorithm bridges different keyword names —
works again on a third structurally different problem (quasiquote
walking). The cumulative extraction story: env.sx → class-chain.sx
→ quoting.sx, three independent kits, all using the same pattern.

`evaluator.sx` (the other deferred candidate the Scheme port
unlocked) is NOT extracted — the genuinely shared content is too
thin (one helper for closure-capturing interaction-environment).
The eval-protocol is more about API surface than algorithm.
Documented as a non-extraction.
2026-05-14 07:54:15 +00:00
680cdf62aa scheme: Phase 11 — test.sh + scoreboard
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 33s
lib/scheme/test.sh — single-process test runner. Loads parser/eval/
runtime + lib/guest/reflective/env.sx once, then for each test
suite loads its file and calls its (*-tests-run!) function. Parses
the {:passed N :failed N ...} dict output and aggregates.

Usage:
  bash lib/scheme/test.sh        # summary
  bash lib/scheme/test.sh -v     # per-suite breakdown

Output: "ok 296/296 scheme-on-sx tests passed (9 suites)"

lib/scheme/scoreboard.md — per-suite passing counts, phase status,
deferred items, reflective-kit consumption ledger.

The scoreboard documents the chisel value of the Scheme port:
three reflective kits unlocked (env.sx — already extracted with
Scheme as third consumer; evaluator.sx + quoting.sx — second-
consumer-ready for extraction whenever a follow-up commit is run).

Loop status: 11 phases done (1, 2, 3, 3.5, 4, 5abc, 6ab, 7, 8, 9,
10, 11). Two deferred (6c hygiene, full call/cc-wind interaction).

296 tests, 1830 LoC of Scheme implementation. Zero substrate fixes
required across the loop.
2026-05-14 06:52:58 +00:00
7e795f95fc scheme: Phase 8 — define-library + import (minimal) + 7 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s
eval.sx adds module support:

  (define-library NAME EXPR...)
    Where EXPR is one of:
      (export NAME ...)
      (import LIB-NAME ...)
      (begin BODY ...)

  (import LIB-NAME ...)
    Looks up each library by key, copies its exported names
    into the current env.

Library values: {:scm-tag :library :name :exports :env}
Stored in scheme-library-registry keyed by joined library-name
(`(my math)` → `"my/math"`).

Library body runs in a FRESH standard env (each library is its
own namespace). Only :exports are visible after import; private
internal definitions stay in the library's env. Internal calls
between library functions use the library's env, so public-facing
exports can rely on private helpers.

Multiple imports work — each library is independent.

NOT yet supported: cond-expand, include, include-library-
declarations, renaming (`(only ...)`, `(except ...)`, `(prefix ...)`,
`(rename ...)`). Standard R7RS modules use these but the core
two-operation flow (define-library / import) covers most everyday
module use.

7 tests: single export, multi-export, private-not-visible,
internal-calls-private, two-libs-both-imported, unknown-lib-error,
single-symbol library name.

296 total Scheme tests (62+23+49+78+25+20+13+10+9+7).

Phases done: 1, 2, 3, 3.5, 4, 5abc, 6ab, 7, 8, 9, 10.
Deferred: 6c (hygiene/scope-set — research-grade), 11 (conformance).
2026-05-14 06:50:58 +00:00
f927fb6515 scheme: Phase 9 — define-record-type + 9 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 26s
eval.sx adds the define-record-type syntactic operator:

  (define-record-type NAME
    (CONSTRUCTOR ARG...)
    PREDICATE
    (FIELD ACCESSOR [MUTATOR])...)

Records are tagged dicts:
  {:scm-record TYPE-NAME :fields {FIELD VALUE ...}}

For each record type, the operator binds:
- Constructor: takes the listed ARGs, populates :fields, returns
  the record. Fields not in CONSTRUCTOR ARGs default to nil.
- Predicate: returns true iff its arg is a record of THIS type
  (tag-match via :scm-record).
- Accessor per field: extracts the field value; errors if not
  a record of the right type.
- Mutator per field (optional): sets the field via dict-set!;
  same type-check.

Distinct types are isolated via their tag — point? returns false
on a circle, even if both have the same shape.

9 tests cover: constructor + predicate + accessors, mutator,
distinct-types-via-tag, records as first-class values (in lists,
passed to map/filter), constructor arity errors.

289 total Scheme tests (62+23+49+78+25+20+13+10+9).
2026-05-14 06:49:24 +00:00
e200935698 scheme: Phase 10 — quasiquote runtime + 10 tests [shapes-reflective]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 26s
eval.sx adds quasiquote / unquote / unquote-splicing as syntactic
operators with the canonical R7RS walker:

- (quasiquote X) — top-level entry to scm-quasi-walk
- (unquote X) — at depth-0, evaluates X in env
- (unquote-splicing X) — inside a list, splices X's list value
- Reader-macro sugar: `X / ,X / ,@X work via Phase 1 parser

Algorithm identical to lib/kernel/runtime.sx's knl-quasi-walk:
- Walk template recursively
- Non-list: pass through
- ($unquote/unquote X) head form: eval X
- Inside a list, ($unquote-splicing/unquote-splicing X) head:
  eval X, splice list into surrounding context
- Otherwise: recurse on each element

No depth-tracking yet — nested quasiquotes are not properly
handled (matches Kernel's deferred state).

10 tests: plain atom/list, unquote substitution, splicing at
start/middle/end, nested list with unquote, unquote evaluates
expression, error on non-list splice, error on bare unquote.

**Second consumer for lib/guest/reflective/quoting.sx unlocked.**
Both Kernel and Scheme have structurally identical walkers; the
extraction would parameterise just the unquote/splicing keyword
names (Kernel uses $unquote / $unquote-splicing; Scheme uses
unquote / unquote-splicing — pure cfg, no algorithmic change).

280 total Scheme tests (62+23+49+78+25+20+13+10).

Three reflective-kit extractions unlocked in this Scheme port:
- env.sx        — Phase 2 (consumed directly, third overall consumer)
- evaluator.sx  — Phase 7 (second consumer via eval/interaction-env)
- quoting.sx    — Phase 10 (second consumer via scm-quasi-walk)

The kit extractions themselves remain follow-on commits when
desired. hygiene.sx still awaits a real second consumer
(Scheme phase 6c with scope-set algorithm).
2026-05-14 06:47:51 +00:00
342e1a2ccf scheme: Phase 7 — eval/interaction-environment/null-env + 13 tests [shapes-reflective]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 31s
runtime.sx binds R7RS reflective primitives:
- eval EXPR ENV
- interaction-environment        — returns env captured by closure
- null-environment VERSION       — fresh empty env (ignores version)
- scheme-report-environment N    — fresh full standard env
- environment? V

interaction-environment closes over the standard env being built;
each invocation of scheme-standard-env produces a distinct
interaction env that returns ITSELF when queried — so user-side
(define name expr) inside (eval ... (interaction-environment))
persists for subsequent (eval 'name ...) lookups.

13 tests cover:
- eval over quoted forms (literal + constructed via list)
- define-then-lookup through interaction-environment
- eqv? identity of interaction-environment across calls
- sandbox semantics: eval in null-environment errors on +
- scheme-report-environment is fresh and distinct from interaction

**Second consumer for lib/guest/reflective/evaluator.sx unlocked.**
Scheme's eval/interaction-environment/null-environment triple is
the same protocol Kernel exposes via eval-applicative /
get-current-environment / make-environment. Extraction now
satisfies the two-consumer rule — same playbook as env.sx and
class-chain.sx, awaits a follow-up commit to actually extract
the kit.

270 total Scheme tests (62 + 23 + 49 + 78 + 25 + 20 + 13).
2026-05-14 06:45:39 +00:00
9a7ca54902 scheme: Phase 6b — syntax-rules ellipsis (tail-rest) + 8 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 29s
scm-match-list now detects `<pat> ...` at the END of a pattern list
and binds <pat> (must be a symbol — single-variable rest) to the
remaining forms as a list. Nested-list patterns under ellipsis and
middle-of-list ellipses are NOT supported yet (rare in practice;
deferred).

scm-instantiate-list mirrors: when it encounters `<var> ... `
inside a list template, it splices the list-valued binding of <var>
in place. Internal list-append-all helper for the splice.

Removes the `(length pat) = (length form)` strict-equality check
in scm-match-step's list case — that gate blocked ellipsis. The
length-1-or-more relaxed check now lives in scm-match-list itself.

8 ellipsis tests cover:
- Empty rest (my-list)
- Non-empty rest (my-list 1 2 3 4)
- my-when with multi-body
- Variadic sum-em via fold-left
- Recursive my-and pattern (short-circuit AND defined as macro)

257 total Scheme tests (62 + 23 + 49 + 78 + 25 + 20).

Phase 6c (proper hygiene) is the next step and will be the
**second consumer for lib/guest/reflective/hygiene.sx** — the
deferred research-grade kit from the kernel-on-sx loop.
2026-05-14 06:43:20 +00:00
eb14a7576b scheme: Phase 6a — define-syntax + syntax-rules (no ellipsis) + 12 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 28s
eval.sx adds macro infrastructure:
- {:scm-tag :macro :literals (LIT...) :rules ((PAT TMPL)...) :env E}
- scheme-macro? predicate
- scm-match / scm-match-list — pattern matching against literals,
  pattern variables, and structural list shapes
- scm-instantiate — template substitution with bindings
- scm-expand-rules — try each rule in order
- (syntax-rules (LITS) (PAT TMPL)...) → macro value
- (define-syntax NAME FORM) → bind macro in env
- scheme-eval: when head looks up to a macro, expand and re-eval

Pattern matching supports:
- _ → match anything, no bind
- literal symbols from the LITERALS list → must equal-match
- other symbols → pattern variables, bind to matched form
- list patterns → must be same length, each element matches

NO ellipsis (`...`) support yet — that's Phase 6b. NO hygiene
yet (introduced symbols can shadow caller bindings) — that's
Phase 6c, which will be the second consumer for
lib/guest/reflective/hygiene.sx.

12 tests cover: simple substitution, multi-rule selection,
nested macro use, swap-idiom (state mutation via set!), control-
flow wrappers, literal-keyword pattern matching, macros inside
lambdas.

249 total Scheme tests now (62 + 23 + 49 + 78 + 25 + 12).
2026-05-14 06:41:11 +00:00
a90f56e3f3 scheme: Phase 5c — dynamic-wind (basic, no call/cc tracking) + 5 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 29s
(dynamic-wind BEFORE THUNK AFTER)
  - Calls BEFORE; runs THUNK; calls AFTER; returns THUNK's value.
  - If THUNK raises, AFTER still runs before the raise propagates.
  - Implementation: outcome-sentinel pattern (same trick as guard
    and with-exception-handler) — catch THUNK's raise inside a
    host guard, run AFTER unconditionally, then either return the
    value or re-raise outside the catch.

Not implemented: call/cc-escape tracking. R7RS specifies that
dynamic-wind's BEFORE and AFTER thunks should re-run when control
re-enters or exits the dynamic extent via continuations. That
requires explicit dynamic-extent stack tracking, deferred until
a consumer needs it (probably never needed for pure-eval Scheme
programs; matters for first-class-continuation-heavy code).

5 tests: success ordering, return value, after-on-raise,
raise propagation, nested wind.

237 total Scheme tests now (62 + 23 + 49 + 78 + 25).
2026-05-14 06:37:51 +00:00
55c376f559 scheme: Phase 5b — R7RS exceptions (raise/guard/with-exception-handler) + 12 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 31s
eval.sx adds the `guard` syntactic operator with R7RS-compliant
clause dispatch: var binds to raised value in a fresh child env;
clauses tried in order; `else` is catch-all; no match re-raises.

Implementation uses a "catch-once-then-handle-outside" pattern to
avoid the handler self-raise loop:
  outcome = host-guard {body}            ;; tag raise vs success
  if outcome was raise:
    try clauses → either result or sentinel
    if sentinel: re-raise OUTSIDE the host-guard scope

runtime.sx binds R7RS exception primitives:
- raise V
- error MSG IRRITANT...  → {:scm-error MSG :irritants LIST}
- error-object?, error-object-message, error-object-irritants
- with-exception-handler HANDLER THUNK
  (same outcome-sentinel pattern — handler's own raises propagate
  outward instead of re-entering)

12 tests cover: catch on raise, predicate dispatch, else catch-all,
no-error pass-through, first-clause-wins, re-raise-on-no-match,
error-object construction and accessors.

232 total Scheme tests now (62 + 23 + 49 + 78 + 20).
2026-05-14 06:36:50 +00:00
e3e5d3e888 scheme: Phase 5a — call/cc + 8 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 38s
scheme-standard-env binds:
- call/cc                            — primary
- call-with-current-continuation     — alias

Implementation wraps SX's host call/cc, presenting the captured
continuation k as a Scheme procedure that accepts a single value
(or a list of values for multi-arg invocation). Single-shot
escape semantics: when k is invoked, control jumps out of the
surrounding call/cc form. Multi-shot re-entry isn't safely
testable without delimited-continuation infrastructure (the
captured continuation re-enters indefinitely if invoked after
the call/cc returns) — deferred to a follow-up commit if needed.

Tests cover:
- No-escape return value
- Escape past arithmetic frames
- Detect/early-exit idiom over for-each
- Procedure? on the captured k

220 total Scheme tests now (62 + 23 + 49 + 78 + 8).
2026-05-14 06:27:03 +00:00
c560f3d70d hs: port loops/hs WebSocket runtime + test suite (replaces arch's underscore-prefixed API)
Adopts loops/hs's cleaner WebSocket API on top of arch's hyperscript:
- Runtime: replace 5 arch socket functions (hs-try-json-parse, hs-socket-normalise-url,
  hs-socket-bind-name!, hs-socket-resolve-rpc!, hs-socket-register!) with loops/hs's
  versions. Wrapper fields now use external-style names (url, timeout, pending, handler,
  json?, closedFlag, dispatchEvent) instead of internal-style underscores (_url,
  _timeout, _pending, _hsSetupSocket).
- Tests: replace arch's 257-line hs-upstream-socket suite (which probed _pending,
  _hsSetupSocket etc.) with loops/hs's 162-line suite that checks the new field names.
  Both suites cover the same 16 E36 behavioral cases.

Parser/compiler unchanged: both branches emit (hs-socket-register! name-path url
timeout handler json?) so the call signature is compatible with either runtime.
Arch's parse-socket-feat / emit-socket are preserved.

Local hs test.sh: 23/25 (the 2 failures are pre-existing hide/show cmd compiler
issues, not socket-related).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 21:16:09 +00:00
5e7d431f15 Merge loops/lua into architecture: features (coroutine, math, string.format, pattern char sets, byte-level chars). GUEST-lex refactor + delay/force to be re-applied in follow-up.
# Conflicts:
#	lib/lua/runtime.sx
#	lib/lua/test.sh
#	lib/lua/tokenizer.sx
2026-05-13 20:59:49 +00:00
88c7ce4068 Merge loops/apl into architecture: Phase 10 runtime gaps (⍸ ∪ ∩ ⊥ ⊤ ⊆ ⍎), life.apl + quicksort.apl run as-written 2026-05-13 20:38:17 +00:00
c19bcc51cb Merge loops/forth into architecture: Hayes conformance 99% (632/638), JIT cooperation, full Forth-2012 core 2026-05-13 20:37:26 +00:00
129f11fdbc Merge lib/tcl/uplevel into architecture: kernel + reflective env extraction (Phase 1-7 kernel, 322+427 tests) 2026-05-13 20:34:07 +00:00
cf933f0ece scheme: Phase 4 standard env + set! bugfix + 78 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 25s
lib/scheme/runtime.sx — full R7RS-base surface:

- Arithmetic: variadic +/-/*//, abs, min, max, modulo, quotient,
  remainder. Predicates zero?/positive?/negative?.
- Comparison: chained =/</>/<=/>=.
- Type predicates: number?/boolean?/symbol?/string?/char?/vector?/
  null?/pair?/procedure?/not.
- List: cons/car/cdr/list/length/reverse/append.
- Higher-order: map/filter/fold-left/fold-right/for-each/apply.
  These re-enter scheme-apply to invoke user-supplied procs.
- String: string-length/string=?/string-append/substring.
- Char: char=?.
- Vector: vector/vector-length/vector-ref/vector->list/list->vector/
  make-vector.
- Equality: eqv?/equal?/eq? (all = under the hood for now).

Built via small adapters: scm-unary, scm-binary, scm-fold (variadic
left-fold with identity + one-arity special), scm-chain (n-ary
chained comparison).

**Bugfix in eval.sx set! handler.** The :else branch had two
expressions `(dict-set! ...) val` — SX cond branches don't run
multiple expressions, they return nil silently (or evaluate only
the first, depending on shape). Wrapped in (begin ...) to force
sequential execution. This fix also unblocks 4 set!-dependent
tests in lib/scheme/tests/syntax.sx that were silently raising
during load (and thus not counted) — syntax test count jumps
from 45 → 49.

Classic programs verified:
- factorial 10 → 3628800
- fib 10 → 55
- recursive list reverse → working
- sum of squares via fold-left + map → 55

212 total Scheme tests: parse 62 + eval 23 + syntax 49 + runtime 78.
All green.

The env-as-value section in runtime tests demonstrates
scheme-standard-env IS a refl-env? — kit primitives operate on it
directly, confirming the third-consumer adoption with zero adapter.
2026-05-13 20:29:37 +00:00
0fccd1b353 scheme: Phase 3.5 — let/let*/cond/when/unless/and/or + 21 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s
Adds the rest of the standard syntactic operators, all built on the
existing eval/closure infrastructure from Phase 3:

- let — parallel bindings in fresh child env; values evaluated in
  outer env (RHS sees pre-let bindings only). Multi-body via
  scheme-eval-body.
- let* — sequential bindings, each in a nested child env; later
  bindings see earlier ones.
- cond — clauses walked in order; first truthy test wins. `else`
  symbol is the catch-all. Test-only clauses (no body) return the
  test value. Scheme truthiness: only #f is false.
- when / unless — single-test conditional execution, multi-body
  body via scheme-eval-body.
- and / or — short-circuit boolean. Empty `(and)` = true,
  `(or)` = false. Both return the actual value at the point
  of short-circuit (not coerced to bool), matching R7RS.

130 total Scheme tests (62 parse + 23 eval + 45 syntax). The
Scheme port is now self-hosting enough to write any non-stdlib
program — factorial, list operations via primitives, closures
with mutable state, all working.

Next phase: standard env (runtime.sx) with variadic +/-, list
ops as Scheme-visible applicatives.
2026-05-13 20:04:44 +00:00