improve can representation of multiline strings

This commit is contained in:
Fabian Schmalzried 2025-08-19 11:42:11 +00:00
parent 852a9af365
commit eec77e64f7
3 changed files with 24 additions and 30 deletions

View file

@ -3382,48 +3382,34 @@ fn extractStringSegments(self: *Self, parts: []const AST.Expr.Idx) std.mem.Alloc
return try self.env.store.exprSpanFrom(start);
}
/// Extract string segments from parsed string parts, combining consecutive string parts with newlines
/// Extract string segments from parsed multiline string parts, adding newlines between consecutive string parts
fn extractMultilineStringSegments(self: *Self, parts: []const AST.Expr.Idx) std.mem.Allocator.Error!Expr.Span {
const start = self.env.store.scratchExprTop();
var combined_text: []const u8 = "";
var combined_region: ?AST.TokenizedRegion = null;
var last_string_part_end: ?Token.Idx = null;
for (parts) |part| {
const part_node = self.parse_ir.store.getExpr(part);
switch (part_node) {
.string_part => |sp| {
// get the raw text of the string part
const part_text = self.parse_ir.resolve(sp.token);
if (combined_text.len == 0) {
combined_text = part_text;
combined_region = part_node.to_tokenized_region();
} else {
// TODO: should this be \n or \\n or even different depending on file encoding
combined_text = try std.fmt.allocPrint(self.env.gpa, "{s}\\n{s}", .{ combined_text, part_text });
combined_region = combined_region.?.spanAcross(part_node.to_tokenized_region());
// Add newline between consecutive string parts
if (last_string_part_end != null) {
try self.addStringLiteralToScratch("\\n", .{ .start = last_string_part_end.?, .end = part_node.to_tokenized_region().start });
}
// Get and process the raw text of the string part
const part_text = self.parse_ir.resolve(sp.token);
if (part_text.len != 0) {
try self.addStringLiteralToScratch(part_text, part_node.to_tokenized_region());
}
last_string_part_end = part_node.to_tokenized_region().end;
},
else => {
// First add any accumulated string parts
if (combined_region != null) {
try self.addStringLiteralToScratch(combined_text, combined_region.?);
// reset combined state
combined_text = "";
combined_region = null;
}
// Then handle the interpolation
last_string_part_end = null;
try self.addInterpolationToScratch(part, part_node);
},
}
}
// add any remaining combined string at the end
if (combined_text.len > 0) {
try self.addStringLiteralToScratch(combined_text, combined_region.?);
}
return try self.env.store.exprSpanFrom(start);
}

View file

@ -97,13 +97,19 @@ NO CHANGE
(d-let
(p-assign @8.1-8.7 (ident "value3"))
(e-string @8.10-10.14
(e-literal @8.13-10.5 (string "This is a string\nWith multiple lines\n"))
(e-literal @8.13-8.29 (string "This is a string"))
(e-literal @9.2-9.5 (string "\n"))
(e-literal @9.5-9.24 (string "With multiple lines"))
(e-literal @10.2-10.5 (string "\n"))
(e-lookup-local @10.7-10.13
(p-assign @3.1-3.7 (ident "value1")))))
(d-let
(p-assign @12.1-12.7 (ident "value4"))
(e-string @13.2-16.14
(e-literal @13.5-16.5 (string "This is a string\nWith multiple lines\n"))
(e-literal @13.5-13.21 (string "This is a string"))
(e-literal @15.2-15.5 (string "\n"))
(e-literal @15.5-15.24 (string "With multiple lines"))
(e-literal @16.2-16.5 (string "\n"))
(e-lookup-local @16.7-16.13
(p-assign @5.1-5.7 (ident "value2"))))))
~~~

View file

@ -30,7 +30,9 @@ NO CHANGE
# CANONICALIZE
~~~clojure
(e-string @1.1-2.23
(e-literal @1.4-2.23 (string "This is a string\nWith multiple lines")))
(e-literal @1.4-1.20 (string "This is a string"))
(e-literal @2.1-2.4 (string "\n"))
(e-literal @2.4-2.23 (string "With multiple lines")))
~~~
# TYPES
~~~clojure