Use match for value dispatch in evaluator and compiler
Convert large cond chains doing string equality dispatch to use the match special form: step-eval-list (42 arms), step-continue (31 arms), compile-list (30 arms), ho-setup-dispatch (7 arms), value-matches-type? (10 arms). Also fix test-canonical.sx to use defsuite/deftest format and load canonical.sx in both test runners. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -82,6 +82,18 @@ env["env-merge"] = function(a, b) { return Object.assign({}, a, b); };
|
||||
|
||||
// Missing primitives referenced by tests
|
||||
// primitive? is now in platform.py PRIMITIVES
|
||||
env["contains-char?"] = function(s, c) { return typeof s === "string" && typeof c === "string" && s.indexOf(c) >= 0; };
|
||||
env["escape-string"] = function(s) { return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\t/g, "\\t"); };
|
||||
env["trim-right"] = function(s) { return typeof s === "string" ? s.trimEnd() : s; };
|
||||
env["sha3-256"] = function(s) {
|
||||
// Simple hash stub for testing — not real SHA3
|
||||
var h = 0;
|
||||
for (var i = 0; i < s.length; i++) { h = ((h << 5) - h + s.charCodeAt(i)) | 0; }
|
||||
h = Math.abs(h);
|
||||
var hex = h.toString(16);
|
||||
while (hex.length < 64) hex = "0" + hex;
|
||||
return hex;
|
||||
};
|
||||
env["upcase"] = function(s) { return s.toUpperCase(); };
|
||||
env["downcase"] = function(s) { return s.toLowerCase(); };
|
||||
env["make-keyword"] = function(name) { return new Sx.Keyword(name); };
|
||||
@@ -291,6 +303,18 @@ if (fs.existsSync(harnessPath)) {
|
||||
}
|
||||
}
|
||||
|
||||
// Load canonical.sx (content-addressing, serialization)
|
||||
const canonicalPath = path.join(projectDir, "spec", "canonical.sx");
|
||||
if (fs.existsSync(canonicalPath)) {
|
||||
const canonicalSrc = fs.readFileSync(canonicalPath, "utf8");
|
||||
const canonicalExprs = Sx.parse(canonicalSrc);
|
||||
for (const expr of canonicalExprs) {
|
||||
try { Sx.eval(expr, env); } catch (e) {
|
||||
console.error(`Error loading canonical.sx: ${e.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load compiler + VM from lib/ when running full tests
|
||||
if (fullBuild) {
|
||||
const libDir = path.join(projectDir, "lib");
|
||||
|
||||
@@ -390,6 +390,22 @@ let make_test_env () =
|
||||
bind "defeffect" (fun _args -> Nil);
|
||||
|
||||
(* --- Primitives for canonical.sx / content tests --- *)
|
||||
bind "symbol-name" (fun args ->
|
||||
match args with
|
||||
| [Symbol s] -> String s
|
||||
| _ -> raise (Eval_error "symbol-name: expected symbol"));
|
||||
bind "keyword-name" (fun args ->
|
||||
match args with
|
||||
| [Keyword k] -> String k
|
||||
| _ -> raise (Eval_error "keyword-name: expected keyword"));
|
||||
bind "trim-right" (fun args ->
|
||||
match args with
|
||||
| [String s] ->
|
||||
let len = String.length s in
|
||||
let i = ref (len - 1) in
|
||||
while !i >= 0 && (s.[!i] = ' ' || s.[!i] = '\t' || s.[!i] = '\n' || s.[!i] = '\r') do decr i done;
|
||||
String (String.sub s 0 (!i + 1))
|
||||
| _ -> raise (Eval_error "trim-right: expected string"));
|
||||
bind "contains-char?" (fun args ->
|
||||
match args with
|
||||
| [String s; String c] when String.length c = 1 ->
|
||||
@@ -809,6 +825,8 @@ let run_spec_tests env test_files =
|
||||
with e -> Printf.eprintf "Warning: %s: %s\n%!" name (Printexc.to_string e))
|
||||
end
|
||||
in
|
||||
(* Content-addressing, serialization *)
|
||||
load_module "canonical.sx" spec_dir;
|
||||
(* Render adapter for test-render-html.sx *)
|
||||
load_module "render.sx" spec_dir;
|
||||
load_module "adapter-html.sx" web_dir;
|
||||
|
||||
Reference in New Issue
Block a user