Skip to content

Commit 13c5152

Browse files
Merge pull request #7672 from roc-lang/fuzz-fixes
Parsing Fuzzer Fixes
2 parents 2484c34 + fefd3a8 commit 13c5152

34 files changed

+1165
-328
lines changed

crates/compiler/builtins/bitcode/build.zig

+3-3
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,9 @@ fn generateObjectFile(
119119

120120
const suffix =
121121
if (target.result.os.tag == std.Target.Os.Tag.windows)
122-
"obj"
123-
else
124-
"o";
122+
"obj"
123+
else
124+
"o";
125125
const install = b.addInstallFile(obj_file, b.fmt("{s}.{s}", .{ object_name, suffix }));
126126

127127
const obj_step = b.step(step_name, "Build object file for linking");

src/base/sexpr.zig

+2-2
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ pub const Expr = union(enum) {
129129

130130
try writer.print(")", .{});
131131
},
132-
.string => |s| try writer.print("'{s}'", .{s}),
132+
.string => |s| try writer.print("\"{s}\"", .{s}),
133133
.signed_int => |i| try writer.print("{d}", .{i}),
134134
.unsigned_int => |u| try writer.print("{d}", .{u}),
135135
.float => |f| try writer.print("{any}", .{f}),
@@ -191,7 +191,7 @@ test "s-expression" {
191191
foo.toStringPretty(buf.writer().any());
192192
const expected =
193193
\\(foo
194-
\\ 'bar'
194+
\\ "bar"
195195
\\ -123
196196
\\ (baz 456 7.89e2))
197197
;

src/check/parse.zig

+6-105
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,19 @@ pub fn parse(env: *base.ModuleEnv, source: []const u8) IR {
2222
tokenizer.tokenize();
2323
const result = tokenizer.finishAndDeinit();
2424

25-
if (result.messages.len > 0) {
26-
tokenizeReport(env.gpa, source, result.messages);
25+
for (result.messages) |msg| {
26+
_ = env.problems.append(env.gpa, .{ .tokenize = msg });
2727
}
2828

2929
var parser = Parser.init(result.tokens);
3030
defer parser.deinit();
3131

3232
parser.parseFile();
3333

34+
for (parser.diagnostics.items) |msg| {
35+
_ = env.problems.append(env.gpa, .{ .parser = msg });
36+
}
37+
3438
const errors = parser.diagnostics.toOwnedSlice(env.gpa) catch |err| exitOnOom(err);
3539

3640
return .{
@@ -40,106 +44,3 @@ pub fn parse(env: *base.ModuleEnv, source: []const u8) IR {
4044
.errors = errors,
4145
};
4246
}
43-
44-
fn lineNum(newlines: std.ArrayList(usize), pos: u32) u32 {
45-
const pos_usize = @as(usize, @intCast(pos));
46-
var lineno: u32 = 0;
47-
while (lineno < newlines.items.len) {
48-
if (newlines.items[lineno + 1] > pos_usize) {
49-
return lineno;
50-
}
51-
lineno += 1;
52-
}
53-
return lineno;
54-
}
55-
56-
fn tokenizeReport(allocator: std.mem.Allocator, source: []const u8, msgs: []const tokenize.Diagnostic) void {
57-
std.debug.print("Found the {d} following issues while tokenizing:\n", .{msgs.len});
58-
var newlines = std.ArrayList(usize).init(allocator);
59-
defer newlines.deinit();
60-
newlines.append(0) catch |err| exitOnOom(err);
61-
var pos: usize = 0;
62-
for (source) |c| {
63-
if (c == '\n') {
64-
newlines.append(pos) catch |err| exitOnOom(err);
65-
}
66-
pos += 1;
67-
}
68-
for (msgs) |message| {
69-
switch (message.tag) {
70-
.MismatchedBrace => {
71-
const start_line_num = lineNum(newlines, message.begin);
72-
const start_col = message.begin - newlines.items[start_line_num];
73-
const end_line_num = lineNum(newlines, message.end);
74-
const end_col = message.end - newlines.items[end_line_num];
75-
76-
const src = source[newlines.items[start_line_num]..newlines.items[end_line_num + 1]];
77-
var spaces = std.ArrayList(u8).init(allocator);
78-
defer spaces.deinit();
79-
for (0..start_col) |_| {
80-
spaces.append(' ') catch |err| exitOnOom(err);
81-
}
82-
83-
std.debug.print(
84-
"({d}:{d}-{d}:{d}) Expected the correct closing brace here:\n{s}\n{s}^\n",
85-
.{ start_line_num, start_col, end_line_num, end_col, src, spaces.toOwnedSlice() catch |err| exitOnOom(err) },
86-
);
87-
},
88-
else => {
89-
std.debug.print("MSG: {any}\n", .{message});
90-
},
91-
}
92-
}
93-
}
94-
95-
// TODO move this somewhere better, for now it's here to keep it simple.
96-
fn testSExprHelper(source: []const u8, expected: []const u8) !void {
97-
var env = base.ModuleEnv.init(testing.allocator);
98-
defer env.deinit();
99-
100-
// parse our source
101-
var parse_ast = parse(&env, source);
102-
defer parse_ast.deinit();
103-
std.testing.expectEqualSlices(IR.Diagnostic, &[_]IR.Diagnostic{}, parse_ast.errors) catch {
104-
std.debug.print("Tokens:\n{any}", .{parse_ast.tokens.tokens.items(.tag)});
105-
std.debug.panic("Test failed with parse errors", .{});
106-
};
107-
108-
// shouldn't be required in future
109-
parse_ast.store.emptyScratch();
110-
111-
// buffer to write our SExpr to
112-
var buf = std.ArrayList(u8).init(testing.allocator);
113-
defer buf.deinit();
114-
115-
// convert the AST to our SExpr
116-
try parse_ast.toSExprStr(&env, buf.writer().any());
117-
118-
// TODO in future we should just write the SExpr to a file and snapshot it
119-
// for now we are comparing strings to keep it simple
120-
try testing.expectEqualStrings(expected, buf.items[0..]);
121-
}
122-
123-
test "example s-expr" {
124-
const source =
125-
\\module [foo, bar]
126-
\\
127-
\\foo = "hey"
128-
\\bar = "yo"
129-
;
130-
131-
const expected =
132-
\\(file
133-
\\ (header
134-
\\ (exposed_item (lower_ident 'foo'))
135-
\\ (exposed_item (lower_ident 'bar')))
136-
\\ (decl
137-
\\ (ident 'foo')
138-
\\ (string 'hey'))
139-
\\ (decl
140-
\\ (ident 'bar')
141-
\\ (string 'yo')))
142-
;
143-
144-
try testSExprHelper(source, expected);
145-
}

0 commit comments

Comments
 (0)