multi-line string literals

This commit is contained in:
2026-06-26 22:53:49 +02:00
parent f2ed0b4c4f
commit f926bbc605
5 changed files with 117 additions and 16 deletions
+29 -2
View File
@@ -560,9 +560,9 @@ parse_primary :: proc(parser: ^Parser, nesting: int) -> ast.Expr_Id {
right=ast.INVALID_EXPR,
diagnostic=source.INVALID_DIAGNOSTIC,
})
case .String:
case .String, .Multiline_String:
advance(parser)
value := decode_import_path(parser, tok)
value := decode_import_path(parser, tok) if tok.kind == .String else decode_multiline_string(parser, tok)
id := u64(len(parser.module.strings))
append(&parser.module.strings, value)
return add_expr(parser, ast.Expr{
@@ -1690,6 +1690,33 @@ decode_import_path :: proc(parser: ^Parser, tok: token.Token) -> string {
return fmt.aprintf("%s", strings.to_string(builder), allocator=parser.module.allocator)
}
decode_multiline_string :: proc(parser: ^Parser, tok: token.Token) -> string {
text := token_text(parser, tok)
builder := strings.builder_make(parser.module.allocator)
defer strings.builder_destroy(&builder)
first := true
index := 0
for index < len(text) {
for index < len(text) && (text[index] == ' ' || text[index] == '\t') {
index += 1
}
if index >= len(text) || text[index] != '`' {
break
}
index += 1 // skip backtick
if !first {
strings.write_byte(&builder, '\n')
}
first = false
for index < len(text) && text[index] != '\n' {
strings.write_byte(&builder, text[index])
index += 1
}
index += 1 // skip newline (terminates this line)
}
return fmt.aprintf("%s", strings.to_string(builder), allocator=parser.module.allocator)
}
parse_import :: proc(parser: ^Parser, alias: token.Token, start: token.Token) {
skip_newlines(parser)
path_token := current(parser)