authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-09 20:50:31-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-09 20:50:31-05:00
log62ead3a2ee3670e2eba8a8e8fe5b2cb32630d787
tree8a15b86876592ed1e1567ed5c7d075c4bce73f7f
parente9efa74333b4890b2598c96dc7df4761965e6819

parsing an extern fn declaration


1 files changed, 87 insertions(+), 3 deletions(-)

src-self-hosted/main.zig+87-3
...@@ -481,6 +481,7 @@ const NoAlias = enum { No, Yes };...@@ -481,6 +481,7 @@ const NoAlias = enum { No, Yes };
481const Extern = enum { No, Yes };481const Extern = enum { No, Yes };
482const VarArgs = enum { No, Yes };482const VarArgs = enum { No, Yes };
483const Mutability = enum { Const, Var };483const Mutability = enum { Const, Var };
484const Volatile = enum { No, Yes };
484485
485const Inline = enum {486const Inline = enum {
486 Auto,487 Auto,
...@@ -511,6 +512,7 @@ const AstNode = struct {...@@ -511,6 +512,7 @@ const AstNode = struct {
511 Identifier,512 Identifier,
512 FnProto,513 FnProto,
513 ParamDecl,514 ParamDecl,
515 AddrOfExpr,
514 };516 };
515517
516 fn iterate(base: &AstNode, index: usize) -> ?&AstNode {518 fn iterate(base: &AstNode, index: usize) -> ?&AstNode {
...@@ -520,6 +522,7 @@ const AstNode = struct {...@@ -520,6 +522,7 @@ const AstNode = struct {
520 Id.Identifier => @fieldParentPtr(AstNodeIdentifier, "base", base).iterate(index),522 Id.Identifier => @fieldParentPtr(AstNodeIdentifier, "base", base).iterate(index),
521 Id.FnProto => @fieldParentPtr(AstNodeFnProto, "base", base).iterate(index),523 Id.FnProto => @fieldParentPtr(AstNodeFnProto, "base", base).iterate(index),
522 Id.ParamDecl => @fieldParentPtr(AstNodeParamDecl, "base", base).iterate(index),524 Id.ParamDecl => @fieldParentPtr(AstNodeParamDecl, "base", base).iterate(index),
525 Id.AddrOfExpr => @fieldParentPtr(AstNodeAddrOfExpr, "base", base).iterate(index),
523 };526 };
524 }527 }
525};528};
...@@ -643,6 +646,31 @@ const AstNodeParamDecl = struct {...@@ -643,6 +646,31 @@ const AstNodeParamDecl = struct {
643 }646 }
644};647};
645648
649const AstNodeAddrOfExpr = struct {
650 base: AstNode,
651 align_expr: ?&AstNode,
652 op_token: Token,
653 bit_offset_start_token: ?Token,
654 bit_offset_end_token: ?Token,
655 const_token: ?Token,
656 volatile_token: ?Token,
657 op_expr: &AstNode,
658
659 fn iterate(self: &AstNodeAddrOfExpr, index: usize) -> ?&AstNode {
660 var i = index;
661
662 if (self.align_expr) |align_expr| {
663 if (i < 1) return align_expr;
664 i -= 1;
665 }
666
667 if (i < 1) return self.op_expr;
668 i -= 1;
669
670 return null;
671 }
672};
673
646error ParseError;674error ParseError;
647675
648const Parser = struct {676const Parser = struct {
...@@ -796,6 +824,7 @@ const Parser = struct {...@@ -796,6 +824,7 @@ const Parser = struct {
796 },824 },
797 Token.Id.Keyword_fn => {825 Token.Id.Keyword_fn => {
798 stack.append(State.TopLevel) %% unreachable;826 stack.append(State.TopLevel) %% unreachable;
827 %return stack.append(State { .ExpectToken = Token.Id.Semicolon });
799 const fn_proto_node = %return self.createAttachFnProto(&root_node.decls, token,828 const fn_proto_node = %return self.createAttachFnProto(&root_node.decls, token,
800 Extern.Yes, CallingConvention.Auto, visib, Inline.Auto);829 Extern.Yes, CallingConvention.Auto, visib, Inline.Auto);
801 %return stack.append(State { .FnProto = fn_proto_node });830 %return stack.append(State { .FnProto = fn_proto_node });
...@@ -806,6 +835,7 @@ const Parser = struct {...@@ -806,6 +835,7 @@ const Parser = struct {
806 },835 },
807 Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {836 Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
808 stack.append(State.TopLevel) %% unreachable;837 stack.append(State.TopLevel) %% unreachable;
838 %return stack.append(State { .ExpectToken = Token.Id.Semicolon });
809 const cc = switch (token.id) {839 const cc = switch (token.id) {
810 Token.Id.Keyword_coldcc => CallingConvention.Cold,840 Token.Id.Keyword_coldcc => CallingConvention.Cold,
811 Token.Id.Keyword_nakedcc => CallingConvention.Naked,841 Token.Id.Keyword_nakedcc => CallingConvention.Naked,
...@@ -904,7 +934,7 @@ const Parser = struct {...@@ -904,7 +934,7 @@ const Parser = struct {
904 },934 },
905935
906 State.AdditionExpression => |result_ptr| {936 State.AdditionExpression => |result_ptr| {
907 stack.append(State {.AdditionExpression = result_ptr}) %% unreachable;937 stack.append(State {.MultiplyExpression = result_ptr}) %% unreachable;
908 continue;938 continue;
909 },939 },
910940
...@@ -919,6 +949,27 @@ const Parser = struct {...@@ -919,6 +949,27 @@ const Parser = struct {
919 },949 },
920950
921 State.PrefixOpExpression => |result_ptr| {951 State.PrefixOpExpression => |result_ptr| {
952 const first_token = self.getNextToken();
953 if (first_token.id == Token.Id.Ampersand) {
954 const addr_of_expr = %return self.createAttachAddrOfExpr(result_ptr, first_token);
955 var token = self.getNextToken();
956 if (token.id == Token.Id.Keyword_align) {
957 @panic("TODO align");
958 }
959 if (token.id == Token.Id.Keyword_const) {
960 addr_of_expr.const_token = token;
961 token = self.getNextToken();
962 }
963 if (token.id == Token.Id.Keyword_volatile) {
964 addr_of_expr.volatile_token = token;
965 token = self.getNextToken();
966 }
967 self.putBackToken(token);
968 stack.append(State { .PrefixOpExpression = &addr_of_expr.op_expr }) %% unreachable;
969 continue;
970 }
971
972 self.putBackToken(first_token);
922 stack.append(State { .SuffixOpExpression = result_ptr }) %% unreachable;973 stack.append(State { .SuffixOpExpression = result_ptr }) %% unreachable;
923 continue;974 continue;
924 },975 },
...@@ -966,8 +1017,17 @@ const Parser = struct {...@@ -966,8 +1017,17 @@ const Parser = struct {
966 },1017 },
9671018
968 State.FnProtoAlign => |fn_proto| {1019 State.FnProtoAlign => |fn_proto| {
969 @panic("TODO fn proto align");1020 const token = self.getNextToken();
970 //continue;1021 if (token.id == Token.Id.Keyword_align) {
1022 @panic("TODO fn proto align");
1023 }
1024 if (token.id == Token.Id.Arrow) {
1025 stack.append(State { .TypeExpr = removeNullCast(&fn_proto.return_type) }) %% unreachable;
1026 continue;
1027 } else {
1028 self.putBackToken(token);
1029 continue;
1030 }
971 },1031 },
9721032
973 State.ParamDecl => |fn_proto| {1033 State.ParamDecl => |fn_proto| {
...@@ -1107,6 +1167,30 @@ const Parser = struct {...@@ -1107,6 +1167,30 @@ const Parser = struct {
1107 return node;1167 return node;
1108 }1168 }
11091169
1170 fn createAddrOfExpr(self: &Parser, op_token: &const Token) -> %&AstNodeAddrOfExpr {
1171 const node = %return self.allocator.create(AstNodeAddrOfExpr);
1172 %defer self.allocator.destroy(node);
1173
1174 *node = AstNodeAddrOfExpr {
1175 .base = AstNode {.id = AstNode.Id.AddrOfExpr},
1176 .align_expr = null,
1177 .op_token = *op_token,
1178 .bit_offset_start_token = null,
1179 .bit_offset_end_token = null,
1180 .const_token = null,
1181 .volatile_token = null,
1182 .op_expr = undefined,
1183 };
1184 return node;
1185 }
1186
1187 fn createAttachAddrOfExpr(self: &Parser, result_ptr: &&AstNode, op_token: &const Token) -> %&AstNodeAddrOfExpr {
1188 const node = %return self.createAddrOfExpr(op_token);
1189 %defer self.allocator.destroy(node);
1190 *result_ptr = &node.base;
1191 return node;
1192 }
1193
1110 fn createAttachParamDecl(self: &Parser, list: &ArrayList(&AstNode)) -> %&AstNodeParamDecl {1194 fn createAttachParamDecl(self: &Parser, list: &ArrayList(&AstNode)) -> %&AstNodeParamDecl {
1111 const node = %return self.createParamDecl();1195 const node = %return self.createParamDecl();
1112 %defer self.allocator.destroy(node);1196 %defer self.allocator.destroy(node);