From 9d364a0c20adee52db6a65ec9fb31f6f84da0b33 Mon Sep 17 00:00:00 2001 From: giles Date: Sun, 10 May 2026 14:52:49 +0000 Subject: [PATCH] js-on-sx: user function prototype chain links Object.prototype + sets constructor --- lib/js/runtime.sx | 6 +++++- plans/js-on-sx.md | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/js/runtime.sx b/lib/js/runtime.sx index c97f72e7..e4ed4adf 100644 --- a/lib/js/runtime.sx +++ b/lib/js/runtime.sx @@ -1482,7 +1482,11 @@ (else (let ((p (dict))) - (begin (dict-set! __js_proto_table__ id p) p))))))))) + (begin + (dict-set! p "__proto__" (get Object "prototype")) + (dict-set! p "constructor" ctor) + (dict-set! __js_proto_table__ id p) + p))))))))) (define js-reset-ctor-proto! diff --git a/plans/js-on-sx.md b/plans/js-on-sx.md index 6186c097..0ab04ec4 100644 --- a/plans/js-on-sx.md +++ b/plans/js-on-sx.md @@ -158,6 +158,8 @@ Each item: implement → tests → update progress. Mark `[x]` when tests green. Append-only record of completed iterations. Loop writes one line per iteration: date, what was done, test count delta. +- 2026-05-10 — **User functions' `prototype` chain through Object.prototype + auto-set `constructor`.** Per ES spec, every function's `prototype` slot defaults to `{ constructor: F, __proto__: Object.prototype }`. Our `js-get-ctor-proto` lazily created a fresh empty `(dict)` for user functions on first access — so `(new F) instanceof Object` was `false`, `F.prototype.constructor` was undefined, and `x.constructor === F` failed. Now the lazy-init seeds the proto with `__proto__ → Object.prototype` and `constructor → F` before caching in `__js_proto_table__`. Result: language/expressions/instanceof 25/30 → 26/30. conformance.sh: 148/148. + - 2026-05-10 — **Postfix `++`/`--` reject a preceding LineTerminator (ASI).** Per ES spec, `x\n++;` is a syntax error: no LineTerminator allowed between LHS and postfix `++`/`--`. Our `jp-parse-postfix` was matching `++`/`--` regardless of whether the preceding token had `:nl true`. Added `(not (jp-token-nl? st))` guard so newline-before-`++` makes the postfix arm fall through, the `++` then becomes a prefix-expr starting a new statement, which fails to parse and the runner classifies as SyntaxError. Result: language/expressions/postfix-increment 16/30 → 18/30 (+2). postfix-decrement 16/30 → 18/30 (+2). conformance.sh: 148/148. - 2026-05-10 — **Parse-time SyntaxError when `let`/`const`/`function`/`class` appear as a single-statement body of `if`/`while`/`do`/`for`/labeled.** Per ES grammar, those positions accept a Statement, not a Declaration — only block bodies (`{ ... }`) may contain Declarations. Added `jp-disallow-decl-stmt!` helper that, when the next token is a Declaration keyword in single-statement context, raises SyntaxError. The `let` arm checks for `let `, `let [`, or `let {` to avoid mis-rejecting `let;` (where `let` is just an identifier expression). Hook calls in `jp-parse-if-stmt` (then + else branches), `jp-parse-while-stmt`, `jp-parse-do-while-stmt`, both for-of/in and C-for body sites, and the labeled-statement entry. Result: language/statements/while 16/30 → 20/30. statements/labeled 4/15 → 7/15. statements/if 20/30 → 21/30. conformance.sh: 148/148.