authorgravatar for me@paperdave.netdave caruso <me@paperdave.net> 2024-09-16 03:32:36-04:00
committergravatar for me@paperdave.netdave caruso <me@paperdave.net> 2024-09-16 03:32:36-04:00
log581369c0836591a07b9b84b54042368db4d00cd5
treec43a78270e72b95b5d2eb7bf627e392482a4966e
parent15d77cb85855a5a5fedbfc51ac3a76b6f937db30
signature Commit is signed but in an unrecognized format.

feat: implement multiline string literals


4 files changed, 55 insertions(+), 0 deletions(-)

CHANGELOG.md+1
...@@ -12,6 +12,7 @@...@@ -12,6 +12,7 @@
12- feat: rename `noreturn` to `never`12- feat: rename `noreturn` to `never`
13- feat: allow instantiating `@extern` at compile time13- feat: allow instantiating `@extern` at compile time
14- feat: implement tuples14- feat: implement tuples
15- feat: implement multiline string literals
15- fix: crash when printing unused struct declaration error16- fix: crash when printing unused struct declaration error
16- fix: provide array result type to sema17- fix: provide array result type to sema
17- fix: crash when analyzing an empty array without a result type18- fix: crash when analyzing an empty array without a result type
src/core/Parse.zig+18
...@@ -819,6 +819,7 @@ fn isExpressionStart(p: *Parse) bool {...@@ -819,6 +819,7 @@ fn isExpressionStart(p: *Parse) bool {
819 .kw_fn,819 .kw_fn,
820 .kw_struct,820 .kw_struct,
821 .kw_tuple,821 .kw_tuple,
822 .multiline_string,
822 => true,823 => true,
823 else => false,824 else => false,
824 };825 };
...@@ -877,6 +878,7 @@ fn parseExpressionPart(p: *Parse, mode: ParseExprMode) Error!NodeIndex {...@@ -877,6 +878,7 @@ fn parseExpressionPart(p: *Parse, mode: ParseExprMode) Error!NodeIndex {
877 .number_int => try p.blankNode(.number_int),878 .number_int => try p.blankNode(.number_int),
878 .number_float => try p.blankNode(.number_float),879 .number_float => try p.blankNode(.number_float),
879 .string => try p.blankNode(.string),880 .string => try p.blankNode(.string),
881 .multiline_string => try p.parseMultilineString(),
880882
881 .builtin_id => try p.parseBuiltinCall(),883 .builtin_id => try p.parseBuiltinCall(),
882 .dot => try p.parseAnonStructInit(),884 .dot => try p.parseAnonStructInit(),
...@@ -1320,6 +1322,22 @@ fn parseTupleType(p: *Parse) Error!NodeIndex {...@@ -1320,6 +1322,22 @@ fn parseTupleType(p: *Parse) Error!NodeIndex {
1320 });1322 });
1321}1323}
13221324
1325fn parseMultilineString(p: *Parse) !NodeIndex {
1326 const start = p.assertToken(.multiline_string);
1327
1328 while (p.eatToken(.multiline_string) != null) {}
1329
1330 const len = p.pos - start;
1331 return p.addNode(.{
1332 .tag = .multiline_string,
1333 .main_token = start,
1334 .data = .{ .list = .{
1335 .start = start,
1336 .len = len,
1337 } },
1338 });
1339}
1340
1323// helpers1341// helpers
13241342
1325/// Append a node and return its index.1343/// Append a node and return its index.
src/core/Transform.zig+22
...@@ -1620,6 +1620,28 @@ fn transformExpression(...@@ -1620,6 +1620,28 @@ fn transformExpression(
1620 });1620 });
1621 },1621 },
16221622
1623 .multiline_string => {
1624 const token_list = t.ast.nodeData(node).list;
1625
1626 assert(t.id_decode_buf.items.len == 0);
1627 defer t.id_decode_buf.clearRetainingCapacity();
1628
1629 try t.id_decode_buf.appendSlice(t.ast.tokenSlice(token_list.start)[2..]);
1630 for (token_list.start + 1..token_list.start + token_list.len) |i| {
1631 try t.id_decode_buf.append('\n');
1632 try t.id_decode_buf.appendSlice(t.ast.tokenSlice(@intCast(i))[2..]);
1633 }
1634
1635 return try t.addRef(.string, .{
1636 .src_node = ctx.nodeOffset(node),
1637 .extra_index = try t.extra.append(
1638 t.gpa,
1639 SlicedString,
1640 try t.addSlicedString(t.id_decode_buf.items),
1641 ),
1642 });
1643 },
1644
1623 else => |tag| std.debug.panic("TODO: expr {s}", .{@tagName(tag)}),1645 else => |tag| std.debug.panic("TODO: expr {s}", .{@tagName(tag)}),
1624 }1646 }
1625}1647}
test/behavior/string created+14
...@@ -0,0 +1,14 @@
1let assertEqual = @extern("assertEqual");
2
3fn main {
4 assertEqual(
5 \\hello world
6 \\etc
7 \\
8 , "hello world\netc\n"
9 );
10 assertEqual(
11 \\language compiler
12 , "language compiler"
13 );
14}