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:
Orkun ÇAKILKAYA 2026-09-25 08:10:46 +03:00
parent b401f7acc1
commit afa4d23a4f
17 changed files with 47107 additions and 46056 deletions

View file

@ -51,6 +51,11 @@ function ck_err(cat: pointer, n: Node, msg: pointer) -> void {
}
# a value given where a type is wanted: `what` says where ("argument 2 of f", "x")
function ck_give(to: pointer, from: pointer, e: Node, what: pointer) -> void {
# a literal past 2^31 - 1 given to an int would lose its value: say so, rather than wrap it
if e != null and e.kind == E_INT and e.s != null and ((to == "int") or (to == "byte") or (to == "fixed")) {
ck_err("literal", e, `{what} wants {ck_a(to)} and {e.s} does not fit one; it is a long`)
return
}
let cat = ck_mismatch(to, from, e)
if cat == null { return }
if (cat == "slice-pointer") {

View file

@ -32,7 +32,10 @@ function ck_expr(e: Node) -> pointer {
let ex = ck_expect
ck_expect = null
let k = e.kind
if k == E_INT { return "int" }
if k == E_INT {
if e.s != null { return "long" } # a literal past 2^31 - 1
return "int"
}
if k == E_FLOAT {
if is_float_file(e.file) { return "float" }
return "fixed"