authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-11 09:21:06-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-11 09:21:06-05:00
logfd6a36a23509fb956e05f0052b8ab5a80ead3380
tree3d4467eae7a82b33d7684255e63b6df8cea3dd51
parent9a51091a5c3d7547989d705e3feebad6252019a6

self-hosted: parsing and rendering blocks


2 files changed, 292 insertions(+), 107 deletions(-)

src-self-hosted/main.zig+284-107
......@@ -169,7 +169,7 @@ const Tokenizer = struct {
169169 if (c == '\n') {
170170 loc.line += 1;
171171 loc.column = 0;
172 loc.line_start = i;
172 loc.line_start = i + 1;
173173 } else {
174174 loc.column += 1;
175175 }
......@@ -520,6 +520,7 @@ const AstNode = struct {
520520 FnProto,
521521 ParamDecl,
522522 AddrOfExpr,
523 Block,
523524 };
524525
525526 fn iterate(base: &AstNode, index: usize) -> ?&AstNode {
......@@ -530,6 +531,7 @@ const AstNode = struct {
530531 Id.FnProto => @fieldParentPtr(AstNodeFnProto, "base", base).iterate(index),
531532 Id.ParamDecl => @fieldParentPtr(AstNodeParamDecl, "base", base).iterate(index),
532533 Id.AddrOfExpr => @fieldParentPtr(AstNodeAddrOfExpr, "base", base).iterate(index),
534 Id.Block => @fieldParentPtr(AstNodeBlock, "base", base).iterate(index),
533535 };
534536 }
535537
......@@ -541,6 +543,7 @@ const AstNode = struct {
541543 Id.FnProto => allocator.destroy(@fieldParentPtr(AstNodeFnProto, "base", base)),
542544 Id.ParamDecl => allocator.destroy(@fieldParentPtr(AstNodeParamDecl, "base", base)),
543545 Id.AddrOfExpr => allocator.destroy(@fieldParentPtr(AstNodeAddrOfExpr, "base", base)),
546 Id.Block => allocator.destroy(@fieldParentPtr(AstNodeBlock, "base", base)),
544547 };
545548 }
546549};
......@@ -551,7 +554,7 @@ const AstNodeRoot = struct {
551554
552555 fn iterate(self: &AstNodeRoot, index: usize) -> ?&AstNode {
553556 if (index < self.decls.len) {
554 return self.decls.items[index];
557 return self.decls.items[self.decls.len - index - 1];
555558 }
556559 return null;
557560 }
......@@ -612,36 +615,36 @@ const AstNodeFnProto = struct {
612615 extern_token: ?Token,
613616 inline_token: ?Token,
614617 cc_token: ?Token,
615 fn_def_node: ?&AstNode,
618 body_node: ?&AstNode,
616619 lib_name: ?&AstNode, // populated if this is an extern declaration
617620 align_expr: ?&AstNode, // populated if align(A) is present
618621
619622 fn iterate(self: &AstNodeFnProto, index: usize) -> ?&AstNode {
620623 var i = index;
621624
622 if (i < self.params.len) return self.params.items[i];
623 i -= self.params.len;
625 if (self.body_node) |body_node| {
626 if (i < 1) return body_node;
627 i -= 1;
628 }
624629
625630 if (self.return_type) |return_type| {
626631 if (i < 1) return return_type;
627632 i -= 1;
628633 }
629634
630 if (self.fn_def_node) |fn_def_node| {
631 if (i < 1) return fn_def_node;
635 if (self.align_expr) |align_expr| {
636 if (i < 1) return align_expr;
632637 i -= 1;
633638 }
634639
640 if (i < self.params.len) return self.params.items[self.params.len - i - 1];
641 i -= self.params.len;
642
635643 if (self.lib_name) |lib_name| {
636644 if (i < 1) return lib_name;
637645 i -= 1;
638646 }
639647
640 if (self.align_expr) |align_expr| {
641 if (i < 1) return align_expr;
642 i -= 1;
643 }
644
645648 return null;
646649 }
647650};
......@@ -689,6 +692,22 @@ const AstNodeAddrOfExpr = struct {
689692 }
690693};
691694
695const AstNodeBlock = struct {
696 base: AstNode,
697 begin_token: Token,
698 end_token: Token,
699 statements: ArrayList(&AstNode),
700
701 fn iterate(self: &AstNodeBlock, index: usize) -> ?&AstNode {
702 var i = index;
703
704 if (i < self.statements.len) return self.statements.items[i];
705 i -= self.statements.len;
706
707 return null;
708 }
709};
710
692711error ParseError;
693712
694713const Parser = struct {
......@@ -734,27 +753,41 @@ const Parser = struct {
734753 extern_token: ?Token,
735754 };
736755
756 const DestPtr = union(enum) {
757 Field: &&AstNode,
758 NullableField: &?&AstNode,
759 List: &ArrayList(&AstNode),
760
761 pub fn store(self: &const DestPtr, value: &AstNode) -> %void {
762 switch (*self) {
763 DestPtr.Field => |ptr| *ptr = value,
764 DestPtr.NullableField => |ptr| *ptr = value,
765 DestPtr.List => |list| %return list.append(value),
766 }
767 }
768 };
769
737770 const State = union(enum) {
738771 TopLevel,
739772 TopLevelExtern: ?Token,
740773 TopLevelDecl: TopLevelDeclCtx,
741 Expression: &&AstNode,
742 GroupedExpression: &&AstNode,
743 UnwrapExpression: &&AstNode,
744 BoolOrExpression: &&AstNode,
745 BoolAndExpression: &&AstNode,
746 ComparisonExpression: &&AstNode,
747 BinaryOrExpression: &&AstNode,
748 BinaryXorExpression: &&AstNode,
749 BinaryAndExpression: &&AstNode,
750 BitShiftExpression: &&AstNode,
751 AdditionExpression: &&AstNode,
752 MultiplyExpression: &&AstNode,
753 BraceSuffixExpression: &&AstNode,
754 PrefixOpExpression: &&AstNode,
755 SuffixOpExpression: &&AstNode,
756 PrimaryExpression: &&AstNode,
757 TypeExpr: &&AstNode,
774 Expression: DestPtr,
775 GroupedExpression: DestPtr,
776 UnwrapExpression: DestPtr,
777 BoolOrExpression: DestPtr,
778 BoolAndExpression: DestPtr,
779 ComparisonExpression: DestPtr,
780 BinaryOrExpression: DestPtr,
781 BinaryXorExpression: DestPtr,
782 BinaryAndExpression: DestPtr,
783 BitShiftExpression: DestPtr,
784 AdditionExpression: DestPtr,
785 MultiplyExpression: DestPtr,
786 BraceSuffixExpression: DestPtr,
787 PrefixOpExpression: DestPtr,
788 SuffixOpExpression: DestPtr,
789 PrimaryExpression: DestPtr,
790 TypeExpr: DestPtr,
758791 VarDecl: &AstNodeVarDecl,
759792 VarDeclAlign: &AstNodeVarDecl,
760793 VarDeclEq: &AstNodeVarDecl,
......@@ -763,6 +796,9 @@ const Parser = struct {
763796 FnProtoAlign: &AstNodeFnProto,
764797 ParamDecl: &AstNodeFnProto,
765798 ParamDeclComma,
799 FnDef: &AstNodeFnProto,
800 Block: &AstNodeBlock,
801 Statement: &AstNodeBlock,
766802 };
767803
768804 pub fn freeAst(self: &Parser, root_node: &AstNodeRoot) {
......@@ -797,6 +833,18 @@ const Parser = struct {
797833 %defer self.freeAst(root_node);
798834
799835 while (true) {
836 //{
837 // const token = self.getNextToken();
838 // warn("{} ", @tagName(token.id));
839 // self.putBackToken(token);
840 // var i: usize = stack.len;
841 // while (i != 0) {
842 // i -= 1;
843 // warn("{} ", @tagName(stack.items[i]));
844 // }
845 // warn("\n");
846 //}
847
800848 // This gives us 1 free append that can't fail
801849 const state = stack.pop();
802850
......@@ -850,11 +898,11 @@ const Parser = struct {
850898 },
851899 Token.Id.Keyword_fn => {
852900 stack.append(State.TopLevel) %% unreachable;
853 %return stack.append(State { .ExpectToken = Token.Id.Semicolon });
854901 // TODO shouldn't need these casts
855 const fn_proto_node = %return self.createAttachFnProto(&root_node.decls, token,
902 const fn_proto = %return self.createAttachFnProto(&root_node.decls, token,
856903 ctx.extern_token, (?Token)(null), (?Token)(null), (?Token)(null));
857 %return stack.append(State { .FnProto = fn_proto_node });
904 %return stack.append(State { .FnDef = fn_proto });
905 %return stack.append(State { .FnProto = fn_proto });
858906 continue;
859907 },
860908 Token.Id.StringLiteral => {
......@@ -862,12 +910,12 @@ const Parser = struct {
862910 },
863911 Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
864912 stack.append(State.TopLevel) %% unreachable;
865 %return stack.append(State { .ExpectToken = Token.Id.Semicolon });
866913 const fn_token = %return self.eatToken(Token.Id.Keyword_fn);
867914 // TODO shouldn't need this cast
868 const fn_proto_node = %return self.createAttachFnProto(&root_node.decls, fn_token,
915 const fn_proto = %return self.createAttachFnProto(&root_node.decls, fn_token,
869916 ctx.extern_token, (?Token)(token), (?Token)(null), (?Token)(null));
870 %return stack.append(State { .FnProto = fn_proto_node });
917 %return stack.append(State { .FnDef = fn_proto });
918 %return stack.append(State { .FnProto = fn_proto });
871919 continue;
872920 },
873921 else => return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id)),
......@@ -879,7 +927,7 @@ const Parser = struct {
879927
880928 const next_token = self.getNextToken();
881929 if (next_token.id == Token.Id.Colon) {
882 %return stack.append(State { .TypeExpr = removeNullCast(&var_decl.type_node) });
930 %return stack.append(State { .TypeExpr = DestPtr {.NullableField = &var_decl.type_node} });
883931 continue;
884932 }
885933
......@@ -891,7 +939,11 @@ const Parser = struct {
891939
892940 const next_token = self.getNextToken();
893941 if (next_token.id == Token.Id.Keyword_align) {
894 %return stack.append(State { .GroupedExpression = removeNullCast(&var_decl.align_node) });
942 %return stack.append(State {
943 .GroupedExpression = DestPtr {
944 .NullableField = &var_decl.align_node
945 }
946 });
895947 continue;
896948 }
897949
......@@ -904,7 +956,7 @@ const Parser = struct {
904956 var_decl.eq_token = token;
905957 stack.append(State { .ExpectToken = Token.Id.Semicolon }) %% unreachable;
906958 %return stack.append(State {
907 .Expression = removeNullCast(&var_decl.init_node),
959 .Expression = DestPtr {.NullableField = &var_decl.init_node},
908960 });
909961 continue;
910962 }
......@@ -917,70 +969,70 @@ const Parser = struct {
917969 _ = %return self.eatToken(token_id);
918970 continue;
919971 },
920 State.Expression => |result_ptr| {
921 stack.append(State {.UnwrapExpression = result_ptr}) %% unreachable;
972 State.Expression => |dest_ptr| {
973 stack.append(State {.UnwrapExpression = dest_ptr}) %% unreachable;
922974 continue;
923975 },
924976
925 State.UnwrapExpression => |result_ptr| {
926 stack.append(State {.BoolOrExpression = result_ptr}) %% unreachable;
977 State.UnwrapExpression => |dest_ptr| {
978 stack.append(State {.BoolOrExpression = dest_ptr}) %% unreachable;
927979 continue;
928980 },
929981
930 State.BoolOrExpression => |result_ptr| {
931 stack.append(State {.BoolAndExpression = result_ptr}) %% unreachable;
982 State.BoolOrExpression => |dest_ptr| {
983 stack.append(State {.BoolAndExpression = dest_ptr}) %% unreachable;
932984 continue;
933985 },
934986
935 State.BoolAndExpression => |result_ptr| {
936 stack.append(State {.ComparisonExpression = result_ptr}) %% unreachable;
987 State.BoolAndExpression => |dest_ptr| {
988 stack.append(State {.ComparisonExpression = dest_ptr}) %% unreachable;
937989 continue;
938990 },
939991
940 State.ComparisonExpression => |result_ptr| {
941 stack.append(State {.BinaryOrExpression = result_ptr}) %% unreachable;
992 State.ComparisonExpression => |dest_ptr| {
993 stack.append(State {.BinaryOrExpression = dest_ptr}) %% unreachable;
942994 continue;
943995 },
944996
945 State.BinaryOrExpression => |result_ptr| {
946 stack.append(State {.BinaryXorExpression = result_ptr}) %% unreachable;
997 State.BinaryOrExpression => |dest_ptr| {
998 stack.append(State {.BinaryXorExpression = dest_ptr}) %% unreachable;
947999 continue;
9481000 },
9491001
950 State.BinaryXorExpression => |result_ptr| {
951 stack.append(State {.BinaryAndExpression = result_ptr}) %% unreachable;
1002 State.BinaryXorExpression => |dest_ptr| {
1003 stack.append(State {.BinaryAndExpression = dest_ptr}) %% unreachable;
9521004 continue;
9531005 },
9541006
955 State.BinaryAndExpression => |result_ptr| {
956 stack.append(State {.BitShiftExpression = result_ptr}) %% unreachable;
1007 State.BinaryAndExpression => |dest_ptr| {
1008 stack.append(State {.BitShiftExpression = dest_ptr}) %% unreachable;
9571009 continue;
9581010 },
9591011
960 State.BitShiftExpression => |result_ptr| {
961 stack.append(State {.AdditionExpression = result_ptr}) %% unreachable;
1012 State.BitShiftExpression => |dest_ptr| {
1013 stack.append(State {.AdditionExpression = dest_ptr}) %% unreachable;
9621014 continue;
9631015 },
9641016
965 State.AdditionExpression => |result_ptr| {
966 stack.append(State {.MultiplyExpression = result_ptr}) %% unreachable;
1017 State.AdditionExpression => |dest_ptr| {
1018 stack.append(State {.MultiplyExpression = dest_ptr}) %% unreachable;
9671019 continue;
9681020 },
9691021
970 State.MultiplyExpression => |result_ptr| {
971 stack.append(State {.BraceSuffixExpression = result_ptr}) %% unreachable;
1022 State.MultiplyExpression => |dest_ptr| {
1023 stack.append(State {.BraceSuffixExpression = dest_ptr}) %% unreachable;
9721024 continue;
9731025 },
9741026
975 State.BraceSuffixExpression => |result_ptr| {
976 stack.append(State {.PrefixOpExpression = result_ptr}) %% unreachable;
1027 State.BraceSuffixExpression => |dest_ptr| {
1028 stack.append(State {.PrefixOpExpression = dest_ptr}) %% unreachable;
9771029 continue;
9781030 },
9791031
980 State.PrefixOpExpression => |result_ptr| {
1032 State.PrefixOpExpression => |dest_ptr| {
9811033 const first_token = self.getNextToken();
9821034 if (first_token.id == Token.Id.Ampersand) {
983 const addr_of_expr = %return self.createAttachAddrOfExpr(result_ptr, first_token);
1035 const addr_of_expr = %return self.createAttachAddrOfExpr(dest_ptr, first_token);
9841036 var token = self.getNextToken();
9851037 if (token.id == Token.Id.Keyword_align) {
9861038 @panic("TODO align");
......@@ -994,40 +1046,42 @@ const Parser = struct {
9941046 token = self.getNextToken();
9951047 }
9961048 self.putBackToken(token);
997 stack.append(State { .PrefixOpExpression = &addr_of_expr.op_expr }) %% unreachable;
1049 stack.append(State {
1050 .PrefixOpExpression = DestPtr { .Field = &addr_of_expr.op_expr},
1051 }) %% unreachable;
9981052 continue;
9991053 }
10001054
10011055 self.putBackToken(first_token);
1002 stack.append(State { .SuffixOpExpression = result_ptr }) %% unreachable;
1056 stack.append(State { .SuffixOpExpression = dest_ptr }) %% unreachable;
10031057 continue;
10041058 },
10051059
1006 State.SuffixOpExpression => |result_ptr| {
1007 stack.append(State { .PrimaryExpression = result_ptr }) %% unreachable;
1060 State.SuffixOpExpression => |dest_ptr| {
1061 stack.append(State { .PrimaryExpression = dest_ptr }) %% unreachable;
10081062 continue;
10091063 },
10101064
1011 State.PrimaryExpression => |result_ptr| {
1065 State.PrimaryExpression => |dest_ptr| {
10121066 const token = self.getNextToken();
10131067 switch (token.id) {
10141068 Token.Id.Identifier => {
10151069 const identifier = %return self.createIdentifier(token);
1016 *result_ptr = &identifier.base;
1070 %return dest_ptr.store(&identifier.base);
10171071 continue;
10181072 },
10191073 else => return self.parseError(token, "expected primary expression, found {}", @tagName(token.id)),
10201074 }
10211075 },
10221076
1023 State.TypeExpr => |result_ptr| {
1077 State.TypeExpr => |dest_ptr| {
10241078 const token = self.getNextToken();
10251079 if (token.id == Token.Id.Keyword_var) {
10261080 @panic("TODO param with type var");
10271081 }
10281082 self.putBackToken(token);
10291083
1030 stack.append(State { .PrefixOpExpression = result_ptr }) %% unreachable;
1084 stack.append(State { .PrefixOpExpression = dest_ptr }) %% unreachable;
10311085 continue;
10321086 },
10331087
......@@ -1051,7 +1105,9 @@ const Parser = struct {
10511105 @panic("TODO fn proto align");
10521106 }
10531107 if (token.id == Token.Id.Arrow) {
1054 stack.append(State { .TypeExpr = removeNullCast(&fn_proto.return_type) }) %% unreachable;
1108 stack.append(State {
1109 .TypeExpr = DestPtr {.NullableField = &fn_proto.return_type},
1110 }) %% unreachable;
10551111 continue;
10561112 } else {
10571113 self.putBackToken(token);
......@@ -1091,7 +1147,9 @@ const Parser = struct {
10911147
10921148 stack.append(State { .ParamDecl = fn_proto }) %% unreachable;
10931149 %return stack.append(State.ParamDeclComma);
1094 %return stack.append(State { .TypeExpr = &param_decl.type_node });
1150 %return stack.append(State {
1151 .TypeExpr = DestPtr {.Field = &param_decl.type_node}
1152 });
10951153 continue;
10961154 },
10971155
......@@ -1107,6 +1165,70 @@ const Parser = struct {
11071165 }
11081166 },
11091167
1168 State.FnDef => |fn_proto| {
1169 const token = self.getNextToken();
1170 switch(token.id) {
1171 Token.Id.LBrace => {
1172 const block = %return self.createBlock(token);
1173 fn_proto.body_node = &block.base;
1174 stack.append(State { .Block = block }) %% unreachable;
1175 continue;
1176 },
1177 Token.Id.Semicolon => continue,
1178 else => return self.parseError(token, "expected ';' or '{{', found {}", @tagName(token.id)),
1179 }
1180 },
1181
1182 State.Block => |block| {
1183 const token = self.getNextToken();
1184 switch (token.id) {
1185 Token.Id.RBrace => {
1186 block.end_token = token;
1187 continue;
1188 },
1189 else => {
1190 self.putBackToken(token);
1191 stack.append(State { .Block = block }) %% unreachable;
1192 %return stack.append(State { .Statement = block });
1193 continue;
1194 },
1195 }
1196 },
1197
1198 State.Statement => |block| {
1199 {
1200 // Look for comptime var, comptime const
1201 const comptime_token = self.getNextToken();
1202 if (comptime_token.id == Token.Id.Keyword_comptime) {
1203 const mut_token = self.getNextToken();
1204 if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) {
1205 // TODO shouldn't need these casts
1206 const var_decl = %return self.createAttachVarDecl(&block.statements, (?Token)(null),
1207 mut_token, (?Token)(comptime_token), (?Token)(null));
1208 %return stack.append(State { .VarDecl = var_decl });
1209 continue;
1210 }
1211 self.putBackToken(mut_token);
1212 }
1213 self.putBackToken(comptime_token);
1214 }
1215 {
1216 // Look for const, var
1217 const mut_token = self.getNextToken();
1218 if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) {
1219 // TODO shouldn't need these casts
1220 const var_decl = %return self.createAttachVarDecl(&block.statements, (?Token)(null),
1221 mut_token, (?Token)(null), (?Token)(null));
1222 %return stack.append(State { .VarDecl = var_decl });
1223 continue;
1224 }
1225 self.putBackToken(mut_token);
1226 }
1227
1228 stack.append(State { .ExpectToken = Token.Id.Semicolon }) %% unreachable;
1229 %return stack.append(State { .Expression = DestPtr{.List = &block.statements} });
1230 continue;
1231 },
11101232
11111233 State.GroupedExpression => @panic("TODO"),
11121234 }
......@@ -1176,7 +1298,7 @@ const Parser = struct {
11761298 .extern_token = *extern_token,
11771299 .inline_token = *inline_token,
11781300 .cc_token = *cc_token,
1179 .fn_def_node = null,
1301 .body_node = null,
11801302 .lib_name = null,
11811303 .align_expr = null,
11821304 };
......@@ -1215,10 +1337,23 @@ const Parser = struct {
12151337 return node;
12161338 }
12171339
1218 fn createAttachAddrOfExpr(self: &Parser, result_ptr: &&AstNode, op_token: &const Token) -> %&AstNodeAddrOfExpr {
1340 fn createBlock(self: &Parser, begin_token: &const Token) -> %&AstNodeBlock {
1341 const node = %return self.allocator.create(AstNodeBlock);
1342 %defer self.allocator.destroy(node);
1343
1344 *node = AstNodeBlock {
1345 .base = AstNode {.id = AstNode.Id.Block},
1346 .begin_token = *begin_token,
1347 .end_token = undefined,
1348 .statements = ArrayList(&AstNode).init(self.allocator),
1349 };
1350 return node;
1351 }
1352
1353 fn createAttachAddrOfExpr(self: &Parser, dest_ptr: &const DestPtr, op_token: &const Token) -> %&AstNodeAddrOfExpr {
12191354 const node = %return self.createAddrOfExpr(op_token);
12201355 %defer self.allocator.destroy(node);
1221 *result_ptr = &node.base;
1356 %return dest_ptr.store(&node.base);
12221357 return node;
12231358 }
12241359
......@@ -1337,7 +1472,11 @@ const Parser = struct {
13371472 Text: []const u8,
13381473 Expression: &AstNode,
13391474 AddrOfExprBit: &AstNodeAddrOfExpr,
1475 VarDecl: &AstNodeVarDecl,
13401476 VarDeclAlign: &AstNodeVarDecl,
1477 Statement: &AstNode,
1478 PrintIndent,
1479 Indent: usize,
13411480 };
13421481
13431482 pub fn renderSource(self: &Parser, stream: &std.io.OutStream, root_node: &AstNodeRoot) -> %void {
......@@ -1353,6 +1492,8 @@ const Parser = struct {
13531492 }
13541493 }
13551494
1495 const indent_delta = 4;
1496 var indent: usize = 0;
13561497 while (stack.popOrNull()) |state| {
13571498 switch (state) {
13581499 RenderState.TopLevelDecl => |decl| {
......@@ -1378,7 +1519,7 @@ const Parser = struct {
13781519 %return stream.print("(");
13791520
13801521 %return stack.append(RenderState { .Text = "\n" });
1381 if (fn_proto.fn_def_node == null) {
1522 if (fn_proto.body_node == null) {
13821523 %return stack.append(RenderState { .Text = ";" });
13831524 }
13841525
......@@ -1395,36 +1536,42 @@ const Parser = struct {
13951536 },
13961537 AstNode.Id.VarDecl => {
13971538 const var_decl = @fieldParentPtr(AstNodeVarDecl, "base", decl);
1398 if (var_decl.visib_token) |visib_token| {
1399 %return stream.print("{} ", self.tokenizer.getTokenSlice(visib_token));
1400 }
1401 if (var_decl.extern_token) |extern_token| {
1402 %return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token));
1403 if (var_decl.lib_name != null) {
1404 @panic("TODO");
1405 }
1406 }
1407 if (var_decl.comptime_token) |comptime_token| {
1408 %return stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token));
1409 }
1410 %return stream.print("{} ", self.tokenizer.getTokenSlice(var_decl.mut_token));
1411 %return stream.print("{}", self.tokenizer.getTokenSlice(var_decl.name_token));
1539 %return stack.append(RenderState { .Text = "\n"});
1540 %return stack.append(RenderState { .VarDecl = var_decl});
14121541
1413 %return stack.append(RenderState { .VarDeclAlign = var_decl });
1414 if (var_decl.type_node) |type_node| {
1415 %return stream.print(": ");
1416 %return stack.append(RenderState { .Expression = type_node });
1417 }
14181542 },
14191543 else => unreachable,
14201544 }
14211545 },
14221546
1547 RenderState.VarDecl => |var_decl| {
1548 if (var_decl.visib_token) |visib_token| {
1549 %return stream.print("{} ", self.tokenizer.getTokenSlice(visib_token));
1550 }
1551 if (var_decl.extern_token) |extern_token| {
1552 %return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token));
1553 if (var_decl.lib_name != null) {
1554 @panic("TODO");
1555 }
1556 }
1557 if (var_decl.comptime_token) |comptime_token| {
1558 %return stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token));
1559 }
1560 %return stream.print("{} ", self.tokenizer.getTokenSlice(var_decl.mut_token));
1561 %return stream.print("{}", self.tokenizer.getTokenSlice(var_decl.name_token));
1562
1563 %return stack.append(RenderState { .VarDeclAlign = var_decl });
1564 if (var_decl.type_node) |type_node| {
1565 %return stream.print(": ");
1566 %return stack.append(RenderState { .Expression = type_node });
1567 }
1568 },
1569
14231570 RenderState.VarDeclAlign => |var_decl| {
14241571 if (var_decl.align_node != null) {
14251572 @panic("TODO");
14261573 }
1427 %return stack.append(RenderState { .Text = ";\n" });
1574 %return stack.append(RenderState { .Text = ";" });
14281575 if (var_decl.init_node) |init_node| {
14291576 %return stream.print(" = ");
14301577 %return stack.append(RenderState { .Expression = init_node });
......@@ -1467,6 +1614,23 @@ const Parser = struct {
14671614 %return stack.append(RenderState { .Expression = align_expr});
14681615 }
14691616 },
1617 AstNode.Id.Block => {
1618 const block = @fieldParentPtr(AstNodeBlock, "base", base);
1619 %return stream.write("{");
1620 %return stack.append(RenderState { .Text = "}"});
1621 %return stack.append(RenderState.PrintIndent);
1622 %return stack.append(RenderState { .Indent = indent});
1623 %return stack.append(RenderState { .Text = "\n"});
1624 var i = block.statements.len;
1625 while (i != 0) {
1626 i -= 1;
1627 const statement_node = block.statements.items[i];
1628 %return stack.append(RenderState { .Statement = statement_node});
1629 %return stack.append(RenderState.PrintIndent);
1630 %return stack.append(RenderState { .Indent = indent + indent_delta});
1631 %return stack.append(RenderState { .Text = "\n" });
1632 }
1633 },
14701634 else => unreachable,
14711635 },
14721636 RenderState.AddrOfExprBit => |addr_of_expr| {
......@@ -1491,9 +1655,24 @@ const Parser = struct {
14911655 }
14921656 if (fn_proto.return_type) |return_type| {
14931657 %return stream.print(" -> ");
1658 if (fn_proto.body_node) |body_node| {
1659 %return stack.append(RenderState { .Expression = body_node});
1660 %return stack.append(RenderState { .Text = " "});
1661 }
14941662 %return stack.append(RenderState { .Expression = return_type});
14951663 }
14961664 },
1665 RenderState.Statement => |base| {
1666 switch (base.id) {
1667 AstNode.Id.VarDecl => {
1668 const var_decl = @fieldParentPtr(AstNodeVarDecl, "base", base);
1669 %return stack.append(RenderState { .VarDecl = var_decl});
1670 },
1671 else => unreachable,
1672 }
1673 },
1674 RenderState.Indent => |new_indent| indent = new_indent,
1675 RenderState.PrintIndent => %return stream.writeByteNTimes(' ', indent),
14971676 }
14981677 }
14991678 }
......@@ -1555,15 +1734,6 @@ pub fn main2() -> %void {
15551734 %return parser.renderSource(out_stream, root_node);
15561735}
15571736
1558fn removeNullCast(x: var) -> {const InnerPtr = @typeOf(x).Child.Child; &InnerPtr} {
1559 comptime assert(@typeId(@typeOf(x)) == builtin.TypeId.Pointer);
1560 comptime assert(@typeId(@typeOf(x).Child) == builtin.TypeId.Nullable);
1561 comptime assert(@typeId(@typeOf(x).Child.Child) == builtin.TypeId.Pointer);
1562 const InnerPtr = @typeOf(x).Child.Child;
1563 return @ptrCast(&InnerPtr, x);
1564}
1565
1566
15671737
15681738fn testCanonical(source: []const u8) {
15691739 const allocator = std.debug.global_allocator;
......@@ -1612,4 +1782,11 @@ test "zig fmt" {
16121782 \\extern var foo: c_int;
16131783 \\
16141784 );
1785
1786 testCanonical(
1787 \\fn main(argc: c_int, argv: &&u8) -> c_int {
1788 \\ const a = b;
1789 \\}
1790 \\
1791 );
16151792}
std/io.zig+8
......@@ -481,6 +481,14 @@ pub const OutStream = struct {
481481 const slice = (&byte)[0..1];
482482 return self.writeFn(self, slice);
483483 }
484
485 pub fn writeByteNTimes(self: &OutStream, byte: u8, n: usize) -> %void {
486 const slice = (&byte)[0..1];
487 var i: usize = 0;
488 while (i < n) : (i += 1) {
489 %return self.writeFn(self, slice);
490 }
491 }
484492};
485493
486494/// `path` may need to be copied in memory to add a null terminating byte. In this case