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
|
|
@ -835,6 +835,9 @@ function cmd_dev_test() -> int {
|
|||
reject_case("rejected/generic_mismatch", "words wants a Pool<string> and this is a Pool<int>", "two instances of one generic are two types")
|
||||
reject_case("rejected/generic_arity", "Pool takes 1 type argument(s) and Pool<int, string> gives 2", "a generic takes as many type arguments as it has parameters")
|
||||
reject_case("rejected/private_generic", "grow is private to module kit", "an instance of a private generic is private to its module")
|
||||
feat_case("lang/long_literals", "", "4294967295 3988292384 -4294967296 1099511627776 -3750763034362895579 -1 1", "long_literals.ludic (a decimal literal past 2^31 - 1, and a hex literal of more than eight digits, is a long)")
|
||||
reject_case("rejected/long_into_int", "4294967295 does not fit one; it is a long", "a long literal given to an int is refused, not wrapped")
|
||||
feat_case("lang/nested_templates", "", "outer [inner 3 {x}] \"`}\" end", "nested_templates.ludic (a template literal inside another's hole)")
|
||||
feat_case("lang/aliases", "", "10 5 3", "aliases.ludic (L6: a namespace method declared as an alias of a function, labelled or by its parameters)")
|
||||
reject_case("rejected/alias_arity", "this call to Trail.length leaves out to, which has no default", "an alias's arguments are checked against its target")
|
||||
reject_case("rejected/alias_twice", "Trail.length is declared twice", "a namespace method is declared once")
|
||||
|
|
|
|||
|
|
@ -136,6 +136,38 @@ program LudicFmt {
|
|||
return c == '&' or c == '|' or c == '^' or c == '~' # & | ^ ~
|
||||
}
|
||||
|
||||
|
||||
# the backtick that closes the template opening at s[i0] (or the end): a `{...}` hole is code, so
|
||||
# a string, a char or another template inside it is skipped whole - as the compiler reads it
|
||||
function fmt_tmpl_end(s: pointer, i0: int) -> int {
|
||||
var i = i0 + 1
|
||||
while s[i] != 0 and s[i] != '`' {
|
||||
if s[i] == '\\' and s[i + 1] != 0 { i += 2; continue }
|
||||
if s[i] == '{' and s[i + 1] == '{' { i += 2; continue }
|
||||
if s[i] == '{' { i = fmt_hole_end(s, i + 1) }
|
||||
if s[i] != 0 { i += 1 }
|
||||
}
|
||||
return i
|
||||
}
|
||||
function fmt_hole_end(s: pointer, i0: int) -> int {
|
||||
var i = i0
|
||||
var depth = 1
|
||||
while s[i] != 0 {
|
||||
let d = s[i]
|
||||
if d == '"' or d == '\'' {
|
||||
i += 1
|
||||
while s[i] != 0 and s[i] != d { if s[i] == '\\' and s[i + 1] != 0 { i += 1 }; i += 1 }
|
||||
}
|
||||
else if d == '`' { i = fmt_tmpl_end(s, i) }
|
||||
else if d == '{' { depth += 1 }
|
||||
else if d == '}' {
|
||||
depth -= 1
|
||||
if depth == 0 { return i }
|
||||
}
|
||||
if s[i] != 0 { i += 1 }
|
||||
}
|
||||
return i
|
||||
}
|
||||
function lex(s: pointer) -> void {
|
||||
src = s
|
||||
tk_kind = new []int; tk_start = new []int; tk_end = new []int; tk_line = new []int
|
||||
|
|
@ -155,9 +187,9 @@ program LudicFmt {
|
|||
if s[i] == '"' { i += 1 }
|
||||
push_tok(LT_STR, st, i, line); continue
|
||||
}
|
||||
if c == '`' { # `interpolated`
|
||||
let st = i; i += 1
|
||||
while s[i] != 0 and s[i] != '`' { if s[i] == '\\' and s[i + 1] != 0 { i += 2 } else { i += 1 } }
|
||||
if c == '`' { # `interpolated`, holes and all
|
||||
let st = i
|
||||
i = fmt_tmpl_end(s, i)
|
||||
if s[i] == '`' { i += 1 }
|
||||
push_tok(LT_STR, st, i, line); continue
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue