Fix CSSX styling: trampoline wiring + scope-emit!/emitted for adapter-html.sx
Root causes of missing CSSX classes in SSR: 1. _sx_trampoline_fn in sx_primitives.ml was never wired — call_any in HO forms (map/filter/for-each) returned unresolved Thunks, so callbacks like render-lambda-html's param binding never executed. Fixed in bootstrap.py FIXUPS: wire Sx_primitives._sx_trampoline_fn after eval_expr. 2. adapter-html.sx used (emit! ...) and (emitted ...) which are CEK special forms (walk kont for ScopeAccFrame), but scope-push!/scope-pop! use the hashtable. CEK frames and hashtable are two different scope systems. Fixed: adapter uses scope-emit!/scope-emitted (hashtable primitives). 3. env-* operations (env-has?, env-get, env-bind!, env-set!, env-extend, env-merge) only accepted Env type. adapter-html.sx passes Dict as env. Fixed: all env ops go through unwrap_env which handles Dict/Nil. Also: fix merge conflict in sx/sx/geography/index.sx, remove duplicate scope primitives from sx_primitives.ml (sx_server.ml registers them). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -701,49 +701,8 @@ let () =
|
||||
| [String name] -> Bool (Hashtbl.mem primitives name)
|
||||
| _ -> Bool false);
|
||||
|
||||
(* ---- Scope stack primitives (for adapter-html.sx tree-walk rendering) ---- *)
|
||||
let scope_stacks : (string, (value * value list) list) Hashtbl.t = Hashtbl.create 8 in
|
||||
register "scope-push!" (fun args ->
|
||||
match args with
|
||||
| [String name; value] ->
|
||||
let stack = try Hashtbl.find scope_stacks name with Not_found -> [] in
|
||||
Hashtbl.replace scope_stacks name ((value, []) :: stack); Nil
|
||||
| [String name] ->
|
||||
let stack = try Hashtbl.find scope_stacks name with Not_found -> [] in
|
||||
Hashtbl.replace scope_stacks name ((Nil, []) :: stack); Nil
|
||||
| _ -> Nil);
|
||||
register "scope-pop!" (fun args ->
|
||||
match args with
|
||||
| [String name] ->
|
||||
let stack = try Hashtbl.find scope_stacks name with Not_found -> [] in
|
||||
(match stack with _ :: rest -> Hashtbl.replace scope_stacks name rest | [] -> ()); Nil
|
||||
| _ -> Nil);
|
||||
register "scope-peek" (fun args ->
|
||||
match args with
|
||||
| [String name] ->
|
||||
(match Hashtbl.find_opt scope_stacks name with
|
||||
| Some ((v, _) :: _) -> v
|
||||
| _ -> Nil)
|
||||
| _ -> Nil);
|
||||
register "scope-emit!" (fun args ->
|
||||
match args with
|
||||
| [String name; value] ->
|
||||
(match Hashtbl.find_opt scope_stacks name with
|
||||
| Some ((v, emitted) :: rest) ->
|
||||
Hashtbl.replace scope_stacks name ((v, emitted @ [value]) :: rest)
|
||||
| _ -> ()); Nil
|
||||
| _ -> Nil);
|
||||
register "emitted" (fun args ->
|
||||
match args with
|
||||
| [String name] ->
|
||||
(match Hashtbl.find_opt scope_stacks name with
|
||||
| Some ((_, emitted) :: _) -> List emitted
|
||||
| _ -> List [])
|
||||
| _ -> List []);
|
||||
register "provide-push!" (fun args ->
|
||||
Hashtbl.find primitives "scope-push!" args);
|
||||
register "provide-pop!" (fun args ->
|
||||
Hashtbl.find primitives "scope-pop!" args);
|
||||
(* Scope stack primitives are registered by sx_server.ml / run_tests.ml
|
||||
because they use a shared scope stacks table with collect!/collected. *)
|
||||
|
||||
(* ---- Predicates needed by adapter-html.sx ---- *)
|
||||
register "lambda?" (fun args ->
|
||||
|
||||
Reference in New Issue
Block a user