- sx_types.ml: CallccContinuation gains winders depth int field
- sx_runtime.ml: make_callcc_continuation(captured, winders_len),
callcc_continuation_winders_len accessor; get_val maps after-thunk,
winders-len, body-result to cf_f/cf_extra/cf_name
- sx_ref.ml: step_limit/step_count restored; make_wind_after_frame and
make_wind_return_frame now store their args in the CekFrame fields
- transpiler.sx: after-thunk→cf_f, winders-len→cf_extra,
body-result→cf_name for future bootstrap runs
- 8 new dynamic-wind tests pass (OCaml), 235/235 no regressions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
empty .class compiled (empty-target (query ".class")) to
(hs-empty-target! (hs-query-first ".class")) via hs-to-sx — only
emptying the first match. Fix: detect (query ...) target in the
empty-target compiler case and emit (for-each (fn (_el)
(hs-empty-target! _el)) (hs-query-all sel)) instead, mirroring the
add-class pattern. Suite hs-upstream-empty: 12/13 → 13/13.
Smoke 0-195: 175/195 unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
${}{"val"} pattern in add {prop: ${}{"val"}} uses two consecutive brace
groups: empty ${} followed by {"val"} for the actual expression. The prior
fix called parse-expr when already at the brace-close of the empty group,
returning nil. New fix: detect empty ${} (brace-open then brace-close),
skip the close, then read the actual value from the following {…} block.
Also handles non-empty ${expr} directly as before.
Suite hs-upstream-add: 17/19 → 18/19. Smoke 0-195: 174/195 → 175/195.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
call X then put it into Y was emitting (hs-win-call ...) without
wrapping in emit-set, so it remained nil. Wrap call result in
emit-set(the-result) so it/the-result are updated. Fixes +1 test.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Matches OCaml run_tests.ml which binds these as NativeFn returning
"foo"/"42" directly. hs-win-call looks up window globals; registering
them synchronously lets put/set tests exercise function-call + put
without requiring real Promise awaiting. Fixes "waits on promises" +1.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents click events from bubbling into ancestor elements that also
have hs handlers (e.g. parent re-inserting HTML after child click).
Fixes put-reprocessing tests 1147/1149/1150 (+3 tests).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tell now rebinds beingTold/you/yourself without overwriting me.
Parser implicit targets use beingTold; handler wrapper seeds beingTold=me.
Fixes: attributes refer to the thing being told, does not overwrite me,
your symbol represents the thing being told.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add integer?/float?/exact?/inexact? predicates (Number.isInteger check).
Add truncate/remainder/modulo/random-int/exact->inexact/inexact->exact/parse-number.
inexact->exact uses Math.round (rounds to nearest, matching OCaml).
Fix sx_server.ml epoch/blob/io-response protocol to accept Integer as
well as Number — parser now produces Integer for whole-number literals.
JS: 60 new passing tests (1880→1940). OCaml: 4874/394 baseline unchanged.
Note: 6 tests fail in JS due to platform limitation (JS cannot distinguish
float 2.0 from integer 2).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- _NO_STEP_LIMIT set exempts hypertrace tests from the 200k step cap
- globalThis.__hs_deadline exposed so cek_step_loop wall-clock check
(every 10k steps) can terminate runaway async loops without needing
to go through host-call or _driveAsync
- meta + _hs-on-caller added to hs-runtime.sx (both lib and bundled):
on-event handlers now set meta.caller to an object with
meta.feature.type = "onFeature" before calling the handler
Tests 196 (async hypertrace), 198 (meta.caller), 199, 200 now pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix PRIMITIVES["index-of"] for arrays: return NIL when not found (matching
OCaml semantics) so bind-lambda-params correctly detects absent &rest params.
Previously String(array).indexOf() returned -1, which passed number? check
and mis-fired the &rest branch, leaving non-&rest params unbound.
- Declare var _lastErrorKont_ and var hostError in IIFE scope (strict mode fix)
- Add PRIMITIVES["host-error"], ["try-catch"], ["without-io-hook"]
- Add env["test-allowed?"] stub in run_tests.js
- Add spec/tests/test-vectors.sx: 42 tests for all vector primitives
- Rebuild sx-browser.js: 1847 standard / 2362 full tests pass (up from 5)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All 10 vector primitives now have :as type annotations on every parameter,
:returns types, and :doc strings. make-vector gains optional fill annotation;
vector uses :rest for its variadic args; vector-ref/set! document bounds error.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
vector-ref and vector-set! now raise Eval_error on out-of-bounds index instead of
an OCaml array exception. vector-copy accepts optional start and end parameters for
slicing (R7RS §6.8). spec/primitives.sx doc updated to reflect slice params.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add hs-tokenize-template: scans " as single STRING token, ${ ... }
as dollar+brace+inner-tokens (inner tokenized with hs-tokenize), and
} as brace-close. Update hs-tokens-of to call hs-tokenize-template
when :template keyword arg is passed. Unlocks tests 1 and 15.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add \r \b \f \v and \xNN escape handling to read-string. Use
char-from-code for non-SX-literal chars. Throw "Unterminated string"
on EOF inside a string literal. Throw "Invalid hexadecimal escape: \x"
on bad \xNN. Add hs-hex-digit? and hs-hex-val helpers. Unlocks
tests 2, 6, 13, 14 once generator lands.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>