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

@ -0,0 +1,16 @@
# long_literals.ludic — a decimal literal past 2^31 - 1 is a long and keeps its value; so is a hex
# literal of more than eight digits (past 2^63 it wraps, as the bits say). Eight hex digits or
# fewer stay a 32-bit pattern (0xFFFFFFFF is -1, as it always was).
#
# Running it prints: 4294967295 3988292384 -4294967296 1099511627776 -3750763034362895579 -1 1
program LongLiterals {
const MASK: long = 4294967295
var poly: long = 3988292384
function neg() -> long { return -4294967296 }
entry {
let big = 0x10000000000
let fnv = 0xcbf29ce484222325
let small = 0xFFFFFFFF
print(`{MASK} {poly} {neg()} {big} {fnv} {small} {MASK > long(2147483647)}`)
}
}

View file

@ -0,0 +1,12 @@
# nested_templates.ludic — a template literal inside another's hole is one expression: the outer
# literal ends at its own backtick, not at the inner one's. A brace or a backtick inside a string in
# a hole is text, and {{ }} are still literal braces.
#
# Running it prints: outer [inner 3 {x}] "`}" end
program NestedTemplates {
function wrap(s: string) -> string { return `[{s}]` }
entry {
let n = 3
print(`outer {wrap(`inner {n} {{x}}`)} {"\"`}\""} end`)
}
}

View file

@ -0,0 +1,7 @@
# a literal past 2^31 - 1 is a long, and a long does not narrow into an int
program LongIntoInt {
entry {
let n: int = 4294967295
print(n)
}
}