authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-03 20:00:02+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-03 20:00:02+02:00
logec611bf8b47af0db5244af644040907bfcb63945
treeb16541e6263b411d2c2877b2862cf2a1de36110f
parentd602f12df8f12c3a363abec8c1976f8bc84eb2be

std.zig.parser now parses regular enums, unions and struct

* Still missing packed, and extern

2 files changed, 350 insertions(+), 59 deletions(-)

std/zig/ast.zig+99-7
...@@ -12,6 +12,9 @@ pub const Node = struct {...@@ -12,6 +12,9 @@ pub const Node = struct {
12 Root,12 Root,
13 VarDecl,13 VarDecl,
14 ContainerDecl,14 ContainerDecl,
15 StructField,
16 UnionTag,
17 EnumTag,
15 Identifier,18 Identifier,
16 FnProto,19 FnProto,
17 ParamDecl,20 ParamDecl,
...@@ -42,6 +45,9 @@ pub const Node = struct {...@@ -42,6 +45,9 @@ pub const Node = struct {
42 Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index),45 Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index),
43 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index),46 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index),
44 Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index),47 Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index),
48 Id.StructField => @fieldParentPtr(NodeStructField, "base", base).iterate(index),
49 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).iterate(index),
50 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).iterate(index),
45 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).iterate(index),51 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).iterate(index),
46 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).iterate(index),52 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).iterate(index),
47 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).iterate(index),53 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).iterate(index),
...@@ -73,6 +79,9 @@ pub const Node = struct {...@@ -73,6 +79,9 @@ pub const Node = struct {
73 Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(),79 Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(),
74 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(),80 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(),
75 Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(),81 Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(),
82 Id.StructField => @fieldParentPtr(NodeStructField, "base", base).firstToken(),
83 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).firstToken(),
84 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).firstToken(),
76 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).firstToken(),85 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).firstToken(),
77 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).firstToken(),86 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).firstToken(),
78 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).firstToken(),87 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).firstToken(),
...@@ -104,6 +113,9 @@ pub const Node = struct {...@@ -104,6 +113,9 @@ pub const Node = struct {
104 Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(),113 Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(),
105 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(),114 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(),
106 Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(),115 Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(),
116 Id.StructField => @fieldParentPtr(NodeStructField, "base", base).lastToken(),
117 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).lastToken(),
118 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).lastToken(),
107 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).lastToken(),119 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).lastToken(),
108 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).lastToken(),120 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).lastToken(),
109 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).lastToken(),121 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).lastToken(),
...@@ -203,16 +215,15 @@ pub const NodeVarDecl = struct {...@@ -203,16 +215,15 @@ pub const NodeVarDecl = struct {
203pub const NodeContainerDecl = struct {215pub const NodeContainerDecl = struct {
204 base: Node,216 base: Node,
205 kind_token: Token,217 kind_token: Token,
206 init_arg_expr: InitArg,
207 kind: Kind,218 kind: Kind,
208 decls: ArrayList(&Node),219 init_arg_expr: InitArg,
220 fields_and_decls: ArrayList(&Node),
209 rbrace_token: Token,221 rbrace_token: Token,
210222
211 // TODO: Different array lists for each kind.223 const Kind = enum {
212 const Kind = union(enum) {224 Struct,
213 Struct: ArrayList(&Node),225 Enum,
214 Enum: ArrayList(&Node),226 Union,
215 Union: ArrayList(&Node),
216 };227 };
217228
218 const InitArg = union(enum) {229 const InitArg = union(enum) {
...@@ -263,6 +274,87 @@ pub const NodeContainerDecl = struct {...@@ -263,6 +274,87 @@ pub const NodeContainerDecl = struct {
263 }274 }
264};275};
265276
277pub const NodeStructField = struct {
278 base: Node,
279 name_token: Token,
280 type_expr: &Node,
281
282 pub fn iterate(self: &NodeStructField, index: usize) ?&Node {
283 var i = index;
284
285 if (i < 1) return self.type_expr;
286 i -= 1;
287
288 return null;
289 }
290
291 pub fn firstToken(self: &NodeStructField) Token {
292 return self.name_token;
293 }
294
295 pub fn lastToken(self: &NodeStructField) Token {
296 return self.type_expr.lastToken();
297 }
298};
299
300pub const NodeUnionTag = struct {
301 base: Node,
302 name_token: Token,
303 type_expr: ?&Node,
304
305 pub fn iterate(self: &NodeUnionTag, index: usize) ?&Node {
306 var i = index;
307
308 if (self.type_expr) |type_expr| {
309 if (i < 1) return type_expr;
310 i -= 1;
311 }
312
313 return null;
314 }
315
316 pub fn firstToken(self: &NodeUnionTag) Token {
317 return self.name_token;
318 }
319
320 pub fn lastToken(self: &NodeUnionTag) Token {
321 if (self.type_expr) |type_expr| {
322 return type_expr.lastToken();
323 }
324
325 return self.name_token;
326 }
327};
328
329pub const NodeEnumTag = struct {
330 base: Node,
331 name_token: Token,
332 value: ?&Node,
333
334 pub fn iterate(self: &NodeEnumTag, index: usize) ?&Node {
335 var i = index;
336
337 if (self.value) |value| {
338 if (i < 1) return value;
339 i -= 1;
340 }
341
342 return null;
343 }
344
345 pub fn firstToken(self: &NodeEnumTag) Token {
346 return self.name_token;
347 }
348
349 pub fn lastToken(self: &NodeEnumTag) Token {
350 if (self.value) |value| {
351 return value.lastToken();
352 }
353
354 return self.name_token;
355 }
356};
357
266pub const NodeIdentifier = struct {358pub const NodeIdentifier = struct {
267 base: Node,359 base: Node,
268 name_token: Token,360 name_token: Token,
std/zig/parser.zig+251-52
...@@ -90,6 +90,7 @@ pub const Parser = struct {...@@ -90,6 +90,7 @@ pub const Parser = struct {
90 TopLevel,90 TopLevel,
91 TopLevelExtern: TopLevelDeclCtx,91 TopLevelExtern: TopLevelDeclCtx,
92 TopLevelDecl: TopLevelDeclCtx,92 TopLevelDecl: TopLevelDeclCtx,
93 ContainerDecl: &ast.NodeContainerDecl,
93 Expression: DestPtr,94 Expression: DestPtr,
94 ExpectOperand,95 ExpectOperand,
95 Operand: &ast.Node,96 Operand: &ast.Node,
...@@ -117,6 +118,7 @@ pub const Parser = struct {...@@ -117,6 +118,7 @@ pub const Parser = struct {
117 ExprListCommaOrEnd: ListState(&ast.Node),118 ExprListCommaOrEnd: ListState(&ast.Node),
118 FieldInitListItemOrEnd: ListState(&ast.NodeFieldInitializer),119 FieldInitListItemOrEnd: ListState(&ast.NodeFieldInitializer),
119 FieldInitListCommaOrEnd: ListState(&ast.NodeFieldInitializer),120 FieldInitListCommaOrEnd: ListState(&ast.NodeFieldInitializer),
121 FieldListCommaOrEnd: &ast.NodeContainerDecl,
120 };122 };
121123
122 /// Returns an AST tree, allocated with the parser's allocator.124 /// Returns an AST tree, allocated with the parser's allocator.
...@@ -181,17 +183,6 @@ pub const Parser = struct {...@@ -181,17 +183,6 @@ pub const Parser = struct {
181 State.TopLevel => {183 State.TopLevel => {
182 const token = self.getNextToken();184 const token = self.getNextToken();
183 switch (token.id) {185 switch (token.id) {
184 Token.Id.Keyword_pub, Token.Id.Keyword_export => {
185 stack.append(State {
186 .TopLevelExtern = TopLevelDeclCtx {
187 .decls = &root_node.decls,
188 .visib_token = token,
189 .extern_token = null,
190 .lib_name = null,
191 }
192 }) catch unreachable;
193 continue;
194 },
195 Token.Id.Keyword_test => {186 Token.Id.Keyword_test => {
196 stack.append(State.TopLevel) catch unreachable;187 stack.append(State.TopLevel) catch unreachable;
197188
...@@ -213,16 +204,29 @@ pub const Parser = struct {...@@ -213,16 +204,29 @@ pub const Parser = struct {
213 root_node.eof_token = token;204 root_node.eof_token = token;
214 return Tree {.root_node = root_node, .arena_allocator = arena_allocator};205 return Tree {.root_node = root_node, .arena_allocator = arena_allocator};
215 },206 },
207 Token.Id.Keyword_pub, Token.Id.Keyword_export => {
208 stack.append(State.TopLevel) catch unreachable;
209 try stack.append(State {
210 .TopLevelExtern = TopLevelDeclCtx {
211 .decls = &root_node.decls,
212 .visib_token = token,
213 .extern_token = null,
214 .lib_name = null,
215 }
216 });
217 continue;
218 },
216 else => {219 else => {
217 self.putBackToken(token);220 self.putBackToken(token);
218 stack.append(State {221 stack.append(State.TopLevel) catch unreachable;
222 try stack.append(State {
219 .TopLevelExtern = TopLevelDeclCtx {223 .TopLevelExtern = TopLevelDeclCtx {
220 .decls = &root_node.decls,224 .decls = &root_node.decls,
221 .visib_token = null,225 .visib_token = null,
222 .extern_token = null,226 .extern_token = null,
223 .lib_name = null,227 .lib_name = null,
224 }228 }
225 }) catch unreachable;229 });
226 continue;230 continue;
227 },231 },
228 }232 }
...@@ -259,7 +263,6 @@ pub const Parser = struct {...@@ -259,7 +263,6 @@ pub const Parser = struct {
259 const token = self.getNextToken();263 const token = self.getNextToken();
260 switch (token.id) {264 switch (token.id) {
261 Token.Id.Keyword_var, Token.Id.Keyword_const => {265 Token.Id.Keyword_var, Token.Id.Keyword_const => {
262 stack.append(State.TopLevel) catch unreachable;
263 // TODO shouldn't need these casts266 // TODO shouldn't need these casts
264 const var_decl_node = try self.createAttachVarDecl(arena, ctx.decls, ctx.visib_token,267 const var_decl_node = try self.createAttachVarDecl(arena, ctx.decls, ctx.visib_token,
265 token, (?Token)(null), ctx.extern_token, ctx.lib_name);268 token, (?Token)(null), ctx.extern_token, ctx.lib_name);
...@@ -267,7 +270,6 @@ pub const Parser = struct {...@@ -267,7 +270,6 @@ pub const Parser = struct {
267 continue;270 continue;
268 },271 },
269 Token.Id.Keyword_fn => {272 Token.Id.Keyword_fn => {
270 stack.append(State.TopLevel) catch unreachable;
271 // TODO shouldn't need these casts273 // TODO shouldn't need these casts
272 const fn_proto = try self.createAttachFnProto(arena, ctx.decls, token,274 const fn_proto = try self.createAttachFnProto(arena, ctx.decls, token,
273 ctx.extern_token, ctx.lib_name, (?Token)(null), ctx.visib_token, (?Token)(null));275 ctx.extern_token, ctx.lib_name, (?Token)(null), ctx.visib_token, (?Token)(null));
...@@ -276,7 +278,6 @@ pub const Parser = struct {...@@ -276,7 +278,6 @@ pub const Parser = struct {
276 continue;278 continue;
277 },279 },
278 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {280 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
279 stack.append(State.TopLevel) catch unreachable;
280 const fn_token = try self.eatToken(Token.Id.Keyword_fn);281 const fn_token = try self.eatToken(Token.Id.Keyword_fn);
281 // TODO shouldn't need this cast282 // TODO shouldn't need this cast
282 const fn_proto = try self.createAttachFnProto(arena, ctx.decls, fn_token,283 const fn_proto = try self.createAttachFnProto(arena, ctx.decls, fn_token,
...@@ -336,6 +337,101 @@ pub const Parser = struct {...@@ -336,6 +337,101 @@ pub const Parser = struct {
336 }337 }
337 return self.parseError(token, "expected '=' or ';', found {}", @tagName(token.id));338 return self.parseError(token, "expected '=' or ';', found {}", @tagName(token.id));
338 },339 },
340
341 State.ContainerDecl => |container_decl| {
342 const token = self.getNextToken();
343
344 switch (token.id) {
345 Token.Id.Identifier => {
346 switch (container_decl.kind) {
347 ast.NodeContainerDecl.Kind.Struct => {
348 const node = try arena.create(ast.NodeStructField);
349 *node = ast.NodeStructField {
350 .base = self.initNode(ast.Node.Id.StructField),
351 .name_token = token,
352 .type_expr = undefined,
353 };
354 try container_decl.fields_and_decls.append(&node.base);
355
356 try stack.append(State { .FieldListCommaOrEnd = container_decl });
357 try stack.append(State { .Expression = DestPtr { .Field = &node.type_expr } });
358 try stack.append(State { .ExpectToken = Token.Id.Colon });
359 continue;
360 },
361 ast.NodeContainerDecl.Kind.Union => {
362 const node = try arena.create(ast.NodeUnionTag);
363 *node = ast.NodeUnionTag {
364 .base = self.initNode(ast.Node.Id.UnionTag),
365 .name_token = token,
366 .type_expr = null,
367 };
368 try container_decl.fields_and_decls.append(&node.base);
369
370 try stack.append(State { .FieldListCommaOrEnd = container_decl });
371
372 const next = self.getNextToken();
373 if (next.id != Token.Id.Colon) {
374 self.putBackToken(next);
375 continue;
376 }
377
378 try stack.append(State { .Expression = DestPtr { .NullableField = &node.type_expr } });
379 continue;
380 },
381 ast.NodeContainerDecl.Kind.Enum => {
382 const node = try arena.create(ast.NodeEnumTag);
383 *node = ast.NodeEnumTag {
384 .base = self.initNode(ast.Node.Id.EnumTag),
385 .name_token = token,
386 .value = null,
387 };
388 try container_decl.fields_and_decls.append(&node.base);
389
390 try stack.append(State { .FieldListCommaOrEnd = container_decl });
391
392 const next = self.getNextToken();
393 if (next.id != Token.Id.Equal) {
394 self.putBackToken(next);
395 continue;
396 }
397
398 try stack.append(State { .Expression = DestPtr { .NullableField = &node.value } });
399 continue;
400 },
401 }
402 },
403 Token.Id.Keyword_pub, Token.Id.Keyword_export => {
404 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
405 try stack.append(State {
406 .TopLevelExtern = TopLevelDeclCtx {
407 .decls = &container_decl.fields_and_decls,
408 .visib_token = token,
409 .extern_token = null,
410 .lib_name = null,
411 }
412 });
413 continue;
414 },
415 Token.Id.RBrace => {
416 container_decl.rbrace_token = token;
417 continue;
418 },
419 else => {
420 self.putBackToken(token);
421 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
422 try stack.append(State {
423 .TopLevelExtern = TopLevelDeclCtx {
424 .decls = &container_decl.fields_and_decls,
425 .visib_token = null,
426 .extern_token = null,
427 .lib_name = null,
428 }
429 });
430 continue;
431 }
432 }
433 },
434
339 State.ExpectToken => |token_id| {435 State.ExpectToken => |token_id| {
340 _ = try self.eatToken(token_id);436 _ = try self.eatToken(token_id);
341 continue;437 continue;
...@@ -537,6 +633,53 @@ pub const Parser = struct {...@@ -537,6 +633,53 @@ pub const Parser = struct {
537 try stack.append(State.AfterOperand);633 try stack.append(State.AfterOperand);
538 continue;634 continue;
539 },635 },
636 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {
637 const node = try arena.create(ast.NodeContainerDecl);
638 *node = ast.NodeContainerDecl {
639 .base = self.initNode(ast.Node.Id.ContainerDecl),
640 .kind_token = token,
641 .kind = switch (token.id) {
642 Token.Id.Keyword_struct => ast.NodeContainerDecl.Kind.Struct,
643 Token.Id.Keyword_union => ast.NodeContainerDecl.Kind.Union,
644 Token.Id.Keyword_enum => ast.NodeContainerDecl.Kind.Enum,
645 else => unreachable,
646 },
647 .init_arg_expr = undefined,
648 .fields_and_decls = ArrayList(&ast.Node).init(arena),
649 .rbrace_token = undefined,
650 };
651
652 try stack.append(State { .Operand = &node.base });
653 try stack.append(State.AfterOperand);
654 try stack.append(State { .ContainerDecl = node });
655 try stack.append(State { .ExpectToken = Token.Id.LBrace });
656
657 const lparen = self.getNextToken();
658 if (lparen.id != Token.Id.LParen) {
659 self.putBackToken(lparen);
660 node.init_arg_expr = ast.NodeContainerDecl.InitArg.None;
661 continue;
662 }
663
664 try stack.append(State { .ExpectToken = Token.Id.RParen });
665
666 const init_arg_token = self.getNextToken();
667 switch (init_arg_token.id) {
668 Token.Id.Keyword_enum => {
669 node.init_arg_expr = ast.NodeContainerDecl.InitArg.Enum;
670 },
671 else => {
672 self.putBackToken(lparen);
673 node.init_arg_expr = ast.NodeContainerDecl.InitArg { .Type = undefined };
674 try stack.append(State {
675 .Expression = DestPtr {
676 .Field = &node.init_arg_expr.Type
677 }
678 });
679 },
680 }
681 continue;
682 },
540 Token.Id.Builtin => {683 Token.Id.Builtin => {
541 const node = try arena.create(ast.NodeBuiltinCall);684 const node = try arena.create(ast.NodeBuiltinCall);
542 *node = ast.NodeBuiltinCall {685 *node = ast.NodeBuiltinCall {
...@@ -799,24 +942,6 @@ pub const Parser = struct {...@@ -799,24 +942,6 @@ pub const Parser = struct {
799 try stack.append(State { .Expression = DestPtr{.List = list_state.list} });942 try stack.append(State { .Expression = DestPtr{.List = list_state.list} });
800 },943 },
801944
802 State.ExprListCommaOrEnd => |list_state| {
803 var token = self.getNextToken();
804 switch (token.id) {
805 Token.Id.Comma => {
806 stack.append(State { .ExprListItemOrEnd = list_state }) catch unreachable;
807 },
808 else => {
809 const IdTag = @TagType(Token.Id);
810 if (IdTag(list_state.end) == token.id) {
811 *list_state.ptr = token;
812 continue;
813 }
814
815 return self.parseError(token, "expected ',' or {}, found {}", @tagName(list_state.end), @tagName(token.id));
816 },
817 }
818 },
819
820 State.FieldInitListItemOrEnd => |list_state| {945 State.FieldInitListItemOrEnd => |list_state| {
821 var token = self.getNextToken();946 var token = self.getNextToken();
822947
...@@ -854,22 +979,20 @@ pub const Parser = struct {...@@ -854,22 +979,20 @@ pub const Parser = struct {
854 });979 });
855 },980 },
856981
982 State.ExprListCommaOrEnd => |list_state| {
983 try self.commaOrEnd(&stack, list_state.end, list_state.ptr, State { .ExprListItemOrEnd = list_state });
984 continue;
985 },
986
857 State.FieldInitListCommaOrEnd => |list_state| {987 State.FieldInitListCommaOrEnd => |list_state| {
858 var token = self.getNextToken();988 try self.commaOrEnd(&stack, list_state.end, list_state.ptr, State { .FieldInitListItemOrEnd = list_state });
859 switch (token.id) {989 continue;
860 Token.Id.Comma => {990 },
861 stack.append(State { .FieldInitListItemOrEnd = list_state }) catch unreachable;
862 },
863 else => {
864 const IdTag = @TagType(Token.Id);
865 if (IdTag(list_state.end) == token.id) {
866 *list_state.ptr = token;
867 continue;
868 }
869991
870 return self.parseError(token, "expected ',' or {}, found {}", @tagName(list_state.end), @tagName(token.id));992 State.FieldListCommaOrEnd => |container_decl| {
871 },993 try self.commaOrEnd(&stack, Token.Id.RBrace, &container_decl.rbrace_token,
872 }994 State { .ContainerDecl = container_decl });
995 continue;
873 },996 },
874997
875 State.AddrOfModifiers => |addr_of_info| {998 State.AddrOfModifiers => |addr_of_info| {
...@@ -1089,6 +1212,24 @@ pub const Parser = struct {...@@ -1089,6 +1212,24 @@ pub const Parser = struct {
1089 }1212 }
1090 }1213 }
10911214
1215 fn commaOrEnd(self: &Parser, stack: &ArrayList(State), end: &const Token.Id, ptr: &Token, state_after_comma: &const State) !void {
1216 var token = self.getNextToken();
1217 switch (token.id) {
1218 Token.Id.Comma => {
1219 stack.append(state_after_comma) catch unreachable;
1220 },
1221 else => {
1222 const IdTag = @TagType(Token.Id);
1223 if (IdTag(*end) == token.id) {
1224 *ptr = token;
1225 return;
1226 }
1227
1228 return self.parseError(token, "expected ',' or {}, found {}", @tagName(*end), @tagName(token.id));
1229 },
1230 }
1231 }
1232
1092 fn popSuffixOp(stack: &ArrayList(State)) &ast.Node {1233 fn popSuffixOp(stack: &ArrayList(State)) &ast.Node {
1093 var expression: &ast.Node = undefined;1234 var expression: &ast.Node = undefined;
1094 var left_leaf_ptr: &&ast.Node = &expression;1235 var left_leaf_ptr: &&ast.Node = &expression;
...@@ -1806,10 +1947,6 @@ pub const Parser = struct {...@@ -1806,10 +1947,6 @@ pub const Parser = struct {
1806 try stack.append(RenderState { .Expression = grouped_expr.expr });1947 try stack.append(RenderState { .Expression = grouped_expr.expr });
1807 try stack.append(RenderState { .Text = "("});1948 try stack.append(RenderState { .Text = "("});
1808 },1949 },
1809 ast.Node.Id.ContainerDecl => {
1810 const container_decl = @fieldParentPtr(ast.NodeGroupedExpression, "base", base);
1811 @panic("TODO: ContainerDecl");
1812 },
1813 ast.Node.Id.FieldInitializer => {1950 ast.Node.Id.FieldInitializer => {
1814 const field_init = @fieldParentPtr(ast.NodeFieldInitializer, "base", base);1951 const field_init = @fieldParentPtr(ast.NodeFieldInitializer, "base", base);
1815 try stream.print(".{} = ", self.tokenizer.getTokenSlice(field_init.name_token));1952 try stream.print(".{} = ", self.tokenizer.getTokenSlice(field_init.name_token));
...@@ -1851,6 +1988,46 @@ pub const Parser = struct {...@@ -1851,6 +1988,46 @@ pub const Parser = struct {
1851 const error_type = @fieldParentPtr(ast.NodeErrorType, "base", base);1988 const error_type = @fieldParentPtr(ast.NodeErrorType, "base", base);
1852 try stream.print("{}", self.tokenizer.getTokenSlice(error_type.token));1989 try stream.print("{}", self.tokenizer.getTokenSlice(error_type.token));
1853 },1990 },
1991 ast.Node.Id.ContainerDecl => {
1992 const container_decl = @fieldParentPtr(ast.NodeContainerDecl, "base", base);
1993 try stream.print("{} {{", self.tokenizer.getTokenSlice(container_decl.kind_token));
1994 try stack.append(RenderState { .Text = "}"});
1995 try stack.append(RenderState.PrintIndent);
1996 try stack.append(RenderState { .Indent = indent });
1997
1998 const fields_and_decls = container_decl.fields_and_decls.toSliceConst();
1999 var i = fields_and_decls.len;
2000 while (i != 0) {
2001 i -= 1;
2002 const node = fields_and_decls[i];
2003 if (i != 0) {
2004 switch (node.id) {
2005 ast.Node.Id.StructField,
2006 ast.Node.Id.UnionTag,
2007 ast.Node.Id.EnumTag => {
2008 try stack.append(RenderState { .Text = "," });
2009 },
2010 else => { }
2011 }
2012 }
2013 try stack.append(RenderState { .Expression = node});
2014 try stack.append(RenderState.PrintIndent);
2015 try stack.append(RenderState {
2016 .Text = blk: {
2017 if (i != 0) {
2018 const prev_node = fields_and_decls[i - 1];
2019 const prev_line_index = prev_node.lastToken().line;
2020 const this_line_index = node.firstToken().line;
2021 if (this_line_index - prev_line_index >= 2) {
2022 break :blk "\n\n";
2023 }
2024 }
2025 break :blk "\n";
2026 },
2027 });
2028 }
2029 try stack.append(RenderState { .Indent = indent + indent_delta});
2030 },
1854 ast.Node.Id.MultilineStringLiteral => {2031 ast.Node.Id.MultilineStringLiteral => {
1855 const multiline_str_literal = @fieldParentPtr(ast.NodeMultilineStringLiteral, "base", base);2032 const multiline_str_literal = @fieldParentPtr(ast.NodeMultilineStringLiteral, "base", base);
1856 try stream.print("\n");2033 try stream.print("\n");
...@@ -1883,6 +2060,28 @@ pub const Parser = struct {...@@ -1883,6 +2060,28 @@ pub const Parser = struct {
1883 }2060 }
1884 }2061 }
1885 },2062 },
2063 ast.Node.Id.StructField => {
2064 const field = @fieldParentPtr(ast.NodeStructField, "base", base);
2065 try stream.print("{}:", self.tokenizer.getTokenSlice(field.name_token));
2066 },
2067 ast.Node.Id.UnionTag => {
2068 const tag = @fieldParentPtr(ast.NodeUnionTag, "base", base);
2069 try stream.print("{}", self.tokenizer.getTokenSlice(tag.name_token));
2070
2071 if (tag.type_expr) |type_expr| {
2072 try stream.print(": ");
2073 try stack.append(RenderState { .Expression = type_expr});
2074 }
2075 },
2076 ast.Node.Id.EnumTag => {
2077 const tag = @fieldParentPtr(ast.NodeEnumTag, "base", base);
2078 try stream.print("{}", self.tokenizer.getTokenSlice(tag.name_token));
2079
2080 if (tag.value) |value| {
2081 try stream.print(" = ");
2082 try stack.append(RenderState { .Expression = value});
2083 }
2084 },
1886 ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"),2085 ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"),
1887 ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"),2086 ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"),
18882087