Fix: local bindings now shadow HTML tag special forms in browser evaluator

Root cause: sx_browser.ml registered all HTML tags (a, b, i, p, s, u, g, etc.)
as custom special forms. The evaluator's step_eval_list checked custom special
forms BEFORE checking local env bindings. So (let ((a (fn () 42))) (a))
matched the HTML tag <a> instead of calling the local function a.

Fix: skip custom special forms AND render-check when the symbol is bound in
the local env. Added (not (env-has? env name)) guard to both checks in
step-eval-list (spec/evaluator.sx and transpiled sx_ref.ml).

This was the root cause of "[sx] resume: Not callable: nil" — after hs-wait
resumed, calling letrec-bound functions like wait-boot (which is not an HTML
tag) worked, but any function whose name collided with an HTML tag failed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-17 12:53:09 +00:00
parent 0f9bb68ba2
commit c641b445f8
16 changed files with 1541 additions and 1376 deletions

View File

@@ -1820,7 +1820,9 @@
("define-syntax" (step-sf-define args env kont))
(_
(cond
(has-key? *custom-special-forms* name)
(and
(has-key? *custom-special-forms* name)
(not (env-has? env name)))
(make-cek-value
((get *custom-special-forms* name) args env)
env
@@ -1829,7 +1831,10 @@
(let
((mac (env-get env name)))
(make-cek-state (expand-macro mac args env) env kont))
(and *render-check* (*render-check* expr env))
(and
*render-check*
(not (env-has? env name))
(*render-check* expr env))
(make-cek-value (*render-fn* expr env) env kont)
:else (step-eval-call head args env kont)))))
(step-eval-call head args env kont))))))