elc: regenerate dist artifacts and ship parser.el state alongside self-host land

This commit is contained in:
Will Anderson
2026-05-02 01:30:31 -05:00
parent 13948f57a6
commit d527fa6065
3 changed files with 3531 additions and 145 deletions
+1859 -60
View File
File diff suppressed because it is too large Load Diff
+78 -6
View File
@@ -209,7 +209,20 @@ fn parse_primary(tokens: [Map<String, Any>], pos: Int) -> Map<String, Any> {
}
// Map literal: { "key": val, ... }
//
// Suppression: when parse_if / parse_while / parse_for / parse_match
// are parsing a head expression, they set __no_block_expr=1 so a stray
// `{` here doesn't get gobbled as a Map literal it belongs to the
// following block. Without this, `if a || b { ... }` could mis-parse
// (the `||` recursion lands at `{` and tries to read the if-body as a
// Map, then loops forever when keys don't match `Str: expr`).
if k == "LBrace" {
let no_block: String = state_get("__no_block_expr")
if str_eq(no_block, "1") {
// Fall through to fallback caller will see `{` and treat it
// as the start of the block they're expecting.
return make_result({ "expr": "Nil" }, pos)
}
let p = pos + 1
let pairs: [Map<String, Any>] = native_list_empty()
let running = true
@@ -223,16 +236,23 @@ fn parse_primary(tokens: [Map<String, Any>], pos: Int) -> Map<String, Any> {
} else {
// key: Str token
let key = tok_value(tokens, p)
let p = p + 1
let p = expect(tokens, p, "Colon")
let r = parse_expr(tokens, p)
let new_p: Int = p + 1
let new_p = expect(tokens, new_p, "Colon")
let r = parse_expr(tokens, new_p)
let val_node = r["node"]
let p = r["pos"]
let new_p = r["pos"]
let pair = { "key": key, "value": val_node }
let pairs = native_list_append(pairs, pair)
let k3 = tok_kind(tokens, p)
let k3 = tok_kind(tokens, new_p)
if k3 == "Comma" {
let new_p = new_p + 1
}
// Non-progress guard: malformed map content can leave
// parse_expr returning the same pos. Force advance.
if new_p <= p {
let p = p + 1
} else {
let p = new_p
}
}
}
@@ -275,13 +295,44 @@ fn parse_primary(tokens: [Map<String, Any>], pos: Int) -> Map<String, Any> {
return make_result({ "expr": "Neg", "inner": inner }, p)
}
// Soft keywords usable as identifiers in expression position. The lexer
// turns words like `target`, `to`, `via`, `deploy`, etc. into dedicated
// token kinds for the deploy/retry DSLs, but they're also valid as
// parameter names and local variables. When one of these appears in
// expression position (where only an Ident makes sense), treat it as
// an Ident carrying the original text otherwise references to a
// parameter named `target` compile to EL_NULL.
if k == "Target" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "To" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Via" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Deploy" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Reason" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Times" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Fallback" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Retry" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Parallel" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Trace" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Requires" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Where" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "As" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "With" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Manager" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Engine" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Accessor" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
if k == "Vessel" { return make_result({ "expr": "Ident", "name": v }, pos + 1) }
// Fallback: skip unknown token
make_result({ "expr": "Nil" }, pos + 1)
}
fn parse_if(tokens: [Map<String, Any>], pos: Int) -> Map<String, Any> {
let p = expect(tokens, pos, "If")
// Suppress Map-literal parsing in the cond so a stray `{` (the start
// of the then-block) isn't gobbled as a Map.
let prev_no_block: String = state_get("__no_block_expr")
state_set("__no_block_expr", "1")
let r = parse_expr(tokens, p)
state_set("__no_block_expr", prev_no_block)
let cond = r["node"]
let p = r["pos"]
let r2 = parse_block(tokens, p)
@@ -312,7 +363,10 @@ fn parse_if(tokens: [Map<String, Any>], pos: Int) -> Map<String, Any> {
fn parse_match(tokens: [Map<String, Any>], pos: Int) -> Map<String, Any> {
let p = expect(tokens, pos, "Match")
let prev_no_block: String = state_get("__no_block_expr")
state_set("__no_block_expr", "1")
let r = parse_expr(tokens, p)
state_set("__no_block_expr", prev_no_block)
let subject = r["node"]
let p = r["pos"]
let p = expect(tokens, p, "LBrace")
@@ -374,7 +428,10 @@ fn parse_for_expr(tokens: [Map<String, Any>], pos: Int) -> Map<String, Any> {
let item_name = tok_value(tokens, p)
let p = p + 1
let p = expect(tokens, p, "In")
let prev_no_block: String = state_get("__no_block_expr")
state_set("__no_block_expr", "1")
let r = parse_expr(tokens, p)
state_set("__no_block_expr", prev_no_block)
let list_expr = r["node"]
let p = r["pos"]
let r2 = parse_block(tokens, p)
@@ -397,8 +454,17 @@ fn parse_block(tokens: [Map<String, Any>], pos: Int) -> Map<String, Any> {
} else {
let r = parse_stmt(tokens, p)
let stmt = r["node"]
let p = r["pos"]
let new_p: Int = r["pos"]
let stmts = native_list_append(stmts, stmt)
// Non-progress guard: a malformed input (e.g. `||` that
// dragged the parser into Map-literal mode partway through
// the if-body) can leave parse_stmt returning the same pos.
// Force advance so the outer compile doesn't hang.
if new_p <= p {
let p = p + 1
} else {
let p = new_p
}
}
}
}
@@ -712,7 +778,10 @@ fn parse_stmt(tokens: [Map<String, Any>], pos: Int) -> Map<String, Any> {
// while loop
if k == "While" {
let p = pos + 1
let prev_no_block: String = state_get("__no_block_expr")
state_set("__no_block_expr", "1")
let r = parse_expr(tokens, p)
state_set("__no_block_expr", prev_no_block)
let cond = r["node"]
let p = r["pos"]
let r2 = parse_block(tokens, p)
@@ -727,7 +796,10 @@ fn parse_stmt(tokens: [Map<String, Any>], pos: Int) -> Map<String, Any> {
let item_name = tok_value(tokens, p)
let p = p + 1
let p = expect(tokens, p, "In")
let prev_no_block: String = state_get("__no_block_expr")
state_set("__no_block_expr", "1")
let r = parse_expr(tokens, p)
state_set("__no_block_expr", prev_no_block)
let list_expr = r["node"]
let p = r["pos"]
let r2 = parse_block(tokens, p)
+1594 -79
View File
File diff suppressed because it is too large Load Diff