Skip to content

Commit 60e0569

Browse files
Merge pull request #7693 from roc-lang/sexpr-region-strings
Fix parsing regions
2 parents 1962383 + 09078a6 commit 60e0569

39 files changed

+395
-286
lines changed

src/base/Region.zig

+1-8
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,7 @@ pub fn format(self: *const Region, comptime fmt: []const u8, _: std.fmt.FormatOp
3737
std.fmt.invalidFmtError(fmt, self);
3838
}
3939

40-
if (self.isEmpty()) {
41-
// In tests, it's super common to set all Located values to 0.
42-
// Also in tests, we don't want to bother printing the locations
43-
// because it makes failed assertions much harder to read.
44-
try writer.print("…", .{});
45-
} else {
46-
try writer.print("@{}-{}", .{ self.start.offset, self.end.offset });
47-
}
40+
try writer.print("@{}-{}", .{ self.start.offset, self.end.offset });
4841
}
4942

5043
/// One side of a [Region].

src/check/parse/IR.zig

+63-87
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,11 @@ pub fn regionIsMultiline(self: *IR, region: Region) bool {
5454
pub fn regionInfo(self: *IR, region: Region, line_starts: std.ArrayList(u32)) base.DiagnosticPosition {
5555
const start = self.tokens.resolve(region.start);
5656
const end = self.tokens.resolve(region.end);
57+
const info = base.DiagnosticPosition.position(self.source, line_starts, start.start.offset, end.end.offset) catch {
58+
std.debug.panic("failed to calculate position info for region {?}, start: {}, end: {}", .{ region, start, end });
59+
};
5760

58-
if (end.isEmpty()) {
59-
// use the range from start only
60-
const info = base.DiagnosticPosition.position(self.source, line_starts, start.start.offset, start.end.offset) catch {
61-
std.debug.panic("failed to calculate position info for region {?}, start: {}, end: {}", .{ region, start, end });
62-
};
63-
64-
return info;
65-
} else {
66-
const info = base.DiagnosticPosition.position(self.source, line_starts, start.start.offset, end.end.offset) catch {
67-
std.debug.panic("failed to calculate position info for region {?}, start: {}, end: {}", .{ region, start, end });
68-
};
69-
70-
return info;
71-
}
61+
return info;
7262
}
7363

7464
pub fn deinit(self: *IR) void {
@@ -1275,7 +1265,10 @@ pub const NodeStore = struct {
12751265
} };
12761266
},
12771267
.malformed => {
1278-
return .{ .malformed = .{ .reason = @enumFromInt(node.data.lhs) } };
1268+
return .{ .malformed = .{
1269+
.reason = @enumFromInt(node.data.lhs),
1270+
.region = node.region,
1271+
} };
12791272
},
12801273
else => {
12811274
std.debug.panic("Expected a valid header tag, got {s}", .{@tagName(node.tag)});
@@ -1657,7 +1650,10 @@ pub const NodeStore = struct {
16571650
} };
16581651
},
16591652
.malformed => {
1660-
return .{ .malformed = .{ .reason = @enumFromInt(node.data.lhs) } };
1653+
return .{ .malformed = .{
1654+
.reason = @enumFromInt(node.data.lhs),
1655+
.region = node.region,
1656+
} };
16611657
},
16621658
else => {
16631659
std.debug.panic("Expected a valid expr tag, got {s}", .{@tagName(node.tag)});
@@ -1782,7 +1778,10 @@ pub const NodeStore = struct {
17821778
} };
17831779
},
17841780
.malformed => {
1785-
return .{ .malformed = .{ .reason = @enumFromInt(node.data.lhs) } };
1781+
return .{ .malformed = .{
1782+
.reason = @enumFromInt(node.data.lhs),
1783+
.region = node.region,
1784+
} };
17861785
},
17871786
else => {
17881787
std.debug.panic("Expected a valid type annotation node, found {s}", .{@tagName(node.tag)});
@@ -1874,6 +1873,7 @@ pub const NodeStore = struct {
18741873
},
18751874
malformed: struct {
18761875
reason: Diagnostic.Tag,
1876+
region: Region,
18771877
},
18781878

18791879
const AppHeaderRhs = packed struct { num_packages: u10, num_provides: u22 };
@@ -1882,55 +1882,41 @@ pub const NodeStore = struct {
18821882
switch (self) {
18831883
.app => |a| {
18841884
var node = sexpr.Expr.init(env.gpa, "app");
1885-
18861885
node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
1887-
18881886
node.appendStringChild(env.gpa, "TODO implement toSExpr for app module header");
18891887
return node;
18901888
},
18911889
.module => |module| {
18921890
var node = sexpr.Expr.init(env.gpa, "module");
1893-
18941891
node.appendRegionChild(env.gpa, ir.regionInfo(module.region, line_starts));
1895-
18961892
for (ir.store.exposedItemSlice(module.exposes)) |exposed| {
18971893
const item = ir.store.getExposedItem(exposed);
18981894
var item_node = item.toSExpr(env, ir, line_starts);
18991895
node.appendNodeChild(env.gpa, &item_node);
19001896
}
1901-
19021897
return node;
19031898
},
19041899
.package => |a| {
19051900
var node = sexpr.Expr.init(env.gpa, "package");
1906-
19071901
node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
1908-
19091902
node.appendStringChild(env.gpa, "TODO implement toSExpr for package module header");
19101903
return node;
19111904
},
19121905
.platform => |a| {
19131906
var node = sexpr.Expr.init(env.gpa, "platform");
1914-
19151907
node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
1916-
19171908
node.appendStringChild(env.gpa, "TODO implement toSExpr for platform module header");
19181909
return node;
19191910
},
19201911
.hosted => |a| {
19211912
var node = sexpr.Expr.init(env.gpa, "hosted");
1922-
19231913
node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
1924-
19251914
node.appendStringChild(env.gpa, "TODO implement toSExpr for hosted module header");
19261915
return node;
19271916
},
19281917
.malformed => |a| {
19291918
var node = sexpr.Expr.init(env.gpa, "malformed_header");
1930-
1931-
// TODO add region to malformed header
1932-
// node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
1933-
1919+
node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
19341920
node.appendStringChild(env.gpa, @tagName(a.reason));
19351921
return node;
19361922
},
@@ -2029,6 +2015,7 @@ pub const NodeStore = struct {
20292015
},
20302016
malformed: struct {
20312017
reason: Diagnostic.Tag,
2018+
region: Region,
20322019
},
20332020

20342021
pub const Import = struct {
@@ -2043,69 +2030,61 @@ pub const NodeStore = struct {
20432030
switch (self) {
20442031
.decl => |decl| {
20452032
var node = sexpr.Expr.init(env.gpa, "decl");
2046-
20472033
node.appendRegionChild(env.gpa, ir.regionInfo(decl.region, line_starts));
2048-
2049-
const pattern = ir.store.getPattern(decl.pattern);
2050-
const body = ir.store.getExpr(decl.body);
2051-
2052-
var pattern_node = pattern.toSExpr(env, ir, line_starts);
2053-
var body_node = body.toSExpr(env, ir, line_starts);
2054-
2055-
node.appendNodeChild(env.gpa, &pattern_node);
2056-
node.appendNodeChild(env.gpa, &body_node);
2057-
2034+
// pattern
2035+
{
2036+
const pattern = ir.store.getPattern(decl.pattern);
2037+
var pattern_node = pattern.toSExpr(env, ir, line_starts);
2038+
node.appendNodeChild(env.gpa, &pattern_node);
2039+
}
2040+
// body
2041+
{
2042+
const body = ir.store.getExpr(decl.body);
2043+
var body_node = body.toSExpr(env, ir, line_starts);
2044+
node.appendNodeChild(env.gpa, &body_node);
2045+
}
20582046
return node;
20592047
},
20602048
.expr => |expr| {
20612049
return ir.store.getExpr(expr.expr).toSExpr(env, ir, line_starts);
20622050
},
20632051
.import => |import| {
20642052
var node = sexpr.Expr.init(env.gpa, "import");
2065-
20662053
node.appendRegionChild(env.gpa, ir.regionInfo(import.region, line_starts));
2067-
2068-
// Module Qualifier e.g. `pf` in `import pf.Stdout`
2069-
node.appendStringChild(
2070-
env.gpa,
2071-
if (import.qualifier_tok) |tok| ir.resolve(tok) else "",
2072-
);
2073-
2074-
// Module Name e.g. `Stdout` in `import pf.Stdout`
2075-
node.appendStringChild(
2076-
env.gpa,
2077-
ir.resolve(import.module_name_tok),
2078-
);
2079-
2080-
// Module Alias e.g. `OUT` in `import pf.Stdout as OUT`
2081-
node.appendStringChild(
2082-
env.gpa,
2083-
if (import.alias_tok) |tok| ir.resolve(tok) else "",
2084-
);
2085-
2086-
// Each exposed identifier e.g. [foo, bar] in `import pf.Stdout exposing [foo, bar]`
2054+
// name e.g. `Stdout` in `import pf.Stdout`
2055+
node.appendStringChild(env.gpa, ir.resolve(import.module_name_tok));
2056+
// qualifier e.g. `pf` in `import pf.Stdout`
2057+
if (import.qualifier_tok) |tok| {
2058+
const qualifier_str = ir.resolve(tok);
2059+
var child = sexpr.Expr.init(env.gpa, "qualifier");
2060+
child.appendStringChild(env.gpa, qualifier_str);
2061+
node.appendNodeChild(env.gpa, &child);
2062+
}
2063+
// alias e.g. `OUT` in `import pf.Stdout as OUT`
2064+
if (import.alias_tok) |tok| {
2065+
const qualifier_str = ir.resolve(tok);
2066+
var child = sexpr.Expr.init(env.gpa, "alias");
2067+
child.appendStringChild(env.gpa, qualifier_str);
2068+
node.appendNodeChild(env.gpa, &child);
2069+
}
2070+
// exposed identifiers e.g. [foo, bar] in `import pf.Stdout exposing [foo, bar]`
20872071
const exposed_slice = ir.store.exposedItemSlice(import.exposes);
20882072
if (exposed_slice.len > 0) {
20892073
var exposed = sexpr.Expr.init(env.gpa, "exposing");
2090-
20912074
for (ir.store.exposedItemSlice(import.exposes)) |e| {
20922075
var exposed_item = &ir.store.getExposedItem(e);
20932076
var exposed_item_sexpr = exposed_item.toSExpr(env, ir, line_starts);
20942077
exposed.appendNodeChild(env.gpa, &exposed_item_sexpr);
20952078
}
20962079
node.appendNodeChild(env.gpa, &exposed);
20972080
}
2098-
20992081
return node;
21002082
},
21012083
// (type_decl (header <name> [<args>]) <annotation>)
21022084
.type_decl => |a| {
21032085
var node = sexpr.Expr.init(env.gpa, "type_decl");
2104-
21052086
node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
2106-
21072087
var header = sexpr.Expr.init(env.gpa, "header");
2108-
21092088
// pattern
21102089
{
21112090
const ty_header = ir.store.getTypeHeader(a.header);
@@ -2123,7 +2102,6 @@ pub const NodeStore = struct {
21232102
var annotation = ir.store.getTypeAnno(a.anno).toSExpr(env, ir, line_starts);
21242103
node.appendNodeChild(env.gpa, &annotation);
21252104
}
2126-
21272105
return node;
21282106
},
21292107
// (crash <expr>)
@@ -2167,8 +2145,11 @@ pub const NodeStore = struct {
21672145
node.appendNodeChild(env.gpa, &child);
21682146
return node;
21692147
},
2170-
else => {
2171-
std.debug.panic("implement toSExpr for Statement: {}", .{self});
2148+
.malformed => |a| {
2149+
var node = sexpr.Expr.init(env.gpa, "malformed_stmt");
2150+
node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
2151+
node.appendStringChild(env.gpa, @tagName(a.reason));
2152+
return node;
21722153
},
21732154
}
21742155
}
@@ -2217,6 +2198,7 @@ pub const NodeStore = struct {
22172198
},
22182199
malformed: struct {
22192200
reason: Diagnostic.Tag,
2201+
region: Region,
22202202
},
22212203

22222204
const TagUnionRhs = packed struct { open: u1, tags_len: u31 };
@@ -2306,10 +2288,7 @@ pub const NodeStore = struct {
23062288
},
23072289
.malformed => |a| {
23082290
var node = sexpr.Expr.init(env.gpa, "malformed_expr");
2309-
2310-
// TODO add region to malformed type anno
2311-
// node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
2312-
2291+
node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
23132292
node.appendStringChild(env.gpa, @tagName(a.reason));
23142293
return node;
23152294
},
@@ -2368,6 +2347,7 @@ pub const NodeStore = struct {
23682347
},
23692348
malformed: struct {
23702349
reason: Diagnostic.Tag,
2350+
region: Region,
23712351
},
23722352

23732353
pub fn toSExpr(self: @This(), env: *base.ModuleEnv, ir: *IR, line_starts: std.ArrayList(u32)) sexpr.Expr {
@@ -2418,10 +2398,7 @@ pub const NodeStore = struct {
24182398
},
24192399
.malformed => |a| {
24202400
var node = sexpr.Expr.init(env.gpa, "malformed_pattern");
2421-
2422-
// TODO add region to malformed pattern
2423-
// node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
2424-
2401+
node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
24252402
node.appendStringChild(env.gpa, @tagName(a.reason));
24262403
return node;
24272404
},
@@ -2513,6 +2490,7 @@ pub const NodeStore = struct {
25132490
block: Body,
25142491
malformed: struct {
25152492
reason: Diagnostic.Tag,
2493+
region: Region,
25162494
},
25172495

25182496
pub fn as_string_part_region(self: @This()) !Region {
@@ -2541,9 +2519,10 @@ pub const NodeStore = struct {
25412519
return node;
25422520
},
25432521
.string_part => |sp| {
2544-
const text = ir.resolve(sp.token);
2545-
const owned_str: []u8 = env.gpa.dupe(u8, text) catch |err| exitOnOom(err);
2546-
return sexpr.Expr{ .string = owned_str };
2522+
var node = sexpr.Expr.init(env.gpa, "string_part");
2523+
node.appendRegionChild(env.gpa, ir.regionInfo(sp.region, line_starts));
2524+
node.appendStringChild(env.gpa, ir.resolve(sp.token));
2525+
return node;
25472526
},
25482527
// (tag <tag>)
25492528
.tag => |tag| {
@@ -2597,10 +2576,7 @@ pub const NodeStore = struct {
25972576
// (malformed_expr <reason>)
25982577
.malformed => |a| {
25992578
var node = sexpr.Expr.init(env.gpa, "malformed_expr");
2600-
2601-
// TODO add region to malformed expression
2602-
// node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
2603-
2579+
node.appendRegionChild(env.gpa, ir.regionInfo(a.region, line_starts));
26042580
node.appendStringChild(env.gpa, @tagName(a.reason));
26052581
return node;
26062582
},

0 commit comments

Comments
 (0)