authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-03 16:13:28-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-03 16:13:28-05:00
logdfbc063f79dc1358208216b466c1bf8c44baa430
tree219c5f46a2e688fc1799117a1680102528691ce3
parentc90c256868a80cd35e9ba679ba082330592620c9
signature Commit is signed but in an unrecognized format.

`std.mem.Allocator.create` replaced with better API

`std.mem.Allocator.createOne` is renamed to `std.mem.Allocator.create`. The problem with the previous API is that even after copy elision, the initalization value passed as a parameter would always be a copy. With the new API, once copy elision is done, initialization functions can directly initialize allocated memory in place. Related: * #1872 * #1873

23 files changed, 451 insertions(+), 312 deletions(-)

src-self-hosted/compilation.zig+43-29
...@@ -83,10 +83,11 @@ pub const ZigCompiler = struct {...@@ -83,10 +83,11 @@ pub const ZigCompiler = struct {
83 const context_ref = c.LLVMContextCreate() orelse return error.OutOfMemory;83 const context_ref = c.LLVMContextCreate() orelse return error.OutOfMemory;
84 errdefer c.LLVMContextDispose(context_ref);84 errdefer c.LLVMContextDispose(context_ref);
8585
86 const node = try self.loop.allocator.create(std.atomic.Stack(llvm.ContextRef).Node{86 const node = try self.loop.allocator.create(std.atomic.Stack(llvm.ContextRef).Node);
87 node.* = std.atomic.Stack(llvm.ContextRef).Node{
87 .next = undefined,88 .next = undefined,
88 .data = context_ref,89 .data = context_ref,
89 });90 };
90 errdefer self.loop.allocator.destroy(node);91 errdefer self.loop.allocator.destroy(node);
9192
92 return LlvmHandle{ .node = node };93 return LlvmHandle{ .node = node };
...@@ -596,7 +597,8 @@ pub const Compilation = struct {...@@ -596,7 +597,8 @@ pub const Compilation = struct {
596 }597 }
597598
598 fn initTypes(comp: *Compilation) !void {599 fn initTypes(comp: *Compilation) !void {
599 comp.meta_type = try comp.arena().create(Type.MetaType{600 comp.meta_type = try comp.arena().create(Type.MetaType);
601 comp.meta_type.* = Type.MetaType{
600 .base = Type{602 .base = Type{
601 .name = "type",603 .name = "type",
602 .base = Value{604 .base = Value{
...@@ -608,12 +610,13 @@ pub const Compilation = struct {...@@ -608,12 +610,13 @@ pub const Compilation = struct {
608 .abi_alignment = Type.AbiAlignment.init(comp.loop),610 .abi_alignment = Type.AbiAlignment.init(comp.loop),
609 },611 },
610 .value = undefined,612 .value = undefined,
611 });613 };
612 comp.meta_type.value = &comp.meta_type.base;614 comp.meta_type.value = &comp.meta_type.base;
613 comp.meta_type.base.base.typ = &comp.meta_type.base;615 comp.meta_type.base.base.typ = &comp.meta_type.base;
614 assert((try comp.primitive_type_table.put(comp.meta_type.base.name, &comp.meta_type.base)) == null);616 assert((try comp.primitive_type_table.put(comp.meta_type.base.name, &comp.meta_type.base)) == null);
615617
616 comp.void_type = try comp.arena().create(Type.Void{618 comp.void_type = try comp.arena().create(Type.Void);
619 comp.void_type.* = Type.Void{
617 .base = Type{620 .base = Type{
618 .name = "void",621 .name = "void",
619 .base = Value{622 .base = Value{
...@@ -624,10 +627,11 @@ pub const Compilation = struct {...@@ -624,10 +627,11 @@ pub const Compilation = struct {
624 .id = builtin.TypeId.Void,627 .id = builtin.TypeId.Void,
625 .abi_alignment = Type.AbiAlignment.init(comp.loop),628 .abi_alignment = Type.AbiAlignment.init(comp.loop),
626 },629 },
627 });630 };
628 assert((try comp.primitive_type_table.put(comp.void_type.base.name, &comp.void_type.base)) == null);631 assert((try comp.primitive_type_table.put(comp.void_type.base.name, &comp.void_type.base)) == null);
629632
630 comp.noreturn_type = try comp.arena().create(Type.NoReturn{633 comp.noreturn_type = try comp.arena().create(Type.NoReturn);
634 comp.noreturn_type.* = Type.NoReturn{
631 .base = Type{635 .base = Type{
632 .name = "noreturn",636 .name = "noreturn",
633 .base = Value{637 .base = Value{
...@@ -638,10 +642,11 @@ pub const Compilation = struct {...@@ -638,10 +642,11 @@ pub const Compilation = struct {
638 .id = builtin.TypeId.NoReturn,642 .id = builtin.TypeId.NoReturn,
639 .abi_alignment = Type.AbiAlignment.init(comp.loop),643 .abi_alignment = Type.AbiAlignment.init(comp.loop),
640 },644 },
641 });645 };
642 assert((try comp.primitive_type_table.put(comp.noreturn_type.base.name, &comp.noreturn_type.base)) == null);646 assert((try comp.primitive_type_table.put(comp.noreturn_type.base.name, &comp.noreturn_type.base)) == null);
643647
644 comp.comptime_int_type = try comp.arena().create(Type.ComptimeInt{648 comp.comptime_int_type = try comp.arena().create(Type.ComptimeInt);
649 comp.comptime_int_type.* = Type.ComptimeInt{
645 .base = Type{650 .base = Type{
646 .name = "comptime_int",651 .name = "comptime_int",
647 .base = Value{652 .base = Value{
...@@ -652,10 +657,11 @@ pub const Compilation = struct {...@@ -652,10 +657,11 @@ pub const Compilation = struct {
652 .id = builtin.TypeId.ComptimeInt,657 .id = builtin.TypeId.ComptimeInt,
653 .abi_alignment = Type.AbiAlignment.init(comp.loop),658 .abi_alignment = Type.AbiAlignment.init(comp.loop),
654 },659 },
655 });660 };
656 assert((try comp.primitive_type_table.put(comp.comptime_int_type.base.name, &comp.comptime_int_type.base)) == null);661 assert((try comp.primitive_type_table.put(comp.comptime_int_type.base.name, &comp.comptime_int_type.base)) == null);
657662
658 comp.bool_type = try comp.arena().create(Type.Bool{663 comp.bool_type = try comp.arena().create(Type.Bool);
664 comp.bool_type.* = Type.Bool{
659 .base = Type{665 .base = Type{
660 .name = "bool",666 .name = "bool",
661 .base = Value{667 .base = Value{
...@@ -666,45 +672,50 @@ pub const Compilation = struct {...@@ -666,45 +672,50 @@ pub const Compilation = struct {
666 .id = builtin.TypeId.Bool,672 .id = builtin.TypeId.Bool,
667 .abi_alignment = Type.AbiAlignment.init(comp.loop),673 .abi_alignment = Type.AbiAlignment.init(comp.loop),
668 },674 },
669 });675 };
670 assert((try comp.primitive_type_table.put(comp.bool_type.base.name, &comp.bool_type.base)) == null);676 assert((try comp.primitive_type_table.put(comp.bool_type.base.name, &comp.bool_type.base)) == null);
671677
672 comp.void_value = try comp.arena().create(Value.Void{678 comp.void_value = try comp.arena().create(Value.Void);
679 comp.void_value.* = Value.Void{
673 .base = Value{680 .base = Value{
674 .id = Value.Id.Void,681 .id = Value.Id.Void,
675 .typ = &Type.Void.get(comp).base,682 .typ = &Type.Void.get(comp).base,
676 .ref_count = std.atomic.Int(usize).init(1),683 .ref_count = std.atomic.Int(usize).init(1),
677 },684 },
678 });685 };
679686
680 comp.true_value = try comp.arena().create(Value.Bool{687 comp.true_value = try comp.arena().create(Value.Bool);
688 comp.true_value.* = Value.Bool{
681 .base = Value{689 .base = Value{
682 .id = Value.Id.Bool,690 .id = Value.Id.Bool,
683 .typ = &Type.Bool.get(comp).base,691 .typ = &Type.Bool.get(comp).base,
684 .ref_count = std.atomic.Int(usize).init(1),692 .ref_count = std.atomic.Int(usize).init(1),
685 },693 },
686 .x = true,694 .x = true,
687 });695 };
688696
689 comp.false_value = try comp.arena().create(Value.Bool{697 comp.false_value = try comp.arena().create(Value.Bool);
698 comp.false_value.* = Value.Bool{
690 .base = Value{699 .base = Value{
691 .id = Value.Id.Bool,700 .id = Value.Id.Bool,
692 .typ = &Type.Bool.get(comp).base,701 .typ = &Type.Bool.get(comp).base,
693 .ref_count = std.atomic.Int(usize).init(1),702 .ref_count = std.atomic.Int(usize).init(1),
694 },703 },
695 .x = false,704 .x = false,
696 });705 };
697706
698 comp.noreturn_value = try comp.arena().create(Value.NoReturn{707 comp.noreturn_value = try comp.arena().create(Value.NoReturn);
708 comp.noreturn_value.* = Value.NoReturn{
699 .base = Value{709 .base = Value{
700 .id = Value.Id.NoReturn,710 .id = Value.Id.NoReturn,
701 .typ = &Type.NoReturn.get(comp).base,711 .typ = &Type.NoReturn.get(comp).base,
702 .ref_count = std.atomic.Int(usize).init(1),712 .ref_count = std.atomic.Int(usize).init(1),
703 },713 },
704 });714 };
705715
706 for (CInt.list) |cint, i| {716 for (CInt.list) |cint, i| {
707 const c_int_type = try comp.arena().create(Type.Int{717 const c_int_type = try comp.arena().create(Type.Int);
718 c_int_type.* = Type.Int{
708 .base = Type{719 .base = Type{
709 .name = cint.zig_name,720 .name = cint.zig_name,
710 .base = Value{721 .base = Value{
...@@ -720,11 +731,12 @@ pub const Compilation = struct {...@@ -720,11 +731,12 @@ pub const Compilation = struct {
720 .bit_count = comp.target.cIntTypeSizeInBits(cint.id),731 .bit_count = comp.target.cIntTypeSizeInBits(cint.id),
721 },732 },
722 .garbage_node = undefined,733 .garbage_node = undefined,
723 });734 };
724 comp.c_int_types[i] = c_int_type;735 comp.c_int_types[i] = c_int_type;
725 assert((try comp.primitive_type_table.put(cint.zig_name, &c_int_type.base)) == null);736 assert((try comp.primitive_type_table.put(cint.zig_name, &c_int_type.base)) == null);
726 }737 }
727 comp.u8_type = try comp.arena().create(Type.Int{738 comp.u8_type = try comp.arena().create(Type.Int);
739 comp.u8_type.* = Type.Int{
728 .base = Type{740 .base = Type{
729 .name = "u8",741 .name = "u8",
730 .base = Value{742 .base = Value{
...@@ -740,7 +752,7 @@ pub const Compilation = struct {...@@ -740,7 +752,7 @@ pub const Compilation = struct {
740 .bit_count = 8,752 .bit_count = 8,
741 },753 },
742 .garbage_node = undefined,754 .garbage_node = undefined,
743 });755 };
744 assert((try comp.primitive_type_table.put(comp.u8_type.base.name, &comp.u8_type.base)) == null);756 assert((try comp.primitive_type_table.put(comp.u8_type.base.name, &comp.u8_type.base)) == null);
745 }757 }
746758
...@@ -829,7 +841,7 @@ pub const Compilation = struct {...@@ -829,7 +841,7 @@ pub const Compilation = struct {
829 };841 };
830 errdefer self.gpa().free(source_code);842 errdefer self.gpa().free(source_code);
831843
832 const tree = try self.gpa().createOne(ast.Tree);844 const tree = try self.gpa().create(ast.Tree);
833 tree.* = try std.zig.parse(self.gpa(), source_code);845 tree.* = try std.zig.parse(self.gpa(), source_code);
834 errdefer {846 errdefer {
835 tree.deinit();847 tree.deinit();
...@@ -925,7 +937,8 @@ pub const Compilation = struct {...@@ -925,7 +937,8 @@ pub const Compilation = struct {
925 }937 }
926 } else {938 } else {
927 // add new decl939 // add new decl
928 const fn_decl = try self.gpa().create(Decl.Fn{940 const fn_decl = try self.gpa().create(Decl.Fn);
941 fn_decl.* = Decl.Fn{
929 .base = Decl{942 .base = Decl{
930 .id = Decl.Id.Fn,943 .id = Decl.Id.Fn,
931 .name = name,944 .name = name,
...@@ -936,7 +949,7 @@ pub const Compilation = struct {...@@ -936,7 +949,7 @@ pub const Compilation = struct {
936 },949 },
937 .value = Decl.Fn.Val{ .Unresolved = {} },950 .value = Decl.Fn.Val{ .Unresolved = {} },
938 .fn_proto = fn_proto,951 .fn_proto = fn_proto,
939 });952 };
940 tree_scope.base.ref();953 tree_scope.base.ref();
941 errdefer self.gpa().destroy(fn_decl);954 errdefer self.gpa().destroy(fn_decl);
942955
...@@ -1140,12 +1153,13 @@ pub const Compilation = struct {...@@ -1140,12 +1153,13 @@ pub const Compilation = struct {
1140 }1153 }
1141 }1154 }
11421155
1143 const link_lib = try self.gpa().create(LinkLib{1156 const link_lib = try self.gpa().create(LinkLib);
1157 link_lib.* = LinkLib{
1144 .name = name,1158 .name = name,
1145 .path = null,1159 .path = null,
1146 .provided_explicitly = provided_explicitly,1160 .provided_explicitly = provided_explicitly,
1147 .symbols = ArrayList([]u8).init(self.gpa()),1161 .symbols = ArrayList([]u8).init(self.gpa()),
1148 });1162 };
1149 try self.link_libs_list.append(link_lib);1163 try self.link_libs_list.append(link_lib);
1150 if (is_libc) {1164 if (is_libc) {
1151 self.libc_link_lib = link_lib;1165 self.libc_link_lib = link_lib;
src-self-hosted/errmsg.zig+12-8
...@@ -118,7 +118,8 @@ pub const Msg = struct {...@@ -118,7 +118,8 @@ pub const Msg = struct {
118 const realpath = try mem.dupe(comp.gpa(), u8, tree_scope.root().realpath);118 const realpath = try mem.dupe(comp.gpa(), u8, tree_scope.root().realpath);
119 errdefer comp.gpa().free(realpath);119 errdefer comp.gpa().free(realpath);
120120
121 const msg = try comp.gpa().create(Msg{121 const msg = try comp.gpa().create(Msg);
122 msg.* = Msg{
122 .text = text,123 .text = text,
123 .realpath = realpath,124 .realpath = realpath,
124 .data = Data{125 .data = Data{
...@@ -128,7 +129,7 @@ pub const Msg = struct {...@@ -128,7 +129,7 @@ pub const Msg = struct {
128 .span = span,129 .span = span,
129 },130 },
130 },131 },
131 });132 };
132 tree_scope.base.ref();133 tree_scope.base.ref();
133 return msg;134 return msg;
134 }135 }
...@@ -139,13 +140,14 @@ pub const Msg = struct {...@@ -139,13 +140,14 @@ pub const Msg = struct {
139 const realpath_copy = try mem.dupe(comp.gpa(), u8, realpath);140 const realpath_copy = try mem.dupe(comp.gpa(), u8, realpath);
140 errdefer comp.gpa().free(realpath_copy);141 errdefer comp.gpa().free(realpath_copy);
141142
142 const msg = try comp.gpa().create(Msg{143 const msg = try comp.gpa().create(Msg);
144 msg.* = Msg{
143 .text = text,145 .text = text,
144 .realpath = realpath_copy,146 .realpath = realpath_copy,
145 .data = Data{147 .data = Data{
146 .Cli = Cli{ .allocator = comp.gpa() },148 .Cli = Cli{ .allocator = comp.gpa() },
147 },149 },
148 });150 };
149 return msg;151 return msg;
150 }152 }
151153
...@@ -164,7 +166,8 @@ pub const Msg = struct {...@@ -164,7 +166,8 @@ pub const Msg = struct {
164 var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;166 var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
165 try parse_error.render(&tree_scope.tree.tokens, out_stream);167 try parse_error.render(&tree_scope.tree.tokens, out_stream);
166168
167 const msg = try comp.gpa().create(Msg{169 const msg = try comp.gpa().create(Msg);
170 msg.* = Msg{
168 .text = undefined,171 .text = undefined,
169 .realpath = realpath_copy,172 .realpath = realpath_copy,
170 .data = Data{173 .data = Data{
...@@ -177,7 +180,7 @@ pub const Msg = struct {...@@ -177,7 +180,7 @@ pub const Msg = struct {
177 },180 },
178 },181 },
179 },182 },
180 });183 };
181 tree_scope.base.ref();184 tree_scope.base.ref();
182 msg.text = text_buf.toOwnedSlice();185 msg.text = text_buf.toOwnedSlice();
183 return msg;186 return msg;
...@@ -203,7 +206,8 @@ pub const Msg = struct {...@@ -203,7 +206,8 @@ pub const Msg = struct {
203 var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;206 var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
204 try parse_error.render(&tree.tokens, out_stream);207 try parse_error.render(&tree.tokens, out_stream);
205208
206 const msg = try allocator.create(Msg{209 const msg = try allocator.create(Msg);
210 msg.* = Msg{
207 .text = undefined,211 .text = undefined,
208 .realpath = realpath_copy,212 .realpath = realpath_copy,
209 .data = Data{213 .data = Data{
...@@ -216,7 +220,7 @@ pub const Msg = struct {...@@ -216,7 +220,7 @@ pub const Msg = struct {
216 },220 },
217 },221 },
218 },222 },
219 });223 };
220 msg.text = text_buf.toOwnedSlice();224 msg.text = text_buf.toOwnedSlice();
221 errdefer allocator.destroy(msg);225 errdefer allocator.destroy(msg);
222226
src-self-hosted/ir.zig+9-6
...@@ -1021,12 +1021,13 @@ pub const Builder = struct {...@@ -1021,12 +1021,13 @@ pub const Builder = struct {
1021 pub const Error = Analyze.Error;1021 pub const Error = Analyze.Error;
10221022
1023 pub fn init(comp: *Compilation, tree_scope: *Scope.AstTree, begin_scope: ?*Scope) !Builder {1023 pub fn init(comp: *Compilation, tree_scope: *Scope.AstTree, begin_scope: ?*Scope) !Builder {
1024 const code = try comp.gpa().create(Code{1024 const code = try comp.gpa().create(Code);
1025 code.* = Code{
1025 .basic_block_list = undefined,1026 .basic_block_list = undefined,
1026 .arena = std.heap.ArenaAllocator.init(comp.gpa()),1027 .arena = std.heap.ArenaAllocator.init(comp.gpa()),
1027 .return_type = null,1028 .return_type = null,
1028 .tree_scope = tree_scope,1029 .tree_scope = tree_scope,
1029 });1030 };
1030 code.basic_block_list = std.ArrayList(*BasicBlock).init(&code.arena.allocator);1031 code.basic_block_list = std.ArrayList(*BasicBlock).init(&code.arena.allocator);
1031 errdefer code.destroy(comp.gpa());1032 errdefer code.destroy(comp.gpa());
10321033
...@@ -1052,7 +1053,8 @@ pub const Builder = struct {...@@ -1052,7 +1053,8 @@ pub const Builder = struct {
10521053
1053 /// No need to clean up resources thanks to the arena allocator.1054 /// No need to clean up resources thanks to the arena allocator.
1054 pub fn createBasicBlock(self: *Builder, scope: *Scope, name_hint: [*]const u8) !*BasicBlock {1055 pub fn createBasicBlock(self: *Builder, scope: *Scope, name_hint: [*]const u8) !*BasicBlock {
1055 const basic_block = try self.arena().create(BasicBlock{1056 const basic_block = try self.arena().create(BasicBlock);
1057 basic_block.* = BasicBlock{
1056 .ref_count = 0,1058 .ref_count = 0,
1057 .name_hint = name_hint,1059 .name_hint = name_hint,
1058 .debug_id = self.next_debug_id,1060 .debug_id = self.next_debug_id,
...@@ -1063,7 +1065,7 @@ pub const Builder = struct {...@@ -1063,7 +1065,7 @@ pub const Builder = struct {
1063 .ref_instruction = null,1065 .ref_instruction = null,
1064 .llvm_block = undefined,1066 .llvm_block = undefined,
1065 .llvm_exit_block = undefined,1067 .llvm_exit_block = undefined,
1066 });1068 };
1067 self.next_debug_id += 1;1069 self.next_debug_id += 1;
1068 return basic_block;1070 return basic_block;
1069 }1071 }
...@@ -1774,7 +1776,8 @@ pub const Builder = struct {...@@ -1774,7 +1776,8 @@ pub const Builder = struct {
1774 params: I.Params,1776 params: I.Params,
1775 is_generated: bool,1777 is_generated: bool,
1776 ) !*Inst {1778 ) !*Inst {
1777 const inst = try self.arena().create(I{1779 const inst = try self.arena().create(I);
1780 inst.* = I{
1778 .base = Inst{1781 .base = Inst{
1779 .id = Inst.typeToId(I),1782 .id = Inst.typeToId(I),
1780 .is_generated = is_generated,1783 .is_generated = is_generated,
...@@ -1793,7 +1796,7 @@ pub const Builder = struct {...@@ -1793,7 +1796,7 @@ pub const Builder = struct {
1793 .owner_bb = self.current_basic_block,1796 .owner_bb = self.current_basic_block,
1794 },1797 },
1795 .params = params,1798 .params = params,
1796 });1799 };
17971800
1798 // Look at the params and ref() other instructions1801 // Look at the params and ref() other instructions
1799 comptime var i = 0;1802 comptime var i = 0;
src-self-hosted/main.zig+3-2
...@@ -944,12 +944,13 @@ const CliPkg = struct {...@@ -944,12 +944,13 @@ const CliPkg = struct {
944 parent: ?*CliPkg,944 parent: ?*CliPkg,
945945
946 pub fn init(allocator: *mem.Allocator, name: []const u8, path: []const u8, parent: ?*CliPkg) !*CliPkg {946 pub fn init(allocator: *mem.Allocator, name: []const u8, path: []const u8, parent: ?*CliPkg) !*CliPkg {
947 var pkg = try allocator.create(CliPkg{947 var pkg = try allocator.create(CliPkg);
948 pkg.* = CliPkg{
948 .name = name,949 .name = name,
949 .path = path,950 .path = path,
950 .children = ArrayList(*CliPkg).init(allocator),951 .children = ArrayList(*CliPkg).init(allocator),
951 .parent = parent,952 .parent = parent,
952 });953 };
953 return pkg;954 return pkg;
954 }955 }
955956
src-self-hosted/package.zig+4-2
...@@ -15,11 +15,13 @@ pub const Package = struct {...@@ -15,11 +15,13 @@ pub const Package = struct {
15 /// makes internal copies of root_src_dir and root_src_path15 /// makes internal copies of root_src_dir and root_src_path
16 /// allocator should be an arena allocator because Package never frees anything16 /// allocator should be an arena allocator because Package never frees anything
17 pub fn create(allocator: *mem.Allocator, root_src_dir: []const u8, root_src_path: []const u8) !*Package {17 pub fn create(allocator: *mem.Allocator, root_src_dir: []const u8, root_src_path: []const u8) !*Package {
18 return allocator.create(Package{18 const ptr = try allocator.create(Package);
19 ptr.* = Package{
19 .root_src_dir = try Buffer.init(allocator, root_src_dir),20 .root_src_dir = try Buffer.init(allocator, root_src_dir),
20 .root_src_path = try Buffer.init(allocator, root_src_path),21 .root_src_path = try Buffer.init(allocator, root_src_path),
21 .table = Table.init(allocator),22 .table = Table.init(allocator),
22 });23 };
24 return ptr;
23 }25 }
2426
25 pub fn add(self: *Package, name: []const u8, package: *Package) !void {27 pub fn add(self: *Package, name: []const u8, package: *Package) !void {
src-self-hosted/scope.zig+9-9
...@@ -120,7 +120,7 @@ pub const Scope = struct {...@@ -120,7 +120,7 @@ pub const Scope = struct {
120 /// Creates a Root scope with 1 reference120 /// Creates a Root scope with 1 reference
121 /// Takes ownership of realpath121 /// Takes ownership of realpath
122 pub fn create(comp: *Compilation, realpath: []u8) !*Root {122 pub fn create(comp: *Compilation, realpath: []u8) !*Root {
123 const self = try comp.gpa().createOne(Root);123 const self = try comp.gpa().create(Root);
124 self.* = Root{124 self.* = Root{
125 .base = Scope{125 .base = Scope{
126 .id = Id.Root,126 .id = Id.Root,
...@@ -150,7 +150,7 @@ pub const Scope = struct {...@@ -150,7 +150,7 @@ pub const Scope = struct {
150 /// Creates a scope with 1 reference150 /// Creates a scope with 1 reference
151 /// Takes ownership of tree, will deinit and destroy when done.151 /// Takes ownership of tree, will deinit and destroy when done.
152 pub fn create(comp: *Compilation, tree: *ast.Tree, root_scope: *Root) !*AstTree {152 pub fn create(comp: *Compilation, tree: *ast.Tree, root_scope: *Root) !*AstTree {
153 const self = try comp.gpa().createOne(AstTree);153 const self = try comp.gpa().create(AstTree);
154 self.* = AstTree{154 self.* = AstTree{
155 .base = undefined,155 .base = undefined,
156 .tree = tree,156 .tree = tree,
...@@ -182,7 +182,7 @@ pub const Scope = struct {...@@ -182,7 +182,7 @@ pub const Scope = struct {
182182
183 /// Creates a Decls scope with 1 reference183 /// Creates a Decls scope with 1 reference
184 pub fn create(comp: *Compilation, parent: *Scope) !*Decls {184 pub fn create(comp: *Compilation, parent: *Scope) !*Decls {
185 const self = try comp.gpa().createOne(Decls);185 const self = try comp.gpa().create(Decls);
186 self.* = Decls{186 self.* = Decls{
187 .base = undefined,187 .base = undefined,
188 .table = event.RwLocked(Decl.Table).init(comp.loop, Decl.Table.init(comp.gpa())),188 .table = event.RwLocked(Decl.Table).init(comp.loop, Decl.Table.init(comp.gpa())),
...@@ -235,7 +235,7 @@ pub const Scope = struct {...@@ -235,7 +235,7 @@ pub const Scope = struct {
235235
236 /// Creates a Block scope with 1 reference236 /// Creates a Block scope with 1 reference
237 pub fn create(comp: *Compilation, parent: *Scope) !*Block {237 pub fn create(comp: *Compilation, parent: *Scope) !*Block {
238 const self = try comp.gpa().createOne(Block);238 const self = try comp.gpa().create(Block);
239 self.* = Block{239 self.* = Block{
240 .base = undefined,240 .base = undefined,
241 .incoming_values = undefined,241 .incoming_values = undefined,
...@@ -262,7 +262,7 @@ pub const Scope = struct {...@@ -262,7 +262,7 @@ pub const Scope = struct {
262 /// Creates a FnDef scope with 1 reference262 /// Creates a FnDef scope with 1 reference
263 /// Must set the fn_val later263 /// Must set the fn_val later
264 pub fn create(comp: *Compilation, parent: *Scope) !*FnDef {264 pub fn create(comp: *Compilation, parent: *Scope) !*FnDef {
265 const self = try comp.gpa().createOne(FnDef);265 const self = try comp.gpa().create(FnDef);
266 self.* = FnDef{266 self.* = FnDef{
267 .base = undefined,267 .base = undefined,
268 .fn_val = null,268 .fn_val = null,
...@@ -281,7 +281,7 @@ pub const Scope = struct {...@@ -281,7 +281,7 @@ pub const Scope = struct {
281281
282 /// Creates a CompTime scope with 1 reference282 /// Creates a CompTime scope with 1 reference
283 pub fn create(comp: *Compilation, parent: *Scope) !*CompTime {283 pub fn create(comp: *Compilation, parent: *Scope) !*CompTime {
284 const self = try comp.gpa().createOne(CompTime);284 const self = try comp.gpa().create(CompTime);
285 self.* = CompTime{ .base = undefined };285 self.* = CompTime{ .base = undefined };
286 self.base.init(Id.CompTime, parent);286 self.base.init(Id.CompTime, parent);
287 return self;287 return self;
...@@ -309,7 +309,7 @@ pub const Scope = struct {...@@ -309,7 +309,7 @@ pub const Scope = struct {
309 kind: Kind,309 kind: Kind,
310 defer_expr_scope: *DeferExpr,310 defer_expr_scope: *DeferExpr,
311 ) !*Defer {311 ) !*Defer {
312 const self = try comp.gpa().createOne(Defer);312 const self = try comp.gpa().create(Defer);
313 self.* = Defer{313 self.* = Defer{
314 .base = undefined,314 .base = undefined,
315 .defer_expr_scope = defer_expr_scope,315 .defer_expr_scope = defer_expr_scope,
...@@ -333,7 +333,7 @@ pub const Scope = struct {...@@ -333,7 +333,7 @@ pub const Scope = struct {
333333
334 /// Creates a DeferExpr scope with 1 reference334 /// Creates a DeferExpr scope with 1 reference
335 pub fn create(comp: *Compilation, parent: *Scope, expr_node: *ast.Node) !*DeferExpr {335 pub fn create(comp: *Compilation, parent: *Scope, expr_node: *ast.Node) !*DeferExpr {
336 const self = try comp.gpa().createOne(DeferExpr);336 const self = try comp.gpa().create(DeferExpr);
337 self.* = DeferExpr{337 self.* = DeferExpr{
338 .base = undefined,338 .base = undefined,
339 .expr_node = expr_node,339 .expr_node = expr_node,
...@@ -398,7 +398,7 @@ pub const Scope = struct {...@@ -398,7 +398,7 @@ pub const Scope = struct {
398 }398 }
399399
400 fn create(comp: *Compilation, parent: *Scope, name: []const u8, src_node: *ast.Node) !*Var {400 fn create(comp: *Compilation, parent: *Scope, name: []const u8, src_node: *ast.Node) !*Var {
401 const self = try comp.gpa().createOne(Var);401 const self = try comp.gpa().create(Var);
402 self.* = Var{402 self.* = Var{
403 .base = undefined,403 .base = undefined,
404 .name = name,404 .name = name,
src-self-hosted/type.zig+10-7
...@@ -413,7 +413,7 @@ pub const Type = struct {...@@ -413,7 +413,7 @@ pub const Type = struct {
413 key.ref();413 key.ref();
414 errdefer key.deref(comp);414 errdefer key.deref(comp);
415415
416 const self = try comp.gpa().createOne(Fn);416 const self = try comp.gpa().create(Fn);
417 self.* = Fn{417 self.* = Fn{
418 .base = undefined,418 .base = undefined,
419 .key = key,419 .key = key,
...@@ -615,11 +615,12 @@ pub const Type = struct {...@@ -615,11 +615,12 @@ pub const Type = struct {
615 }615 }
616 }616 }
617617
618 const self = try comp.gpa().create(Int{618 const self = try comp.gpa().create(Int);
619 self.* = Int{
619 .base = undefined,620 .base = undefined,
620 .key = key,621 .key = key,
621 .garbage_node = undefined,622 .garbage_node = undefined,
622 });623 };
623 errdefer comp.gpa().destroy(self);624 errdefer comp.gpa().destroy(self);
624625
625 const u_or_i = "ui"[@boolToInt(key.is_signed)];626 const u_or_i = "ui"[@boolToInt(key.is_signed)];
...@@ -781,11 +782,12 @@ pub const Type = struct {...@@ -781,11 +782,12 @@ pub const Type = struct {
781 }782 }
782 }783 }
783784
784 const self = try comp.gpa().create(Pointer{785 const self = try comp.gpa().create(Pointer);
786 self.* = Pointer{
785 .base = undefined,787 .base = undefined,
786 .key = normal_key,788 .key = normal_key,
787 .garbage_node = undefined,789 .garbage_node = undefined,
788 });790 };
789 errdefer comp.gpa().destroy(self);791 errdefer comp.gpa().destroy(self);
790792
791 const size_str = switch (self.key.size) {793 const size_str = switch (self.key.size) {
...@@ -879,11 +881,12 @@ pub const Type = struct {...@@ -879,11 +881,12 @@ pub const Type = struct {
879 }881 }
880 }882 }
881883
882 const self = try comp.gpa().create(Array{884 const self = try comp.gpa().create(Array);
885 self.* = Array{
883 .base = undefined,886 .base = undefined,
884 .key = key,887 .key = key,
885 .garbage_node = undefined,888 .garbage_node = undefined,
886 });889 };
887 errdefer comp.gpa().destroy(self);890 errdefer comp.gpa().destroy(self);
888891
889 const name = try std.fmt.allocPrint(comp.gpa(), "[{}]{}", key.len, key.elem_type.name);892 const name = try std.fmt.allocPrint(comp.gpa(), "[{}]{}", key.len, key.elem_type.name);
src-self-hosted/value.zig+21-14
...@@ -135,14 +135,15 @@ pub const Value = struct {...@@ -135,14 +135,15 @@ pub const Value = struct {
135 symbol_name: Buffer,135 symbol_name: Buffer,
136136
137 pub fn create(comp: *Compilation, fn_type: *Type.Fn, symbol_name: Buffer) !*FnProto {137 pub fn create(comp: *Compilation, fn_type: *Type.Fn, symbol_name: Buffer) !*FnProto {
138 const self = try comp.gpa().create(FnProto{138 const self = try comp.gpa().create(FnProto);
139 self.* = FnProto{
139 .base = Value{140 .base = Value{
140 .id = Value.Id.FnProto,141 .id = Value.Id.FnProto,
141 .typ = &fn_type.base,142 .typ = &fn_type.base,
142 .ref_count = std.atomic.Int(usize).init(1),143 .ref_count = std.atomic.Int(usize).init(1),
143 },144 },
144 .symbol_name = symbol_name,145 .symbol_name = symbol_name,
145 });146 };
146 fn_type.base.base.ref();147 fn_type.base.base.ref();
147 return self;148 return self;
148 }149 }
...@@ -190,14 +191,16 @@ pub const Value = struct {...@@ -190,14 +191,16 @@ pub const Value = struct {
190 /// Creates a Fn value with 1 ref191 /// Creates a Fn value with 1 ref
191 /// Takes ownership of symbol_name192 /// Takes ownership of symbol_name
192 pub fn create(comp: *Compilation, fn_type: *Type.Fn, fndef_scope: *Scope.FnDef, symbol_name: Buffer) !*Fn {193 pub fn create(comp: *Compilation, fn_type: *Type.Fn, fndef_scope: *Scope.FnDef, symbol_name: Buffer) !*Fn {
193 const link_set_node = try comp.gpa().create(Compilation.FnLinkSet.Node{194 const link_set_node = try comp.gpa().create(Compilation.FnLinkSet.Node);
195 link_set_node.* = Compilation.FnLinkSet.Node{
194 .data = null,196 .data = null,
195 .next = undefined,197 .next = undefined,
196 .prev = undefined,198 .prev = undefined,
197 });199 };
198 errdefer comp.gpa().destroy(link_set_node);200 errdefer comp.gpa().destroy(link_set_node);
199201
200 const self = try comp.gpa().create(Fn{202 const self = try comp.gpa().create(Fn);
203 self.* = Fn{
201 .base = Value{204 .base = Value{
202 .id = Value.Id.Fn,205 .id = Value.Id.Fn,
203 .typ = &fn_type.base,206 .typ = &fn_type.base,
...@@ -209,7 +212,7 @@ pub const Value = struct {...@@ -209,7 +212,7 @@ pub const Value = struct {
209 .symbol_name = symbol_name,212 .symbol_name = symbol_name,
210 .containing_object = Buffer.initNull(comp.gpa()),213 .containing_object = Buffer.initNull(comp.gpa()),
211 .link_set_node = link_set_node,214 .link_set_node = link_set_node,
212 });215 };
213 fn_type.base.base.ref();216 fn_type.base.base.ref();
214 fndef_scope.fn_val = self;217 fndef_scope.fn_val = self;
215 fndef_scope.base.ref();218 fndef_scope.base.ref();
...@@ -353,7 +356,8 @@ pub const Value = struct {...@@ -353,7 +356,8 @@ pub const Value = struct {
353 var ptr_type_consumed = false;356 var ptr_type_consumed = false;
354 errdefer if (!ptr_type_consumed) ptr_type.base.base.deref(comp);357 errdefer if (!ptr_type_consumed) ptr_type.base.base.deref(comp);
355358
356 const self = try comp.gpa().create(Value.Ptr{359 const self = try comp.gpa().create(Value.Ptr);
360 self.* = Value.Ptr{
357 .base = Value{361 .base = Value{
358 .id = Value.Id.Ptr,362 .id = Value.Id.Ptr,
359 .typ = &ptr_type.base,363 .typ = &ptr_type.base,
...@@ -366,7 +370,7 @@ pub const Value = struct {...@@ -366,7 +370,7 @@ pub const Value = struct {
366 },370 },
367 },371 },
368 .mut = Mut.CompTimeConst,372 .mut = Mut.CompTimeConst,
369 });373 };
370 ptr_type_consumed = true;374 ptr_type_consumed = true;
371 errdefer comp.gpa().destroy(self);375 errdefer comp.gpa().destroy(self);
372376
...@@ -430,14 +434,15 @@ pub const Value = struct {...@@ -430,14 +434,15 @@ pub const Value = struct {
430 }) catch unreachable);434 }) catch unreachable);
431 errdefer array_type.base.base.deref(comp);435 errdefer array_type.base.base.deref(comp);
432436
433 const self = try comp.gpa().create(Value.Array{437 const self = try comp.gpa().create(Value.Array);
438 self.* = Value.Array{
434 .base = Value{439 .base = Value{
435 .id = Value.Id.Array,440 .id = Value.Id.Array,
436 .typ = &array_type.base,441 .typ = &array_type.base,
437 .ref_count = std.atomic.Int(usize).init(1),442 .ref_count = std.atomic.Int(usize).init(1),
438 },443 },
439 .special = Special{ .OwnedBuffer = buffer },444 .special = Special{ .OwnedBuffer = buffer },
440 });445 };
441 errdefer comp.gpa().destroy(self);446 errdefer comp.gpa().destroy(self);
442447
443 return self;448 return self;
...@@ -509,14 +514,15 @@ pub const Value = struct {...@@ -509,14 +514,15 @@ pub const Value = struct {
509 big_int: std.math.big.Int,514 big_int: std.math.big.Int,
510515
511 pub fn createFromString(comp: *Compilation, typ: *Type, base: u8, value: []const u8) !*Int {516 pub fn createFromString(comp: *Compilation, typ: *Type, base: u8, value: []const u8) !*Int {
512 const self = try comp.gpa().create(Value.Int{517 const self = try comp.gpa().create(Value.Int);
518 self.* = Value.Int{
513 .base = Value{519 .base = Value{
514 .id = Value.Id.Int,520 .id = Value.Id.Int,
515 .typ = typ,521 .typ = typ,
516 .ref_count = std.atomic.Int(usize).init(1),522 .ref_count = std.atomic.Int(usize).init(1),
517 },523 },
518 .big_int = undefined,524 .big_int = undefined,
519 });525 };
520 typ.base.ref();526 typ.base.ref();
521 errdefer comp.gpa().destroy(self);527 errdefer comp.gpa().destroy(self);
522528
...@@ -557,14 +563,15 @@ pub const Value = struct {...@@ -557,14 +563,15 @@ pub const Value = struct {
557 old.base.typ.base.ref();563 old.base.typ.base.ref();
558 errdefer old.base.typ.base.deref(comp);564 errdefer old.base.typ.base.deref(comp);
559565
560 const new = try comp.gpa().create(Value.Int{566 const new = try comp.gpa().create(Value.Int);
567 new.* = Value.Int{
561 .base = Value{568 .base = Value{
562 .id = Value.Id.Int,569 .id = Value.Id.Int,
563 .typ = old.base.typ,570 .typ = old.base.typ,
564 .ref_count = std.atomic.Int(usize).init(1),571 .ref_count = std.atomic.Int(usize).init(1),
565 },572 },
566 .big_int = undefined,573 .big_int = undefined,
567 });574 };
568 errdefer comp.gpa().destroy(new);575 errdefer comp.gpa().destroy(new);
569576
570 new.big_int = try old.big_int.clone();577 new.big_int = try old.big_int.clone();
std/atomic/queue.zig+3-2
...@@ -221,11 +221,12 @@ fn startPuts(ctx: *Context) u8 {...@@ -221,11 +221,12 @@ fn startPuts(ctx: *Context) u8 {
221 while (put_count != 0) : (put_count -= 1) {221 while (put_count != 0) : (put_count -= 1) {
222 std.os.time.sleep(1); // let the os scheduler be our fuzz222 std.os.time.sleep(1); // let the os scheduler be our fuzz
223 const x = @bitCast(i32, r.random.scalar(u32));223 const x = @bitCast(i32, r.random.scalar(u32));
224 const node = ctx.allocator.create(Queue(i32).Node{224 const node = ctx.allocator.create(Queue(i32).Node) catch unreachable;
225 node.* = Queue(i32).Node{
225 .prev = undefined,226 .prev = undefined,
226 .next = undefined,227 .next = undefined,
227 .data = x,228 .data = x,
228 }) catch unreachable;229 };
229 ctx.queue.put(node);230 ctx.queue.put(node);
230 _ = @atomicRmw(isize, &ctx.put_sum, builtin.AtomicRmwOp.Add, x, AtomicOrder.SeqCst);231 _ = @atomicRmw(isize, &ctx.put_sum, builtin.AtomicRmwOp.Add, x, AtomicOrder.SeqCst);
231 }232 }
std/atomic/stack.zig+3-2
...@@ -155,10 +155,11 @@ fn startPuts(ctx: *Context) u8 {...@@ -155,10 +155,11 @@ fn startPuts(ctx: *Context) u8 {
155 while (put_count != 0) : (put_count -= 1) {155 while (put_count != 0) : (put_count -= 1) {
156 std.os.time.sleep(1); // let the os scheduler be our fuzz156 std.os.time.sleep(1); // let the os scheduler be our fuzz
157 const x = @bitCast(i32, r.random.scalar(u32));157 const x = @bitCast(i32, r.random.scalar(u32));
158 const node = ctx.allocator.create(Stack(i32).Node{158 const node = ctx.allocator.create(Stack(i32).Node) catch unreachable;
159 node.* = Stack(i32).Node{
159 .next = undefined,160 .next = undefined,
160 .data = x,161 .data = x,
161 }) catch unreachable;162 };
162 ctx.stack.push(node);163 ctx.stack.push(node);
163 _ = @atomicRmw(isize, &ctx.put_sum, builtin.AtomicRmwOp.Add, x, AtomicOrder.SeqCst);164 _ = @atomicRmw(isize, &ctx.put_sum, builtin.AtomicRmwOp.Add, x, AtomicOrder.SeqCst);
164 }165 }
std/build.zig+36-20
...@@ -89,7 +89,7 @@ pub const Builder = struct {...@@ -89,7 +89,7 @@ pub const Builder = struct {
89 };89 };
9090
91 pub fn init(allocator: *Allocator, zig_exe: []const u8, build_root: []const u8, cache_root: []const u8) Builder {91 pub fn init(allocator: *Allocator, zig_exe: []const u8, build_root: []const u8, cache_root: []const u8) Builder {
92 const env_map = allocator.createOne(BufMap) catch unreachable;92 const env_map = allocator.create(BufMap) catch unreachable;
93 env_map.* = os.getEnvMap(allocator) catch unreachable;93 env_map.* = os.getEnvMap(allocator) catch unreachable;
94 var self = Builder{94 var self = Builder{
95 .zig_exe = zig_exe,95 .zig_exe = zig_exe,
...@@ -170,7 +170,8 @@ pub const Builder = struct {...@@ -170,7 +170,8 @@ pub const Builder = struct {
170 }170 }
171171
172 pub fn addTest(self: *Builder, root_src: []const u8) *TestStep {172 pub fn addTest(self: *Builder, root_src: []const u8) *TestStep {
173 const test_step = self.allocator.create(TestStep.init(self, root_src)) catch unreachable;173 const test_step = self.allocator.create(TestStep) catch unreachable;
174 test_step.* = TestStep.init(self, root_src);
174 return test_step;175 return test_step;
175 }176 }
176177
...@@ -202,18 +203,21 @@ pub const Builder = struct {...@@ -202,18 +203,21 @@ pub const Builder = struct {
202 }203 }
203204
204 pub fn addWriteFile(self: *Builder, file_path: []const u8, data: []const u8) *WriteFileStep {205 pub fn addWriteFile(self: *Builder, file_path: []const u8, data: []const u8) *WriteFileStep {
205 const write_file_step = self.allocator.create(WriteFileStep.init(self, file_path, data)) catch unreachable;206 const write_file_step = self.allocator.create(WriteFileStep) catch unreachable;
207 write_file_step.* = WriteFileStep.init(self, file_path, data);
206 return write_file_step;208 return write_file_step;
207 }209 }
208210
209 pub fn addLog(self: *Builder, comptime format: []const u8, args: ...) *LogStep {211 pub fn addLog(self: *Builder, comptime format: []const u8, args: ...) *LogStep {
210 const data = self.fmt(format, args);212 const data = self.fmt(format, args);
211 const log_step = self.allocator.create(LogStep.init(self, data)) catch unreachable;213 const log_step = self.allocator.create(LogStep) catch unreachable;
214 log_step.* = LogStep.init(self, data);
212 return log_step;215 return log_step;
213 }216 }
214217
215 pub fn addRemoveDirTree(self: *Builder, dir_path: []const u8) *RemoveDirStep {218 pub fn addRemoveDirTree(self: *Builder, dir_path: []const u8) *RemoveDirStep {
216 const remove_dir_step = self.allocator.create(RemoveDirStep.init(self, dir_path)) catch unreachable;219 const remove_dir_step = self.allocator.create(RemoveDirStep) catch unreachable;
220 remove_dir_step.* = RemoveDirStep.init(self, dir_path);
217 return remove_dir_step;221 return remove_dir_step;
218 }222 }
219223
...@@ -414,10 +418,11 @@ pub const Builder = struct {...@@ -414,10 +418,11 @@ pub const Builder = struct {
414 }418 }
415419
416 pub fn step(self: *Builder, name: []const u8, description: []const u8) *Step {420 pub fn step(self: *Builder, name: []const u8, description: []const u8) *Step {
417 const step_info = self.allocator.create(TopLevelStep{421 const step_info = self.allocator.create(TopLevelStep) catch unreachable;
422 step_info.* = TopLevelStep{
418 .step = Step.initNoOp(name, self.allocator),423 .step = Step.initNoOp(name, self.allocator),
419 .description = description,424 .description = description,
420 }) catch unreachable;425 };
421 self.top_level_steps.append(step_info) catch unreachable;426 self.top_level_steps.append(step_info) catch unreachable;
422 return &step_info.step;427 return &step_info.step;
423 }428 }
...@@ -616,7 +621,8 @@ pub const Builder = struct {...@@ -616,7 +621,8 @@ pub const Builder = struct {
616 const full_dest_path = os.path.resolve(self.allocator, self.prefix, dest_rel_path) catch unreachable;621 const full_dest_path = os.path.resolve(self.allocator, self.prefix, dest_rel_path) catch unreachable;
617 self.pushInstalledFile(full_dest_path);622 self.pushInstalledFile(full_dest_path);
618623
619 const install_step = self.allocator.create(InstallFileStep.init(self, src_path, full_dest_path)) catch unreachable;624 const install_step = self.allocator.create(InstallFileStep) catch unreachable;
625 install_step.* = InstallFileStep.init(self, src_path, full_dest_path);
620 return install_step;626 return install_step;
621 }627 }
622628
...@@ -865,43 +871,51 @@ pub const LibExeObjStep = struct {...@@ -865,43 +871,51 @@ pub const LibExeObjStep = struct {
865 };871 };
866872
867 pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8, ver: Version) *LibExeObjStep {873 pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8, ver: Version) *LibExeObjStep {
868 const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Lib, false, ver)) catch unreachable;874 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
875 self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver);
869 return self;876 return self;
870 }877 }
871878
872 pub fn createCSharedLibrary(builder: *Builder, name: []const u8, version: Version) *LibExeObjStep {879 pub fn createCSharedLibrary(builder: *Builder, name: []const u8, version: Version) *LibExeObjStep {
873 const self = builder.allocator.create(initC(builder, name, Kind.Lib, version, false)) catch unreachable;880 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
881 self.* = initC(builder, name, Kind.Lib, version, false);
874 return self;882 return self;
875 }883 }
876884
877 pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {885 pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
878 const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0))) catch unreachable;886 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
887 self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0));
879 return self;888 return self;
880 }889 }
881890
882 pub fn createCStaticLibrary(builder: *Builder, name: []const u8) *LibExeObjStep {891 pub fn createCStaticLibrary(builder: *Builder, name: []const u8) *LibExeObjStep {
883 const self = builder.allocator.create(initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true)) catch unreachable;892 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
893 self.* = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true);
884 return self;894 return self;
885 }895 }
886896
887 pub fn createObject(builder: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep {897 pub fn createObject(builder: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep {
888 const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0))) catch unreachable;898 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
899 self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
889 return self;900 return self;
890 }901 }
891902
892 pub fn createCObject(builder: *Builder, name: []const u8, src: []const u8) *LibExeObjStep {903 pub fn createCObject(builder: *Builder, name: []const u8, src: []const u8) *LibExeObjStep {
893 const self = builder.allocator.create(initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false)) catch unreachable;904 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
905 self.* = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false);
894 self.object_src = src;906 self.object_src = src;
895 return self;907 return self;
896 }908 }
897909
898 pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?[]const u8, static: bool) *LibExeObjStep {910 pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?[]const u8, static: bool) *LibExeObjStep {
899 const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Exe, static, builder.version(0, 0, 0))) catch unreachable;911 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
912 self.* = initExtraArgs(builder, name, root_src, Kind.Exe, static, builder.version(0, 0, 0));
900 return self;913 return self;
901 }914 }
902915
903 pub fn createCExecutable(builder: *Builder, name: []const u8) *LibExeObjStep {916 pub fn createCExecutable(builder: *Builder, name: []const u8) *LibExeObjStep {
904 const self = builder.allocator.create(initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false)) catch unreachable;917 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
918 self.* = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false);
905 return self;919 return self;
906 }920 }
907921
...@@ -1914,13 +1928,14 @@ pub const CommandStep = struct {...@@ -1914,13 +1928,14 @@ pub const CommandStep = struct {
19141928
1915 /// ::argv is copied.1929 /// ::argv is copied.
1916 pub fn create(builder: *Builder, cwd: ?[]const u8, env_map: *const BufMap, argv: []const []const u8) *CommandStep {1930 pub fn create(builder: *Builder, cwd: ?[]const u8, env_map: *const BufMap, argv: []const []const u8) *CommandStep {
1917 const self = builder.allocator.create(CommandStep{1931 const self = builder.allocator.create(CommandStep) catch unreachable;
1932 self.* = CommandStep{
1918 .builder = builder,1933 .builder = builder,
1919 .step = Step.init(argv[0], builder.allocator, make),1934 .step = Step.init(argv[0], builder.allocator, make),
1920 .argv = builder.allocator.alloc([]u8, argv.len) catch unreachable,1935 .argv = builder.allocator.alloc([]u8, argv.len) catch unreachable,
1921 .cwd = cwd,1936 .cwd = cwd,
1922 .env_map = env_map,1937 .env_map = env_map,
1923 }) catch unreachable;1938 };
19241939
1925 mem.copy([]const u8, self.argv, argv);1940 mem.copy([]const u8, self.argv, argv);
1926 self.step.name = self.argv[0];1941 self.step.name = self.argv[0];
...@@ -1949,12 +1964,13 @@ const InstallArtifactStep = struct {...@@ -1949,12 +1964,13 @@ const InstallArtifactStep = struct {
1949 LibExeObjStep.Kind.Exe => builder.exe_dir,1964 LibExeObjStep.Kind.Exe => builder.exe_dir,
1950 LibExeObjStep.Kind.Lib => builder.lib_dir,1965 LibExeObjStep.Kind.Lib => builder.lib_dir,
1951 };1966 };
1952 const self = builder.allocator.create(Self{1967 const self = builder.allocator.create(Self) catch unreachable;
1968 self.* = Self{
1953 .builder = builder,1969 .builder = builder,
1954 .step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),1970 .step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),
1955 .artifact = artifact,1971 .artifact = artifact,
1956 .dest_file = os.path.join(builder.allocator, dest_dir, artifact.out_filename) catch unreachable,1972 .dest_file = os.path.join(builder.allocator, dest_dir, artifact.out_filename) catch unreachable,
1957 }) catch unreachable;1973 };
1958 self.step.dependOn(&artifact.step);1974 self.step.dependOn(&artifact.step);
1959 builder.pushInstalledFile(self.dest_file);1975 builder.pushInstalledFile(self.dest_file);
1960 if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {1976 if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {
std/debug/index.zig+4-3
...@@ -751,7 +751,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {...@@ -751,7 +751,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
751 const self_file = try os.openSelfExe();751 const self_file = try os.openSelfExe();
752 defer self_file.close();752 defer self_file.close();
753753
754 const coff_obj = try allocator.createOne(coff.Coff);754 const coff_obj = try allocator.create(coff.Coff);
755 coff_obj.* = coff.Coff{755 coff_obj.* = coff.Coff{
756 .in_file = self_file,756 .in_file = self_file,
757 .allocator = allocator,757 .allocator = allocator,
...@@ -1036,7 +1036,7 @@ fn openSelfDebugInfoMacOs(allocator: *mem.Allocator) !DebugInfo {...@@ -1036,7 +1036,7 @@ fn openSelfDebugInfoMacOs(allocator: *mem.Allocator) !DebugInfo {
1036 }1036 }
1037 }1037 }
1038 }1038 }
1039 const sentinel = try allocator.createOne(macho.nlist_64);1039 const sentinel = try allocator.create(macho.nlist_64);
1040 sentinel.* = macho.nlist_64{1040 sentinel.* = macho.nlist_64{
1041 .n_strx = 0,1041 .n_strx = 0,
1042 .n_type = 36,1042 .n_type = 36,
...@@ -1949,7 +1949,8 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void {...@@ -1949,7 +1949,8 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void {
19491949
1950 try di.dwarf_seekable_stream.seekTo(compile_unit_pos);1950 try di.dwarf_seekable_stream.seekTo(compile_unit_pos);
19511951
1952 const compile_unit_die = try di.allocator().create(try parseDie(di, abbrev_table, is_64));1952 const compile_unit_die = try di.allocator().create(Die);
1953 compile_unit_die.* = try parseDie(di, abbrev_table, is_64);
19531954
1954 if (compile_unit_die.tag_id != DW.TAG_compile_unit) return error.InvalidDebugInfo;1955 if (compile_unit_die.tag_id != DW.TAG_compile_unit) return error.InvalidDebugInfo;
19551956
std/event/channel.zig+3-2
...@@ -54,7 +54,8 @@ pub fn Channel(comptime T: type) type {...@@ -54,7 +54,8 @@ pub fn Channel(comptime T: type) type {
54 const buffer_nodes = try loop.allocator.alloc(T, capacity);54 const buffer_nodes = try loop.allocator.alloc(T, capacity);
55 errdefer loop.allocator.free(buffer_nodes);55 errdefer loop.allocator.free(buffer_nodes);
5656
57 const self = try loop.allocator.create(SelfChannel{57 const self = try loop.allocator.create(SelfChannel);
58 self.* = SelfChannel{
58 .loop = loop,59 .loop = loop,
59 .buffer_len = 0,60 .buffer_len = 0,
60 .buffer_nodes = buffer_nodes,61 .buffer_nodes = buffer_nodes,
...@@ -66,7 +67,7 @@ pub fn Channel(comptime T: type) type {...@@ -66,7 +67,7 @@ pub fn Channel(comptime T: type) type {
66 .or_null_queue = std.atomic.Queue(*std.atomic.Queue(GetNode).Node).init(),67 .or_null_queue = std.atomic.Queue(*std.atomic.Queue(GetNode).Node).init(),
67 .get_count = 0,68 .get_count = 0,
68 .put_count = 0,69 .put_count = 0,
69 });70 };
70 errdefer loop.allocator.destroy(self);71 errdefer loop.allocator.destroy(self);
7172
72 return self;73 return self;
std/event/fs.zig+4-4
...@@ -495,7 +495,7 @@ pub const CloseOperation = struct {...@@ -495,7 +495,7 @@ pub const CloseOperation = struct {
495 };495 };
496496
497 pub fn start(loop: *Loop) (error{OutOfMemory}!*CloseOperation) {497 pub fn start(loop: *Loop) (error{OutOfMemory}!*CloseOperation) {
498 const self = try loop.allocator.createOne(CloseOperation);498 const self = try loop.allocator.create(CloseOperation);
499 self.* = CloseOperation{499 self.* = CloseOperation{
500 .loop = loop,500 .loop = loop,
501 .os_data = switch (builtin.os) {501 .os_data = switch (builtin.os) {
...@@ -787,7 +787,7 @@ pub fn Watch(comptime V: type) type {...@@ -787,7 +787,7 @@ pub fn Watch(comptime V: type) type {
787 },787 },
788788
789 builtin.Os.windows => {789 builtin.Os.windows => {
790 const self = try loop.allocator.createOne(Self);790 const self = try loop.allocator.create(Self);
791 errdefer loop.allocator.destroy(self);791 errdefer loop.allocator.destroy(self);
792 self.* = Self{792 self.* = Self{
793 .channel = channel,793 .channel = channel,
...@@ -802,7 +802,7 @@ pub fn Watch(comptime V: type) type {...@@ -802,7 +802,7 @@ pub fn Watch(comptime V: type) type {
802 },802 },
803803
804 builtin.Os.macosx, builtin.Os.freebsd => {804 builtin.Os.macosx, builtin.Os.freebsd => {
805 const self = try loop.allocator.createOne(Self);805 const self = try loop.allocator.create(Self);
806 errdefer loop.allocator.destroy(self);806 errdefer loop.allocator.destroy(self);
807807
808 self.* = Self{808 self.* = Self{
...@@ -1068,7 +1068,7 @@ pub fn Watch(comptime V: type) type {...@@ -1068,7 +1068,7 @@ pub fn Watch(comptime V: type) type {
1068 }1068 }
1069 } else {1069 } else {
1070 errdefer _ = self.os_data.dir_table.remove(dirname);1070 errdefer _ = self.os_data.dir_table.remove(dirname);
1071 const dir = try self.channel.loop.allocator.createOne(OsData.Dir);1071 const dir = try self.channel.loop.allocator.create(OsData.Dir);
1072 errdefer self.channel.loop.allocator.destroy(dir);1072 errdefer self.channel.loop.allocator.destroy(dir);
10731073
1074 dir.* = OsData.Dir{1074 dir.* = OsData.Dir{
std/event/group.zig+3-2
...@@ -42,10 +42,11 @@ pub fn Group(comptime ReturnType: type) type {...@@ -42,10 +42,11 @@ pub fn Group(comptime ReturnType: type) type {
4242
43 /// Add a promise to the group. Thread-safe.43 /// Add a promise to the group. Thread-safe.
44 pub fn add(self: *Self, handle: promise->ReturnType) (error{OutOfMemory}!void) {44 pub fn add(self: *Self, handle: promise->ReturnType) (error{OutOfMemory}!void) {
45 const node = try self.lock.loop.allocator.create(Stack.Node{45 const node = try self.lock.loop.allocator.create(Stack.Node);
46 node.* = Stack.Node{
46 .next = undefined,47 .next = undefined,
47 .data = handle,48 .data = handle,
48 });49 };
49 self.alloc_stack.push(node);50 self.alloc_stack.push(node);
50 }51 }
5152
std/heap.zig+2-1
...@@ -518,7 +518,8 @@ fn testAllocator(allocator: *mem.Allocator) !void {...@@ -518,7 +518,8 @@ fn testAllocator(allocator: *mem.Allocator) !void {
518 var slice = try allocator.alloc(*i32, 100);518 var slice = try allocator.alloc(*i32, 100);
519 assert(slice.len == 100);519 assert(slice.len == 100);
520 for (slice) |*item, i| {520 for (slice) |*item, i| {
521 item.* = try allocator.create(@intCast(i32, i));521 item.* = try allocator.create(i32);
522 item.*.* = @intCast(i32, i);
522 }523 }
523524
524 slice = try allocator.realloc(*i32, slice, 20000);525 slice = try allocator.realloc(*i32, slice, 20000);
std/io.zig+3-2
...@@ -944,12 +944,13 @@ pub const BufferedAtomicFile = struct {...@@ -944,12 +944,13 @@ pub const BufferedAtomicFile = struct {
944944
945 pub fn create(allocator: *mem.Allocator, dest_path: []const u8) !*BufferedAtomicFile {945 pub fn create(allocator: *mem.Allocator, dest_path: []const u8) !*BufferedAtomicFile {
946 // TODO with well defined copy elision we don't need this allocation946 // TODO with well defined copy elision we don't need this allocation
947 var self = try allocator.create(BufferedAtomicFile{947 var self = try allocator.create(BufferedAtomicFile);
948 self.* = BufferedAtomicFile{
948 .atomic_file = undefined,949 .atomic_file = undefined,
949 .file_stream = undefined,950 .file_stream = undefined,
950 .buffered_stream = undefined,951 .buffered_stream = undefined,
951 .allocator = allocator,952 .allocator = allocator,
952 });953 };
953 errdefer allocator.destroy(self);954 errdefer allocator.destroy(self);
954955
955 self.atomic_file = try os.AtomicFile.init(dest_path, os.File.default_mode);956 self.atomic_file = try os.AtomicFile.init(dest_path, os.File.default_mode);
std/linked_list.zig+1-1
...@@ -190,7 +190,7 @@ pub fn LinkedList(comptime T: type) type {...@@ -190,7 +190,7 @@ pub fn LinkedList(comptime T: type) type {
190 /// Returns:190 /// Returns:
191 /// A pointer to the new node.191 /// A pointer to the new node.
192 pub fn allocateNode(list: *Self, allocator: *Allocator) !*Node {192 pub fn allocateNode(list: *Self, allocator: *Allocator) !*Node {
193 return allocator.create(Node(undefined));193 return allocator.create(Node);
194 }194 }
195195
196 /// Deallocate a node.196 /// Deallocate a node.
std/mem.zig+1-12
...@@ -36,20 +36,9 @@ pub const Allocator = struct {...@@ -36,20 +36,9 @@ pub const Allocator = struct {
36 /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`36 /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`
37 freeFn: fn (self: *Allocator, old_mem: []u8) void,37 freeFn: fn (self: *Allocator, old_mem: []u8) void,
3838
39 /// Call `destroy` with the result
40 /// TODO this is deprecated. use createOne instead
41 pub fn create(self: *Allocator, init: var) Error!*@typeOf(init) {
42 const T = @typeOf(init);
43 if (@sizeOf(T) == 0) return &(T{});
44 const slice = try self.alloc(T, 1);
45 const ptr = &slice[0];
46 ptr.* = init;
47 return ptr;
48 }
49
50 /// Call `destroy` with the result.39 /// Call `destroy` with the result.
51 /// Returns undefined memory.40 /// Returns undefined memory.
52 pub fn createOne(self: *Allocator, comptime T: type) Error!*T {41 pub fn create(self: *Allocator, comptime T: type) Error!*T {
53 if (@sizeOf(T) == 0) return &(T{});42 if (@sizeOf(T) == 0) return &(T{});
54 const slice = try self.alloc(T, 1);43 const slice = try self.alloc(T, 1);
55 return &slice[0];44 return &slice[0];
std/os/child_process.zig+3-2
...@@ -88,7 +88,8 @@ pub const ChildProcess = struct {...@@ -88,7 +88,8 @@ pub const ChildProcess = struct {
88 /// First argument in argv is the executable.88 /// First argument in argv is the executable.
89 /// On success must call deinit.89 /// On success must call deinit.
90 pub fn init(argv: []const []const u8, allocator: *mem.Allocator) !*ChildProcess {90 pub fn init(argv: []const []const u8, allocator: *mem.Allocator) !*ChildProcess {
91 const child = try allocator.create(ChildProcess{91 const child = try allocator.create(ChildProcess);
92 child.* = ChildProcess{
92 .allocator = allocator,93 .allocator = allocator,
93 .argv = argv,94 .argv = argv,
94 .pid = undefined,95 .pid = undefined,
...@@ -109,7 +110,7 @@ pub const ChildProcess = struct {...@@ -109,7 +110,7 @@ pub const ChildProcess = struct {
109 .stdin_behavior = StdIo.Inherit,110 .stdin_behavior = StdIo.Inherit,
110 .stdout_behavior = StdIo.Inherit,111 .stdout_behavior = StdIo.Inherit,
111 .stderr_behavior = StdIo.Inherit,112 .stderr_behavior = StdIo.Inherit,
112 });113 };
113 errdefer allocator.destroy(child);114 errdefer allocator.destroy(child);
114 return child;115 return child;
115 }116 }
std/os/index.zig+3-2
...@@ -3047,7 +3047,8 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread...@@ -3047,7 +3047,8 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
3047 const bytes_ptr = windows.HeapAlloc(heap_handle, 0, byte_count) orelse return SpawnThreadError.OutOfMemory;3047 const bytes_ptr = windows.HeapAlloc(heap_handle, 0, byte_count) orelse return SpawnThreadError.OutOfMemory;
3048 errdefer assert(windows.HeapFree(heap_handle, 0, bytes_ptr) != 0);3048 errdefer assert(windows.HeapFree(heap_handle, 0, bytes_ptr) != 0);
3049 const bytes = @ptrCast([*]u8, bytes_ptr)[0..byte_count];3049 const bytes = @ptrCast([*]u8, bytes_ptr)[0..byte_count];
3050 const outer_context = std.heap.FixedBufferAllocator.init(bytes).allocator.create(WinThread.OuterContext{3050 const outer_context = std.heap.FixedBufferAllocator.init(bytes).allocator.create(WinThread.OuterContext) catch unreachable;
3051 outer_context.* = WinThread.OuterContext{
3051 .thread = Thread{3052 .thread = Thread{
3052 .data = Thread.Data{3053 .data = Thread.Data{
3053 .heap_handle = heap_handle,3054 .heap_handle = heap_handle,
...@@ -3056,7 +3057,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread...@@ -3056,7 +3057,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
3056 },3057 },
3057 },3058 },
3058 .inner = context,3059 .inner = context,
3059 }) catch unreachable;3060 };
30603061
3061 const parameter = if (@sizeOf(Context) == 0) null else @ptrCast(*c_void, &outer_context.inner);3062 const parameter = if (@sizeOf(Context) == 0) null else @ptrCast(*c_void, &outer_context.inner);
3062 outer_context.thread.data.handle = windows.CreateThread(null, default_stack_size, WinThread.threadMain, parameter, 0, null) orelse {3063 outer_context.thread.data.handle = windows.CreateThread(null, default_stack_size, WinThread.threadMain, parameter, 0, null) orelse {
std/zig/parse.zig+226-150
...@@ -17,14 +17,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -17,14 +17,15 @@ 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 arena.create(ast.Node.Root{20 const root_node = try arena.create(ast.Node.Root);
21 root_node.* = ast.Node.Root{
21 .base = ast.Node{ .id = ast.Node.Id.Root },22 .base = ast.Node{ .id = ast.Node.Id.Root },
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 .shebang = null,25 .shebang = null,
25 // initialized when we get the eof token26 // initialized when we get the eof token
26 .eof_token = undefined,27 .eof_token = undefined,
27 });28 };
2829
29 var tree = ast.Tree{30 var tree = ast.Tree{
30 .source = source,31 .source = source,
...@@ -75,20 +76,22 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -75,20 +76,22 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
75 Token.Id.Keyword_test => {76 Token.Id.Keyword_test => {
76 stack.append(State.TopLevel) catch unreachable;77 stack.append(State.TopLevel) catch unreachable;
7778
78 const block = try arena.create(ast.Node.Block{79 const block = try arena.create(ast.Node.Block);
80 block.* = ast.Node.Block{
79 .base = ast.Node{ .id = ast.Node.Id.Block },81 .base = ast.Node{ .id = ast.Node.Id.Block },
80 .label = null,82 .label = null,
81 .lbrace = undefined,83 .lbrace = undefined,
82 .statements = ast.Node.Block.StatementList.init(arena),84 .statements = ast.Node.Block.StatementList.init(arena),
83 .rbrace = undefined,85 .rbrace = undefined,
84 });86 };
85 const test_node = try arena.create(ast.Node.TestDecl{87 const test_node = try arena.create(ast.Node.TestDecl);
88 test_node.* = ast.Node.TestDecl{
86 .base = ast.Node{ .id = ast.Node.Id.TestDecl },89 .base = ast.Node{ .id = ast.Node.Id.TestDecl },
87 .doc_comments = comments,90 .doc_comments = comments,
88 .test_token = token_index,91 .test_token = token_index,
89 .name = undefined,92 .name = undefined,
90 .body_node = &block.base,93 .body_node = &block.base,
91 });94 };
92 try root_node.decls.push(&test_node.base);95 try root_node.decls.push(&test_node.base);
93 try stack.append(State{ .Block = block });96 try stack.append(State{ .Block = block });
94 try stack.append(State{97 try stack.append(State{
...@@ -119,19 +122,21 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -119,19 +122,21 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
119 continue;122 continue;
120 },123 },
121 Token.Id.Keyword_comptime => {124 Token.Id.Keyword_comptime => {
122 const block = try arena.create(ast.Node.Block{125 const block = try arena.create(ast.Node.Block);
126 block.* = ast.Node.Block{
123 .base = ast.Node{ .id = ast.Node.Id.Block },127 .base = ast.Node{ .id = ast.Node.Id.Block },
124 .label = null,128 .label = null,
125 .lbrace = undefined,129 .lbrace = undefined,
126 .statements = ast.Node.Block.StatementList.init(arena),130 .statements = ast.Node.Block.StatementList.init(arena),
127 .rbrace = undefined,131 .rbrace = undefined,
128 });132 };
129 const node = try arena.create(ast.Node.Comptime{133 const node = try arena.create(ast.Node.Comptime);
134 node.* = ast.Node.Comptime{
130 .base = ast.Node{ .id = ast.Node.Id.Comptime },135 .base = ast.Node{ .id = ast.Node.Id.Comptime },
131 .comptime_token = token_index,136 .comptime_token = token_index,
132 .expr = &block.base,137 .expr = &block.base,
133 .doc_comments = comments,138 .doc_comments = comments,
134 });139 };
135 try root_node.decls.push(&node.base);140 try root_node.decls.push(&node.base);
136141
137 stack.append(State.TopLevel) catch unreachable;142 stack.append(State.TopLevel) catch unreachable;
...@@ -235,14 +240,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -235,14 +240,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
235 return tree;240 return tree;
236 }241 }
237242
238 const node = try arena.create(ast.Node.Use{243 const node = try arena.create(ast.Node.Use);
244 node.* = ast.Node.Use{
239 .base = ast.Node{ .id = ast.Node.Id.Use },245 .base = ast.Node{ .id = ast.Node.Id.Use },
240 .use_token = token_index,246 .use_token = token_index,
241 .visib_token = ctx.visib_token,247 .visib_token = ctx.visib_token,
242 .expr = undefined,248 .expr = undefined,
243 .semicolon_token = undefined,249 .semicolon_token = undefined,
244 .doc_comments = ctx.comments,250 .doc_comments = ctx.comments,
245 });251 };
246 try ctx.decls.push(&node.base);252 try ctx.decls.push(&node.base);
247253
248 stack.append(State{254 stack.append(State{
...@@ -276,7 +282,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -276,7 +282,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
276 continue;282 continue;
277 },283 },
278 Token.Id.Keyword_fn, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc, Token.Id.Keyword_async => {284 Token.Id.Keyword_fn, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc, Token.Id.Keyword_async => {
279 const fn_proto = try arena.create(ast.Node.FnProto{285 const fn_proto = try arena.create(ast.Node.FnProto);
286 fn_proto.* = ast.Node.FnProto{
280 .base = ast.Node{ .id = ast.Node.Id.FnProto },287 .base = ast.Node{ .id = ast.Node.Id.FnProto },
281 .doc_comments = ctx.comments,288 .doc_comments = ctx.comments,
282 .visib_token = ctx.visib_token,289 .visib_token = ctx.visib_token,
...@@ -292,7 +299,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -292,7 +299,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
292 .lib_name = ctx.lib_name,299 .lib_name = ctx.lib_name,
293 .align_expr = null,300 .align_expr = null,
294 .section_expr = null,301 .section_expr = null,
295 });302 };
296 try ctx.decls.push(&fn_proto.base);303 try ctx.decls.push(&fn_proto.base);
297 stack.append(State{ .FnDef = fn_proto }) catch unreachable;304 stack.append(State{ .FnDef = fn_proto }) catch unreachable;
298 try stack.append(State{ .FnProto = fn_proto });305 try stack.append(State{ .FnProto = fn_proto });
...@@ -309,12 +316,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -309,12 +316,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
309 continue;316 continue;
310 },317 },
311 Token.Id.Keyword_async => {318 Token.Id.Keyword_async => {
312 const async_node = try arena.create(ast.Node.AsyncAttribute{319 const async_node = try arena.create(ast.Node.AsyncAttribute);
320 async_node.* = ast.Node.AsyncAttribute{
313 .base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },321 .base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },
314 .async_token = token_index,322 .async_token = token_index,
315 .allocator_type = null,323 .allocator_type = null,
316 .rangle_bracket = null,324 .rangle_bracket = null,
317 });325 };
318 fn_proto.async_attr = async_node;326 fn_proto.async_attr = async_node;
319327
320 try stack.append(State{328 try stack.append(State{
...@@ -341,13 +349,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -341,13 +349,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
341 },349 },
342 State.TopLevelExternOrField => |ctx| {350 State.TopLevelExternOrField => |ctx| {
343 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |identifier| {351 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |identifier| {
344 const node = try arena.create(ast.Node.StructField{352 const node = try arena.create(ast.Node.StructField);
353 node.* = ast.Node.StructField{
345 .base = ast.Node{ .id = ast.Node.Id.StructField },354 .base = ast.Node{ .id = ast.Node.Id.StructField },
346 .doc_comments = ctx.comments,355 .doc_comments = ctx.comments,
347 .visib_token = ctx.visib_token,356 .visib_token = ctx.visib_token,
348 .name_token = identifier,357 .name_token = identifier,
349 .type_expr = undefined,358 .type_expr = undefined,
350 });359 };
351 const node_ptr = try ctx.container_decl.fields_and_decls.addOne();360 const node_ptr = try ctx.container_decl.fields_and_decls.addOne();
352 node_ptr.* = &node.base;361 node_ptr.* = &node.base;
353362
...@@ -391,7 +400,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -391,7 +400,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
391 const token = nextToken(&tok_it, &tree);400 const token = nextToken(&tok_it, &tree);
392 const token_index = token.index;401 const token_index = token.index;
393 const token_ptr = token.ptr;402 const token_ptr = token.ptr;
394 const node = try arena.create(ast.Node.ContainerDecl{403 const node = try arena.create(ast.Node.ContainerDecl);
404 node.* = ast.Node.ContainerDecl{
395 .base = ast.Node{ .id = ast.Node.Id.ContainerDecl },405 .base = ast.Node{ .id = ast.Node.Id.ContainerDecl },
396 .layout_token = ctx.layout_token,406 .layout_token = ctx.layout_token,
397 .kind_token = switch (token_ptr.id) {407 .kind_token = switch (token_ptr.id) {
...@@ -405,7 +415,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -405,7 +415,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
405 .fields_and_decls = ast.Node.ContainerDecl.DeclList.init(arena),415 .fields_and_decls = ast.Node.ContainerDecl.DeclList.init(arena),
406 .lbrace_token = undefined,416 .lbrace_token = undefined,
407 .rbrace_token = undefined,417 .rbrace_token = undefined,
408 });418 };
409 ctx.opt_ctx.store(&node.base);419 ctx.opt_ctx.store(&node.base);
410420
411 stack.append(State{ .ContainerDecl = node }) catch unreachable;421 stack.append(State{ .ContainerDecl = node }) catch unreachable;
...@@ -464,13 +474,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -464,13 +474,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
464 Token.Id.Identifier => {474 Token.Id.Identifier => {
465 switch (tree.tokens.at(container_decl.kind_token).id) {475 switch (tree.tokens.at(container_decl.kind_token).id) {
466 Token.Id.Keyword_struct => {476 Token.Id.Keyword_struct => {
467 const node = try arena.create(ast.Node.StructField{477 const node = try arena.create(ast.Node.StructField);
478 node.* = ast.Node.StructField{
468 .base = ast.Node{ .id = ast.Node.Id.StructField },479 .base = ast.Node{ .id = ast.Node.Id.StructField },
469 .doc_comments = comments,480 .doc_comments = comments,
470 .visib_token = null,481 .visib_token = null,
471 .name_token = token_index,482 .name_token = token_index,
472 .type_expr = undefined,483 .type_expr = undefined,
473 });484 };
474 const node_ptr = try container_decl.fields_and_decls.addOne();485 const node_ptr = try container_decl.fields_and_decls.addOne();
475 node_ptr.* = &node.base;486 node_ptr.* = &node.base;
476487
...@@ -485,13 +496,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -485,13 +496,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
485 continue;496 continue;
486 },497 },
487 Token.Id.Keyword_union => {498 Token.Id.Keyword_union => {
488 const node = try arena.create(ast.Node.UnionTag{499 const node = try arena.create(ast.Node.UnionTag);
500 node.* = ast.Node.UnionTag{
489 .base = ast.Node{ .id = ast.Node.Id.UnionTag },501 .base = ast.Node{ .id = ast.Node.Id.UnionTag },
490 .name_token = token_index,502 .name_token = token_index,
491 .type_expr = null,503 .type_expr = null,
492 .value_expr = null,504 .value_expr = null,
493 .doc_comments = comments,505 .doc_comments = comments,
494 });506 };
495 try container_decl.fields_and_decls.push(&node.base);507 try container_decl.fields_and_decls.push(&node.base);
496508
497 try stack.append(State{509 try stack.append(State{
...@@ -506,12 +518,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -506,12 +518,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
506 continue;518 continue;
507 },519 },
508 Token.Id.Keyword_enum => {520 Token.Id.Keyword_enum => {
509 const node = try arena.create(ast.Node.EnumTag{521 const node = try arena.create(ast.Node.EnumTag);
522 node.* = ast.Node.EnumTag{
510 .base = ast.Node{ .id = ast.Node.Id.EnumTag },523 .base = ast.Node{ .id = ast.Node.Id.EnumTag },
511 .name_token = token_index,524 .name_token = token_index,
512 .value = null,525 .value = null,
513 .doc_comments = comments,526 .doc_comments = comments,
514 });527 };
515 try container_decl.fields_and_decls.push(&node.base);528 try container_decl.fields_and_decls.push(&node.base);
516529
517 try stack.append(State{530 try stack.append(State{
...@@ -593,7 +606,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -593,7 +606,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
593 },606 },
594607
595 State.VarDecl => |ctx| {608 State.VarDecl => |ctx| {
596 const var_decl = try arena.create(ast.Node.VarDecl{609 const var_decl = try arena.create(ast.Node.VarDecl);
610 var_decl.* = ast.Node.VarDecl{
597 .base = ast.Node{ .id = ast.Node.Id.VarDecl },611 .base = ast.Node{ .id = ast.Node.Id.VarDecl },
598 .doc_comments = ctx.comments,612 .doc_comments = ctx.comments,
599 .visib_token = ctx.visib_token,613 .visib_token = ctx.visib_token,
...@@ -609,7 +623,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -609,7 +623,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
609 .name_token = undefined,623 .name_token = undefined,
610 .eq_token = undefined,624 .eq_token = undefined,
611 .semicolon_token = undefined,625 .semicolon_token = undefined,
612 });626 };
613 try ctx.list.push(&var_decl.base);627 try ctx.list.push(&var_decl.base);
614628
615 try stack.append(State{ .VarDeclAlign = var_decl });629 try stack.append(State{ .VarDeclAlign = var_decl });
...@@ -708,13 +722,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -708,13 +722,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
708 const token_ptr = token.ptr;722 const token_ptr = token.ptr;
709 switch (token_ptr.id) {723 switch (token_ptr.id) {
710 Token.Id.LBrace => {724 Token.Id.LBrace => {
711 const block = try arena.create(ast.Node.Block{725 const block = try arena.create(ast.Node.Block);
726 block.* = ast.Node.Block{
712 .base = ast.Node{ .id = ast.Node.Id.Block },727 .base = ast.Node{ .id = ast.Node.Id.Block },
713 .label = null,728 .label = null,
714 .lbrace = token_index,729 .lbrace = token_index,
715 .statements = ast.Node.Block.StatementList.init(arena),730 .statements = ast.Node.Block.StatementList.init(arena),
716 .rbrace = undefined,731 .rbrace = undefined,
717 });732 };
718 fn_proto.body_node = &block.base;733 fn_proto.body_node = &block.base;
719 stack.append(State{ .Block = block }) catch unreachable;734 stack.append(State{ .Block = block }) catch unreachable;
720 continue;735 continue;
...@@ -770,10 +785,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -770,10 +785,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
770 // TODO: this is a special case. Remove this when #760 is fixed785 // TODO: this is a special case. Remove this when #760 is fixed
771 if (token_ptr.id == Token.Id.Keyword_anyerror) {786 if (token_ptr.id == Token.Id.Keyword_anyerror) {
772 if (tok_it.peek().?.id == Token.Id.LBrace) {787 if (tok_it.peek().?.id == Token.Id.LBrace) {
773 const error_type_node = try arena.create(ast.Node.ErrorType{788 const error_type_node = try arena.create(ast.Node.ErrorType);
789 error_type_node.* = ast.Node.ErrorType{
774 .base = ast.Node{ .id = ast.Node.Id.ErrorType },790 .base = ast.Node{ .id = ast.Node.Id.ErrorType },
775 .token = token_index,791 .token = token_index,
776 });792 };
777 fn_proto.return_type = ast.Node.FnProto.ReturnType{ .Explicit = &error_type_node.base };793 fn_proto.return_type = ast.Node.FnProto.ReturnType{ .Explicit = &error_type_node.base };
778 continue;794 continue;
779 }795 }
...@@ -791,14 +807,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -791,14 +807,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
791 if (eatToken(&tok_it, &tree, Token.Id.RParen)) |_| {807 if (eatToken(&tok_it, &tree, Token.Id.RParen)) |_| {
792 continue;808 continue;
793 }809 }
794 const param_decl = try arena.create(ast.Node.ParamDecl{810 const param_decl = try arena.create(ast.Node.ParamDecl);
811 param_decl.* = ast.Node.ParamDecl{
795 .base = ast.Node{ .id = ast.Node.Id.ParamDecl },812 .base = ast.Node{ .id = ast.Node.Id.ParamDecl },
796 .comptime_token = null,813 .comptime_token = null,
797 .noalias_token = null,814 .noalias_token = null,
798 .name_token = null,815 .name_token = null,
799 .type_node = undefined,816 .type_node = undefined,
800 .var_args_token = null,817 .var_args_token = null,
801 });818 };
802 try fn_proto.params.push(&param_decl.base);819 try fn_proto.params.push(&param_decl.base);
803820
804 stack.append(State{821 stack.append(State{
...@@ -877,13 +894,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -877,13 +894,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
877 const token_ptr = token.ptr;894 const token_ptr = token.ptr;
878 switch (token_ptr.id) {895 switch (token_ptr.id) {
879 Token.Id.LBrace => {896 Token.Id.LBrace => {
880 const block = try arena.create(ast.Node.Block{897 const block = try arena.create(ast.Node.Block);
898 block.* = ast.Node.Block{
881 .base = ast.Node{ .id = ast.Node.Id.Block },899 .base = ast.Node{ .id = ast.Node.Id.Block },
882 .label = ctx.label,900 .label = ctx.label,
883 .lbrace = token_index,901 .lbrace = token_index,
884 .statements = ast.Node.Block.StatementList.init(arena),902 .statements = ast.Node.Block.StatementList.init(arena),
885 .rbrace = undefined,903 .rbrace = undefined,
886 });904 };
887 ctx.opt_ctx.store(&block.base);905 ctx.opt_ctx.store(&block.base);
888 stack.append(State{ .Block = block }) catch unreachable;906 stack.append(State{ .Block = block }) catch unreachable;
889 continue;907 continue;
...@@ -970,7 +988,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -970,7 +988,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
970 }988 }
971 },989 },
972 State.While => |ctx| {990 State.While => |ctx| {
973 const node = try arena.create(ast.Node.While{991 const node = try arena.create(ast.Node.While);
992 node.* = ast.Node.While{
974 .base = ast.Node{ .id = ast.Node.Id.While },993 .base = ast.Node{ .id = ast.Node.Id.While },
975 .label = ctx.label,994 .label = ctx.label,
976 .inline_token = ctx.inline_token,995 .inline_token = ctx.inline_token,
...@@ -980,7 +999,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -980,7 +999,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
980 .continue_expr = null,999 .continue_expr = null,
981 .body = undefined,1000 .body = undefined,
982 .@"else" = null,1001 .@"else" = null,
983 });1002 };
984 ctx.opt_ctx.store(&node.base);1003 ctx.opt_ctx.store(&node.base);
985 stack.append(State{ .Else = &node.@"else" }) catch unreachable;1004 stack.append(State{ .Else = &node.@"else" }) catch unreachable;
986 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } });1005 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } });
...@@ -999,7 +1018,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -999,7 +1018,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
999 continue;1018 continue;
1000 },1019 },
1001 State.For => |ctx| {1020 State.For => |ctx| {
1002 const node = try arena.create(ast.Node.For{1021 const node = try arena.create(ast.Node.For);
1022 node.* = ast.Node.For{
1003 .base = ast.Node{ .id = ast.Node.Id.For },1023 .base = ast.Node{ .id = ast.Node.Id.For },
1004 .label = ctx.label,1024 .label = ctx.label,
1005 .inline_token = ctx.inline_token,1025 .inline_token = ctx.inline_token,
...@@ -1008,7 +1028,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1008,7 +1028,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1008 .payload = null,1028 .payload = null,
1009 .body = undefined,1029 .body = undefined,
1010 .@"else" = null,1030 .@"else" = null,
1011 });1031 };
1012 ctx.opt_ctx.store(&node.base);1032 ctx.opt_ctx.store(&node.base);
1013 stack.append(State{ .Else = &node.@"else" }) catch unreachable;1033 stack.append(State{ .Else = &node.@"else" }) catch unreachable;
1014 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } });1034 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } });
...@@ -1020,12 +1040,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1020,12 +1040,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1020 },1040 },
1021 State.Else => |dest| {1041 State.Else => |dest| {
1022 if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| {1042 if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| {
1023 const node = try arena.create(ast.Node.Else{1043 const node = try arena.create(ast.Node.Else);
1044 node.* = ast.Node.Else{
1024 .base = ast.Node{ .id = ast.Node.Id.Else },1045 .base = ast.Node{ .id = ast.Node.Id.Else },
1025 .else_token = else_token,1046 .else_token = else_token,
1026 .payload = null,1047 .payload = null,
1027 .body = undefined,1048 .body = undefined,
1028 });1049 };
1029 dest.* = node;1050 dest.* = node;
10301051
1031 stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } }) catch unreachable;1052 stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } }) catch unreachable;
...@@ -1083,11 +1104,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1083,11 +1104,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1083 continue;1104 continue;
1084 },1105 },
1085 Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {1106 Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {
1086 const node = try arena.create(ast.Node.Defer{1107 const node = try arena.create(ast.Node.Defer);
1108 node.* = ast.Node.Defer{
1087 .base = ast.Node{ .id = ast.Node.Id.Defer },1109 .base = ast.Node{ .id = ast.Node.Id.Defer },
1088 .defer_token = token_index,1110 .defer_token = token_index,
1089 .expr = undefined,1111 .expr = undefined,
1090 });1112 };
1091 const node_ptr = try block.statements.addOne();1113 const node_ptr = try block.statements.addOne();
1092 node_ptr.* = &node.base;1114 node_ptr.* = &node.base;
10931115
...@@ -1096,13 +1118,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1096,13 +1118,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1096 continue;1118 continue;
1097 },1119 },
1098 Token.Id.LBrace => {1120 Token.Id.LBrace => {
1099 const inner_block = try arena.create(ast.Node.Block{1121 const inner_block = try arena.create(ast.Node.Block);
1122 inner_block.* = ast.Node.Block{
1100 .base = ast.Node{ .id = ast.Node.Id.Block },1123 .base = ast.Node{ .id = ast.Node.Id.Block },
1101 .label = null,1124 .label = null,
1102 .lbrace = token_index,1125 .lbrace = token_index,
1103 .statements = ast.Node.Block.StatementList.init(arena),1126 .statements = ast.Node.Block.StatementList.init(arena),
1104 .rbrace = undefined,1127 .rbrace = undefined,
1105 });1128 };
1106 try block.statements.push(&inner_block.base);1129 try block.statements.push(&inner_block.base);
11071130
1108 stack.append(State{ .Block = inner_block }) catch unreachable;1131 stack.append(State{ .Block = inner_block }) catch unreachable;
...@@ -1164,14 +1187,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1164,14 +1187,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1164 continue;1187 continue;
1165 }1188 }
11661189
1167 const node = try arena.create(ast.Node.AsmOutput{1190 const node = try arena.create(ast.Node.AsmOutput);
1191 node.* = ast.Node.AsmOutput{
1168 .base = ast.Node{ .id = ast.Node.Id.AsmOutput },1192 .base = ast.Node{ .id = ast.Node.Id.AsmOutput },
1169 .lbracket = lbracket_index,1193 .lbracket = lbracket_index,
1170 .symbolic_name = undefined,1194 .symbolic_name = undefined,
1171 .constraint = undefined,1195 .constraint = undefined,
1172 .kind = undefined,1196 .kind = undefined,
1173 .rparen = undefined,1197 .rparen = undefined,
1174 });1198 };
1175 try items.push(node);1199 try items.push(node);
11761200
1177 stack.append(State{ .AsmOutputItems = items }) catch unreachable;1201 stack.append(State{ .AsmOutputItems = items }) catch unreachable;
...@@ -1218,14 +1242,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1218,14 +1242,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1218 continue;1242 continue;
1219 }1243 }
12201244
1221 const node = try arena.create(ast.Node.AsmInput{1245 const node = try arena.create(ast.Node.AsmInput);
1246 node.* = ast.Node.AsmInput{
1222 .base = ast.Node{ .id = ast.Node.Id.AsmInput },1247 .base = ast.Node{ .id = ast.Node.Id.AsmInput },
1223 .lbracket = lbracket_index,1248 .lbracket = lbracket_index,
1224 .symbolic_name = undefined,1249 .symbolic_name = undefined,
1225 .constraint = undefined,1250 .constraint = undefined,
1226 .expr = undefined,1251 .expr = undefined,
1227 .rparen = undefined,1252 .rparen = undefined,
1228 });1253 };
1229 try items.push(node);1254 try items.push(node);
12301255
1231 stack.append(State{ .AsmInputItems = items }) catch unreachable;1256 stack.append(State{ .AsmInputItems = items }) catch unreachable;
...@@ -1283,12 +1308,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1283,12 +1308,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1283 continue;1308 continue;
1284 }1309 }
12851310
1286 const node = try arena.create(ast.Node.FieldInitializer{1311 const node = try arena.create(ast.Node.FieldInitializer);
1312 node.* = ast.Node.FieldInitializer{
1287 .base = ast.Node{ .id = ast.Node.Id.FieldInitializer },1313 .base = ast.Node{ .id = ast.Node.Id.FieldInitializer },
1288 .period_token = undefined,1314 .period_token = undefined,
1289 .name_token = undefined,1315 .name_token = undefined,
1290 .expr = undefined,1316 .expr = undefined,
1291 });1317 };
1292 try list_state.list.push(&node.base);1318 try list_state.list.push(&node.base);
12931319
1294 stack.append(State{ .FieldInitListCommaOrEnd = list_state }) catch unreachable;1320 stack.append(State{ .FieldInitListCommaOrEnd = list_state }) catch unreachable;
...@@ -1390,13 +1416,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1390,13 +1416,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1390 }1416 }
13911417
1392 const comments = try eatDocComments(arena, &tok_it, &tree);1418 const comments = try eatDocComments(arena, &tok_it, &tree);
1393 const node = try arena.create(ast.Node.SwitchCase{1419 const node = try arena.create(ast.Node.SwitchCase);
1420 node.* = ast.Node.SwitchCase{
1394 .base = ast.Node{ .id = ast.Node.Id.SwitchCase },1421 .base = ast.Node{ .id = ast.Node.Id.SwitchCase },
1395 .items = ast.Node.SwitchCase.ItemList.init(arena),1422 .items = ast.Node.SwitchCase.ItemList.init(arena),
1396 .payload = null,1423 .payload = null,
1397 .expr = undefined,1424 .expr = undefined,
1398 .arrow_token = undefined,1425 .arrow_token = undefined,
1399 });1426 };
1400 try list_state.list.push(&node.base);1427 try list_state.list.push(&node.base);
1401 try stack.append(State{ .SwitchCaseCommaOrEnd = list_state });1428 try stack.append(State{ .SwitchCaseCommaOrEnd = list_state });
1402 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });1429 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });
...@@ -1427,10 +1454,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1427,10 +1454,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1427 const token_index = token.index;1454 const token_index = token.index;
1428 const token_ptr = token.ptr;1455 const token_ptr = token.ptr;
1429 if (token_ptr.id == Token.Id.Keyword_else) {1456 if (token_ptr.id == Token.Id.Keyword_else) {
1430 const else_node = try arena.create(ast.Node.SwitchElse{1457 const else_node = try arena.create(ast.Node.SwitchElse);
1458 else_node.* = ast.Node.SwitchElse{
1431 .base = ast.Node{ .id = ast.Node.Id.SwitchElse },1459 .base = ast.Node{ .id = ast.Node.Id.SwitchElse },
1432 .token = token_index,1460 .token = token_index,
1433 });1461 };
1434 try switch_case.items.push(&else_node.base);1462 try switch_case.items.push(&else_node.base);
14351463
1436 try stack.append(State{1464 try stack.append(State{
...@@ -1537,7 +1565,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1537,7 +1565,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
15371565
1538 State.ExternType => |ctx| {1566 State.ExternType => |ctx| {
1539 if (eatToken(&tok_it, &tree, Token.Id.Keyword_fn)) |fn_token| {1567 if (eatToken(&tok_it, &tree, Token.Id.Keyword_fn)) |fn_token| {
1540 const fn_proto = try arena.create(ast.Node.FnProto{1568 const fn_proto = try arena.create(ast.Node.FnProto);
1569 fn_proto.* = ast.Node.FnProto{
1541 .base = ast.Node{ .id = ast.Node.Id.FnProto },1570 .base = ast.Node{ .id = ast.Node.Id.FnProto },
1542 .doc_comments = ctx.comments,1571 .doc_comments = ctx.comments,
1543 .visib_token = null,1572 .visib_token = null,
...@@ -1553,7 +1582,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1553,7 +1582,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1553 .lib_name = null,1582 .lib_name = null,
1554 .align_expr = null,1583 .align_expr = null,
1555 .section_expr = null,1584 .section_expr = null,
1556 });1585 };
1557 ctx.opt_ctx.store(&fn_proto.base);1586 ctx.opt_ctx.store(&fn_proto.base);
1558 stack.append(State{ .FnProto = fn_proto }) catch unreachable;1587 stack.append(State{ .FnProto = fn_proto }) catch unreachable;
1559 continue;1588 continue;
...@@ -1711,12 +1740,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1711,12 +1740,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1711 continue;1740 continue;
1712 }1741 }
17131742
1714 const node = try arena.create(ast.Node.Payload{1743 const node = try arena.create(ast.Node.Payload);
1744 node.* = ast.Node.Payload{
1715 .base = ast.Node{ .id = ast.Node.Id.Payload },1745 .base = ast.Node{ .id = ast.Node.Id.Payload },
1716 .lpipe = token_index,1746 .lpipe = token_index,
1717 .error_symbol = undefined,1747 .error_symbol = undefined,
1718 .rpipe = undefined,1748 .rpipe = undefined,
1719 });1749 };
1720 opt_ctx.store(&node.base);1750 opt_ctx.store(&node.base);
17211751
1722 stack.append(State{1752 stack.append(State{
...@@ -1747,13 +1777,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1747,13 +1777,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1747 continue;1777 continue;
1748 }1778 }
17491779
1750 const node = try arena.create(ast.Node.PointerPayload{1780 const node = try arena.create(ast.Node.PointerPayload);
1781 node.* = ast.Node.PointerPayload{
1751 .base = ast.Node{ .id = ast.Node.Id.PointerPayload },1782 .base = ast.Node{ .id = ast.Node.Id.PointerPayload },
1752 .lpipe = token_index,1783 .lpipe = token_index,
1753 .ptr_token = null,1784 .ptr_token = null,
1754 .value_symbol = undefined,1785 .value_symbol = undefined,
1755 .rpipe = undefined,1786 .rpipe = undefined,
1756 });1787 };
1757 opt_ctx.store(&node.base);1788 opt_ctx.store(&node.base);
17581789
1759 try stack.append(State{1790 try stack.append(State{
...@@ -1790,14 +1821,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1790,14 +1821,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1790 continue;1821 continue;
1791 }1822 }
17921823
1793 const node = try arena.create(ast.Node.PointerIndexPayload{1824 const node = try arena.create(ast.Node.PointerIndexPayload);
1825 node.* = ast.Node.PointerIndexPayload{
1794 .base = ast.Node{ .id = ast.Node.Id.PointerIndexPayload },1826 .base = ast.Node{ .id = ast.Node.Id.PointerIndexPayload },
1795 .lpipe = token_index,1827 .lpipe = token_index,
1796 .ptr_token = null,1828 .ptr_token = null,
1797 .value_symbol = undefined,1829 .value_symbol = undefined,
1798 .index_symbol = null,1830 .index_symbol = null,
1799 .rpipe = undefined,1831 .rpipe = undefined,
1800 });1832 };
1801 opt_ctx.store(&node.base);1833 opt_ctx.store(&node.base);
18021834
1803 stack.append(State{1835 stack.append(State{
...@@ -1824,12 +1856,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1824,12 +1856,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1824 const token_ptr = token.ptr;1856 const token_ptr = token.ptr;
1825 switch (token_ptr.id) {1857 switch (token_ptr.id) {
1826 Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => {1858 Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => {
1827 const node = try arena.create(ast.Node.ControlFlowExpression{1859 const node = try arena.create(ast.Node.ControlFlowExpression);
1860 node.* = ast.Node.ControlFlowExpression{
1828 .base = ast.Node{ .id = ast.Node.Id.ControlFlowExpression },1861 .base = ast.Node{ .id = ast.Node.Id.ControlFlowExpression },
1829 .ltoken = token_index,1862 .ltoken = token_index,
1830 .kind = undefined,1863 .kind = undefined,
1831 .rhs = null,1864 .rhs = null,
1832 });1865 };
1833 opt_ctx.store(&node.base);1866 opt_ctx.store(&node.base);
18341867
1835 stack.append(State{ .Expression = OptionalCtx{ .Optional = &node.rhs } }) catch unreachable;1868 stack.append(State{ .Expression = OptionalCtx{ .Optional = &node.rhs } }) catch unreachable;
...@@ -1853,7 +1886,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1853,7 +1886,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1853 continue;1886 continue;
1854 },1887 },
1855 Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {1888 Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {
1856 const node = try arena.create(ast.Node.PrefixOp{1889 const node = try arena.create(ast.Node.PrefixOp);
1890 node.* = ast.Node.PrefixOp{
1857 .base = ast.Node{ .id = ast.Node.Id.PrefixOp },1891 .base = ast.Node{ .id = ast.Node.Id.PrefixOp },
1858 .op_token = token_index,1892 .op_token = token_index,
1859 .op = switch (token_ptr.id) {1893 .op = switch (token_ptr.id) {
...@@ -1863,7 +1897,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1863,7 +1897,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1863 else => unreachable,1897 else => unreachable,
1864 },1898 },
1865 .rhs = undefined,1899 .rhs = undefined,
1866 });1900 };
1867 opt_ctx.store(&node.base);1901 opt_ctx.store(&node.base);
18681902
1869 stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;1903 stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
...@@ -1887,13 +1921,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1887,13 +1921,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1887 const lhs = opt_ctx.get() orelse continue;1921 const lhs = opt_ctx.get() orelse continue;
18881922
1889 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {1923 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {
1890 const node = try arena.create(ast.Node.InfixOp{1924 const node = try arena.create(ast.Node.InfixOp);
1925 node.* = ast.Node.InfixOp{
1891 .base = ast.Node{ .id = ast.Node.Id.InfixOp },1926 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
1892 .lhs = lhs,1927 .lhs = lhs,
1893 .op_token = ellipsis3,1928 .op_token = ellipsis3,
1894 .op = ast.Node.InfixOp.Op.Range,1929 .op = ast.Node.InfixOp.Op.Range,
1895 .rhs = undefined,1930 .rhs = undefined,
1896 });1931 };
1897 opt_ctx.store(&node.base);1932 opt_ctx.store(&node.base);
1898 stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;1933 stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
1899 continue;1934 continue;
...@@ -1912,13 +1947,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1912,13 +1947,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1912 const token_index = token.index;1947 const token_index = token.index;
1913 const token_ptr = token.ptr;1948 const token_ptr = token.ptr;
1914 if (tokenIdToAssignment(token_ptr.id)) |ass_id| {1949 if (tokenIdToAssignment(token_ptr.id)) |ass_id| {
1915 const node = try arena.create(ast.Node.InfixOp{1950 const node = try arena.create(ast.Node.InfixOp);
1951 node.* = ast.Node.InfixOp{
1916 .base = ast.Node{ .id = ast.Node.Id.InfixOp },1952 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
1917 .lhs = lhs,1953 .lhs = lhs,
1918 .op_token = token_index,1954 .op_token = token_index,
1919 .op = ass_id,1955 .op = ass_id,
1920 .rhs = undefined,1956 .rhs = undefined,
1921 });1957 };
1922 opt_ctx.store(&node.base);1958 opt_ctx.store(&node.base);
1923 stack.append(State{ .AssignmentExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1959 stack.append(State{ .AssignmentExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1924 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } });1960 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } });
...@@ -1942,13 +1978,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1942,13 +1978,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1942 const token_index = token.index;1978 const token_index = token.index;
1943 const token_ptr = token.ptr;1979 const token_ptr = token.ptr;
1944 if (tokenIdToUnwrapExpr(token_ptr.id)) |unwrap_id| {1980 if (tokenIdToUnwrapExpr(token_ptr.id)) |unwrap_id| {
1945 const node = try arena.create(ast.Node.InfixOp{1981 const node = try arena.create(ast.Node.InfixOp);
1982 node.* = ast.Node.InfixOp{
1946 .base = ast.Node{ .id = ast.Node.Id.InfixOp },1983 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
1947 .lhs = lhs,1984 .lhs = lhs,
1948 .op_token = token_index,1985 .op_token = token_index,
1949 .op = unwrap_id,1986 .op = unwrap_id,
1950 .rhs = undefined,1987 .rhs = undefined,
1951 });1988 };
1952 opt_ctx.store(&node.base);1989 opt_ctx.store(&node.base);
19531990
1954 stack.append(State{ .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1991 stack.append(State{ .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
...@@ -1974,13 +2011,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1974,13 +2011,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1974 const lhs = opt_ctx.get() orelse continue;2011 const lhs = opt_ctx.get() orelse continue;
19752012
1976 if (eatToken(&tok_it, &tree, Token.Id.Keyword_or)) |or_token| {2013 if (eatToken(&tok_it, &tree, Token.Id.Keyword_or)) |or_token| {
1977 const node = try arena.create(ast.Node.InfixOp{2014 const node = try arena.create(ast.Node.InfixOp);
2015 node.* = ast.Node.InfixOp{
1978 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2016 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
1979 .lhs = lhs,2017 .lhs = lhs,
1980 .op_token = or_token,2018 .op_token = or_token,
1981 .op = ast.Node.InfixOp.Op.BoolOr,2019 .op = ast.Node.InfixOp.Op.BoolOr,
1982 .rhs = undefined,2020 .rhs = undefined,
1983 });2021 };
1984 opt_ctx.store(&node.base);2022 opt_ctx.store(&node.base);
1985 stack.append(State{ .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2023 stack.append(State{ .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1986 try stack.append(State{ .BoolAndExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2024 try stack.append(State{ .BoolAndExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
...@@ -1998,13 +2036,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1998,13 +2036,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1998 const lhs = opt_ctx.get() orelse continue;2036 const lhs = opt_ctx.get() orelse continue;
19992037
2000 if (eatToken(&tok_it, &tree, Token.Id.Keyword_and)) |and_token| {2038 if (eatToken(&tok_it, &tree, Token.Id.Keyword_and)) |and_token| {
2001 const node = try arena.create(ast.Node.InfixOp{2039 const node = try arena.create(ast.Node.InfixOp);
2040 node.* = ast.Node.InfixOp{
2002 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2041 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2003 .lhs = lhs,2042 .lhs = lhs,
2004 .op_token = and_token,2043 .op_token = and_token,
2005 .op = ast.Node.InfixOp.Op.BoolAnd,2044 .op = ast.Node.InfixOp.Op.BoolAnd,
2006 .rhs = undefined,2045 .rhs = undefined,
2007 });2046 };
2008 opt_ctx.store(&node.base);2047 opt_ctx.store(&node.base);
2009 stack.append(State{ .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2048 stack.append(State{ .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2010 try stack.append(State{ .ComparisonExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2049 try stack.append(State{ .ComparisonExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
...@@ -2025,13 +2064,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2025,13 +2064,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2025 const token_index = token.index;2064 const token_index = token.index;
2026 const token_ptr = token.ptr;2065 const token_ptr = token.ptr;
2027 if (tokenIdToComparison(token_ptr.id)) |comp_id| {2066 if (tokenIdToComparison(token_ptr.id)) |comp_id| {
2028 const node = try arena.create(ast.Node.InfixOp{2067 const node = try arena.create(ast.Node.InfixOp);
2068 node.* = ast.Node.InfixOp{
2029 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2069 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2030 .lhs = lhs,2070 .lhs = lhs,
2031 .op_token = token_index,2071 .op_token = token_index,
2032 .op = comp_id,2072 .op = comp_id,
2033 .rhs = undefined,2073 .rhs = undefined,
2034 });2074 };
2035 opt_ctx.store(&node.base);2075 opt_ctx.store(&node.base);
2036 stack.append(State{ .ComparisonExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2076 stack.append(State{ .ComparisonExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2037 try stack.append(State{ .BinaryOrExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2077 try stack.append(State{ .BinaryOrExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
...@@ -2052,13 +2092,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2052,13 +2092,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2052 const lhs = opt_ctx.get() orelse continue;2092 const lhs = opt_ctx.get() orelse continue;
20532093
2054 if (eatToken(&tok_it, &tree, Token.Id.Pipe)) |pipe| {2094 if (eatToken(&tok_it, &tree, Token.Id.Pipe)) |pipe| {
2055 const node = try arena.create(ast.Node.InfixOp{2095 const node = try arena.create(ast.Node.InfixOp);
2096 node.* = ast.Node.InfixOp{
2056 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2097 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2057 .lhs = lhs,2098 .lhs = lhs,
2058 .op_token = pipe,2099 .op_token = pipe,
2059 .op = ast.Node.InfixOp.Op.BitOr,2100 .op = ast.Node.InfixOp.Op.BitOr,
2060 .rhs = undefined,2101 .rhs = undefined,
2061 });2102 };
2062 opt_ctx.store(&node.base);2103 opt_ctx.store(&node.base);
2063 stack.append(State{ .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2104 stack.append(State{ .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2064 try stack.append(State{ .BinaryXorExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2105 try stack.append(State{ .BinaryXorExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
...@@ -2076,13 +2117,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2076,13 +2117,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2076 const lhs = opt_ctx.get() orelse continue;2117 const lhs = opt_ctx.get() orelse continue;
20772118
2078 if (eatToken(&tok_it, &tree, Token.Id.Caret)) |caret| {2119 if (eatToken(&tok_it, &tree, Token.Id.Caret)) |caret| {
2079 const node = try arena.create(ast.Node.InfixOp{2120 const node = try arena.create(ast.Node.InfixOp);
2121 node.* = ast.Node.InfixOp{
2080 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2122 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2081 .lhs = lhs,2123 .lhs = lhs,
2082 .op_token = caret,2124 .op_token = caret,
2083 .op = ast.Node.InfixOp.Op.BitXor,2125 .op = ast.Node.InfixOp.Op.BitXor,
2084 .rhs = undefined,2126 .rhs = undefined,
2085 });2127 };
2086 opt_ctx.store(&node.base);2128 opt_ctx.store(&node.base);
2087 stack.append(State{ .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2129 stack.append(State{ .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2088 try stack.append(State{ .BinaryAndExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2130 try stack.append(State{ .BinaryAndExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
...@@ -2100,13 +2142,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2100,13 +2142,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2100 const lhs = opt_ctx.get() orelse continue;2142 const lhs = opt_ctx.get() orelse continue;
21012143
2102 if (eatToken(&tok_it, &tree, Token.Id.Ampersand)) |ampersand| {2144 if (eatToken(&tok_it, &tree, Token.Id.Ampersand)) |ampersand| {
2103 const node = try arena.create(ast.Node.InfixOp{2145 const node = try arena.create(ast.Node.InfixOp);
2146 node.* = ast.Node.InfixOp{
2104 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2147 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2105 .lhs = lhs,2148 .lhs = lhs,
2106 .op_token = ampersand,2149 .op_token = ampersand,
2107 .op = ast.Node.InfixOp.Op.BitAnd,2150 .op = ast.Node.InfixOp.Op.BitAnd,
2108 .rhs = undefined,2151 .rhs = undefined,
2109 });2152 };
2110 opt_ctx.store(&node.base);2153 opt_ctx.store(&node.base);
2111 stack.append(State{ .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2154 stack.append(State{ .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2112 try stack.append(State{ .BitShiftExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2155 try stack.append(State{ .BitShiftExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
...@@ -2127,13 +2170,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2127,13 +2170,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2127 const token_index = token.index;2170 const token_index = token.index;
2128 const token_ptr = token.ptr;2171 const token_ptr = token.ptr;
2129 if (tokenIdToBitShift(token_ptr.id)) |bitshift_id| {2172 if (tokenIdToBitShift(token_ptr.id)) |bitshift_id| {
2130 const node = try arena.create(ast.Node.InfixOp{2173 const node = try arena.create(ast.Node.InfixOp);
2174 node.* = ast.Node.InfixOp{
2131 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2175 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2132 .lhs = lhs,2176 .lhs = lhs,
2133 .op_token = token_index,2177 .op_token = token_index,
2134 .op = bitshift_id,2178 .op = bitshift_id,
2135 .rhs = undefined,2179 .rhs = undefined,
2136 });2180 };
2137 opt_ctx.store(&node.base);2181 opt_ctx.store(&node.base);
2138 stack.append(State{ .BitShiftExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2182 stack.append(State{ .BitShiftExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2139 try stack.append(State{ .AdditionExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2183 try stack.append(State{ .AdditionExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
...@@ -2157,13 +2201,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2157,13 +2201,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2157 const token_index = token.index;2201 const token_index = token.index;
2158 const token_ptr = token.ptr;2202 const token_ptr = token.ptr;
2159 if (tokenIdToAddition(token_ptr.id)) |add_id| {2203 if (tokenIdToAddition(token_ptr.id)) |add_id| {
2160 const node = try arena.create(ast.Node.InfixOp{2204 const node = try arena.create(ast.Node.InfixOp);
2205 node.* = ast.Node.InfixOp{
2161 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2206 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2162 .lhs = lhs,2207 .lhs = lhs,
2163 .op_token = token_index,2208 .op_token = token_index,
2164 .op = add_id,2209 .op = add_id,
2165 .rhs = undefined,2210 .rhs = undefined,
2166 });2211 };
2167 opt_ctx.store(&node.base);2212 opt_ctx.store(&node.base);
2168 stack.append(State{ .AdditionExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2213 stack.append(State{ .AdditionExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2169 try stack.append(State{ .MultiplyExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2214 try stack.append(State{ .MultiplyExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
...@@ -2187,13 +2232,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2187,13 +2232,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2187 const token_index = token.index;2232 const token_index = token.index;
2188 const token_ptr = token.ptr;2233 const token_ptr = token.ptr;
2189 if (tokenIdToMultiply(token_ptr.id)) |mult_id| {2234 if (tokenIdToMultiply(token_ptr.id)) |mult_id| {
2190 const node = try arena.create(ast.Node.InfixOp{2235 const node = try arena.create(ast.Node.InfixOp);
2236 node.* = ast.Node.InfixOp{
2191 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2237 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2192 .lhs = lhs,2238 .lhs = lhs,
2193 .op_token = token_index,2239 .op_token = token_index,
2194 .op = mult_id,2240 .op = mult_id,
2195 .rhs = undefined,2241 .rhs = undefined,
2196 });2242 };
2197 opt_ctx.store(&node.base);2243 opt_ctx.store(&node.base);
2198 stack.append(State{ .MultiplyExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2244 stack.append(State{ .MultiplyExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2199 try stack.append(State{ .CurlySuffixExpressionBegin = OptionalCtx{ .Required = &node.rhs } });2245 try stack.append(State{ .CurlySuffixExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
...@@ -2215,12 +2261,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2215,12 +2261,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2215 const lhs = opt_ctx.get() orelse continue;2261 const lhs = opt_ctx.get() orelse continue;
22162262
2217 if (tok_it.peek().?.id == Token.Id.Period) {2263 if (tok_it.peek().?.id == Token.Id.Period) {
2218 const node = try arena.create(ast.Node.SuffixOp{2264 const node = try arena.create(ast.Node.SuffixOp);
2265 node.* = ast.Node.SuffixOp{
2219 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },2266 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
2220 .lhs = lhs,2267 .lhs = lhs,
2221 .op = ast.Node.SuffixOp.Op{ .StructInitializer = ast.Node.SuffixOp.Op.InitList.init(arena) },2268 .op = ast.Node.SuffixOp.Op{ .StructInitializer = ast.Node.SuffixOp.Op.InitList.init(arena) },
2222 .rtoken = undefined,2269 .rtoken = undefined,
2223 });2270 };
2224 opt_ctx.store(&node.base);2271 opt_ctx.store(&node.base);
22252272
2226 stack.append(State{ .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2273 stack.append(State{ .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
...@@ -2234,12 +2281,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2234,12 +2281,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2234 continue;2281 continue;
2235 }2282 }
22362283
2237 const node = try arena.create(ast.Node.SuffixOp{2284 const node = try arena.create(ast.Node.SuffixOp);
2285 node.* = ast.Node.SuffixOp{
2238 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },2286 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
2239 .lhs = lhs,2287 .lhs = lhs,
2240 .op = ast.Node.SuffixOp.Op{ .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(arena) },2288 .op = ast.Node.SuffixOp.Op{ .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(arena) },
2241 .rtoken = undefined,2289 .rtoken = undefined,
2242 });2290 };
2243 opt_ctx.store(&node.base);2291 opt_ctx.store(&node.base);
2244 stack.append(State{ .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2292 stack.append(State{ .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2245 try stack.append(State{ .IfToken = Token.Id.LBrace });2293 try stack.append(State{ .IfToken = Token.Id.LBrace });
...@@ -2263,13 +2311,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2263,13 +2311,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2263 const lhs = opt_ctx.get() orelse continue;2311 const lhs = opt_ctx.get() orelse continue;
22642312
2265 if (eatToken(&tok_it, &tree, Token.Id.Bang)) |bang| {2313 if (eatToken(&tok_it, &tree, Token.Id.Bang)) |bang| {
2266 const node = try arena.create(ast.Node.InfixOp{2314 const node = try arena.create(ast.Node.InfixOp);
2315 node.* = ast.Node.InfixOp{
2267 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2316 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2268 .lhs = lhs,2317 .lhs = lhs,
2269 .op_token = bang,2318 .op_token = bang,
2270 .op = ast.Node.InfixOp.Op.ErrorUnion,2319 .op = ast.Node.InfixOp.Op.ErrorUnion,
2271 .rhs = undefined,2320 .rhs = undefined,
2272 });2321 };
2273 opt_ctx.store(&node.base);2322 opt_ctx.store(&node.base);
2274 stack.append(State{ .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable;2323 stack.append(State{ .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable;
2275 try stack.append(State{ .PrefixOpExpression = OptionalCtx{ .Required = &node.rhs } });2324 try stack.append(State{ .PrefixOpExpression = OptionalCtx{ .Required = &node.rhs } });
...@@ -2282,22 +2331,24 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2282,22 +2331,24 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2282 const token_index = token.index;2331 const token_index = token.index;
2283 const token_ptr = token.ptr;2332 const token_ptr = token.ptr;
2284 if (tokenIdToPrefixOp(token_ptr.id)) |prefix_id| {2333 if (tokenIdToPrefixOp(token_ptr.id)) |prefix_id| {
2285 var node = try arena.create(ast.Node.PrefixOp{2334 var node = try arena.create(ast.Node.PrefixOp);
2335 node.* = ast.Node.PrefixOp{
2286 .base = ast.Node{ .id = ast.Node.Id.PrefixOp },2336 .base = ast.Node{ .id = ast.Node.Id.PrefixOp },
2287 .op_token = token_index,2337 .op_token = token_index,
2288 .op = prefix_id,2338 .op = prefix_id,
2289 .rhs = undefined,2339 .rhs = undefined,
2290 });2340 };
2291 opt_ctx.store(&node.base);2341 opt_ctx.store(&node.base);
22922342
2293 // Treat '**' token as two pointer types2343 // Treat '**' token as two pointer types
2294 if (token_ptr.id == Token.Id.AsteriskAsterisk) {2344 if (token_ptr.id == Token.Id.AsteriskAsterisk) {
2295 const child = try arena.create(ast.Node.PrefixOp{2345 const child = try arena.create(ast.Node.PrefixOp);
2346 child.* = ast.Node.PrefixOp{
2296 .base = ast.Node{ .id = ast.Node.Id.PrefixOp },2347 .base = ast.Node{ .id = ast.Node.Id.PrefixOp },
2297 .op_token = token_index,2348 .op_token = token_index,
2298 .op = prefix_id,2349 .op = prefix_id,
2299 .rhs = undefined,2350 .rhs = undefined,
2300 });2351 };
2301 node.rhs = &child.base;2352 node.rhs = &child.base;
2302 node = child;2353 node = child;
2303 }2354 }
...@@ -2316,12 +2367,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2316,12 +2367,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
23162367
2317 State.SuffixOpExpressionBegin => |opt_ctx| {2368 State.SuffixOpExpressionBegin => |opt_ctx| {
2318 if (eatToken(&tok_it, &tree, Token.Id.Keyword_async)) |async_token| {2369 if (eatToken(&tok_it, &tree, Token.Id.Keyword_async)) |async_token| {
2319 const async_node = try arena.create(ast.Node.AsyncAttribute{2370 const async_node = try arena.create(ast.Node.AsyncAttribute);
2371 async_node.* = ast.Node.AsyncAttribute{
2320 .base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },2372 .base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },
2321 .async_token = async_token,2373 .async_token = async_token,
2322 .allocator_type = null,2374 .allocator_type = null,
2323 .rangle_bracket = null,2375 .rangle_bracket = null,
2324 });2376 };
2325 stack.append(State{2377 stack.append(State{
2326 .AsyncEnd = AsyncEndCtx{2378 .AsyncEnd = AsyncEndCtx{
2327 .ctx = opt_ctx,2379 .ctx = opt_ctx,
...@@ -2347,7 +2399,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2347,7 +2399,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2347 const token_ptr = token.ptr;2399 const token_ptr = token.ptr;
2348 switch (token_ptr.id) {2400 switch (token_ptr.id) {
2349 Token.Id.LParen => {2401 Token.Id.LParen => {
2350 const node = try arena.create(ast.Node.SuffixOp{2402 const node = try arena.create(ast.Node.SuffixOp);
2403 node.* = ast.Node.SuffixOp{
2351 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },2404 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
2352 .lhs = lhs,2405 .lhs = lhs,
2353 .op = ast.Node.SuffixOp.Op{2406 .op = ast.Node.SuffixOp.Op{
...@@ -2357,7 +2410,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2357,7 +2410,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2357 },2410 },
2358 },2411 },
2359 .rtoken = undefined,2412 .rtoken = undefined,
2360 });2413 };
2361 opt_ctx.store(&node.base);2414 opt_ctx.store(&node.base);
23622415
2363 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2416 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
...@@ -2371,12 +2424,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2371,12 +2424,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2371 continue;2424 continue;
2372 },2425 },
2373 Token.Id.LBracket => {2426 Token.Id.LBracket => {
2374 const node = try arena.create(ast.Node.SuffixOp{2427 const node = try arena.create(ast.Node.SuffixOp);
2428 node.* = ast.Node.SuffixOp{
2375 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },2429 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
2376 .lhs = lhs,2430 .lhs = lhs,
2377 .op = ast.Node.SuffixOp.Op{ .ArrayAccess = undefined },2431 .op = ast.Node.SuffixOp.Op{ .ArrayAccess = undefined },
2378 .rtoken = undefined,2432 .rtoken = undefined,
2379 });2433 };
2380 opt_ctx.store(&node.base);2434 opt_ctx.store(&node.base);
23812435
2382 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2436 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
...@@ -2386,34 +2440,37 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2386,34 +2440,37 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2386 },2440 },
2387 Token.Id.Period => {2441 Token.Id.Period => {
2388 if (eatToken(&tok_it, &tree, Token.Id.Asterisk)) |asterisk_token| {2442 if (eatToken(&tok_it, &tree, Token.Id.Asterisk)) |asterisk_token| {
2389 const node = try arena.create(ast.Node.SuffixOp{2443 const node = try arena.create(ast.Node.SuffixOp);
2444 node.* = ast.Node.SuffixOp{
2390 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },2445 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
2391 .lhs = lhs,2446 .lhs = lhs,
2392 .op = ast.Node.SuffixOp.Op.Deref,2447 .op = ast.Node.SuffixOp.Op.Deref,
2393 .rtoken = asterisk_token,2448 .rtoken = asterisk_token,
2394 });2449 };
2395 opt_ctx.store(&node.base);2450 opt_ctx.store(&node.base);
2396 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2451 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2397 continue;2452 continue;
2398 }2453 }
2399 if (eatToken(&tok_it, &tree, Token.Id.QuestionMark)) |question_token| {2454 if (eatToken(&tok_it, &tree, Token.Id.QuestionMark)) |question_token| {
2400 const node = try arena.create(ast.Node.SuffixOp{2455 const node = try arena.create(ast.Node.SuffixOp);
2456 node.* = ast.Node.SuffixOp{
2401 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },2457 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
2402 .lhs = lhs,2458 .lhs = lhs,
2403 .op = ast.Node.SuffixOp.Op.UnwrapOptional,2459 .op = ast.Node.SuffixOp.Op.UnwrapOptional,
2404 .rtoken = question_token,2460 .rtoken = question_token,
2405 });2461 };
2406 opt_ctx.store(&node.base);2462 opt_ctx.store(&node.base);
2407 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2463 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2408 continue;2464 continue;
2409 }2465 }
2410 const node = try arena.create(ast.Node.InfixOp{2466 const node = try arena.create(ast.Node.InfixOp);
2467 node.* = ast.Node.InfixOp{
2411 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2468 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2412 .lhs = lhs,2469 .lhs = lhs,
2413 .op_token = token_index,2470 .op_token = token_index,
2414 .op = ast.Node.InfixOp.Op.Period,2471 .op = ast.Node.InfixOp.Op.Period,
2415 .rhs = undefined,2472 .rhs = undefined,
2416 });2473 };
2417 opt_ctx.store(&node.base);2474 opt_ctx.store(&node.base);
24182475
2419 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2476 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
...@@ -2467,11 +2524,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2467,11 +2524,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2467 continue;2524 continue;
2468 },2525 },
2469 Token.Id.Keyword_promise => {2526 Token.Id.Keyword_promise => {
2470 const node = try arena.create(ast.Node.PromiseType{2527 const node = try arena.create(ast.Node.PromiseType);
2528 node.* = ast.Node.PromiseType{
2471 .base = ast.Node{ .id = ast.Node.Id.PromiseType },2529 .base = ast.Node{ .id = ast.Node.Id.PromiseType },
2472 .promise_token = token.index,2530 .promise_token = token.index,
2473 .result = null,2531 .result = null,
2474 });2532 };
2475 opt_ctx.store(&node.base);2533 opt_ctx.store(&node.base);
2476 const next_token = nextToken(&tok_it, &tree);2534 const next_token = nextToken(&tok_it, &tree);
2477 const next_token_index = next_token.index;2535 const next_token_index = next_token.index;
...@@ -2493,12 +2551,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2493,12 +2551,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2493 continue;2551 continue;
2494 },2552 },
2495 Token.Id.LParen => {2553 Token.Id.LParen => {
2496 const node = try arena.create(ast.Node.GroupedExpression{2554 const node = try arena.create(ast.Node.GroupedExpression);
2555 node.* = ast.Node.GroupedExpression{
2497 .base = ast.Node{ .id = ast.Node.Id.GroupedExpression },2556 .base = ast.Node{ .id = ast.Node.Id.GroupedExpression },
2498 .lparen = token.index,2557 .lparen = token.index,
2499 .expr = undefined,2558 .expr = undefined,
2500 .rparen = undefined,2559 .rparen = undefined,
2501 });2560 };
2502 opt_ctx.store(&node.base);2561 opt_ctx.store(&node.base);
25032562
2504 stack.append(State{2563 stack.append(State{
...@@ -2511,12 +2570,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2511,12 +2570,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2511 continue;2570 continue;
2512 },2571 },
2513 Token.Id.Builtin => {2572 Token.Id.Builtin => {
2514 const node = try arena.create(ast.Node.BuiltinCall{2573 const node = try arena.create(ast.Node.BuiltinCall);
2574 node.* = ast.Node.BuiltinCall{
2515 .base = ast.Node{ .id = ast.Node.Id.BuiltinCall },2575 .base = ast.Node{ .id = ast.Node.Id.BuiltinCall },
2516 .builtin_token = token.index,2576 .builtin_token = token.index,
2517 .params = ast.Node.BuiltinCall.ParamList.init(arena),2577 .params = ast.Node.BuiltinCall.ParamList.init(arena),
2518 .rparen_token = undefined,2578 .rparen_token = undefined,
2519 });2579 };
2520 opt_ctx.store(&node.base);2580 opt_ctx.store(&node.base);
25212581
2522 stack.append(State{2582 stack.append(State{
...@@ -2530,12 +2590,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2530,12 +2590,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2530 continue;2590 continue;
2531 },2591 },
2532 Token.Id.LBracket => {2592 Token.Id.LBracket => {
2533 const node = try arena.create(ast.Node.PrefixOp{2593 const node = try arena.create(ast.Node.PrefixOp);
2594 node.* = ast.Node.PrefixOp{
2534 .base = ast.Node{ .id = ast.Node.Id.PrefixOp },2595 .base = ast.Node{ .id = ast.Node.Id.PrefixOp },
2535 .op_token = token.index,2596 .op_token = token.index,
2536 .op = undefined,2597 .op = undefined,
2537 .rhs = undefined,2598 .rhs = undefined,
2538 });2599 };
2539 opt_ctx.store(&node.base);2600 opt_ctx.store(&node.base);
25402601
2541 stack.append(State{ .SliceOrArrayType = node }) catch unreachable;2602 stack.append(State{ .SliceOrArrayType = node }) catch unreachable;
...@@ -2593,7 +2654,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2593,7 +2654,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2593 continue;2654 continue;
2594 },2655 },
2595 Token.Id.Keyword_fn => {2656 Token.Id.Keyword_fn => {
2596 const fn_proto = try arena.create(ast.Node.FnProto{2657 const fn_proto = try arena.create(ast.Node.FnProto);
2658 fn_proto.* = ast.Node.FnProto{
2597 .base = ast.Node{ .id = ast.Node.Id.FnProto },2659 .base = ast.Node{ .id = ast.Node.Id.FnProto },
2598 .doc_comments = null,2660 .doc_comments = null,
2599 .visib_token = null,2661 .visib_token = null,
...@@ -2609,13 +2671,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2609,13 +2671,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2609 .lib_name = null,2671 .lib_name = null,
2610 .align_expr = null,2672 .align_expr = null,
2611 .section_expr = null,2673 .section_expr = null,
2612 });2674 };
2613 opt_ctx.store(&fn_proto.base);2675 opt_ctx.store(&fn_proto.base);
2614 stack.append(State{ .FnProto = fn_proto }) catch unreachable;2676 stack.append(State{ .FnProto = fn_proto }) catch unreachable;
2615 continue;2677 continue;
2616 },2678 },
2617 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {2679 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
2618 const fn_proto = try arena.create(ast.Node.FnProto{2680 const fn_proto = try arena.create(ast.Node.FnProto);
2681 fn_proto.* = ast.Node.FnProto{
2619 .base = ast.Node{ .id = ast.Node.Id.FnProto },2682 .base = ast.Node{ .id = ast.Node.Id.FnProto },
2620 .doc_comments = null,2683 .doc_comments = null,
2621 .visib_token = null,2684 .visib_token = null,
...@@ -2631,7 +2694,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2631,7 +2694,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2631 .lib_name = null,2694 .lib_name = null,
2632 .align_expr = null,2695 .align_expr = null,
2633 .section_expr = null,2696 .section_expr = null,
2634 });2697 };
2635 opt_ctx.store(&fn_proto.base);2698 opt_ctx.store(&fn_proto.base);
2636 stack.append(State{ .FnProto = fn_proto }) catch unreachable;2699 stack.append(State{ .FnProto = fn_proto }) catch unreachable;
2637 try stack.append(State{2700 try stack.append(State{
...@@ -2643,7 +2706,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2643,7 +2706,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2643 continue;2706 continue;
2644 },2707 },
2645 Token.Id.Keyword_asm => {2708 Token.Id.Keyword_asm => {
2646 const node = try arena.create(ast.Node.Asm{2709 const node = try arena.create(ast.Node.Asm);
2710 node.* = ast.Node.Asm{
2647 .base = ast.Node{ .id = ast.Node.Id.Asm },2711 .base = ast.Node{ .id = ast.Node.Id.Asm },
2648 .asm_token = token.index,2712 .asm_token = token.index,
2649 .volatile_token = null,2713 .volatile_token = null,
...@@ -2652,7 +2716,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2652,7 +2716,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2652 .inputs = ast.Node.Asm.InputList.init(arena),2716 .inputs = ast.Node.Asm.InputList.init(arena),
2653 .clobbers = ast.Node.Asm.ClobberList.init(arena),2717 .clobbers = ast.Node.Asm.ClobberList.init(arena),
2654 .rparen = undefined,2718 .rparen = undefined,
2655 });2719 };
2656 opt_ctx.store(&node.base);2720 opt_ctx.store(&node.base);
26572721
2658 stack.append(State{2722 stack.append(State{
...@@ -2701,13 +2765,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2701,13 +2765,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
27012765
2702 State.ErrorTypeOrSetDecl => |ctx| {2766 State.ErrorTypeOrSetDecl => |ctx| {
2703 if (eatToken(&tok_it, &tree, Token.Id.LBrace) == null) {2767 if (eatToken(&tok_it, &tree, Token.Id.LBrace) == null) {
2704 const node = try arena.create(ast.Node.InfixOp{2768 const node = try arena.create(ast.Node.InfixOp);
2769 node.* = ast.Node.InfixOp{
2705 .base = ast.Node{ .id = ast.Node.Id.InfixOp },2770 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2706 .lhs = &(try createLiteral(arena, ast.Node.ErrorType, ctx.error_token)).base,2771 .lhs = &(try createLiteral(arena, ast.Node.ErrorType, ctx.error_token)).base,
2707 .op_token = undefined,2772 .op_token = undefined,
2708 .op = ast.Node.InfixOp.Op.Period,2773 .op = ast.Node.InfixOp.Op.Period,
2709 .rhs = undefined,2774 .rhs = undefined,
2710 });2775 };
2711 ctx.opt_ctx.store(&node.base);2776 ctx.opt_ctx.store(&node.base);
2712 stack.append(State{ .Identifier = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;2777 stack.append(State{ .Identifier = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
2713 try stack.append(State{2778 try stack.append(State{
...@@ -2719,12 +2784,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2719,12 +2784,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2719 continue;2784 continue;
2720 }2785 }
27212786
2722 const node = try arena.create(ast.Node.ErrorSetDecl{2787 const node = try arena.create(ast.Node.ErrorSetDecl);
2788 node.* = ast.Node.ErrorSetDecl{
2723 .base = ast.Node{ .id = ast.Node.Id.ErrorSetDecl },2789 .base = ast.Node{ .id = ast.Node.Id.ErrorSetDecl },
2724 .error_token = ctx.error_token,2790 .error_token = ctx.error_token,
2725 .decls = ast.Node.ErrorSetDecl.DeclList.init(arena),2791 .decls = ast.Node.ErrorSetDecl.DeclList.init(arena),
2726 .rbrace_token = undefined,2792 .rbrace_token = undefined,
2727 });2793 };
2728 ctx.opt_ctx.store(&node.base);2794 ctx.opt_ctx.store(&node.base);
27292795
2730 stack.append(State{2796 stack.append(State{
...@@ -2785,11 +2851,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -2785,11 +2851,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2785 return tree;2851 return tree;
2786 }2852 }
27872853
2788 const node = try arena.create(ast.Node.ErrorTag{2854 const node = try arena.create(ast.Node.ErrorTag);
2855 node.* = ast.Node.ErrorTag{
2789 .base = ast.Node{ .id = ast.Node.Id.ErrorTag },2856 .base = ast.Node{ .id = ast.Node.Id.ErrorTag },
2790 .doc_comments = comments,2857 .doc_comments = comments,
2791 .name_token = ident_token_index,2858 .name_token = ident_token_index,
2792 });2859 };
2793 node_ptr.* = &node.base;2860 node_ptr.* = &node.base;
2794 continue;2861 continue;
2795 },2862 },
...@@ -3129,10 +3196,11 @@ fn pushDocComment(arena: *mem.Allocator, line_comment: TokenIndex, result: *?*as...@@ -3129,10 +3196,11 @@ fn pushDocComment(arena: *mem.Allocator, line_comment: TokenIndex, result: *?*as
3129 if (result.*) |comment_node| {3196 if (result.*) |comment_node| {
3130 break :blk comment_node;3197 break :blk comment_node;
3131 } else {3198 } else {
3132 const comment_node = try arena.create(ast.Node.DocComment{3199 const comment_node = try arena.create(ast.Node.DocComment);
3200 comment_node.* = ast.Node.DocComment{
3133 .base = ast.Node{ .id = ast.Node.Id.DocComment },3201 .base = ast.Node{ .id = ast.Node.Id.DocComment },
3134 .lines = ast.Node.DocComment.LineList.init(arena),3202 .lines = ast.Node.DocComment.LineList.init(arena),
3135 });3203 };
3136 result.* = comment_node;3204 result.* = comment_node;
3137 break :blk comment_node;3205 break :blk comment_node;
3138 }3206 }
...@@ -3158,10 +3226,11 @@ fn parseStringLiteral(arena: *mem.Allocator, tok_it: *ast.Tree.TokenList.Iterato...@@ -3158,10 +3226,11 @@ fn parseStringLiteral(arena: *mem.Allocator, tok_it: *ast.Tree.TokenList.Iterato
3158 return &(try createLiteral(arena, ast.Node.StringLiteral, token_index)).base;3226 return &(try createLiteral(arena, ast.Node.StringLiteral, token_index)).base;
3159 },3227 },
3160 Token.Id.MultilineStringLiteralLine => {3228 Token.Id.MultilineStringLiteralLine => {
3161 const node = try arena.create(ast.Node.MultilineStringLiteral{3229 const node = try arena.create(ast.Node.MultilineStringLiteral);
3230 node.* = ast.Node.MultilineStringLiteral{
3162 .base = ast.Node{ .id = ast.Node.Id.MultilineStringLiteral },3231 .base = ast.Node{ .id = ast.Node.Id.MultilineStringLiteral },
3163 .lines = ast.Node.MultilineStringLiteral.LineList.init(arena),3232 .lines = ast.Node.MultilineStringLiteral.LineList.init(arena),
3164 });3233 };
3165 try node.lines.push(token_index);3234 try node.lines.push(token_index);
3166 while (true) {3235 while (true) {
3167 const multiline_str = nextToken(tok_it, tree);3236 const multiline_str = nextToken(tok_it, tree);
...@@ -3186,25 +3255,27 @@ fn parseStringLiteral(arena: *mem.Allocator, tok_it: *ast.Tree.TokenList.Iterato...@@ -3186,25 +3255,27 @@ fn parseStringLiteral(arena: *mem.Allocator, tok_it: *ast.Tree.TokenList.Iterato
3186fn parseBlockExpr(stack: *std.ArrayList(State), arena: *mem.Allocator, ctx: OptionalCtx, token_ptr: Token, token_index: TokenIndex) !bool {3255fn parseBlockExpr(stack: *std.ArrayList(State), arena: *mem.Allocator, ctx: OptionalCtx, token_ptr: Token, token_index: TokenIndex) !bool {
3187 switch (token_ptr.id) {3256 switch (token_ptr.id) {
3188 Token.Id.Keyword_suspend => {3257 Token.Id.Keyword_suspend => {
3189 const node = try arena.create(ast.Node.Suspend{3258 const node = try arena.create(ast.Node.Suspend);
3259 node.* = ast.Node.Suspend{
3190 .base = ast.Node{ .id = ast.Node.Id.Suspend },3260 .base = ast.Node{ .id = ast.Node.Id.Suspend },
3191 .suspend_token = token_index,3261 .suspend_token = token_index,
3192 .body = null,3262 .body = null,
3193 });3263 };
3194 ctx.store(&node.base);3264 ctx.store(&node.base);
31953265
3196 stack.append(State{ .SuspendBody = node }) catch unreachable;3266 stack.append(State{ .SuspendBody = node }) catch unreachable;
3197 return true;3267 return true;
3198 },3268 },
3199 Token.Id.Keyword_if => {3269 Token.Id.Keyword_if => {
3200 const node = try arena.create(ast.Node.If{3270 const node = try arena.create(ast.Node.If);
3271 node.* = ast.Node.If{
3201 .base = ast.Node{ .id = ast.Node.Id.If },3272 .base = ast.Node{ .id = ast.Node.Id.If },
3202 .if_token = token_index,3273 .if_token = token_index,
3203 .condition = undefined,3274 .condition = undefined,
3204 .payload = null,3275 .payload = null,
3205 .body = undefined,3276 .body = undefined,
3206 .@"else" = null,3277 .@"else" = null,
3207 });3278 };
3208 ctx.store(&node.base);3279 ctx.store(&node.base);
32093280
3210 stack.append(State{ .Else = &node.@"else" }) catch unreachable;3281 stack.append(State{ .Else = &node.@"else" }) catch unreachable;
...@@ -3238,13 +3309,14 @@ fn parseBlockExpr(stack: *std.ArrayList(State), arena: *mem.Allocator, ctx: Opti...@@ -3238,13 +3309,14 @@ fn parseBlockExpr(stack: *std.ArrayList(State), arena: *mem.Allocator, ctx: Opti
3238 return true;3309 return true;
3239 },3310 },
3240 Token.Id.Keyword_switch => {3311 Token.Id.Keyword_switch => {
3241 const node = try arena.create(ast.Node.Switch{3312 const node = try arena.create(ast.Node.Switch);
3313 node.* = ast.Node.Switch{
3242 .base = ast.Node{ .id = ast.Node.Id.Switch },3314 .base = ast.Node{ .id = ast.Node.Id.Switch },
3243 .switch_token = token_index,3315 .switch_token = token_index,
3244 .expr = undefined,3316 .expr = undefined,
3245 .cases = ast.Node.Switch.CaseList.init(arena),3317 .cases = ast.Node.Switch.CaseList.init(arena),
3246 .rbrace = undefined,3318 .rbrace = undefined,
3247 });3319 };
3248 ctx.store(&node.base);3320 ctx.store(&node.base);
32493321
3250 stack.append(State{3322 stack.append(State{
...@@ -3260,25 +3332,27 @@ fn parseBlockExpr(stack: *std.ArrayList(State), arena: *mem.Allocator, ctx: Opti...@@ -3260,25 +3332,27 @@ fn parseBlockExpr(stack: *std.ArrayList(State), arena: *mem.Allocator, ctx: Opti
3260 return true;3332 return true;
3261 },3333 },
3262 Token.Id.Keyword_comptime => {3334 Token.Id.Keyword_comptime => {
3263 const node = try arena.create(ast.Node.Comptime{3335 const node = try arena.create(ast.Node.Comptime);
3336 node.* = ast.Node.Comptime{
3264 .base = ast.Node{ .id = ast.Node.Id.Comptime },3337 .base = ast.Node{ .id = ast.Node.Id.Comptime },
3265 .comptime_token = token_index,3338 .comptime_token = token_index,
3266 .expr = undefined,3339 .expr = undefined,
3267 .doc_comments = null,3340 .doc_comments = null,
3268 });3341 };
3269 ctx.store(&node.base);3342 ctx.store(&node.base);
32703343
3271 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });3344 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });
3272 return true;3345 return true;
3273 },3346 },
3274 Token.Id.LBrace => {3347 Token.Id.LBrace => {
3275 const block = try arena.create(ast.Node.Block{3348 const block = try arena.create(ast.Node.Block);
3349 block.* = ast.Node.Block{
3276 .base = ast.Node{ .id = ast.Node.Id.Block },3350 .base = ast.Node{ .id = ast.Node.Id.Block },
3277 .label = null,3351 .label = null,
3278 .lbrace = token_index,3352 .lbrace = token_index,
3279 .statements = ast.Node.Block.StatementList.init(arena),3353 .statements = ast.Node.Block.StatementList.init(arena),
3280 .rbrace = undefined,3354 .rbrace = undefined,
3281 });3355 };
3282 ctx.store(&block.base);3356 ctx.store(&block.base);
3283 stack.append(State{ .Block = block }) catch unreachable;3357 stack.append(State{ .Block = block }) catch unreachable;
3284 return true;3358 return true;
...@@ -3412,10 +3486,12 @@ fn tokenIdToPrefixOp(id: Token.Id) ?ast.Node.PrefixOp.Op {...@@ -3412,10 +3486,12 @@ fn tokenIdToPrefixOp(id: Token.Id) ?ast.Node.PrefixOp.Op {
3412}3486}
34133487
3414fn createLiteral(arena: *mem.Allocator, comptime T: type, token_index: TokenIndex) !*T {3488fn createLiteral(arena: *mem.Allocator, comptime T: type, token_index: TokenIndex) !*T {
3415 return arena.create(T{3489 const result = try arena.create(T);
3490 result.* = T{
3416 .base = ast.Node{ .id = ast.Node.typeToId(T) },3491 .base = ast.Node{ .id = ast.Node.typeToId(T) },
3417 .token = token_index,3492 .token = token_index,
3418 });3493 };
3494 return result;
3419}3495}
34203496
3421fn createToCtxLiteral(arena: *mem.Allocator, opt_ctx: OptionalCtx, comptime T: type, token_index: TokenIndex) !*T {3497fn createToCtxLiteral(arena: *mem.Allocator, opt_ctx: OptionalCtx, comptime T: type, token_index: TokenIndex) !*T {
test/tests.zig+45-30
...@@ -48,13 +48,14 @@ const test_targets = []TestTarget{...@@ -48,13 +48,14 @@ const test_targets = []TestTarget{
48const max_stdout_size = 1 * 1024 * 1024; // 1 MB48const max_stdout_size = 1 * 1024 * 1024; // 1 MB
4949
50pub fn addCompareOutputTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {50pub fn addCompareOutputTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
51 const cases = b.allocator.create(CompareOutputContext{51 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
52 cases.* = CompareOutputContext{
52 .b = b,53 .b = b,
53 .step = b.step("test-compare-output", "Run the compare output tests"),54 .step = b.step("test-compare-output", "Run the compare output tests"),
54 .test_index = 0,55 .test_index = 0,
55 .test_filter = test_filter,56 .test_filter = test_filter,
56 .modes = modes,57 .modes = modes,
57 }) catch unreachable;58 };
5859
59 compare_output.addCases(cases);60 compare_output.addCases(cases);
6061
...@@ -62,13 +63,14 @@ pub fn addCompareOutputTests(b: *build.Builder, test_filter: ?[]const u8, modes:...@@ -62,13 +63,14 @@ pub fn addCompareOutputTests(b: *build.Builder, test_filter: ?[]const u8, modes:
62}63}
6364
64pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {65pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
65 const cases = b.allocator.create(CompareOutputContext{66 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
67 cases.* = CompareOutputContext{
66 .b = b,68 .b = b,
67 .step = b.step("test-runtime-safety", "Run the runtime safety tests"),69 .step = b.step("test-runtime-safety", "Run the runtime safety tests"),
68 .test_index = 0,70 .test_index = 0,
69 .test_filter = test_filter,71 .test_filter = test_filter,
70 .modes = modes,72 .modes = modes,
71 }) catch unreachable;73 };
7274
73 runtime_safety.addCases(cases);75 runtime_safety.addCases(cases);
7476
...@@ -76,13 +78,14 @@ pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes:...@@ -76,13 +78,14 @@ pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes:
76}78}
7779
78pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {80pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
79 const cases = b.allocator.create(CompileErrorContext{81 const cases = b.allocator.create(CompileErrorContext) catch unreachable;
82 cases.* = CompileErrorContext{
80 .b = b,83 .b = b,
81 .step = b.step("test-compile-errors", "Run the compile error tests"),84 .step = b.step("test-compile-errors", "Run the compile error tests"),
82 .test_index = 0,85 .test_index = 0,
83 .test_filter = test_filter,86 .test_filter = test_filter,
84 .modes = modes,87 .modes = modes,
85 }) catch unreachable;88 };
8689
87 compile_errors.addCases(cases);90 compile_errors.addCases(cases);
8891
...@@ -90,13 +93,14 @@ pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes:...@@ -90,13 +93,14 @@ pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes:
90}93}
9194
92pub fn addBuildExampleTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {95pub fn addBuildExampleTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
93 const cases = b.allocator.create(BuildExamplesContext{96 const cases = b.allocator.create(BuildExamplesContext) catch unreachable;
97 cases.* = BuildExamplesContext{
94 .b = b,98 .b = b,
95 .step = b.step("test-build-examples", "Build the examples"),99 .step = b.step("test-build-examples", "Build the examples"),
96 .test_index = 0,100 .test_index = 0,
97 .test_filter = test_filter,101 .test_filter = test_filter,
98 .modes = modes,102 .modes = modes,
99 }) catch unreachable;103 };
100104
101 build_examples.addCases(cases);105 build_examples.addCases(cases);
102106
...@@ -119,13 +123,14 @@ pub fn addCliTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const M...@@ -119,13 +123,14 @@ pub fn addCliTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const M
119}123}
120124
121pub fn addAssembleAndLinkTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {125pub fn addAssembleAndLinkTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
122 const cases = b.allocator.create(CompareOutputContext{126 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
127 cases.* = CompareOutputContext{
123 .b = b,128 .b = b,
124 .step = b.step("test-asm-link", "Run the assemble and link tests"),129 .step = b.step("test-asm-link", "Run the assemble and link tests"),
125 .test_index = 0,130 .test_index = 0,
126 .test_filter = test_filter,131 .test_filter = test_filter,
127 .modes = modes,132 .modes = modes,
128 }) catch unreachable;133 };
129134
130 assemble_and_link.addCases(cases);135 assemble_and_link.addCases(cases);
131136
...@@ -133,12 +138,13 @@ pub fn addAssembleAndLinkTests(b: *build.Builder, test_filter: ?[]const u8, mode...@@ -133,12 +138,13 @@ pub fn addAssembleAndLinkTests(b: *build.Builder, test_filter: ?[]const u8, mode
133}138}
134139
135pub fn addTranslateCTests(b: *build.Builder, test_filter: ?[]const u8) *build.Step {140pub fn addTranslateCTests(b: *build.Builder, test_filter: ?[]const u8) *build.Step {
136 const cases = b.allocator.create(TranslateCContext{141 const cases = b.allocator.create(TranslateCContext) catch unreachable;
142 cases.* = TranslateCContext{
137 .b = b,143 .b = b,
138 .step = b.step("test-translate-c", "Run the C transation tests"),144 .step = b.step("test-translate-c", "Run the C transation tests"),
139 .test_index = 0,145 .test_index = 0,
140 .test_filter = test_filter,146 .test_filter = test_filter,
141 }) catch unreachable;147 };
142148
143 translate_c.addCases(cases);149 translate_c.addCases(cases);
144150
...@@ -146,12 +152,13 @@ pub fn addTranslateCTests(b: *build.Builder, test_filter: ?[]const u8) *build.St...@@ -146,12 +152,13 @@ pub fn addTranslateCTests(b: *build.Builder, test_filter: ?[]const u8) *build.St
146}152}
147153
148pub fn addGenHTests(b: *build.Builder, test_filter: ?[]const u8) *build.Step {154pub fn addGenHTests(b: *build.Builder, test_filter: ?[]const u8) *build.Step {
149 const cases = b.allocator.create(GenHContext{155 const cases = b.allocator.create(GenHContext) catch unreachable;
156 cases.* = GenHContext{
150 .b = b,157 .b = b,
151 .step = b.step("test-gen-h", "Run the C header file generation tests"),158 .step = b.step("test-gen-h", "Run the C header file generation tests"),
152 .test_index = 0,159 .test_index = 0,
153 .test_filter = test_filter,160 .test_filter = test_filter,
154 }) catch unreachable;161 };
155162
156 gen_h.addCases(cases);163 gen_h.addCases(cases);
157164
...@@ -244,7 +251,8 @@ pub const CompareOutputContext = struct {...@@ -244,7 +251,8 @@ pub const CompareOutputContext = struct {
244251
245 pub fn create(context: *CompareOutputContext, exe_path: []const u8, name: []const u8, expected_output: []const u8, cli_args: []const []const u8) *RunCompareOutputStep {252 pub fn create(context: *CompareOutputContext, exe_path: []const u8, name: []const u8, expected_output: []const u8, cli_args: []const []const u8) *RunCompareOutputStep {
246 const allocator = context.b.allocator;253 const allocator = context.b.allocator;
247 const ptr = allocator.create(RunCompareOutputStep{254 const ptr = allocator.create(RunCompareOutputStep) catch unreachable;
255 ptr.* = RunCompareOutputStep{
248 .context = context,256 .context = context,
249 .exe_path = exe_path,257 .exe_path = exe_path,
250 .name = name,258 .name = name,
...@@ -252,7 +260,7 @@ pub const CompareOutputContext = struct {...@@ -252,7 +260,7 @@ pub const CompareOutputContext = struct {
252 .test_index = context.test_index,260 .test_index = context.test_index,
253 .step = build.Step.init("RunCompareOutput", allocator, make),261 .step = build.Step.init("RunCompareOutput", allocator, make),
254 .cli_args = cli_args,262 .cli_args = cli_args,
255 }) catch unreachable;263 };
256 context.test_index += 1;264 context.test_index += 1;
257 return ptr;265 return ptr;
258 }266 }
...@@ -331,13 +339,14 @@ pub const CompareOutputContext = struct {...@@ -331,13 +339,14 @@ pub const CompareOutputContext = struct {
331339
332 pub fn create(context: *CompareOutputContext, exe_path: []const u8, name: []const u8) *RuntimeSafetyRunStep {340 pub fn create(context: *CompareOutputContext, exe_path: []const u8, name: []const u8) *RuntimeSafetyRunStep {
333 const allocator = context.b.allocator;341 const allocator = context.b.allocator;
334 const ptr = allocator.create(RuntimeSafetyRunStep{342 const ptr = allocator.create(RuntimeSafetyRunStep) catch unreachable;
343 ptr.* = RuntimeSafetyRunStep{
335 .context = context,344 .context = context,
336 .exe_path = exe_path,345 .exe_path = exe_path,
337 .name = name,346 .name = name,
338 .test_index = context.test_index,347 .test_index = context.test_index,
339 .step = build.Step.init("RuntimeSafetyRun", allocator, make),348 .step = build.Step.init("RuntimeSafetyRun", allocator, make),
340 }) catch unreachable;349 };
341350
342 context.test_index += 1;351 context.test_index += 1;
343 return ptr;352 return ptr;
...@@ -542,14 +551,15 @@ pub const CompileErrorContext = struct {...@@ -542,14 +551,15 @@ pub const CompileErrorContext = struct {
542551
543 pub fn create(context: *CompileErrorContext, name: []const u8, case: *const TestCase, build_mode: Mode) *CompileCmpOutputStep {552 pub fn create(context: *CompileErrorContext, name: []const u8, case: *const TestCase, build_mode: Mode) *CompileCmpOutputStep {
544 const allocator = context.b.allocator;553 const allocator = context.b.allocator;
545 const ptr = allocator.create(CompileCmpOutputStep{554 const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;
555 ptr.* = CompileCmpOutputStep{
546 .step = build.Step.init("CompileCmpOutput", allocator, make),556 .step = build.Step.init("CompileCmpOutput", allocator, make),
547 .context = context,557 .context = context,
548 .name = name,558 .name = name,
549 .test_index = context.test_index,559 .test_index = context.test_index,
550 .case = case,560 .case = case,
551 .build_mode = build_mode,561 .build_mode = build_mode,
552 }) catch unreachable;562 };
553563
554 context.test_index += 1;564 context.test_index += 1;
555 return ptr;565 return ptr;
...@@ -661,13 +671,14 @@ pub const CompileErrorContext = struct {...@@ -661,13 +671,14 @@ pub const CompileErrorContext = struct {
661 }671 }
662672
663 pub fn create(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {673 pub fn create(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
664 const tc = self.b.allocator.create(TestCase{674 const tc = self.b.allocator.create(TestCase) catch unreachable;
675 tc.* = TestCase{
665 .name = name,676 .name = name,
666 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),677 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
667 .expected_errors = ArrayList([]const u8).init(self.b.allocator),678 .expected_errors = ArrayList([]const u8).init(self.b.allocator),
668 .link_libc = false,679 .link_libc = false,
669 .is_exe = false,680 .is_exe = false,
670 }) catch unreachable;681 };
671682
672 tc.addSourceFile(".tmp_source.zig", source);683 tc.addSourceFile(".tmp_source.zig", source);
673 comptime var arg_i = 0;684 comptime var arg_i = 0;
...@@ -821,13 +832,14 @@ pub const TranslateCContext = struct {...@@ -821,13 +832,14 @@ pub const TranslateCContext = struct {
821832
822 pub fn create(context: *TranslateCContext, name: []const u8, case: *const TestCase) *TranslateCCmpOutputStep {833 pub fn create(context: *TranslateCContext, name: []const u8, case: *const TestCase) *TranslateCCmpOutputStep {
823 const allocator = context.b.allocator;834 const allocator = context.b.allocator;
824 const ptr = allocator.create(TranslateCCmpOutputStep{835 const ptr = allocator.create(TranslateCCmpOutputStep) catch unreachable;
836 ptr.* = TranslateCCmpOutputStep{
825 .step = build.Step.init("ParseCCmpOutput", allocator, make),837 .step = build.Step.init("ParseCCmpOutput", allocator, make),
826 .context = context,838 .context = context,
827 .name = name,839 .name = name,
828 .test_index = context.test_index,840 .test_index = context.test_index,
829 .case = case,841 .case = case,
830 }) catch unreachable;842 };
831843
832 context.test_index += 1;844 context.test_index += 1;
833 return ptr;845 return ptr;
...@@ -928,12 +940,13 @@ pub const TranslateCContext = struct {...@@ -928,12 +940,13 @@ pub const TranslateCContext = struct {
928 }940 }
929941
930 pub fn create(self: *TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {942 pub fn create(self: *TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
931 const tc = self.b.allocator.create(TestCase{943 const tc = self.b.allocator.create(TestCase) catch unreachable;
944 tc.* = TestCase{
932 .name = name,945 .name = name,
933 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),946 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
934 .expected_lines = ArrayList([]const u8).init(self.b.allocator),947 .expected_lines = ArrayList([]const u8).init(self.b.allocator),
935 .allow_warnings = allow_warnings,948 .allow_warnings = allow_warnings,
936 }) catch unreachable;949 };
937950
938 tc.addSourceFile(filename, source);951 tc.addSourceFile(filename, source);
939 comptime var arg_i = 0;952 comptime var arg_i = 0;
...@@ -1015,14 +1028,15 @@ pub const GenHContext = struct {...@@ -1015,14 +1028,15 @@ pub const GenHContext = struct {
10151028
1016 pub fn create(context: *GenHContext, h_path: []const u8, name: []const u8, case: *const TestCase) *GenHCmpOutputStep {1029 pub fn create(context: *GenHContext, h_path: []const u8, name: []const u8, case: *const TestCase) *GenHCmpOutputStep {
1017 const allocator = context.b.allocator;1030 const allocator = context.b.allocator;
1018 const ptr = allocator.create(GenHCmpOutputStep{1031 const ptr = allocator.create(GenHCmpOutputStep) catch unreachable;
1032 ptr.* = GenHCmpOutputStep{
1019 .step = build.Step.init("ParseCCmpOutput", allocator, make),1033 .step = build.Step.init("ParseCCmpOutput", allocator, make),
1020 .context = context,1034 .context = context,
1021 .h_path = h_path,1035 .h_path = h_path,
1022 .name = name,1036 .name = name,
1023 .test_index = context.test_index,1037 .test_index = context.test_index,
1024 .case = case,1038 .case = case,
1025 }) catch unreachable;1039 };
10261040
1027 context.test_index += 1;1041 context.test_index += 1;
1028 return ptr;1042 return ptr;
...@@ -1062,11 +1076,12 @@ pub const GenHContext = struct {...@@ -1062,11 +1076,12 @@ pub const GenHContext = struct {
1062 }1076 }
10631077
1064 pub fn create(self: *GenHContext, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {1078 pub fn create(self: *GenHContext, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
1065 const tc = self.b.allocator.create(TestCase{1079 const tc = self.b.allocator.create(TestCase) catch unreachable;
1080 tc.* = TestCase{
1066 .name = name,1081 .name = name,
1067 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),1082 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
1068 .expected_lines = ArrayList([]const u8).init(self.b.allocator),1083 .expected_lines = ArrayList([]const u8).init(self.b.allocator),
1069 }) catch unreachable;1084 };
10701085
1071 tc.addSourceFile(filename, source);1086 tc.addSourceFile(filename, source);
1072 comptime var arg_i = 0;1087 comptime var arg_i = 0;