Commit Graph

41 Commits

Author SHA1 Message Date
2d475f95d1 js-on-sx: constructors carry __proto__ = Function.prototype
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 42s
Object/Array/Number/String/Boolean had no __proto__, so
Function.prototype mutations were invisible to them. Added a
post-init (begin (dict-set! ...)) at the end of runtime.sx
that wires each constructor to js-function-global.prototype.
Combined with the recent Object.prototype fallback, the chain
now terminates correctly: ctor → Function.prototype → Object.prototype.
built-ins/Number: 41/50 → 42/50, built-ins/String: 75/99 → 78/99,
built-ins/Array: 12/45 → 13/45. conformance.sh: 148/148.
2026-05-07 20:14:15 +00:00
11612a511b js-on-sx: js-neg preserves IEEE-754 negative zero
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 45s
JS -0 was returning rational integer 0; the (- 0 x) form loses the
sign-of-zero. Switched js-neg to (* -1 (exact->inexact (js-to-number a))),
which produces a float and preserves -0.0. Now 1/(-0) === -Infinity
and Math.asinh(-0) preserves the sign as required by the spec.
built-ins/Math: 41/45 → 42/45. conformance.sh: 148/148.
2026-05-07 19:11:30 +00:00
5f97e78d5f js-on-sx: js-div coerces divisor to inexact
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 55s
(js-div 1 0) with rational integer literals throws "rational: division
by zero" instead of producing Infinity. Wrapped the divisor in
(exact->inexact ...) so integer-by-zero now returns inf/-inf/nan
matching JS semantics. Hit by the harness's _isSameValue +0/-0 check
which calls (js-div 1 a) on JS literal arguments.
built-ins/Number: 37/50 → 41/50. built-ins/String: 77/99.
conformance.sh: 148/148.
2026-05-07 18:35:29 +00:00
f4b0ebf353 js-on-sx: js-to-string throws TypeError on non-primitive toString/valueOf
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 52s
Per ECMA, String(obj) should throw TypeError when both
obj.toString() and obj.valueOf() return objects. Was returning
"[object Object]" instead, silently swallowing the spec violation.
Replaced the inner fallback with (raise (js-new-call TypeError ...)).
Preserves the outer "[object Object]" for the case where there's
no toString lambda. Fixes S8.12.8_A1.
built-ins/String: 75/99 → 77/99 (canonical, best run).
conformance.sh: 148/148.
2026-05-07 17:44:30 +00:00
95fb5ef8ef js-on-sx: TypeError-on-not-callable uses type-of, not (str fn-val)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 56s
Formatting wrapper dicts with (str fn-val) recursively walks the
proto chain through SX inspect — for String/Number wrappers whose
prototype contains lambdas this hangs. Switched the message to
(type-of fn-val), e.g. "dict is not a function". Less specific
but always terminates.
built-ins/String: 73/99 → 75/99 (canonical). conformance.sh:
148/148.
2026-05-07 16:54:06 +00:00
843c3a7e5e js-on-sx: raise JS TypeError for non-callable callee, undefined()
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 59s
Calling a non-callable raised an OCaml-level Eval_error "Not callable"
that JS try/catch couldn't intercept. Added a (js-function? callable)
precheck in js-apply-fn that raises a TypeError instance via
(js-new-call TypeError (list msg)) so e instanceof TypeError is
true. Same swap for the undefined() branch in js-call-plain (was
raising a bare string). built-ins/String: 71/99 → 73/99 (canonical),
74/99 → 75/99 (isolated). conformance.sh: 148/148.
2026-05-07 15:58:16 +00:00
cf0ba8a02a js-on-sx: js-dict-get-walk falls back to Object.prototype
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 54s
Object literals didn't carry a __proto__ link, so ({}).toString()
couldn't reach Object.prototype.toString. Added a cond clause: if
the object has no __proto__ AND is not Object.prototype itself,
walk into Object.prototype. Now ({}).toString() works, override
of Object.prototype.toString propagates, and ({a:1}).hasOwnProperty
('a') returns true. built-ins/String: 69/99 → 71/99 (canonical),
71/99 → 74/99 (isolated). conformance.sh: 148/148.
2026-05-07 15:08:55 +00:00
4e554113a9 js-on-sx: js-new-call accepts list-typed constructor returns
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m1s
new Array(1,2,3) was returning an empty wrapper object because
js-new-call only honoured a non-undefined return when
(type-of ret) === "dict"; SX lists (representing JS arrays) were
silently discarded. Widened the check to accept "list" too.
Fixes new Array(1,2,3).length, String(new Array(1,2,3)), and any
constructor whose body returns a list. built-ins/String:
67/99 → 69/99 (canonical). conformance.sh: 148/148.
2026-05-07 14:24:52 +00:00
c81e3f3705 js-on-sx: js-num-from-string uses pow (float) for exponent
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m4s
js-pow-int 10 20 overflows int64 (10^20 > 2^63), so numeric literals
like 1e20 and 100000000000000000000 were parsing as
-1457092405402533888. The pow primitive uses float-domain
exponentiation and produces 1e+20 correctly. Single call swap in
js-num-from-string. built-ins/String (with --restart-every 1):
67/99 → 70/99. conformance.sh: 148/148.
2026-05-07 13:42:32 +00:00
66f13c95d5 js-on-sx: js-to-string emits comma-joined elements for SX lists
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m3s
String([1,2,3]) was returning "(1 2 3)" (the SX (str v) fallback in
js-to-string fell through for SX lists). Replaced the fallback with
a list-typed branch that delegates to (js-list-join v ","). Fixes
String(arr), "" + arr, and any implicit array-to-string coercion.
built-ins/String: 65/99 → 67/99. conformance.sh: 148/148.
2026-05-07 12:45:06 +00:00
081f934cad js-on-sx: lexer handles \uXXXX and \xXX string escapes
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m3s
read-string fell through to the literal-char branch for \u and \x,
silently stripping the backslash ("A".length returned 5 instead
of 1). Added js-hex-value helper and two cond clauses that read the
hex digits via js-peek + js-hex-digit?, compute the code point, and
emit it via char-from-code. Invalid escapes fall through to the
literal-char behaviour. built-ins/String (with --restart-every 1):
65/99 → 68/99. conformance.sh: 148/148.
2026-05-07 12:02:30 +00:00
89f1c0ccbe js-on-sx: bump test262 runner per-test timeout 5s→15s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 59s
With 4 parallel workers contending, the 5s default timed out 85/99
built-ins/String tests. Bumping to 15s yields 65/99 (65.7%) with
real failure modes now visible instead of "85x Timeout".
2026-05-07 07:57:23 +00:00
066ddcd6e1 js-on-sx: fix rational-zero-division in core constants + charCodeAt
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 51s
(/ 0 0), (/ 1 0), (/ -1 0) throw "rational: division by zero" with
the OCaml binary's integer rational arithmetic. Replace with nan/inf
literals in js-nan-value, js-infinity-value, js-number-is-finite,
js-math-min, js-math-max. js-max-value-approx looped forever (rationals
never reach float infinity); replace with literal 1.7976931348623157e+308.
charCodeAt and string .length called missing unicode-len /
unicode-char-code-at primitives — switch to (len s) and
(char-code (char-at s idx)). conformance.sh: 0→148/148.
2026-05-06 21:02:58 +00:00
97180b4aa3 js-on-sx: wrapper constructor-detection, Array.prototype.toString, >>> operator
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 11s
Number.__callable__ and String.__callable__ now check this.__proto__ ===
Number/String.prototype before writing wrapper slots, preventing false-positive
mutation when called as plain function. js-to-number extended to unwrap
wrapper dicts and call valueOf/toString for plain objects. Array.prototype.toString
replaced with a direct js-list-join implementation (eliminates infinite recursion
via js-invoke-method on dict-based arrays). >>> added to transpiler + runtime.

String test262 subset: 62→66/100. 529/530 unit, 147/148 slice.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 19:22:53 +00:00
ea63b6d9bb plans: log precision number-to-string iteration
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-25 14:42:44 +00:00
79f3e1ada2 plans: log String wrapper + number-to-string sci notation iteration
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-25 14:27:25 +00:00
80c21cbabb js-on-sx: String fixes — fromCodePoint, multi-arg indexOf/split/lastIndexOf, matchAll, constructor, js-to-string dict
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
- String.fromCodePoint added (BMP + surrogate pairs)
- indexOf/lastIndexOf/split now accept optional second argument (fromIndex / limit)
- matchAll stub added to js-string-method and String.prototype
- String property else-branch now falls back to String.prototype (fixes 'a'.constructor === String)
- js-to-string for dict returns [object Object] instead of recursing into circular String.prototype.constructor structure
- js-list-take helper added for split limit

Scoreboard: String 42→43, timeouts 32→13, total 162→202/300 (54%→67.3%). 529/530 unit, 148/148 slice.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 13:41:58 +00:00
70f91ef3d8 plans: log Math methods iteration
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-25 12:47:27 +00:00
0f9d361a92 plans: tick var hoisting, add progress log entry
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-25 12:19:07 +00:00
f16e1b69c0 js-on-sx: tick ASI checkbox, append progress log entry
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 11:53:45 +00:00
6a4269d327 plan: Blocker — SX number promotion narrows floats to ints 2026-04-24 12:21:22 +00:00
ec0be48a00 plan: progress log session 4 — 147/300 (49%), harness cache + 6 features 2026-04-24 12:20:25 +00:00
dc97c17304 js-on-sx: Blockers — Math trig primitives + evaluator CPU bound
Two shared-file entries based on scoreboard patterns:

- Math trig/transcendental primitives missing. 34× "TypeError: not a
  function" across Math category — sin/cos/tan/asin/acos/atan/atan2,
  sinh/cosh/tanh/asinh/acosh/atanh, log/log2/log10/log1p/expm1,
  clz32/imul/fround, variadic hypot/max/min. All need OCaml/JS platform
  primitives; can't polyfill from pure SX and keep precision. Once
  present in the runtime, `js-global.Math` gets one extension and all 34
  failures flip together.

- Evaluator CPU bound at ~1 test/s on 2-core box. Runner already
  auto-disables parallel workers on ≤2 cores. Optimization surface for
  the shared evaluator: lexical addresses (vs name walk), inline caches
  on js-get-prop (vs __proto__ walk), force-JIT transpiled JS bodies
  (vs lazy), OCaml 5 domains (vs separate processes).

Progress-log entry for P0 harness cache added alongside.
2026-04-24 11:21:58 +00:00
eb587bb3d0 plan: progress log — session 3 continued, 100/cat scoreboard 114/300 2026-04-24 09:57:17 +00:00
c22f553146 plan: update progress log with session 3 summary, Math 39.6% wide 36.4% 2026-04-24 09:08:15 +00:00
fe6cadd268 plan: update progress log with final Math scoreboard 2026-04-23 23:42:08 +00:00
64e53518ae plan: js-on-sx progress log update 2026-04-23 23:35:01 +00:00
1459f7a637 js-on-sx: callable Number/String/Boolean/Array + Array.sort
Builtin constructors now have :__callable__ slot. js-call-plain
and js-function? detect dicts with __callable__ and dispatch
through it. Number('42')===42, String(true)==='true', Boolean(0)
===false, Array(3) builds length-3 list.

Array.prototype.sort(comparator?): bubble sort via js-list-sort-
outer!/-inner!. Default lex order, custom comparator supported.

Wide scoreboard committed: 259/5354 (4.8%) from earlier runtime.

438/440 unit (+11), 148/148 slice unchanged.
2026-04-23 22:53:13 +00:00
15c310cdc1 js-on-sx: object + array destructuring
Parser: jp-parse-vardecl handles {a, b} obj pattern and [a, , c]
arr pattern (with hole support) in addition to plain idents.
Emits (js-vardecl-obj names rhs) and (js-vardecl-arr names rhs).

Transpile: js-vardecl-forms dispatches on tag. Destructures emit
(define __destruct__ rhs) then (define name (js-get-prop __destruct__
key-or-index)) for each pattern element. Array holes (nil) are skipped.

418/420 unit (+4), 148/148 slice unchanged.
2026-04-23 22:32:24 +00:00
4800246b23 js-on-sx: spread ... in array literals and call args
Parser: jp-array-loop and jp-call-args-loop detect punct "..."
and emit (js-spread inner).

Transpile: when any element is spread, build array/args via
js-array-spread-build with (list "js-value" v) and (list
"js-spread" xs) tags.

Runtime: js-array-spread-build walks items, appending values or
splicing spreads via js-iterable-to-list (handles list/string/dict).

Works in arrays, call args, variadic fns (Math.max(...arr)),
and string spread ([...'abc']).

414/416 unit (+5), 148/148 slice unchanged.
2026-04-23 22:10:15 +00:00
f113b45d48 js-on-sx: for..of / for..in + more Array methods
Parser: jp-parse-for-stmt does 2-token lookahead for (var? ident
(of|in) expr), emits (js-for-of-in kind ident iter body) else
classic (js-for init cond step body).

Transpile: wraps body in (call/cc (__break__) (let items
(for-each (fn (ident) (call/cc (__continue__) body)) items))).

Runtime: js-iterable-to-list normalizes list/string/dict for of
iteration; js-string-to-list expands string to char list.

399/401 unit (+8), 148/148 slice unchanged.
2026-04-23 21:41:52 +00:00
ebaec1659e js-on-sx: JSON.stringify + JSON.parse
Recursive-descent parser/serializer in SX.

stringify: type-of dispatch for primitives, lists, dicts. Strings
escape \\ \" \n \r \t.

parse: {:s src :i idx} state dict threaded through helpers.
Handles primitives, strings (with escapes), numbers, arrays,
objects.

Wired into js-global.

391/393 unit (+10), 148/148 slice unchanged.
2026-04-23 21:22:32 +00:00
6f0b4fb476 js-on-sx: String.fromCharCode + parseInt + parseFloat
String global with fromCharCode (variadic). parseInt truncates via
js-math-trunc; parseFloat delegates to js-to-number. Wired into
js-global.

381/383 unit (+5), 148/148 slice unchanged.
2026-04-23 21:16:41 +00:00
2bd3a6b2ba js-on-sx: Array.prototype includes/find/some/every/reverse + Object fallbacks
Array: includes, find, findIndex, some, every, reverse via
tail-recursive helpers.

Object: hasOwnProperty, isPrototypeOf, propertyIsEnumerable,
toString, valueOf, toLocaleString fallback in js-invoke-method
when js-get-prop returns undefined. Lets o.hasOwnProperty('k')
work on plain dicts.

376/378 unit (+13), 148/148 slice unchanged.
2026-04-23 21:11:12 +00:00
9d3e54029a js-on-sx: switch/case/default/break
Parser: jp-parse-switch-stmt + jp-parse-switch-cases + jp-parse-switch-body.
AST: (js-switch discr (("case" val body) ("default" nil body) ...)).

Transpile: wraps body in (call/cc (fn (__break__) ...)). Each case
clause becomes (when (or __matched__ (js-strict-eq discr val))
(set! __matched__ true) body). Fall-through works naturally via
__matched__. Default appended as (when (not __matched__) body).

363/365 unit (+6), 148/148 slice unchanged.
2026-04-23 21:04:22 +00:00
275d2ecbae js-on-sx: String.prototype extensions + Object/Array builtins
Strings: includes, startsWith, endsWith, trim, trimStart, trimEnd,
repeat, padStart, padEnd, toString, valueOf.

Object: keys, values, entries, assign, freeze (no-op).
Array: isArray, of.

All wired into js-global. 17 new unit tests.

357/359 unit (+17), 148/148 slice unchanged.
2026-04-23 20:58:24 +00:00
6c4001a299 js-on-sx: postfix + prefix ++/--
Parser: jp-parse-postfix emits (js-postfix op target) on trailing
++/--; jp-parse-primary emits (js-prefix op target) before the
unary -/+/!/~ branch.

Transpile: js-transpile-prefix → (set! name (+ (js-to-number name)
±1)) for idents, (js-set-prop obj key ...) for members/indices.
js-transpile-postfix caches old value in a let binding, updates,
returns the saved value.

340/342 unit (+11), 148/148 slice unchanged.
2026-04-23 20:50:10 +00:00
608a5088a4 js-on-sx: expanded Math + Number globals
Math gains sqrt/pow/trunc/sign/cbrt/hypot plus LN2/LN10/LOG2E/
LOG10E/SQRT2/SQRT1_2 constants and full-precision PI/E.

Number global: isFinite/isNaN/isInteger/isSafeInteger plus
MAX_VALUE/MIN_VALUE/MAX_SAFE_INTEGER/MIN_SAFE_INTEGER/EPSILON/
POSITIVE_INFINITY/NEGATIVE_INFINITY/NaN.

Global isFinite, isNaN, Infinity, NaN. Wired into js-global.

329/331 unit (+21), 148/148 slice unchanged.
2026-04-23 20:42:57 +00:00
ce46420c2e js-on-sx: regex literal lex+parse+transpile+runtime stub
Lexer: js-regex-context? disambiguates / based on prior token;
read-regex handles [...] classes and \ escapes. Emits
{:type "regex" :value {:pattern :flags}}.

Parser: new primary branch → (js-regex pat flags).

Transpile: (js-regex-new pat flags).

Runtime: js-regex? predicate, js-regex-new builds tagged dict with
source/flags/global/ignoreCase/multiline/sticky/unicode/dotAll/
hasIndices/lastIndex. js-regex-invoke-method dispatches .test/.exec/
.toString. js-invoke-method detects regex receivers. Stub engine
uses js-string-index-of; __js_regex_platform__ + override! let a
real engine plug in later.

Runner: repeatable --filter flags (OR'd).

308/310 unit (+30 regex tests), 148/148 slice unchanged.
2026-04-23 20:27:19 +00:00
1613f551ef HS add/append: Set dedup, @attr support, when-clause result tracking
- runtime hs-add-to!/hs-append: dedupe on list targets (Set semantics)
- compiler emit-set: set result to X now syncs it too
- compiler append!: handle (local)/(ref) targets via emit-set so scoped
  vars get rebound to the returned list
- parser add/remove: accept bare @attr (not just [@attr])
- parser add-attr: support when-clause → emits add-attr-when
- compiler add-class-when/add-attr-when: collect matched items into
  the-result / it so subsequent "if the result is empty" works

+6 upstream tests in early range (add 13→17, append 10→12).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 19:55:27 +00:00
9e568ad886 js-on-sx: baseline commit (278/280 unit, 148/148 slice, runner stub)
Initial commit of the lib/js/ tree and plans/ directory. A previous
session left template-string work in progress — 278/280 unit tests pass
(2 failing: tpl part-count off-by-one, escaped-backtick ident lookup).
test262-runner.py and scoreboard are placeholders (0/8 with 7 timeouts);
fixing the runner is the next queue item.
2026-04-23 19:42:16 +00:00