feat: string interpolation via f"..." syntax
Bootstrap compiler:
- Add ekStringInterp AST node with text/expr parts
- Lexer: recognize f"..." prefix for interpolation strings
- Parser: split f"..." into ekStringInterp, parse inner expressions
via sub-lexer/sub-parser. Supports escaped braces \{ and \}.
- Sema: type-check interpolated expressions, return String type
- HIR lowerer: desugar ekStringInterp to chained String_Concat
calls with automatic type conversions:
- int/uint types -> String_FromInt
- float types -> String_FromFloat
- bool -> String_FromBool
- String -> as-is
Selfhost compiler:
- ast.bux: add ekStringInterp constant (reserved for future)
- lexer.bux: accept f" prefix, treat as plain string literal
(selfhost parser does not implement interpolation yet)
Tests:
- _test_string_interp verifies int, float, bool, String,
multiple interpolations, plain strings, and Fmt-style {0} templates
This commit is contained in:
@@ -95,6 +95,7 @@ const ekBlock: int = 21;
|
||||
const ekMatch: int = 22;
|
||||
const ekSpawn: int = 24;
|
||||
const ekAwait: int = 25;
|
||||
const ekStringInterp: int = 26;
|
||||
|
||||
struct ExprList {
|
||||
expr: *Expr,
|
||||
|
||||
+6
-1
@@ -704,7 +704,12 @@ func lexNextToken(lex: *Lexer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// String prefixes: c8" c16" c32"
|
||||
// String prefixes: f" c8" c16" c32"
|
||||
if c == 102 && lexPeek(lex, 1) == 34 { // f"
|
||||
discard lexAdvance(lex); // f
|
||||
lexMarkStart(lex); // treat as plain string literal in selfhost
|
||||
lexScanString(lex); return;
|
||||
}
|
||||
if c == 99 { // 'c'
|
||||
let d: uint32 = lexPeek(lex, 1);
|
||||
if d == 56 && lexPeek(lex, 2) == 34 { // c8"
|
||||
|
||||
Reference in New Issue
Block a user