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 };
481481const Extern = enum { No, Yes };
482482const VarArgs = enum { No, Yes };
483483const Mutability = enum { Const, Var };
484const Volatile = enum { No, Yes };
484485
485486const Inline = enum {
486487 Auto,
......@@ -511,6 +512,7 @@ const AstNode = struct {
511512 Identifier,
512513 FnProto,
513514 ParamDecl,
515 AddrOfExpr,
514516 };
515517
516518 fn iterate(base: &AstNode, index: usize) -> ?&AstNode {
......@@ -520,6 +522,7 @@ const AstNode = struct {
520522 Id.Identifier => @fieldParentPtr(AstNodeIdentifier, "base", base).iterate(index),
521523 Id.FnProto => @fieldParentPtr(AstNodeFnProto, "base", base).iterate(index),
522524 Id.ParamDecl => @fieldParentPtr(AstNodeParamDecl, "base", base).iterate(index),
525 Id.AddrOfExpr => @fieldParentPtr(AstNodeAddrOfExpr, "base", base).iterate(index),
523526 };
524527 }
525528};
......@@ -643,6 +646,31 @@ const AstNodeParamDecl = struct {
643646 }
644647};
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
646674error ParseError;
647675
648676const Parser = struct {
......@@ -796,6 +824,7 @@ const Parser = struct {
796824 },
797825 Token.Id.Keyword_fn => {
798826 stack.append(State.TopLevel) %% unreachable;
827 %return stack.append(State { .ExpectToken = Token.Id.Semicolon });
799828 const fn_proto_node = %return self.createAttachFnProto(&root_node.decls, token,
800829 Extern.Yes, CallingConvention.Auto, visib, Inline.Auto);
801830 %return stack.append(State { .FnProto = fn_proto_node });
......@@ -806,6 +835,7 @@ const Parser = struct {
806835 },
807836 Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
808837 stack.append(State.TopLevel) %% unreachable;
838 %return stack.append(State { .ExpectToken = Token.Id.Semicolon });
809839 const cc = switch (token.id) {
810840 Token.Id.Keyword_coldcc => CallingConvention.Cold,
811841 Token.Id.Keyword_nakedcc => CallingConvention.Naked,
......@@ -904,7 +934,7 @@ const Parser = struct {
904934 },
905935
906936 State.AdditionExpression => |result_ptr| {
907 stack.append(State {.AdditionExpression = result_ptr}) %% unreachable;
937 stack.append(State {.MultiplyExpression = result_ptr}) %% unreachable;
908938 continue;
909939 },
910940
......@@ -919,6 +949,27 @@ const Parser = struct {
919949 },
920950
921951 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);
922973 stack.append(State { .SuffixOpExpression = result_ptr }) %% unreachable;
923974 continue;
924975 },
......@@ -966,8 +1017,17 @@ const Parser = struct {
9661017 },
9671018
9681019 State.FnProtoAlign => |fn_proto| {
969 @panic("TODO fn proto align");
970 //continue;
1020 const token = self.getNextToken();
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 }
9711031 },
9721032
9731033 State.ParamDecl => |fn_proto| {
......@@ -1107,6 +1167,30 @@ const Parser = struct {
11071167 return node;
11081168 }
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
11101194 fn createAttachParamDecl(self: &Parser, list: &ArrayList(&AstNode)) -> %&AstNodeParamDecl {
11111195 const node = %return self.createParamDecl();
11121196 %defer self.allocator.destroy(node);