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
|
|
@ -985,7 +985,10 @@ function emit_call(e: Node) -> Val {
|
|||
|
||||
function emit_expr(e: Node) -> Val {
|
||||
if (e == null) { return val("0", "int") }
|
||||
if e.kind == E_INT { return val(itoa(e.ival), "int") }
|
||||
if e.kind == E_INT {
|
||||
if e.s != null { return val(e.s, "long") } # a literal past 2^31 - 1
|
||||
return val(itoa(e.ival), "int")
|
||||
}
|
||||
if e.kind == E_FLOAT and is_float_file(e.file) {
|
||||
let ff = val(fp_lit_code(e.s, "float"), "float")
|
||||
ff.lit = e
|
||||
|
|
|
|||
|
|
@ -360,7 +360,10 @@ function static_type(e: Node) -> pointer {
|
|||
if (et != null) { return "[]" + et }
|
||||
}
|
||||
if e.kind == E_STR or e.kind == E_SLICE { return "string" }
|
||||
if e.kind == E_INT { return "int" }
|
||||
if e.kind == E_INT {
|
||||
if e.s != null { return "long" }
|
||||
return "int"
|
||||
}
|
||||
if e.kind == E_FLOAT and is_float_file(e.file) { return "float" }
|
||||
if e.kind == E_FLOAT { return "fixed" }
|
||||
if e.kind == E_BOOL { return "bool" }
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ function fp_result(a: pointer, b: pointer) -> pointer {
|
|||
# a literal-only expression (Val.lit) evaluated exactly in float type t
|
||||
function fp_const(e: Node, t: pointer) -> pointer {
|
||||
if e.kind == E_FLOAT { return fp_lit_code(e.s, t) }
|
||||
if e.kind == E_INT { return fp_lit_code(itoa(e.ival), t) }
|
||||
if e.kind == E_INT { return fp_lit_code(int_lit_code(e), t) }
|
||||
if e.kind == E_UN {
|
||||
let x = fp_const(e.a, t)
|
||||
return emit_bind(`fneg {t} {x}`)
|
||||
|
|
|
|||
|
|
@ -30,12 +30,18 @@ function emit_escaped(s: pointer) -> void {
|
|||
}
|
||||
}
|
||||
|
||||
# an int literal's LLVM constant: its value, or a long literal's own digits
|
||||
function int_lit_code(e: Node) -> pointer {
|
||||
if e.s != null { return e.s }
|
||||
return itoa(e.ival)
|
||||
}
|
||||
# the constant initializer for a global var: a literal, or 0/null
|
||||
function global_init(d: Node) -> pointer {
|
||||
if (d.a == null) or is_fp(d.ty) { return zero_of(llty(d.ty)) } # a float's value is set by L_init_globals
|
||||
let e = d.a
|
||||
if e.kind == E_INT or e.kind == E_FLOAT or e.kind == E_BOOL { return itoa(e.ival) }
|
||||
if e.kind == E_UN and (e.s == ("-")) and e.a.kind == E_INT { return (("-") + itoa(e.a.ival)) }
|
||||
if e.kind == E_INT { return int_lit_code(e) }
|
||||
if e.kind == E_FLOAT or e.kind == E_BOOL { return itoa(e.ival) }
|
||||
if e.kind == E_UN and (e.s == ("-")) and e.a.kind == E_INT { return (("-") + int_lit_code(e.a)) }
|
||||
if e.kind == E_MEMBER and e.a.kind == E_ID { # `Enum.Variant` is a compile-time int
|
||||
let ord = enum_ordinal(e.a.s, e.s)
|
||||
if ord >= 0 { return itoa(ord) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue