| ... | @@ -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 | }; |
| 121 | | 123 | |
| 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; |
| 197 | | 188 | |
| ... | @@ -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 casts | 266 | // 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 casts | 273 | // 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 cast | 282 | // 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 | }, |
| 801 | | 944 | |
| 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(); |
| 822 | | 947 | |
| ... | @@ -854,22 +979,20 @@ pub const Parser = struct { | ... | @@ -854,22 +979,20 @@ pub const Parser = struct { |
| 854 | }); | 979 | }); |
| 855 | }, | 980 | }, |
| 856 | | 981 | |
| | 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 | } | | |
| 869 | | 991 | |
| 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 | }, |
| 874 | | 997 | |
| 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 | } |
| 1091 | | 1214 | |
| | 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"), |
| 1888 | | 2087 | |