authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-10 22:44:04-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-10 22:44:04-05:00
log53d58684a6cb09f6c8463b162e5c059a45ca56eb
treeb524a73cceb4474ec623a13f57443e9a8fb13d4d
parentf210f17d306ed1298901d38a29c1e50a1ee38ae5

self-hosted: parse var decls


1 files changed, 89 insertions(+), 60 deletions(-)

src-self-hosted/main.zig+89-60
......@@ -562,9 +562,9 @@ const AstNodeVarDecl = struct {
562562 visib_token: ?Token,
563563 name_token: Token,
564564 eq_token: Token,
565 mut: Mutability,
566 is_comptime: Comptime,
567 is_extern: Extern,
565 mut_token: Token,
566 comptime_token: ?Token,
567 extern_token: ?Token,
568568 lib_name: ?&AstNode,
569569 type_node: ?&AstNode,
570570 align_node: ?&AstNode,
......@@ -608,10 +608,10 @@ const AstNodeFnProto = struct {
608608 name_token: ?Token,
609609 params: ArrayList(&AstNode),
610610 return_type: ?&AstNode,
611 var_args: VarArgs,
612 is_extern: Extern,
613 is_inline: Inline,
614 cc: CallingConvention,
611 var_args_token: ?Token,
612 extern_token: ?Token,
613 inline_token: ?Token,
614 cc_token: ?Token,
615615 fn_def_node: ?&AstNode,
616616 lib_name: ?&AstNode, // populated if this is an extern declaration
617617 align_expr: ?&AstNode, // populated if align(A) is present
......@@ -729,10 +729,15 @@ const Parser = struct {
729729 self.allocator.free(self.utility_bytes);
730730 }
731731
732 const TopLevelExternCtx = struct {
733 visib_token: ?Token,
734 extern_token: Token,
735 };
736
732737 const State = union(enum) {
733738 TopLevel,
734739 TopLevelModifier: ?Token,
735 TopLevelExtern: ?Token,
740 TopLevelExtern: TopLevelExternCtx,
736741 Expression: &&AstNode,
737742 GroupedExpression: &&AstNode,
738743 UnwrapExpression: &&AstNode,
......@@ -803,25 +808,22 @@ const Parser = struct {
803808 stack.append(State { .TopLevelModifier = token }) %% unreachable;
804809 continue;
805810 },
806 Token.Id.Keyword_const => {
807 stack.append(State.TopLevel) %% unreachable;
808 // TODO shouldn't need this cast
809 const var_decl_node = %return self.createAttachVarDecl(&root_node.decls, (?Token)(null),
810 Mutability.Const, Comptime.No, Extern.No);
811 %return stack.append(State { .VarDecl = var_decl_node });
812 continue;
813 },
814 Token.Id.Keyword_var => {
811 Token.Id.Keyword_const, Token.Id.Keyword_var => {
815812 stack.append(State.TopLevel) %% unreachable;
816813 // TODO shouldn't need this cast
817814 const var_decl_node = %return self.createAttachVarDecl(&root_node.decls, (?Token)(null),
818 Mutability.Var, Comptime.No, Extern.No);
815 token, (?Token)(null), (?Token)(null));
819816 %return stack.append(State { .VarDecl = var_decl_node });
820817 continue;
821818 },
822819 Token.Id.Eof => return root_node,
823820 Token.Id.Keyword_extern => {
824 stack.append(State { .TopLevelExtern = null }) %% unreachable;
821 stack.append(State {
822 .TopLevelExtern = TopLevelExternCtx {
823 .visib_token = null,
824 .extern_token = token,
825 }
826 }) %% unreachable;
825827 continue;
826828 },
827829 else => return self.parseError(token, "expected top level declaration, found {}", @tagName(token.id)),
......@@ -830,43 +832,43 @@ const Parser = struct {
830832 State.TopLevelModifier => |visib_token| {
831833 const token = self.getNextToken();
832834 switch (token.id) {
833 Token.Id.Keyword_const => {
834 stack.append(State.TopLevel) %% unreachable;
835 const var_decl_node = %return self.createAttachVarDecl(&root_node.decls, visib_token,
836 Mutability.Const, Comptime.No, Extern.No);
837 %return stack.append(State { .VarDecl = var_decl_node });
838 continue;
839 },
840 Token.Id.Keyword_var => {
835 Token.Id.Keyword_const, Token.Id.Keyword_var => {
841836 stack.append(State.TopLevel) %% unreachable;
837 // TODO shouldn't need the casts here
842838 const var_decl_node = %return self.createAttachVarDecl(&root_node.decls, visib_token,
843 Mutability.Var, Comptime.No, Extern.No);
839 token, (?Token)(null), (?Token)(null));
844840 %return stack.append(State { .VarDecl = var_decl_node });
845841 continue;
846842 },
847843 Token.Id.Keyword_extern => {
848 stack.append(State { .TopLevelExtern = visib_token }) %% unreachable;
844 stack.append(State {
845 .TopLevelExtern = TopLevelExternCtx {
846 .visib_token = visib_token,
847 .extern_token = token,
848 },
849 }) %% unreachable;
849850 continue;
850851 },
851852 else => return self.parseError(token, "expected top level declaration, found {}", @tagName(token.id)),
852853 }
853854 },
854 State.TopLevelExtern => |visib_token| {
855 State.TopLevelExtern => |ctx| {
855856 const token = self.getNextToken();
856857 switch (token.id) {
857 Token.Id.Keyword_var => {
858 Token.Id.Keyword_var, Token.Id.Keyword_const => {
858859 stack.append(State.TopLevel) %% unreachable;
859 const var_decl_node = %return self.createAttachVarDecl(&root_node.decls, visib_token,
860 Mutability.Var, Comptime.No, Extern.Yes);
860 // TODO shouldn't need these casts
861 const var_decl_node = %return self.createAttachVarDecl(&root_node.decls, ctx.visib_token,
862 token, (?Token)(null), (?Token)(ctx.extern_token));
861863 %return stack.append(State { .VarDecl = var_decl_node });
862864 continue;
863865 },
864866 Token.Id.Keyword_fn => {
865867 stack.append(State.TopLevel) %% unreachable;
866868 %return stack.append(State { .ExpectToken = Token.Id.Semicolon });
867 // TODO shouldn't need this cast
869 // TODO shouldn't need these casts
868870 const fn_proto_node = %return self.createAttachFnProto(&root_node.decls, token,
869 Extern.Yes, CallingConvention.Auto, (?Token)(null), Inline.Auto);
871 (?Token)(ctx.extern_token), (?Token)(null), (?Token)(null), (?Token)(null));
870872 %return stack.append(State { .FnProto = fn_proto_node });
871873 continue;
872874 },
......@@ -876,16 +878,10 @@ const Parser = struct {
876878 Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
877879 stack.append(State.TopLevel) %% unreachable;
878880 %return stack.append(State { .ExpectToken = Token.Id.Semicolon });
879 const cc = switch (token.id) {
880 Token.Id.Keyword_coldcc => CallingConvention.Cold,
881 Token.Id.Keyword_nakedcc => CallingConvention.Naked,
882 Token.Id.Keyword_stdcallcc => CallingConvention.Stdcall,
883 else => unreachable,
884 };
885881 const fn_token = %return self.eatToken(Token.Id.Keyword_fn);
886882 // TODO shouldn't need this cast
887883 const fn_proto_node = %return self.createAttachFnProto(&root_node.decls, fn_token,
888 Extern.Yes, cc, (?Token)(null), Inline.Auto);
884 (?Token)(ctx.extern_token), (?Token)(token), (?Token)(null), (?Token)(null));
889885 %return stack.append(State { .FnProto = fn_proto_node });
890886 continue;
891887 },
......@@ -1137,8 +1133,8 @@ const Parser = struct {
11371133 return node;
11381134 }
11391135
1140 fn createVarDecl(self: &Parser, visib_token: &const ?Token, mut: Mutability, is_comptime: Comptime,
1141 is_extern: Extern) -> %&AstNodeVarDecl
1136 fn createVarDecl(self: &Parser, visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token,
1137 extern_token: &const ?Token) -> %&AstNodeVarDecl
11421138 {
11431139 const node = %return self.allocator.create(AstNodeVarDecl);
11441140 %defer self.allocator.destroy(node);
......@@ -1146,9 +1142,9 @@ const Parser = struct {
11461142 *node = AstNodeVarDecl {
11471143 .base = AstNode {.id = AstNode.Id.VarDecl},
11481144 .visib_token = *visib_token,
1149 .mut = mut,
1150 .is_comptime = is_comptime,
1151 .is_extern = is_extern,
1145 .mut_token = *mut_token,
1146 .comptime_token = *comptime_token,
1147 .extern_token = *extern_token,
11521148 .type_node = null,
11531149 .align_node = null,
11541150 .init_node = null,
......@@ -1171,8 +1167,8 @@ const Parser = struct {
11711167 return node;
11721168 }
11731169
1174 fn createFnProto(self: &Parser, fn_token: &const Token, is_extern: Extern,
1175 cc: CallingConvention, visib_token: &const ?Token, is_inline: Inline) -> %&AstNodeFnProto
1170 fn createFnProto(self: &Parser, fn_token: &const Token, extern_token: &const ?Token,
1171 cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) -> %&AstNodeFnProto
11761172 {
11771173 const node = %return self.allocator.create(AstNodeFnProto);
11781174 %defer self.allocator.destroy(node);
......@@ -1184,10 +1180,10 @@ const Parser = struct {
11841180 .fn_token = *fn_token,
11851181 .params = ArrayList(&AstNode).init(self.allocator),
11861182 .return_type = null,
1187 .var_args = VarArgs.No,
1188 .is_extern = is_extern,
1189 .is_inline = is_inline,
1190 .cc = cc,
1183 .var_args_token = null,
1184 .extern_token = *extern_token,
1185 .inline_token = *inline_token,
1186 .cc_token = *cc_token,
11911187 .fn_def_node = null,
11921188 .lib_name = null,
11931189 .align_expr = null,
......@@ -1242,18 +1238,19 @@ const Parser = struct {
12421238 }
12431239
12441240 fn createAttachFnProto(self: &Parser, list: &ArrayList(&AstNode), fn_token: &const Token,
1245 is_extern: Extern, cc: CallingConvention, visib_token: &const ?Token, is_inline: Inline) -> %&AstNodeFnProto
1241 extern_token: &const ?Token, cc_token: &const ?Token, visib_token: &const ?Token,
1242 inline_token: &const ?Token) -> %&AstNodeFnProto
12461243 {
1247 const node = %return self.createFnProto(fn_token, is_extern, cc, visib_token, is_inline);
1244 const node = %return self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token);
12481245 %defer self.allocator.destroy(node);
12491246 %return list.append(&node.base);
12501247 return node;
12511248 }
12521249
1253 fn createAttachVarDecl(self: &Parser, list: &ArrayList(&AstNode), visib_token: &const ?Token, mut: Mutability,
1254 is_comptime: Comptime, is_extern: Extern) -> %&AstNodeVarDecl
1250 fn createAttachVarDecl(self: &Parser, list: &ArrayList(&AstNode), visib_token: &const ?Token,
1251 mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) -> %&AstNodeVarDecl
12551252 {
1256 const node = %return self.createVarDecl(visib_token, mut, is_comptime, is_extern);
1253 const node = %return self.createVarDecl(visib_token, mut_token, comptime_token, extern_token);
12571254 %defer self.allocator.destroy(node);
12581255 %return list.append(&node.base);
12591256 return node;
......@@ -1376,8 +1373,8 @@ const Parser = struct {
13761373 else => unreachable,
13771374 };
13781375 }
1379 if (fn_proto.is_extern == Extern.Yes) {
1380 %return stream.print("extern ");
1376 if (fn_proto.extern_token) |extern_token| {
1377 %return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token));
13811378 }
13821379 %return stream.print("fn");
13831380
......@@ -1403,6 +1400,30 @@ const Parser = struct {
14031400 }
14041401 }
14051402 },
1403 AstNode.Id.VarDecl => {
1404 const var_decl = @fieldParentPtr(AstNodeVarDecl, "base", decl);
1405 if (var_decl.visib_token) |visib_token| {
1406 %return stream.print("{} ", self.tokenizer.getTokenSlice(visib_token));
1407 }
1408 if (var_decl.extern_token) |extern_token| {
1409 %return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token));
1410 if (var_decl.lib_name != null) {
1411 @panic("TODO");
1412 }
1413 }
1414 if (var_decl.comptime_token) |comptime_token| {
1415 %return stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token));
1416 }
1417 %return stream.print("{} ", self.tokenizer.getTokenSlice(var_decl.mut_token));
1418 %return stream.print("{}", self.tokenizer.getTokenSlice(var_decl.name_token));
1419
1420 %return stream.print(" = ");
1421
1422 %return stack.append(RenderState { .Text = ";\n" });
1423 if (var_decl.init_node) |init_node| {
1424 %return stack.append(RenderState { .Expression = init_node });
1425 }
1426 },
14061427 else => unreachable,
14071428 }
14081429 },
......@@ -1570,4 +1591,12 @@ test "zig fmt" {
15701591 \\extern fn puts(s: &const u8) -> c_int;
15711592 \\
15721593 );
1594
1595 testCanonical(
1596 \\const a = b;
1597 \\pub const a = b;
1598 \\var a = b;
1599 \\pub var a = b;
1600 \\
1601 );
15731602}