authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-11 10:37:04+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-11 10:37:04+02:00
logdae287524d94219b1f3a2ec82d410b9f34fb2546
treeb9a90c0a8357ce481cbe6db5039aca947eee75e6
parentf43711e5fbbedafa1c28c933fdca0949427c77cd

std.zig: Major refactor

* There now exists a few function to allocate all nodes in parser.zig * ast.zig now have a table of Ids and their corrisponding type

2 files changed, 954 insertions(+), 974 deletions(-)

std/zig/ast.zig+147-188
...@@ -9,38 +9,34 @@ pub const Node = struct {...@@ -9,38 +9,34 @@ pub const Node = struct {
9 comment: ?&NodeLineComment,9 comment: ?&NodeLineComment,
1010
11 pub const Id = enum {11 pub const Id = enum {
12 // Top level
12 Root,13 Root,
13 VarDecl,
14 Use,14 Use,
15 ErrorSetDecl,15 TestDecl,
16 ContainerDecl,16
17 StructField,17 // Statements
18 UnionTag,18 VarDecl,
19 EnumTag,
20 Identifier,
21 AsyncAttribute,
22 FnProto,
23 ParamDecl,
24 Block,
25 Defer,19 Defer,
26 Comptime,20
27 Payload,21 // Operators
28 PointerPayload,22 InfixOp,
29 PointerIndexPayload,23 PrefixOp,
30 Else,24 SuffixOp,
25
26 // Control flow
31 Switch,27 Switch,
32 SwitchCase,
33 SwitchElse,
34 While,28 While,
35 For,29 For,
36 If,30 If,
37 InfixOp,
38 PrefixOp,
39 SuffixOp,
40 GroupedExpression,
41 ControlFlowExpression,31 ControlFlowExpression,
42 Suspend,32 Suspend,
43 FieldInitializer,33
34 // Type expressions
35 VarType,
36 ErrorType,
37 FnProto,
38
39 // Primary expressions
44 IntegerLiteral,40 IntegerLiteral,
45 FloatLiteral,41 FloatLiteral,
46 StringLiteral,42 StringLiteral,
...@@ -50,180 +46,143 @@ pub const Node = struct {...@@ -50,180 +46,143 @@ pub const Node = struct {
50 NullLiteral,46 NullLiteral,
51 UndefinedLiteral,47 UndefinedLiteral,
52 ThisLiteral,48 ThisLiteral,
53 Asm,
54 AsmInput,
55 AsmOutput,
56 Unreachable,49 Unreachable,
57 ErrorType,50 Identifier,
58 VarType,51 GroupedExpression,
59 BuiltinCall,52 BuiltinCall,
53 ErrorSetDecl,
54 ContainerDecl,
55 Asm,
56 Comptime,
57 Block,
58
59 // Misc
60 LineComment,60 LineComment,
61 TestDecl,61 SwitchCase,
62 SwitchElse,
63 Else,
64 Payload,
65 PointerPayload,
66 PointerIndexPayload,
67 StructField,
68 UnionTag,
69 EnumTag,
70 AsmInput,
71 AsmOutput,
72 AsyncAttribute,
73 ParamDecl,
74 FieldInitializer,
62 };75 };
6376
77 const IdTypePair = struct {
78 id: Id,
79 Type: type,
80 };
81
82 // TODO: When @field exists, we could generate this by iterating over all members of `Id`,
83 // and making an array of `IdTypePair { .id = @field(Id, @memberName(Id, i)), .Type = @field(ast, "Node" ++ @memberName(Id, i)) }`
84 const idTypeTable = []IdTypePair {
85 IdTypePair { .id = Id.Root, .Type = NodeRoot },
86 IdTypePair { .id = Id.Use, .Type = NodeUse },
87 IdTypePair { .id = Id.TestDecl, .Type = NodeTestDecl },
88
89 IdTypePair { .id = Id.VarDecl, .Type = NodeVarDecl },
90 IdTypePair { .id = Id.Defer, .Type = NodeDefer },
91
92 IdTypePair { .id = Id.InfixOp, .Type = NodeInfixOp },
93 IdTypePair { .id = Id.PrefixOp, .Type = NodePrefixOp },
94 IdTypePair { .id = Id.SuffixOp, .Type = NodeSuffixOp },
95
96 IdTypePair { .id = Id.Switch, .Type = NodeSwitch },
97 IdTypePair { .id = Id.While, .Type = NodeWhile },
98 IdTypePair { .id = Id.For, .Type = NodeFor },
99 IdTypePair { .id = Id.If, .Type = NodeIf },
100 IdTypePair { .id = Id.ControlFlowExpression, .Type = NodeControlFlowExpression },
101 IdTypePair { .id = Id.Suspend, .Type = NodeSuspend },
102
103 IdTypePair { .id = Id.VarType, .Type = NodeVarType },
104 IdTypePair { .id = Id.ErrorType, .Type = NodeErrorType },
105 IdTypePair { .id = Id.FnProto, .Type = NodeFnProto },
106
107 IdTypePair { .id = Id.IntegerLiteral, .Type = NodeIntegerLiteral },
108 IdTypePair { .id = Id.FloatLiteral, .Type = NodeFloatLiteral },
109 IdTypePair { .id = Id.StringLiteral, .Type = NodeStringLiteral },
110 IdTypePair { .id = Id.MultilineStringLiteral, .Type = NodeMultilineStringLiteral },
111 IdTypePair { .id = Id.CharLiteral, .Type = NodeCharLiteral },
112 IdTypePair { .id = Id.BoolLiteral, .Type = NodeBoolLiteral },
113 IdTypePair { .id = Id.NullLiteral, .Type = NodeNullLiteral },
114 IdTypePair { .id = Id.UndefinedLiteral, .Type = NodeUndefinedLiteral },
115 IdTypePair { .id = Id.ThisLiteral, .Type = NodeThisLiteral },
116 IdTypePair { .id = Id.Unreachable, .Type = NodeUnreachable },
117 IdTypePair { .id = Id.Identifier, .Type = NodeIdentifier },
118 IdTypePair { .id = Id.GroupedExpression, .Type = NodeGroupedExpression },
119 IdTypePair { .id = Id.BuiltinCall, .Type = NodeBuiltinCall },
120 IdTypePair { .id = Id.ErrorSetDecl, .Type = NodeErrorSetDecl },
121 IdTypePair { .id = Id.ContainerDecl, .Type = NodeContainerDecl },
122 IdTypePair { .id = Id.Asm, .Type = NodeAsm },
123 IdTypePair { .id = Id.Comptime, .Type = NodeComptime },
124 IdTypePair { .id = Id.Block, .Type = NodeBlock },
125
126 IdTypePair { .id = Id.LineComment, .Type = NodeLineComment },
127 IdTypePair { .id = Id.SwitchCase, .Type = NodeSwitchCase },
128 IdTypePair { .id = Id.SwitchElse, .Type = NodeSwitchElse },
129 IdTypePair { .id = Id.Else, .Type = NodeElse },
130 IdTypePair { .id = Id.Payload, .Type = NodePayload },
131 IdTypePair { .id = Id.PointerPayload, .Type = NodePointerPayload },
132 IdTypePair { .id = Id.PointerIndexPayload, .Type = NodePointerIndexPayload },
133 IdTypePair { .id = Id.StructField, .Type = NodeStructField },
134 IdTypePair { .id = Id.UnionTag, .Type = NodeUnionTag },
135 IdTypePair { .id = Id.EnumTag, .Type = NodeEnumTag },
136 IdTypePair { .id = Id.AsmInput, .Type = NodeAsmInput },
137 IdTypePair { .id = Id.AsmOutput, .Type = NodeAsmOutput },
138 IdTypePair { .id = Id.AsyncAttribute, .Type = NodeAsyncAttribute },
139 IdTypePair { .id = Id.ParamDecl, .Type = NodeParamDecl },
140 IdTypePair { .id = Id.FieldInitializer, .Type = NodeFieldInitializer },
141 };
142
143 pub fn IdToType(comptime id: Id) type {
144 inline for (idTypeTable) |id_type_pair| {
145 if (id == id_type_pair.id)
146 return id_type_pair.Type;
147 }
148
149 unreachable;
150 }
151
152 pub fn typeToId(comptime T: type) Id {
153 inline for (idTypeTable) |id_type_pair| {
154 if (T == id_type_pair.Type)
155 return id_type_pair.id;
156 }
157
158 unreachable;
159 }
160
64 pub fn iterate(base: &Node, index: usize) ?&Node {161 pub fn iterate(base: &Node, index: usize) ?&Node {
65 return switch (base.id) {162 inline for (idTypeTable) |id_type_pair| {
66 Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index),163 if (base.id == id_type_pair.id)
67 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index),164 return @fieldParentPtr(id_type_pair.Type, "base", base).iterate(index);
68 Id.Use => @fieldParentPtr(NodeUse, "base", base).iterate(index),165 }
69 Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).iterate(index),166
70 Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index),167 unreachable;
71 Id.StructField => @fieldParentPtr(NodeStructField, "base", base).iterate(index),
72 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).iterate(index),
73 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).iterate(index),
74 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).iterate(index),
75 Id.AsyncAttribute => @fieldParentPtr(NodeAsyncAttribute, "base", base).iterate(index),
76 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).iterate(index),
77 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).iterate(index),
78 Id.Block => @fieldParentPtr(NodeBlock, "base", base).iterate(index),
79 Id.Defer => @fieldParentPtr(NodeDefer, "base", base).iterate(index),
80 Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).iterate(index),
81 Id.Payload => @fieldParentPtr(NodePayload, "base", base).iterate(index),
82 Id.PointerPayload => @fieldParentPtr(NodePointerPayload, "base", base).iterate(index),
83 Id.PointerIndexPayload => @fieldParentPtr(NodePointerIndexPayload, "base", base).iterate(index),
84 Id.Else => @fieldParentPtr(NodeSwitch, "base", base).iterate(index),
85 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).iterate(index),
86 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).iterate(index),
87 Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).iterate(index),
88 Id.While => @fieldParentPtr(NodeWhile, "base", base).iterate(index),
89 Id.For => @fieldParentPtr(NodeFor, "base", base).iterate(index),
90 Id.If => @fieldParentPtr(NodeIf, "base", base).iterate(index),
91 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).iterate(index),
92 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index),
93 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),
94 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).iterate(index),
95 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).iterate(index),
96 Id.Suspend => @fieldParentPtr(NodeSuspend, "base", base).iterate(index),
97 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).iterate(index),
98 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).iterate(index),
99 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).iterate(index),
100 Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).iterate(index),
101 Id.MultilineStringLiteral => @fieldParentPtr(NodeMultilineStringLiteral, "base", base).iterate(index),
102 Id.CharLiteral => @fieldParentPtr(NodeCharLiteral, "base", base).iterate(index),
103 Id.BoolLiteral => @fieldParentPtr(NodeBoolLiteral, "base", base).iterate(index),
104 Id.NullLiteral => @fieldParentPtr(NodeNullLiteral, "base", base).iterate(index),
105 Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).iterate(index),
106 Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).iterate(index),
107 Id.Asm => @fieldParentPtr(NodeAsm, "base", base).iterate(index),
108 Id.AsmInput => @fieldParentPtr(NodeAsmInput, "base", base).iterate(index),
109 Id.AsmOutput => @fieldParentPtr(NodeAsmOutput, "base", base).iterate(index),
110 Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).iterate(index),
111 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).iterate(index),
112 Id.VarType => @fieldParentPtr(NodeVarType, "base", base).iterate(index),
113 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).iterate(index),
114 Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).iterate(index),
115 Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).iterate(index),
116 };
117 }168 }
118169
119 pub fn firstToken(base: &Node) Token {170 pub fn firstToken(base: &Node) Token {
120 return switch (base.id) {171 inline for (idTypeTable) |id_type_pair| {
121 Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(),172 if (base.id == id_type_pair.id)
122 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(),173 return @fieldParentPtr(id_type_pair.Type, "base", base).firstToken();
123 Id.Use => @fieldParentPtr(NodeUse, "base", base).firstToken(),174 }
124 Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).firstToken(),175
125 Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(),176 unreachable;
126 Id.StructField => @fieldParentPtr(NodeStructField, "base", base).firstToken(),
127 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).firstToken(),
128 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).firstToken(),
129 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).firstToken(),
130 Id.AsyncAttribute => @fieldParentPtr(NodeAsyncAttribute, "base", base).firstToken(),
131 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).firstToken(),
132 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).firstToken(),
133 Id.Block => @fieldParentPtr(NodeBlock, "base", base).firstToken(),
134 Id.Defer => @fieldParentPtr(NodeDefer, "base", base).firstToken(),
135 Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).firstToken(),
136 Id.Payload => @fieldParentPtr(NodePayload, "base", base).firstToken(),
137 Id.PointerPayload => @fieldParentPtr(NodePointerPayload, "base", base).firstToken(),
138 Id.PointerIndexPayload => @fieldParentPtr(NodePointerIndexPayload, "base", base).firstToken(),
139 Id.Else => @fieldParentPtr(NodeSwitch, "base", base).firstToken(),
140 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).firstToken(),
141 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).firstToken(),
142 Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).firstToken(),
143 Id.While => @fieldParentPtr(NodeWhile, "base", base).firstToken(),
144 Id.For => @fieldParentPtr(NodeFor, "base", base).firstToken(),
145 Id.If => @fieldParentPtr(NodeIf, "base", base).firstToken(),
146 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).firstToken(),
147 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(),
148 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),
149 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).firstToken(),
150 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).firstToken(),
151 Id.Suspend => @fieldParentPtr(NodeSuspend, "base", base).firstToken(),
152 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).firstToken(),
153 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).firstToken(),
154 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).firstToken(),
155 Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).firstToken(),
156 Id.MultilineStringLiteral => @fieldParentPtr(NodeMultilineStringLiteral, "base", base).firstToken(),
157 Id.CharLiteral => @fieldParentPtr(NodeCharLiteral, "base", base).firstToken(),
158 Id.BoolLiteral => @fieldParentPtr(NodeBoolLiteral, "base", base).firstToken(),
159 Id.NullLiteral => @fieldParentPtr(NodeNullLiteral, "base", base).firstToken(),
160 Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).firstToken(),
161 Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).firstToken(),
162 Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).firstToken(),
163 Id.Asm => @fieldParentPtr(NodeAsm, "base", base).firstToken(),
164 Id.AsmInput => @fieldParentPtr(NodeAsmInput, "base", base).firstToken(),
165 Id.AsmOutput => @fieldParentPtr(NodeAsmOutput, "base", base).firstToken(),
166 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).firstToken(),
167 Id.VarType => @fieldParentPtr(NodeVarType, "base", base).firstToken(),
168 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).firstToken(),
169 Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).firstToken(),
170 Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).firstToken(),
171 };
172 }177 }
173178
174 pub fn lastToken(base: &Node) Token {179 pub fn lastToken(base: &Node) Token {
175 return switch (base.id) {180 inline for (idTypeTable) |id_type_pair| {
176 Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(),181 if (base.id == id_type_pair.id)
177 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(),182 return @fieldParentPtr(id_type_pair.Type, "base", base).lastToken();
178 Id.Use => @fieldParentPtr(NodeUse, "base", base).lastToken(),183 }
179 Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).lastToken(),184
180 Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(),185 unreachable;
181 Id.StructField => @fieldParentPtr(NodeStructField, "base", base).lastToken(),
182 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).lastToken(),
183 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).lastToken(),
184 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).lastToken(),
185 Id.AsyncAttribute => @fieldParentPtr(NodeAsyncAttribute, "base", base).lastToken(),
186 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).lastToken(),
187 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).lastToken(),
188 Id.Block => @fieldParentPtr(NodeBlock, "base", base).lastToken(),
189 Id.Defer => @fieldParentPtr(NodeDefer, "base", base).lastToken(),
190 Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).lastToken(),
191 Id.Payload => @fieldParentPtr(NodePayload, "base", base).lastToken(),
192 Id.PointerPayload => @fieldParentPtr(NodePointerPayload, "base", base).lastToken(),
193 Id.PointerIndexPayload => @fieldParentPtr(NodePointerIndexPayload, "base", base).lastToken(),
194 Id.Else => @fieldParentPtr(NodeElse, "base", base).lastToken(),
195 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).lastToken(),
196 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).lastToken(),
197 Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).lastToken(),
198 Id.While => @fieldParentPtr(NodeWhile, "base", base).lastToken(),
199 Id.For => @fieldParentPtr(NodeFor, "base", base).lastToken(),
200 Id.If => @fieldParentPtr(NodeIf, "base", base).lastToken(),
201 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).lastToken(),
202 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(),
203 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),
204 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).lastToken(),
205 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).lastToken(),
206 Id.Suspend => @fieldParentPtr(NodeSuspend, "base", base).lastToken(),
207 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).lastToken(),
208 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).lastToken(),
209 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).lastToken(),
210 Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).lastToken(),
211 Id.MultilineStringLiteral => @fieldParentPtr(NodeMultilineStringLiteral, "base", base).lastToken(),
212 Id.CharLiteral => @fieldParentPtr(NodeCharLiteral, "base", base).lastToken(),
213 Id.BoolLiteral => @fieldParentPtr(NodeBoolLiteral, "base", base).lastToken(),
214 Id.NullLiteral => @fieldParentPtr(NodeNullLiteral, "base", base).lastToken(),
215 Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).lastToken(),
216 Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).lastToken(),
217 Id.Asm => @fieldParentPtr(NodeAsm, "base", base).lastToken(),
218 Id.AsmInput => @fieldParentPtr(NodeAsmInput, "base", base).lastToken(),
219 Id.AsmOutput => @fieldParentPtr(NodeAsmOutput, "base", base).lastToken(),
220 Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).lastToken(),
221 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).lastToken(),
222 Id.VarType => @fieldParentPtr(NodeVarType, "base", base).lastToken(),
223 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).lastToken(),
224 Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).lastToken(),
225 Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).lastToken(),
226 };
227 }186 }
228};187};
229188
...@@ -482,18 +441,18 @@ pub const NodeEnumTag = struct {...@@ -482,18 +441,18 @@ pub const NodeEnumTag = struct {
482441
483pub const NodeIdentifier = struct {442pub const NodeIdentifier = struct {
484 base: Node,443 base: Node,
485 name_token: Token,444 token: Token,
486445
487 pub fn iterate(self: &NodeIdentifier, index: usize) ?&Node {446 pub fn iterate(self: &NodeIdentifier, index: usize) ?&Node {
488 return null;447 return null;
489 }448 }
490449
491 pub fn firstToken(self: &NodeIdentifier) Token {450 pub fn firstToken(self: &NodeIdentifier) Token {
492 return self.name_token;451 return self.token;
493 }452 }
494453
495 pub fn lastToken(self: &NodeIdentifier) Token {454 pub fn lastToken(self: &NodeIdentifier) Token {
496 return self.name_token;455 return self.token;
497 }456 }
498};457};
499458
std/zig/parser.zig+807-786
...@@ -240,7 +240,14 @@ pub const Parser = struct {...@@ -240,7 +240,14 @@ pub const Parser = struct {
240 errdefer arena_allocator.deinit();240 errdefer arena_allocator.deinit();
241241
242 const arena = &arena_allocator.allocator;242 const arena = &arena_allocator.allocator;
243 const root_node = try self.createRoot(arena);243 const root_node = try self.createNode(arena, ast.NodeRoot,
244 ast.NodeRoot {
245 .base = undefined,
246 .decls = ArrayList(&ast.Node).init(arena),
247 // initialized when we get the eof token
248 .eof_token = undefined,
249 }
250 );
244251
245 try stack.append(State.TopLevel);252 try stack.append(State.TopLevel);
246253
...@@ -297,9 +304,23 @@ pub const Parser = struct {...@@ -297,9 +304,23 @@ pub const Parser = struct {
297 const name_token = (try self.eatToken(&stack, Token.Id.StringLiteral)) ?? continue;304 const name_token = (try self.eatToken(&stack, Token.Id.StringLiteral)) ?? continue;
298 const lbrace = (try self.eatToken(&stack, Token.Id.LBrace)) ?? continue;305 const lbrace = (try self.eatToken(&stack, Token.Id.LBrace)) ?? continue;
299306
300 const name = try self.createStringLiteral(arena, name_token);307 const block = try self.createNode(arena, ast.NodeBlock,
301 const block = try self.createBlock(arena, (?Token)(null), token);308 ast.NodeBlock {
302 const test_decl = try self.createAttachTestDecl(arena, &root_node.decls, token, &name.base, block);309 .base = undefined,
310 .label = null,
311 .lbrace = lbrace,
312 .statements = ArrayList(&ast.Node).init(arena),
313 .rbrace = undefined,
314 }
315 );
316 _ = try self.createAttachNode(arena, &root_node.decls, ast.NodeTestDecl,
317 ast.NodeTestDecl {
318 .base = undefined,
319 .test_token = token,
320 .name = &(try self.createLiteral(arena, ast.NodeStringLiteral, name_token)).base,
321 .body_node = &block.base,
322 }
323 );
303 stack.append(State { .Block = block }) catch unreachable;324 stack.append(State { .Block = block }) catch unreachable;
304 continue;325 continue;
305 },326 },
...@@ -320,13 +341,13 @@ pub const Parser = struct {...@@ -320,13 +341,13 @@ pub const Parser = struct {
320 continue;341 continue;
321 },342 },
322 Token.Id.Keyword_comptime => {343 Token.Id.Keyword_comptime => {
323 const node = try arena.create(ast.NodeComptime);344 const node = try self.createAttachNode(arena, &root_node.decls, ast.NodeComptime,
324 *node = ast.NodeComptime {345 ast.NodeComptime {
325 .base = self.initNode(ast.Node.Id.Comptime),346 .base = undefined,
326 .comptime_token = token,347 .comptime_token = token,
327 .expr = undefined,348 .expr = undefined,
328 };349 }
329 try root_node.decls.append(&node.base);350 );
330 stack.append(State.TopLevel) catch unreachable;351 stack.append(State.TopLevel) catch unreachable;
331 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });352 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
332 continue;353 continue;
...@@ -350,15 +371,14 @@ pub const Parser = struct {...@@ -350,15 +371,14 @@ pub const Parser = struct {
350 const token = self.getNextToken();371 const token = self.getNextToken();
351 switch (token.id) {372 switch (token.id) {
352 Token.Id.Keyword_use => {373 Token.Id.Keyword_use => {
353 const node = try arena.create(ast.NodeUse);374 const node = try self.createAttachNode(arena, ctx.decls, ast.NodeUse,
354 *node = ast.NodeUse {375 ast.NodeUse {
355 .base = self.initNode(ast.Node.Id.Use),376 .base = undefined,
356 .visib_token = ctx.visib_token,377 .visib_token = ctx.visib_token,
357 .expr = undefined,378 .expr = undefined,
358 .semicolon_token = undefined,379 .semicolon_token = undefined,
359 };380 }
360 try ctx.decls.append(&node.base);381 );
361
362 stack.append(State {382 stack.append(State {
363 .ExpectTokenSave = ExpectTokenSave {383 .ExpectTokenSave = ExpectTokenSave {
364 .id = Token.Id.Semicolon,384 .id = Token.Id.Semicolon,
...@@ -372,7 +392,7 @@ pub const Parser = struct {...@@ -372,7 +392,7 @@ pub const Parser = struct {
372 const lib_name_token = self.getNextToken();392 const lib_name_token = self.getNextToken();
373 const lib_name = blk: {393 const lib_name = blk: {
374 if (lib_name_token.id == Token.Id.StringLiteral) {394 if (lib_name_token.id == Token.Id.StringLiteral) {
375 const res = try self.createStringLiteral(arena, lib_name_token);395 const res = try self.createLiteral(arena, ast.NodeStringLiteral, lib_name_token);
376 break :blk &res.base;396 break :blk &res.base;
377 } else {397 } else {
378 self.putBackToken(lib_name_token);398 self.putBackToken(lib_name_token);
...@@ -401,24 +421,68 @@ pub const Parser = struct {...@@ -401,24 +421,68 @@ pub const Parser = struct {
401 const token = self.getNextToken();421 const token = self.getNextToken();
402 switch (token.id) {422 switch (token.id) {
403 Token.Id.Keyword_var, Token.Id.Keyword_const => {423 Token.Id.Keyword_var, Token.Id.Keyword_const => {
404 // TODO shouldn't need these casts424 const var_decl_node = try self.createAttachNode(arena, ctx.decls, ast.NodeVarDecl,
405 const var_decl_node = try self.createAttachVarDecl(arena, ctx.decls, ctx.visib_token,425 ast.NodeVarDecl {
406 token, (?Token)(null), ctx.extern_token, ctx.lib_name);426 .base = undefined,
427 .visib_token = ctx.visib_token,
428 .mut_token = token,
429 .comptime_token = null,
430 .extern_token = ctx.extern_token,
431 .type_node = null,
432 .align_node = null,
433 .init_node = null,
434 .lib_name = ctx.lib_name,
435 // initialized later
436 .name_token = undefined,
437 .eq_token = undefined,
438 .semicolon_token = undefined,
439 }
440 );
407 stack.append(State { .VarDecl = var_decl_node }) catch unreachable;441 stack.append(State { .VarDecl = var_decl_node }) catch unreachable;
408 continue;442 continue;
409 },443 },
410 Token.Id.Keyword_fn => {444 Token.Id.Keyword_fn => {
411 // TODO shouldn't need these casts445 const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto,
412 const fn_proto = try self.createAttachFnProto(arena, ctx.decls, token,446 ast.NodeFnProto {
413 ctx.extern_token, ctx.lib_name, (?Token)(null), ctx.visib_token, (?Token)(null));447 .base = undefined,
448 .visib_token = ctx.visib_token,
449 .name_token = null,
450 .fn_token = token,
451 .params = ArrayList(&ast.Node).init(arena),
452 .return_type = undefined,
453 .var_args_token = null,
454 .extern_token = ctx.extern_token,
455 .inline_token = null,
456 .cc_token = null,
457 .async_attr = null,
458 .body_node = null,
459 .lib_name = ctx.lib_name,
460 .align_expr = null,
461 }
462 );
414 stack.append(State { .FnDef = fn_proto }) catch unreachable;463 stack.append(State { .FnDef = fn_proto }) catch unreachable;
415 try stack.append(State { .FnProto = fn_proto });464 try stack.append(State { .FnProto = fn_proto });
416 continue;465 continue;
417 },466 },
418 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {467 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
419 // TODO shouldn't need this cast468 const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto,
420 const fn_proto = try self.createAttachFnProto(arena, ctx.decls, Token(undefined),469 ast.NodeFnProto {
421 ctx.extern_token, ctx.lib_name, (?Token)(token), (?Token)(null), (?Token)(null));470 .base = undefined,
471 .visib_token = ctx.visib_token,
472 .name_token = null,
473 .fn_token = undefined,
474 .params = ArrayList(&ast.Node).init(arena),
475 .return_type = undefined,
476 .var_args_token = null,
477 .extern_token = ctx.extern_token,
478 .inline_token = null,
479 .cc_token = token,
480 .async_attr = null,
481 .body_node = null,
482 .lib_name = ctx.lib_name,
483 .align_expr = null,
484 }
485 );
422 stack.append(State { .FnDef = fn_proto }) catch unreachable;486 stack.append(State { .FnDef = fn_proto }) catch unreachable;
423 try stack.append(State { .FnProto = fn_proto });487 try stack.append(State { .FnProto = fn_proto });
424 try stack.append(State {488 try stack.append(State {
...@@ -430,19 +494,33 @@ pub const Parser = struct {...@@ -430,19 +494,33 @@ pub const Parser = struct {
430 continue;494 continue;
431 },495 },
432 Token.Id.Keyword_async => {496 Token.Id.Keyword_async => {
433 // TODO shouldn't need this cast497 const async_node = try self.createNode(arena, ast.NodeAsyncAttribute,
434 const fn_proto = try self.createAttachFnProto(arena, ctx.decls, Token(undefined),498 ast.NodeAsyncAttribute {
435 ctx.extern_token, ctx.lib_name, (?Token)(null), (?Token)(null), (?Token)(null));499 .base = undefined,
436500 .async_token = token,
437 const async_node = try arena.create(ast.NodeAsyncAttribute);501 .allocator_type = null,
438 *async_node = ast.NodeAsyncAttribute {502 .rangle_bracket = null,
439 .base = self.initNode(ast.Node.Id.AsyncAttribute),503 }
440 .async_token = token,504 );
441 .allocator_type = null,
442 .rangle_bracket = null,
443 };
444505
445 fn_proto.async_attr = async_node;506 const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto,
507 ast.NodeFnProto {
508 .base = undefined,
509 .visib_token = ctx.visib_token,
510 .name_token = null,
511 .fn_token = undefined,
512 .params = ArrayList(&ast.Node).init(arena),
513 .return_type = undefined,
514 .var_args_token = null,
515 .extern_token = ctx.extern_token,
516 .inline_token = null,
517 .cc_token = null,
518 .async_attr = async_node,
519 .body_node = null,
520 .lib_name = ctx.lib_name,
521 .align_expr = null,
522 }
523 );
446 stack.append(State { .FnDef = fn_proto }) catch unreachable;524 stack.append(State { .FnDef = fn_proto }) catch unreachable;
447 try stack.append(State { .FnProto = fn_proto });525 try stack.append(State { .FnProto = fn_proto });
448 try stack.append(State {526 try stack.append(State {
...@@ -525,30 +603,29 @@ pub const Parser = struct {...@@ -525,30 +603,29 @@ pub const Parser = struct {
525603
526 State.ContainerExtern => |ctx| {604 State.ContainerExtern => |ctx| {
527 const token = self.getNextToken();605 const token = self.getNextToken();
528606 const node = try self.createToDestNode(arena, ctx.dest_ptr, ast.NodeContainerDecl,
529 const node = try arena.create(ast.NodeContainerDecl);607 ast.NodeContainerDecl {
530 *node = ast.NodeContainerDecl {608 .base = undefined,
531 .base = self.initNode(ast.Node.Id.ContainerDecl),609 .ltoken = ctx.ltoken,
532 .ltoken = ctx.ltoken,610 .layout = ctx.layout,
533 .layout = ctx.layout,611 .kind = switch (token.id) {
534 .kind = switch (token.id) {612 Token.Id.Keyword_struct => ast.NodeContainerDecl.Kind.Struct,
535 Token.Id.Keyword_struct => ast.NodeContainerDecl.Kind.Struct,613 Token.Id.Keyword_union => ast.NodeContainerDecl.Kind.Union,
536 Token.Id.Keyword_union => ast.NodeContainerDecl.Kind.Union,614 Token.Id.Keyword_enum => ast.NodeContainerDecl.Kind.Enum,
537 Token.Id.Keyword_enum => ast.NodeContainerDecl.Kind.Enum,615 else => {
538 else => {616 try self.parseError(&stack, token, "expected {}, {} or {}, found {}",
539 try self.parseError(&stack, token, "expected {}, {} or {}, found {}",617 @tagName(Token.Id.Keyword_struct),
540 @tagName(Token.Id.Keyword_struct),618 @tagName(Token.Id.Keyword_union),
541 @tagName(Token.Id.Keyword_union),619 @tagName(Token.Id.Keyword_enum),
542 @tagName(Token.Id.Keyword_enum),620 @tagName(token.id));
543 @tagName(token.id));621 continue;
544 continue;622 },
545 },623 },
546 },624 .init_arg_expr = undefined,
547 .init_arg_expr = undefined,625 .fields_and_decls = ArrayList(&ast.Node).init(arena),
548 .fields_and_decls = ArrayList(&ast.Node).init(arena),626 .rbrace_token = undefined,
549 .rbrace_token = undefined,627 }
550 };628 );
551 ctx.dest_ptr.store(&node.base);
552629
553 stack.append(State { .ContainerDecl = node }) catch unreachable;630 stack.append(State { .ContainerDecl = node }) catch unreachable;
554 try stack.append(State { .ExpectToken = Token.Id.LBrace });631 try stack.append(State { .ExpectToken = Token.Id.LBrace });
...@@ -587,13 +664,13 @@ pub const Parser = struct {...@@ -587,13 +664,13 @@ pub const Parser = struct {
587 Token.Id.Identifier => {664 Token.Id.Identifier => {
588 switch (container_decl.kind) {665 switch (container_decl.kind) {
589 ast.NodeContainerDecl.Kind.Struct => {666 ast.NodeContainerDecl.Kind.Struct => {
590 const node = try arena.create(ast.NodeStructField);667 const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.NodeStructField,
591 *node = ast.NodeStructField {668 ast.NodeStructField {
592 .base = self.initNode(ast.Node.Id.StructField),669 .base = undefined,
593 .name_token = token,670 .name_token = token,
594 .type_expr = undefined,671 .type_expr = undefined,
595 };672 }
596 try container_decl.fields_and_decls.append(&node.base);673 );
597674
598 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;675 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
599 try stack.append(State { .Expression = DestPtr { .Field = &node.type_expr } });676 try stack.append(State { .Expression = DestPtr { .Field = &node.type_expr } });
...@@ -601,13 +678,13 @@ pub const Parser = struct {...@@ -601,13 +678,13 @@ pub const Parser = struct {
601 continue;678 continue;
602 },679 },
603 ast.NodeContainerDecl.Kind.Union => {680 ast.NodeContainerDecl.Kind.Union => {
604 const node = try arena.create(ast.NodeUnionTag);681 const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.NodeUnionTag,
605 *node = ast.NodeUnionTag {682 ast.NodeUnionTag {
606 .base = self.initNode(ast.Node.Id.UnionTag),683 .base = undefined,
607 .name_token = token,684 .name_token = token,
608 .type_expr = null,685 .type_expr = null,
609 };686 }
610 try container_decl.fields_and_decls.append(&node.base);687 );
611688
612 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;689 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
613690
...@@ -621,13 +698,13 @@ pub const Parser = struct {...@@ -621,13 +698,13 @@ pub const Parser = struct {
621 continue;698 continue;
622 },699 },
623 ast.NodeContainerDecl.Kind.Enum => {700 ast.NodeContainerDecl.Kind.Enum => {
624 const node = try arena.create(ast.NodeEnumTag);701 const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.NodeEnumTag,
625 *node = ast.NodeEnumTag {702 ast.NodeEnumTag {
626 .base = self.initNode(ast.Node.Id.EnumTag),703 .base = undefined,
627 .name_token = token,704 .name_token = token,
628 .value = null,705 .value = null,
629 };706 }
630 try container_decl.fields_and_decls.append(&node.base);707 );
631708
632 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;709 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
633710
...@@ -711,17 +788,17 @@ pub const Parser = struct {...@@ -711,17 +788,17 @@ pub const Parser = struct {
711 State.Expression => |dest_ptr| {788 State.Expression => |dest_ptr| {
712 const token = self.getNextToken();789 const token = self.getNextToken();
713 switch (token.id) {790 switch (token.id) {
714 Token.Id.Keyword_try => {
715 const node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp.Try);
716 dest_ptr.store(&node.base);
717
718 stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }) catch unreachable;
719 continue;
720 },
721 Token.Id.Keyword_return => {791 Token.Id.Keyword_return => {
722 const node = try self.createControlFlowExpr(arena, token, ast.NodeControlFlowExpression.Kind.Return);792 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeControlFlowExpression,
723 dest_ptr.store(&node.base);793 ast.NodeControlFlowExpression {
794 .base = undefined,
795 .ltoken = token,
796 .kind = ast.NodeControlFlowExpression.Kind.Return,
797 .rhs = undefined,
798 }
799 );
724800
801 // TODO: Find another way to do optional expressions
725 stack.append(State {802 stack.append(State {
726 .Optional = RevertState {803 .Optional = RevertState {
727 .parser = *self,804 .parser = *self,
...@@ -732,7 +809,7 @@ pub const Parser = struct {...@@ -732,7 +809,7 @@ pub const Parser = struct {
732 try stack.append(State { .Expression = DestPtr { .NullableField = &node.rhs } });809 try stack.append(State { .Expression = DestPtr { .NullableField = &node.rhs } });
733 continue;810 continue;
734 },811 },
735 Token.Id.Keyword_break => {812 Token.Id.Keyword_break, Token.Id.Keyword_continue => {
736 const label = blk: {813 const label = blk: {
737 const colon = self.getNextToken();814 const colon = self.getNextToken();
738 if (colon.id != Token.Id.Colon) {815 if (colon.id != Token.Id.Colon) {
...@@ -743,13 +820,20 @@ pub const Parser = struct {...@@ -743,13 +820,20 @@ pub const Parser = struct {
743 break :blk (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;820 break :blk (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;
744 };821 };
745822
746 const node = try self.createControlFlowExpr(arena, token,823 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeControlFlowExpression,
747 ast.NodeControlFlowExpression.Kind {824 ast.NodeControlFlowExpression {
748 .Break = label,825 .base = undefined,
826 .ltoken = token,
827 .kind = switch (token.id) {
828 Token.Id.Keyword_break => ast.NodeControlFlowExpression.Kind { .Break = label },
829 Token.Id.Keyword_continue => ast.NodeControlFlowExpression.Kind { .Continue = label },
830 else => unreachable,
831 },
832 .rhs = undefined,
749 }833 }
750 );834 );
751 dest_ptr.store(&node.base);
752835
836 // TODO: Find another way to do optional expressions
753 stack.append(State {837 stack.append(State {
754 .Optional = RevertState {838 .Optional = RevertState {
755 .parser = *self,839 .parser = *self,
...@@ -760,59 +844,49 @@ pub const Parser = struct {...@@ -760,59 +844,49 @@ pub const Parser = struct {
760 try stack.append(State { .Expression = DestPtr { .NullableField = &node.rhs } });844 try stack.append(State { .Expression = DestPtr { .NullableField = &node.rhs } });
761 continue;845 continue;
762 },846 },
763 Token.Id.Keyword_continue => {847 Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {
764 const label = blk: {848 const node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,
765 const colon = self.getNextToken();849 ast.NodePrefixOp {
766 if (colon.id != Token.Id.Colon) {850 .base = undefined,
767 self.putBackToken(colon);851 .op_token = token,
768 break :blk null;852 .op = switch (token.id) {
769 }853 Token.Id.Keyword_try => ast.NodePrefixOp.PrefixOp { .Try = void{} },
770854 Token.Id.Keyword_cancel => ast.NodePrefixOp.PrefixOp { .Cancel = void{} },
771 break :blk (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;855 Token.Id.Keyword_resume => ast.NodePrefixOp.PrefixOp { .Resume = void{} },
772 };856 else => unreachable,
773857 },
774 const node = try self.createControlFlowExpr(arena, token,858 .rhs = undefined,
775 ast.NodeControlFlowExpression.Kind {
776 .Continue = label,
777 }859 }
778 );860 );
779 dest_ptr.store(&node.base);861
862 stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }) catch unreachable;
780 continue;863 continue;
781 },864 },
782 Token.Id.Keyword_cancel => {
783 const cancel_node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp.Cancel);
784 dest_ptr.store(&cancel_node.base);
785 stack.append(State { .Expression = DestPtr { .Field = &cancel_node.rhs } }) catch unreachable;
786 },
787 Token.Id.Keyword_resume => {
788 const resume_node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp.Resume);
789 dest_ptr.store(&resume_node.base);
790 stack.append(State { .Expression = DestPtr { .Field = &resume_node.rhs } }) catch unreachable;
791 },
792 Token.Id.Keyword_suspend => {865 Token.Id.Keyword_suspend => {
793 const node = try arena.create(ast.NodeSuspend);866 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuspend,
794 *node = ast.NodeSuspend {867 ast.NodeSuspend {
795 .base = self.initNode(ast.Node.Id.Suspend),868 .base = undefined,
796 .suspend_token = token,869 .suspend_token = token,
797 .payload = null,870 .payload = null,
798 .body = null,871 .body = null,
799 };872 }
800 dest_ptr.store(&node.base);873 );
874
801 stack.append(State { .SuspendBody = node }) catch unreachable;875 stack.append(State { .SuspendBody = node }) catch unreachable;
802 try stack.append(State { .Payload = &node.payload });876 try stack.append(State { .Payload = &node.payload });
803 continue;877 continue;
804 },878 },
805 Token.Id.Keyword_if => {879 Token.Id.Keyword_if => {
806 const node = try arena.create(ast.NodeIf);880 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeIf,
807 *node = ast.NodeIf {881 ast.NodeIf {
808 .base = self.initNode(ast.Node.Id.If),882 .base = undefined,
809 .if_token = token,883 .if_token = token,
810 .condition = undefined,884 .condition = undefined,
811 .payload = null,885 .payload = null,
812 .body = undefined,886 .body = undefined,
813 .@"else" = null,887 .@"else" = null,
814 };888 }
815 dest_ptr.store(&node.base);889 );
816890
817 stack.append(State { .Else = &node.@"else" }) catch unreachable;891 stack.append(State { .Else = &node.@"else" }) catch unreachable;
818 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });892 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
...@@ -845,15 +919,15 @@ pub const Parser = struct {...@@ -845,15 +919,15 @@ pub const Parser = struct {
845 continue;919 continue;
846 },920 },
847 Token.Id.Keyword_switch => {921 Token.Id.Keyword_switch => {
848 const node = try arena.create(ast.NodeSwitch);922 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSwitch,
849 *node = ast.NodeSwitch {923 ast.NodeSwitch {
850 .base = self.initNode(ast.Node.Id.Switch),924 .base = undefined,
851 .switch_token = token,925 .switch_token = token,
852 .expr = undefined,926 .expr = undefined,
853 .cases = ArrayList(&ast.NodeSwitchCase).init(arena),927 .cases = ArrayList(&ast.NodeSwitchCase).init(arena),
854 .rbrace = undefined,928 .rbrace = undefined,
855 };929 }
856 dest_ptr.store(&node.base);930 );
857931
858 stack.append(State {932 stack.append(State {
859 .SwitchCaseOrEnd = ListSave(&ast.NodeSwitchCase) {933 .SwitchCaseOrEnd = ListSave(&ast.NodeSwitchCase) {
...@@ -867,20 +941,26 @@ pub const Parser = struct {...@@ -867,20 +941,26 @@ pub const Parser = struct {
867 try stack.append(State { .ExpectToken = Token.Id.LParen });941 try stack.append(State { .ExpectToken = Token.Id.LParen });
868 },942 },
869 Token.Id.Keyword_comptime => {943 Token.Id.Keyword_comptime => {
870 const node = try arena.create(ast.NodeComptime);944 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeComptime,
871 *node = ast.NodeComptime {945 ast.NodeComptime {
872 .base = self.initNode(ast.Node.Id.Comptime),946 .base = undefined,
873 .comptime_token = token,947 .comptime_token = token,
874 .expr = undefined,948 .expr = undefined,
875 };949 }
876 dest_ptr.store(&node.base);950 );
877 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });951 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
878 continue;952 continue;
879 },953 },
880 Token.Id.LBrace => {954 Token.Id.LBrace => {
881 const block = try self.createBlock(arena, (?Token)(null), token);955 const block = try self.createToDestNode(arena, dest_ptr, ast.NodeBlock,
882 dest_ptr.store(&block.base);956 ast.NodeBlock {
883957 .base = undefined,
958 .label = null,
959 .lbrace = token,
960 .statements = ArrayList(&ast.Node).init(arena),
961 .rbrace = undefined,
962 }
963 );
884 stack.append(State { .Block = block }) catch unreachable;964 stack.append(State { .Block = block }) catch unreachable;
885 continue;965 continue;
886 },966 },
...@@ -901,10 +981,15 @@ pub const Parser = struct {...@@ -901,10 +981,15 @@ pub const Parser = struct {
901 State.RangeExpressionEnd => |dest_ptr| {981 State.RangeExpressionEnd => |dest_ptr| {
902 const token = self.getNextToken();982 const token = self.getNextToken();
903 if (token.id == Token.Id.Ellipsis3) {983 if (token.id == Token.Id.Ellipsis3) {
904 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.Range);984 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
905 node.lhs = dest_ptr.get();985 ast.NodeInfixOp {
906 dest_ptr.store(&node.base);986 .base = undefined,
907987 .lhs = dest_ptr.get(),
988 .op_token = token,
989 .op = ast.NodeInfixOp.InfixOp.Range,
990 .rhs = undefined,
991 }
992 );
908 stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }) catch unreachable;993 stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }) catch unreachable;
909 continue;994 continue;
910 } else {995 } else {
...@@ -922,10 +1007,15 @@ pub const Parser = struct {...@@ -922,10 +1007,15 @@ pub const Parser = struct {
922 State.AssignmentExpressionEnd => |dest_ptr| {1007 State.AssignmentExpressionEnd => |dest_ptr| {
923 const token = self.getNextToken();1008 const token = self.getNextToken();
924 if (tokenIdToAssignment(token.id)) |ass_id| {1009 if (tokenIdToAssignment(token.id)) |ass_id| {
925 const node = try self.createInfixOp(arena, token, ass_id);1010 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
926 node.lhs = dest_ptr.get();1011 ast.NodeInfixOp {
927 dest_ptr.store(&node.base);1012 .base = undefined,
9281013 .lhs = dest_ptr.get(),
1014 .op_token = token,
1015 .op = ass_id,
1016 .rhs = undefined,
1017 }
1018 );
929 stack.append(State { .AssignmentExpressionEnd = dest_ptr }) catch unreachable;1019 stack.append(State { .AssignmentExpressionEnd = dest_ptr }) catch unreachable;
930 try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } });1020 try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } });
931 continue;1021 continue;
...@@ -944,23 +1034,27 @@ pub const Parser = struct {...@@ -944,23 +1034,27 @@ pub const Parser = struct {
944 State.UnwrapExpressionEnd => |dest_ptr| {1034 State.UnwrapExpressionEnd => |dest_ptr| {
945 const token = self.getNextToken();1035 const token = self.getNextToken();
946 switch (token.id) {1036 switch (token.id) {
947 Token.Id.Keyword_catch => {1037 Token.Id.Keyword_catch, Token.Id.QuestionMarkQuestionMark => {
948 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp { .Catch = null });1038 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
949 node.lhs = dest_ptr.get();1039 ast.NodeInfixOp {
950 dest_ptr.store(&node.base);1040 .base = undefined,
1041 .lhs = dest_ptr.get(),
1042 .op_token = token,
1043 .op = switch (token.id) {
1044 Token.Id.Keyword_catch => ast.NodeInfixOp.InfixOp { .Catch = null },
1045 Token.Id.QuestionMarkQuestionMark => ast.NodeInfixOp.InfixOp { .UnwrapMaybe = void{} },
1046 else => unreachable,
1047 },
1048 .rhs = undefined,
1049 }
1050 );
9511051
952 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;1052 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;
953 try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } });1053 try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } });
954 try stack.append(State { .Payload = &node.op.Catch });
955 continue;
956 },
957 Token.Id.QuestionMarkQuestionMark => {
958 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.UnwrapMaybe);
959 node.lhs = dest_ptr.get();
960 dest_ptr.store(&node.base);
9611054
962 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;1055 if (node.op == ast.NodeInfixOp.InfixOp.Catch) {
963 try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } });1056 try stack.append(State { .Payload = &node.op.Catch });
1057 }
964 continue;1058 continue;
965 },1059 },
966 else => {1060 else => {
...@@ -980,10 +1074,15 @@ pub const Parser = struct {...@@ -980,10 +1074,15 @@ pub const Parser = struct {
980 const token = self.getNextToken();1074 const token = self.getNextToken();
981 switch (token.id) {1075 switch (token.id) {
982 Token.Id.Keyword_or => {1076 Token.Id.Keyword_or => {
983 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.BoolOr);1077 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
984 node.lhs = dest_ptr.get();1078 ast.NodeInfixOp {
985 dest_ptr.store(&node.base);1079 .base = undefined,
9861080 .lhs = dest_ptr.get(),
1081 .op_token = token,
1082 .op = ast.NodeInfixOp.InfixOp.BoolOr,
1083 .rhs = undefined,
1084 }
1085 );
987 stack.append(State { .BoolOrExpressionEnd = dest_ptr }) catch unreachable;1086 stack.append(State { .BoolOrExpressionEnd = dest_ptr }) catch unreachable;
988 try stack.append(State { .BoolAndExpressionBegin = DestPtr { .Field = &node.rhs } });1087 try stack.append(State { .BoolAndExpressionBegin = DestPtr { .Field = &node.rhs } });
989 continue;1088 continue;
...@@ -1005,10 +1104,15 @@ pub const Parser = struct {...@@ -1005,10 +1104,15 @@ pub const Parser = struct {
1005 const token = self.getNextToken();1104 const token = self.getNextToken();
1006 switch (token.id) {1105 switch (token.id) {
1007 Token.Id.Keyword_and => {1106 Token.Id.Keyword_and => {
1008 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.BoolAnd);1107 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1009 node.lhs = dest_ptr.get();1108 ast.NodeInfixOp {
1010 dest_ptr.store(&node.base);1109 .base = undefined,
10111110 .lhs = dest_ptr.get(),
1111 .op_token = token,
1112 .op = ast.NodeInfixOp.InfixOp.BoolAnd,
1113 .rhs = undefined,
1114 }
1115 );
1012 stack.append(State { .BoolAndExpressionEnd = dest_ptr }) catch unreachable;1116 stack.append(State { .BoolAndExpressionEnd = dest_ptr }) catch unreachable;
1013 try stack.append(State { .ComparisonExpressionBegin = DestPtr { .Field = &node.rhs } });1117 try stack.append(State { .ComparisonExpressionBegin = DestPtr { .Field = &node.rhs } });
1014 continue;1118 continue;
...@@ -1029,10 +1133,15 @@ pub const Parser = struct {...@@ -1029,10 +1133,15 @@ pub const Parser = struct {
1029 State.ComparisonExpressionEnd => |dest_ptr| {1133 State.ComparisonExpressionEnd => |dest_ptr| {
1030 const token = self.getNextToken();1134 const token = self.getNextToken();
1031 if (tokenIdToComparison(token.id)) |comp_id| {1135 if (tokenIdToComparison(token.id)) |comp_id| {
1032 const node = try self.createInfixOp(arena, token, comp_id);1136 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1033 node.lhs = dest_ptr.get();1137 ast.NodeInfixOp {
1034 dest_ptr.store(&node.base);1138 .base = undefined,
10351139 .lhs = dest_ptr.get(),
1140 .op_token = token,
1141 .op = comp_id,
1142 .rhs = undefined,
1143 }
1144 );
1036 stack.append(State { .ComparisonExpressionEnd = dest_ptr }) catch unreachable;1145 stack.append(State { .ComparisonExpressionEnd = dest_ptr }) catch unreachable;
1037 try stack.append(State { .BinaryOrExpressionBegin = DestPtr { .Field = &node.rhs } });1146 try stack.append(State { .BinaryOrExpressionBegin = DestPtr { .Field = &node.rhs } });
1038 continue;1147 continue;
...@@ -1052,10 +1161,15 @@ pub const Parser = struct {...@@ -1052,10 +1161,15 @@ pub const Parser = struct {
1052 const token = self.getNextToken();1161 const token = self.getNextToken();
1053 switch (token.id) {1162 switch (token.id) {
1054 Token.Id.Pipe => {1163 Token.Id.Pipe => {
1055 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.BitOr);1164 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1056 node.lhs = dest_ptr.get();1165 ast.NodeInfixOp {
1057 dest_ptr.store(&node.base);1166 .base = undefined,
10581167 .lhs = dest_ptr.get(),
1168 .op_token = token,
1169 .op = ast.NodeInfixOp.InfixOp.BitOr,
1170 .rhs = undefined,
1171 }
1172 );
1059 stack.append(State { .BinaryOrExpressionEnd = dest_ptr }) catch unreachable;1173 stack.append(State { .BinaryOrExpressionEnd = dest_ptr }) catch unreachable;
1060 try stack.append(State { .BinaryXorExpressionBegin = DestPtr { .Field = &node.rhs } });1174 try stack.append(State { .BinaryXorExpressionBegin = DestPtr { .Field = &node.rhs } });
1061 continue;1175 continue;
...@@ -1077,10 +1191,15 @@ pub const Parser = struct {...@@ -1077,10 +1191,15 @@ pub const Parser = struct {
1077 const token = self.getNextToken();1191 const token = self.getNextToken();
1078 switch (token.id) {1192 switch (token.id) {
1079 Token.Id.Caret => {1193 Token.Id.Caret => {
1080 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.BitXor);1194 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1081 node.lhs = dest_ptr.get();1195 ast.NodeInfixOp {
1082 dest_ptr.store(&node.base);1196 .base = undefined,
10831197 .lhs = dest_ptr.get(),
1198 .op_token = token,
1199 .op = ast.NodeInfixOp.InfixOp.BitXor,
1200 .rhs = undefined,
1201 }
1202 );
1084 stack.append(State { .BinaryXorExpressionEnd = dest_ptr }) catch unreachable;1203 stack.append(State { .BinaryXorExpressionEnd = dest_ptr }) catch unreachable;
1085 try stack.append(State { .BinaryAndExpressionBegin = DestPtr { .Field = &node.rhs } });1204 try stack.append(State { .BinaryAndExpressionBegin = DestPtr { .Field = &node.rhs } });
1086 continue;1205 continue;
...@@ -1102,10 +1221,15 @@ pub const Parser = struct {...@@ -1102,10 +1221,15 @@ pub const Parser = struct {
1102 const token = self.getNextToken();1221 const token = self.getNextToken();
1103 switch (token.id) {1222 switch (token.id) {
1104 Token.Id.Ampersand => {1223 Token.Id.Ampersand => {
1105 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.BitAnd);1224 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1106 node.lhs = dest_ptr.get();1225 ast.NodeInfixOp {
1107 dest_ptr.store(&node.base);1226 .base = undefined,
11081227 .lhs = dest_ptr.get(),
1228 .op_token = token,
1229 .op = ast.NodeInfixOp.InfixOp.BitAnd,
1230 .rhs = undefined,
1231 }
1232 );
1109 stack.append(State { .BinaryAndExpressionEnd = dest_ptr }) catch unreachable;1233 stack.append(State { .BinaryAndExpressionEnd = dest_ptr }) catch unreachable;
1110 try stack.append(State { .BitShiftExpressionBegin = DestPtr { .Field = &node.rhs } });1234 try stack.append(State { .BitShiftExpressionBegin = DestPtr { .Field = &node.rhs } });
1111 continue;1235 continue;
...@@ -1126,10 +1250,15 @@ pub const Parser = struct {...@@ -1126,10 +1250,15 @@ pub const Parser = struct {
1126 State.BitShiftExpressionEnd => |dest_ptr| {1250 State.BitShiftExpressionEnd => |dest_ptr| {
1127 const token = self.getNextToken();1251 const token = self.getNextToken();
1128 if (tokenIdToBitShift(token.id)) |bitshift_id| {1252 if (tokenIdToBitShift(token.id)) |bitshift_id| {
1129 const node = try self.createInfixOp(arena, token, bitshift_id);1253 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1130 node.lhs = dest_ptr.get();1254 ast.NodeInfixOp {
1131 dest_ptr.store(&node.base);1255 .base = undefined,
11321256 .lhs = dest_ptr.get(),
1257 .op_token = token,
1258 .op = bitshift_id,
1259 .rhs = undefined,
1260 }
1261 );
1133 stack.append(State { .BitShiftExpressionEnd = dest_ptr }) catch unreachable;1262 stack.append(State { .BitShiftExpressionEnd = dest_ptr }) catch unreachable;
1134 try stack.append(State { .AdditionExpressionBegin = DestPtr { .Field = &node.rhs } });1263 try stack.append(State { .AdditionExpressionBegin = DestPtr { .Field = &node.rhs } });
1135 continue;1264 continue;
...@@ -1148,10 +1277,15 @@ pub const Parser = struct {...@@ -1148,10 +1277,15 @@ pub const Parser = struct {
1148 State.AdditionExpressionEnd => |dest_ptr| {1277 State.AdditionExpressionEnd => |dest_ptr| {
1149 const token = self.getNextToken();1278 const token = self.getNextToken();
1150 if (tokenIdToAddition(token.id)) |add_id| {1279 if (tokenIdToAddition(token.id)) |add_id| {
1151 const node = try self.createInfixOp(arena, token, add_id);1280 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1152 node.lhs = dest_ptr.get();1281 ast.NodeInfixOp {
1153 dest_ptr.store(&node.base);1282 .base = undefined,
11541283 .lhs = dest_ptr.get(),
1284 .op_token = token,
1285 .op = add_id,
1286 .rhs = undefined,
1287 }
1288 );
1155 stack.append(State { .AdditionExpressionEnd = dest_ptr }) catch unreachable;1289 stack.append(State { .AdditionExpressionEnd = dest_ptr }) catch unreachable;
1156 try stack.append(State { .MultiplyExpressionBegin = DestPtr { .Field = &node.rhs } });1290 try stack.append(State { .MultiplyExpressionBegin = DestPtr { .Field = &node.rhs } });
1157 continue;1291 continue;
...@@ -1170,10 +1304,15 @@ pub const Parser = struct {...@@ -1170,10 +1304,15 @@ pub const Parser = struct {
1170 State.MultiplyExpressionEnd => |dest_ptr| {1304 State.MultiplyExpressionEnd => |dest_ptr| {
1171 const token = self.getNextToken();1305 const token = self.getNextToken();
1172 if (tokenIdToMultiply(token.id)) |mult_id| {1306 if (tokenIdToMultiply(token.id)) |mult_id| {
1173 const node = try self.createInfixOp(arena, token, mult_id);1307 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1174 node.lhs = dest_ptr.get();1308 ast.NodeInfixOp {
1175 dest_ptr.store(&node.base);1309 .base = undefined,
11761310 .lhs = dest_ptr.get(),
1311 .op_token = token,
1312 .op = mult_id,
1313 .rhs = undefined,
1314 }
1315 );
1177 stack.append(State { .MultiplyExpressionEnd = dest_ptr }) catch unreachable;1316 stack.append(State { .MultiplyExpressionEnd = dest_ptr }) catch unreachable;
1178 try stack.append(State { .CurlySuffixExpressionBegin = DestPtr { .Field = &node.rhs } });1317 try stack.append(State { .CurlySuffixExpressionBegin = DestPtr { .Field = &node.rhs } });
1179 continue;1318 continue;
...@@ -1199,12 +1338,16 @@ pub const Parser = struct {...@@ -1199,12 +1338,16 @@ pub const Parser = struct {
1199 const next = self.getNextToken();1338 const next = self.getNextToken();
1200 switch (next.id) {1339 switch (next.id) {
1201 Token.Id.Period => {1340 Token.Id.Period => {
1202 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {1341 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuffixOp,
1203 .StructInitializer = ArrayList(&ast.NodeFieldInitializer).init(arena),1342 ast.NodeSuffixOp {
1204 });1343 .base = undefined,
1205 node.lhs = dest_ptr.get();1344 .lhs = dest_ptr.get(),
1206 dest_ptr.store(&node.base);1345 .op = ast.NodeSuffixOp.SuffixOp {
12071346 .StructInitializer = ArrayList(&ast.NodeFieldInitializer).init(arena),
1347 },
1348 .rtoken = undefined,
1349 }
1350 );
1208 stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable;1351 stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable;
1209 try stack.append(State {1352 try stack.append(State {
1210 .FieldInitListItemOrEnd = ListSave(&ast.NodeFieldInitializer) {1353 .FieldInitListItemOrEnd = ListSave(&ast.NodeFieldInitializer) {
...@@ -1216,12 +1359,16 @@ pub const Parser = struct {...@@ -1216,12 +1359,16 @@ pub const Parser = struct {
1216 continue;1359 continue;
1217 },1360 },
1218 else => {1361 else => {
1219 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {1362 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuffixOp,
1220 .ArrayInitializer = ArrayList(&ast.Node).init(arena),1363 ast.NodeSuffixOp {
1221 });1364 .base = undefined,
1222 node.lhs = dest_ptr.get();1365 .lhs = dest_ptr.get(),
1223 dest_ptr.store(&node.base);1366 .op = ast.NodeSuffixOp.SuffixOp {
12241367 .ArrayInitializer = ArrayList(&ast.Node).init(arena),
1368 },
1369 .rtoken = undefined,
1370 }
1371 );
1225 stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable;1372 stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable;
1226 try stack.append(State {1373 try stack.append(State {
1227 .ExprListItemOrEnd = ExprListCtx {1374 .ExprListItemOrEnd = ExprListCtx {
...@@ -1246,10 +1393,15 @@ pub const Parser = struct {...@@ -1246,10 +1393,15 @@ pub const Parser = struct {
1246 const token = self.getNextToken();1393 const token = self.getNextToken();
1247 switch (token.id) {1394 switch (token.id) {
1248 Token.Id.Bang => {1395 Token.Id.Bang => {
1249 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.ErrorUnion);1396 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1250 node.lhs = dest_ptr.get();1397 ast.NodeInfixOp {
1251 dest_ptr.store(&node.base);1398 .base = undefined,
12521399 .lhs = dest_ptr.get(),
1400 .op_token = token,
1401 .op = ast.NodeInfixOp.InfixOp.ErrorUnion,
1402 .rhs = undefined,
1403 }
1404 );
1253 stack.append(State { .TypeExprEnd = dest_ptr }) catch unreachable;1405 stack.append(State { .TypeExprEnd = dest_ptr }) catch unreachable;
1254 try stack.append(State { .PrefixOpExpression = DestPtr { .Field = &node.rhs } });1406 try stack.append(State { .PrefixOpExpression = DestPtr { .Field = &node.rhs } });
1255 continue;1407 continue;
...@@ -1264,9 +1416,14 @@ pub const Parser = struct {...@@ -1264,9 +1416,14 @@ pub const Parser = struct {
1264 State.PrefixOpExpression => |dest_ptr| {1416 State.PrefixOpExpression => |dest_ptr| {
1265 const token = self.getNextToken();1417 const token = self.getNextToken();
1266 if (tokenIdToPrefixOp(token.id)) |prefix_id| {1418 if (tokenIdToPrefixOp(token.id)) |prefix_id| {
1267 const node = try self.createPrefixOp(arena, token, prefix_id);1419 const node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,
1268 dest_ptr.store(&node.base);1420 ast.NodePrefixOp {
12691421 .base = undefined,
1422 .op_token = token,
1423 .op = prefix_id,
1424 .rhs = undefined,
1425 }
1426 );
1270 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;1427 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;
1271 if (node.op == ast.NodePrefixOp.PrefixOp.AddrOf) {1428 if (node.op == ast.NodePrefixOp.PrefixOp.AddrOf) {
1272 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });1429 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });
...@@ -1283,14 +1440,14 @@ pub const Parser = struct {...@@ -1283,14 +1440,14 @@ pub const Parser = struct {
1283 const token = self.getNextToken();1440 const token = self.getNextToken();
1284 switch (token.id) {1441 switch (token.id) {
1285 Token.Id.Keyword_async => {1442 Token.Id.Keyword_async => {
1286 const async_node = try arena.create(ast.NodeAsyncAttribute);1443 const async_node = try self.createNode(arena, ast.NodeAsyncAttribute,
1287 *async_node = ast.NodeAsyncAttribute {1444 ast.NodeAsyncAttribute {
1288 .base = self.initNode(ast.Node.Id.AsyncAttribute),1445 .base = undefined,
1289 .async_token = token,1446 .async_token = token,
1290 .allocator_type = null,1447 .allocator_type = null,
1291 .rangle_bracket = null,1448 .rangle_bracket = null,
1292 };1449 }
12931450 );
1294 stack.append(State {1451 stack.append(State {
1295 .AsyncEnd = AsyncEndCtx {1452 .AsyncEnd = AsyncEndCtx {
1296 .dest_ptr = dest_ptr,1453 .dest_ptr = dest_ptr,
...@@ -1329,15 +1486,19 @@ pub const Parser = struct {...@@ -1329,15 +1486,19 @@ pub const Parser = struct {
1329 const token = self.getNextToken();1486 const token = self.getNextToken();
1330 switch (token.id) {1487 switch (token.id) {
1331 Token.Id.LParen => {1488 Token.Id.LParen => {
1332 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {1489 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuffixOp,
1333 .Call = ast.NodeSuffixOp.CallInfo {1490 ast.NodeSuffixOp {
1334 .params = ArrayList(&ast.Node).init(arena),1491 .base = undefined,
1335 .async_attr = null,1492 .lhs = dest_ptr.get(),
1493 .op = ast.NodeSuffixOp.SuffixOp {
1494 .Call = ast.NodeSuffixOp.CallInfo {
1495 .params = ArrayList(&ast.Node).init(arena),
1496 .async_attr = null,
1497 }
1498 },
1499 .rtoken = undefined,
1336 }1500 }
1337 });1501 );
1338 node.lhs = dest_ptr.get();
1339 dest_ptr.store(&node.base);
1340
1341 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;1502 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1342 try stack.append(State {1503 try stack.append(State {
1343 .ExprListItemOrEnd = ExprListCtx {1504 .ExprListItemOrEnd = ExprListCtx {
...@@ -1349,28 +1510,31 @@ pub const Parser = struct {...@@ -1349,28 +1510,31 @@ pub const Parser = struct {
1349 continue;1510 continue;
1350 },1511 },
1351 Token.Id.LBracket => {1512 Token.Id.LBracket => {
1352 const node = try arena.create(ast.NodeSuffixOp);1513 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuffixOp,
1353 *node = ast.NodeSuffixOp {1514 ast.NodeSuffixOp {
1354 .base = self.initNode(ast.Node.Id.SuffixOp),1515 .base = undefined,
1355 .lhs = undefined,1516 .lhs = dest_ptr.get(),
1356 .op = ast.NodeSuffixOp.SuffixOp {1517 .op = ast.NodeSuffixOp.SuffixOp {
1357 .ArrayAccess = undefined,1518 .ArrayAccess = undefined,
1358 },1519 },
1359 .rtoken = undefined,1520 .rtoken = undefined
1360 };1521 }
1361 node.lhs = dest_ptr.get();1522 );
1362 dest_ptr.store(&node.base);
1363
1364 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;1523 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1365 try stack.append(State { .SliceOrArrayAccess = node });1524 try stack.append(State { .SliceOrArrayAccess = node });
1366 try stack.append(State { .Expression = DestPtr { .Field = &node.op.ArrayAccess }});1525 try stack.append(State { .Expression = DestPtr { .Field = &node.op.ArrayAccess }});
1367 continue;1526 continue;
1368 },1527 },
1369 Token.Id.Period => {1528 Token.Id.Period => {
1370 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.Period);1529 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1371 node.lhs = dest_ptr.get();1530 ast.NodeInfixOp {
1372 dest_ptr.store(&node.base);1531 .base = undefined,
13731532 .lhs = dest_ptr.get(),
1533 .op_token = token,
1534 .op = ast.NodeInfixOp.InfixOp.Period,
1535 .rhs = undefined,
1536 }
1537 );
1374 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;1538 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1375 try stack.append(State { .SuffixOpExpressionBegin = DestPtr { .Field = &node.rhs }});1539 try stack.append(State { .SuffixOpExpressionBegin = DestPtr { .Field = &node.rhs }});
1376 continue;1540 continue;
...@@ -1386,83 +1550,53 @@ pub const Parser = struct {...@@ -1386,83 +1550,53 @@ pub const Parser = struct {
1386 const token = self.getNextToken();1550 const token = self.getNextToken();
1387 switch (token.id) {1551 switch (token.id) {
1388 Token.Id.IntegerLiteral => {1552 Token.Id.IntegerLiteral => {
1389 dest_ptr.store(&(try self.createIntegerLiteral(arena, token)).base);1553 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeStringLiteral, token)).base);
1390 continue;1554 continue;
1391 },1555 },
1392 Token.Id.FloatLiteral => {1556 Token.Id.FloatLiteral => {
1393 dest_ptr.store(&(try self.createFloatLiteral(arena, token)).base);1557 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeFloatLiteral, token)).base);
1394 continue;1558 continue;
1395 },1559 },
1396 Token.Id.StringLiteral => {1560 Token.Id.StringLiteral => {
1397 dest_ptr.store(&(try self.createStringLiteral(arena, token)).base);1561 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeStringLiteral, token)).base);
1398 continue;1562 continue;
1399 },1563 },
1400 Token.Id.CharLiteral => {1564 Token.Id.CharLiteral => {
1401 const node = try arena.create(ast.NodeCharLiteral);1565 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeCharLiteral, token)).base);
1402 *node = ast.NodeCharLiteral {
1403 .base = self.initNode(ast.Node.Id.CharLiteral),
1404 .token = token,
1405 };
1406 dest_ptr.store(&node.base);
1407 continue;1566 continue;
1408 },1567 },
1409 Token.Id.Keyword_undefined => {1568 Token.Id.Keyword_undefined => {
1410 dest_ptr.store(&(try self.createUndefined(arena, token)).base);1569 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeUndefinedLiteral, token)).base);
1411 continue;1570 continue;
1412 },1571 },
1413 Token.Id.Keyword_true, Token.Id.Keyword_false => {1572 Token.Id.Keyword_true, Token.Id.Keyword_false => {
1414 const node = try arena.create(ast.NodeBoolLiteral);1573 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeBoolLiteral, token)).base);
1415 *node = ast.NodeBoolLiteral {
1416 .base = self.initNode(ast.Node.Id.BoolLiteral),
1417 .token = token,
1418 };
1419 dest_ptr.store(&node.base);
1420 continue;1574 continue;
1421 },1575 },
1422 Token.Id.Keyword_null => {1576 Token.Id.Keyword_null => {
1423 const node = try arena.create(ast.NodeNullLiteral);1577 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeNullLiteral, token)).base);
1424 *node = ast.NodeNullLiteral {
1425 .base = self.initNode(ast.Node.Id.NullLiteral),
1426 .token = token,
1427 };
1428 dest_ptr.store(&node.base);
1429 continue;1578 continue;
1430 },1579 },
1431 Token.Id.Keyword_this => {1580 Token.Id.Keyword_this => {
1432 const node = try arena.create(ast.NodeThisLiteral);1581 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeThisLiteral, token)).base);
1433 *node = ast.NodeThisLiteral {
1434 .base = self.initNode(ast.Node.Id.ThisLiteral),
1435 .token = token,
1436 };
1437 dest_ptr.store(&node.base);
1438 continue;1582 continue;
1439 },1583 },
1440 Token.Id.Keyword_var => {1584 Token.Id.Keyword_var => {
1441 const node = try arena.create(ast.NodeVarType);1585 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeVarType, token)).base);
1442 *node = ast.NodeVarType {1586 continue;
1443 .base = self.initNode(ast.Node.Id.VarType),
1444 .token = token,
1445 };
1446 dest_ptr.store(&node.base);
1447 },1587 },
1448 Token.Id.Keyword_unreachable => {1588 Token.Id.Keyword_unreachable => {
1449 const node = try arena.create(ast.NodeUnreachable);1589 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeUnreachable, token)).base);
1450 *node = ast.NodeUnreachable {
1451 .base = self.initNode(ast.Node.Id.Unreachable),
1452 .token = token,
1453 };
1454 dest_ptr.store(&node.base);
1455 continue;1590 continue;
1456 },1591 },
1457 Token.Id.MultilineStringLiteralLine => {1592 Token.Id.MultilineStringLiteralLine => {
1458 const node = try arena.create(ast.NodeMultilineStringLiteral);1593 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeMultilineStringLiteral,
1459 *node = ast.NodeMultilineStringLiteral {1594 ast.NodeMultilineStringLiteral {
1460 .base = self.initNode(ast.Node.Id.MultilineStringLiteral),1595 .base = undefined,
1461 .tokens = ArrayList(Token).init(arena),1596 .tokens = ArrayList(Token).init(arena),
1462 };1597 }
1463 dest_ptr.store(&node.base);1598 );
1464 try node.tokens.append(token);1599 try node.tokens.append(token);
1465
1466 while (true) {1600 while (true) {
1467 const multiline_str = self.getNextToken();1601 const multiline_str = self.getNextToken();
1468 if (multiline_str.id != Token.Id.MultilineStringLiteralLine) {1602 if (multiline_str.id != Token.Id.MultilineStringLiteralLine) {
...@@ -1475,14 +1609,14 @@ pub const Parser = struct {...@@ -1475,14 +1609,14 @@ pub const Parser = struct {
1475 continue;1609 continue;
1476 },1610 },
1477 Token.Id.LParen => {1611 Token.Id.LParen => {
1478 const node = try arena.create(ast.NodeGroupedExpression);1612 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeGroupedExpression,
1479 *node = ast.NodeGroupedExpression {1613 ast.NodeGroupedExpression {
1480 .base = self.initNode(ast.Node.Id.GroupedExpression),1614 .base = undefined,
1481 .lparen = token,1615 .lparen = token,
1482 .expr = undefined,1616 .expr = undefined,
1483 .rparen = undefined,1617 .rparen = undefined,
1484 };1618 }
1485 dest_ptr.store(&node.base);1619 );
1486 stack.append(State {1620 stack.append(State {
1487 .ExpectTokenSave = ExpectTokenSave {1621 .ExpectTokenSave = ExpectTokenSave {
1488 .id = Token.Id.RParen,1622 .id = Token.Id.RParen,
...@@ -1493,14 +1627,14 @@ pub const Parser = struct {...@@ -1493,14 +1627,14 @@ pub const Parser = struct {
1493 continue;1627 continue;
1494 },1628 },
1495 Token.Id.Builtin => {1629 Token.Id.Builtin => {
1496 const node = try arena.create(ast.NodeBuiltinCall);1630 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeBuiltinCall,
1497 *node = ast.NodeBuiltinCall {1631 ast.NodeBuiltinCall {
1498 .base = self.initNode(ast.Node.Id.BuiltinCall),1632 .base = undefined,
1499 .builtin_token = token,1633 .builtin_token = token,
1500 .params = ArrayList(&ast.Node).init(arena),1634 .params = ArrayList(&ast.Node).init(arena),
1501 .rparen_token = undefined,1635 .rparen_token = undefined,
1502 };1636 }
1503 dest_ptr.store(&node.base);1637 );
1504 stack.append(State {1638 stack.append(State {
1505 .ExprListItemOrEnd = ExprListCtx {1639 .ExprListItemOrEnd = ExprListCtx {
1506 .list = &node.params,1640 .list = &node.params,
...@@ -1514,15 +1648,22 @@ pub const Parser = struct {...@@ -1514,15 +1648,22 @@ pub const Parser = struct {
1514 Token.Id.LBracket => {1648 Token.Id.LBracket => {
1515 const rbracket_token = self.getNextToken();1649 const rbracket_token = self.getNextToken();
1516 if (rbracket_token.id == Token.Id.RBracket) {1650 if (rbracket_token.id == Token.Id.RBracket) {
1517 const node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp{1651 const node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,
1518 .SliceType = ast.NodePrefixOp.AddrOfInfo {1652 ast.NodePrefixOp {
1519 .align_expr = null,1653 .base = undefined,
1520 .bit_offset_start_token = null,1654 .op_token = token,
1521 .bit_offset_end_token = null,1655 .op = ast.NodePrefixOp.PrefixOp{
1522 .const_token = null,1656 .SliceType = ast.NodePrefixOp.AddrOfInfo {
1523 .volatile_token = null,1657 .align_expr = null,
1658 .bit_offset_start_token = null,
1659 .bit_offset_end_token = null,
1660 .const_token = null,
1661 .volatile_token = null,
1662 }
1663 },
1664 .rhs = undefined,
1524 }1665 }
1525 });1666 );
1526 dest_ptr.store(&node.base);1667 dest_ptr.store(&node.base);
1527 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;1668 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;
1528 try stack.append(State { .AddrOfModifiers = &node.op.SliceType });1669 try stack.append(State { .AddrOfModifiers = &node.op.SliceType });
...@@ -1531,10 +1672,16 @@ pub const Parser = struct {...@@ -1531,10 +1672,16 @@ pub const Parser = struct {
15311672
1532 self.putBackToken(rbracket_token);1673 self.putBackToken(rbracket_token);
15331674
1534 const node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp{1675 const node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,
1535 .ArrayType = undefined,1676 ast.NodePrefixOp {
1536 });1677 .base = undefined,
1537 dest_ptr.store(&node.base);1678 .op_token = token,
1679 .op = ast.NodePrefixOp.PrefixOp{
1680 .ArrayType = undefined,
1681 },
1682 .rhs = undefined,
1683 }
1684 );
1538 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;1685 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;
1539 try stack.append(State { .ExpectToken = Token.Id.RBracket });1686 try stack.append(State { .ExpectToken = Token.Id.RBracket });
1540 try stack.append(State { .Expression = DestPtr { .Field = &node.op.ArrayType } });1687 try stack.append(State { .Expression = DestPtr { .Field = &node.op.ArrayType } });
...@@ -1544,24 +1691,19 @@ pub const Parser = struct {...@@ -1544,24 +1691,19 @@ pub const Parser = struct {
1544 const next = self.getNextToken();1691 const next = self.getNextToken();
15451692
1546 if (next.id != Token.Id.LBrace) {1693 if (next.id != Token.Id.LBrace) {
1694 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeErrorType, token)).base);
1547 self.putBackToken(next);1695 self.putBackToken(next);
1548 const node = try arena.create(ast.NodeErrorType);
1549 *node = ast.NodeErrorType {
1550 .base = self.initNode(ast.Node.Id.ErrorType),
1551 .token = token,
1552 };
1553 dest_ptr.store(&node.base);
1554 continue;1696 continue;
1555 }1697 }
15561698
1557 const node = try arena.create(ast.NodeErrorSetDecl);1699 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeErrorSetDecl,
1558 *node = ast.NodeErrorSetDecl {1700 ast.NodeErrorSetDecl {
1559 .base = self.initNode(ast.Node.Id.ErrorSetDecl),1701 .base = undefined,
1560 .error_token = token,1702 .error_token = token,
1561 .decls = ArrayList(&ast.NodeIdentifier).init(arena),1703 .decls = ArrayList(&ast.NodeIdentifier).init(arena),
1562 .rbrace_token = undefined,1704 .rbrace_token = undefined,
1563 };1705 }
1564 dest_ptr.store(&node.base);1706 );
15651707
1566 while (true) {1708 while (true) {
1567 const t = self.getNextToken();1709 const t = self.getNextToken();
...@@ -1572,7 +1714,7 @@ pub const Parser = struct {...@@ -1572,7 +1714,7 @@ pub const Parser = struct {
1572 },1714 },
1573 Token.Id.Identifier => {1715 Token.Id.Identifier => {
1574 try node.decls.append(1716 try node.decls.append(
1575 try self.createIdentifier(arena, t)1717 try self.createLiteral(arena, ast.NodeIdentifier, t)
1576 );1718 );
1577 },1719 },
1578 else => {1720 else => {
...@@ -1614,10 +1756,24 @@ pub const Parser = struct {...@@ -1614,10 +1756,24 @@ pub const Parser = struct {
1614 Token.Id.Keyword_extern => {1756 Token.Id.Keyword_extern => {
1615 const next = self.getNextToken();1757 const next = self.getNextToken();
1616 if (next.id == Token.Id.Keyword_fn) {1758 if (next.id == Token.Id.Keyword_fn) {
1617 // TODO shouldn't need this cast1759 const fn_proto = try self.createToDestNode(arena, dest_ptr, ast.NodeFnProto,
1618 const fn_proto = try self.createFnProto(arena, next,1760 ast.NodeFnProto {
1619 (?Token)(token), (?&ast.Node)(null), (?Token)(null), (?Token)(null), (?Token)(null));1761 .base = undefined,
1620 dest_ptr.store(&fn_proto.base);1762 .visib_token = null,
1763 .name_token = null,
1764 .fn_token = next,
1765 .params = ArrayList(&ast.Node).init(arena),
1766 .return_type = undefined,
1767 .var_args_token = null,
1768 .extern_token = token,
1769 .inline_token = null,
1770 .cc_token = null,
1771 .async_attr = null,
1772 .body_node = null,
1773 .lib_name = null,
1774 .align_expr = null,
1775 }
1776 );
1621 stack.append(State { .FnProto = fn_proto }) catch unreachable;1777 stack.append(State { .FnProto = fn_proto }) catch unreachable;
1622 continue;1778 continue;
1623 }1779 }
...@@ -1645,7 +1801,7 @@ pub const Parser = struct {...@@ -1645,7 +1801,7 @@ pub const Parser = struct {
1645 const next = self.getNextToken();1801 const next = self.getNextToken();
1646 if (next.id != Token.Id.Colon) {1802 if (next.id != Token.Id.Colon) {
1647 self.putBackToken(next);1803 self.putBackToken(next);
1648 dest_ptr.store(&(try self.createIdentifier(arena, token)).base);1804 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeIdentifier, token)).base);
1649 continue;1805 continue;
1650 }1806 }
16511807
...@@ -1658,19 +1814,47 @@ pub const Parser = struct {...@@ -1658,19 +1814,47 @@ pub const Parser = struct {
1658 continue;1814 continue;
1659 },1815 },
1660 Token.Id.Keyword_fn => {1816 Token.Id.Keyword_fn => {
1661 // TODO shouldn't need these casts1817 const fn_proto = try self.createToDestNode(arena, dest_ptr, ast.NodeFnProto,
1662 const fn_proto = try self.createFnProto(arena, token,1818 ast.NodeFnProto {
1663 (?Token)(null), (?&ast.Node)(null), (?Token)(null), (?Token)(null), (?Token)(null));1819 .base = undefined,
1664 dest_ptr.store(&fn_proto.base);1820 .visib_token = null,
1821 .name_token = null,
1822 .fn_token = token,
1823 .params = ArrayList(&ast.Node).init(arena),
1824 .return_type = undefined,
1825 .var_args_token = null,
1826 .extern_token = null,
1827 .inline_token = null,
1828 .cc_token = null,
1829 .async_attr = null,
1830 .body_node = null,
1831 .lib_name = null,
1832 .align_expr = null,
1833 }
1834 );
1665 stack.append(State { .FnProto = fn_proto }) catch unreachable;1835 stack.append(State { .FnProto = fn_proto }) catch unreachable;
1666 continue;1836 continue;
1667 },1837 },
1668 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {1838 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
1669 const fn_token = (try self.eatToken(&stack, Token.Id.Keyword_fn)) ?? continue;1839 const fn_token = (try self.eatToken(&stack, Token.Id.Keyword_fn)) ?? continue;
1670 // TODO shouldn't need this cast1840 const fn_proto = try self.createToDestNode(arena, dest_ptr, ast.NodeFnProto,
1671 const fn_proto = try self.createFnProto(arena, fn_token,1841 ast.NodeFnProto {
1672 (?Token)(null), (?&ast.Node)(null), (?Token)(token), (?Token)(null), (?Token)(null));1842 .base = undefined,
1673 dest_ptr.store(&fn_proto.base);1843 .visib_token = null,
1844 .name_token = null,
1845 .fn_token = fn_token,
1846 .params = ArrayList(&ast.Node).init(arena),
1847 .return_type = undefined,
1848 .var_args_token = null,
1849 .extern_token = null,
1850 .inline_token = null,
1851 .cc_token = token,
1852 .async_attr = null,
1853 .body_node = null,
1854 .lib_name = null,
1855 .align_expr = null,
1856 }
1857 );
1674 stack.append(State { .FnProto = fn_proto }) catch unreachable;1858 stack.append(State { .FnProto = fn_proto }) catch unreachable;
1675 continue;1859 continue;
1676 },1860 },
...@@ -1687,20 +1871,19 @@ pub const Parser = struct {...@@ -1687,20 +1871,19 @@ pub const Parser = struct {
1687 const template = (try self.eatToken(&stack, Token.Id.StringLiteral)) ?? continue;1871 const template = (try self.eatToken(&stack, Token.Id.StringLiteral)) ?? continue;
1688 // TODO parse template1872 // TODO parse template
16891873
1690 const node = try arena.create(ast.NodeAsm);1874 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeAsm,
1691 *node = ast.NodeAsm {1875 ast.NodeAsm {
1692 .base = self.initNode(ast.Node.Id.Asm),1876 .base = undefined,
1693 .asm_token = token,1877 .asm_token = token,
1694 .is_volatile = is_volatile,1878 .is_volatile = is_volatile,
1695 .template = template,1879 .template = template,
1696 //.tokens = ArrayList(ast.NodeAsm.AsmToken).init(arena),1880 //.tokens = ArrayList(ast.NodeAsm.AsmToken).init(arena),
1697 .outputs = ArrayList(&ast.NodeAsmOutput).init(arena),1881 .outputs = ArrayList(&ast.NodeAsmOutput).init(arena),
1698 .inputs = ArrayList(&ast.NodeAsmInput).init(arena),1882 .inputs = ArrayList(&ast.NodeAsmInput).init(arena),
1699 .cloppers = ArrayList(&ast.NodeStringLiteral).init(arena),1883 .cloppers = ArrayList(&ast.NodeStringLiteral).init(arena),
1700 .rparen = undefined,1884 .rparen = undefined,
1701 };1885 }
1702 dest_ptr.store(&node.base);1886 );
1703
1704 stack.append(State {1887 stack.append(State {
1705 .ExpectTokenSave = ExpectTokenSave {1888 .ExpectTokenSave = ExpectTokenSave {
1706 .id = Token.Id.RParen,1889 .id = Token.Id.RParen,
...@@ -1788,19 +1971,20 @@ pub const Parser = struct {...@@ -1788,19 +1971,20 @@ pub const Parser = struct {
1788 _ = (try self.eatToken(&stack, Token.Id.LParen)) ?? continue;1971 _ = (try self.eatToken(&stack, Token.Id.LParen)) ?? continue;
1789 try stack.append(State { .ExpectToken = Token.Id.RParen });1972 try stack.append(State { .ExpectToken = Token.Id.RParen });
17901973
1791 const node = try arena.create(ast.NodeAsmOutput);1974 const node = try self.createNode(arena, ast.NodeAsmOutput,
1792 *node = ast.NodeAsmOutput {1975 ast.NodeAsmOutput {
1793 .base = self.initNode(ast.Node.Id.AsmOutput),1976 .base = undefined,
1794 .symbolic_name = try self.createIdentifier(arena, symbolic_name),1977 .symbolic_name = try self.createLiteral(arena, ast.NodeIdentifier, symbolic_name),
1795 .constraint = try self.createStringLiteral(arena, constraint),1978 .constraint = try self.createLiteral(arena, ast.NodeStringLiteral, constraint),
1796 .kind = undefined,1979 .kind = undefined,
1797 };1980 }
1981 );
1798 try items.append(node);1982 try items.append(node);
17991983
1800 const symbol_or_arrow = self.getNextToken();1984 const symbol_or_arrow = self.getNextToken();
1801 switch (symbol_or_arrow.id) {1985 switch (symbol_or_arrow.id) {
1802 Token.Id.Identifier => {1986 Token.Id.Identifier => {
1803 node.kind = ast.NodeAsmOutput.Kind { .Variable = try self.createIdentifier(arena, symbol_or_arrow) };1987 node.kind = ast.NodeAsmOutput.Kind { .Variable = try self.createLiteral(arena, ast.NodeIdentifier, symbol_or_arrow) };
1804 },1988 },
1805 Token.Id.Arrow => {1989 Token.Id.Arrow => {
1806 node.kind = ast.NodeAsmOutput.Kind { .Return = undefined };1990 node.kind = ast.NodeAsmOutput.Kind { .Return = undefined };
...@@ -1832,13 +2016,14 @@ pub const Parser = struct {...@@ -1832,13 +2016,14 @@ pub const Parser = struct {
1832 _ = (try self.eatToken(&stack, Token.Id.LParen)) ?? continue;2016 _ = (try self.eatToken(&stack, Token.Id.LParen)) ?? continue;
1833 try stack.append(State { .ExpectToken = Token.Id.RParen });2017 try stack.append(State { .ExpectToken = Token.Id.RParen });
18342018
1835 const node = try arena.create(ast.NodeAsmInput);2019 const node = try self.createNode(arena, ast.NodeAsmInput,
1836 *node = ast.NodeAsmInput {2020 ast.NodeAsmInput {
1837 .base = self.initNode(ast.Node.Id.AsmInput),2021 .base = undefined,
1838 .symbolic_name = try self.createIdentifier(arena, symbolic_name),2022 .symbolic_name = try self.createLiteral(arena, ast.NodeIdentifier, symbolic_name),
1839 .constraint = try self.createStringLiteral(arena, constraint),2023 .constraint = try self.createLiteral(arena, ast.NodeStringLiteral, constraint),
1840 .expr = undefined,2024 .expr = undefined,
1841 };2025 }
2026 );
1842 try items.append(node);2027 try items.append(node);
1843 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });2028 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
1844 },2029 },
...@@ -1850,7 +2035,7 @@ pub const Parser = struct {...@@ -1850,7 +2035,7 @@ pub const Parser = struct {
1850 continue;2035 continue;
1851 }2036 }
18522037
1853 try items.append(try self.createStringLiteral(arena, string));2038 try items.append(try self.createLiteral(arena, ast.NodeStringLiteral, string));
1854 stack.append(State { .AsmClopperItems = items }) catch unreachable;2039 stack.append(State { .AsmClopperItems = items }) catch unreachable;
1855 try stack.append(State { .IfToken = Token.Id.Comma });2040 try stack.append(State { .IfToken = Token.Id.Comma });
1856 },2041 },
...@@ -1871,21 +2056,20 @@ pub const Parser = struct {...@@ -1871,21 +2056,20 @@ pub const Parser = struct {
18712056
1872 State.FieldInitListItemOrEnd => |list_state| {2057 State.FieldInitListItemOrEnd => |list_state| {
1873 var token = self.getNextToken();2058 var token = self.getNextToken();
1874
1875 if (token.id == Token.Id.RBrace){2059 if (token.id == Token.Id.RBrace){
1876 *list_state.ptr = token;2060 *list_state.ptr = token;
1877 continue;2061 continue;
1878 }2062 }
1879
1880 self.putBackToken(token);2063 self.putBackToken(token);
18812064
1882 const node = try arena.create(ast.NodeFieldInitializer);2065 const node = try self.createNode(arena, ast.NodeFieldInitializer,
1883 *node = ast.NodeFieldInitializer {2066 ast.NodeFieldInitializer {
1884 .base = self.initNode(ast.Node.Id.FieldInitializer),2067 .base = undefined,
1885 .period_token = undefined,2068 .period_token = undefined,
1886 .name_token = undefined,2069 .name_token = undefined,
1887 .expr = undefined,2070 .expr = undefined,
1888 };2071 }
2072 );
1889 try list_state.list.append(node);2073 try list_state.list.append(node);
18902074
1891 stack.append(State { .FieldInitListCommaOrEnd = list_state }) catch unreachable;2075 stack.append(State { .FieldInitListCommaOrEnd = list_state }) catch unreachable;
...@@ -1907,21 +2091,20 @@ pub const Parser = struct {...@@ -1907,21 +2091,20 @@ pub const Parser = struct {
19072091
1908 State.SwitchCaseOrEnd => |list_state| {2092 State.SwitchCaseOrEnd => |list_state| {
1909 var token = self.getNextToken();2093 var token = self.getNextToken();
1910
1911 if (token.id == Token.Id.RBrace){2094 if (token.id == Token.Id.RBrace){
1912 *list_state.ptr = token;2095 *list_state.ptr = token;
1913 continue;2096 continue;
1914 }2097 }
1915
1916 self.putBackToken(token);2098 self.putBackToken(token);
19172099
1918 const node = try arena.create(ast.NodeSwitchCase);2100 const node = try self.createNode(arena, ast.NodeSwitchCase,
1919 *node = ast.NodeSwitchCase {2101 ast.NodeSwitchCase {
1920 .base = self.initNode(ast.Node.Id.SwitchCase),2102 .base = undefined,
1921 .items = ArrayList(&ast.Node).init(arena),2103 .items = ArrayList(&ast.Node).init(arena),
1922 .payload = null,2104 .payload = null,
1923 .expr = undefined,2105 .expr = undefined,
1924 };2106 }
2107 );
1925 try list_state.list.append(node);2108 try list_state.list.append(node);
1926 stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable;2109 stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable;
1927 try stack.append(State { .Expression = DestPtr{ .Field = &node.expr } });2110 try stack.append(State { .Expression = DestPtr{ .Field = &node.expr } });
...@@ -1982,13 +2165,14 @@ pub const Parser = struct {...@@ -1982,13 +2165,14 @@ pub const Parser = struct {
1982 continue;2165 continue;
1983 }2166 }
19842167
1985 const node = try arena.create(ast.NodeElse);2168 const node = try self.createNode(arena, ast.NodeElse,
1986 *node = ast.NodeElse {2169 ast.NodeElse {
1987 .base = self.initNode(ast.Node.Id.Else),2170 .base = undefined,
1988 .else_token = else_token,2171 .else_token = else_token,
1989 .payload = null,2172 .payload = null,
1990 .body = undefined,2173 .body = undefined,
1991 };2174 }
2175 );
1992 *dest = node;2176 *dest = node;
19932177
1994 stack.append(State { .Expression = DestPtr { .Field = &node.body } }) catch unreachable;2178 stack.append(State { .Expression = DestPtr { .Field = &node.body } }) catch unreachable;
...@@ -2050,14 +2234,14 @@ pub const Parser = struct {...@@ -2050,14 +2234,14 @@ pub const Parser = struct {
20502234
2051 const error_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;2235 const error_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;
2052 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;2236 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;
2053 const node = try arena.create(ast.NodePayload);2237 *dest = try self.createNode(arena, ast.NodePayload,
2054 *node = ast.NodePayload {2238 ast.NodePayload {
2055 .base = self.initNode(ast.Node.Id.Payload),2239 .base = undefined,
2056 .lpipe = lpipe,2240 .lpipe = lpipe,
2057 .error_symbol = try self.createIdentifier(arena, error_symbol),2241 .error_symbol = try self.createLiteral(arena, ast.NodeIdentifier, error_symbol),
2058 .rpipe = rpipe2242 .rpipe = rpipe
2059 };2243 }
2060 *dest = node;2244 );
2061 },2245 },
20622246
2063 State.PointerPayload => |dest| {2247 State.PointerPayload => |dest| {
...@@ -2079,15 +2263,15 @@ pub const Parser = struct {...@@ -2079,15 +2263,15 @@ pub const Parser = struct {
20792263
2080 const value_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;2264 const value_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;
2081 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;2265 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;
2082 const node = try arena.create(ast.NodePointerPayload);2266 *dest = try self.createNode(arena, ast.NodePointerPayload,
2083 *node = ast.NodePointerPayload {2267 ast.NodePointerPayload {
2084 .base = self.initNode(ast.Node.Id.PointerPayload),2268 .base = undefined,
2085 .lpipe = lpipe,2269 .lpipe = lpipe,
2086 .is_ptr = is_ptr,2270 .is_ptr = is_ptr,
2087 .value_symbol = try self.createIdentifier(arena, value_symbol),2271 .value_symbol = try self.createLiteral(arena, ast.NodeIdentifier, value_symbol),
2088 .rpipe = rpipe2272 .rpipe = rpipe
2089 };2273 }
2090 *dest = node;2274 );
2091 },2275 },
20922276
2093 State.PointerIndexPayload => |dest| {2277 State.PointerIndexPayload => |dest| {
...@@ -2116,20 +2300,20 @@ pub const Parser = struct {...@@ -2116,20 +2300,20 @@ pub const Parser = struct {
2116 }2300 }
21172301
2118 const symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;2302 const symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;
2119 break :blk try self.createIdentifier(arena, symbol);2303 break :blk try self.createLiteral(arena, ast.NodeIdentifier, symbol);
2120 };2304 };
21212305
2122 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;2306 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;
2123 const node = try arena.create(ast.NodePointerIndexPayload);2307 *dest = try self.createNode(arena, ast.NodePointerIndexPayload,
2124 *node = ast.NodePointerIndexPayload {2308 ast.NodePointerIndexPayload {
2125 .base = self.initNode(ast.Node.Id.PointerIndexPayload),2309 .base = undefined,
2126 .lpipe = lpipe,2310 .lpipe = lpipe,
2127 .is_ptr = is_ptr,2311 .is_ptr = is_ptr,
2128 .value_symbol = try self.createIdentifier(arena, value_symbol),2312 .value_symbol = try self.createLiteral(arena, ast.NodeIdentifier, value_symbol),
2129 .index_symbol = index_symbol,2313 .index_symbol = index_symbol,
2130 .rpipe = rpipe2314 .rpipe = rpipe
2131 };2315 }
2132 *dest = node;2316 );
2133 },2317 },
21342318
2135 State.AddrOfModifiers => |addr_of_info| {2319 State.AddrOfModifiers => |addr_of_info| {
...@@ -2225,7 +2409,16 @@ pub const Parser = struct {...@@ -2225,7 +2409,16 @@ pub const Parser = struct {
2225 if (token.id == Token.Id.RParen) {2409 if (token.id == Token.Id.RParen) {
2226 continue;2410 continue;
2227 }2411 }
2228 const param_decl = try self.createAttachParamDecl(arena, &fn_proto.params);2412 const param_decl = try self.createAttachNode(arena, &fn_proto.params, ast.NodeParamDecl,
2413 ast.NodeParamDecl {
2414 .base = undefined,
2415 .comptime_token = null,
2416 .noalias_token = null,
2417 .name_token = null,
2418 .type_node = undefined,
2419 .var_args_token = null,
2420 },
2421 );
2229 if (token.id == Token.Id.Keyword_comptime) {2422 if (token.id == Token.Id.Keyword_comptime) {
2230 param_decl.comptime_token = token;2423 param_decl.comptime_token = token;
2231 token = self.getNextToken();2424 token = self.getNextToken();
...@@ -2277,7 +2470,15 @@ pub const Parser = struct {...@@ -2277,7 +2470,15 @@ pub const Parser = struct {
2277 const token = self.getNextToken();2470 const token = self.getNextToken();
2278 switch(token.id) {2471 switch(token.id) {
2279 Token.Id.LBrace => {2472 Token.Id.LBrace => {
2280 const block = try self.createBlock(arena, (?Token)(null), token);2473 const block = try self.createNode(arena, ast.NodeBlock,
2474 ast.NodeBlock {
2475 .base = undefined,
2476 .label = null,
2477 .lbrace = token,
2478 .statements = ArrayList(&ast.Node).init(arena),
2479 .rbrace = undefined,
2480 }
2481 );
2281 fn_proto.body_node = &block.base;2482 fn_proto.body_node = &block.base;
2282 stack.append(State { .Block = block }) catch unreachable;2483 stack.append(State { .Block = block }) catch unreachable;
2283 continue;2484 continue;
...@@ -2294,9 +2495,15 @@ pub const Parser = struct {...@@ -2294,9 +2495,15 @@ pub const Parser = struct {
2294 const token = self.getNextToken();2495 const token = self.getNextToken();
2295 switch (token.id) {2496 switch (token.id) {
2296 Token.Id.LBrace => {2497 Token.Id.LBrace => {
2297 const block = try self.createBlock(arena, (?Token)(ctx.label), token);2498 const block = try self.createToDestNode(arena, ctx.dest_ptr, ast.NodeBlock,
2298 ctx.dest_ptr.store(&block.base);2499 ast.NodeBlock {
22992500 .base = undefined,
2501 .label = ctx.label,
2502 .lbrace = token,
2503 .statements = ArrayList(&ast.Node).init(arena),
2504 .rbrace = undefined,
2505 }
2506 );
2300 stack.append(State { .Block = block }) catch unreachable;2507 stack.append(State { .Block = block }) catch unreachable;
2301 continue;2508 continue;
2302 },2509 },
...@@ -2372,20 +2579,19 @@ pub const Parser = struct {...@@ -2372,20 +2579,19 @@ pub const Parser = struct {
2372 },2579 },
23732580
2374 State.While => |ctx| {2581 State.While => |ctx| {
2375 const node = try arena.create(ast.NodeWhile);2582 const node = try self.createToDestNode(arena, ctx.dest_ptr, ast.NodeWhile,
2376 *node = ast.NodeWhile {2583 ast.NodeWhile {
2377 .base = self.initNode(ast.Node.Id.While),2584 .base = undefined,
2378 .label = ctx.label,2585 .label = ctx.label,
2379 .inline_token = ctx.inline_token,2586 .inline_token = ctx.inline_token,
2380 .while_token = ctx.loop_token,2587 .while_token = ctx.loop_token,
2381 .condition = undefined,2588 .condition = undefined,
2382 .payload = null,2589 .payload = null,
2383 .continue_expr = null,2590 .continue_expr = null,
2384 .body = undefined,2591 .body = undefined,
2385 .@"else" = null,2592 .@"else" = null,
2386 };2593 }
2387 ctx.dest_ptr.store(&node.base);2594 );
2388
2389 stack.append(State { .Else = &node.@"else" }) catch unreachable;2595 stack.append(State { .Else = &node.@"else" }) catch unreachable;
2390 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });2596 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
2391 try stack.append(State { .WhileContinueExpr = &node.continue_expr });2597 try stack.append(State { .WhileContinueExpr = &node.continue_expr });
...@@ -2396,19 +2602,18 @@ pub const Parser = struct {...@@ -2396,19 +2602,18 @@ pub const Parser = struct {
2396 },2602 },
23972603
2398 State.For => |ctx| {2604 State.For => |ctx| {
2399 const node = try arena.create(ast.NodeFor);2605 const node = try self.createToDestNode(arena, ctx.dest_ptr, ast.NodeFor,
2400 *node = ast.NodeFor {2606 ast.NodeFor {
2401 .base = self.initNode(ast.Node.Id.For),2607 .base = undefined,
2402 .label = ctx.label,2608 .label = ctx.label,
2403 .inline_token = ctx.inline_token,2609 .inline_token = ctx.inline_token,
2404 .for_token = ctx.loop_token,2610 .for_token = ctx.loop_token,
2405 .array_expr = undefined,2611 .array_expr = undefined,
2406 .payload = null,2612 .payload = null,
2407 .body = undefined,2613 .body = undefined,
2408 .@"else" = null,2614 .@"else" = null,
2409 };2615 }
2410 ctx.dest_ptr.store(&node.base);2616 );
2411
2412 stack.append(State { .Else = &node.@"else" }) catch unreachable;2617 stack.append(State { .Else = &node.@"else" }) catch unreachable;
2413 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });2618 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
2414 try stack.append(State { .PointerIndexPayload = &node.payload });2619 try stack.append(State { .PointerIndexPayload = &node.payload });
...@@ -2439,9 +2644,23 @@ pub const Parser = struct {...@@ -2439,9 +2644,23 @@ pub const Parser = struct {
2439 Token.Id.Keyword_comptime => {2644 Token.Id.Keyword_comptime => {
2440 const mut_token = self.getNextToken();2645 const mut_token = self.getNextToken();
2441 if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) {2646 if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) {
2442 // TODO shouldn't need these casts2647 const var_decl = try self.createAttachNode(arena, &block.statements, ast.NodeVarDecl,
2443 const var_decl = try self.createAttachVarDecl(arena, &block.statements, (?Token)(null),2648 ast.NodeVarDecl {
2444 mut_token, (?Token)(next), (?Token)(null), null);2649 .base = undefined,
2650 .visib_token = null,
2651 .mut_token = mut_token,
2652 .comptime_token = next,
2653 .extern_token = null,
2654 .type_node = null,
2655 .align_node = null,
2656 .init_node = null,
2657 .lib_name = null,
2658 // initialized later
2659 .name_token = undefined,
2660 .eq_token = undefined,
2661 .semicolon_token = undefined,
2662 }
2663 );
2445 stack.append(State { .VarDecl = var_decl }) catch unreachable;2664 stack.append(State { .VarDecl = var_decl }) catch unreachable;
2446 continue;2665 continue;
2447 } else {2666 } else {
...@@ -2453,33 +2672,53 @@ pub const Parser = struct {...@@ -2453,33 +2672,53 @@ pub const Parser = struct {
2453 }2672 }
2454 },2673 },
2455 Token.Id.Keyword_var, Token.Id.Keyword_const => {2674 Token.Id.Keyword_var, Token.Id.Keyword_const => {
2456 const var_decl = try self.createAttachVarDecl(arena, &block.statements, (?Token)(null),2675 const var_decl = try self.createAttachNode(arena, &block.statements, ast.NodeVarDecl,
2457 next, (?Token)(null), (?Token)(null), null);2676 ast.NodeVarDecl {
2677 .base = undefined,
2678 .visib_token = null,
2679 .mut_token = next,
2680 .comptime_token = null,
2681 .extern_token = null,
2682 .type_node = null,
2683 .align_node = null,
2684 .init_node = null,
2685 .lib_name = null,
2686 // initialized later
2687 .name_token = undefined,
2688 .eq_token = undefined,
2689 .semicolon_token = undefined,
2690 }
2691 );
2458 stack.append(State { .VarDecl = var_decl }) catch unreachable;2692 stack.append(State { .VarDecl = var_decl }) catch unreachable;
2459 continue;2693 continue;
2460 },2694 },
2461 Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {2695 Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {
2462 const node = try arena.create(ast.NodeDefer);2696 const node = try self.createAttachNode(arena, &block.statements, ast.NodeDefer,
2463 *node = ast.NodeDefer {2697 ast.NodeDefer {
2464 .base = self.initNode(ast.Node.Id.Defer),2698 .base = undefined,
2465 .defer_token = next,2699 .defer_token = next,
2466 .kind = switch (next.id) {2700 .kind = switch (next.id) {
2467 Token.Id.Keyword_defer => ast.NodeDefer.Kind.Unconditional,2701 Token.Id.Keyword_defer => ast.NodeDefer.Kind.Unconditional,
2468 Token.Id.Keyword_errdefer => ast.NodeDefer.Kind.Error,2702 Token.Id.Keyword_errdefer => ast.NodeDefer.Kind.Error,
2469 else => unreachable,2703 else => unreachable,
2470 },2704 },
2471 .expr = undefined,2705 .expr = undefined,
2472 };2706 }
2473 try block.statements.append(&node.base);2707 );
2474
2475 stack.append(State { .Semicolon = &node.base }) catch unreachable;2708 stack.append(State { .Semicolon = &node.base }) catch unreachable;
2476 try stack.append(State { .AssignmentExpressionBegin = DestPtr{.Field = &node.expr } });2709 try stack.append(State { .AssignmentExpressionBegin = DestPtr{.Field = &node.expr } });
2477 continue;2710 continue;
2478 },2711 },
2479 Token.Id.LBrace => {2712 Token.Id.LBrace => {
2480 const inner_block = try self.createBlock(arena, (?Token)(null), next);2713 const inner_block = try self.createAttachNode(arena, &block.statements, ast.NodeBlock,
2481 try block.statements.append(&inner_block.base);2714 ast.NodeBlock {
24822715 .base = undefined,
2716 .label = null,
2717 .lbrace = next,
2718 .statements = ArrayList(&ast.Node).init(arena),
2719 .rbrace = undefined,
2720 }
2721 );
2483 stack.append(State { .Block = inner_block }) catch unreachable;2722 stack.append(State { .Block = inner_block }) catch unreachable;
2484 continue;2723 continue;
2485 },2724 },
...@@ -2600,84 +2839,74 @@ pub const Parser = struct {...@@ -2600,84 +2839,74 @@ pub const Parser = struct {
2600 // TODO: We have to cast all cases because of this:2839 // TODO: We have to cast all cases because of this:
2601 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'2840 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
2602 return switch (*id) {2841 return switch (*id) {
2603 Token.Id.AmpersandEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignBitAnd),2842 Token.Id.AmpersandEqual => ast.NodeInfixOp.InfixOp { .AssignBitAnd = void{} },
2604 Token.Id.AngleBracketAngleBracketLeftEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignBitShiftLeft),2843 Token.Id.AngleBracketAngleBracketLeftEqual => ast.NodeInfixOp.InfixOp { .AssignBitShiftLeft = void{} },
2605 Token.Id.AngleBracketAngleBracketRightEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignBitShiftRight),2844 Token.Id.AngleBracketAngleBracketRightEqual => ast.NodeInfixOp.InfixOp { .AssignBitShiftRight = void{} },
2606 Token.Id.AsteriskEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignTimes),2845 Token.Id.AsteriskEqual => ast.NodeInfixOp.InfixOp { .AssignTimes = void{} },
2607 Token.Id.AsteriskPercentEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignTimesWarp),2846 Token.Id.AsteriskPercentEqual => ast.NodeInfixOp.InfixOp { .AssignTimesWarp = void{} },
2608 Token.Id.CaretEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignBitXor),2847 Token.Id.CaretEqual => ast.NodeInfixOp.InfixOp { .AssignBitXor = void{} },
2609 Token.Id.Equal => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.Assign),2848 Token.Id.Equal => ast.NodeInfixOp.InfixOp { .Assign = void{} },
2610 Token.Id.MinusEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignMinus),2849 Token.Id.MinusEqual => ast.NodeInfixOp.InfixOp { .AssignMinus = void{} },
2611 Token.Id.MinusPercentEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignMinusWrap),2850 Token.Id.MinusPercentEqual => ast.NodeInfixOp.InfixOp { .AssignMinusWrap = void{} },
2612 Token.Id.PercentEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignMod),2851 Token.Id.PercentEqual => ast.NodeInfixOp.InfixOp { .AssignMod = void{} },
2613 Token.Id.PipeEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignBitOr),2852 Token.Id.PipeEqual => ast.NodeInfixOp.InfixOp { .AssignBitOr = void{} },
2614 Token.Id.PlusEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignPlus),2853 Token.Id.PlusEqual => ast.NodeInfixOp.InfixOp { .AssignPlus = void{} },
2615 Token.Id.PlusPercentEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignPlusWrap),2854 Token.Id.PlusPercentEqual => ast.NodeInfixOp.InfixOp { .AssignPlusWrap = void{} },
2616 Token.Id.SlashEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignDiv),2855 Token.Id.SlashEqual => ast.NodeInfixOp.InfixOp { .AssignDiv = void{} },
2617 else => null,2856 else => null,
2618 };2857 };
2619 }2858 }
26202859
2621 fn tokenIdToComparison(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {2860 fn tokenIdToComparison(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
2622 // TODO: We have to cast all cases because of this:
2623 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
2624 return switch (*id) {2861 return switch (*id) {
2625 Token.Id.BangEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.BangEqual),2862 Token.Id.BangEqual => ast.NodeInfixOp.InfixOp { .BangEqual = void{} },
2626 Token.Id.EqualEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.EqualEqual),2863 Token.Id.EqualEqual => ast.NodeInfixOp.InfixOp { .EqualEqual = void{} },
2627 Token.Id.AngleBracketLeft => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.LessThan),2864 Token.Id.AngleBracketLeft => ast.NodeInfixOp.InfixOp { .LessThan = void{} },
2628 Token.Id.AngleBracketLeftEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.LessOrEqual),2865 Token.Id.AngleBracketLeftEqual => ast.NodeInfixOp.InfixOp { .LessOrEqual = void{} },
2629 Token.Id.AngleBracketRight => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.GreaterThan),2866 Token.Id.AngleBracketRight => ast.NodeInfixOp.InfixOp { .GreaterThan = void{} },
2630 Token.Id.AngleBracketRightEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.GreaterOrEqual),2867 Token.Id.AngleBracketRightEqual => ast.NodeInfixOp.InfixOp { .GreaterOrEqual = void{} },
2631 else => null,2868 else => null,
2632 };2869 };
2633 }2870 }
26342871
2635 fn tokenIdToBitShift(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {2872 fn tokenIdToBitShift(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
2636 // TODO: We have to cast all cases because of this:
2637 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
2638 return switch (*id) {2873 return switch (*id) {
2639 Token.Id.AngleBracketAngleBracketLeft => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.BitShiftLeft),2874 Token.Id.AngleBracketAngleBracketLeft => ast.NodeInfixOp.InfixOp { .BitShiftLeft = void{} },
2640 Token.Id.AngleBracketAngleBracketRight => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.BitShiftRight),2875 Token.Id.AngleBracketAngleBracketRight => ast.NodeInfixOp.InfixOp { .BitShiftRight = void{} },
2641 else => null,2876 else => null,
2642 };2877 };
2643 }2878 }
26442879
2645 fn tokenIdToAddition(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {2880 fn tokenIdToAddition(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
2646 // TODO: We have to cast all cases because of this:
2647 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
2648 return switch (*id) {2881 return switch (*id) {
2649 Token.Id.Minus => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.Sub),2882 Token.Id.Minus => ast.NodeInfixOp.InfixOp { .Sub = void{} },
2650 Token.Id.MinusPercent => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.SubWrap),2883 Token.Id.MinusPercent => ast.NodeInfixOp.InfixOp { .SubWrap = void{} },
2651 Token.Id.Plus => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.Add),2884 Token.Id.Plus => ast.NodeInfixOp.InfixOp { .Add = void{} },
2652 Token.Id.PlusPercent => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AddWrap),2885 Token.Id.PlusPercent => ast.NodeInfixOp.InfixOp { .AddWrap = void{} },
2653 Token.Id.PlusPlus => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.ArrayCat),2886 Token.Id.PlusPlus => ast.NodeInfixOp.InfixOp { .ArrayCat = void{} },
2654 else => null,2887 else => null,
2655 };2888 };
2656 }2889 }
26572890
2658 fn tokenIdToMultiply(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {2891 fn tokenIdToMultiply(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
2659 // TODO: We have to cast all cases because of this:
2660 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
2661 return switch (*id) {2892 return switch (*id) {
2662 Token.Id.Slash => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.Div),2893 Token.Id.Slash => ast.NodeInfixOp.InfixOp { .Div = void{} },
2663 Token.Id.Asterisk => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.Mult),2894 Token.Id.Asterisk => ast.NodeInfixOp.InfixOp { .Mult = void{} },
2664 Token.Id.AsteriskAsterisk => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.ArrayMult),2895 Token.Id.AsteriskAsterisk => ast.NodeInfixOp.InfixOp { .ArrayMult = void{} },
2665 Token.Id.AsteriskPercent => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.MultWrap),2896 Token.Id.AsteriskPercent => ast.NodeInfixOp.InfixOp { .MultWrap = void{} },
2666 Token.Id.Percent => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.Mod),2897 Token.Id.Percent => ast.NodeInfixOp.InfixOp { .Mod = void{} },
2667 Token.Id.PipePipe => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.MergeErrorSets),2898 Token.Id.PipePipe => ast.NodeInfixOp.InfixOp { .MergeErrorSets = void{} },
2668 else => null,2899 else => null,
2669 };2900 };
2670 }2901 }
26712902
2672 fn tokenIdToPrefixOp(id: &const Token.Id) ?ast.NodePrefixOp.PrefixOp {2903 fn tokenIdToPrefixOp(id: &const Token.Id) ?ast.NodePrefixOp.PrefixOp {
2673 // TODO: We have to cast all cases because of this:
2674 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
2675 return switch (*id) {2904 return switch (*id) {
2676 Token.Id.Bang => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.BoolNot),2905 Token.Id.Bang => ast.NodePrefixOp.PrefixOp { .BoolNot = void{} },
2677 Token.Id.Tilde => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.BitNot),2906 Token.Id.Tilde => ast.NodePrefixOp.PrefixOp { .BitNot = void{} },
2678 Token.Id.Minus => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.Negation),2907 Token.Id.Minus => ast.NodePrefixOp.PrefixOp { .Negation = void{} },
2679 Token.Id.MinusPercent => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.NegationWrap),2908 Token.Id.MinusPercent => ast.NodePrefixOp.PrefixOp { .NegationWrap = void{} },
2680 Token.Id.Asterisk => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.Deref),2909 Token.Id.Asterisk => ast.NodePrefixOp.PrefixOp { .Deref = void{} },
2681 Token.Id.Ampersand => ast.NodePrefixOp.PrefixOp {2910 Token.Id.Ampersand => ast.NodePrefixOp.PrefixOp {
2682 .AddrOf = ast.NodePrefixOp.AddrOfInfo {2911 .AddrOf = ast.NodePrefixOp.AddrOfInfo {
2683 .align_expr = null,2912 .align_expr = null,
...@@ -2687,9 +2916,9 @@ pub const Parser = struct {...@@ -2687,9 +2916,9 @@ pub const Parser = struct {
2687 .volatile_token = null,2916 .volatile_token = null,
2688 },2917 },
2689 },2918 },
2690 Token.Id.QuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.MaybeType),2919 Token.Id.QuestionMark => ast.NodePrefixOp.PrefixOp { .MaybeType = void{} },
2691 Token.Id.QuestionMarkQuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.UnwrapMaybe),2920 Token.Id.QuestionMarkQuestionMark => ast.NodePrefixOp.PrefixOp { .UnwrapMaybe = void{} },
2692 Token.Id.Keyword_await => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.Await),2921 Token.Id.Keyword_await => ast.NodePrefixOp.PrefixOp { .Await = void{} },
2693 else => null,2922 else => null,
2694 };2923 };
2695 }2924 }
...@@ -2702,243 +2931,35 @@ pub const Parser = struct {...@@ -2702,243 +2931,35 @@ pub const Parser = struct {
2702 return ast.Node {.id = id, .comment = null };2931 return ast.Node {.id = id, .comment = null };
2703 }2932 }
27042933
2705 fn createRoot(self: &Parser, arena: &mem.Allocator) !&ast.NodeRoot {2934 fn createNode(self: &Parser, arena: &mem.Allocator, comptime T: type, init_to: &const T) !&T {
2706 const node = try arena.create(ast.NodeRoot);2935 const node = try arena.create(T);
27072936 *node = *init_to;
2708 *node = ast.NodeRoot {2937 node.base = self.initNode(ast.Node.typeToId(T));
2709 .base = self.initNode(ast.Node.Id.Root),
2710 .decls = ArrayList(&ast.Node).init(arena),
2711 // initialized when we get the eof token
2712 .eof_token = undefined,
2713 };
2714 return node;
2715 }
2716
2717 fn createVarDecl(self: &Parser, arena: &mem.Allocator, visib_token: &const ?Token, mut_token: &const Token,
2718 comptime_token: &const ?Token, extern_token: &const ?Token, lib_name: ?&ast.Node) !&ast.NodeVarDecl
2719 {
2720 const node = try arena.create(ast.NodeVarDecl);
2721
2722 *node = ast.NodeVarDecl {
2723 .base = self.initNode(ast.Node.Id.VarDecl),
2724 .visib_token = *visib_token,
2725 .mut_token = *mut_token,
2726 .comptime_token = *comptime_token,
2727 .extern_token = *extern_token,
2728 .type_node = null,
2729 .align_node = null,
2730 .init_node = null,
2731 .lib_name = lib_name,
2732 // initialized later
2733 .name_token = undefined,
2734 .eq_token = undefined,
2735 .semicolon_token = undefined,
2736 };
2737 return node;
2738 }
2739
2740 fn createStringLiteral(self: &Parser, arena: &mem.Allocator, token: &const Token) !&ast.NodeStringLiteral {
2741 const node = try arena.create(ast.NodeStringLiteral);
2742
2743 assert(token.id == Token.Id.StringLiteral);
2744 *node = ast.NodeStringLiteral {
2745 .base = self.initNode(ast.Node.Id.StringLiteral),
2746 .token = *token,
2747 };
2748 return node;
2749 }
2750
2751 fn createTestDecl(self: &Parser, arena: &mem.Allocator, test_token: &const Token, name: &ast.Node,
2752 block: &ast.NodeBlock) !&ast.NodeTestDecl
2753 {
2754 const node = try arena.create(ast.NodeTestDecl);
2755
2756 *node = ast.NodeTestDecl {
2757 .base = self.initNode(ast.Node.Id.TestDecl),
2758 .test_token = *test_token,
2759 .name = name,
2760 .body_node = &block.base,
2761 };
2762 return node;
2763 }
2764
2765 fn createFnProto(self: &Parser, arena: &mem.Allocator, fn_token: &const Token, extern_token: &const ?Token,
2766 lib_name: ?&ast.Node, cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) !&ast.NodeFnProto
2767 {
2768 const node = try arena.create(ast.NodeFnProto);
2769
2770 *node = ast.NodeFnProto {
2771 .base = self.initNode(ast.Node.Id.FnProto),
2772 .visib_token = *visib_token,
2773 .name_token = null,
2774 .fn_token = *fn_token,
2775 .params = ArrayList(&ast.Node).init(arena),
2776 .return_type = undefined,
2777 .var_args_token = null,
2778 .extern_token = *extern_token,
2779 .inline_token = *inline_token,
2780 .cc_token = *cc_token,
2781 .async_attr = null,
2782 .body_node = null,
2783 .lib_name = lib_name,
2784 .align_expr = null,
2785 };
2786 return node;
2787 }
2788
2789 fn createParamDecl(self: &Parser, arena: &mem.Allocator) !&ast.NodeParamDecl {
2790 const node = try arena.create(ast.NodeParamDecl);
2791
2792 *node = ast.NodeParamDecl {
2793 .base = self.initNode(ast.Node.Id.ParamDecl),
2794 .comptime_token = null,
2795 .noalias_token = null,
2796 .name_token = null,
2797 .type_node = undefined,
2798 .var_args_token = null,
2799 };
2800 return node;
2801 }
2802
2803 fn createBlock(self: &Parser, arena: &mem.Allocator, label: &const ?Token, lbrace: &const Token) !&ast.NodeBlock {
2804 const node = try arena.create(ast.NodeBlock);
2805
2806 *node = ast.NodeBlock {
2807 .base = self.initNode(ast.Node.Id.Block),
2808 .label = *label,
2809 .lbrace = *lbrace,
2810 .statements = ArrayList(&ast.Node).init(arena),
2811 .rbrace = undefined,
2812 };
2813 return node;
2814 }
2815
2816 fn createControlFlowExpr(self: &Parser, arena: &mem.Allocator, ltoken: &const Token,
2817 kind: &const ast.NodeControlFlowExpression.Kind) !&ast.NodeControlFlowExpression
2818 {
2819 const node = try arena.create(ast.NodeControlFlowExpression);
2820 *node = ast.NodeControlFlowExpression {
2821 .base = self.initNode(ast.Node.Id.ControlFlowExpression),
2822 .ltoken = *ltoken,
2823 .kind = *kind,
2824 .rhs = null,
2825 };
2826 return node;
2827 }
2828
2829 fn createInfixOp(self: &Parser, arena: &mem.Allocator, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) !&ast.NodeInfixOp {
2830 const node = try arena.create(ast.NodeInfixOp);
2831
2832 *node = ast.NodeInfixOp {
2833 .base = self.initNode(ast.Node.Id.InfixOp),
2834 .op_token = *op_token,
2835 .lhs = undefined,
2836 .op = *op,
2837 .rhs = undefined,
2838 };
2839 return node;
2840 }
2841
2842 fn createPrefixOp(self: &Parser, arena: &mem.Allocator, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) !&ast.NodePrefixOp {
2843 const node = try arena.create(ast.NodePrefixOp);
2844
2845 *node = ast.NodePrefixOp {
2846 .base = self.initNode(ast.Node.Id.PrefixOp),
2847 .op_token = *op_token,
2848 .op = *op,
2849 .rhs = undefined,
2850 };
2851 return node;
2852 }
2853
2854 fn createSuffixOp(self: &Parser, arena: &mem.Allocator, op: &const ast.NodeSuffixOp.SuffixOp) !&ast.NodeSuffixOp {
2855 const node = try arena.create(ast.NodeSuffixOp);
2856
2857 *node = ast.NodeSuffixOp {
2858 .base = self.initNode(ast.Node.Id.SuffixOp),
2859 .lhs = undefined,
2860 .op = *op,
2861 .rtoken = undefined,
2862 };
2863 return node;
2864 }
2865
2866 fn createIdentifier(self: &Parser, arena: &mem.Allocator, name_token: &const Token) !&ast.NodeIdentifier {
2867 const node = try arena.create(ast.NodeIdentifier);
2868
2869 *node = ast.NodeIdentifier {
2870 .base = self.initNode(ast.Node.Id.Identifier),
2871 .name_token = *name_token,
2872 };
2873 return node;
2874 }
2875
2876 fn createIntegerLiteral(self: &Parser, arena: &mem.Allocator, token: &const Token) !&ast.NodeIntegerLiteral {
2877 const node = try arena.create(ast.NodeIntegerLiteral);
28782938
2879 *node = ast.NodeIntegerLiteral {
2880 .base = self.initNode(ast.Node.Id.IntegerLiteral),
2881 .token = *token,
2882 };
2883 return node;
2884 }
2885
2886 fn createFloatLiteral(self: &Parser, arena: &mem.Allocator, token: &const Token) !&ast.NodeFloatLiteral {
2887 const node = try arena.create(ast.NodeFloatLiteral);
2888
2889 *node = ast.NodeFloatLiteral {
2890 .base = self.initNode(ast.Node.Id.FloatLiteral),
2891 .token = *token,
2892 };
2893 return node;
2894 }
2895
2896 fn createUndefined(self: &Parser, arena: &mem.Allocator, token: &const Token) !&ast.NodeUndefinedLiteral {
2897 const node = try arena.create(ast.NodeUndefinedLiteral);
2898
2899 *node = ast.NodeUndefinedLiteral {
2900 .base = self.initNode(ast.Node.Id.UndefinedLiteral),
2901 .token = *token,
2902 };
2903 return node;2939 return node;
2904 }2940 }
29052941
2906 fn createAttachIdentifier(self: &Parser, arena: &mem.Allocator, dest_ptr: &const DestPtr, name_token: &const Token) !&ast.NodeIdentifier {2942 fn createAttachNode(self: &Parser, arena: &mem.Allocator, list: &ArrayList(&ast.Node), comptime T: type, init_to: &const T) !&T {
2907 const node = try self.createIdentifier(arena, name_token);2943 const node = try self.createNode(arena, T, init_to);
2908 try dest_ptr.store(&node.base);
2909 return node;
2910 }
2911
2912 fn createAttachParamDecl(self: &Parser, arena: &mem.Allocator, list: &ArrayList(&ast.Node)) !&ast.NodeParamDecl {
2913 const node = try self.createParamDecl(arena);
2914 try list.append(&node.base);2944 try list.append(&node.base);
2915 return node;
2916 }
29172945
2918 fn createAttachFnProto(self: &Parser, arena: &mem.Allocator, list: &ArrayList(&ast.Node), fn_token: &const Token,
2919 extern_token: &const ?Token, lib_name: ?&ast.Node, cc_token: &const ?Token, visib_token: &const ?Token,
2920 inline_token: &const ?Token) !&ast.NodeFnProto
2921 {
2922 const node = try self.createFnProto(arena, fn_token, extern_token, lib_name, cc_token, visib_token, inline_token);
2923 try list.append(&node.base);
2924 return node;2946 return node;
2925 }2947 }
29262948
2927 fn createAttachVarDecl(self: &Parser, arena: &mem.Allocator, list: &ArrayList(&ast.Node),2949 fn createToDestNode(self: &Parser, arena: &mem.Allocator, dest_ptr: &const DestPtr, comptime T: type, init_to: &const T) !&T {
2928 visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token,2950 const node = try self.createNode(arena, T, init_to);
2929 extern_token: &const ?Token, lib_name: ?&ast.Node) !&ast.NodeVarDecl2951 dest_ptr.store(&node.base);
2930 {2952
2931 const node = try self.createVarDecl(arena, visib_token, mut_token, comptime_token, extern_token, lib_name);
2932 try list.append(&node.base);
2933 return node;2953 return node;
2934 }2954 }
29352955
2936 fn createAttachTestDecl(self: &Parser, arena: &mem.Allocator, list: &ArrayList(&ast.Node),2956 fn createLiteral(self: &Parser, arena: &mem.Allocator, comptime T: type, token: &const Token) !&T {
2937 test_token: &const Token, name: &ast.Node, block: &ast.NodeBlock) !&ast.NodeTestDecl2957 return self.createNode(arena, T,
2938 {2958 T {
2939 const node = try self.createTestDecl(arena, test_token, name, block);2959 .base = undefined,
2940 try list.append(&node.base);2960 .token = *token,
2941 return node;2961 }
2962 );
2942 }2963 }
29432964
2944 fn parseError(self: &Parser, stack: &ArrayList(State), token: &const Token, comptime fmt: []const u8, args: ...) !void {2965 fn parseError(self: &Parser, stack: &ArrayList(State), token: &const Token, comptime fmt: []const u8, args: ...) !void {
...@@ -3217,7 +3238,7 @@ pub const Parser = struct {...@@ -3217,7 +3238,7 @@ pub const Parser = struct {
3217 RenderState.Expression => |base| switch (base.id) {3238 RenderState.Expression => |base| switch (base.id) {
3218 ast.Node.Id.Identifier => {3239 ast.Node.Id.Identifier => {
3219 const identifier = @fieldParentPtr(ast.NodeIdentifier, "base", base);3240 const identifier = @fieldParentPtr(ast.NodeIdentifier, "base", base);
3220 try stream.print("{}", self.tokenizer.getTokenSlice(identifier.name_token));3241 try stream.print("{}", self.tokenizer.getTokenSlice(identifier.token));
3221 },3242 },
3222 ast.Node.Id.Block => {3243 ast.Node.Id.Block => {
3223 const block = @fieldParentPtr(ast.NodeBlock, "base", base);3244 const block = @fieldParentPtr(ast.NodeBlock, "base", base);