Add --test mode to elc with Assert stmt and full native test suite passing

Implement compile_test() entry point that emits a C test harness instead
of a normal program. Test blocks (previously skipped) now compile to
static functions with per-assertion pass/fail tracking. Assert statement
added to parser and codegen. Runtime extended with now_ns, fs_list_json,
json_build_object, json_build_array, json_escape_string, state_has,
state_get_or. Fix float negation codegen, float equality comparisons,
time_to_parts return type (JSON string), time_format empty-fmt, json_set
raw-value semantics, state_keys JSON array return. All 310 native tests
pass across 9 suites (core, text, string, math, env, state, json, time, fs).
This commit is contained in:
Will Anderson
2026-05-06 14:33:47 -05:00
parent 6ced0f8009
commit ec889e1e53
7 changed files with 460 additions and 28 deletions
+22
View File
@@ -1684,6 +1684,28 @@ fn parse_stmt(tokens: [Any], pos: Int) -> Map<String, Any> {
}, p)
}
// assert <cond_expr> [ , <msg_expr> ]
// The message is optional if the next token after the condition is not a
// Comma, emit an empty string placeholder so the test still works.
if k == "Assert" {
let p: Int = pos + 1
let cond_r = parse_expr(tokens, p)
let cond_node = cond_r["node"]
let p: Int = cond_r["pos"]
el_release(cond_r)
let after_k: String = tok_kind(tokens, p)
if str_eq(after_k, "Comma") {
let p = p + 1
let msg_r = parse_expr(tokens, p)
let msg_node = msg_r["node"]
let p: Int = msg_r["pos"]
el_release(msg_r)
return make_result({ "stmt": "Assert", "cond": cond_node, "msg": msg_node }, p)
}
// No message use empty string placeholder.
return make_result({ "stmt": "Assert", "cond": cond_node, "msg": { "expr": "Str", "value": "" } }, p)
}
// Bare reassignment: `name = expr`. Handled BEFORE the expression
// fallback so we don't drop the assign on the floor and emit three
// orphan expressions (the original silent-miscompile bug). El's `let`