Fix primitive? lookup + replace coercion; remove debug output

primitive? in make_server_env was checking env bindings only (NativeFn),
missing all 132 primitives in the Sx_primitives hashtable. Now checks
both primitives table and env. get-primitive similarly fixed.

replace primitive now coerces SxExpr/Thunk/RawHTML/etc to strings instead
of crashing with "replace: 3 string args" — fixes aser JIT DISABLED.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-24 16:29:52 +00:00
parent f9f810ffd7
commit 6ef9688bd2
2 changed files with 17 additions and 5 deletions

View File

@@ -593,14 +593,17 @@ let make_server_env () =
bind "primitive?" (fun args -> bind "primitive?" (fun args ->
match args with match args with
| [String name] -> | [String name] ->
(* Check if name is bound in the env as a NativeFn *) (* Check both the primitives table and the env *)
(try match env_get env name with NativeFn _ -> Bool true | _ -> Bool false Bool (Sx_primitives.is_primitive name ||
with _ -> Bool false) (try (match env_get env name with NativeFn _ -> true | _ -> false)
with _ -> false))
| _ -> Bool false); | _ -> Bool false);
bind "get-primitive" (fun args -> bind "get-primitive" (fun args ->
match args with match args with
| [String name] -> | [String name] ->
(try env_get env name with _ -> Nil) (* Check primitives table first, then env *)
(try Sx_primitives.get_primitive name
with _ -> try env_get env name with _ -> Nil)
| _ -> Nil); | _ -> Nil);
(* Character classification — platform primitives for spec/parser.sx *) (* Character classification — platform primitives for spec/parser.sx *)

View File

@@ -283,8 +283,17 @@ let () =
String (String.concat sep (List.map to_string items)) String (String.concat sep (List.map to_string items))
| _ -> raise (Eval_error "join: 2 args")); | _ -> raise (Eval_error "join: 2 args"));
register "replace" (fun args -> register "replace" (fun args ->
let to_str = function
| String s -> s | SxExpr s -> s | RawHTML s -> s
| Keyword k -> k | Symbol s -> s
| Nil -> "" | Bool true -> "true" | Bool false -> "false"
| Number n -> if Float.is_integer n then string_of_int (int_of_float n) else Printf.sprintf "%g" n
| Thunk _ as t -> (match !_sx_trampoline_fn t with String s -> s | v -> to_string v)
| v -> to_string v
in
match args with match args with
| [String s; String old_s; String new_s] -> | [s; old_s; new_s] ->
let s = to_str s and old_s = to_str old_s and new_s = to_str new_s in
let ol = String.length old_s in let ol = String.length old_s in
if ol = 0 then String s if ol = 0 then String s
else begin else begin