Phase 7d: string interpolation text {expr} text
The readable way to build strings, as you noted `{a} {b}` beats `a + " " + b`.
A backtick string embeds any expression in `{…}` and desugars to the Phase-7c
`+` chain, wrapping each hole in `str(...)`:
`hello {name}, n={count + 1}`
== "hello " + name + ", n=" + str(count + 1)
- Lexer: a backtick captures its content raw as TK_INTERP.
- Parser: parse_interp splits literal runs from `{…}` holes (brace-depth aware,
`{{`/`}}` escape to literal braces), re-lexes each hole as a full expression
(save/restore toks/pi like an import), and folds it all into E_BIN(+) nodes —
so no new AST or runtime beyond the existing concat.
- str(x): a string passes through; int/bool/fixed convert via a small emitted
@fn_int_str prelude (digits from the end of a buffer, '-' for negatives),
emitted once into any program that uses it.
examples/strings.ludic gains interpolation cases (now prints 1..7); the smoke
covers it. Grammar + ludic_syntax.h tokenize backtick strings (holes highlighted
as embedded code). LANGUAGE.md documents it as the preferred form.
Reseeded (22530 lines); C-free fixpoint holds; goldens identical; 18/18; vocab +
doc-fences clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
a997e34b2d
commit
ad63f09d53
13 changed files with 4748 additions and 3962 deletions
|
|
@ -9,6 +9,7 @@ const TK_OP: int = 3
|
|||
const TK_NL: int = 4
|
||||
const TK_EOF: int = 5
|
||||
const TK_FLOAT: int = 6
|
||||
const TK_INTERP: int = 7 # `text {expr} text` — raw content, split by the parser
|
||||
|
||||
property Tok { kind: int = 0, text: ptr = null, ival: int = 0, line: int = 0 }
|
||||
|
||||
|
|
@ -69,6 +70,16 @@ fn lex(src: ptr) -> void {
|
|||
tok_push(TK_STR, out, 0, line)
|
||||
continue
|
||||
}
|
||||
if c == 96 { # `interpolated string` — captured raw
|
||||
i = i + 1
|
||||
let out = mem_alloc(n)
|
||||
var j = 0
|
||||
while i < n and peek8(src, i) != 96 { poke8(out, j, peek8(src, i)); j = j + 1; i = i + 1 }
|
||||
i = i + 1
|
||||
poke8(out, j, 0)
|
||||
tok_push(TK_INTERP, out, 0, line)
|
||||
continue
|
||||
}
|
||||
if c == 39 { # 'c' char literal -> int
|
||||
i = i + 1
|
||||
var v = 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue