authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-26 15:40:29-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-26 15:43:36-04:00
log28071ac637a73fea7db89cf9c041ca349554a437
tree61c4e48014809508763864f0805d0c1091f84f96
parentc82acdbb9ed65f3443544fe2be9bd12c9a7686d9
signaturelock-open Commit is signed but in an unrecognized format.

self-hosted translate-c emits a hello world AST

Also breaking std lib API change: the return value of std.zig.parse returns `*ast.Tree` rather than `ast.Tree`. See #1964

9 files changed, 230 insertions(+), 181 deletions(-)

src-self-hosted/compilation.zig+4-6
...@@ -569,9 +569,9 @@ pub const Compilation = struct {...@@ -569,9 +569,9 @@ pub const Compilation = struct {
569 'i', 'u' => blk: {569 'i', 'u' => blk: {
570 for (name[1..]) |byte|570 for (name[1..]) |byte|
571 switch (byte) {571 switch (byte) {
572 '0'...'9' => {},572 '0'...'9' => {},
573 else => break :blk,573 else => break :blk,
574 };574 };
575 const is_signed = name[0] == 'i';575 const is_signed = name[0] == 'i';
576 const bit_count = std.fmt.parseUnsigned(u32, name[1..], 10) catch |err| switch (err) {576 const bit_count = std.fmt.parseUnsigned(u32, name[1..], 10) catch |err| switch (err) {
577 error.Overflow => return error.Overflow,577 error.Overflow => return error.Overflow,
...@@ -841,11 +841,9 @@ pub const Compilation = struct {...@@ -841,11 +841,9 @@ pub const Compilation = struct {
841 };841 };
842 errdefer self.gpa().free(source_code);842 errdefer self.gpa().free(source_code);
843843
844 const tree = try self.gpa().create(ast.Tree);844 const tree = try std.zig.parse(self.gpa(), source_code);
845 tree.* = try std.zig.parse(self.gpa(), source_code);
846 errdefer {845 errdefer {
847 tree.deinit();846 tree.deinit();
848 self.gpa().destroy(tree);
849 }847 }
850848
851 break :blk try Scope.AstTree.create(self, tree, root_scope);849 break :blk try Scope.AstTree.create(self, tree, root_scope);
src-self-hosted/main.zig+8-8
...@@ -625,7 +625,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {...@@ -625,7 +625,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
625 const source_code = try stdin.stream.readAllAlloc(allocator, max_src_size);625 const source_code = try stdin.stream.readAllAlloc(allocator, max_src_size);
626 defer allocator.free(source_code);626 defer allocator.free(source_code);
627627
628 var tree = std.zig.parse(allocator, source_code) catch |err| {628 const tree = std.zig.parse(allocator, source_code) catch |err| {
629 try stderr.print("error parsing stdin: {}\n", err);629 try stderr.print("error parsing stdin: {}\n", err);
630 os.exit(1);630 os.exit(1);
631 };631 };
...@@ -633,7 +633,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {...@@ -633,7 +633,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
633633
634 var error_it = tree.errors.iterator(0);634 var error_it = tree.errors.iterator(0);
635 while (error_it.next()) |parse_error| {635 while (error_it.next()) |parse_error| {
636 const msg = try errmsg.Msg.createFromParseError(allocator, parse_error, &tree, "<stdin>");636 const msg = try errmsg.Msg.createFromParseError(allocator, parse_error, tree, "<stdin>");
637 defer msg.destroy();637 defer msg.destroy();
638638
639 try msg.printToFile(stderr_file, color);639 try msg.printToFile(stderr_file, color);
...@@ -642,12 +642,12 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {...@@ -642,12 +642,12 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
642 os.exit(1);642 os.exit(1);
643 }643 }
644 if (flags.present("check")) {644 if (flags.present("check")) {
645 const anything_changed = try std.zig.render(allocator, io.null_out_stream, &tree);645 const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
646 const code = if (anything_changed) u8(1) else u8(0);646 const code = if (anything_changed) u8(1) else u8(0);
647 os.exit(code);647 os.exit(code);
648 }648 }
649649
650 _ = try std.zig.render(allocator, stdout, &tree);650 _ = try std.zig.render(allocator, stdout, tree);
651 return;651 return;
652 }652 }
653653
...@@ -768,7 +768,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro...@@ -768,7 +768,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
768 };768 };
769 defer fmt.loop.allocator.free(source_code);769 defer fmt.loop.allocator.free(source_code);
770770
771 var tree = std.zig.parse(fmt.loop.allocator, source_code) catch |err| {771 const tree = std.zig.parse(fmt.loop.allocator, source_code) catch |err| {
772 try stderr.print("error parsing file '{}': {}\n", file_path, err);772 try stderr.print("error parsing file '{}': {}\n", file_path, err);
773 fmt.any_error = true;773 fmt.any_error = true;
774 return;774 return;
...@@ -777,7 +777,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro...@@ -777,7 +777,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
777777
778 var error_it = tree.errors.iterator(0);778 var error_it = tree.errors.iterator(0);
779 while (error_it.next()) |parse_error| {779 while (error_it.next()) |parse_error| {
780 const msg = try errmsg.Msg.createFromParseError(fmt.loop.allocator, parse_error, &tree, file_path);780 const msg = try errmsg.Msg.createFromParseError(fmt.loop.allocator, parse_error, tree, file_path);
781 defer fmt.loop.allocator.destroy(msg);781 defer fmt.loop.allocator.destroy(msg);
782782
783 try msg.printToFile(stderr_file, fmt.color);783 try msg.printToFile(stderr_file, fmt.color);
...@@ -788,7 +788,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro...@@ -788,7 +788,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
788 }788 }
789789
790 if (check_mode) {790 if (check_mode) {
791 const anything_changed = try std.zig.render(fmt.loop.allocator, io.null_out_stream, &tree);791 const anything_changed = try std.zig.render(fmt.loop.allocator, io.null_out_stream, tree);
792 if (anything_changed) {792 if (anything_changed) {
793 try stderr.print("{}\n", file_path);793 try stderr.print("{}\n", file_path);
794 fmt.any_error = true;794 fmt.any_error = true;
...@@ -798,7 +798,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro...@@ -798,7 +798,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
798 const baf = try io.BufferedAtomicFile.create(fmt.loop.allocator, file_path);798 const baf = try io.BufferedAtomicFile.create(fmt.loop.allocator, file_path);
799 defer baf.destroy();799 defer baf.destroy();
800800
801 const anything_changed = try std.zig.render(fmt.loop.allocator, baf.stream(), &tree);801 const anything_changed = try std.zig.render(fmt.loop.allocator, baf.stream(), tree);
802 if (anything_changed) {802 if (anything_changed) {
803 try stderr.print("{}\n", file_path);803 try stderr.print("{}\n", file_path);
804 try baf.finish();804 try baf.finish();
src-self-hosted/scope.zig-1
...@@ -163,7 +163,6 @@ pub const Scope = struct {...@@ -163,7 +163,6 @@ pub const Scope = struct {
163 pub fn destroy(self: *AstTree, comp: *Compilation) void {163 pub fn destroy(self: *AstTree, comp: *Compilation) void {
164 comp.gpa().free(self.tree.source);164 comp.gpa().free(self.tree.source);
165 self.tree.deinit();165 self.tree.deinit();
166 comp.gpa().destroy(self.tree);
167 comp.gpa().destroy(self);166 comp.gpa().destroy(self);
168 }167 }
169168
src-self-hosted/stage1.zig+1-2
...@@ -85,11 +85,10 @@ export fn stage2_translate_c(...@@ -85,11 +85,10 @@ export fn stage2_translate_c(
85 resources_path: [*]const u8,85 resources_path: [*]const u8,
86) Error {86) Error {
87 var errors: []translate_c.ClangErrMsg = undefined;87 var errors: []translate_c.ClangErrMsg = undefined;
88 out_ast.* = translate_c.translate(args_begin, args_end, switch (mode) {88 out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, switch (mode) {
89 .import => translate_c.Mode.import,89 .import => translate_c.Mode.import,
90 .translate => translate_c.Mode.translate,90 .translate => translate_c.Mode.translate,
91 }, &errors, resources_path) catch |err| switch (err) {91 }, &errors, resources_path) catch |err| switch (err) {
92 error.Unimplemented => return Error.Unimplemented,
93 error.SemanticAnalyzeFail => {92 error.SemanticAnalyzeFail => {
94 out_errors_ptr.* = errors.ptr;93 out_errors_ptr.* = errors.ptr;
95 out_errors_len.* = errors.len;94 out_errors_len.* = errors.len;
src-self-hosted/translate_c.zig+44-1
...@@ -3,6 +3,7 @@...@@ -3,6 +3,7 @@
33
4const std = @import("std");4const std = @import("std");
5const ast = std.zig.ast;5const ast = std.zig.ast;
6const Token = std.zig.Token;
6use @import("clang.zig");7use @import("clang.zig");
78
8pub const Mode = enum {9pub const Mode = enum {
...@@ -13,6 +14,7 @@ pub const Mode = enum {...@@ -13,6 +14,7 @@ pub const Mode = enum {
13pub const ClangErrMsg = Stage2ErrorMsg;14pub const ClangErrMsg = Stage2ErrorMsg;
1415
15pub fn translate(16pub fn translate(
17 backing_allocator: *std.mem.Allocator,
16 args_begin: [*]?[*]const u8,18 args_begin: [*]?[*]const u8,
17 args_end: [*]?[*]const u8,19 args_end: [*]?[*]const u8,
18 mode: Mode,20 mode: Mode,
...@@ -29,8 +31,49 @@ pub fn translate(...@@ -29,8 +31,49 @@ pub fn translate(
29 if (errors.len == 0) return error.OutOfMemory;31 if (errors.len == 0) return error.OutOfMemory;
30 return error.SemanticAnalyzeFail;32 return error.SemanticAnalyzeFail;
31 };33 };
34 defer ZigClangASTUnit_delete(ast_unit);
3235
33 return error.Unimplemented;36 var tree_arena = std.heap.ArenaAllocator.init(backing_allocator);
37 errdefer tree_arena.deinit();
38 const arena = &tree_arena.allocator;
39
40 const root_node = try arena.create(ast.Node.Root);
41 root_node.* = ast.Node.Root{
42 .base = ast.Node{ .id = ast.Node.Id.Root },
43 .decls = ast.Node.Root.DeclList.init(arena),
44 .doc_comments = null,
45 // initialized with the eof token at the end
46 .eof_token = undefined,
47 };
48
49 const tree = try arena.create(ast.Tree);
50 tree.* = ast.Tree{
51 .source = undefined, // need to use Buffer.toOwnedSlice later
52 .root_node = root_node,
53 .arena_allocator = tree_arena,
54 .tokens = ast.Tree.TokenList.init(arena),
55 .errors = ast.Tree.ErrorList.init(arena),
56 };
57
58 var source_buffer = try std.Buffer.initSize(arena, 0);
59
60 try appendToken(tree, &source_buffer, "// TODO: implement more than just an empty source file", .LineComment);
61
62 try appendToken(tree, &source_buffer, "", .Eof);
63 tree.source = source_buffer.toOwnedSlice();
64 return tree;
65}
66
67fn appendToken(tree: *ast.Tree, source_buffer: *std.Buffer, src_text: []const u8, token_id: Token.Id) !void {
68 const start_index = source_buffer.len();
69 try source_buffer.append(src_text);
70 const end_index = source_buffer.len();
71 const new_token = try tree.tokens.addOne();
72 new_token.* = Token{
73 .id = token_id,
74 .start = start_index,
75 .end = end_index,
76 };
34}77}
3578
36pub fn freeErrors(errors: []ClangErrMsg) void {79pub fn freeErrors(errors: []ClangErrMsg) void {
std/special/fmt_runner.zig+16-11
...@@ -71,7 +71,7 @@ pub fn main() !void {...@@ -71,7 +71,7 @@ pub fn main() !void {
71 const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size);71 const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size);
72 defer allocator.free(source_code);72 defer allocator.free(source_code);
7373
74 var tree = std.zig.parse(allocator, source_code) catch |err| {74 const tree = std.zig.parse(allocator, source_code) catch |err| {
75 try stderr.print("error parsing stdin: {}\n", err);75 try stderr.print("error parsing stdin: {}\n", err);
76 os.exit(1);76 os.exit(1);
77 };77 };
...@@ -79,18 +79,18 @@ pub fn main() !void {...@@ -79,18 +79,18 @@ pub fn main() !void {
7979
80 var error_it = tree.errors.iterator(0);80 var error_it = tree.errors.iterator(0);
81 while (error_it.next()) |parse_error| {81 while (error_it.next()) |parse_error| {
82 try printErrMsgToFile(allocator, parse_error, &tree, "<stdin>", stderr_file, color);82 try printErrMsgToFile(allocator, parse_error, tree, "<stdin>", stderr_file, color);
83 }83 }
84 if (tree.errors.len != 0) {84 if (tree.errors.len != 0) {
85 os.exit(1);85 os.exit(1);
86 }86 }
87 if (flags.present("check")) {87 if (flags.present("check")) {
88 const anything_changed = try std.zig.render(allocator, io.null_out_stream, &tree);88 const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
89 const code = if (anything_changed) u8(1) else u8(0);89 const code = if (anything_changed) u8(1) else u8(0);
90 os.exit(code);90 os.exit(code);
91 }91 }
9292
93 _ = try std.zig.render(allocator, stdout, &tree);93 _ = try std.zig.render(allocator, stdout, tree);
94 return;94 return;
95 }95 }
9696
...@@ -166,7 +166,7 @@ fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void...@@ -166,7 +166,7 @@ fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void
166 };166 };
167 defer fmt.allocator.free(source_code);167 defer fmt.allocator.free(source_code);
168168
169 var tree = std.zig.parse(fmt.allocator, source_code) catch |err| {169 const tree = std.zig.parse(fmt.allocator, source_code) catch |err| {
170 try stderr.print("error parsing file '{}': {}\n", file_path, err);170 try stderr.print("error parsing file '{}': {}\n", file_path, err);
171 fmt.any_error = true;171 fmt.any_error = true;
172 return;172 return;
...@@ -175,7 +175,7 @@ fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void...@@ -175,7 +175,7 @@ fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void
175175
176 var error_it = tree.errors.iterator(0);176 var error_it = tree.errors.iterator(0);
177 while (error_it.next()) |parse_error| {177 while (error_it.next()) |parse_error| {
178 try printErrMsgToFile(fmt.allocator, parse_error, &tree, file_path, stderr_file, fmt.color);178 try printErrMsgToFile(fmt.allocator, parse_error, tree, file_path, stderr_file, fmt.color);
179 }179 }
180 if (tree.errors.len != 0) {180 if (tree.errors.len != 0) {
181 fmt.any_error = true;181 fmt.any_error = true;
...@@ -183,7 +183,7 @@ fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void...@@ -183,7 +183,7 @@ fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void
183 }183 }
184184
185 if (check_mode) {185 if (check_mode) {
186 const anything_changed = try std.zig.render(fmt.allocator, io.null_out_stream, &tree);186 const anything_changed = try std.zig.render(fmt.allocator, io.null_out_stream, tree);
187 if (anything_changed) {187 if (anything_changed) {
188 try stderr.print("{}\n", file_path);188 try stderr.print("{}\n", file_path);
189 fmt.any_error = true;189 fmt.any_error = true;
...@@ -193,7 +193,7 @@ fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void...@@ -193,7 +193,7 @@ fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void
193 const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path);193 const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path);
194 defer baf.destroy();194 defer baf.destroy();
195195
196 const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), &tree);196 const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree);
197 if (anything_changed) {197 if (anything_changed) {
198 try stderr.print("{}\n", file_path);198 try stderr.print("{}\n", file_path);
199 try baf.finish();199 try baf.finish();
...@@ -210,9 +210,14 @@ const Fmt = struct {...@@ -210,9 +210,14 @@ const Fmt = struct {
210 const SeenMap = std.HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8);210 const SeenMap = std.HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8);
211};211};
212212
213fn printErrMsgToFile(allocator: *mem.Allocator, parse_error: *const ast.Error, tree: *ast.Tree,213fn printErrMsgToFile(
214 path: []const u8, file: os.File, color: errmsg.Color,) !void214 allocator: *mem.Allocator,
215{215 parse_error: *const ast.Error,
216 tree: *ast.Tree,
217 path: []const u8,
218 file: os.File,
219 color: errmsg.Color,
220) !void {
216 const color_on = switch (color) {221 const color_on = switch (color) {
217 errmsg.Color.Auto => file.isTty(),222 errmsg.Color.Auto => file.isTty(),
218 errmsg.Color.On => true,223 errmsg.Color.On => true,
std/zig/ast.zig+5-1
...@@ -18,7 +18,11 @@ pub const Tree = struct {...@@ -18,7 +18,11 @@ pub const Tree = struct {
18 pub const ErrorList = SegmentedList(Error, 0);18 pub const ErrorList = SegmentedList(Error, 0);
1919
20 pub fn deinit(self: *Tree) void {20 pub fn deinit(self: *Tree) void {
21 self.arena_allocator.deinit();21 // Here we copy the arena allocator into stack memory, because
22 // otherwise it would destroy itself while it was still working.
23 var arena_allocator = self.arena_allocator;
24 arena_allocator.deinit();
25 // self is destroyed
22 }26 }
2327
24 pub fn renderError(self: *Tree, parse_error: *Error, stream: var) !void {28 pub fn renderError(self: *Tree, parse_error: *Error, stream: var) !void {
std/zig/parse.zig+150-149
...@@ -9,7 +9,7 @@ const Error = ast.Error;...@@ -9,7 +9,7 @@ const Error = ast.Error;
99
10/// Result should be freed with tree.deinit() when there are10/// Result should be freed with tree.deinit() when there are
11/// no more references to any of the tokens or nodes.11/// no more references to any of the tokens or nodes.
12pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {12pub fn parse(allocator: *mem.Allocator, source: []const u8) !*ast.Tree {
13 var tree_arena = std.heap.ArenaAllocator.init(allocator);13 var tree_arena = std.heap.ArenaAllocator.init(allocator);
14 errdefer tree_arena.deinit();14 errdefer tree_arena.deinit();
1515
...@@ -26,7 +26,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -26,7 +26,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
26 .eof_token = undefined,26 .eof_token = undefined,
27 };27 };
2828
29 var tree = ast.Tree{29 const tree = try arena.create(ast.Tree);
30 tree.* = ast.Tree{
30 .source = source,31 .source = source,
31 .root_node = root_node,32 .root_node = root_node,
32 .arena_allocator = tree_arena,33 .arena_allocator = tree_arena,
...@@ -57,9 +58,9 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -57,9 +58,9 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
5758
58 switch (state) {59 switch (state) {
59 State.TopLevel => {60 State.TopLevel => {
60 const comments = try eatDocComments(arena, &tok_it, &tree);61 const comments = try eatDocComments(arena, &tok_it, tree);
6162
62 const token = nextToken(&tok_it, &tree);63 const token = nextToken(&tok_it, tree);
63 const token_index = token.index;64 const token_index = token.index;
64 const token_ptr = token.ptr;65 const token_ptr = token.ptr;
65 switch (token_ptr.id) {66 switch (token_ptr.id) {
...@@ -140,7 +141,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -140,7 +141,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
140 continue;141 continue;
141 },142 },
142 else => {143 else => {
143 prevToken(&tok_it, &tree);144 prevToken(&tok_it, tree);
144 stack.append(State.TopLevel) catch unreachable;145 stack.append(State.TopLevel) catch unreachable;
145 try stack.append(State{146 try stack.append(State{
146 .TopLevelExtern = TopLevelDeclCtx{147 .TopLevelExtern = TopLevelDeclCtx{
...@@ -156,7 +157,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -156,7 +157,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
156 }157 }
157 },158 },
158 State.TopLevelExtern => |ctx| {159 State.TopLevelExtern => |ctx| {
159 const token = nextToken(&tok_it, &tree);160 const token = nextToken(&tok_it, tree);
160 const token_index = token.index;161 const token_index = token.index;
161 const token_ptr = token.ptr;162 const token_ptr = token.ptr;
162 switch (token_ptr.id) {163 switch (token_ptr.id) {
...@@ -191,7 +192,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -191,7 +192,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
191 continue;192 continue;
192 },193 },
193 else => {194 else => {
194 prevToken(&tok_it, &tree);195 prevToken(&tok_it, tree);
195 stack.append(State{ .TopLevelDecl = ctx }) catch unreachable;196 stack.append(State{ .TopLevelDecl = ctx }) catch unreachable;
196 continue;197 continue;
197 },198 },
...@@ -199,11 +200,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -199,11 +200,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
199 },200 },
200 State.TopLevelLibname => |ctx| {201 State.TopLevelLibname => |ctx| {
201 const lib_name = blk: {202 const lib_name = blk: {
202 const lib_name_token = nextToken(&tok_it, &tree);203 const lib_name_token = nextToken(&tok_it, tree);
203 const lib_name_token_index = lib_name_token.index;204 const lib_name_token_index = lib_name_token.index;
204 const lib_name_token_ptr = lib_name_token.ptr;205 const lib_name_token_ptr = lib_name_token.ptr;
205 break :blk (try parseStringLiteral(arena, &tok_it, lib_name_token_ptr, lib_name_token_index, &tree)) orelse {206 break :blk (try parseStringLiteral(arena, &tok_it, lib_name_token_ptr, lib_name_token_index, tree)) orelse {
206 prevToken(&tok_it, &tree);207 prevToken(&tok_it, tree);
207 break :blk null;208 break :blk null;
208 };209 };
209 };210 };
...@@ -220,7 +221,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -220,7 +221,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
220 continue;221 continue;
221 },222 },
222 State.ThreadLocal => |ctx| {223 State.ThreadLocal => |ctx| {
223 const token = nextToken(&tok_it, &tree);224 const token = nextToken(&tok_it, tree);
224 const token_index = token.index;225 const token_index = token.index;
225 const token_ptr = token.ptr;226 const token_ptr = token.ptr;
226 switch (token_ptr.id) {227 switch (token_ptr.id) {
...@@ -246,7 +247,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -246,7 +247,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
246 }247 }
247 },248 },
248 State.TopLevelDecl => |ctx| {249 State.TopLevelDecl => |ctx| {
249 const token = nextToken(&tok_it, &tree);250 const token = nextToken(&tok_it, tree);
250 const token_index = token.index;251 const token_index = token.index;
251 const token_ptr = token.ptr;252 const token_ptr = token.ptr;
252 switch (token_ptr.id) {253 switch (token_ptr.id) {
...@@ -387,7 +388,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -387,7 +388,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
387 }388 }
388 },389 },
389 State.TopLevelExternOrField => |ctx| {390 State.TopLevelExternOrField => |ctx| {
390 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |identifier| {391 if (eatToken(&tok_it, tree, Token.Id.Identifier)) |identifier| {
391 const node = try arena.create(ast.Node.StructField);392 const node = try arena.create(ast.Node.StructField);
392 node.* = ast.Node.StructField{393 node.* = ast.Node.StructField{
393 .base = ast.Node{ .id = ast.Node.Id.StructField },394 .base = ast.Node{ .id = ast.Node.Id.StructField },
...@@ -424,11 +425,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -424,11 +425,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
424 },425 },
425426
426 State.FieldInitValue => |ctx| {427 State.FieldInitValue => |ctx| {
427 const eq_tok = nextToken(&tok_it, &tree);428 const eq_tok = nextToken(&tok_it, tree);
428 const eq_tok_index = eq_tok.index;429 const eq_tok_index = eq_tok.index;
429 const eq_tok_ptr = eq_tok.ptr;430 const eq_tok_ptr = eq_tok.ptr;
430 if (eq_tok_ptr.id != Token.Id.Equal) {431 if (eq_tok_ptr.id != Token.Id.Equal) {
431 prevToken(&tok_it, &tree);432 prevToken(&tok_it, tree);
432 continue;433 continue;
433 }434 }
434 stack.append(State{ .Expression = ctx }) catch unreachable;435 stack.append(State{ .Expression = ctx }) catch unreachable;
...@@ -436,7 +437,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -436,7 +437,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
436 },437 },
437438
438 State.ContainerKind => |ctx| {439 State.ContainerKind => |ctx| {
439 const token = nextToken(&tok_it, &tree);440 const token = nextToken(&tok_it, tree);
440 const token_index = token.index;441 const token_index = token.index;
441 const token_ptr = token.ptr;442 const token_ptr = token.ptr;
442 const node = try arena.create(ast.Node.ContainerDecl);443 const node = try arena.create(ast.Node.ContainerDecl);
...@@ -469,7 +470,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -469,7 +470,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
469 },470 },
470471
471 State.ContainerInitArgStart => |container_decl| {472 State.ContainerInitArgStart => |container_decl| {
472 if (eatToken(&tok_it, &tree, Token.Id.LParen) == null) {473 if (eatToken(&tok_it, tree, Token.Id.LParen) == null) {
473 continue;474 continue;
474 }475 }
475476
...@@ -479,24 +480,24 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -479,24 +480,24 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
479 },480 },
480481
481 State.ContainerInitArg => |container_decl| {482 State.ContainerInitArg => |container_decl| {
482 const init_arg_token = nextToken(&tok_it, &tree);483 const init_arg_token = nextToken(&tok_it, tree);
483 const init_arg_token_index = init_arg_token.index;484 const init_arg_token_index = init_arg_token.index;
484 const init_arg_token_ptr = init_arg_token.ptr;485 const init_arg_token_ptr = init_arg_token.ptr;
485 switch (init_arg_token_ptr.id) {486 switch (init_arg_token_ptr.id) {
486 Token.Id.Keyword_enum => {487 Token.Id.Keyword_enum => {
487 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg{ .Enum = null };488 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg{ .Enum = null };
488 const lparen_tok = nextToken(&tok_it, &tree);489 const lparen_tok = nextToken(&tok_it, tree);
489 const lparen_tok_index = lparen_tok.index;490 const lparen_tok_index = lparen_tok.index;
490 const lparen_tok_ptr = lparen_tok.ptr;491 const lparen_tok_ptr = lparen_tok.ptr;
491 if (lparen_tok_ptr.id == Token.Id.LParen) {492 if (lparen_tok_ptr.id == Token.Id.LParen) {
492 try stack.append(State{ .ExpectToken = Token.Id.RParen });493 try stack.append(State{ .ExpectToken = Token.Id.RParen });
493 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &container_decl.init_arg_expr.Enum } });494 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &container_decl.init_arg_expr.Enum } });
494 } else {495 } else {
495 prevToken(&tok_it, &tree);496 prevToken(&tok_it, tree);
496 }497 }
497 },498 },
498 else => {499 else => {
499 prevToken(&tok_it, &tree);500 prevToken(&tok_it, tree);
500 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg{ .Type = undefined };501 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg{ .Type = undefined };
501 stack.append(State{ .Expression = OptionalCtx{ .Required = &container_decl.init_arg_expr.Type } }) catch unreachable;502 stack.append(State{ .Expression = OptionalCtx{ .Required = &container_decl.init_arg_expr.Type } }) catch unreachable;
502 },503 },
...@@ -505,8 +506,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -505,8 +506,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
505 },506 },
506507
507 State.ContainerDecl => |container_decl| {508 State.ContainerDecl => |container_decl| {
508 const comments = try eatDocComments(arena, &tok_it, &tree);509 const comments = try eatDocComments(arena, &tok_it, tree);
509 const token = nextToken(&tok_it, &tree);510 const token = nextToken(&tok_it, tree);
510 const token_index = token.index;511 const token_index = token.index;
511 const token_ptr = token.ptr;512 const token_ptr = token.ptr;
512 switch (token_ptr.id) {513 switch (token_ptr.id) {
...@@ -657,7 +658,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -657,7 +658,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
657 continue;658 continue;
658 },659 },
659 else => {660 else => {
660 prevToken(&tok_it, &tree);661 prevToken(&tok_it, tree);
661 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;662 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
662 try stack.append(State{663 try stack.append(State{
663 .TopLevelExtern = TopLevelDeclCtx{664 .TopLevelExtern = TopLevelDeclCtx{
...@@ -709,7 +710,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -709,7 +710,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
709 State.VarDeclAlign => |var_decl| {710 State.VarDeclAlign => |var_decl| {
710 try stack.append(State{ .VarDeclSection = var_decl });711 try stack.append(State{ .VarDeclSection = var_decl });
711712
712 const next_token = nextToken(&tok_it, &tree);713 const next_token = nextToken(&tok_it, tree);
713 const next_token_index = next_token.index;714 const next_token_index = next_token.index;
714 const next_token_ptr = next_token.ptr;715 const next_token_ptr = next_token.ptr;
715 if (next_token_ptr.id == Token.Id.Keyword_align) {716 if (next_token_ptr.id == Token.Id.Keyword_align) {
...@@ -719,13 +720,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -719,13 +720,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
719 continue;720 continue;
720 }721 }
721722
722 prevToken(&tok_it, &tree);723 prevToken(&tok_it, tree);
723 continue;724 continue;
724 },725 },
725 State.VarDeclSection => |var_decl| {726 State.VarDeclSection => |var_decl| {
726 try stack.append(State{ .VarDeclEq = var_decl });727 try stack.append(State{ .VarDeclEq = var_decl });
727728
728 const next_token = nextToken(&tok_it, &tree);729 const next_token = nextToken(&tok_it, tree);
729 const next_token_index = next_token.index;730 const next_token_index = next_token.index;
730 const next_token_ptr = next_token.ptr;731 const next_token_ptr = next_token.ptr;
731 if (next_token_ptr.id == Token.Id.Keyword_linksection) {732 if (next_token_ptr.id == Token.Id.Keyword_linksection) {
...@@ -735,11 +736,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -735,11 +736,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
735 continue;736 continue;
736 }737 }
737738
738 prevToken(&tok_it, &tree);739 prevToken(&tok_it, tree);
739 continue;740 continue;
740 },741 },
741 State.VarDeclEq => |var_decl| {742 State.VarDeclEq => |var_decl| {
742 const token = nextToken(&tok_it, &tree);743 const token = nextToken(&tok_it, tree);
743 const token_index = token.index;744 const token_index = token.index;
744 const token_ptr = token.ptr;745 const token_ptr = token.ptr;
745 switch (token_ptr.id) {746 switch (token_ptr.id) {
...@@ -761,7 +762,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -761,7 +762,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
761 },762 },
762763
763 State.VarDeclSemiColon => |var_decl| {764 State.VarDeclSemiColon => |var_decl| {
764 const semicolon_token = nextToken(&tok_it, &tree);765 const semicolon_token = nextToken(&tok_it, tree);
765766
766 if (semicolon_token.ptr.id != Token.Id.Semicolon) {767 if (semicolon_token.ptr.id != Token.Id.Semicolon) {
767 ((try tree.errors.addOne())).* = Error{768 ((try tree.errors.addOne())).* = Error{
...@@ -775,18 +776,18 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -775,18 +776,18 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
775776
776 var_decl.semicolon_token = semicolon_token.index;777 var_decl.semicolon_token = semicolon_token.index;
777778
778 if (eatToken(&tok_it, &tree, Token.Id.DocComment)) |doc_comment_token| {779 if (eatToken(&tok_it, tree, Token.Id.DocComment)) |doc_comment_token| {
779 const loc = tree.tokenLocation(semicolon_token.ptr.end, doc_comment_token);780 const loc = tree.tokenLocation(semicolon_token.ptr.end, doc_comment_token);
780 if (loc.line == 0) {781 if (loc.line == 0) {
781 try pushDocComment(arena, doc_comment_token, &var_decl.doc_comments);782 try pushDocComment(arena, doc_comment_token, &var_decl.doc_comments);
782 } else {783 } else {
783 prevToken(&tok_it, &tree);784 prevToken(&tok_it, tree);
784 }785 }
785 }786 }
786 },787 },
787788
788 State.FnDef => |fn_proto| {789 State.FnDef => |fn_proto| {
789 const token = nextToken(&tok_it, &tree);790 const token = nextToken(&tok_it, tree);
790 const token_index = token.index;791 const token_index = token.index;
791 const token_ptr = token.ptr;792 const token_ptr = token.ptr;
792 switch (token_ptr.id) {793 switch (token_ptr.id) {
...@@ -815,7 +816,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -815,7 +816,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
815 try stack.append(State{ .ParamDecl = fn_proto });816 try stack.append(State{ .ParamDecl = fn_proto });
816 try stack.append(State{ .ExpectToken = Token.Id.LParen });817 try stack.append(State{ .ExpectToken = Token.Id.LParen });
817818
818 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |name_token| {819 if (eatToken(&tok_it, tree, Token.Id.Identifier)) |name_token| {
819 fn_proto.name_token = name_token;820 fn_proto.name_token = name_token;
820 }821 }
821 continue;822 continue;
...@@ -823,7 +824,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -823,7 +824,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
823 State.FnProtoAlign => |fn_proto| {824 State.FnProtoAlign => |fn_proto| {
824 stack.append(State{ .FnProtoSection = fn_proto }) catch unreachable;825 stack.append(State{ .FnProtoSection = fn_proto }) catch unreachable;
825826
826 if (eatToken(&tok_it, &tree, Token.Id.Keyword_align)) |align_token| {827 if (eatToken(&tok_it, tree, Token.Id.Keyword_align)) |align_token| {
827 try stack.append(State{ .ExpectToken = Token.Id.RParen });828 try stack.append(State{ .ExpectToken = Token.Id.RParen });
828 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &fn_proto.align_expr } });829 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &fn_proto.align_expr } });
829 try stack.append(State{ .ExpectToken = Token.Id.LParen });830 try stack.append(State{ .ExpectToken = Token.Id.LParen });
...@@ -833,7 +834,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -833,7 +834,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
833 State.FnProtoSection => |fn_proto| {834 State.FnProtoSection => |fn_proto| {
834 stack.append(State{ .FnProtoReturnType = fn_proto }) catch unreachable;835 stack.append(State{ .FnProtoReturnType = fn_proto }) catch unreachable;
835836
836 if (eatToken(&tok_it, &tree, Token.Id.Keyword_linksection)) |align_token| {837 if (eatToken(&tok_it, tree, Token.Id.Keyword_linksection)) |align_token| {
837 try stack.append(State{ .ExpectToken = Token.Id.RParen });838 try stack.append(State{ .ExpectToken = Token.Id.RParen });
838 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &fn_proto.section_expr } });839 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &fn_proto.section_expr } });
839 try stack.append(State{ .ExpectToken = Token.Id.LParen });840 try stack.append(State{ .ExpectToken = Token.Id.LParen });
...@@ -841,7 +842,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -841,7 +842,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
841 continue;842 continue;
842 },843 },
843 State.FnProtoReturnType => |fn_proto| {844 State.FnProtoReturnType => |fn_proto| {
844 const token = nextToken(&tok_it, &tree);845 const token = nextToken(&tok_it, tree);
845 const token_index = token.index;846 const token_index = token.index;
846 const token_ptr = token.ptr;847 const token_ptr = token.ptr;
847 switch (token_ptr.id) {848 switch (token_ptr.id) {
...@@ -864,7 +865,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -864,7 +865,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
864 }865 }
865 }866 }
866867
867 prevToken(&tok_it, &tree);868 prevToken(&tok_it, tree);
868 fn_proto.return_type = ast.Node.FnProto.ReturnType{ .Explicit = undefined };869 fn_proto.return_type = ast.Node.FnProto.ReturnType{ .Explicit = undefined };
869 stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &fn_proto.return_type.Explicit } }) catch unreachable;870 stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &fn_proto.return_type.Explicit } }) catch unreachable;
870 continue;871 continue;
...@@ -873,8 +874,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -873,8 +874,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
873 },874 },
874875
875 State.ParamDecl => |fn_proto| {876 State.ParamDecl => |fn_proto| {
876 const comments = try eatDocComments(arena, &tok_it, &tree);877 const comments = try eatDocComments(arena, &tok_it, tree);
877 if (eatToken(&tok_it, &tree, Token.Id.RParen)) |_| {878 if (eatToken(&tok_it, tree, Token.Id.RParen)) |_| {
878 continue;879 continue;
879 }880 }
880 const param_decl = try arena.create(ast.Node.ParamDecl);881 const param_decl = try arena.create(ast.Node.ParamDecl);
...@@ -900,9 +901,9 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -900,9 +901,9 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
900 continue;901 continue;
901 },902 },
902 State.ParamDeclAliasOrComptime => |param_decl| {903 State.ParamDeclAliasOrComptime => |param_decl| {
903 if (eatToken(&tok_it, &tree, Token.Id.Keyword_comptime)) |comptime_token| {904 if (eatToken(&tok_it, tree, Token.Id.Keyword_comptime)) |comptime_token| {
904 param_decl.comptime_token = comptime_token;905 param_decl.comptime_token = comptime_token;
905 } else if (eatToken(&tok_it, &tree, Token.Id.Keyword_noalias)) |noalias_token| {906 } else if (eatToken(&tok_it, tree, Token.Id.Keyword_noalias)) |noalias_token| {
906 param_decl.noalias_token = noalias_token;907 param_decl.noalias_token = noalias_token;
907 }908 }
908 continue;909 continue;
...@@ -910,20 +911,20 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -910,20 +911,20 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
910 State.ParamDeclName => |param_decl| {911 State.ParamDeclName => |param_decl| {
911 // TODO: Here, we eat two tokens in one state. This means that we can't have912 // TODO: Here, we eat two tokens in one state. This means that we can't have
912 // comments between these two tokens.913 // comments between these two tokens.
913 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |ident_token| {914 if (eatToken(&tok_it, tree, Token.Id.Identifier)) |ident_token| {
914 if (eatToken(&tok_it, &tree, Token.Id.Colon)) |_| {915 if (eatToken(&tok_it, tree, Token.Id.Colon)) |_| {
915 param_decl.name_token = ident_token;916 param_decl.name_token = ident_token;
916 } else {917 } else {
917 prevToken(&tok_it, &tree);918 prevToken(&tok_it, tree);
918 }919 }
919 }920 }
920 continue;921 continue;
921 },922 },
922 State.ParamDeclEnd => |ctx| {923 State.ParamDeclEnd => |ctx| {
923 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {924 if (eatToken(&tok_it, tree, Token.Id.Ellipsis3)) |ellipsis3| {
924 ctx.param_decl.var_args_token = ellipsis3;925 ctx.param_decl.var_args_token = ellipsis3;
925926
926 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) {927 switch (expectCommaOrEnd(&tok_it, tree, Token.Id.RParen)) {
927 ExpectCommaOrEndResult.end_token => |t| {928 ExpectCommaOrEndResult.end_token => |t| {
928 if (t == null) {929 if (t == null) {
929 stack.append(State{ .ExpectToken = Token.Id.RParen }) catch unreachable;930 stack.append(State{ .ExpectToken = Token.Id.RParen }) catch unreachable;
...@@ -943,7 +944,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -943,7 +944,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
943 continue;944 continue;
944 },945 },
945 State.ParamDeclComma => |fn_proto| {946 State.ParamDeclComma => |fn_proto| {
946 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) {947 switch (expectCommaOrEnd(&tok_it, tree, Token.Id.RParen)) {
947 ExpectCommaOrEndResult.end_token => |t| {948 ExpectCommaOrEndResult.end_token => |t| {
948 if (t == null) {949 if (t == null) {
949 stack.append(State{ .ParamDecl = fn_proto }) catch unreachable;950 stack.append(State{ .ParamDecl = fn_proto }) catch unreachable;
...@@ -958,7 +959,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -958,7 +959,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
958 },959 },
959960
960 State.MaybeLabeledExpression => |ctx| {961 State.MaybeLabeledExpression => |ctx| {
961 if (eatToken(&tok_it, &tree, Token.Id.Colon)) |_| {962 if (eatToken(&tok_it, tree, Token.Id.Colon)) |_| {
962 stack.append(State{963 stack.append(State{
963 .LabeledExpression = LabelCtx{964 .LabeledExpression = LabelCtx{
964 .label = ctx.label,965 .label = ctx.label,
...@@ -972,7 +973,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -972,7 +973,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
972 continue;973 continue;
973 },974 },
974 State.LabeledExpression => |ctx| {975 State.LabeledExpression => |ctx| {
975 const token = nextToken(&tok_it, &tree);976 const token = nextToken(&tok_it, tree);
976 const token_index = token.index;977 const token_index = token.index;
977 const token_ptr = token.ptr;978 const token_ptr = token.ptr;
978 switch (token_ptr.id) {979 switch (token_ptr.id) {
...@@ -1027,13 +1028,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1027,13 +1028,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1027 return tree;1028 return tree;
1028 }1029 }
10291030
1030 prevToken(&tok_it, &tree);1031 prevToken(&tok_it, tree);
1031 continue;1032 continue;
1032 },1033 },
1033 }1034 }
1034 },1035 },
1035 State.Inline => |ctx| {1036 State.Inline => |ctx| {
1036 const token = nextToken(&tok_it, &tree);1037 const token = nextToken(&tok_it, tree);
1037 const token_index = token.index;1038 const token_index = token.index;
1038 const token_ptr = token.ptr;1039 const token_ptr = token.ptr;
1039 switch (token_ptr.id) {1040 switch (token_ptr.id) {
...@@ -1065,7 +1066,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1065,7 +1066,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1065 return tree;1066 return tree;
1066 }1067 }
10671068
1068 prevToken(&tok_it, &tree);1069 prevToken(&tok_it, tree);
1069 continue;1070 continue;
1070 },1071 },
1071 }1072 }
...@@ -1122,7 +1123,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1122,7 +1123,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1122 continue;1123 continue;
1123 },1124 },
1124 State.Else => |dest| {1125 State.Else => |dest| {
1125 if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| {1126 if (eatToken(&tok_it, tree, Token.Id.Keyword_else)) |else_token| {
1126 const node = try arena.create(ast.Node.Else);1127 const node = try arena.create(ast.Node.Else);
1127 node.* = ast.Node.Else{1128 node.* = ast.Node.Else{
1128 .base = ast.Node{ .id = ast.Node.Id.Else },1129 .base = ast.Node{ .id = ast.Node.Id.Else },
...@@ -1141,7 +1142,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1141,7 +1142,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1141 },1142 },
11421143
1143 State.Block => |block| {1144 State.Block => |block| {
1144 const token = nextToken(&tok_it, &tree);1145 const token = nextToken(&tok_it, tree);
1145 const token_index = token.index;1146 const token_index = token.index;
1146 const token_ptr = token.ptr;1147 const token_ptr = token.ptr;
1147 switch (token_ptr.id) {1148 switch (token_ptr.id) {
...@@ -1150,7 +1151,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1150,7 +1151,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1150 continue;1151 continue;
1151 },1152 },
1152 else => {1153 else => {
1153 prevToken(&tok_it, &tree);1154 prevToken(&tok_it, tree);
1154 stack.append(State{ .Block = block }) catch unreachable;1155 stack.append(State{ .Block = block }) catch unreachable;
11551156
1156 try stack.append(State{ .Statement = block });1157 try stack.append(State{ .Statement = block });
...@@ -1159,7 +1160,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1159,7 +1160,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1159 }1160 }
1160 },1161 },
1161 State.Statement => |block| {1162 State.Statement => |block| {
1162 const token = nextToken(&tok_it, &tree);1163 const token = nextToken(&tok_it, tree);
1163 const token_index = token.index;1164 const token_index = token.index;
1164 const token_ptr = token.ptr;1165 const token_ptr = token.ptr;
1165 switch (token_ptr.id) {1166 switch (token_ptr.id) {
...@@ -1216,7 +1217,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1216,7 +1217,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1216 continue;1217 continue;
1217 },1218 },
1218 else => {1219 else => {
1219 prevToken(&tok_it, &tree);1220 prevToken(&tok_it, tree);
1220 const statement = try block.statements.addOne();1221 const statement = try block.statements.addOne();
1221 try stack.append(State{ .Semicolon = statement });1222 try stack.append(State{ .Semicolon = statement });
1222 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .Required = statement } });1223 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .Required = statement } });
...@@ -1225,7 +1226,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1225,7 +1226,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1225 }1226 }
1226 },1227 },
1227 State.ComptimeStatement => |ctx| {1228 State.ComptimeStatement => |ctx| {
1228 const token = nextToken(&tok_it, &tree);1229 const token = nextToken(&tok_it, tree);
1229 const token_index = token.index;1230 const token_index = token.index;
1230 const token_ptr = token.ptr;1231 const token_ptr = token.ptr;
1231 switch (token_ptr.id) {1232 switch (token_ptr.id) {
...@@ -1245,8 +1246,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1245,8 +1246,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1245 continue;1246 continue;
1246 },1247 },
1247 else => {1248 else => {
1248 prevToken(&tok_it, &tree);1249 prevToken(&tok_it, tree);
1249 prevToken(&tok_it, &tree);1250 prevToken(&tok_it, tree);
1250 const statement = try ctx.block.statements.addOne();1251 const statement = try ctx.block.statements.addOne();
1251 try stack.append(State{ .Semicolon = statement });1252 try stack.append(State{ .Semicolon = statement });
1252 try stack.append(State{ .Expression = OptionalCtx{ .Required = statement } });1253 try stack.append(State{ .Expression = OptionalCtx{ .Required = statement } });
...@@ -1264,11 +1265,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1264,11 +1265,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1264 },1265 },
12651266
1266 State.AsmOutputItems => |items| {1267 State.AsmOutputItems => |items| {
1267 const lbracket = nextToken(&tok_it, &tree);1268 const lbracket = nextToken(&tok_it, tree);
1268 const lbracket_index = lbracket.index;1269 const lbracket_index = lbracket.index;
1269 const lbracket_ptr = lbracket.ptr;1270 const lbracket_ptr = lbracket.ptr;
1270 if (lbracket_ptr.id != Token.Id.LBracket) {1271 if (lbracket_ptr.id != Token.Id.LBracket) {
1271 prevToken(&tok_it, &tree);1272 prevToken(&tok_it, tree);
1272 continue;1273 continue;
1273 }1274 }
12741275
...@@ -1299,7 +1300,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1299,7 +1300,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1299 continue;1300 continue;
1300 },1301 },
1301 State.AsmOutputReturnOrType => |node| {1302 State.AsmOutputReturnOrType => |node| {
1302 const token = nextToken(&tok_it, &tree);1303 const token = nextToken(&tok_it, tree);
1303 const token_index = token.index;1304 const token_index = token.index;
1304 const token_ptr = token.ptr;1305 const token_ptr = token.ptr;
1305 switch (token_ptr.id) {1306 switch (token_ptr.id) {
...@@ -1319,11 +1320,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1319,11 +1320,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1319 }1320 }
1320 },1321 },
1321 State.AsmInputItems => |items| {1322 State.AsmInputItems => |items| {
1322 const lbracket = nextToken(&tok_it, &tree);1323 const lbracket = nextToken(&tok_it, tree);
1323 const lbracket_index = lbracket.index;1324 const lbracket_index = lbracket.index;
1324 const lbracket_ptr = lbracket.ptr;1325 const lbracket_ptr = lbracket.ptr;
1325 if (lbracket_ptr.id != Token.Id.LBracket) {1326 if (lbracket_ptr.id != Token.Id.LBracket) {
1326 prevToken(&tok_it, &tree);1327 prevToken(&tok_it, tree);
1327 continue;1328 continue;
1328 }1329 }
13291330
...@@ -1354,16 +1355,16 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1354,16 +1355,16 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1354 continue;1355 continue;
1355 },1356 },
1356 State.AsmClobberItems => |items| {1357 State.AsmClobberItems => |items| {
1357 while (eatToken(&tok_it, &tree, Token.Id.StringLiteral)) |strlit| {1358 while (eatToken(&tok_it, tree, Token.Id.StringLiteral)) |strlit| {
1358 try items.push(strlit);1359 try items.push(strlit);
1359 if (eatToken(&tok_it, &tree, Token.Id.Comma) == null)1360 if (eatToken(&tok_it, tree, Token.Id.Comma) == null)
1360 break;1361 break;
1361 }1362 }
1362 continue;1363 continue;
1363 },1364 },
13641365
1365 State.ExprListItemOrEnd => |list_state| {1366 State.ExprListItemOrEnd => |list_state| {
1366 if (eatToken(&tok_it, &tree, list_state.end)) |token_index| {1367 if (eatToken(&tok_it, tree, list_state.end)) |token_index| {
1367 (list_state.ptr).* = token_index;1368 (list_state.ptr).* = token_index;
1368 continue;1369 continue;
1369 }1370 }
...@@ -1373,7 +1374,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1373,7 +1374,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1373 continue;1374 continue;
1374 },1375 },
1375 State.ExprListCommaOrEnd => |list_state| {1376 State.ExprListCommaOrEnd => |list_state| {
1376 switch (expectCommaOrEnd(&tok_it, &tree, list_state.end)) {1377 switch (expectCommaOrEnd(&tok_it, tree, list_state.end)) {
1377 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {1378 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
1378 (list_state.ptr).* = end;1379 (list_state.ptr).* = end;
1379 continue;1380 continue;
...@@ -1388,7 +1389,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1388,7 +1389,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1388 }1389 }
1389 },1390 },
1390 State.FieldInitListItemOrEnd => |list_state| {1391 State.FieldInitListItemOrEnd => |list_state| {
1391 if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| {1392 if (eatToken(&tok_it, tree, Token.Id.RBrace)) |rbrace| {
1392 (list_state.ptr).* = rbrace;1393 (list_state.ptr).* = rbrace;
1393 continue;1394 continue;
1394 }1395 }
...@@ -1420,7 +1421,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1420,7 +1421,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1420 continue;1421 continue;
1421 },1422 },
1422 State.FieldInitListCommaOrEnd => |list_state| {1423 State.FieldInitListCommaOrEnd => |list_state| {
1423 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {1424 switch (expectCommaOrEnd(&tok_it, tree, Token.Id.RBrace)) {
1424 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {1425 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
1425 (list_state.ptr).* = end;1426 (list_state.ptr).* = end;
1426 continue;1427 continue;
...@@ -1435,17 +1436,17 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1435,17 +1436,17 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1435 }1436 }
1436 },1437 },
1437 State.FieldListCommaOrEnd => |field_ctx| {1438 State.FieldListCommaOrEnd => |field_ctx| {
1438 const end_token = nextToken(&tok_it, &tree);1439 const end_token = nextToken(&tok_it, tree);
1439 const end_token_index = end_token.index;1440 const end_token_index = end_token.index;
1440 const end_token_ptr = end_token.ptr;1441 const end_token_ptr = end_token.ptr;
1441 switch (end_token_ptr.id) {1442 switch (end_token_ptr.id) {
1442 Token.Id.Comma => {1443 Token.Id.Comma => {
1443 if (eatToken(&tok_it, &tree, Token.Id.DocComment)) |doc_comment_token| {1444 if (eatToken(&tok_it, tree, Token.Id.DocComment)) |doc_comment_token| {
1444 const loc = tree.tokenLocation(end_token_ptr.end, doc_comment_token);1445 const loc = tree.tokenLocation(end_token_ptr.end, doc_comment_token);
1445 if (loc.line == 0) {1446 if (loc.line == 0) {
1446 try pushDocComment(arena, doc_comment_token, field_ctx.doc_comments);1447 try pushDocComment(arena, doc_comment_token, field_ctx.doc_comments);
1447 } else {1448 } else {
1448 prevToken(&tok_it, &tree);1449 prevToken(&tok_it, tree);
1449 }1450 }
1450 }1451 }
14511452
...@@ -1468,7 +1469,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1468,7 +1469,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1468 }1469 }
1469 },1470 },
1470 State.ErrorTagListItemOrEnd => |list_state| {1471 State.ErrorTagListItemOrEnd => |list_state| {
1471 if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| {1472 if (eatToken(&tok_it, tree, Token.Id.RBrace)) |rbrace| {
1472 (list_state.ptr).* = rbrace;1473 (list_state.ptr).* = rbrace;
1473 continue;1474 continue;
1474 }1475 }
...@@ -1480,7 +1481,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1480,7 +1481,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1480 continue;1481 continue;
1481 },1482 },
1482 State.ErrorTagListCommaOrEnd => |list_state| {1483 State.ErrorTagListCommaOrEnd => |list_state| {
1483 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {1484 switch (expectCommaOrEnd(&tok_it, tree, Token.Id.RBrace)) {
1484 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {1485 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
1485 (list_state.ptr).* = end;1486 (list_state.ptr).* = end;
1486 continue;1487 continue;
...@@ -1495,12 +1496,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1495,12 +1496,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1495 }1496 }
1496 },1497 },
1497 State.SwitchCaseOrEnd => |list_state| {1498 State.SwitchCaseOrEnd => |list_state| {
1498 if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| {1499 if (eatToken(&tok_it, tree, Token.Id.RBrace)) |rbrace| {
1499 (list_state.ptr).* = rbrace;1500 (list_state.ptr).* = rbrace;
1500 continue;1501 continue;
1501 }1502 }
15021503
1503 const comments = try eatDocComments(arena, &tok_it, &tree);1504 const comments = try eatDocComments(arena, &tok_it, tree);
1504 const node = try arena.create(ast.Node.SwitchCase);1505 const node = try arena.create(ast.Node.SwitchCase);
1505 node.* = ast.Node.SwitchCase{1506 node.* = ast.Node.SwitchCase{
1506 .base = ast.Node{ .id = ast.Node.Id.SwitchCase },1507 .base = ast.Node{ .id = ast.Node.Id.SwitchCase },
...@@ -1519,7 +1520,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1519,7 +1520,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1519 },1520 },
15201521
1521 State.SwitchCaseCommaOrEnd => |list_state| {1522 State.SwitchCaseCommaOrEnd => |list_state| {
1522 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {1523 switch (expectCommaOrEnd(&tok_it, tree, Token.Id.RBrace)) {
1523 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {1524 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
1524 (list_state.ptr).* = end;1525 (list_state.ptr).* = end;
1525 continue;1526 continue;
...@@ -1535,7 +1536,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1535,7 +1536,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1535 },1536 },
15361537
1537 State.SwitchCaseFirstItem => |switch_case| {1538 State.SwitchCaseFirstItem => |switch_case| {
1538 const token = nextToken(&tok_it, &tree);1539 const token = nextToken(&tok_it, tree);
1539 const token_index = token.index;1540 const token_index = token.index;
1540 const token_ptr = token.ptr;1541 const token_ptr = token.ptr;
1541 if (token_ptr.id == Token.Id.Keyword_else) {1542 if (token_ptr.id == Token.Id.Keyword_else) {
...@@ -1554,26 +1555,26 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1554,26 +1555,26 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1554 });1555 });
1555 continue;1556 continue;
1556 } else {1557 } else {
1557 prevToken(&tok_it, &tree);1558 prevToken(&tok_it, tree);
1558 stack.append(State{ .SwitchCaseItemCommaOrEnd = switch_case }) catch unreachable;1559 stack.append(State{ .SwitchCaseItemCommaOrEnd = switch_case }) catch unreachable;
1559 try stack.append(State{ .RangeExpressionBegin = OptionalCtx{ .Required = try switch_case.items.addOne() } });1560 try stack.append(State{ .RangeExpressionBegin = OptionalCtx{ .Required = try switch_case.items.addOne() } });
1560 continue;1561 continue;
1561 }1562 }
1562 },1563 },
1563 State.SwitchCaseItemOrEnd => |switch_case| {1564 State.SwitchCaseItemOrEnd => |switch_case| {
1564 const token = nextToken(&tok_it, &tree);1565 const token = nextToken(&tok_it, tree);
1565 if (token.ptr.id == Token.Id.EqualAngleBracketRight) {1566 if (token.ptr.id == Token.Id.EqualAngleBracketRight) {
1566 switch_case.arrow_token = token.index;1567 switch_case.arrow_token = token.index;
1567 continue;1568 continue;
1568 } else {1569 } else {
1569 prevToken(&tok_it, &tree);1570 prevToken(&tok_it, tree);
1570 stack.append(State{ .SwitchCaseItemCommaOrEnd = switch_case }) catch unreachable;1571 stack.append(State{ .SwitchCaseItemCommaOrEnd = switch_case }) catch unreachable;
1571 try stack.append(State{ .RangeExpressionBegin = OptionalCtx{ .Required = try switch_case.items.addOne() } });1572 try stack.append(State{ .RangeExpressionBegin = OptionalCtx{ .Required = try switch_case.items.addOne() } });
1572 continue;1573 continue;
1573 }1574 }
1574 },1575 },
1575 State.SwitchCaseItemCommaOrEnd => |switch_case| {1576 State.SwitchCaseItemCommaOrEnd => |switch_case| {
1576 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.EqualAngleBracketRight)) {1577 switch (expectCommaOrEnd(&tok_it, tree, Token.Id.EqualAngleBracketRight)) {
1577 ExpectCommaOrEndResult.end_token => |end_token| {1578 ExpectCommaOrEndResult.end_token => |end_token| {
1578 if (end_token) |t| {1579 if (end_token) |t| {
1579 switch_case.arrow_token = t;1580 switch_case.arrow_token = t;
...@@ -1591,14 +1592,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1591,14 +1592,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1591 },1592 },
15921593
1593 State.SuspendBody => |suspend_node| {1594 State.SuspendBody => |suspend_node| {
1594 const token = nextToken(&tok_it, &tree);1595 const token = nextToken(&tok_it, tree);
1595 switch (token.ptr.id) {1596 switch (token.ptr.id) {
1596 Token.Id.Semicolon => {1597 Token.Id.Semicolon => {
1597 prevToken(&tok_it, &tree);1598 prevToken(&tok_it, tree);
1598 continue;1599 continue;
1599 },1600 },
1600 Token.Id.LBrace => {1601 Token.Id.LBrace => {
1601 prevToken(&tok_it, &tree);1602 prevToken(&tok_it, tree);
1602 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .RequiredNull = &suspend_node.body } });1603 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .RequiredNull = &suspend_node.body } });
1603 continue;1604 continue;
1604 },1605 },
...@@ -1608,7 +1609,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1608,7 +1609,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1608 }1609 }
1609 },1610 },
1610 State.AsyncAllocator => |async_node| {1611 State.AsyncAllocator => |async_node| {
1611 if (eatToken(&tok_it, &tree, Token.Id.AngleBracketLeft) == null) {1612 if (eatToken(&tok_it, tree, Token.Id.AngleBracketLeft) == null) {
1612 continue;1613 continue;
1613 }1614 }
16141615
...@@ -1649,7 +1650,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1649,7 +1650,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1649 },1650 },
16501651
1651 State.ExternType => |ctx| {1652 State.ExternType => |ctx| {
1652 if (eatToken(&tok_it, &tree, Token.Id.Keyword_fn)) |fn_token| {1653 if (eatToken(&tok_it, tree, Token.Id.Keyword_fn)) |fn_token| {
1653 const fn_proto = try arena.create(ast.Node.FnProto);1654 const fn_proto = try arena.create(ast.Node.FnProto);
1654 fn_proto.* = ast.Node.FnProto{1655 fn_proto.* = ast.Node.FnProto{
1655 .base = ast.Node{ .id = ast.Node.Id.FnProto },1656 .base = ast.Node{ .id = ast.Node.Id.FnProto },
...@@ -1682,7 +1683,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1682,7 +1683,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1682 continue;1683 continue;
1683 },1684 },
1684 State.SliceOrArrayAccess => |node| {1685 State.SliceOrArrayAccess => |node| {
1685 const token = nextToken(&tok_it, &tree);1686 const token = nextToken(&tok_it, tree);
1686 const token_index = token.index;1687 const token_index = token.index;
1687 const token_ptr = token.ptr;1688 const token_ptr = token.ptr;
1688 switch (token_ptr.id) {1689 switch (token_ptr.id) {
...@@ -1715,7 +1716,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1715,7 +1716,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1715 }1716 }
1716 },1717 },
1717 State.SliceOrArrayType => |node| {1718 State.SliceOrArrayType => |node| {
1718 if (eatToken(&tok_it, &tree, Token.Id.RBracket)) |_| {1719 if (eatToken(&tok_it, tree, Token.Id.RBracket)) |_| {
1719 node.op = ast.Node.PrefixOp.Op{1720 node.op = ast.Node.PrefixOp.Op{
1720 .SliceType = ast.Node.PrefixOp.PtrInfo{1721 .SliceType = ast.Node.PrefixOp.PtrInfo{
1721 .align_info = null,1722 .align_info = null,
...@@ -1737,7 +1738,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1737,7 +1738,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1737 },1738 },
17381739
1739 State.PtrTypeModifiers => |addr_of_info| {1740 State.PtrTypeModifiers => |addr_of_info| {
1740 const token = nextToken(&tok_it, &tree);1741 const token = nextToken(&tok_it, tree);
1741 const token_index = token.index;1742 const token_index = token.index;
1742 const token_ptr = token.ptr;1743 const token_ptr = token.ptr;
1743 switch (token_ptr.id) {1744 switch (token_ptr.id) {
...@@ -1787,14 +1788,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1787,14 +1788,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1787 continue;1788 continue;
1788 },1789 },
1789 else => {1790 else => {
1790 prevToken(&tok_it, &tree);1791 prevToken(&tok_it, tree);
1791 continue;1792 continue;
1792 },1793 },
1793 }1794 }
1794 },1795 },
17951796
1796 State.AlignBitRange => |align_info| {1797 State.AlignBitRange => |align_info| {
1797 const token = nextToken(&tok_it, &tree);1798 const token = nextToken(&tok_it, tree);
1798 switch (token.ptr.id) {1799 switch (token.ptr.id) {
1799 Token.Id.Colon => {1800 Token.Id.Colon => {
1800 align_info.bit_range = ast.Node.PrefixOp.PtrInfo.Align.BitRange(undefined);1801 align_info.bit_range = ast.Node.PrefixOp.PtrInfo.Align.BitRange(undefined);
...@@ -1817,7 +1818,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1817,7 +1818,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1817 },1818 },
18181819
1819 State.Payload => |opt_ctx| {1820 State.Payload => |opt_ctx| {
1820 const token = nextToken(&tok_it, &tree);1821 const token = nextToken(&tok_it, tree);
1821 const token_index = token.index;1822 const token_index = token.index;
1822 const token_ptr = token.ptr;1823 const token_ptr = token.ptr;
1823 if (token_ptr.id != Token.Id.Pipe) {1824 if (token_ptr.id != Token.Id.Pipe) {
...@@ -1831,7 +1832,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1831,7 +1832,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1831 return tree;1832 return tree;
1832 }1833 }
18331834
1834 prevToken(&tok_it, &tree);1835 prevToken(&tok_it, tree);
1835 continue;1836 continue;
1836 }1837 }
18371838
...@@ -1854,7 +1855,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1854,7 +1855,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1854 continue;1855 continue;
1855 },1856 },
1856 State.PointerPayload => |opt_ctx| {1857 State.PointerPayload => |opt_ctx| {
1857 const token = nextToken(&tok_it, &tree);1858 const token = nextToken(&tok_it, tree);
1858 const token_index = token.index;1859 const token_index = token.index;
1859 const token_ptr = token.ptr;1860 const token_ptr = token.ptr;
1860 if (token_ptr.id != Token.Id.Pipe) {1861 if (token_ptr.id != Token.Id.Pipe) {
...@@ -1868,7 +1869,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1868,7 +1869,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1868 return tree;1869 return tree;
1869 }1870 }
18701871
1871 prevToken(&tok_it, &tree);1872 prevToken(&tok_it, tree);
1872 continue;1873 continue;
1873 }1874 }
18741875
...@@ -1898,7 +1899,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1898,7 +1899,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1898 continue;1899 continue;
1899 },1900 },
1900 State.PointerIndexPayload => |opt_ctx| {1901 State.PointerIndexPayload => |opt_ctx| {
1901 const token = nextToken(&tok_it, &tree);1902 const token = nextToken(&tok_it, tree);
1902 const token_index = token.index;1903 const token_index = token.index;
1903 const token_ptr = token.ptr;1904 const token_ptr = token.ptr;
1904 if (token_ptr.id != Token.Id.Pipe) {1905 if (token_ptr.id != Token.Id.Pipe) {
...@@ -1912,7 +1913,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1912,7 +1913,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1912 return tree;1913 return tree;
1913 }1914 }
19141915
1915 prevToken(&tok_it, &tree);1916 prevToken(&tok_it, tree);
1916 continue;1917 continue;
1917 }1918 }
19181919
...@@ -1946,7 +1947,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1946,7 +1947,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1946 },1947 },
19471948
1948 State.Expression => |opt_ctx| {1949 State.Expression => |opt_ctx| {
1949 const token = nextToken(&tok_it, &tree);1950 const token = nextToken(&tok_it, tree);
1950 const token_index = token.index;1951 const token_index = token.index;
1951 const token_ptr = token.ptr;1952 const token_ptr = token.ptr;
1952 switch (token_ptr.id) {1953 switch (token_ptr.id) {
...@@ -2000,7 +2001,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2000,7 +2001,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2000 },2001 },
2001 else => {2002 else => {
2002 if (!try parseBlockExpr(&stack, arena, opt_ctx, token_ptr.*, token_index)) {2003 if (!try parseBlockExpr(&stack, arena, opt_ctx, token_ptr.*, token_index)) {
2003 prevToken(&tok_it, &tree);2004 prevToken(&tok_it, tree);
2004 stack.append(State{ .UnwrapExpressionBegin = opt_ctx }) catch unreachable;2005 stack.append(State{ .UnwrapExpressionBegin = opt_ctx }) catch unreachable;
2005 }2006 }
2006 continue;2007 continue;
...@@ -2015,7 +2016,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2015,7 +2016,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2015 State.RangeExpressionEnd => |opt_ctx| {2016 State.RangeExpressionEnd => |opt_ctx| {
2016 const lhs = opt_ctx.get() orelse continue;2017 const lhs = opt_ctx.get() orelse continue;
20172018
2018 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {2019 if (eatToken(&tok_it, tree, Token.Id.Ellipsis3)) |ellipsis3| {
2019 const node = try arena.create(ast.Node.InfixOp);2020 const node = try arena.create(ast.Node.InfixOp);
2020 node.* = ast.Node.InfixOp{2021 node.* = ast.Node.InfixOp{
2021 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2022 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
...@@ -2038,7 +2039,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2038,7 +2039,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2038 State.AssignmentExpressionEnd => |opt_ctx| {2039 State.AssignmentExpressionEnd => |opt_ctx| {
2039 const lhs = opt_ctx.get() orelse continue;2040 const lhs = opt_ctx.get() orelse continue;
20402041
2041 const token = nextToken(&tok_it, &tree);2042 const token = nextToken(&tok_it, tree);
2042 const token_index = token.index;2043 const token_index = token.index;
2043 const token_ptr = token.ptr;2044 const token_ptr = token.ptr;
2044 if (tokenIdToAssignment(token_ptr.id)) |ass_id| {2045 if (tokenIdToAssignment(token_ptr.id)) |ass_id| {
...@@ -2055,7 +2056,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2055,7 +2056,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2055 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } });2056 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } });
2056 continue;2057 continue;
2057 } else {2058 } else {
2058 prevToken(&tok_it, &tree);2059 prevToken(&tok_it, tree);
2059 continue;2060 continue;
2060 }2061 }
2061 },2062 },
...@@ -2069,7 +2070,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2069,7 +2070,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2069 State.UnwrapExpressionEnd => |opt_ctx| {2070 State.UnwrapExpressionEnd => |opt_ctx| {
2070 const lhs = opt_ctx.get() orelse continue;2071 const lhs = opt_ctx.get() orelse continue;
20712072
2072 const token = nextToken(&tok_it, &tree);2073 const token = nextToken(&tok_it, tree);
2073 const token_index = token.index;2074 const token_index = token.index;
2074 const token_ptr = token.ptr;2075 const token_ptr = token.ptr;
2075 if (tokenIdToUnwrapExpr(token_ptr.id)) |unwrap_id| {2076 if (tokenIdToUnwrapExpr(token_ptr.id)) |unwrap_id| {
...@@ -2091,7 +2092,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2091,7 +2092,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2091 }2092 }
2092 continue;2093 continue;
2093 } else {2094 } else {
2094 prevToken(&tok_it, &tree);2095 prevToken(&tok_it, tree);
2095 continue;2096 continue;
2096 }2097 }
2097 },2098 },
...@@ -2105,7 +2106,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2105,7 +2106,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2105 State.BoolOrExpressionEnd => |opt_ctx| {2106 State.BoolOrExpressionEnd => |opt_ctx| {
2106 const lhs = opt_ctx.get() orelse continue;2107 const lhs = opt_ctx.get() orelse continue;
21072108
2108 if (eatToken(&tok_it, &tree, Token.Id.Keyword_or)) |or_token| {2109 if (eatToken(&tok_it, tree, Token.Id.Keyword_or)) |or_token| {
2109 const node = try arena.create(ast.Node.InfixOp);2110 const node = try arena.create(ast.Node.InfixOp);
2110 node.* = ast.Node.InfixOp{2111 node.* = ast.Node.InfixOp{
2111 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2112 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
...@@ -2130,7 +2131,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2130,7 +2131,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2130 State.BoolAndExpressionEnd => |opt_ctx| {2131 State.BoolAndExpressionEnd => |opt_ctx| {
2131 const lhs = opt_ctx.get() orelse continue;2132 const lhs = opt_ctx.get() orelse continue;
21322133
2133 if (eatToken(&tok_it, &tree, Token.Id.Keyword_and)) |and_token| {2134 if (eatToken(&tok_it, tree, Token.Id.Keyword_and)) |and_token| {
2134 const node = try arena.create(ast.Node.InfixOp);2135 const node = try arena.create(ast.Node.InfixOp);
2135 node.* = ast.Node.InfixOp{2136 node.* = ast.Node.InfixOp{
2136 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2137 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
...@@ -2155,7 +2156,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2155,7 +2156,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2155 State.ComparisonExpressionEnd => |opt_ctx| {2156 State.ComparisonExpressionEnd => |opt_ctx| {
2156 const lhs = opt_ctx.get() orelse continue;2157 const lhs = opt_ctx.get() orelse continue;
21572158
2158 const token = nextToken(&tok_it, &tree);2159 const token = nextToken(&tok_it, tree);
2159 const token_index = token.index;2160 const token_index = token.index;
2160 const token_ptr = token.ptr;2161 const token_ptr = token.ptr;
2161 if (tokenIdToComparison(token_ptr.id)) |comp_id| {2162 if (tokenIdToComparison(token_ptr.id)) |comp_id| {
...@@ -2172,7 +2173,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2172,7 +2173,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2172 try stack.append(State{ .BinaryOrExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2173 try stack.append(State{ .BinaryOrExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
2173 continue;2174 continue;
2174 } else {2175 } else {
2175 prevToken(&tok_it, &tree);2176 prevToken(&tok_it, tree);
2176 continue;2177 continue;
2177 }2178 }
2178 },2179 },
...@@ -2186,7 +2187,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2186,7 +2187,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2186 State.BinaryOrExpressionEnd => |opt_ctx| {2187 State.BinaryOrExpressionEnd => |opt_ctx| {
2187 const lhs = opt_ctx.get() orelse continue;2188 const lhs = opt_ctx.get() orelse continue;
21882189
2189 if (eatToken(&tok_it, &tree, Token.Id.Pipe)) |pipe| {2190 if (eatToken(&tok_it, tree, Token.Id.Pipe)) |pipe| {
2190 const node = try arena.create(ast.Node.InfixOp);2191 const node = try arena.create(ast.Node.InfixOp);
2191 node.* = ast.Node.InfixOp{2192 node.* = ast.Node.InfixOp{
2192 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2193 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
...@@ -2211,7 +2212,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2211,7 +2212,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2211 State.BinaryXorExpressionEnd => |opt_ctx| {2212 State.BinaryXorExpressionEnd => |opt_ctx| {
2212 const lhs = opt_ctx.get() orelse continue;2213 const lhs = opt_ctx.get() orelse continue;
22132214
2214 if (eatToken(&tok_it, &tree, Token.Id.Caret)) |caret| {2215 if (eatToken(&tok_it, tree, Token.Id.Caret)) |caret| {
2215 const node = try arena.create(ast.Node.InfixOp);2216 const node = try arena.create(ast.Node.InfixOp);
2216 node.* = ast.Node.InfixOp{2217 node.* = ast.Node.InfixOp{
2217 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2218 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
...@@ -2236,7 +2237,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2236,7 +2237,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2236 State.BinaryAndExpressionEnd => |opt_ctx| {2237 State.BinaryAndExpressionEnd => |opt_ctx| {
2237 const lhs = opt_ctx.get() orelse continue;2238 const lhs = opt_ctx.get() orelse continue;
22382239
2239 if (eatToken(&tok_it, &tree, Token.Id.Ampersand)) |ampersand| {2240 if (eatToken(&tok_it, tree, Token.Id.Ampersand)) |ampersand| {
2240 const node = try arena.create(ast.Node.InfixOp);2241 const node = try arena.create(ast.Node.InfixOp);
2241 node.* = ast.Node.InfixOp{2242 node.* = ast.Node.InfixOp{
2242 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2243 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
...@@ -2261,7 +2262,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2261,7 +2262,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2261 State.BitShiftExpressionEnd => |opt_ctx| {2262 State.BitShiftExpressionEnd => |opt_ctx| {
2262 const lhs = opt_ctx.get() orelse continue;2263 const lhs = opt_ctx.get() orelse continue;
22632264
2264 const token = nextToken(&tok_it, &tree);2265 const token = nextToken(&tok_it, tree);
2265 const token_index = token.index;2266 const token_index = token.index;
2266 const token_ptr = token.ptr;2267 const token_ptr = token.ptr;
2267 if (tokenIdToBitShift(token_ptr.id)) |bitshift_id| {2268 if (tokenIdToBitShift(token_ptr.id)) |bitshift_id| {
...@@ -2278,7 +2279,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2278,7 +2279,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2278 try stack.append(State{ .AdditionExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2279 try stack.append(State{ .AdditionExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
2279 continue;2280 continue;
2280 } else {2281 } else {
2281 prevToken(&tok_it, &tree);2282 prevToken(&tok_it, tree);
2282 continue;2283 continue;
2283 }2284 }
2284 },2285 },
...@@ -2292,7 +2293,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2292,7 +2293,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2292 State.AdditionExpressionEnd => |opt_ctx| {2293 State.AdditionExpressionEnd => |opt_ctx| {
2293 const lhs = opt_ctx.get() orelse continue;2294 const lhs = opt_ctx.get() orelse continue;
22942295
2295 const token = nextToken(&tok_it, &tree);2296 const token = nextToken(&tok_it, tree);
2296 const token_index = token.index;2297 const token_index = token.index;
2297 const token_ptr = token.ptr;2298 const token_ptr = token.ptr;
2298 if (tokenIdToAddition(token_ptr.id)) |add_id| {2299 if (tokenIdToAddition(token_ptr.id)) |add_id| {
...@@ -2309,7 +2310,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2309,7 +2310,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2309 try stack.append(State{ .MultiplyExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2310 try stack.append(State{ .MultiplyExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
2310 continue;2311 continue;
2311 } else {2312 } else {
2312 prevToken(&tok_it, &tree);2313 prevToken(&tok_it, tree);
2313 continue;2314 continue;
2314 }2315 }
2315 },2316 },
...@@ -2323,7 +2324,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2323,7 +2324,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2323 State.MultiplyExpressionEnd => |opt_ctx| {2324 State.MultiplyExpressionEnd => |opt_ctx| {
2324 const lhs = opt_ctx.get() orelse continue;2325 const lhs = opt_ctx.get() orelse continue;
23252326
2326 const token = nextToken(&tok_it, &tree);2327 const token = nextToken(&tok_it, tree);
2327 const token_index = token.index;2328 const token_index = token.index;
2328 const token_ptr = token.ptr;2329 const token_ptr = token.ptr;
2329 if (tokenIdToMultiply(token_ptr.id)) |mult_id| {2330 if (tokenIdToMultiply(token_ptr.id)) |mult_id| {
...@@ -2340,7 +2341,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2340,7 +2341,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2340 try stack.append(State{ .CurlySuffixExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2341 try stack.append(State{ .CurlySuffixExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
2341 continue;2342 continue;
2342 } else {2343 } else {
2343 prevToken(&tok_it, &tree);2344 prevToken(&tok_it, tree);
2344 continue;2345 continue;
2345 }2346 }
2346 },2347 },
...@@ -2405,7 +2406,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2405,7 +2406,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2405 State.TypeExprEnd => |opt_ctx| {2406 State.TypeExprEnd => |opt_ctx| {
2406 const lhs = opt_ctx.get() orelse continue;2407 const lhs = opt_ctx.get() orelse continue;
24072408
2408 if (eatToken(&tok_it, &tree, Token.Id.Bang)) |bang| {2409 if (eatToken(&tok_it, tree, Token.Id.Bang)) |bang| {
2409 const node = try arena.create(ast.Node.InfixOp);2410 const node = try arena.create(ast.Node.InfixOp);
2410 node.* = ast.Node.InfixOp{2411 node.* = ast.Node.InfixOp{
2411 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2412 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
...@@ -2422,7 +2423,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2422,7 +2423,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2422 },2423 },
24232424
2424 State.PrefixOpExpression => |opt_ctx| {2425 State.PrefixOpExpression => |opt_ctx| {
2425 const token = nextToken(&tok_it, &tree);2426 const token = nextToken(&tok_it, tree);
2426 const token_index = token.index;2427 const token_index = token.index;
2427 const token_ptr = token.ptr;2428 const token_ptr = token.ptr;
2428 if (tokenIdToPrefixOp(token_ptr.id)) |prefix_id| {2429 if (tokenIdToPrefixOp(token_ptr.id)) |prefix_id| {
...@@ -2454,14 +2455,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2454,14 +2455,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2454 }2455 }
2455 continue;2456 continue;
2456 } else {2457 } else {
2457 prevToken(&tok_it, &tree);2458 prevToken(&tok_it, tree);
2458 stack.append(State{ .SuffixOpExpressionBegin = opt_ctx }) catch unreachable;2459 stack.append(State{ .SuffixOpExpressionBegin = opt_ctx }) catch unreachable;
2459 continue;2460 continue;
2460 }2461 }
2461 },2462 },
24622463
2463 State.SuffixOpExpressionBegin => |opt_ctx| {2464 State.SuffixOpExpressionBegin => |opt_ctx| {
2464 if (eatToken(&tok_it, &tree, Token.Id.Keyword_async)) |async_token| {2465 if (eatToken(&tok_it, tree, Token.Id.Keyword_async)) |async_token| {
2465 const async_node = try arena.create(ast.Node.AsyncAttribute);2466 const async_node = try arena.create(ast.Node.AsyncAttribute);
2466 async_node.* = ast.Node.AsyncAttribute{2467 async_node.* = ast.Node.AsyncAttribute{
2467 .base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },2468 .base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },
...@@ -2489,7 +2490,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2489,7 +2490,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2489 State.SuffixOpExpressionEnd => |opt_ctx| {2490 State.SuffixOpExpressionEnd => |opt_ctx| {
2490 const lhs = opt_ctx.get() orelse continue;2491 const lhs = opt_ctx.get() orelse continue;
24912492
2492 const token = nextToken(&tok_it, &tree);2493 const token = nextToken(&tok_it, tree);
2493 const token_index = token.index;2494 const token_index = token.index;
2494 const token_ptr = token.ptr;2495 const token_ptr = token.ptr;
2495 switch (token_ptr.id) {2496 switch (token_ptr.id) {
...@@ -2534,7 +2535,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2534,7 +2535,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2534 continue;2535 continue;
2535 },2536 },
2536 Token.Id.Period => {2537 Token.Id.Period => {
2537 if (eatToken(&tok_it, &tree, Token.Id.Asterisk)) |asterisk_token| {2538 if (eatToken(&tok_it, tree, Token.Id.Asterisk)) |asterisk_token| {
2538 const node = try arena.create(ast.Node.SuffixOp);2539 const node = try arena.create(ast.Node.SuffixOp);
2539 node.* = ast.Node.SuffixOp{2540 node.* = ast.Node.SuffixOp{
2540 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },2541 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
...@@ -2546,7 +2547,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2546,7 +2547,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2546 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2547 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2547 continue;2548 continue;
2548 }2549 }
2549 if (eatToken(&tok_it, &tree, Token.Id.QuestionMark)) |question_token| {2550 if (eatToken(&tok_it, tree, Token.Id.QuestionMark)) |question_token| {
2550 const node = try arena.create(ast.Node.SuffixOp);2551 const node = try arena.create(ast.Node.SuffixOp);
2551 node.* = ast.Node.SuffixOp{2552 node.* = ast.Node.SuffixOp{
2552 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },2553 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
...@@ -2573,21 +2574,21 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2573,21 +2574,21 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2573 continue;2574 continue;
2574 },2575 },
2575 else => {2576 else => {
2576 prevToken(&tok_it, &tree);2577 prevToken(&tok_it, tree);
2577 continue;2578 continue;
2578 },2579 },
2579 }2580 }
2580 },2581 },
25812582
2582 State.PrimaryExpression => |opt_ctx| {2583 State.PrimaryExpression => |opt_ctx| {
2583 const token = nextToken(&tok_it, &tree);2584 const token = nextToken(&tok_it, tree);
2584 switch (token.ptr.id) {2585 switch (token.ptr.id) {
2585 Token.Id.IntegerLiteral => {2586 Token.Id.IntegerLiteral => {
2586 _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.IntegerLiteral, token.index);2587 _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.IntegerLiteral, token.index);
2587 continue;2588 continue;
2588 },2589 },
2589 Token.Id.Period => {2590 Token.Id.Period => {
2590 const name_token = nextToken(&tok_it, &tree);2591 const name_token = nextToken(&tok_it, tree);
2591 if (name_token.ptr.id != Token.Id.Identifier) {2592 if (name_token.ptr.id != Token.Id.Identifier) {
2592 ((try tree.errors.addOne())).* = Error{2593 ((try tree.errors.addOne())).* = Error{
2593 .ExpectedToken = Error.ExpectedToken{2594 .ExpectedToken = Error.ExpectedToken{
...@@ -2643,11 +2644,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2643,11 +2644,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2643 .result = null,2644 .result = null,
2644 };2645 };
2645 opt_ctx.store(&node.base);2646 opt_ctx.store(&node.base);
2646 const next_token = nextToken(&tok_it, &tree);2647 const next_token = nextToken(&tok_it, tree);
2647 const next_token_index = next_token.index;2648 const next_token_index = next_token.index;
2648 const next_token_ptr = next_token.ptr;2649 const next_token_ptr = next_token.ptr;
2649 if (next_token_ptr.id != Token.Id.Arrow) {2650 if (next_token_ptr.id != Token.Id.Arrow) {
2650 prevToken(&tok_it, &tree);2651 prevToken(&tok_it, tree);
2651 continue;2652 continue;
2652 }2653 }
2653 node.result = ast.Node.PromiseType.Result{2654 node.result = ast.Node.PromiseType.Result{
...@@ -2659,7 +2660,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2659,7 +2660,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2659 continue;2660 continue;
2660 },2661 },
2661 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {2662 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {
2662 opt_ctx.store((try parseStringLiteral(arena, &tok_it, token.ptr, token.index, &tree)) orelse unreachable);2663 opt_ctx.store((try parseStringLiteral(arena, &tok_it, token.ptr, token.index, tree)) orelse unreachable);
2663 continue;2664 continue;
2664 },2665 },
2665 Token.Id.LParen => {2666 Token.Id.LParen => {
...@@ -2747,7 +2748,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2747,7 +2748,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2747 continue;2748 continue;
2748 },2749 },
2749 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {2750 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {
2750 prevToken(&tok_it, &tree);2751 prevToken(&tok_it, tree);
2751 stack.append(State{2752 stack.append(State{
2752 .ContainerKind = ContainerKindCtx{2753 .ContainerKind = ContainerKindCtx{
2753 .opt_ctx = opt_ctx,2754 .opt_ctx = opt_ctx,
...@@ -2864,7 +2865,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2864,7 +2865,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2864 },2865 },
2865 else => {2866 else => {
2866 if (!try parseBlockExpr(&stack, arena, opt_ctx, token.ptr.*, token.index)) {2867 if (!try parseBlockExpr(&stack, arena, opt_ctx, token.ptr.*, token.index)) {
2867 prevToken(&tok_it, &tree);2868 prevToken(&tok_it, tree);
2868 if (opt_ctx != OptionalCtx.Optional) {2869 if (opt_ctx != OptionalCtx.Optional) {
2869 ((try tree.errors.addOne())).* = Error{ .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr{ .token = token.index } };2870 ((try tree.errors.addOne())).* = Error{ .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr{ .token = token.index } };
2870 return tree;2871 return tree;
...@@ -2876,7 +2877,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2876,7 +2877,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2876 },2877 },
28772878
2878 State.ErrorTypeOrSetDecl => |ctx| {2879 State.ErrorTypeOrSetDecl => |ctx| {
2879 if (eatToken(&tok_it, &tree, Token.Id.LBrace) == null) {2880 if (eatToken(&tok_it, tree, Token.Id.LBrace) == null) {
2880 const node = try arena.create(ast.Node.InfixOp);2881 const node = try arena.create(ast.Node.InfixOp);
2881 node.* = ast.Node.InfixOp{2882 node.* = ast.Node.InfixOp{
2882 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2883 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
...@@ -2914,11 +2915,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2914,11 +2915,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2914 continue;2915 continue;
2915 },2916 },
2916 State.StringLiteral => |opt_ctx| {2917 State.StringLiteral => |opt_ctx| {
2917 const token = nextToken(&tok_it, &tree);2918 const token = nextToken(&tok_it, tree);
2918 const token_index = token.index;2919 const token_index = token.index;
2919 const token_ptr = token.ptr;2920 const token_ptr = token.ptr;
2920 opt_ctx.store((try parseStringLiteral(arena, &tok_it, token_ptr, token_index, &tree)) orelse {2921 opt_ctx.store((try parseStringLiteral(arena, &tok_it, token_ptr, token_index, tree)) orelse {
2921 prevToken(&tok_it, &tree);2922 prevToken(&tok_it, tree);
2922 if (opt_ctx != OptionalCtx.Optional) {2923 if (opt_ctx != OptionalCtx.Optional) {
2923 ((try tree.errors.addOne())).* = Error{ .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr{ .token = token_index } };2924 ((try tree.errors.addOne())).* = Error{ .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr{ .token = token_index } };
2924 return tree;2925 return tree;
...@@ -2929,13 +2930,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2929,13 +2930,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2929 },2930 },
29302931
2931 State.Identifier => |opt_ctx| {2932 State.Identifier => |opt_ctx| {
2932 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |ident_token| {2933 if (eatToken(&tok_it, tree, Token.Id.Identifier)) |ident_token| {
2933 _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.Identifier, ident_token);2934 _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.Identifier, ident_token);
2934 continue;2935 continue;
2935 }2936 }
29362937
2937 if (opt_ctx != OptionalCtx.Optional) {2938 if (opt_ctx != OptionalCtx.Optional) {
2938 const token = nextToken(&tok_it, &tree);2939 const token = nextToken(&tok_it, tree);
2939 const token_index = token.index;2940 const token_index = token.index;
2940 const token_ptr = token.ptr;2941 const token_ptr = token.ptr;
2941 ((try tree.errors.addOne())).* = Error{2942 ((try tree.errors.addOne())).* = Error{
...@@ -2949,8 +2950,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2949,8 +2950,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2949 },2950 },
29502951
2951 State.ErrorTag => |node_ptr| {2952 State.ErrorTag => |node_ptr| {
2952 const comments = try eatDocComments(arena, &tok_it, &tree);2953 const comments = try eatDocComments(arena, &tok_it, tree);
2953 const ident_token = nextToken(&tok_it, &tree);2954 const ident_token = nextToken(&tok_it, tree);
2954 const ident_token_index = ident_token.index;2955 const ident_token_index = ident_token.index;
2955 const ident_token_ptr = ident_token.ptr;2956 const ident_token_ptr = ident_token.ptr;
2956 if (ident_token_ptr.id != Token.Id.Identifier) {2957 if (ident_token_ptr.id != Token.Id.Identifier) {
...@@ -2974,7 +2975,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2974,7 +2975,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2974 },2975 },
29752976
2976 State.ExpectToken => |token_id| {2977 State.ExpectToken => |token_id| {
2977 const token = nextToken(&tok_it, &tree);2978 const token = nextToken(&tok_it, tree);
2978 const token_index = token.index;2979 const token_index = token.index;
2979 const token_ptr = token.ptr;2980 const token_ptr = token.ptr;
2980 if (token_ptr.id != token_id) {2981 if (token_ptr.id != token_id) {
...@@ -2989,7 +2990,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2989,7 +2990,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2989 continue;2990 continue;
2990 },2991 },
2991 State.ExpectTokenSave => |expect_token_save| {2992 State.ExpectTokenSave => |expect_token_save| {
2992 const token = nextToken(&tok_it, &tree);2993 const token = nextToken(&tok_it, tree);
2993 const token_index = token.index;2994 const token_index = token.index;
2994 const token_ptr = token.ptr;2995 const token_ptr = token.ptr;
2995 if (token_ptr.id != expect_token_save.id) {2996 if (token_ptr.id != expect_token_save.id) {
...@@ -3005,7 +3006,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -3005,7 +3006,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
3005 continue;3006 continue;
3006 },3007 },
3007 State.IfToken => |token_id| {3008 State.IfToken => |token_id| {
3008 if (eatToken(&tok_it, &tree, token_id)) |_| {3009 if (eatToken(&tok_it, tree, token_id)) |_| {
3009 continue;3010 continue;
3010 }3011 }
30113012
...@@ -3013,7 +3014,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -3013,7 +3014,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
3013 continue;3014 continue;
3014 },3015 },
3015 State.IfTokenSave => |if_token_save| {3016 State.IfTokenSave => |if_token_save| {
3016 if (eatToken(&tok_it, &tree, if_token_save.id)) |token_index| {3017 if (eatToken(&tok_it, tree, if_token_save.id)) |token_index| {
3017 (if_token_save.ptr).* = token_index;3018 (if_token_save.ptr).* = token_index;
3018 continue;3019 continue;
3019 }3020 }
...@@ -3022,7 +3023,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -3022,7 +3023,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
3022 continue;3023 continue;
3023 },3024 },
3024 State.OptionalTokenSave => |optional_token_save| {3025 State.OptionalTokenSave => |optional_token_save| {
3025 if (eatToken(&tok_it, &tree, optional_token_save.id)) |token_index| {3026 if (eatToken(&tok_it, tree, optional_token_save.id)) |token_index| {
3026 (optional_token_save.ptr).* = token_index;3027 (optional_token_save.ptr).* = token_index;
3027 continue;3028 continue;
3028 }3029 }
std/zig/parser_test.zig+2-2
...@@ -2137,7 +2137,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b...@@ -2137,7 +2137,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
2137 var stderr_file = try io.getStdErr();2137 var stderr_file = try io.getStdErr();
2138 var stderr = &stderr_file.outStream().stream;2138 var stderr = &stderr_file.outStream().stream;
21392139
2140 var tree = try std.zig.parse(allocator, source);2140 const tree = try std.zig.parse(allocator, source);
2141 defer tree.deinit();2141 defer tree.deinit();
21422142
2143 var error_it = tree.errors.iterator(0);2143 var error_it = tree.errors.iterator(0);
...@@ -2170,7 +2170,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b...@@ -2170,7 +2170,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
2170 errdefer buffer.deinit();2170 errdefer buffer.deinit();
21712171
2172 var buffer_out_stream = io.BufferOutStream.init(&buffer);2172 var buffer_out_stream = io.BufferOutStream.init(&buffer);
2173 anything_changed.* = try std.zig.render(allocator, &buffer_out_stream.stream, &tree);2173 anything_changed.* = try std.zig.render(allocator, &buffer_out_stream.stream, tree);
2174 return buffer.toOwnedSlice();2174 return buffer.toOwnedSlice();
2175}2175}
21762176