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>
Add hs-eof-sentinel, hs-op-type, hs-raw->api-token, hs-tokens-of,
hs-stream-token, hs-stream-consume, hs-stream-has-more, and the
three token accessors (hs-token-type, hs-token-value, hs-token-op?).
No test delta yet — API-only, generator comes in step 6.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Threads declaration kind ("var"/"let"/"const") through js-transpile-var →
js-vardecl-forms so the transpiler knows which kind is being declared.
Infrastructure for full TDZ enforcement: js-tdz-check can wrap let/const
reads to raise TypeError before initialization.
Updates plans/js-on-sx.md: ticks [x] for TDZ, marks regex blocker RESOLVED,
adds progress log entry for 2026-04-25.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
`1 in [1, 2, 3]` must return (list 1) not true. Root cause: in? compiled
to hs-contains? which returns boolean for scalar items. Fix: new hs-in?
returns filtered list; new in-bool? operator for is/am-in comparison
contexts so those still return boolean. Parser generates in-bool? for
`X is in Y` / `X am in Y`; plain `in` keeps in? → list return.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>