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

@ -1764,13 +1764,19 @@ let msg = `hello {name}, you have {count + 1} messages`
# == "hello " + name + ", you have " + str(count + 1) + " messages"
```
`str(x)` is the same conversion on its own. Write a literal brace as `{{` / `}}`.
`str(x)` is the same conversion on its own. Write a literal brace as `{{` / `}}`. A hole is code,
so a string, a char or another template literal inside it is taken whole - `` `a {wrap(`b {n}`)} c` ``
is one literal, and a brace or a backtick inside a string in a hole is text.
**Slicing.** `s[a..b]` is a fresh substring of the bytes `[a, b)`, and `len(s)`
is a string's byte length — so `path[0..len(path) - 6]` trims an extension and
`s[i]` still indexes a single byte. `expr with { field: … }`
is not implemented; records appear only in `spawn`. Char literals (`'w'`) are
`int` code points; colors are hex ints (`0xff8800`). `null` is the null-pointer
`int` code points; colors are hex ints (`0xff8800`). An integer literal past `2147483647` is a
`long` and keeps its value (`let mask: long = 4294967295`); given to an `int` it is refused (`n wants
an int and 4294967295 does not fit one; it is a long`). A hex literal of up to eight digits is a
32-bit pattern - `0xFFFFFFFF` is `-1`, and `0xEDB88320` given to a `long` is negative - and one of
more digits is a `long` (`0x10000000000`). `null` is the null-pointer
literal; test any pointer/record/slice with `x == null` / `x != null` (an unset
`Node`/`ptr` field reads back as `null`).