authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-16 00:02:26-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-16 00:02:26-04:00
log5cfabdd493c6602243f47e24320bae940a3c417a
tree3d8acc6fd643058367a08d44274c8efb46d6829f
parent86a352c45bb654951529660b2e6cbbfa72773170
parent492a214d4c4f4feb15620dfd05230de0086825e5

Merge remote-tracking branch 'origin/master' into pointer-reform


6 files changed, 657 insertions(+), 589 deletions(-)

CMakeLists.txt+1-1
...@@ -196,7 +196,7 @@ else()...@@ -196,7 +196,7 @@ else()
196 if(MSVC)196 if(MSVC)
197 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -D_CRT_SECURE_NO_WARNINGS /w")197 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -D_CRT_SECURE_NO_WARNINGS /w")
198 else()198 else()
199 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment")199 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment -Wno-class-memaccess -Wno-unknown-warning-option")
200 endif()200 endif()
201 set_target_properties(embedded_lld_lib PROPERTIES201 set_target_properties(embedded_lld_lib PROPERTIES
202 COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS}202 COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS}
src/ir.cpp+1
...@@ -16555,6 +16555,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t...@@ -16555,6 +16555,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
16555 {16555 {
16556 size_t byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, type_entry->type_ref, struct_field->gen_index);16556 size_t byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, type_entry->type_ref, struct_field->gen_index);
16557 inner_fields[1].data.x_maybe = create_const_vals(1);16557 inner_fields[1].data.x_maybe = create_const_vals(1);
16558 inner_fields[1].data.x_maybe->special = ConstValSpecialStatic;
16558 inner_fields[1].data.x_maybe->type = ira->codegen->builtin_types.entry_usize;16559 inner_fields[1].data.x_maybe->type = ira->codegen->builtin_types.entry_usize;
16559 bigint_init_unsigned(&inner_fields[1].data.x_maybe->data.x_bigint, byte_offset);16560 bigint_init_unsigned(&inner_fields[1].data.x_maybe->data.x_bigint, byte_offset);
16560 }16561 }
std/fmt/index.zig+59-1
...@@ -25,6 +25,8 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -25,6 +25,8 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
25 Character,25 Character,
26 Buf,26 Buf,
27 BufWidth,27 BufWidth,
28 Bytes,
29 BytesWidth,
28 };30 };
2931
30 comptime var start_index = 0;32 comptime var start_index = 0;
...@@ -93,6 +95,10 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -93,6 +95,10 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
93 '.' => {95 '.' => {
94 state = State.Float;96 state = State.Float;
95 },97 },
98 'B' => {
99 width = 0;
100 state = State.Bytes;
101 },
96 else => @compileError("Unknown format character: " ++ []u8{c}),102 else => @compileError("Unknown format character: " ++ []u8{c}),
97 },103 },
98 State.Buf => switch (c) {104 State.Buf => switch (c) {
...@@ -204,6 +210,30 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -204,6 +210,30 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
204 },210 },
205 else => @compileError("Unexpected character in format string: " ++ []u8{c}),211 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
206 },212 },
213 State.Bytes => switch (c) {
214 '}' => {
215 try formatBytes(args[next_arg], 0, context, Errors, output);
216 next_arg += 1;
217 state = State.Start;
218 start_index = i + 1;
219 },
220 '0' ... '9' => {
221 width_start = i;
222 state = State.BytesWidth;
223 },
224 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
225 },
226 State.BytesWidth => switch (c) {
227 '}' => {
228 width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable);
229 try formatBytes(args[next_arg], width, context, Errors, output);
230 next_arg += 1;
231 state = State.Start;
232 start_index = i + 1;
233 },
234 '0' ... '9' => {},
235 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
236 },
207 }237 }
208 }238 }
209 comptime {239 comptime {
...@@ -513,7 +543,29 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com...@@ -513,7 +543,29 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com
513 }543 }
514}544}
515545
516pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8) Errors!void) Errors!void {546pub fn formatBytes(value: var, width: ?usize,
547 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
548{
549 if (value == 0) {
550 return output(context, "0B");
551 }
552
553 const mags = " KMGTPEZY";
554 const magnitude = math.min(math.log2(value) / 10, mags.len - 1);
555 const new_value = f64(value) / math.pow(f64, 1024, f64(magnitude));
556 const suffix = mags[magnitude];
557
558 try formatFloatDecimal(new_value, width, context, Errors, output);
559
560 if (suffix != ' ') {
561 try output(context, (&suffix)[0..1]);
562 }
563 return output(context, "B");
564}
565
566pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
567 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
568{
517 if (@typeOf(value).is_signed) {569 if (@typeOf(value).is_signed) {
518 return formatIntSigned(value, base, uppercase, width, context, Errors, output);570 return formatIntSigned(value, base, uppercase, width, context, Errors, output);
519 } else {571 } else {
...@@ -750,6 +802,12 @@ test "fmt.format" {...@@ -750,6 +802,12 @@ test "fmt.format" {
750 const result = try bufPrint(buf1[0..], "u3: {}\n", value);802 const result = try bufPrint(buf1[0..], "u3: {}\n", value);
751 assert(mem.eql(u8, result, "u3: 5\n"));803 assert(mem.eql(u8, result, "u3: 5\n"));
752 }804 }
805 {
806 var buf1: [32]u8 = undefined;
807 const value: usize = 63 * 1024 * 1024;
808 const result = try bufPrint(buf1[0..], "file size: {B}\n", value);
809 assert(mem.eql(u8, result, "file size: 63MB\n"));
810 }
753 {811 {
754 // Dummy field because of https://github.com/zig-lang/zig/issues/557.812 // Dummy field because of https://github.com/zig-lang/zig/issues/557.
755 const Struct = struct {813 const Struct = struct {
std/zig/parse.zig+405-445
...@@ -17,15 +17,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -17,15 +17,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
17 defer stack.deinit();17 defer stack.deinit();
1818
19 const arena = &tree_arena.allocator;19 const arena = &tree_arena.allocator;
20 const root_node = try createNode(arena, ast.Node.Root,20 const root_node = try arena.construct(ast.Node.Root {
21 ast.Node.Root {21 .base = ast.Node { .id = ast.Node.Id.Root },
22 .base = undefined,22 .decls = ast.Node.Root.DeclList.init(arena),
23 .decls = ast.Node.Root.DeclList.init(arena),23 .doc_comments = null,
24 .doc_comments = null,24 // initialized when we get the eof token
25 // initialized when we get the eof token25 .eof_token = undefined,
26 .eof_token = undefined,26 });
27 }
28 );
2927
30 var tree = ast.Tree {28 var tree = ast.Tree {
31 .source = source,29 .source = source,
...@@ -113,15 +111,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -113,15 +111,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
113 continue;111 continue;
114 },112 },
115 Token.Id.Keyword_comptime => {113 Token.Id.Keyword_comptime => {
116 const block = try createNode(arena, ast.Node.Block,114 const block = try arena.construct(ast.Node.Block {
117 ast.Node.Block {115 .base = ast.Node {.id = ast.Node.Id.Block },
118 .base = undefined,116 .label = null,
119 .label = null,117 .lbrace = undefined,
120 .lbrace = undefined,118 .statements = ast.Node.Block.StatementList.init(arena),
121 .statements = ast.Node.Block.StatementList.init(arena),119 .rbrace = undefined,
122 .rbrace = undefined,120 });
123 }
124 );
125 const node = try arena.construct(ast.Node.Comptime {121 const node = try arena.construct(ast.Node.Comptime {
126 .base = ast.Node {122 .base = ast.Node {
127 .id = ast.Node.Id.Comptime,123 .id = ast.Node.Id.Comptime,
...@@ -312,14 +308,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -312,14 +308,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
312 continue;308 continue;
313 },309 },
314 Token.Id.Keyword_async => {310 Token.Id.Keyword_async => {
315 const async_node = try createNode(arena, ast.Node.AsyncAttribute,311 const async_node = try arena.construct(ast.Node.AsyncAttribute {
316 ast.Node.AsyncAttribute {312 .base = ast.Node {.id = ast.Node.Id.AsyncAttribute },
317 .base = undefined,313 .async_token = token_index,
318 .async_token = token_index,314 .allocator_type = null,
319 .allocator_type = null,315 .rangle_bracket = null,
320 .rangle_bracket = null,316 });
321 }
322 );
323 fn_proto.async_attr = async_node;317 fn_proto.async_attr = async_node;
324318
325 try stack.append(State {319 try stack.append(State {
...@@ -396,27 +390,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -396,27 +390,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
396 const token = nextToken(&tok_it, &tree);390 const token = nextToken(&tok_it, &tree);
397 const token_index = token.index;391 const token_index = token.index;
398 const token_ptr = token.ptr;392 const token_ptr = token.ptr;
399 const node = try createToCtxNode(arena, ctx.opt_ctx, ast.Node.ContainerDecl,393 const node = try arena.construct(ast.Node.ContainerDecl {
400 ast.Node.ContainerDecl {394 .base = ast.Node {.id = ast.Node.Id.ContainerDecl },
401 .base = undefined,395 .ltoken = ctx.ltoken,
402 .ltoken = ctx.ltoken,396 .layout = ctx.layout,
403 .layout = ctx.layout,397 .kind = switch (token_ptr.id) {
404 .kind = switch (token_ptr.id) {398 Token.Id.Keyword_struct => ast.Node.ContainerDecl.Kind.Struct,
405 Token.Id.Keyword_struct => ast.Node.ContainerDecl.Kind.Struct,399 Token.Id.Keyword_union => ast.Node.ContainerDecl.Kind.Union,
406 Token.Id.Keyword_union => ast.Node.ContainerDecl.Kind.Union,400 Token.Id.Keyword_enum => ast.Node.ContainerDecl.Kind.Enum,
407 Token.Id.Keyword_enum => ast.Node.ContainerDecl.Kind.Enum,401 else => {
408 else => {402 *(try tree.errors.addOne()) = Error {
409 *(try tree.errors.addOne()) = Error {403 .ExpectedAggregateKw = Error.ExpectedAggregateKw { .token = token_index },
410 .ExpectedAggregateKw = Error.ExpectedAggregateKw { .token = token_index },404 };
411 };405 return tree;
412 return tree;
413 },
414 },406 },
415 .init_arg_expr = ast.Node.ContainerDecl.InitArg.None,407 },
416 .fields_and_decls = ast.Node.ContainerDecl.DeclList.init(arena),408 .init_arg_expr = ast.Node.ContainerDecl.InitArg.None,
417 .rbrace_token = undefined,409 .fields_and_decls = ast.Node.ContainerDecl.DeclList.init(arena),
418 }410 .rbrace_token = undefined,
419 );411 });
412 ctx.opt_ctx.store(&node.base);
420413
421 stack.append(State { .ContainerDecl = node }) catch unreachable;414 stack.append(State { .ContainerDecl = node }) catch unreachable;
422 try stack.append(State { .ExpectToken = Token.Id.LBrace });415 try stack.append(State { .ExpectToken = Token.Id.LBrace });
...@@ -647,12 +640,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -647,12 +640,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
647 switch (token_ptr.id) {640 switch (token_ptr.id) {
648 Token.Id.Equal => {641 Token.Id.Equal => {
649 var_decl.eq_token = token_index;642 var_decl.eq_token = token_index;
650 stack.append(State {643 stack.append(State { .VarDeclSemiColon = var_decl }) catch unreachable;
651 .ExpectTokenSave = ExpectTokenSave {
652 .id = Token.Id.Semicolon,
653 .ptr = &var_decl.semicolon_token,
654 },
655 }) catch unreachable;
656 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.init_node } });644 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.init_node } });
657 continue;645 continue;
658 },646 },
...@@ -669,6 +657,30 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -669,6 +657,30 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
669 }657 }
670 },658 },
671659
660 State.VarDeclSemiColon => |var_decl| {
661 const semicolon_token = nextToken(&tok_it, &tree);
662
663 if (semicolon_token.ptr.id != Token.Id.Semicolon) {
664 *(try tree.errors.addOne()) = Error {
665 .ExpectedToken = Error.ExpectedToken {
666 .token = semicolon_token.index,
667 .expected_id = Token.Id.Semicolon,
668 },
669 };
670 return tree;
671 }
672
673 var_decl.semicolon_token = semicolon_token.index;
674
675 if (eatToken(&tok_it, &tree, Token.Id.DocComment)) |doc_comment_token| {
676 const loc = tree.tokenLocation(semicolon_token.ptr.end, doc_comment_token);
677 if (loc.line == 0) {
678 try pushDocComment(arena, doc_comment_token, &var_decl.doc_comments);
679 } else {
680 putBackToken(&tok_it, &tree);
681 }
682 }
683 },
672684
673 State.FnDef => |fn_proto| {685 State.FnDef => |fn_proto| {
674 const token = nextToken(&tok_it, &tree);686 const token = nextToken(&tok_it, &tree);
...@@ -844,15 +856,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -844,15 +856,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
844 const token_ptr = token.ptr;856 const token_ptr = token.ptr;
845 switch (token_ptr.id) {857 switch (token_ptr.id) {
846 Token.Id.LBrace => {858 Token.Id.LBrace => {
847 const block = try createToCtxNode(arena, ctx.opt_ctx, ast.Node.Block,859 const block = try arena.construct(ast.Node.Block {
848 ast.Node.Block {860 .base = ast.Node {.id = ast.Node.Id.Block},
849 .base = undefined,861 .label = ctx.label,
850 .label = ctx.label,862 .lbrace = token_index,
851 .lbrace = token_index,863 .statements = ast.Node.Block.StatementList.init(arena),
852 .statements = ast.Node.Block.StatementList.init(arena),864 .rbrace = undefined,
853 .rbrace = undefined,865 });
854 }866 ctx.opt_ctx.store(&block.base);
855 );
856 stack.append(State { .Block = block }) catch unreachable;867 stack.append(State { .Block = block }) catch unreachable;
857 continue;868 continue;
858 },869 },
...@@ -957,19 +968,18 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -957,19 +968,18 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
957 }968 }
958 },969 },
959 State.While => |ctx| {970 State.While => |ctx| {
960 const node = try createToCtxNode(arena, ctx.opt_ctx, ast.Node.While,971 const node = try arena.construct(ast.Node.While {
961 ast.Node.While {972 .base = ast.Node {.id = ast.Node.Id.While },
962 .base = undefined,973 .label = ctx.label,
963 .label = ctx.label,974 .inline_token = ctx.inline_token,
964 .inline_token = ctx.inline_token,975 .while_token = ctx.loop_token,
965 .while_token = ctx.loop_token,976 .condition = undefined,
966 .condition = undefined,977 .payload = null,
967 .payload = null,978 .continue_expr = null,
968 .continue_expr = null,979 .body = undefined,
969 .body = undefined,980 .@"else" = null,
970 .@"else" = null,981 });
971 }982 ctx.opt_ctx.store(&node.base);
972 );
973 stack.append(State { .Else = &node.@"else" }) catch unreachable;983 stack.append(State { .Else = &node.@"else" }) catch unreachable;
974 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });984 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });
975 try stack.append(State { .WhileContinueExpr = &node.continue_expr });985 try stack.append(State { .WhileContinueExpr = &node.continue_expr });
...@@ -987,18 +997,17 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -987,18 +997,17 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
987 continue;997 continue;
988 },998 },
989 State.For => |ctx| {999 State.For => |ctx| {
990 const node = try createToCtxNode(arena, ctx.opt_ctx, ast.Node.For,1000 const node = try arena.construct(ast.Node.For {
991 ast.Node.For {1001 .base = ast.Node {.id = ast.Node.Id.For },
992 .base = undefined,1002 .label = ctx.label,
993 .label = ctx.label,1003 .inline_token = ctx.inline_token,
994 .inline_token = ctx.inline_token,1004 .for_token = ctx.loop_token,
995 .for_token = ctx.loop_token,1005 .array_expr = undefined,
996 .array_expr = undefined,1006 .payload = null,
997 .payload = null,1007 .body = undefined,
998 .body = undefined,1008 .@"else" = null,
999 .@"else" = null,1009 });
1000 }1010 ctx.opt_ctx.store(&node.base);
1001 );
1002 stack.append(State { .Else = &node.@"else" }) catch unreachable;1011 stack.append(State { .Else = &node.@"else" }) catch unreachable;
1003 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });1012 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });
1004 try stack.append(State { .PointerIndexPayload = OptionalCtx { .Optional = &node.payload } });1013 try stack.append(State { .PointerIndexPayload = OptionalCtx { .Optional = &node.payload } });
...@@ -1009,14 +1018,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1009,14 +1018,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1009 },1018 },
1010 State.Else => |dest| {1019 State.Else => |dest| {
1011 if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| {1020 if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| {
1012 const node = try createNode(arena, ast.Node.Else,1021 const node = try arena.construct(ast.Node.Else {
1013 ast.Node.Else {1022 .base = ast.Node {.id = ast.Node.Id.Else },
1014 .base = undefined,1023 .else_token = else_token,
1015 .else_token = else_token,1024 .payload = null,
1016 .payload = null,1025 .body = undefined,
1017 .body = undefined,1026 });
1018 }
1019 );
1020 *dest = node;1027 *dest = node;
10211028
1022 stack.append(State { .Expression = OptionalCtx { .Required = &node.body } }) catch unreachable;1029 stack.append(State { .Expression = OptionalCtx { .Required = &node.body } }) catch unreachable;
...@@ -1170,14 +1177,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1170,14 +1177,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1170 continue;1177 continue;
1171 }1178 }
11721179
1173 const node = try createNode(arena, ast.Node.AsmOutput,1180 const node = try arena.construct(ast.Node.AsmOutput {
1174 ast.Node.AsmOutput {1181 .base = ast.Node {.id = ast.Node.Id.AsmOutput },
1175 .base = undefined,1182 .symbolic_name = undefined,
1176 .symbolic_name = undefined,1183 .constraint = undefined,
1177 .constraint = undefined,1184 .kind = undefined,
1178 .kind = undefined,1185 });
1179 }
1180 );
1181 try items.push(node);1186 try items.push(node);
11821187
1183 stack.append(State { .AsmOutputItems = items }) catch unreachable;1188 stack.append(State { .AsmOutputItems = items }) catch unreachable;
...@@ -1223,14 +1228,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1223,14 +1228,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1223 continue;1228 continue;
1224 }1229 }
12251230
1226 const node = try createNode(arena, ast.Node.AsmInput,1231 const node = try arena.construct(ast.Node.AsmInput {
1227 ast.Node.AsmInput {1232 .base = ast.Node {.id = ast.Node.Id.AsmInput },
1228 .base = undefined,1233 .symbolic_name = undefined,
1229 .symbolic_name = undefined,1234 .constraint = undefined,
1230 .constraint = undefined,1235 .expr = undefined,
1231 .expr = undefined,1236 });
1232 }
1233 );
1234 try items.push(node);1237 try items.push(node);
12351238
1236 stack.append(State { .AsmInputItems = items }) catch unreachable;1239 stack.append(State { .AsmInputItems = items }) catch unreachable;
...@@ -1668,14 +1671,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1668,14 +1671,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1668 continue;1671 continue;
1669 }1672 }
16701673
1671 const node = try createToCtxNode(arena, opt_ctx, ast.Node.Payload,1674 const node = try arena.construct(ast.Node.Payload {
1672 ast.Node.Payload {1675 .base = ast.Node {.id = ast.Node.Id.Payload },
1673 .base = undefined,1676 .lpipe = token_index,
1674 .lpipe = token_index,1677 .error_symbol = undefined,
1675 .error_symbol = undefined,1678 .rpipe = undefined
1676 .rpipe = undefined1679 });
1677 }1680 opt_ctx.store(&node.base);
1678 );
16791681
1680 stack.append(State {1682 stack.append(State {
1681 .ExpectTokenSave = ExpectTokenSave {1683 .ExpectTokenSave = ExpectTokenSave {
...@@ -1705,15 +1707,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1705,15 +1707,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1705 continue;1707 continue;
1706 }1708 }
17071709
1708 const node = try createToCtxNode(arena, opt_ctx, ast.Node.PointerPayload,1710 const node = try arena.construct(ast.Node.PointerPayload {
1709 ast.Node.PointerPayload {1711 .base = ast.Node {.id = ast.Node.Id.PointerPayload },
1710 .base = undefined,1712 .lpipe = token_index,
1711 .lpipe = token_index,1713 .ptr_token = null,
1712 .ptr_token = null,1714 .value_symbol = undefined,
1713 .value_symbol = undefined,1715 .rpipe = undefined
1714 .rpipe = undefined1716 });
1715 }1717 opt_ctx.store(&node.base);
1716 );
17171718
1718 try stack.append(State {1719 try stack.append(State {
1719 .ExpectTokenSave = ExpectTokenSave {1720 .ExpectTokenSave = ExpectTokenSave {
...@@ -1749,16 +1750,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1749,16 +1750,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1749 continue;1750 continue;
1750 }1751 }
17511752
1752 const node = try createToCtxNode(arena, opt_ctx, ast.Node.PointerIndexPayload,1753 const node = try arena.construct(ast.Node.PointerIndexPayload {
1753 ast.Node.PointerIndexPayload {1754 .base = ast.Node {.id = ast.Node.Id.PointerIndexPayload },
1754 .base = undefined,1755 .lpipe = token_index,
1755 .lpipe = token_index,1756 .ptr_token = null,
1756 .ptr_token = null,1757 .value_symbol = undefined,
1757 .value_symbol = undefined,1758 .index_symbol = null,
1758 .index_symbol = null,1759 .rpipe = undefined
1759 .rpipe = undefined1760 });
1760 }1761 opt_ctx.store(&node.base);
1761 );
17621762
1763 stack.append(State {1763 stack.append(State {
1764 .ExpectTokenSave = ExpectTokenSave {1764 .ExpectTokenSave = ExpectTokenSave {
...@@ -1785,14 +1785,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1785,14 +1785,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1785 const token_ptr = token.ptr;1785 const token_ptr = token.ptr;
1786 switch (token_ptr.id) {1786 switch (token_ptr.id) {
1787 Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => {1787 Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => {
1788 const node = try createToCtxNode(arena, opt_ctx, ast.Node.ControlFlowExpression,1788 const node = try arena.construct(ast.Node.ControlFlowExpression {
1789 ast.Node.ControlFlowExpression {1789 .base = ast.Node {.id = ast.Node.Id.ControlFlowExpression },
1790 .base = undefined,1790 .ltoken = token_index,
1791 .ltoken = token_index,1791 .kind = undefined,
1792 .kind = undefined,1792 .rhs = null,
1793 .rhs = null,1793 });
1794 }1794 opt_ctx.store(&node.base);
1795 );
17961795
1797 stack.append(State { .Expression = OptionalCtx { .Optional = &node.rhs } }) catch unreachable;1796 stack.append(State { .Expression = OptionalCtx { .Optional = &node.rhs } }) catch unreachable;
17981797
...@@ -1815,19 +1814,18 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1815,19 +1814,18 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1815 continue;1814 continue;
1816 },1815 },
1817 Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {1816 Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {
1818 const node = try createToCtxNode(arena, opt_ctx, ast.Node.PrefixOp,1817 const node = try arena.construct(ast.Node.PrefixOp {
1819 ast.Node.PrefixOp {1818 .base = ast.Node {.id = ast.Node.Id.PrefixOp },
1820 .base = undefined,1819 .op_token = token_index,
1821 .op_token = token_index,1820 .op = switch (token_ptr.id) {
1822 .op = switch (token_ptr.id) {1821 Token.Id.Keyword_try => ast.Node.PrefixOp.Op { .Try = void{} },
1823 Token.Id.Keyword_try => ast.Node.PrefixOp.Op { .Try = void{} },1822 Token.Id.Keyword_cancel => ast.Node.PrefixOp.Op { .Cancel = void{} },
1824 Token.Id.Keyword_cancel => ast.Node.PrefixOp.Op { .Cancel = void{} },1823 Token.Id.Keyword_resume => ast.Node.PrefixOp.Op { .Resume = void{} },
1825 Token.Id.Keyword_resume => ast.Node.PrefixOp.Op { .Resume = void{} },1824 else => unreachable,
1826 else => unreachable,1825 },
1827 },1826 .rhs = undefined,
1828 .rhs = undefined,1827 });
1829 }1828 opt_ctx.store(&node.base);
1830 );
18311829
1832 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;1830 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1833 continue;1831 continue;
...@@ -1850,15 +1848,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1850,15 +1848,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1850 const lhs = opt_ctx.get() ?? continue;1848 const lhs = opt_ctx.get() ?? continue;
18511849
1852 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {1850 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {
1853 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1851 const node = try arena.construct(ast.Node.InfixOp {
1854 ast.Node.InfixOp {1852 .base = ast.Node {.id = ast.Node.Id.InfixOp },
1855 .base = undefined,1853 .lhs = lhs,
1856 .lhs = lhs,1854 .op_token = ellipsis3,
1857 .op_token = ellipsis3,1855 .op = ast.Node.InfixOp.Op.Range,
1858 .op = ast.Node.InfixOp.Op.Range,1856 .rhs = undefined,
1859 .rhs = undefined,1857 });
1860 }1858 opt_ctx.store(&node.base);
1861 );
1862 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;1859 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1863 continue;1860 continue;
1864 }1861 }
...@@ -1876,15 +1873,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1876,15 +1873,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1876 const token_index = token.index;1873 const token_index = token.index;
1877 const token_ptr = token.ptr;1874 const token_ptr = token.ptr;
1878 if (tokenIdToAssignment(token_ptr.id)) |ass_id| {1875 if (tokenIdToAssignment(token_ptr.id)) |ass_id| {
1879 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1876 const node = try arena.construct(ast.Node.InfixOp {
1880 ast.Node.InfixOp {1877 .base = ast.Node {.id = ast.Node.Id.InfixOp },
1881 .base = undefined,1878 .lhs = lhs,
1882 .lhs = lhs,1879 .op_token = token_index,
1883 .op_token = token_index,1880 .op = ass_id,
1884 .op = ass_id,1881 .rhs = undefined,
1885 .rhs = undefined,1882 });
1886 }1883 opt_ctx.store(&node.base);
1887 );
1888 stack.append(State { .AssignmentExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1884 stack.append(State { .AssignmentExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1889 try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });1885 try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });
1890 continue;1886 continue;
...@@ -1907,15 +1903,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1907,15 +1903,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1907 const token_index = token.index;1903 const token_index = token.index;
1908 const token_ptr = token.ptr;1904 const token_ptr = token.ptr;
1909 if (tokenIdToUnwrapExpr(token_ptr.id)) |unwrap_id| {1905 if (tokenIdToUnwrapExpr(token_ptr.id)) |unwrap_id| {
1910 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1906 const node = try arena.construct(ast.Node.InfixOp {
1911 ast.Node.InfixOp {1907 .base = ast.Node {.id = ast.Node.Id.InfixOp },
1912 .base = undefined,1908 .lhs = lhs,
1913 .lhs = lhs,1909 .op_token = token_index,
1914 .op_token = token_index,1910 .op = unwrap_id,
1915 .op = unwrap_id,1911 .rhs = undefined,
1916 .rhs = undefined,1912 });
1917 }1913 opt_ctx.store(&node.base);
1918 );
19191914
1920 stack.append(State { .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1915 stack.append(State { .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1921 try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });1916 try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });
...@@ -1940,15 +1935,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1940,15 +1935,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1940 const lhs = opt_ctx.get() ?? continue;1935 const lhs = opt_ctx.get() ?? continue;
19411936
1942 if (eatToken(&tok_it, &tree, Token.Id.Keyword_or)) |or_token| {1937 if (eatToken(&tok_it, &tree, Token.Id.Keyword_or)) |or_token| {
1943 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1938 const node = try arena.construct(ast.Node.InfixOp {
1944 ast.Node.InfixOp {1939 .base = ast.Node {.id = ast.Node.Id.InfixOp },
1945 .base = undefined,1940 .lhs = lhs,
1946 .lhs = lhs,1941 .op_token = or_token,
1947 .op_token = or_token,1942 .op = ast.Node.InfixOp.Op.BoolOr,
1948 .op = ast.Node.InfixOp.Op.BoolOr,1943 .rhs = undefined,
1949 .rhs = undefined,1944 });
1950 }1945 opt_ctx.store(&node.base);
1951 );
1952 stack.append(State { .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1946 stack.append(State { .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1953 try stack.append(State { .BoolAndExpressionBegin = OptionalCtx { .Required = &node.rhs } });1947 try stack.append(State { .BoolAndExpressionBegin = OptionalCtx { .Required = &node.rhs } });
1954 continue;1948 continue;
...@@ -1965,15 +1959,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1965,15 +1959,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1965 const lhs = opt_ctx.get() ?? continue;1959 const lhs = opt_ctx.get() ?? continue;
19661960
1967 if (eatToken(&tok_it, &tree, Token.Id.Keyword_and)) |and_token| {1961 if (eatToken(&tok_it, &tree, Token.Id.Keyword_and)) |and_token| {
1968 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1962 const node = try arena.construct(ast.Node.InfixOp {
1969 ast.Node.InfixOp {1963 .base = ast.Node {.id = ast.Node.Id.InfixOp },
1970 .base = undefined,1964 .lhs = lhs,
1971 .lhs = lhs,1965 .op_token = and_token,
1972 .op_token = and_token,1966 .op = ast.Node.InfixOp.Op.BoolAnd,
1973 .op = ast.Node.InfixOp.Op.BoolAnd,1967 .rhs = undefined,
1974 .rhs = undefined,1968 });
1975 }1969 opt_ctx.store(&node.base);
1976 );
1977 stack.append(State { .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1970 stack.append(State { .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1978 try stack.append(State { .ComparisonExpressionBegin = OptionalCtx { .Required = &node.rhs } });1971 try stack.append(State { .ComparisonExpressionBegin = OptionalCtx { .Required = &node.rhs } });
1979 continue;1972 continue;
...@@ -1993,15 +1986,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1993,15 +1986,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1993 const token_index = token.index;1986 const token_index = token.index;
1994 const token_ptr = token.ptr;1987 const token_ptr = token.ptr;
1995 if (tokenIdToComparison(token_ptr.id)) |comp_id| {1988 if (tokenIdToComparison(token_ptr.id)) |comp_id| {
1996 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1989 const node = try arena.construct(ast.Node.InfixOp {
1997 ast.Node.InfixOp {1990 .base = ast.Node {.id = ast.Node.Id.InfixOp },
1998 .base = undefined,1991 .lhs = lhs,
1999 .lhs = lhs,1992 .op_token = token_index,
2000 .op_token = token_index,1993 .op = comp_id,
2001 .op = comp_id,1994 .rhs = undefined,
2002 .rhs = undefined,1995 });
2003 }1996 opt_ctx.store(&node.base);
2004 );
2005 stack.append(State { .ComparisonExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1997 stack.append(State { .ComparisonExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2006 try stack.append(State { .BinaryOrExpressionBegin = OptionalCtx { .Required = &node.rhs } });1998 try stack.append(State { .BinaryOrExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2007 continue;1999 continue;
...@@ -2021,15 +2013,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2021,15 +2013,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2021 const lhs = opt_ctx.get() ?? continue;2013 const lhs = opt_ctx.get() ?? continue;
20222014
2023 if (eatToken(&tok_it, &tree, Token.Id.Pipe)) |pipe| {2015 if (eatToken(&tok_it, &tree, Token.Id.Pipe)) |pipe| {
2024 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2016 const node = try arena.construct(ast.Node.InfixOp {
2025 ast.Node.InfixOp {2017 .base = ast.Node {.id = ast.Node.Id.InfixOp },
2026 .base = undefined,2018 .lhs = lhs,
2027 .lhs = lhs,2019 .op_token = pipe,
2028 .op_token = pipe,2020 .op = ast.Node.InfixOp.Op.BitOr,
2029 .op = ast.Node.InfixOp.Op.BitOr,2021 .rhs = undefined,
2030 .rhs = undefined,2022 });
2031 }2023 opt_ctx.store(&node.base);
2032 );
2033 stack.append(State { .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2024 stack.append(State { .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2034 try stack.append(State { .BinaryXorExpressionBegin = OptionalCtx { .Required = &node.rhs } });2025 try stack.append(State { .BinaryXorExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2035 continue;2026 continue;
...@@ -2046,15 +2037,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2046,15 +2037,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2046 const lhs = opt_ctx.get() ?? continue;2037 const lhs = opt_ctx.get() ?? continue;
20472038
2048 if (eatToken(&tok_it, &tree, Token.Id.Caret)) |caret| {2039 if (eatToken(&tok_it, &tree, Token.Id.Caret)) |caret| {
2049 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2040 const node = try arena.construct(ast.Node.InfixOp {
2050 ast.Node.InfixOp {2041 .base = ast.Node {.id = ast.Node.Id.InfixOp },
2051 .base = undefined,2042 .lhs = lhs,
2052 .lhs = lhs,2043 .op_token = caret,
2053 .op_token = caret,2044 .op = ast.Node.InfixOp.Op.BitXor,
2054 .op = ast.Node.InfixOp.Op.BitXor,2045 .rhs = undefined,
2055 .rhs = undefined,2046 });
2056 }2047 opt_ctx.store(&node.base);
2057 );
2058 stack.append(State { .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2048 stack.append(State { .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2059 try stack.append(State { .BinaryAndExpressionBegin = OptionalCtx { .Required = &node.rhs } });2049 try stack.append(State { .BinaryAndExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2060 continue;2050 continue;
...@@ -2071,15 +2061,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2071,15 +2061,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2071 const lhs = opt_ctx.get() ?? continue;2061 const lhs = opt_ctx.get() ?? continue;
20722062
2073 if (eatToken(&tok_it, &tree, Token.Id.Ampersand)) |ampersand| {2063 if (eatToken(&tok_it, &tree, Token.Id.Ampersand)) |ampersand| {
2074 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2064 const node = try arena.construct(ast.Node.InfixOp {
2075 ast.Node.InfixOp {2065 .base = ast.Node {.id = ast.Node.Id.InfixOp },
2076 .base = undefined,2066 .lhs = lhs,
2077 .lhs = lhs,2067 .op_token = ampersand,
2078 .op_token = ampersand,2068 .op = ast.Node.InfixOp.Op.BitAnd,
2079 .op = ast.Node.InfixOp.Op.BitAnd,2069 .rhs = undefined,
2080 .rhs = undefined,2070 });
2081 }2071 opt_ctx.store(&node.base);
2082 );
2083 stack.append(State { .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2072 stack.append(State { .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2084 try stack.append(State { .BitShiftExpressionBegin = OptionalCtx { .Required = &node.rhs } });2073 try stack.append(State { .BitShiftExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2085 continue;2074 continue;
...@@ -2099,15 +2088,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2099,15 +2088,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2099 const token_index = token.index;2088 const token_index = token.index;
2100 const token_ptr = token.ptr;2089 const token_ptr = token.ptr;
2101 if (tokenIdToBitShift(token_ptr.id)) |bitshift_id| {2090 if (tokenIdToBitShift(token_ptr.id)) |bitshift_id| {
2102 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2091 const node = try arena.construct(ast.Node.InfixOp {
2103 ast.Node.InfixOp {2092 .base = ast.Node {.id = ast.Node.Id.InfixOp },
2104 .base = undefined,2093 .lhs = lhs,
2105 .lhs = lhs,2094 .op_token = token_index,
2106 .op_token = token_index,2095 .op = bitshift_id,
2107 .op = bitshift_id,2096 .rhs = undefined,
2108 .rhs = undefined,2097 });
2109 }2098 opt_ctx.store(&node.base);
2110 );
2111 stack.append(State { .BitShiftExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2099 stack.append(State { .BitShiftExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2112 try stack.append(State { .AdditionExpressionBegin = OptionalCtx { .Required = &node.rhs } });2100 try stack.append(State { .AdditionExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2113 continue;2101 continue;
...@@ -2130,15 +2118,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2130,15 +2118,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2130 const token_index = token.index;2118 const token_index = token.index;
2131 const token_ptr = token.ptr;2119 const token_ptr = token.ptr;
2132 if (tokenIdToAddition(token_ptr.id)) |add_id| {2120 if (tokenIdToAddition(token_ptr.id)) |add_id| {
2133 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2121 const node = try arena.construct(ast.Node.InfixOp {
2134 ast.Node.InfixOp {2122 .base = ast.Node {.id = ast.Node.Id.InfixOp },
2135 .base = undefined,2123 .lhs = lhs,
2136 .lhs = lhs,2124 .op_token = token_index,
2137 .op_token = token_index,2125 .op = add_id,
2138 .op = add_id,2126 .rhs = undefined,
2139 .rhs = undefined,2127 });
2140 }2128 opt_ctx.store(&node.base);
2141 );
2142 stack.append(State { .AdditionExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2129 stack.append(State { .AdditionExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2143 try stack.append(State { .MultiplyExpressionBegin = OptionalCtx { .Required = &node.rhs } });2130 try stack.append(State { .MultiplyExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2144 continue;2131 continue;
...@@ -2161,15 +2148,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2161,15 +2148,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2161 const token_index = token.index;2148 const token_index = token.index;
2162 const token_ptr = token.ptr;2149 const token_ptr = token.ptr;
2163 if (tokenIdToMultiply(token_ptr.id)) |mult_id| {2150 if (tokenIdToMultiply(token_ptr.id)) |mult_id| {
2164 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2151 const node = try arena.construct(ast.Node.InfixOp {
2165 ast.Node.InfixOp {2152 .base = ast.Node {.id = ast.Node.Id.InfixOp },
2166 .base = undefined,2153 .lhs = lhs,
2167 .lhs = lhs,2154 .op_token = token_index,
2168 .op_token = token_index,2155 .op = mult_id,
2169 .op = mult_id,2156 .rhs = undefined,
2170 .rhs = undefined,2157 });
2171 }2158 opt_ctx.store(&node.base);
2172 );
2173 stack.append(State { .MultiplyExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2159 stack.append(State { .MultiplyExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2174 try stack.append(State { .CurlySuffixExpressionBegin = OptionalCtx { .Required = &node.rhs } });2160 try stack.append(State { .CurlySuffixExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2175 continue;2161 continue;
...@@ -2211,16 +2197,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2211,16 +2197,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2211 continue;2197 continue;
2212 }2198 }
22132199
2214 const node = try createToCtxNode(arena, opt_ctx, ast.Node.SuffixOp,2200 const node = try arena.construct(ast.Node.SuffixOp {
2215 ast.Node.SuffixOp {2201 .base = ast.Node {.id = ast.Node.Id.SuffixOp },
2216 .base = undefined,2202 .lhs = lhs,
2217 .lhs = lhs,2203 .op = ast.Node.SuffixOp.Op {
2218 .op = ast.Node.SuffixOp.Op {2204 .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(arena),
2219 .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(arena),2205 },
2220 },2206 .rtoken = undefined,
2221 .rtoken = undefined,2207 });
2222 }2208 opt_ctx.store(&node.base);
2223 );
2224 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2209 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2225 try stack.append(State { .IfToken = Token.Id.LBrace });2210 try stack.append(State { .IfToken = Token.Id.LBrace });
2226 try stack.append(State {2211 try stack.append(State {
...@@ -2243,15 +2228,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2243,15 +2228,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2243 const lhs = opt_ctx.get() ?? continue;2228 const lhs = opt_ctx.get() ?? continue;
22442229
2245 if (eatToken(&tok_it, &tree, Token.Id.Bang)) |bang| {2230 if (eatToken(&tok_it, &tree, Token.Id.Bang)) |bang| {
2246 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2231 const node = try arena.construct(ast.Node.InfixOp {
2247 ast.Node.InfixOp {2232 .base = ast.Node {.id = ast.Node.Id.InfixOp },
2248 .base = undefined,2233 .lhs = lhs,
2249 .lhs = lhs,2234 .op_token = bang,
2250 .op_token = bang,2235 .op = ast.Node.InfixOp.Op.ErrorUnion,
2251 .op = ast.Node.InfixOp.Op.ErrorUnion,2236 .rhs = undefined,
2252 .rhs = undefined,2237 });
2253 }2238 opt_ctx.store(&node.base);
2254 );
2255 stack.append(State { .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable;2239 stack.append(State { .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable;
2256 try stack.append(State { .PrefixOpExpression = OptionalCtx { .Required = &node.rhs } });2240 try stack.append(State { .PrefixOpExpression = OptionalCtx { .Required = &node.rhs } });
2257 continue;2241 continue;
...@@ -2263,25 +2247,22 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2263,25 +2247,22 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2263 const token_index = token.index;2247 const token_index = token.index;
2264 const token_ptr = token.ptr;2248 const token_ptr = token.ptr;
2265 if (tokenIdToPrefixOp(token_ptr.id)) |prefix_id| {2249 if (tokenIdToPrefixOp(token_ptr.id)) |prefix_id| {
2266 var node = try createToCtxNode(arena, opt_ctx, ast.Node.PrefixOp,2250 var node = try arena.construct(ast.Node.PrefixOp {
2267 ast.Node.PrefixOp {2251 .base = ast.Node {.id = ast.Node.Id.PrefixOp },
2268 .base = undefined,2252 .op_token = token_index,
2269 .op_token = token_index,2253 .op = prefix_id,
2270 .op = prefix_id,2254 .rhs = undefined,
2271 .rhs = undefined,2255 });
2272 }2256 opt_ctx.store(&node.base);
2273 );
22742257
2275 // Treat '**' token as two derefs2258 // Treat '**' token as two derefs
2276 if (token_ptr.id == Token.Id.AsteriskAsterisk) {2259 if (token_ptr.id == Token.Id.AsteriskAsterisk) {
2277 const child = try createNode(arena, ast.Node.PrefixOp,2260 const child = try arena.construct(ast.Node.PrefixOp {
2278 ast.Node.PrefixOp {2261 .base = ast.Node {.id = ast.Node.Id.PrefixOp},
2279 .base = undefined,2262 .op_token = token_index,
2280 .op_token = token_index,2263 .op = prefix_id,
2281 .op = prefix_id,2264 .rhs = undefined,
2282 .rhs = undefined,2265 });
2283 }
2284 );
2285 node.rhs = &child.base;2266 node.rhs = &child.base;
2286 node = child;2267 node = child;
2287 }2268 }
...@@ -2300,14 +2281,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2300,14 +2281,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
23002281
2301 State.SuffixOpExpressionBegin => |opt_ctx| {2282 State.SuffixOpExpressionBegin => |opt_ctx| {
2302 if (eatToken(&tok_it, &tree, Token.Id.Keyword_async)) |async_token| {2283 if (eatToken(&tok_it, &tree, Token.Id.Keyword_async)) |async_token| {
2303 const async_node = try createNode(arena, ast.Node.AsyncAttribute,2284 const async_node = try arena.construct(ast.Node.AsyncAttribute {
2304 ast.Node.AsyncAttribute {2285 .base = ast.Node {.id = ast.Node.Id.AsyncAttribute},
2305 .base = undefined,2286 .async_token = async_token,
2306 .async_token = async_token,2287 .allocator_type = null,
2307 .allocator_type = null,2288 .rangle_bracket = null,
2308 .rangle_bracket = null,2289 });
2309 }
2310 );
2311 stack.append(State {2290 stack.append(State {
2312 .AsyncEnd = AsyncEndCtx {2291 .AsyncEnd = AsyncEndCtx {
2313 .ctx = opt_ctx,2292 .ctx = opt_ctx,
...@@ -2333,19 +2312,19 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2333,19 +2312,19 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2333 const token_ptr = token.ptr;2312 const token_ptr = token.ptr;
2334 switch (token_ptr.id) {2313 switch (token_ptr.id) {
2335 Token.Id.LParen => {2314 Token.Id.LParen => {
2336 const node = try createToCtxNode(arena, opt_ctx, ast.Node.SuffixOp,2315 const node = try arena.construct(ast.Node.SuffixOp {
2337 ast.Node.SuffixOp {2316 .base = ast.Node {.id = ast.Node.Id.SuffixOp },
2338 .base = undefined,2317 .lhs = lhs,
2339 .lhs = lhs,2318 .op = ast.Node.SuffixOp.Op {
2340 .op = ast.Node.SuffixOp.Op {2319 .Call = ast.Node.SuffixOp.Op.Call {
2341 .Call = ast.Node.SuffixOp.Op.Call {2320 .params = ast.Node.SuffixOp.Op.Call.ParamList.init(arena),
2342 .params = ast.Node.SuffixOp.Op.Call.ParamList.init(arena),2321 .async_attr = null,
2343 .async_attr = null,2322 }
2344 }2323 },
2345 },2324 .rtoken = undefined,
2346 .rtoken = undefined,2325 });
2347 }2326 opt_ctx.store(&node.base);
2348 );2327
2349 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2328 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2350 try stack.append(State {2329 try stack.append(State {
2351 .ExprListItemOrEnd = ExprListCtx {2330 .ExprListItemOrEnd = ExprListCtx {
...@@ -2357,31 +2336,31 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2357,31 +2336,31 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2357 continue;2336 continue;
2358 },2337 },
2359 Token.Id.LBracket => {2338 Token.Id.LBracket => {
2360 const node = try createToCtxNode(arena, opt_ctx, ast.Node.SuffixOp,2339 const node = try arena.construct(ast.Node.SuffixOp {
2361 ast.Node.SuffixOp {2340 .base = ast.Node {.id = ast.Node.Id.SuffixOp },
2362 .base = undefined,2341 .lhs = lhs,
2363 .lhs = lhs,2342 .op = ast.Node.SuffixOp.Op {
2364 .op = ast.Node.SuffixOp.Op {2343 .ArrayAccess = undefined,
2365 .ArrayAccess = undefined,2344 },
2366 },2345 .rtoken = undefined
2367 .rtoken = undefined2346 });
2368 }2347 opt_ctx.store(&node.base);
2369 );2348
2370 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2349 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2371 try stack.append(State { .SliceOrArrayAccess = node });2350 try stack.append(State { .SliceOrArrayAccess = node });
2372 try stack.append(State { .Expression = OptionalCtx { .Required = &node.op.ArrayAccess }});2351 try stack.append(State { .Expression = OptionalCtx { .Required = &node.op.ArrayAccess }});
2373 continue;2352 continue;
2374 },2353 },
2375 Token.Id.Period => {2354 Token.Id.Period => {
2376 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2355 const node = try arena.construct(ast.Node.InfixOp {
2377 ast.Node.InfixOp {2356 .base = ast.Node {.id = ast.Node.Id.InfixOp },
2378 .base = undefined,2357 .lhs = lhs,
2379 .lhs = lhs,2358 .op_token = token_index,
2380 .op_token = token_index,2359 .op = ast.Node.InfixOp.Op.Period,
2381 .op = ast.Node.InfixOp.Op.Period,2360 .rhs = undefined,
2382 .rhs = undefined,2361 });
2383 }2362 opt_ctx.store(&node.base);
2384 );2363
2385 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2364 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2386 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.rhs } });2365 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.rhs } });
2387 continue;2366 continue;
...@@ -2461,14 +2440,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2461,14 +2440,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2461 continue;2440 continue;
2462 },2441 },
2463 Token.Id.LParen => {2442 Token.Id.LParen => {
2464 const node = try createToCtxNode(arena, opt_ctx, ast.Node.GroupedExpression,2443 const node = try arena.construct(ast.Node.GroupedExpression {
2465 ast.Node.GroupedExpression {2444 .base = ast.Node {.id = ast.Node.Id.GroupedExpression },
2466 .base = undefined,2445 .lparen = token.index,
2467 .lparen = token.index,2446 .expr = undefined,
2468 .expr = undefined,2447 .rparen = undefined,
2469 .rparen = undefined,2448 });
2470 }2449 opt_ctx.store(&node.base);
2471 );2450
2472 stack.append(State {2451 stack.append(State {
2473 .ExpectTokenSave = ExpectTokenSave {2452 .ExpectTokenSave = ExpectTokenSave {
2474 .id = Token.Id.RParen,2453 .id = Token.Id.RParen,
...@@ -2479,14 +2458,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2479,14 +2458,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2479 continue;2458 continue;
2480 },2459 },
2481 Token.Id.Builtin => {2460 Token.Id.Builtin => {
2482 const node = try createToCtxNode(arena, opt_ctx, ast.Node.BuiltinCall,2461 const node = try arena.construct(ast.Node.BuiltinCall {
2483 ast.Node.BuiltinCall {2462 .base = ast.Node {.id = ast.Node.Id.BuiltinCall },
2484 .base = undefined,2463 .builtin_token = token.index,
2485 .builtin_token = token.index,2464 .params = ast.Node.BuiltinCall.ParamList.init(arena),
2486 .params = ast.Node.BuiltinCall.ParamList.init(arena),2465 .rparen_token = undefined,
2487 .rparen_token = undefined,2466 });
2488 }2467 opt_ctx.store(&node.base);
2489 );2468
2490 stack.append(State {2469 stack.append(State {
2491 .ExprListItemOrEnd = ExprListCtx {2470 .ExprListItemOrEnd = ExprListCtx {
2492 .list = &node.params,2471 .list = &node.params,
...@@ -2498,14 +2477,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2498,14 +2477,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2498 continue;2477 continue;
2499 },2478 },
2500 Token.Id.LBracket => {2479 Token.Id.LBracket => {
2501 const node = try createToCtxNode(arena, opt_ctx, ast.Node.PrefixOp,2480 const node = try arena.construct(ast.Node.PrefixOp {
2502 ast.Node.PrefixOp {2481 .base = ast.Node {.id = ast.Node.Id.PrefixOp },
2503 .base = undefined,2482 .op_token = token.index,
2504 .op_token = token.index,2483 .op = undefined,
2505 .op = undefined,2484 .rhs = undefined,
2506 .rhs = undefined,2485 });
2507 }2486 opt_ctx.store(&node.base);
2508 );2487
2509 stack.append(State { .SliceOrArrayType = node }) catch unreachable;2488 stack.append(State { .SliceOrArrayType = node }) catch unreachable;
2510 continue;2489 continue;
2511 },2490 },
...@@ -2611,18 +2590,18 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2611,18 +2590,18 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2611 continue;2590 continue;
2612 },2591 },
2613 Token.Id.Keyword_asm => {2592 Token.Id.Keyword_asm => {
2614 const node = try createToCtxNode(arena, opt_ctx, ast.Node.Asm,2593 const node = try arena.construct(ast.Node.Asm {
2615 ast.Node.Asm {2594 .base = ast.Node {.id = ast.Node.Id.Asm },
2616 .base = undefined,2595 .asm_token = token.index,
2617 .asm_token = token.index,2596 .volatile_token = null,
2618 .volatile_token = null,2597 .template = undefined,
2619 .template = undefined,2598 .outputs = ast.Node.Asm.OutputList.init(arena),
2620 .outputs = ast.Node.Asm.OutputList.init(arena),2599 .inputs = ast.Node.Asm.InputList.init(arena),
2621 .inputs = ast.Node.Asm.InputList.init(arena),2600 .clobbers = ast.Node.Asm.ClobberList.init(arena),
2622 .clobbers = ast.Node.Asm.ClobberList.init(arena),2601 .rparen = undefined,
2623 .rparen = undefined,2602 });
2624 }2603 opt_ctx.store(&node.base);
2625 );2604
2626 stack.append(State {2605 stack.append(State {
2627 .ExpectTokenSave = ExpectTokenSave {2606 .ExpectTokenSave = ExpectTokenSave {
2628 .id = Token.Id.RParen,2607 .id = Token.Id.RParen,
...@@ -2978,6 +2957,7 @@ const State = union(enum) {...@@ -2978,6 +2957,7 @@ const State = union(enum) {
2978 VarDecl: VarDeclCtx,2957 VarDecl: VarDeclCtx,
2979 VarDeclAlign: &ast.Node.VarDecl,2958 VarDeclAlign: &ast.Node.VarDecl,
2980 VarDeclEq: &ast.Node.VarDecl,2959 VarDeclEq: &ast.Node.VarDecl,
2960 VarDeclSemiColon: &ast.Node.VarDecl,
29812961
2982 FnDef: &ast.Node.FnProto,2962 FnDef: &ast.Node.FnProto,
2983 FnProto: &ast.Node.FnProto,2963 FnProto: &ast.Node.FnProto,
...@@ -3082,25 +3062,29 @@ const State = union(enum) {...@@ -3082,25 +3062,29 @@ const State = union(enum) {
3082 OptionalTokenSave: OptionalTokenSave,3062 OptionalTokenSave: OptionalTokenSave,
3083};3063};
30843064
3065fn pushDocComment(arena: &mem.Allocator, line_comment: TokenIndex, result: &?&ast.Node.DocComment) !void {
3066 const node = blk: {
3067 if (*result) |comment_node| {
3068 break :blk comment_node;
3069 } else {
3070 const comment_node = try arena.construct(ast.Node.DocComment {
3071 .base = ast.Node {
3072 .id = ast.Node.Id.DocComment,
3073 },
3074 .lines = ast.Node.DocComment.LineList.init(arena),
3075 });
3076 *result = comment_node;
3077 break :blk comment_node;
3078 }
3079 };
3080 try node.lines.push(line_comment);
3081}
3082
3085fn eatDocComments(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) !?&ast.Node.DocComment {3083fn eatDocComments(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) !?&ast.Node.DocComment {
3086 var result: ?&ast.Node.DocComment = null;3084 var result: ?&ast.Node.DocComment = null;
3087 while (true) {3085 while (true) {
3088 if (eatToken(tok_it, tree, Token.Id.DocComment)) |line_comment| {3086 if (eatToken(tok_it, tree, Token.Id.DocComment)) |line_comment| {
3089 const node = blk: {3087 try pushDocComment(arena, line_comment, &result);
3090 if (result) |comment_node| {
3091 break :blk comment_node;
3092 } else {
3093 const comment_node = try arena.construct(ast.Node.DocComment {
3094 .base = ast.Node {
3095 .id = ast.Node.Id.DocComment,
3096 },
3097 .lines = ast.Node.DocComment.LineList.init(arena),
3098 });
3099 result = comment_node;
3100 break :blk comment_node;
3101 }
3102 };
3103 try node.lines.push(line_comment);
3104 continue;3088 continue;
3105 }3089 }
3106 break;3090 break;
...@@ -3155,31 +3139,29 @@ fn parseBlockExpr(stack: &std.ArrayList(State), arena: &mem.Allocator, ctx: &con...@@ -3155,31 +3139,29 @@ fn parseBlockExpr(stack: &std.ArrayList(State), arena: &mem.Allocator, ctx: &con
3155 token_ptr: &const Token, token_index: TokenIndex) !bool {3139 token_ptr: &const Token, token_index: TokenIndex) !bool {
3156 switch (token_ptr.id) {3140 switch (token_ptr.id) {
3157 Token.Id.Keyword_suspend => {3141 Token.Id.Keyword_suspend => {
3158 const node = try createToCtxNode(arena, ctx, ast.Node.Suspend,3142 const node = try arena.construct(ast.Node.Suspend {
3159 ast.Node.Suspend {3143 .base = ast.Node {.id = ast.Node.Id.Suspend },
3160 .base = undefined,3144 .label = null,
3161 .label = null,3145 .suspend_token = token_index,
3162 .suspend_token = token_index,3146 .payload = null,
3163 .payload = null,3147 .body = null,
3164 .body = null,3148 });
3165 }3149 ctx.store(&node.base);
3166 );
31673150
3168 stack.append(State { .SuspendBody = node }) catch unreachable;3151 stack.append(State { .SuspendBody = node }) catch unreachable;
3169 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } });3152 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } });
3170 return true;3153 return true;
3171 },3154 },
3172 Token.Id.Keyword_if => {3155 Token.Id.Keyword_if => {
3173 const node = try createToCtxNode(arena, ctx, ast.Node.If,3156 const node = try arena.construct(ast.Node.If {
3174 ast.Node.If {3157 .base = ast.Node {.id = ast.Node.Id.If },
3175 .base = undefined,3158 .if_token = token_index,
3176 .if_token = token_index,3159 .condition = undefined,
3177 .condition = undefined,3160 .payload = null,
3178 .payload = null,3161 .body = undefined,
3179 .body = undefined,3162 .@"else" = null,
3180 .@"else" = null,3163 });
3181 }3164 ctx.store(&node.base);
3182 );
31833165
3184 stack.append(State { .Else = &node.@"else" }) catch unreachable;3166 stack.append(State { .Else = &node.@"else" }) catch unreachable;
3185 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });3167 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });
...@@ -3236,14 +3218,14 @@ fn parseBlockExpr(stack: &std.ArrayList(State), arena: &mem.Allocator, ctx: &con...@@ -3236,14 +3218,14 @@ fn parseBlockExpr(stack: &std.ArrayList(State), arena: &mem.Allocator, ctx: &con
3236 return true;3218 return true;
3237 },3219 },
3238 Token.Id.Keyword_comptime => {3220 Token.Id.Keyword_comptime => {
3239 const node = try createToCtxNode(arena, ctx, ast.Node.Comptime,3221 const node = try arena.construct(ast.Node.Comptime {
3240 ast.Node.Comptime {3222 .base = ast.Node {.id = ast.Node.Id.Comptime },
3241 .base = undefined,3223 .comptime_token = token_index,
3242 .comptime_token = token_index,3224 .expr = undefined,
3243 .expr = undefined,3225 .doc_comments = null,
3244 .doc_comments = null,3226 });
3245 }3227 ctx.store(&node.base);
3246 );3228
3247 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });3229 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
3248 return true;3230 return true;
3249 },3231 },
...@@ -3390,33 +3372,11 @@ fn tokenIdToPrefixOp(id: @TagType(Token.Id)) ?ast.Node.PrefixOp.Op {...@@ -3390,33 +3372,11 @@ fn tokenIdToPrefixOp(id: @TagType(Token.Id)) ?ast.Node.PrefixOp.Op {
3390 };3372 };
3391}3373}
33923374
3393fn createNode(arena: &mem.Allocator, comptime T: type, init_to: &const T) !&T {
3394 const node = try arena.create(T);
3395 *node = *init_to;
3396 node.base = blk: {
3397 const id = ast.Node.typeToId(T);
3398 break :blk ast.Node {
3399 .id = id,
3400 };
3401 };
3402
3403 return node;
3404}
3405
3406fn createToCtxNode(arena: &mem.Allocator, opt_ctx: &const OptionalCtx, comptime T: type, init_to: &const T) !&T {
3407 const node = try createNode(arena, T, init_to);
3408 opt_ctx.store(&node.base);
3409
3410 return node;
3411}
3412
3413fn createLiteral(arena: &mem.Allocator, comptime T: type, token_index: TokenIndex) !&T {3375fn createLiteral(arena: &mem.Allocator, comptime T: type, token_index: TokenIndex) !&T {
3414 return createNode(arena, T,3376 return arena.construct(T {
3415 T {3377 .base = ast.Node {.id = ast.Node.typeToId(T)},
3416 .base = undefined,3378 .token = token_index,
3417 .token = token_index,3379 });
3418 }
3419 );
3420}3380}
34213381
3422fn createToCtxLiteral(arena: &mem.Allocator, opt_ctx: &const OptionalCtx, comptime T: type, token_index: TokenIndex) !&T {3382fn createToCtxLiteral(arena: &mem.Allocator, opt_ctx: &const OptionalCtx, comptime T: type, token_index: TokenIndex) !&T {
std/zig/parser_test.zig+14
...@@ -1,3 +1,17 @@...@@ -1,3 +1,17 @@
1test "zig fmt: same-line doc comment on variable declaration" {
2 try testTransform(
3 \\pub const MAP_ANONYMOUS = 0x1000; /// allocated from memory, swap space
4 \\pub const MAP_FILE = 0x0000; /// map from file (default)
5 \\
6 ,
7 \\/// allocated from memory, swap space
8 \\pub const MAP_ANONYMOUS = 0x1000;
9 \\/// map from file (default)
10 \\pub const MAP_FILE = 0x0000;
11 \\
12 );
13}
14
1test "zig fmt: same-line comment after a statement" {15test "zig fmt: same-line comment after a statement" {
2 try testCanonical(16 try testCanonical(
3 \\test "" {17 \\test "" {
test/cases/type_info.zig+177-142
...@@ -4,167 +4,199 @@ const TypeInfo = @import("builtin").TypeInfo;...@@ -4,167 +4,199 @@ const TypeInfo = @import("builtin").TypeInfo;
4const TypeId = @import("builtin").TypeId;4const TypeId = @import("builtin").TypeId;
55
6test "type info: tag type, void info" {6test "type info: tag type, void info" {
7 comptime {7 testBasic();
8 assert(@TagType(TypeInfo) == TypeId);8 comptime testBasic();
9 const void_info = @typeInfo(void);9}
10 assert(TypeId(void_info) == TypeId.Void);10
11 assert(void_info.Void == {});11fn testBasic() void {
12 }12 assert(@TagType(TypeInfo) == TypeId);
13 const void_info = @typeInfo(void);
14 assert(TypeId(void_info) == TypeId.Void);
15 assert(void_info.Void == {});
13}16}
1417
15test "type info: integer, floating point type info" {18test "type info: integer, floating point type info" {
16 comptime {19 testIntFloat();
17 const u8_info = @typeInfo(u8);20 comptime testIntFloat();
18 assert(TypeId(u8_info) == TypeId.Int);21}
19 assert(!u8_info.Int.is_signed);
20 assert(u8_info.Int.bits == 8);
2122
22 const f64_info = @typeInfo(f64);23fn testIntFloat() void {
23 assert(TypeId(f64_info) == TypeId.Float);24 const u8_info = @typeInfo(u8);
24 assert(f64_info.Float.bits == 64);25 assert(TypeId(u8_info) == TypeId.Int);
25 }26 assert(!u8_info.Int.is_signed);
27 assert(u8_info.Int.bits == 8);
28
29 const f64_info = @typeInfo(f64);
30 assert(TypeId(f64_info) == TypeId.Float);
31 assert(f64_info.Float.bits == 64);
26}32}
2733
28test "type info: pointer type info" {34test "type info: pointer type info" {
29 comptime {35 testPointer();
30 const u32_ptr_info = @typeInfo(&u32);36 comptime testPointer();
31 assert(TypeId(u32_ptr_info) == TypeId.Pointer);37}
32 assert(u32_ptr_info.Pointer.is_const == false);38
33 assert(u32_ptr_info.Pointer.is_volatile == false);39fn testPointer() void {
34 assert(u32_ptr_info.Pointer.alignment == 4);40 const u32_ptr_info = @typeInfo(&u32);
35 assert(u32_ptr_info.Pointer.child == u32);41 assert(TypeId(u32_ptr_info) == TypeId.Pointer);
36 }42 assert(u32_ptr_info.Pointer.is_const == false);
43 assert(u32_ptr_info.Pointer.is_volatile == false);
44 assert(u32_ptr_info.Pointer.alignment == 4);
45 assert(u32_ptr_info.Pointer.child == u32);
37}46}
3847
39test "type info: slice type info" {48test "type info: slice type info" {
40 comptime {49 testSlice();
41 const u32_slice_info = @typeInfo([]u32);50 comptime testSlice();
42 assert(TypeId(u32_slice_info) == TypeId.Slice);51}
43 assert(u32_slice_info.Slice.is_const == false);52
44 assert(u32_slice_info.Slice.is_volatile == false);53fn testSlice() void {
45 assert(u32_slice_info.Slice.alignment == 4);54 const u32_slice_info = @typeInfo([]u32);
46 assert(u32_slice_info.Slice.child == u32);55 assert(TypeId(u32_slice_info) == TypeId.Slice);
47 }56 assert(u32_slice_info.Slice.is_const == false);
57 assert(u32_slice_info.Slice.is_volatile == false);
58 assert(u32_slice_info.Slice.alignment == 4);
59 assert(u32_slice_info.Slice.child == u32);
48}60}
4961
50test "type info: array type info" {62test "type info: array type info" {
51 comptime {63 testArray();
52 const arr_info = @typeInfo([42]bool);64 comptime testArray();
53 assert(TypeId(arr_info) == TypeId.Array);65}
54 assert(arr_info.Array.len == 42);66
55 assert(arr_info.Array.child == bool);67fn testArray() void {
56 }68 const arr_info = @typeInfo([42]bool);
69 assert(TypeId(arr_info) == TypeId.Array);
70 assert(arr_info.Array.len == 42);
71 assert(arr_info.Array.child == bool);
57}72}
5873
59test "type info: nullable type info" {74test "type info: nullable type info" {
60 comptime {75 testNullable();
61 const null_info = @typeInfo(?void);76 comptime testNullable();
62 assert(TypeId(null_info) == TypeId.Nullable);77}
63 assert(null_info.Nullable.child == void);78
64 }79fn testNullable() void {
80 const null_info = @typeInfo(?void);
81 assert(TypeId(null_info) == TypeId.Nullable);
82 assert(null_info.Nullable.child == void);
65}83}
6684
67test "type info: promise info" {85test "type info: promise info" {
68 comptime {86 testPromise();
69 const null_promise_info = @typeInfo(promise);87 comptime testPromise();
70 assert(TypeId(null_promise_info) == TypeId.Promise);88}
71 assert(null_promise_info.Promise.child == @typeOf(undefined));
7289
73 const promise_info = @typeInfo(promise->usize);90fn testPromise() void {
74 assert(TypeId(promise_info) == TypeId.Promise);91 const null_promise_info = @typeInfo(promise);
75 assert(promise_info.Promise.child == usize);92 assert(TypeId(null_promise_info) == TypeId.Promise);
76 }93 assert(null_promise_info.Promise.child == @typeOf(undefined));
7794
95 const promise_info = @typeInfo(promise->usize);
96 assert(TypeId(promise_info) == TypeId.Promise);
97 assert(promise_info.Promise.child == usize);
78}98}
7999
80test "type info: error set, error union info" {100test "type info: error set, error union info" {
81 comptime {101 testErrorSet();
82 const TestErrorSet = error {102 comptime testErrorSet();
83 First,103}
84 Second,104
85 Third,105fn testErrorSet() void {
86 };106 const TestErrorSet = error {
87107 First,
88 const error_set_info = @typeInfo(TestErrorSet);108 Second,
89 assert(TypeId(error_set_info) == TypeId.ErrorSet);109 Third,
90 assert(error_set_info.ErrorSet.errors.len == 3);110 };
91 assert(mem.eql(u8, error_set_info.ErrorSet.errors[0].name, "First"));111
92 assert(error_set_info.ErrorSet.errors[2].value == usize(TestErrorSet.Third));112 const error_set_info = @typeInfo(TestErrorSet);
93113 assert(TypeId(error_set_info) == TypeId.ErrorSet);
94 const error_union_info = @typeInfo(TestErrorSet!usize);114 assert(error_set_info.ErrorSet.errors.len == 3);
95 assert(TypeId(error_union_info) == TypeId.ErrorUnion);115 assert(mem.eql(u8, error_set_info.ErrorSet.errors[0].name, "First"));
96 assert(error_union_info.ErrorUnion.error_set == TestErrorSet);116 assert(error_set_info.ErrorSet.errors[2].value == usize(TestErrorSet.Third));
97 assert(error_union_info.ErrorUnion.payload == usize);117
98 }118 const error_union_info = @typeInfo(TestErrorSet!usize);
119 assert(TypeId(error_union_info) == TypeId.ErrorUnion);
120 assert(error_union_info.ErrorUnion.error_set == TestErrorSet);
121 assert(error_union_info.ErrorUnion.payload == usize);
99}122}
100123
101test "type info: enum info" {124test "type info: enum info" {
102 comptime {125 testEnum();
103 const Os = @import("builtin").Os;126 comptime testEnum();
127}
104128
105 const os_info = @typeInfo(Os);129fn testEnum() void {
106 assert(TypeId(os_info) == TypeId.Enum);130 const Os = @import("builtin").Os;
107 assert(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto);131
108 assert(os_info.Enum.fields.len == 32);132 const os_info = @typeInfo(Os);
109 assert(mem.eql(u8, os_info.Enum.fields[1].name, "ananas"));133 assert(TypeId(os_info) == TypeId.Enum);
110 assert(os_info.Enum.fields[10].value == 10);134 assert(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto);
111 assert(os_info.Enum.tag_type == u5);135 assert(os_info.Enum.fields.len == 32);
112 assert(os_info.Enum.defs.len == 0);136 assert(mem.eql(u8, os_info.Enum.fields[1].name, "ananas"));
113 }137 assert(os_info.Enum.fields[10].value == 10);
138 assert(os_info.Enum.tag_type == u5);
139 assert(os_info.Enum.defs.len == 0);
114}140}
115141
116test "type info: union info" {142test "type info: union info" {
117 comptime {143 testUnion();
118 const typeinfo_info = @typeInfo(TypeInfo);144 comptime testUnion();
119 assert(TypeId(typeinfo_info) == TypeId.Union);145}
120 assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);146
121 assert(typeinfo_info.Union.tag_type == TypeId);147fn testUnion() void {
122 assert(typeinfo_info.Union.fields.len == 26);148 const typeinfo_info = @typeInfo(TypeInfo);
123 assert(typeinfo_info.Union.fields[4].enum_field != null);149 assert(TypeId(typeinfo_info) == TypeId.Union);
124 assert((??typeinfo_info.Union.fields[4].enum_field).value == 4);150 assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
125 assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));151 assert(typeinfo_info.Union.tag_type == TypeId);
126 assert(typeinfo_info.Union.defs.len == 21);152 assert(typeinfo_info.Union.fields.len == 26);
127153 assert(typeinfo_info.Union.fields[4].enum_field != null);
128 const TestNoTagUnion = union {154 assert((??typeinfo_info.Union.fields[4].enum_field).value == 4);
129 Foo: void,155 assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
130 Bar: u32,156 assert(typeinfo_info.Union.defs.len == 21);
131 };157
132158 const TestNoTagUnion = union {
133 const notag_union_info = @typeInfo(TestNoTagUnion);159 Foo: void,
134 assert(TypeId(notag_union_info) == TypeId.Union);160 Bar: u32,
135 assert(notag_union_info.Union.tag_type == @typeOf(undefined));161 };
136 assert(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);162
137 assert(notag_union_info.Union.fields.len == 2);163 const notag_union_info = @typeInfo(TestNoTagUnion);
138 assert(notag_union_info.Union.fields[0].enum_field == null);164 assert(TypeId(notag_union_info) == TypeId.Union);
139 assert(notag_union_info.Union.fields[1].field_type == u32);165 assert(notag_union_info.Union.tag_type == @typeOf(undefined));
140166 assert(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);
141 const TestExternUnion = extern union {167 assert(notag_union_info.Union.fields.len == 2);
142 foo: &c_void,168 assert(notag_union_info.Union.fields[0].enum_field == null);
143 };169 assert(notag_union_info.Union.fields[1].field_type == u32);
144170
145 const extern_union_info = @typeInfo(TestExternUnion);171 const TestExternUnion = extern union {
146 assert(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern);172 foo: &c_void,
147 assert(extern_union_info.Union.tag_type == @typeOf(undefined));173 };
148 assert(extern_union_info.Union.fields[0].enum_field == null);174
149 assert(extern_union_info.Union.fields[0].field_type == &c_void);175 const extern_union_info = @typeInfo(TestExternUnion);
150 }176 assert(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern);
177 assert(extern_union_info.Union.tag_type == @typeOf(undefined));
178 assert(extern_union_info.Union.fields[0].enum_field == null);
179 assert(extern_union_info.Union.fields[0].field_type == &c_void);
151}180}
152181
153test "type info: struct info" {182test "type info: struct info" {
154 comptime {183 testStruct();
155 const struct_info = @typeInfo(TestStruct);184 comptime testStruct();
156 assert(TypeId(struct_info) == TypeId.Struct);185}
157 assert(struct_info.Struct.layout == TypeInfo.ContainerLayout.Packed);186
158 assert(struct_info.Struct.fields.len == 3);187fn testStruct() void {
159 assert(struct_info.Struct.fields[1].offset == null);188 const struct_info = @typeInfo(TestStruct);
160 assert(struct_info.Struct.fields[2].field_type == &TestStruct);189 assert(TypeId(struct_info) == TypeId.Struct);
161 assert(struct_info.Struct.defs.len == 2);190 assert(struct_info.Struct.layout == TypeInfo.ContainerLayout.Packed);
162 assert(struct_info.Struct.defs[0].is_pub);191 assert(struct_info.Struct.fields.len == 3);
163 assert(!struct_info.Struct.defs[0].data.Fn.is_extern);192 assert(struct_info.Struct.fields[1].offset == null);
164 assert(struct_info.Struct.defs[0].data.Fn.lib_name == null);193 assert(struct_info.Struct.fields[2].field_type == &TestStruct);
165 assert(struct_info.Struct.defs[0].data.Fn.return_type == void);194 assert(struct_info.Struct.defs.len == 2);
166 assert(struct_info.Struct.defs[0].data.Fn.fn_type == fn(&const TestStruct)void);195 assert(struct_info.Struct.defs[0].is_pub);
167 }196 assert(!struct_info.Struct.defs[0].data.Fn.is_extern);
197 assert(struct_info.Struct.defs[0].data.Fn.lib_name == null);
198 assert(struct_info.Struct.defs[0].data.Fn.return_type == void);
199 assert(struct_info.Struct.defs[0].data.Fn.fn_type == fn(&const TestStruct)void);
168}200}
169201
170const TestStruct = packed struct {202const TestStruct = packed struct {
...@@ -178,21 +210,24 @@ const TestStruct = packed struct {...@@ -178,21 +210,24 @@ const TestStruct = packed struct {
178};210};
179211
180test "type info: function type info" {212test "type info: function type info" {
181 comptime {213 testFunction();
182 const fn_info = @typeInfo(@typeOf(foo));214 comptime testFunction();
183 assert(TypeId(fn_info) == TypeId.Fn);215}
184 assert(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified);216
185 assert(fn_info.Fn.is_generic);217fn testFunction() void {
186 assert(fn_info.Fn.args.len == 2);218 const fn_info = @typeInfo(@typeOf(foo));
187 assert(fn_info.Fn.is_var_args);219 assert(TypeId(fn_info) == TypeId.Fn);
188 assert(fn_info.Fn.return_type == @typeOf(undefined));220 assert(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified);
189 assert(fn_info.Fn.async_allocator_type == @typeOf(undefined));221 assert(fn_info.Fn.is_generic);
190222 assert(fn_info.Fn.args.len == 2);
191 const test_instance: TestStruct = undefined;223 assert(fn_info.Fn.is_var_args);
192 const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));224 assert(fn_info.Fn.return_type == @typeOf(undefined));
193 assert(TypeId(bound_fn_info) == TypeId.BoundFn);225 assert(fn_info.Fn.async_allocator_type == @typeOf(undefined));
194 assert(bound_fn_info.BoundFn.args[0].arg_type == &const TestStruct);226
195 }227 const test_instance: TestStruct = undefined;
228 const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));
229 assert(TypeId(bound_fn_info) == TypeId.BoundFn);
230 assert(bound_fn_info.BoundFn.args[0].arg_type == &const TestStruct);
196}231}
197232
198fn foo(comptime a: usize, b: bool, args: ...) usize {233fn foo(comptime a: usize, b: bool, args: ...) usize {