authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-04 23:36:55+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-04 23:36:55+02:00
log779247ba114492a28287bc2026719091b7022e1d
treeb36eec7a6977f50582d6d934d9db446e6310ee76
parent744416ce0cd23c84e33965fc8171c0d1aea0659c

std.zig Major Refactor

* parser now parses expression like the C++ compiler does * This makes initializers work * Added control flow expression (only return is parsed) * Added catch parsing (It doesn't quite work) * The parse can now specify states as optional. * The parse will roll back on error if states are optional * This can be overriden by State.Required

3 files changed, 1071 insertions(+), 678 deletions(-)

std/zig/ast.zig+58-2
......@@ -24,6 +24,7 @@ pub const Node = struct {
2424 PrefixOp,
2525 SuffixOp,
2626 GroupedExpression,
27 ControlFlowExpression,
2728 FieldInitializer,
2829 IntegerLiteral,
2930 FloatLiteral,
......@@ -58,6 +59,7 @@ pub const Node = struct {
5859 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index),
5960 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),
6061 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).iterate(index),
62 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).iterate(index),
6163 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).iterate(index),
6264 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).iterate(index),
6365 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).iterate(index),
......@@ -93,6 +95,7 @@ pub const Node = struct {
9395 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(),
9496 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),
9597 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).firstToken(),
98 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).firstToken(),
9699 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).firstToken(),
97100 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).firstToken(),
98101 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).firstToken(),
......@@ -128,6 +131,7 @@ pub const Node = struct {
128131 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(),
129132 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),
130133 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).lastToken(),
134 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).lastToken(),
131135 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).lastToken(),
132136 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).lastToken(),
133137 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).lastToken(),
......@@ -531,7 +535,7 @@ pub const NodeInfixOp = struct {
531535 op: InfixOp,
532536 rhs: &Node,
533537
534 const InfixOp = enum {
538 const InfixOp = union(enum) {
535539 Add,
536540 AddWrap,
537541 ArrayCat,
......@@ -558,6 +562,7 @@ pub const NodeInfixOp = struct {
558562 BitXor,
559563 BoolAnd,
560564 BoolOr,
565 Catch: ?&NodeIdentifier,
561566 Div,
562567 EqualEqual,
563568 ErrorUnion,
......@@ -651,9 +656,9 @@ pub const NodePrefixOp = struct {
651656 BitNot,
652657 BoolNot,
653658 Deref,
659 MaybeType,
654660 Negation,
655661 NegationWrap,
656 Return,
657662 ArrayType: &Node,
658663 SliceType: AddrOfInfo,
659664 Try,
......@@ -754,6 +759,7 @@ pub const NodeSuffixOp = struct {
754759 const CallInfo = struct {
755760 params: ArrayList(&Node),
756761 is_async: bool,
762 allocator: ?&Node,
757763 };
758764
759765 const SliceRange = struct {
......@@ -831,6 +837,56 @@ pub const NodeGroupedExpression = struct {
831837 }
832838};
833839
840pub const NodeControlFlowExpression = struct {
841 base: Node,
842 ltoken: Token,
843 kind: Kind,
844 rhs: ?&Node,
845
846 const Kind = union(enum) {
847 Break: ?Token,
848 Continue: ?Token,
849 Return,
850 };
851
852 pub fn iterate(self: &NodeControlFlowExpression, index: usize) ?&Node {
853 var i = index;
854
855 if (self.rhs) |rhs| {
856 if (i < 1) return rhs;
857 i -= 1;
858 }
859
860 return null;
861 }
862
863 pub fn firstToken(self: &NodeControlFlowExpression) Token {
864 return self.ltoken;
865 }
866
867 pub fn lastToken(self: &NodeControlFlowExpression) Token {
868 if (self.rhs) |rhs| {
869 return rhs.lastToken();
870 }
871
872 switch (self.kind) {
873 Kind.Break => |maybe_blk_token| {
874 if (maybe_blk_token) |blk_token| {
875 return blk_token;
876 }
877 },
878 Kind.Continue => |maybe_blk_token| {
879 if (maybe_blk_token) |blk_token| {
880 return blk_token;
881 }
882 },
883 Kind.Return => return self.ltoken,
884 }
885
886 return self.ltoken;
887 }
888};
889
834890pub const NodeIntegerLiteral = struct {
835891 base: Node,
836892 token: Token,
std/zig/parser.zig+1003-676
......@@ -60,6 +60,7 @@ pub const Parser = struct {
6060 };
6161
6262 const ContainerExternCtx = struct {
63 dest_ptr: DestPtr,
6364 ltoken: Token,
6465 layout: ast.NodeContainerDecl.Layout,
6566 };
......@@ -67,13 +68,18 @@ pub const Parser = struct {
6768 const DestPtr = union(enum) {
6869 Field: &&ast.Node,
6970 NullableField: &?&ast.Node,
70 List: &ArrayList(&ast.Node),
7171
72 pub fn store(self: &const DestPtr, value: &ast.Node) !void {
72 pub fn store(self: &const DestPtr, value: &ast.Node) void {
7373 switch (*self) {
7474 DestPtr.Field => |ptr| *ptr = value,
7575 DestPtr.NullableField => |ptr| *ptr = value,
76 DestPtr.List => |list| try list.append(value),
76 }
77 }
78
79 pub fn get(self: &const DestPtr) &ast.Node {
80 switch (*self) {
81 DestPtr.Field => |ptr| return *ptr,
82 DestPtr.NullableField => |ptr| return ??*ptr,
7783 }
7884 }
7985 };
......@@ -97,19 +103,13 @@ pub const Parser = struct {
97103 TopLevelDecl: TopLevelDeclCtx,
98104 ContainerExtern: ContainerExternCtx,
99105 ContainerDecl: &ast.NodeContainerDecl,
100 Expression: DestPtr,
101 ExpectOperand,
102 Operand: &ast.Node,
103 AfterOperand,
104 InfixOp: &ast.NodeInfixOp,
105 PrefixOp: &ast.NodePrefixOp,
106 SuffixOp: &ast.NodeSuffixOp,
107106 SliceOrArrayAccess: &ast.NodeSuffixOp,
108107 AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
109 TypeExpr: DestPtr,
110108 VarDecl: &ast.NodeVarDecl,
111109 VarDeclAlign: &ast.NodeVarDecl,
112110 VarDeclEq: &ast.NodeVarDecl,
111 IfToken: @TagType(Token.Id),
112 IfTokenSave: ExpectTokenSave,
113113 ExpectToken: @TagType(Token.Id),
114114 ExpectTokenSave: ExpectTokenSave,
115115 FnProto: &ast.NodeFnProto,
......@@ -125,6 +125,48 @@ pub const Parser = struct {
125125 FieldInitListItemOrEnd: ListState(&ast.NodeFieldInitializer),
126126 FieldInitListCommaOrEnd: ListState(&ast.NodeFieldInitializer),
127127 FieldListCommaOrEnd: &ast.NodeContainerDecl,
128
129 /// A state that can be appended before any other State. If an error occures,
130 /// the parser will first try looking for the closest optional state. If an
131 /// optional state is found, the parser will revert to the state it was in
132 /// when the optional was added. This will polute the arena allocator with
133 /// "leaked" nodes. TODO: Figure out if it's nessesary to handle leaked nodes.
134 Optional: Parser,
135
136 /// Optional can be reverted by adding the Required state to the stack.
137 Required,
138
139 Expression: DestPtr,
140 AssignmentExpressionBegin: DestPtr,
141 AssignmentExpressionEnd: DestPtr,
142 UnwrapExpressionBegin: DestPtr,
143 UnwrapExpressionEnd: DestPtr,
144 BoolOrExpressionBegin: DestPtr,
145 BoolOrExpressionEnd: DestPtr,
146 BoolAndExpressionBegin: DestPtr,
147 BoolAndExpressionEnd: DestPtr,
148 ComparisonExpressionBegin: DestPtr,
149 ComparisonExpressionEnd: DestPtr,
150 BinaryOrExpressionBegin: DestPtr,
151 BinaryOrExpressionEnd: DestPtr,
152 BinaryXorExpressionBegin: DestPtr,
153 BinaryXorExpressionEnd: DestPtr,
154 BinaryAndExpressionBegin: DestPtr,
155 BinaryAndExpressionEnd: DestPtr,
156 BitShiftExpressionBegin: DestPtr,
157 BitShiftExpressionEnd: DestPtr,
158 AdditionExpressionBegin: DestPtr,
159 AdditionExpressionEnd: DestPtr,
160 MultiplyExpressionBegin: DestPtr,
161 MultiplyExpressionEnd: DestPtr,
162 CurlySuffixExpressionBegin: DestPtr,
163 CurlySuffixExpressionEnd: DestPtr,
164 TypeExprBegin: DestPtr,
165 TypeExprEnd: DestPtr,
166 PrefixOpExpression: DestPtr,
167 SuffixOpExpressionBegin: DestPtr,
168 SuffixOpExpressionEnd: DestPtr,
169 PrimaryExpression: DestPtr,
128170 };
129171
130172 /// Returns an AST tree, allocated with the parser's allocator.
......@@ -193,12 +235,16 @@ pub const Parser = struct {
193235 stack.append(State.TopLevel) catch unreachable;
194236
195237 const name_token = self.getNextToken();
196 if (name_token.id != Token.Id.StringLiteral)
197 return self.parseError(token, "expected {}, found {}", @tagName(Token.Id.StringLiteral), @tagName(name_token.id));
238 if (name_token.id != Token.Id.StringLiteral) {
239 try self.parseError(&stack, token, "expected {}, found {}", @tagName(Token.Id.StringLiteral), @tagName(name_token.id));
240 continue;
241 }
198242
199243 const lbrace = self.getNextToken();
200 if (lbrace.id != Token.Id.LBrace)
201 return self.parseError(token, "expected {}, found {}", @tagName(Token.Id.LBrace), @tagName(name_token.id));
244 if (lbrace.id != Token.Id.LBrace) {
245 try self.parseError(&stack, token, "expected {}, found {}", @tagName(Token.Id.LBrace), @tagName(name_token.id));
246 continue;
247 }
202248
203249 const name = try self.createStringLiteral(arena, name_token);
204250 const block = try self.createBlock(arena, token);
......@@ -284,28 +330,35 @@ pub const Parser = struct {
284330 continue;
285331 },
286332 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
287 const fn_token = try self.eatToken(Token.Id.Keyword_fn);
288333 // TODO shouldn't need this cast
289 const fn_proto = try self.createAttachFnProto(arena, ctx.decls, fn_token,
334 const fn_proto = try self.createAttachFnProto(arena, ctx.decls, undefined,
290335 ctx.extern_token, ctx.lib_name, (?Token)(token), (?Token)(null), (?Token)(null));
291336 try stack.append(State { .FnDef = fn_proto });
292337 try stack.append(State { .FnProto = fn_proto });
338 try stack.append(State {
339 .ExpectTokenSave = ExpectTokenSave {
340 .id = Token.Id.Keyword_fn,
341 .ptr = &fn_proto.fn_token,
342 }
343 });
344 continue;
345 },
346 else => {
347 try self.parseError(&stack, token, "expected variable declaration or function, found {}", @tagName(token.id));
293348 continue;
294349 },
295 else => return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id)),
296350 }
297351 },
298352 State.VarDecl => |var_decl| {
299 var_decl.name_token = try self.eatToken(Token.Id.Identifier);
300353 stack.append(State { .VarDeclAlign = var_decl }) catch unreachable;
301
302 const next_token = self.getNextToken();
303 if (next_token.id == Token.Id.Colon) {
304 try stack.append(State { .TypeExpr = DestPtr {.NullableField = &var_decl.type_node} });
305 continue;
306 }
307
308 self.putBackToken(next_token);
354 try stack.append(State { .TypeExprBegin = DestPtr {.NullableField = &var_decl.type_node} });
355 try stack.append(State { .IfToken = Token.Id.Colon });
356 try stack.append(State {
357 .ExpectTokenSave = ExpectTokenSave {
358 .id = Token.Id.Identifier,
359 .ptr = &var_decl.name_token,
360 }
361 });
309362 continue;
310363 },
311364 State.VarDeclAlign => |var_decl| {
......@@ -313,9 +366,9 @@ pub const Parser = struct {
313366
314367 const next_token = self.getNextToken();
315368 if (next_token.id == Token.Id.Keyword_align) {
316 _ = try self.eatToken(Token.Id.LParen);
317369 try stack.append(State { .ExpectToken = Token.Id.RParen });
318370 try stack.append(State { .Expression = DestPtr{.NullableField = &var_decl.align_node} });
371 try stack.append(State { .ExpectToken = Token.Id.LParen });
319372 continue;
320373 }
321374
......@@ -341,7 +394,8 @@ pub const Parser = struct {
341394 var_decl.semicolon_token = token;
342395 continue;
343396 }
344 return self.parseError(token, "expected '=' or ';', found {}", @tagName(token.id));
397 try self.parseError(&stack, token, "expected '=' or ';', found {}", @tagName(token.id));
398 continue;
345399 },
346400
347401 State.ContainerExtern => |ctx| {
......@@ -357,20 +411,20 @@ pub const Parser = struct {
357411 Token.Id.Keyword_union => ast.NodeContainerDecl.Kind.Union,
358412 Token.Id.Keyword_enum => ast.NodeContainerDecl.Kind.Enum,
359413 else => {
360 return self.parseError(token, "expected {}, {} or {}, found {}",
414 try self.parseError(&stack, token, "expected {}, {} or {}, found {}",
361415 @tagName(Token.Id.Keyword_struct),
362416 @tagName(Token.Id.Keyword_union),
363417 @tagName(Token.Id.Keyword_enum),
364418 @tagName(token.id));
419 continue;
365420 },
366421 },
367422 .init_arg_expr = undefined,
368423 .fields_and_decls = ArrayList(&ast.Node).init(arena),
369424 .rbrace_token = undefined,
370425 };
426 ctx.dest_ptr.store(&node.base);
371427
372 try stack.append(State { .Operand = &node.base });
373 try stack.append(State.AfterOperand);
374428 try stack.append(State { .ContainerDecl = node });
375429 try stack.append(State { .ExpectToken = Token.Id.LBrace });
376430
......@@ -496,144 +550,569 @@ pub const Parser = struct {
496550 },
497551
498552 State.ExpectToken => |token_id| {
499 _ = try self.eatToken(token_id);
553 _ = (try self.eatToken(&stack, token_id)) ?? continue;
500554 continue;
501555 },
502556
503557 State.ExpectTokenSave => |expect_token_save| {
504 *expect_token_save.ptr = try self.eatToken(expect_token_save.id);
558 *expect_token_save.ptr = (try self.eatToken(&stack, expect_token_save.id)) ?? continue;
505559 continue;
506560 },
507561
508 State.Expression => |dest_ptr| {
509 // save the dest_ptr for later
510 stack.append(state) catch unreachable;
511 try stack.append(State.ExpectOperand);
562 State.IfToken => |token_id| {
563 const token = self.getNextToken();
564 if (@TagType(Token.Id)(token.id) != token_id) {
565 self.putBackToken(token);
566 _ = stack.pop();
567 continue;
568 }
569 continue;
570 },
571
572 State.IfTokenSave => |if_token_save| {
573 const token = self.getNextToken();
574 if (@TagType(Token.Id)(token.id) != if_token_save.id) {
575 self.putBackToken(token);
576 _ = stack.pop();
577 continue;
578 }
579
580 *if_token_save.ptr = token;
512581 continue;
513582 },
514 State.ExpectOperand => {
515 // we'll either get an operand (like 1 or x),
516 // or a prefix operator (like ~ or return).
583
584 State.Optional,
585 State.Required => { },
586
587 State.Expression => |dest_ptr| {
517588 const token = self.getNextToken();
518589 switch (token.id) {
590 Token.Id.Keyword_try => {
591 const node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp.Try);
592 dest_ptr.store(&node.base);
593
594 stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }) catch unreachable;
595 continue;
596 },
519597 Token.Id.Keyword_return => {
520 try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
521 ast.NodePrefixOp.PrefixOp.Return) });
522 try stack.append(State.ExpectOperand);
598 const node = try self.createControlFlowExpr(arena, token, ast.NodeControlFlowExpression.Kind.Return);
599 dest_ptr.store(&node.base);
600
601 stack.append(State { .Optional = *self }) catch unreachable;
602 try stack.append(State { .Expression = DestPtr { .NullableField = &node.rhs } });
523603 continue;
524604 },
525 Token.Id.Keyword_try => {
526 try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
527 ast.NodePrefixOp.PrefixOp.Try) });
528 try stack.append(State.ExpectOperand);
605 Token.Id.Keyword_break => {
606 @panic("TODO: break");
607 },
608 Token.Id.Keyword_continue => {
609 @panic("TODO: break");
610 },
611 Token.Id.Keyword_cancel => {
612 @panic("TODO: cancel");
613 },
614 Token.Id.Keyword_resume => {
615 @panic("TODO: resume");
616 },
617 Token.Id.Keyword_await => {
618 @panic("TODO: await");
619 },
620 Token.Id.Keyword_suspend => {
621 @panic("TODO: suspend");
622 },
623 else => {
624 self.putBackToken(token);
625 stack.append(State { .AssignmentExpressionBegin = dest_ptr }) catch unreachable;
626 continue;
627 }
628 }
629 },
630
631 State.AssignmentExpressionBegin => |dest_ptr| {
632 try stack.append(State { .AssignmentExpressionEnd = dest_ptr });
633 stack.append(State { .UnwrapExpressionBegin = dest_ptr }) catch unreachable;
634 continue;
635 },
636
637 State.AssignmentExpressionEnd => |dest_ptr| {
638 const token = self.getNextToken();
639 if (tokenIdToAssignment(token.id)) |ass_id| {
640 const node = try self.createInfixOp(arena, token, ass_id);
641 node.lhs = dest_ptr.get();
642 dest_ptr.store(&node.base);
643
644 stack.append(State { .AssignmentExpressionEnd = dest_ptr }) catch unreachable;
645 try stack.append(State { .UnwrapExpressionBegin = DestPtr { .Field = &node.rhs } });
646 continue;
647 } else {
648 self.putBackToken(token);
649 continue;
650 }
651 },
652
653 State.UnwrapExpressionBegin => |dest_ptr| {
654 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;
655 try stack.append(State { .BoolOrExpressionBegin = dest_ptr });
656 continue;
657 },
658
659 State.UnwrapExpressionEnd => |dest_ptr| {
660 const token = self.getNextToken();
661 switch (token.id) {
662 Token.Id.Keyword_catch => {
663 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp { .Catch = null });
664 node.lhs = dest_ptr.get();
665 dest_ptr.store(&node.base);
666
667 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;
668 try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } });
669
670 const next = self.getNextToken();
671 if (next.id != Token.Id.Pipe) {
672 self.putBackToken(next);
673 continue;
674 }
675
676 node.op.Catch = try self.createIdentifier(arena, undefined);
677 try stack.append(State { .ExpectToken = Token.Id.Pipe });
678 try stack.append(State {
679 .ExpectTokenSave = ExpectTokenSave {
680 .id = Token.Id.Identifier,
681 .ptr = &(??node.op.Catch).name_token
682 }
683 });
529684 continue;
530685 },
531 Token.Id.Minus => {
532 try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
533 ast.NodePrefixOp.PrefixOp.Negation) });
534 try stack.append(State.ExpectOperand);
686 Token.Id.QuestionMarkQuestionMark => {
687 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.UnwrapMaybe);
688 node.lhs = dest_ptr.get();
689 dest_ptr.store(&node.base);
690
691 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;
692 try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } });
535693 continue;
536694 },
537 Token.Id.MinusPercent => {
538 try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
539 ast.NodePrefixOp.PrefixOp.NegationWrap) });
540 try stack.append(State.ExpectOperand);
695 else => {
696 self.putBackToken(token);
541697 continue;
542698 },
543 Token.Id.Tilde => {
544 try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
545 ast.NodePrefixOp.PrefixOp.BitNot) });
546 try stack.append(State.ExpectOperand);
699 }
700 },
701
702 State.BoolOrExpressionBegin => |dest_ptr| {
703 stack.append(State { .BoolOrExpressionEnd = dest_ptr }) catch unreachable;
704 try stack.append(State { .BoolAndExpressionBegin = dest_ptr });
705 continue;
706 },
707
708 State.BoolOrExpressionEnd => |dest_ptr| {
709 const token = self.getNextToken();
710 switch (token.id) {
711 Token.Id.Keyword_or => {
712 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.BoolOr);
713 node.lhs = dest_ptr.get();
714 dest_ptr.store(&node.base);
715
716 stack.append(State { .BoolOrExpressionEnd = dest_ptr }) catch unreachable;
717 try stack.append(State { .BoolAndExpressionBegin = DestPtr { .Field = &node.rhs } });
547718 continue;
548719 },
549 Token.Id.QuestionMarkQuestionMark => {
550 try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
551 ast.NodePrefixOp.PrefixOp.UnwrapMaybe) });
552 try stack.append(State.ExpectOperand);
720 else => {
721 self.putBackToken(token);
553722 continue;
554723 },
555 Token.Id.Bang => {
556 try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
557 ast.NodePrefixOp.PrefixOp.BoolNot) });
558 try stack.append(State.ExpectOperand);
724 }
725 },
726
727 State.BoolAndExpressionBegin => |dest_ptr| {
728 stack.append(State { .BoolAndExpressionEnd = dest_ptr }) catch unreachable;
729 try stack.append(State { .ComparisonExpressionBegin = dest_ptr });
730 continue;
731 },
732
733 State.BoolAndExpressionEnd => |dest_ptr| {
734 const token = self.getNextToken();
735 switch (token.id) {
736 Token.Id.Keyword_and => {
737 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.BoolAnd);
738 node.lhs = dest_ptr.get();
739 dest_ptr.store(&node.base);
740
741 stack.append(State { .BoolAndExpressionEnd = dest_ptr }) catch unreachable;
742 try stack.append(State { .ComparisonExpressionBegin = DestPtr { .Field = &node.rhs } });
559743 continue;
560744 },
561 Token.Id.Asterisk => {
562 try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
563 ast.NodePrefixOp.PrefixOp.Deref) });
564 try stack.append(State.ExpectOperand);
745 else => {
746 self.putBackToken(token);
565747 continue;
566748 },
567 Token.Id.LBracket => {
568 const rbracket_token = self.getNextToken();
569 if (rbracket_token.id == Token.Id.RBracket) {
570 const prefix_op = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp{
571 .SliceType = ast.NodePrefixOp.AddrOfInfo {
572 .align_expr = null,
573 .bit_offset_start_token = null,
574 .bit_offset_end_token = null,
575 .const_token = null,
576 .volatile_token = null,
577 }
578 });
579 try stack.append(State { .PrefixOp = prefix_op });
580 try stack.append(State.ExpectOperand);
581 try stack.append(State { .AddrOfModifiers = &prefix_op.op.AddrOf });
582 continue;
583 }
749 }
750 },
584751
585 self.putBackToken(rbracket_token);
752 State.ComparisonExpressionBegin => |dest_ptr| {
753 stack.append(State { .ComparisonExpressionEnd = dest_ptr }) catch unreachable;
754 try stack.append(State { .BinaryOrExpressionBegin = dest_ptr });
755 continue;
756 },
586757
587 const prefix_op = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp{
588 .ArrayType = undefined,
589 });
590 try stack.append(State { .PrefixOp = prefix_op });
591 try stack.append(State.ExpectOperand);
592 try stack.append(State { .ExpectToken = Token.Id.RBracket });
593 try stack.append(State { .Expression = DestPtr { .Field = &prefix_op.op.ArrayType } });
758 State.ComparisonExpressionEnd => |dest_ptr| {
759 const token = self.getNextToken();
760 if (tokenIdToComparison(token.id)) |comp_id| {
761 const node = try self.createInfixOp(arena, token, comp_id);
762 node.lhs = dest_ptr.get();
763 dest_ptr.store(&node.base);
764
765 stack.append(State { .ComparisonExpressionEnd = dest_ptr }) catch unreachable;
766 try stack.append(State { .BinaryOrExpressionBegin = DestPtr { .Field = &node.rhs } });
767 continue;
768 } else {
769 self.putBackToken(token);
770 continue;
771 }
772 },
773
774 State.BinaryOrExpressionBegin => |dest_ptr| {
775 stack.append(State { .BinaryOrExpressionEnd = dest_ptr }) catch unreachable;
776 try stack.append(State { .BinaryXorExpressionBegin = dest_ptr });
777 continue;
778 },
779
780 State.BinaryOrExpressionEnd => |dest_ptr| {
781 const token = self.getNextToken();
782 switch (token.id) {
783 Token.Id.Pipe => {
784 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.BitOr);
785 node.lhs = dest_ptr.get();
786 dest_ptr.store(&node.base);
594787
788 stack.append(State { .BinaryOrExpressionEnd = dest_ptr }) catch unreachable;
789 try stack.append(State { .BinaryXorExpressionBegin = DestPtr { .Field = &node.rhs } });
790 continue;
791 },
792 else => {
793 self.putBackToken(token);
794 continue;
795 },
796 }
797 },
798
799 State.BinaryXorExpressionBegin => |dest_ptr| {
800 stack.append(State { .BinaryXorExpressionEnd = dest_ptr }) catch unreachable;
801 try stack.append(State { .BinaryAndExpressionBegin = dest_ptr });
802 continue;
803 },
804
805 State.BinaryXorExpressionEnd => |dest_ptr| {
806 const token = self.getNextToken();
807 switch (token.id) {
808 Token.Id.Caret => {
809 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.BitXor);
810 node.lhs = dest_ptr.get();
811 dest_ptr.store(&node.base);
812
813 stack.append(State { .BinaryXorExpressionEnd = dest_ptr }) catch unreachable;
814 try stack.append(State { .BinaryAndExpressionBegin = DestPtr { .Field = &node.rhs } });
815 continue;
595816 },
817 else => {
818 self.putBackToken(token);
819 continue;
820 },
821 }
822 },
823
824 State.BinaryAndExpressionBegin => |dest_ptr| {
825 stack.append(State { .BinaryAndExpressionEnd = dest_ptr }) catch unreachable;
826 try stack.append(State { .BitShiftExpressionBegin = dest_ptr });
827 continue;
828 },
829
830 State.BinaryAndExpressionEnd => |dest_ptr| {
831 const token = self.getNextToken();
832 switch (token.id) {
596833 Token.Id.Ampersand => {
597 const prefix_op = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp{
598 .AddrOf = ast.NodePrefixOp.AddrOfInfo {
599 .align_expr = null,
600 .bit_offset_start_token = null,
601 .bit_offset_end_token = null,
602 .const_token = null,
603 .volatile_token = null,
834 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.BitAnd);
835 node.lhs = dest_ptr.get();
836 dest_ptr.store(&node.base);
837
838 stack.append(State { .BinaryAndExpressionEnd = dest_ptr }) catch unreachable;
839 try stack.append(State { .BitShiftExpressionBegin = DestPtr { .Field = &node.rhs } });
840 continue;
841 },
842 else => {
843 self.putBackToken(token);
844 continue;
845 },
846 }
847 },
848
849 State.BitShiftExpressionBegin => |dest_ptr| {
850 stack.append(State { .BitShiftExpressionEnd = dest_ptr }) catch unreachable;
851 try stack.append(State { .AdditionExpressionBegin = dest_ptr });
852 continue;
853 },
854
855 State.BitShiftExpressionEnd => |dest_ptr| {
856 const token = self.getNextToken();
857 if (tokenIdToBitShift(token.id)) |bitshift_id| {
858 const node = try self.createInfixOp(arena, token, bitshift_id);
859 node.lhs = dest_ptr.get();
860 dest_ptr.store(&node.base);
861
862 stack.append(State { .BitShiftExpressionEnd = dest_ptr }) catch unreachable;
863 try stack.append(State { .AdditionExpressionBegin = DestPtr { .Field = &node.rhs } });
864 continue;
865 } else {
866 self.putBackToken(token);
867 continue;
868 }
869 },
870
871 State.AdditionExpressionBegin => |dest_ptr| {
872 stack.append(State { .AdditionExpressionEnd = dest_ptr }) catch unreachable;
873 try stack.append(State { .MultiplyExpressionBegin = dest_ptr });
874 continue;
875 },
876
877 State.AdditionExpressionEnd => |dest_ptr| {
878 const token = self.getNextToken();
879 if (tokenIdToAddition(token.id)) |add_id| {
880 const node = try self.createInfixOp(arena, token, add_id);
881 node.lhs = dest_ptr.get();
882 dest_ptr.store(&node.base);
883
884 stack.append(State { .AdditionExpressionEnd = dest_ptr }) catch unreachable;
885 try stack.append(State { .MultiplyExpressionBegin = DestPtr { .Field = &node.rhs } });
886 continue;
887 } else {
888 self.putBackToken(token);
889 continue;
890 }
891 },
892
893 State.MultiplyExpressionBegin => |dest_ptr| {
894 stack.append(State { .MultiplyExpressionEnd = dest_ptr }) catch unreachable;
895 try stack.append(State { .CurlySuffixExpressionBegin = dest_ptr });
896 continue;
897 },
898
899 State.MultiplyExpressionEnd => |dest_ptr| {
900 const token = self.getNextToken();
901 if (tokenIdToMultiply(token.id)) |mult_id| {
902 const node = try self.createInfixOp(arena, token, mult_id);
903 node.lhs = dest_ptr.get();
904 dest_ptr.store(&node.base);
905
906 stack.append(State { .MultiplyExpressionEnd = dest_ptr }) catch unreachable;
907 try stack.append(State { .CurlySuffixExpressionBegin = DestPtr { .Field = &node.rhs } });
908 continue;
909 } else {
910 self.putBackToken(token);
911 continue;
912 }
913 },
914
915 State.CurlySuffixExpressionBegin => |dest_ptr| {
916 stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable;
917 try stack.append(State { .TypeExprBegin = dest_ptr });
918 continue;
919 },
920
921 State.CurlySuffixExpressionEnd => |dest_ptr| {
922 const token = self.getNextToken();
923 if (token.id != Token.Id.LBrace) {
924 self.putBackToken(token);
925 continue;
926 }
927
928 const next = self.getNextToken();
929 self.putBackToken(token);
930 switch (next.id) {
931 Token.Id.Period => {
932 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
933 .StructInitializer = ArrayList(&ast.NodeFieldInitializer).init(arena),
934 });
935 node.lhs = dest_ptr.get();
936 dest_ptr.store(&node.base);
937
938 stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable;
939 try stack.append(State {
940 .FieldInitListItemOrEnd = ListState(&ast.NodeFieldInitializer) {
941 .list = &node.op.StructInitializer,
942 .end = Token.Id.RBrace,
943 .ptr = &node.rtoken,
604944 }
605945 });
606 try stack.append(State { .PrefixOp = prefix_op });
607 try stack.append(State.ExpectOperand);
608 try stack.append(State { .AddrOfModifiers = &prefix_op.op.AddrOf });
609946 continue;
610947 },
611 Token.Id.Identifier => {
948 else => {
949 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
950 .ArrayInitializer = ArrayList(&ast.Node).init(arena),
951 });
952 node.lhs = dest_ptr.get();
953 dest_ptr.store(&node.base);
954
955 stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable;
612956 try stack.append(State {
613 .Operand = &(try self.createIdentifier(arena, token)).base
957 .ExprListItemOrEnd = ListState(&ast.Node) {
958 .list = &node.op.ArrayInitializer,
959 .end = Token.Id.RBrace,
960 .ptr = &node.rtoken,
961 }
614962 });
615 try stack.append(State.AfterOperand);
616963 continue;
617964 },
618 Token.Id.IntegerLiteral => {
965 }
966 },
967
968 State.TypeExprBegin => |dest_ptr| {
969 const token = self.getNextToken();
970 if (token.id == Token.Id.Keyword_var) {
971 @panic("TODO param with type var");
972 }
973 self.putBackToken(token);
974
975 stack.append(State { .TypeExprEnd = dest_ptr }) catch unreachable;
976 try stack.append(State { .PrefixOpExpression = dest_ptr });
977 continue;
978 },
979
980 State.TypeExprEnd => |dest_ptr| {
981 const token = self.getNextToken();
982 switch (token.id) {
983 Token.Id.Bang => {
984 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.ErrorUnion);
985 node.lhs = dest_ptr.get();
986 dest_ptr.store(&node.base);
987
988 stack.append(State { .TypeExprEnd = dest_ptr }) catch unreachable;
989 try stack.append(State { .PrefixOpExpression = DestPtr { .Field = &node.rhs } });
990 continue;
991 },
992 else => {
993 self.putBackToken(token);
994 continue;
995 },
996 }
997 },
998
999 State.PrefixOpExpression => |dest_ptr| {
1000 const token = self.getNextToken();
1001 if (tokenIdToPrefixOp(token.id)) |prefix_id| {
1002 const node = try self.createPrefixOp(arena, token, prefix_id);
1003 dest_ptr.store(&node.base);
1004
1005 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;
1006 if (node.op == ast.NodePrefixOp.PrefixOp.AddrOf) {
1007 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });
1008 }
1009 continue;
1010 } else {
1011 self.putBackToken(token);
1012 stack.append(State { .SuffixOpExpressionBegin = dest_ptr }) catch unreachable;
1013 continue;
1014 }
1015 },
1016
1017 State.SuffixOpExpressionBegin => |dest_ptr| {
1018 const token = self.getNextToken();
1019 switch (token.id) {
1020 Token.Id.Keyword_async => {
1021 @panic("TODO: Parse async");
1022 },
1023 else => {
1024 self.putBackToken(token);
1025 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1026 try stack.append(State { .PrimaryExpression = dest_ptr });
1027 continue;
1028 }
1029 }
1030 },
1031
1032 State.SuffixOpExpressionEnd => |dest_ptr| {
1033 const token = self.getNextToken();
1034 switch (token.id) {
1035 Token.Id.LParen => {
1036 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
1037 .Call = ast.NodeSuffixOp.CallInfo {
1038 .params = ArrayList(&ast.Node).init(arena),
1039 .is_async = false, // TODO: ASYNC
1040 .allocator = null,
1041 }
1042 });
1043 node.lhs = dest_ptr.get();
1044 dest_ptr.store(&node.base);
1045
1046 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
6191047 try stack.append(State {
620 .Operand = &(try self.createIntegerLiteral(arena, token)).base
1048 .ExprListItemOrEnd = ListState(&ast.Node) {
1049 .list = &node.op.Call.params,
1050 .end = Token.Id.RParen,
1051 .ptr = &node.rtoken,
1052 }
6211053 });
622 try stack.append(State.AfterOperand);
1054 continue;
1055 },
1056 Token.Id.LBracket => {
1057 const node = try arena.create(ast.NodeSuffixOp);
1058 *node = ast.NodeSuffixOp {
1059 .base = self.initNode(ast.Node.Id.SuffixOp),
1060 .lhs = undefined,
1061 .op = ast.NodeSuffixOp.SuffixOp {
1062 .ArrayAccess = undefined,
1063 },
1064 .rtoken = undefined,
1065 };
1066 node.lhs = dest_ptr.get();
1067 dest_ptr.store(&node.base);
1068
1069 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1070 try stack.append(State { .SliceOrArrayAccess = node });
1071 try stack.append(State { .Expression = DestPtr { .Field = &node.op.ArrayAccess }});
1072 continue;
1073 },
1074 Token.Id.Period => {
1075 const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.Period);
1076 node.lhs = dest_ptr.get();
1077 dest_ptr.store(&node.base);
1078
1079 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1080 try stack.append(State { .SuffixOpExpressionBegin = DestPtr { .Field = &node.rhs }});
1081 continue;
1082 },
1083 else => {
1084 self.putBackToken(token);
1085 continue;
1086 },
1087 }
1088 },
1089
1090 State.PrimaryExpression => |dest_ptr| {
1091 const token = self.getNextToken();
1092 switch (token.id) {
1093 Token.Id.IntegerLiteral => {
1094 dest_ptr.store(&(try self.createIntegerLiteral(arena, token)).base);
6231095 continue;
6241096 },
6251097 Token.Id.FloatLiteral => {
626 try stack.append(State {
627 .Operand = &(try self.createFloatLiteral(arena, token)).base
628 });
629 try stack.append(State.AfterOperand);
1098 dest_ptr.store(&(try self.createFloatLiteral(arena, token)).base);
1099 continue;
1100 },
1101 Token.Id.StringLiteral => {
1102 dest_ptr.store(&(try self.createStringLiteral(arena, token)).base);
1103 continue;
1104 },
1105 Token.Id.CharLiteral => {
1106 const node = try arena.create(ast.NodeCharLiteral);
1107 *node = ast.NodeCharLiteral {
1108 .base = self.initNode(ast.Node.Id.CharLiteral),
1109 .token = token,
1110 };
1111 dest_ptr.store(&node.base);
6301112 continue;
6311113 },
6321114 Token.Id.Keyword_undefined => {
633 try stack.append(State {
634 .Operand = &(try self.createUndefined(arena, token)).base
635 });
636 try stack.append(State.AfterOperand);
1115 dest_ptr.store(&(try self.createUndefined(arena, token)).base);
6371116 continue;
6381117 },
6391118 Token.Id.Keyword_true, Token.Id.Keyword_false => {
......@@ -642,10 +1121,7 @@ pub const Parser = struct {
6421121 .base = self.initNode(ast.Node.Id.BoolLiteral),
6431122 .token = token,
6441123 };
645 try stack.append(State {
646 .Operand = &node.base
647 });
648 try stack.append(State.AfterOperand);
1124 dest_ptr.store(&node.base);
6491125 continue;
6501126 },
6511127 Token.Id.Keyword_null => {
......@@ -654,10 +1130,7 @@ pub const Parser = struct {
6541130 .base = self.initNode(ast.Node.Id.NullLiteral),
6551131 .token = token,
6561132 };
657 try stack.append(State {
658 .Operand = &node.base
659 });
660 try stack.append(State.AfterOperand);
1133 dest_ptr.store(&node.base);
6611134 continue;
6621135 },
6631136 Token.Id.Keyword_this => {
......@@ -666,10 +1139,7 @@ pub const Parser = struct {
6661139 .base = self.initNode(ast.Node.Id.ThisLiteral),
6671140 .token = token,
6681141 };
669 try stack.append(State {
670 .Operand = &node.base
671 });
672 try stack.append(State.AfterOperand);
1142 dest_ptr.store(&node.base);
6731143 continue;
6741144 },
6751145 Token.Id.Keyword_unreachable => {
......@@ -678,12 +1148,97 @@ pub const Parser = struct {
6781148 .base = self.initNode(ast.Node.Id.Unreachable),
6791149 .token = token,
6801150 };
1151 dest_ptr.store(&node.base);
1152 continue;
1153 },
1154 Token.Id.MultilineStringLiteralLine => {
1155 const node = try arena.create(ast.NodeMultilineStringLiteral);
1156 *node = ast.NodeMultilineStringLiteral {
1157 .base = self.initNode(ast.Node.Id.MultilineStringLiteral),
1158 .tokens = ArrayList(Token).init(arena),
1159 };
1160 dest_ptr.store(&node.base);
1161 try node.tokens.append(token);
1162
1163 while (true) {
1164 const multiline_str = self.getNextToken();
1165 if (multiline_str.id != Token.Id.MultilineStringLiteralLine) {
1166 self.putBackToken(multiline_str);
1167 break;
1168 }
1169
1170 try node.tokens.append(multiline_str);
1171 }
1172 continue;
1173 },
1174 Token.Id.LParen => {
1175 const node = try arena.create(ast.NodeGroupedExpression);
1176 *node = ast.NodeGroupedExpression {
1177 .base = self.initNode(ast.Node.Id.GroupedExpression),
1178 .lparen = token,
1179 .expr = undefined,
1180 .rparen = undefined,
1181 };
1182 dest_ptr.store(&node.base);
6811183 try stack.append(State {
682 .Operand = &node.base
1184 .ExpectTokenSave = ExpectTokenSave {
1185 .id = Token.Id.RParen,
1186 .ptr = &node.rparen,
1187 }
6831188 });
684 try stack.append(State.AfterOperand);
1189 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
1190 continue;
1191 },
1192 Token.Id.Identifier => {
1193 dest_ptr.store(&(try self.createIdentifier(arena, token)).base);
1194 continue;
1195 },
1196 Token.Id.Builtin => {
1197 const node = try arena.create(ast.NodeBuiltinCall);
1198 *node = ast.NodeBuiltinCall {
1199 .base = self.initNode(ast.Node.Id.BuiltinCall),
1200 .builtin_token = token,
1201 .params = ArrayList(&ast.Node).init(arena),
1202 .rparen_token = undefined,
1203 };
1204 dest_ptr.store(&node.base);
1205 try stack.append(State {
1206 .ExprListItemOrEnd = ListState(&ast.Node) {
1207 .list = &node.params,
1208 .end = Token.Id.RParen,
1209 .ptr = &node.rparen_token,
1210 }
1211 });
1212 try stack.append(State { .ExpectToken = Token.Id.LParen, });
6851213 continue;
6861214 },
1215 Token.Id.LBracket => {
1216 const rbracket_token = self.getNextToken();
1217 if (rbracket_token.id == Token.Id.RBracket) {
1218 const node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp{
1219 .SliceType = ast.NodePrefixOp.AddrOfInfo {
1220 .align_expr = null,
1221 .bit_offset_start_token = null,
1222 .bit_offset_end_token = null,
1223 .const_token = null,
1224 .volatile_token = null,
1225 }
1226 });
1227 dest_ptr.store(&node.base);
1228 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });
1229 continue;
1230 }
1231
1232 self.putBackToken(rbracket_token);
1233
1234 const node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp{
1235 .ArrayType = undefined,
1236 });
1237 dest_ptr.store(&node.base);
1238 try stack.append(State { .ExpectToken = Token.Id.RBracket });
1239 try stack.append(State { .Expression = DestPtr { .Field = &node.op.ArrayType } });
1240
1241 },
6871242 Token.Id.Keyword_error => {
6881243 const next = self.getNextToken();
6891244
......@@ -694,10 +1249,7 @@ pub const Parser = struct {
6941249 .base = self.initNode(ast.Node.Id.ErrorType),
6951250 .token = token,
6961251 };
697 try stack.append(State {
698 .Operand = &node.base
699 });
700 try stack.append(State.AfterOperand);
1252 dest_ptr.store(&node.base);
7011253 continue;
7021254 }
7031255
......@@ -708,6 +1260,7 @@ pub const Parser = struct {
7081260 .decls = ArrayList(&ast.NodeIdentifier).init(arena),
7091261 .rbrace_token = undefined,
7101262 };
1263 dest_ptr.store(&node.base);
7111264
7121265 while (true) {
7131266 const t = self.getNextToken();
......@@ -722,10 +1275,11 @@ pub const Parser = struct {
7221275 );
7231276 },
7241277 else => {
725 return self.parseError(token, "expected {} or {}, found {}",
1278 try self.parseError(&stack, token, "expected {} or {}, found {}",
7261279 @tagName(Token.Id.RBrace),
7271280 @tagName(Token.Id.Identifier),
7281281 @tagName(token.id));
1282 continue;
7291283 }
7301284 }
7311285
......@@ -737,23 +1291,20 @@ pub const Parser = struct {
7371291 },
7381292 Token.Id.Comma => continue,
7391293 else => {
740 return self.parseError(token, "expected {} or {}, found {}",
1294 try self.parseError(&stack, token, "expected {} or {}, found {}",
7411295 @tagName(Token.Id.RBrace),
7421296 @tagName(Token.Id.Comma),
7431297 @tagName(token.id));
1298 continue;
7441299 }
7451300 }
7461301 }
747
748 try stack.append(State {
749 .Operand = &node.base
750 });
751 try stack.append(State.AfterOperand);
7521302 continue;
7531303 },
7541304 Token.Id.Keyword_packed => {
7551305 try stack.append(State {
7561306 .ContainerExtern = ContainerExternCtx {
1307 .dest_ptr = dest_ptr,
7571308 .ltoken = token,
7581309 .layout = ast.NodeContainerDecl.Layout.Packed,
7591310 },
......@@ -762,109 +1313,35 @@ pub const Parser = struct {
7621313 Token.Id.Keyword_extern => {
7631314 try stack.append(State {
7641315 .ContainerExtern = ContainerExternCtx {
1316 .dest_ptr = dest_ptr,
7651317 .ltoken = token,
7661318 .layout = ast.NodeContainerDecl.Layout.Extern,
7671319 },
7681320 });
7691321 },
770 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {
771 self.putBackToken(token);
772 try stack.append(State {
773 .ContainerExtern = ContainerExternCtx {
774 .ltoken = token,
775 .layout = ast.NodeContainerDecl.Layout.Auto,
776 },
777 });
778 },
779 Token.Id.Builtin => {
780 const node = try arena.create(ast.NodeBuiltinCall);
781 *node = ast.NodeBuiltinCall {
782 .base = self.initNode(ast.Node.Id.BuiltinCall),
783 .builtin_token = token,
784 .params = ArrayList(&ast.Node).init(arena),
785 .rparen_token = undefined,
786 };
787 try stack.append(State {
788 .Operand = &node.base
789 });
790 try stack.append(State.AfterOperand);
791 try stack.append(State {
792 .ExprListItemOrEnd = ListState(&ast.Node) {
793 .list = &node.params,
794 .end = Token.Id.RParen,
795 .ptr = &node.rparen_token,
796 }
797 });
798 try stack.append(State { .ExpectToken = Token.Id.LParen, });
799 continue;
800 },
801 Token.Id.StringLiteral => {
802 const node = try self.createStringLiteral(arena, token);
803 try stack.append(State {
804 .Operand = &node.base
805 });
806 try stack.append(State.AfterOperand);
807 continue;
808 },
809 Token.Id.CharLiteral => {
810 const node = try arena.create(ast.NodeCharLiteral);
811 *node = ast.NodeCharLiteral {
812 .base = self.initNode(ast.Node.Id.CharLiteral),
813 .token = token,
814 };
815 try stack.append(State {
816 .Operand = &node.base
817 });
818 try stack.append(State.AfterOperand);
819 continue;
820 },
821 Token.Id.MultilineStringLiteralLine => {
822 const node = try arena.create(ast.NodeMultilineStringLiteral);
823 *node = ast.NodeMultilineStringLiteral {
824 .base = self.initNode(ast.Node.Id.MultilineStringLiteral),
825 .tokens = ArrayList(Token).init(arena),
826 };
827 try node.tokens.append(token);
828
829 while (true) {
830 const multiline_str = self.getNextToken();
831 if (multiline_str.id != Token.Id.MultilineStringLiteralLine) {
832 self.putBackToken(multiline_str);
833 break;
834 }
835
836 try node.tokens.append(multiline_str);
837 }
838
839 try stack.append(State {
840 .Operand = &node.base
841 });
842 try stack.append(State.AfterOperand);
843 continue;
844 },
845 Token.Id.LParen => {
846 const node = try arena.create(ast.NodeGroupedExpression);
847 *node = ast.NodeGroupedExpression {
848 .base = self.initNode(ast.Node.Id.GroupedExpression),
849 .lparen = token,
850 .expr = undefined,
851 .rparen = undefined,
852 };
853 try stack.append(State {
854 .Operand = &node.base
855 });
856 try stack.append(State.AfterOperand);
1322 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {
1323 self.putBackToken(token);
8571324 try stack.append(State {
858 .ExpectTokenSave = ExpectTokenSave {
859 .id = Token.Id.RParen,
860 .ptr = &node.rparen,
861 }
1325 .ContainerExtern = ContainerExternCtx {
1326 .dest_ptr = dest_ptr,
1327 .ltoken = token,
1328 .layout = ast.NodeContainerDecl.Layout.Auto,
1329 },
8621330 });
863 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
864 continue;
8651331 },
866
867 else => return self.parseError(token, "expected primary expression, found {}", @tagName(token.id)),
1332 Token.Id.LBrace => {
1333 @panic("TODO: Block expr");
1334 },
1335 Token.Id.Keyword_fn => {
1336 @panic("TODO: fn proto");
1337 },
1338 Token.Id.Keyword_asm => {
1339 @panic("TODO: inline asm");
1340 },
1341 else => {
1342 try self.parseError(&stack, token, "expected primary expression, found {}", @tagName(token.id));
1343 continue;
1344 }
8681345 }
8691346 },
8701347
......@@ -880,8 +1357,6 @@ pub const Parser = struct {
8801357 .end = undefined,
8811358 }
8821359 };
883 try stack.append(State { .SuffixOp = node });
884 try stack.append(State.AfterOperand);
8851360
8861361 const rbracket_token = self.getNextToken();
8871362 if (rbracket_token.id != Token.Id.RBracket) {
......@@ -900,161 +1375,12 @@ pub const Parser = struct {
9001375 },
9011376 Token.Id.RBracket => {
9021377 node.rtoken = token;
903 try stack.append(State { .SuffixOp = node });
904 try stack.append(State.AfterOperand);
9051378 continue;
9061379 },
907 else => return self.parseError(token, "expected ']' or '..', found {}", @tagName(token.id))
908 }
909 },
910
911 State.AfterOperand => {
912 // we'll either get an infix operator (like != or ^),
913 // or a postfix operator (like () or {}),
914 // otherwise this expression is done (like on a ; or else).
915 var token = self.getNextToken();
916 if (tokenIdToInfixOp(token.id)) |infix_id| {
917 try stack.append(State {
918 .InfixOp = try self.createInfixOp(arena, token, infix_id)
919 });
920 try stack.append(State.ExpectOperand);
1380 else => {
1381 try self.parseError(&stack, token, "expected ']' or '..', found {}", @tagName(token.id));
9211382 continue;
922
923 } else if (token.id == Token.Id.LParen) {
924 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
925 .Call = ast.NodeSuffixOp.CallInfo {
926 .params = ArrayList(&ast.Node).init(arena),
927 .is_async = false, // TODO: ASYNC
928 }
929 });
930 try stack.append(State { .SuffixOp = node });
931 try stack.append(State.AfterOperand);
932 try stack.append(State {
933 .ExprListItemOrEnd = ListState(&ast.Node) {
934 .list = &node.op.Call.params,
935 .end = Token.Id.RParen,
936 .ptr = &node.rtoken,
937 }
938 });
939 continue;
940
941 } else if (token.id == Token.Id.LBracket) {
942 const node = try arena.create(ast.NodeSuffixOp);
943 *node = ast.NodeSuffixOp {
944 .base = self.initNode(ast.Node.Id.SuffixOp),
945 .lhs = undefined,
946 .op = ast.NodeSuffixOp.SuffixOp {
947 .ArrayAccess = undefined,
948 },
949 .rtoken = undefined,
950 };
951 try stack.append(State { .SliceOrArrayAccess = node });
952 try stack.append(State { .Expression = DestPtr { .Field = &node.op.ArrayAccess }});
953 continue;
954
955 // TODO: This is the initializer parsing code. It doesn't work because of
956 // the ambiguity between function bodies and initializers:
957 // fn main() void {} or fn main() (void {})
958 } else if (false) { //(token.id == Token.Id.LBrace) {
959 const next = self.getNextToken();
960
961 switch (next.id) {
962 Token.Id.Period => {
963 self.putBackToken(token);
964
965 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
966 .StructInitializer = ArrayList(&ast.NodeFieldInitializer).init(arena),
967 });
968
969 try stack.append(State {
970 .FieldInitListItemOrEnd = ListState(&ast.NodeFieldInitializer) {
971 .list = &node.op.StructInitializer,
972 .end = Token.Id.RBrace,
973 .ptr = &node.rtoken,
974 }
975 });
976 continue;
977 },
978 else => {
979 self.putBackToken(token);
980
981 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
982 .ArrayInitializer = ArrayList(&ast.Node).init(arena),
983 });
984
985 try stack.append(State {
986 .ExprListItemOrEnd = ListState(&ast.Node) {
987 .list = &node.op.ArrayInitializer,
988 .end = Token.Id.RBrace,
989 .ptr = &node.rtoken,
990 }
991 });
992 continue;
993 },
994 }
995
996 // TODO: Parse postfix operator
997 } else {
998 // no postfix/infix operator after this operand.
999 self.putBackToken(token);
1000
1001 var expression = popSuffixOp(&stack);
1002 while (true) {
1003 const s = stack.pop();
1004 if (s == State.Expression) {
1005 const dest_ptr = s.Expression;
1006 // we're done
1007 try dest_ptr.store(expression);
1008 break;
1009 }
1010
1011 var placement_ptr = &expression;
1012 var rhs : &&ast.Node = undefined;
1013 const node = blk: {
1014 switch (s) {
1015 State.InfixOp => |infix_op| {
1016 infix_op.lhs = popSuffixOp(&stack);
1017 infix_op.rhs = expression;
1018 rhs = &infix_op.rhs;
1019 break :blk &infix_op.base;
1020 },
1021 State.PrefixOp => |prefix_op| {
1022 prefix_op.rhs = expression;
1023 rhs = &prefix_op.rhs;
1024 break :blk &prefix_op.base;
1025 },
1026 else => unreachable,
1027 }
1028 };
1029 const node_perc = precedence(node);
1030
1031 while (true) {
1032 const perc = precedence(*placement_ptr);
1033
1034 if (node_perc > perc) {
1035 *placement_ptr = node;
1036 break;
1037 }
1038
1039 switch ((*placement_ptr).id) {
1040 ast.Node.Id.SuffixOp => {
1041 const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", *placement_ptr);
1042 placement_ptr = &suffix_op.lhs;
1043 *rhs = suffix_op.lhs;
1044 },
1045 ast.Node.Id.InfixOp => {
1046 const infix_op = @fieldParentPtr(ast.NodeInfixOp, "base", *placement_ptr);
1047 placement_ptr = &infix_op.lhs;
1048 *rhs = infix_op.lhs;
1049 },
1050 else => {
1051 *placement_ptr = node;
1052 break;
1053 },
1054 }
1055 }
10561383 }
1057 continue;
10581384 }
10591385 },
10601386
......@@ -1069,7 +1395,7 @@ pub const Parser = struct {
10691395
10701396 self.putBackToken(token);
10711397 stack.append(State { .ExprListCommaOrEnd = list_state }) catch unreachable;
1072 try stack.append(State { .Expression = DestPtr{.List = list_state.list} });
1398 try stack.append(State { .Expression = DestPtr{ .Field = try list_state.list.addOne() } });
10731399 },
10741400
10751401 State.FieldInitListItemOrEnd => |list_state| {
......@@ -1130,21 +1456,30 @@ pub const Parser = struct {
11301456 switch (token.id) {
11311457 Token.Id.Keyword_align => {
11321458 stack.append(state) catch unreachable;
1133 if (addr_of_info.align_expr != null) return self.parseError(token, "multiple align qualifiers");
1134 _ = try self.eatToken(Token.Id.LParen);
1459 if (addr_of_info.align_expr != null) {
1460 try self.parseError(&stack, token, "multiple align qualifiers");
1461 continue;
1462 }
11351463 try stack.append(State { .ExpectToken = Token.Id.RParen });
11361464 try stack.append(State { .Expression = DestPtr{.NullableField = &addr_of_info.align_expr} });
1465 try stack.append(State { .ExpectToken = Token.Id.LParen });
11371466 continue;
11381467 },
11391468 Token.Id.Keyword_const => {
11401469 stack.append(state) catch unreachable;
1141 if (addr_of_info.const_token != null) return self.parseError(token, "duplicate qualifier: const");
1470 if (addr_of_info.const_token != null) {
1471 try self.parseError(&stack, token, "duplicate qualifier: const");
1472 continue;
1473 }
11421474 addr_of_info.const_token = token;
11431475 continue;
11441476 },
11451477 Token.Id.Keyword_volatile => {
11461478 stack.append(state) catch unreachable;
1147 if (addr_of_info.volatile_token != null) return self.parseError(token, "duplicate qualifier: volatile");
1479 if (addr_of_info.volatile_token != null) {
1480 try self.parseError(&stack, token, "duplicate qualifier: volatile");
1481 continue;
1482 }
11481483 addr_of_info.volatile_token = token;
11491484 continue;
11501485 },
......@@ -1155,17 +1490,6 @@ pub const Parser = struct {
11551490 }
11561491 },
11571492
1158 State.TypeExpr => |dest_ptr| {
1159 const token = self.getNextToken();
1160 if (token.id == Token.Id.Keyword_var) {
1161 @panic("TODO param with type var");
1162 }
1163 self.putBackToken(token);
1164
1165 stack.append(State { .Expression = dest_ptr }) catch unreachable;
1166 continue;
1167 },
1168
11691493 State.FnProto => |fn_proto| {
11701494 stack.append(State { .FnProtoAlign = fn_proto }) catch unreachable;
11711495 try stack.append(State { .ParamDecl = fn_proto });
......@@ -1201,14 +1525,14 @@ pub const Parser = struct {
12011525 Token.Id.Bang => {
12021526 fn_proto.return_type = ast.NodeFnProto.ReturnType { .InferErrorSet = undefined };
12031527 stack.append(State {
1204 .TypeExpr = DestPtr {.Field = &fn_proto.return_type.InferErrorSet},
1528 .TypeExprBegin = DestPtr {.Field = &fn_proto.return_type.InferErrorSet},
12051529 }) catch unreachable;
12061530 },
12071531 else => {
12081532 self.putBackToken(token);
12091533 fn_proto.return_type = ast.NodeFnProto.ReturnType { .Explicit = undefined };
12101534 stack.append(State {
1211 .TypeExpr = DestPtr {.Field = &fn_proto.return_type.Explicit},
1535 .TypeExprBegin = DestPtr {.Field = &fn_proto.return_type.Explicit},
12121536 }) catch unreachable;
12131537 },
12141538 }
......@@ -1251,7 +1575,7 @@ pub const Parser = struct {
12511575 stack.append(State { .ParamDecl = fn_proto }) catch unreachable;
12521576 try stack.append(State.ParamDeclComma);
12531577 try stack.append(State {
1254 .TypeExpr = DestPtr {.Field = &param_decl.type_node}
1578 .TypeExprBegin = DestPtr {.Field = &param_decl.type_node}
12551579 });
12561580 continue;
12571581 },
......@@ -1264,7 +1588,10 @@ pub const Parser = struct {
12641588 continue;
12651589 },
12661590 Token.Id.Comma => continue,
1267 else => return self.parseError(token, "expected ',' or ')', found {}", @tagName(token.id)),
1591 else => {
1592 try self.parseError(&stack, token, "expected ',' or ')', found {}", @tagName(token.id));
1593 continue;
1594 },
12681595 }
12691596 },
12701597
......@@ -1278,7 +1605,10 @@ pub const Parser = struct {
12781605 continue;
12791606 },
12801607 Token.Id.Semicolon => continue,
1281 else => return self.parseError(token, "expected ';' or '{{', found {}", @tagName(token.id)),
1608 else => {
1609 try self.parseError(&stack, token, "expected ';' or '{{', found {}", @tagName(token.id));
1610 continue;
1611 },
12821612 }
12831613 },
12841614
......@@ -1329,112 +1659,13 @@ pub const Parser = struct {
13291659 }
13301660
13311661 stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable;
1332 try stack.append(State { .Expression = DestPtr{.List = &block.statements} });
1662 try stack.append(State { .Expression = DestPtr{.Field = try block.statements.addOne() } });
13331663 continue;
13341664 },
1335
1336 // These are data, not control flow.
1337 State.InfixOp => unreachable,
1338 State.PrefixOp => unreachable,
1339 State.SuffixOp => unreachable,
1340 State.Operand => unreachable,
13411665 }
13421666 }
13431667 }
13441668
1345 fn precedence(node: &ast.Node) u8 {
1346 switch (node.id) {
1347 ast.Node.Id.PrefixOp => {
1348 const prefix_op = @fieldParentPtr(ast.NodePrefixOp, "base", node);
1349 switch (prefix_op.op) {
1350 ast.NodePrefixOp.PrefixOp.ArrayType,
1351 ast.NodePrefixOp.PrefixOp.SliceType => return 1,
1352
1353 ast.NodePrefixOp.PrefixOp.BoolNot,
1354 ast.NodePrefixOp.PrefixOp.Negation,
1355 ast.NodePrefixOp.PrefixOp.NegationWrap,
1356 ast.NodePrefixOp.PrefixOp.BitNot,
1357 ast.NodePrefixOp.PrefixOp.Deref,
1358 ast.NodePrefixOp.PrefixOp.AddrOf,
1359 ast.NodePrefixOp.PrefixOp.UnwrapMaybe => return 3,
1360
1361 ast.NodePrefixOp.PrefixOp.Try,
1362 ast.NodePrefixOp.PrefixOp.Return => return 255,
1363 }
1364 },
1365 ast.Node.Id.SuffixOp => {
1366 const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", node);
1367 switch (suffix_op.op) {
1368 ast.NodeSuffixOp.SuffixOp.Call,
1369 ast.NodeSuffixOp.SuffixOp.Slice,
1370 ast.NodeSuffixOp.SuffixOp.ArrayAccess => return 2,
1371
1372 ast.NodeSuffixOp.SuffixOp.ArrayInitializer,
1373 ast.NodeSuffixOp.SuffixOp.StructInitializer => return 5,
1374 }
1375 },
1376 ast.Node.Id.InfixOp => {
1377 const infix_op = @fieldParentPtr(ast.NodeInfixOp, "base", node);
1378 switch (infix_op.op) {
1379 ast.NodeInfixOp.InfixOp.Period => return 2,
1380
1381 ast.NodeInfixOp.InfixOp.ErrorUnion => return 4,
1382
1383 ast.NodeInfixOp.InfixOp.Div,
1384 ast.NodeInfixOp.InfixOp.ArrayMult,
1385 ast.NodeInfixOp.InfixOp.Mod,
1386 ast.NodeInfixOp.InfixOp.Mult,
1387 ast.NodeInfixOp.InfixOp.MultWrap => return 6,
1388
1389 ast.NodeInfixOp.InfixOp.Add,
1390 ast.NodeInfixOp.InfixOp.AddWrap,
1391 ast.NodeInfixOp.InfixOp.ArrayCat,
1392 ast.NodeInfixOp.InfixOp.Sub,
1393 ast.NodeInfixOp.InfixOp.SubWrap => return 7,
1394
1395 ast.NodeInfixOp.InfixOp.BitShiftLeft,
1396 ast.NodeInfixOp.InfixOp.BitShiftRight => return 8,
1397
1398 ast.NodeInfixOp.InfixOp.BitAnd => return 9,
1399
1400 ast.NodeInfixOp.InfixOp.BitXor => return 10,
1401
1402 ast.NodeInfixOp.InfixOp.BitOr => return 11,
1403
1404 ast.NodeInfixOp.InfixOp.EqualEqual,
1405 ast.NodeInfixOp.InfixOp.BangEqual,
1406 ast.NodeInfixOp.InfixOp.GreaterOrEqual,
1407 ast.NodeInfixOp.InfixOp.GreaterThan,
1408 ast.NodeInfixOp.InfixOp.LessOrEqual,
1409 ast.NodeInfixOp.InfixOp.LessThan => return 12,
1410
1411 ast.NodeInfixOp.InfixOp.BoolAnd => return 13,
1412
1413 ast.NodeInfixOp.InfixOp.BoolOr => return 14,
1414
1415 ast.NodeInfixOp.InfixOp.UnwrapMaybe => return 15,
1416
1417 ast.NodeInfixOp.InfixOp.Assign,
1418 ast.NodeInfixOp.InfixOp.AssignBitAnd,
1419 ast.NodeInfixOp.InfixOp.AssignBitOr,
1420 ast.NodeInfixOp.InfixOp.AssignBitShiftLeft,
1421 ast.NodeInfixOp.InfixOp.AssignBitShiftRight,
1422 ast.NodeInfixOp.InfixOp.AssignBitXor,
1423 ast.NodeInfixOp.InfixOp.AssignDiv,
1424 ast.NodeInfixOp.InfixOp.AssignMinus,
1425 ast.NodeInfixOp.InfixOp.AssignMinusWrap,
1426 ast.NodeInfixOp.InfixOp.AssignMod,
1427 ast.NodeInfixOp.InfixOp.AssignPlus,
1428 ast.NodeInfixOp.InfixOp.AssignPlusWrap,
1429 ast.NodeInfixOp.InfixOp.AssignTimes,
1430 ast.NodeInfixOp.InfixOp.AssignTimesWarp,
1431 ast.NodeInfixOp.InfixOp.MergeErrorSets => return 16,
1432 }
1433 },
1434 else => return 0,
1435 }
1436 }
1437
14381669 fn commaOrEnd(self: &Parser, stack: &ArrayList(State), end: &const Token.Id, ptr: &Token, state_after_comma: &const State) !void {
14391670 var token = self.getNextToken();
14401671 switch (token.id) {
......@@ -1448,74 +1679,104 @@ pub const Parser = struct {
14481679 return;
14491680 }
14501681
1451 return self.parseError(token, "expected ',' or {}, found {}", @tagName(*end), @tagName(token.id));
1682 try self.parseError(stack, token, "expected ',' or {}, found {}", @tagName(*end), @tagName(token.id));
14521683 },
14531684 }
14541685 }
14551686
1456 fn popSuffixOp(stack: &ArrayList(State)) &ast.Node {
1457 var expression: &ast.Node = undefined;
1458 var left_leaf_ptr: &&ast.Node = &expression;
1459 while (true) {
1460 switch (stack.pop()) {
1461 State.SuffixOp => |suffix_op| {
1462 *left_leaf_ptr = &suffix_op.base;
1463 left_leaf_ptr = &suffix_op.lhs;
1464 },
1465 State.Operand => |operand| {
1466 *left_leaf_ptr = operand;
1467 break;
1468 },
1469 else => unreachable,
1470 }
1471 }
1687 fn tokenIdToAssignment(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
1688 // TODO: We have to cast all cases because of this:
1689 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
1690 return switch (*id) {
1691 Token.Id.AmpersandEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignBitAnd),
1692 Token.Id.AngleBracketAngleBracketLeftEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignBitShiftLeft),
1693 Token.Id.AngleBracketAngleBracketRightEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignBitShiftRight),
1694 Token.Id.AsteriskEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignTimes),
1695 Token.Id.AsteriskPercentEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignTimesWarp),
1696 Token.Id.CaretEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignBitXor),
1697 Token.Id.Equal => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.Assign),
1698 Token.Id.MinusEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignMinus),
1699 Token.Id.MinusPercentEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignMinusWrap),
1700 Token.Id.PercentEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignMod),
1701 Token.Id.PipeEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignBitOr),
1702 Token.Id.PlusEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignPlus),
1703 Token.Id.PlusPercentEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignPlusWrap),
1704 Token.Id.SlashEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AssignDiv),
1705 else => null,
1706 };
1707 }
1708
1709 fn tokenIdToComparison(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
1710 // TODO: We have to cast all cases because of this:
1711 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
1712 return switch (*id) {
1713 Token.Id.BangEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.BangEqual),
1714 Token.Id.EqualEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.EqualEqual),
1715 Token.Id.AngleBracketLeft => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.LessThan),
1716 Token.Id.AngleBracketLeftEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.LessOrEqual),
1717 Token.Id.AngleBracketRight => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.GreaterThan),
1718 Token.Id.AngleBracketRightEqual => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.GreaterOrEqual),
1719 else => null,
1720 };
1721 }
1722
1723 fn tokenIdToBitShift(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
1724 // TODO: We have to cast all cases because of this:
1725 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
1726 return switch (*id) {
1727 Token.Id.AngleBracketAngleBracketLeft => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.BitShiftLeft),
1728 Token.Id.AngleBracketAngleBracketRight => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.BitShiftRight),
1729 else => null,
1730 };
1731 }
14721732
1473 return expression;
1733 fn tokenIdToAddition(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
1734 // TODO: We have to cast all cases because of this:
1735 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
1736 return switch (*id) {
1737 Token.Id.Minus => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.Sub),
1738 Token.Id.MinusPercent => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.SubWrap),
1739 Token.Id.Plus => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.Add),
1740 Token.Id.PlusPercent => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.AddWrap),
1741 Token.Id.PlusPlus => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.ArrayCat),
1742 else => null,
1743 };
1744 }
1745
1746 fn tokenIdToMultiply(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
1747 // TODO: We have to cast all cases because of this:
1748 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
1749 return switch (*id) {
1750 Token.Id.Slash => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.Div),
1751 Token.Id.Asterisk => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.Mult),
1752 Token.Id.AsteriskAsterisk => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.ArrayMult),
1753 Token.Id.AsteriskPercent => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.MultWrap),
1754 Token.Id.Percent => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.Mod),
1755 Token.Id.PipePipe => (ast.NodeInfixOp.InfixOp)(ast.NodeInfixOp.InfixOp.MergeErrorSets),
1756 else => null,
1757 };
14741758 }
14751759
1476 fn tokenIdToInfixOp(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
1760 fn tokenIdToPrefixOp(id: &const Token.Id) ?ast.NodePrefixOp.PrefixOp {
1761 // TODO: We have to cast all cases because of this:
1762 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
14771763 return switch (*id) {
1478 Token.Id.Ampersand => ast.NodeInfixOp.InfixOp.BitAnd,
1479 Token.Id.AmpersandEqual => ast.NodeInfixOp.InfixOp.AssignBitAnd,
1480 Token.Id.AngleBracketAngleBracketLeft => ast.NodeInfixOp.InfixOp.BitShiftLeft,
1481 Token.Id.AngleBracketAngleBracketLeftEqual => ast.NodeInfixOp.InfixOp.AssignBitShiftLeft,
1482 Token.Id.AngleBracketAngleBracketRight => ast.NodeInfixOp.InfixOp.BitShiftRight,
1483 Token.Id.AngleBracketAngleBracketRightEqual => ast.NodeInfixOp.InfixOp.AssignBitShiftRight,
1484 Token.Id.AngleBracketLeft => ast.NodeInfixOp.InfixOp.LessThan,
1485 Token.Id.AngleBracketLeftEqual => ast.NodeInfixOp.InfixOp.LessOrEqual,
1486 Token.Id.AngleBracketRight => ast.NodeInfixOp.InfixOp.GreaterThan,
1487 Token.Id.AngleBracketRightEqual => ast.NodeInfixOp.InfixOp.GreaterOrEqual,
1488 Token.Id.Asterisk => ast.NodeInfixOp.InfixOp.Mult,
1489 Token.Id.AsteriskAsterisk => ast.NodeInfixOp.InfixOp.ArrayMult,
1490 Token.Id.AsteriskEqual => ast.NodeInfixOp.InfixOp.AssignTimes,
1491 Token.Id.AsteriskPercent => ast.NodeInfixOp.InfixOp.MultWrap,
1492 Token.Id.AsteriskPercentEqual => ast.NodeInfixOp.InfixOp.AssignTimesWarp,
1493 Token.Id.Bang => ast.NodeInfixOp.InfixOp.ErrorUnion,
1494 Token.Id.BangEqual => ast.NodeInfixOp.InfixOp.BangEqual,
1495 Token.Id.Caret => ast.NodeInfixOp.InfixOp.BitXor,
1496 Token.Id.CaretEqual => ast.NodeInfixOp.InfixOp.AssignBitXor,
1497 Token.Id.Equal => ast.NodeInfixOp.InfixOp.Assign,
1498 Token.Id.EqualEqual => ast.NodeInfixOp.InfixOp.EqualEqual,
1499 Token.Id.Keyword_and => ast.NodeInfixOp.InfixOp.BoolAnd,
1500 Token.Id.Keyword_or => ast.NodeInfixOp.InfixOp.BoolOr,
1501 Token.Id.Minus => ast.NodeInfixOp.InfixOp.Sub,
1502 Token.Id.MinusEqual => ast.NodeInfixOp.InfixOp.AssignMinus,
1503 Token.Id.MinusPercent => ast.NodeInfixOp.InfixOp.SubWrap,
1504 Token.Id.MinusPercentEqual => ast.NodeInfixOp.InfixOp.AssignMinusWrap,
1505 Token.Id.Percent => ast.NodeInfixOp.InfixOp.Mod,
1506 Token.Id.PercentEqual => ast.NodeInfixOp.InfixOp.AssignMod,
1507 Token.Id.Period => ast.NodeInfixOp.InfixOp.Period,
1508 Token.Id.Pipe => ast.NodeInfixOp.InfixOp.BitOr,
1509 Token.Id.PipeEqual => ast.NodeInfixOp.InfixOp.AssignBitOr,
1510 Token.Id.PipePipe => ast.NodeInfixOp.InfixOp.MergeErrorSets,
1511 Token.Id.Plus => ast.NodeInfixOp.InfixOp.Add,
1512 Token.Id.PlusEqual => ast.NodeInfixOp.InfixOp.AssignPlus,
1513 Token.Id.PlusPercent => ast.NodeInfixOp.InfixOp.AddWrap,
1514 Token.Id.PlusPercentEqual => ast.NodeInfixOp.InfixOp.AssignPlusWrap,
1515 Token.Id.PlusPlus => ast.NodeInfixOp.InfixOp.ArrayCat,
1516 Token.Id.QuestionMarkQuestionMark => ast.NodeInfixOp.InfixOp.UnwrapMaybe,
1517 Token.Id.Slash => ast.NodeInfixOp.InfixOp.Div,
1518 Token.Id.SlashEqual => ast.NodeInfixOp.InfixOp.AssignDiv,
1764 Token.Id.Bang => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.BoolNot),
1765 Token.Id.Tilde => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.BitNot),
1766 Token.Id.Minus => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.Negation),
1767 Token.Id.MinusPercent => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.NegationWrap),
1768 Token.Id.Asterisk => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.Deref),
1769 Token.Id.Ampersand => ast.NodePrefixOp.PrefixOp {
1770 .AddrOf = ast.NodePrefixOp.AddrOfInfo {
1771 .align_expr = null,
1772 .bit_offset_start_token = null,
1773 .bit_offset_end_token = null,
1774 .const_token = null,
1775 .volatile_token = null,
1776 },
1777 },
1778 Token.Id.QuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.MaybeType),
1779 Token.Id.QuestionMarkQuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.UnwrapMaybe),
15191780 else => null,
15201781 };
15211782 }
......@@ -1637,6 +1898,19 @@ pub const Parser = struct {
16371898 return node;
16381899 }
16391900
1901 fn createControlFlowExpr(self: &Parser, arena: &mem.Allocator, ltoken: &const Token,
1902 kind: &const ast.NodeControlFlowExpression.Kind) !&ast.NodeControlFlowExpression
1903 {
1904 const node = try arena.create(ast.NodeControlFlowExpression);
1905 *node = ast.NodeControlFlowExpression {
1906 .base = self.initNode(ast.Node.Id.ControlFlowExpression),
1907 .ltoken = *ltoken,
1908 .kind = *kind,
1909 .rhs = undefined,
1910 };
1911 return node;
1912 }
1913
16401914 fn createInfixOp(self: &Parser, arena: &mem.Allocator, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) !&ast.NodeInfixOp {
16411915 const node = try arena.create(ast.NodeInfixOp);
16421916
......@@ -1752,37 +2026,54 @@ pub const Parser = struct {
17522026 return node;
17532027 }
17542028
1755 fn parseError(self: &Parser, token: &const Token, comptime fmt: []const u8, args: ...) (error{ParseError}) {
1756 const loc = self.tokenizer.getTokenLocation(0, token);
1757 warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args);
1758 warn("{}\n", self.tokenizer.buffer[loc.line_start..loc.line_end]);
1759 {
1760 var i: usize = 0;
1761 while (i < loc.column) : (i += 1) {
1762 warn(" ");
2029 fn parseError(self: &Parser, stack: &ArrayList(State), token: &const Token, comptime fmt: []const u8, args: ...) !void {
2030 // Before reporting an error. We pop the stack to see if our state was optional
2031 self.revertIfOptional(stack) catch {
2032 const loc = self.tokenizer.getTokenLocation(0, token);
2033 warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args);
2034 warn("{}\n", self.tokenizer.buffer[loc.line_start..loc.line_end]);
2035 {
2036 var i: usize = 0;
2037 while (i < loc.column) : (i += 1) {
2038 warn(" ");
2039 }
17632040 }
1764 }
1765 {
1766 const caret_count = token.end - token.start;
1767 var i: usize = 0;
1768 while (i < caret_count) : (i += 1) {
1769 warn("~");
2041 {
2042 const caret_count = token.end - token.start;
2043 var i: usize = 0;
2044 while (i < caret_count) : (i += 1) {
2045 warn("~");
2046 }
17702047 }
1771 }
1772 warn("\n");
1773 return error.ParseError;
2048 warn("\n");
2049 return error.ParseError;
2050 };
17742051 }
17752052
1776 fn expectToken(self: &Parser, token: &const Token, id: @TagType(Token.Id)) !void {
2053 fn eatToken(self: &Parser, stack: &ArrayList(State), id: @TagType(Token.Id)) !?Token {
2054 const token = self.getNextToken();
17772055 if (token.id != id) {
1778 return self.parseError(token, "expected {}, found {}", @tagName(id), @tagName(token.id));
2056 try self.parseError(stack, token, "expected {}, found {}", @tagName(id), @tagName(token.id));
2057 return null;
17792058 }
2059 return token;
17802060 }
17812061
1782 fn eatToken(self: &Parser, id: @TagType(Token.Id)) !Token {
1783 const token = self.getNextToken();
1784 try self.expectToken(token, id);
1785 return token;
2062 fn revertIfOptional(self: &Parser, stack: &ArrayList(State)) !void {
2063 while (stack.popOrNull()) |state| {
2064 switch (state) {
2065 State.Optional => |revert| {
2066 *self = state.Optional;
2067 return;
2068 },
2069 State.Required => {
2070 return error.StateRequired;
2071 },
2072 else => { }
2073 }
2074 }
2075
2076 return error.NoOptionalStateFound;
17862077 }
17872078
17882079 fn putBackToken(self: &Parser, token: &const Token) void {
......@@ -2054,51 +2345,62 @@ pub const Parser = struct {
20542345 ast.Node.Id.InfixOp => {
20552346 const prefix_op_node = @fieldParentPtr(ast.NodeInfixOp, "base", base);
20562347 try stack.append(RenderState { .Expression = prefix_op_node.rhs });
2057 const text = switch (prefix_op_node.op) {
2058 ast.NodeInfixOp.InfixOp.Add => " + ",
2059 ast.NodeInfixOp.InfixOp.AddWrap => " +% ",
2060 ast.NodeInfixOp.InfixOp.ArrayCat => " ++ ",
2061 ast.NodeInfixOp.InfixOp.ArrayMult => " ** ",
2062 ast.NodeInfixOp.InfixOp.Assign => " = ",
2063 ast.NodeInfixOp.InfixOp.AssignBitAnd => " &= ",
2064 ast.NodeInfixOp.InfixOp.AssignBitOr => " |= ",
2065 ast.NodeInfixOp.InfixOp.AssignBitShiftLeft => " <<= ",
2066 ast.NodeInfixOp.InfixOp.AssignBitShiftRight => " >>= ",
2067 ast.NodeInfixOp.InfixOp.AssignBitXor => " ^= ",
2068 ast.NodeInfixOp.InfixOp.AssignDiv => " /= ",
2069 ast.NodeInfixOp.InfixOp.AssignMinus => " -= ",
2070 ast.NodeInfixOp.InfixOp.AssignMinusWrap => " -%= ",
2071 ast.NodeInfixOp.InfixOp.AssignMod => " %= ",
2072 ast.NodeInfixOp.InfixOp.AssignPlus => " += ",
2073 ast.NodeInfixOp.InfixOp.AssignPlusWrap => " +%= ",
2074 ast.NodeInfixOp.InfixOp.AssignTimes => " *= ",
2075 ast.NodeInfixOp.InfixOp.AssignTimesWarp => " *%= ",
2076 ast.NodeInfixOp.InfixOp.BangEqual => " != ",
2077 ast.NodeInfixOp.InfixOp.BitAnd => " & ",
2078 ast.NodeInfixOp.InfixOp.BitOr => " | ",
2079 ast.NodeInfixOp.InfixOp.BitShiftLeft => " << ",
2080 ast.NodeInfixOp.InfixOp.BitShiftRight => " >> ",
2081 ast.NodeInfixOp.InfixOp.BitXor => " ^ ",
2082 ast.NodeInfixOp.InfixOp.BoolAnd => " and ",
2083 ast.NodeInfixOp.InfixOp.BoolOr => " or ",
2084 ast.NodeInfixOp.InfixOp.Div => " / ",
2085 ast.NodeInfixOp.InfixOp.EqualEqual => " == ",
2086 ast.NodeInfixOp.InfixOp.ErrorUnion => "!",
2087 ast.NodeInfixOp.InfixOp.GreaterOrEqual => " >= ",
2088 ast.NodeInfixOp.InfixOp.GreaterThan => " > ",
2089 ast.NodeInfixOp.InfixOp.LessOrEqual => " <= ",
2090 ast.NodeInfixOp.InfixOp.LessThan => " < ",
2091 ast.NodeInfixOp.InfixOp.MergeErrorSets => " || ",
2092 ast.NodeInfixOp.InfixOp.Mod => " % ",
2093 ast.NodeInfixOp.InfixOp.Mult => " * ",
2094 ast.NodeInfixOp.InfixOp.MultWrap => " *% ",
2095 ast.NodeInfixOp.InfixOp.Period => ".",
2096 ast.NodeInfixOp.InfixOp.Sub => " - ",
2097 ast.NodeInfixOp.InfixOp.SubWrap => " -% ",
2098 ast.NodeInfixOp.InfixOp.UnwrapMaybe => " ?? ",
2099 };
21002348
2101 try stack.append(RenderState { .Text = text });
2349 if (prefix_op_node.op == ast.NodeInfixOp.InfixOp.Catch) {
2350 if (prefix_op_node.op.Catch) |payload| {
2351 try stack.append(RenderState { .Text = "|" });
2352 try stack.append(RenderState { .Expression = &payload.base });
2353 try stack.append(RenderState { .Text = "|" });
2354 }
2355 try stack.append(RenderState { .Text = " catch " });
2356 } else {
2357 const text = switch (prefix_op_node.op) {
2358 ast.NodeInfixOp.InfixOp.Add => " + ",
2359 ast.NodeInfixOp.InfixOp.AddWrap => " +% ",
2360 ast.NodeInfixOp.InfixOp.ArrayCat => " ++ ",
2361 ast.NodeInfixOp.InfixOp.ArrayMult => " ** ",
2362 ast.NodeInfixOp.InfixOp.Assign => " = ",
2363 ast.NodeInfixOp.InfixOp.AssignBitAnd => " &= ",
2364 ast.NodeInfixOp.InfixOp.AssignBitOr => " |= ",
2365 ast.NodeInfixOp.InfixOp.AssignBitShiftLeft => " <<= ",
2366 ast.NodeInfixOp.InfixOp.AssignBitShiftRight => " >>= ",
2367 ast.NodeInfixOp.InfixOp.AssignBitXor => " ^= ",
2368 ast.NodeInfixOp.InfixOp.AssignDiv => " /= ",
2369 ast.NodeInfixOp.InfixOp.AssignMinus => " -= ",
2370 ast.NodeInfixOp.InfixOp.AssignMinusWrap => " -%= ",
2371 ast.NodeInfixOp.InfixOp.AssignMod => " %= ",
2372 ast.NodeInfixOp.InfixOp.AssignPlus => " += ",
2373 ast.NodeInfixOp.InfixOp.AssignPlusWrap => " +%= ",
2374 ast.NodeInfixOp.InfixOp.AssignTimes => " *= ",
2375 ast.NodeInfixOp.InfixOp.AssignTimesWarp => " *%= ",
2376 ast.NodeInfixOp.InfixOp.BangEqual => " != ",
2377 ast.NodeInfixOp.InfixOp.BitAnd => " & ",
2378 ast.NodeInfixOp.InfixOp.BitOr => " | ",
2379 ast.NodeInfixOp.InfixOp.BitShiftLeft => " << ",
2380 ast.NodeInfixOp.InfixOp.BitShiftRight => " >> ",
2381 ast.NodeInfixOp.InfixOp.BitXor => " ^ ",
2382 ast.NodeInfixOp.InfixOp.BoolAnd => " and ",
2383 ast.NodeInfixOp.InfixOp.BoolOr => " or ",
2384 ast.NodeInfixOp.InfixOp.Div => " / ",
2385 ast.NodeInfixOp.InfixOp.EqualEqual => " == ",
2386 ast.NodeInfixOp.InfixOp.ErrorUnion => "!",
2387 ast.NodeInfixOp.InfixOp.GreaterOrEqual => " >= ",
2388 ast.NodeInfixOp.InfixOp.GreaterThan => " > ",
2389 ast.NodeInfixOp.InfixOp.LessOrEqual => " <= ",
2390 ast.NodeInfixOp.InfixOp.LessThan => " < ",
2391 ast.NodeInfixOp.InfixOp.MergeErrorSets => " || ",
2392 ast.NodeInfixOp.InfixOp.Mod => " % ",
2393 ast.NodeInfixOp.InfixOp.Mult => " * ",
2394 ast.NodeInfixOp.InfixOp.MultWrap => " *% ",
2395 ast.NodeInfixOp.InfixOp.Period => ".",
2396 ast.NodeInfixOp.InfixOp.Sub => " - ",
2397 ast.NodeInfixOp.InfixOp.SubWrap => " -% ",
2398 ast.NodeInfixOp.InfixOp.UnwrapMaybe => " ?? ",
2399 else => unreachable,
2400 };
2401
2402 try stack.append(RenderState { .Text = text });
2403 }
21022404 try stack.append(RenderState { .Expression = prefix_op_node.lhs });
21032405 },
21042406 ast.Node.Id.PrefixOp => {
......@@ -2143,9 +2445,9 @@ pub const Parser = struct {
21432445 ast.NodePrefixOp.PrefixOp.Deref => try stream.write("*"),
21442446 ast.NodePrefixOp.PrefixOp.Negation => try stream.write("-"),
21452447 ast.NodePrefixOp.PrefixOp.NegationWrap => try stream.write("-%"),
2146 ast.NodePrefixOp.PrefixOp.Return => try stream.write("return "),
21472448 ast.NodePrefixOp.PrefixOp.Try => try stream.write("try "),
21482449 ast.NodePrefixOp.PrefixOp.UnwrapMaybe => try stream.write("??"),
2450 ast.NodePrefixOp.PrefixOp.MaybeType => try stream.write("?"),
21492451 }
21502452 },
21512453 ast.Node.Id.SuffixOp => {
......@@ -2185,6 +2487,32 @@ pub const Parser = struct {
21852487
21862488 try stack.append(RenderState { .Expression = suffix_op.lhs });
21872489 },
2490 ast.Node.Id.ControlFlowExpression => {
2491 const flow_expr = @fieldParentPtr(ast.NodeControlFlowExpression, "base", base);
2492 switch (flow_expr.kind) {
2493 ast.NodeControlFlowExpression.Kind.Break => |maybe_blk_token| {
2494 try stream.print("break");
2495 if (maybe_blk_token) |blk_token| {
2496 try stream.print(" :{}", self.tokenizer.getTokenSlice(blk_token));
2497 }
2498 },
2499 ast.NodeControlFlowExpression.Kind.Continue => |maybe_blk_token| {
2500 try stream.print("continue");
2501 if (maybe_blk_token) |blk_token| {
2502 try stream.print(" :{}", self.tokenizer.getTokenSlice(blk_token));
2503 }
2504 },
2505 ast.NodeControlFlowExpression.Kind.Return => {
2506 try stream.print("return");
2507 },
2508
2509 }
2510
2511 if (flow_expr.rhs) |rhs| {
2512 try stream.print(" ");
2513 try stack.append(RenderState { .Expression = rhs });
2514 }
2515 },
21882516 ast.Node.Id.GroupedExpression => {
21892517 const grouped_expr = @fieldParentPtr(ast.NodeGroupedExpression, "base", base);
21902518 try stack.append(RenderState { .Text = ")"});
......@@ -2770,7 +3098,6 @@ test "zig fmt: values" {
27703098 \\ error;
27713099 \\ this;
27723100 \\ unreachable;
2773 \\ suspend;
27743101 \\}
27753102 \\
27763103 );
......@@ -2906,6 +3233,38 @@ test "zig fmt: error set declaration" {
29063233 );
29073234}
29083235
3236test "zig fmt: catch" {
3237 try testCanonical(
3238 \\test "catch" {
3239 \\ const a: error!u8 = 0;
3240 \\ _ = a catch return;
3241 \\ _ = a catch |err| return;
3242 \\}
3243 \\
3244 );
3245}
3246
3247test "zig fmt: arrays" {
3248 try testCanonical(
3249 \\test "test array" {
3250 \\ const a: [2]u8 = [2]u8{ 1, 2 };
3251 \\ const a: [2]u8 = []u8{ 1, 2 };
3252 \\ const a: [0]u8 = []u8{};
3253 \\}
3254 \\
3255 );
3256}
3257
3258test "zig fmt: container initializers" {
3259 try testCanonical(
3260 \\const a1 = []u8{ };
3261 \\const a2 = []u8{ 1, 2, 3, 4 };
3262 \\const s1 = S{ };
3263 \\const s2 = S{ .a = 1, .b = 2, };
3264 \\
3265 );
3266}
3267
29093268test "zig fmt: switch" {
29103269 try testCanonical(
29113270 \\test "switch" {
......@@ -3106,17 +3465,6 @@ test "zig fmt: defer" {
31063465 );
31073466}
31083467
3109test "zig fmt: catch" {
3110 try testCanonical(
3111 \\test "catch" {
3112 \\ const a: error!u8 = 0;
3113 \\ _ = a catch return;
3114 \\ _ = a catch |err| return;
3115 \\}
3116 \\
3117 );
3118}
3119
31203468test "zig fmt: comptime" {
31213469 try testCanonical(
31223470 \\fn a() u8 {
......@@ -3201,27 +3549,6 @@ test "zig fmt: coroutines" {
32013549 );
32023550}
32033551
3204test "zig fmt: arrays" {
3205 try testCanonical(
3206 \\test "test array" {
3207 \\ const a: [2]u8 = [2]u8{ 1, 2 };
3208 \\ const a: [2]u8 = []u8{ 1, 2 };
3209 \\ const a: [0]u8 = []u8{};
3210 \\}
3211 \\
3212 );
3213}
3214
3215test "zig fmt: container initializers" {
3216 try testCanonical(
3217 \\const a1 = []u8{ };
3218 \\const a2 = []u8{ 1, 2, 3, 4 };
3219 \\const s1 = S{ };
3220 \\const s2 = S{ .a = 1, .b = 2, };
3221 \\
3222 );
3223}
3224
32253552test "zig fmt: zig fmt" {
32263553 try testCanonical(@embedFile("ast.zig"));
32273554 try testCanonical(@embedFile("index.zig"));
std/zig/tokenizer.zig+10
......@@ -15,8 +15,11 @@ pub const Token = struct {
1515 KeywordId{.bytes="align", .id = Id.Keyword_align},
1616 KeywordId{.bytes="and", .id = Id.Keyword_and},
1717 KeywordId{.bytes="asm", .id = Id.Keyword_asm},
18 KeywordId{.bytes="async", .id = Id.Keyword_async},
19 KeywordId{.bytes="await", .id = Id.Keyword_await},
1820 KeywordId{.bytes="break", .id = Id.Keyword_break},
1921 KeywordId{.bytes="catch", .id = Id.Keyword_catch},
22 KeywordId{.bytes="cancel", .id = Id.Keyword_cancel},
2023 KeywordId{.bytes="comptime", .id = Id.Keyword_comptime},
2124 KeywordId{.bytes="const", .id = Id.Keyword_const},
2225 KeywordId{.bytes="continue", .id = Id.Keyword_continue},
......@@ -37,10 +40,12 @@ pub const Token = struct {
3740 KeywordId{.bytes="or", .id = Id.Keyword_or},
3841 KeywordId{.bytes="packed", .id = Id.Keyword_packed},
3942 KeywordId{.bytes="pub", .id = Id.Keyword_pub},
43 KeywordId{.bytes="resume", .id = Id.Keyword_resume},
4044 KeywordId{.bytes="return", .id = Id.Keyword_return},
4145 KeywordId{.bytes="section", .id = Id.Keyword_section},
4246 KeywordId{.bytes="stdcallcc", .id = Id.Keyword_stdcallcc},
4347 KeywordId{.bytes="struct", .id = Id.Keyword_struct},
48 KeywordId{.bytes="suspend", .id = Id.Keyword_suspend},
4449 KeywordId{.bytes="switch", .id = Id.Keyword_switch},
4550 KeywordId{.bytes="test", .id = Id.Keyword_test},
4651 KeywordId{.bytes="this", .id = Id.Keyword_this},
......@@ -134,7 +139,10 @@ pub const Token = struct {
134139 Keyword_align,
135140 Keyword_and,
136141 Keyword_asm,
142 Keyword_async,
143 Keyword_await,
137144 Keyword_break,
145 Keyword_cancel,
138146 Keyword_catch,
139147 Keyword_comptime,
140148 Keyword_const,
......@@ -156,10 +164,12 @@ pub const Token = struct {
156164 Keyword_or,
157165 Keyword_packed,
158166 Keyword_pub,
167 Keyword_resume,
159168 Keyword_return,
160169 Keyword_section,
161170 Keyword_stdcallcc,
162171 Keyword_struct,
172 Keyword_suspend,
163173 Keyword_switch,
164174 Keyword_test,
165175 Keyword_this,