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
+41
View File
@@ -969,6 +969,47 @@ main :: func() void {
testing.expect(t, strings.contains(llvm_text, "declare i32 @take_c_sentinel(ptr)"))
}
@(test)
multiline_strings_join_lines_and_strip_indentation :: proc(t: ^testing.T) {
// Source written double-quoted (not a raw `...` literal) because the
// backtick is the multi-line string marker. Covers basic join, the
// trailing-newline form, a blank line in the middle, and value-on-next-line.
text := "main :: func() void {\n" +
"\tbasic ::\n\t\t`a\n\t\t`b\n" +
"\ttrailing ::\n\t\t`hello\n\t\t`world\n\t\t`\n" +
"\tgapped ::\n\t\t`x\n\t\t`\n\t\t`y\n" +
"\t_ = basic\n\t_ = trailing\n\t_ = gapped\n}\n"
source_file := source.Source{path="test.bro", text=text}
diagnostics := source.init_diagnostics(&source_file)
defer source.destroy_diagnostics(&diagnostics)
symbols := symbol.init_table()
defer symbol.destroy_table(&symbols)
stream := lexer.lex(&source_file, &diagnostics, &symbols)
defer delete(stream.items)
ast_module := parser.parse(&stream, &source_file, &diagnostics)
defer ast.destroy_module(&ast_module)
hir_module := checker.check(&ast_module, &diagnostics, &symbols)
defer hir.destroy_module(&hir_module)
testing.expect_value(t, len(diagnostics.items), 0)
testing.expect_value(t, len(ast_module.strings), 3)
testing.expect_value(t, ast_module.strings[0], "a\nb")
testing.expect_value(t, ast_module.strings[1], "hello\nworld\n")
testing.expect_value(t, ast_module.strings[2], "x\n\ny")
// A multi-line string is an ordinary string literal: @[N;0]u8.
string_type := types.INVALID
for expr in hir_module.exprs {
if expr.kind == .String {
string_type = expr.type
break
}
}
pointer, array, string_ok := types.array_pointer(string_type, &hir_module.types)
testing.expect(t, string_ok && !pointer.mutable && array.child == types.U8 &&
array.has_sentinel && array.sentinel == 0)
}
@(test)
array_pointer_and_c_string_coercion_restrictions_are_diagnosed :: proc(t: ^testing.T) {
text := `take_c_string :: c_func(value *c_char) c_int