fix(lang): a template inside another's hole, and integer literals past 2^31 - 1
A template literal nested in a {...} hole crashed the parser: the outer
literal ended at the inner backtick. The lexer (and ludic-fmt's) now
reads a hole as code, taking strings, chars and templates in it whole.
A decimal literal past 2147483647, or a hex one of more than eight
digits, was wrapped into a negative int; it is a long with its value
now, and giving one to an int is refused. Reseed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
b401f7acc1
commit
afa4d23a4f
17 changed files with 47107 additions and 46056 deletions
|
|
@ -199,19 +199,9 @@ function parse_interp(raw: pointer) -> Node {
|
|||
if lj > 0 { acc = interp_add(acc, interp_lit(lit, lj)); lj = 0 }
|
||||
i += 1
|
||||
let hs = i
|
||||
# find the hole's closing brace: braces nest, and a brace inside a
|
||||
# "string" or 'char' literal in the hole is text, not structure
|
||||
var depth = 1
|
||||
while i < n and depth > 0 {
|
||||
let d = raw[i]
|
||||
if d == '"' or d == CH_SQUOTE {
|
||||
i += 1
|
||||
while i < n and raw[i] != d { if raw[i] == CH_BACKSLASH { i += 1 }; i += 1 }
|
||||
}
|
||||
else if d == '{' { depth += 1 }
|
||||
else if d == '}' { depth -= 1; if depth == 0 { break } }
|
||||
i += 1
|
||||
}
|
||||
# find the hole's closing brace: braces nest, and a brace inside a "string", a 'char' or a
|
||||
# `template` in the hole is text, not structure (lex.ludic, hole_end)
|
||||
i = hole_end(raw, i, n)
|
||||
acc = interp_add(acc, interp_str(parse_hole(raw[hs..i])))
|
||||
i += 1 # skip the closing '}'
|
||||
} else {
|
||||
|
|
@ -259,7 +249,7 @@ function p_primary() -> Node {
|
|||
if t.kind == TK_INTERP { pi += 1; g_interp_line = t.line; return parse_interp(t.text) }
|
||||
if is_op("[") { return parse_list() }
|
||||
if t.kind == TK_ID and (t.text == "emit") and (toks[pi + 1].kind == TK_ID) { return parse_emit() }
|
||||
if t.kind == TK_INT { let n = node(E_INT); n.ival = t.ival; pi += 1; return n }
|
||||
if t.kind == TK_INT { let n = node(E_INT); n.ival = t.ival; n.s = t.text; pi += 1; return n } # s: a long literal's digits
|
||||
if t.kind == TK_FLOAT { let n = node(E_FLOAT); n.ival = t.ival; n.s = t.text; pi += 1; return n }
|
||||
if t.kind == TK_STR { let n = node(E_STR); n.s = t.text; pi += 1; return n }
|
||||
if t.kind == TK_ID {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue