| ... | @@ -481,6 +481,7 @@ const NoAlias = enum { No, Yes }; | ... | @@ -481,6 +481,7 @@ const NoAlias = enum { No, Yes }; |
| 481 | const Extern = enum { No, Yes }; | 481 | const Extern = enum { No, Yes }; |
| 482 | const VarArgs = enum { No, Yes }; | 482 | const VarArgs = enum { No, Yes }; |
| 483 | const Mutability = enum { Const, Var }; | 483 | const Mutability = enum { Const, Var }; |
| | 484 | const Volatile = enum { No, Yes }; |
| 484 | | 485 | |
| 485 | const Inline = enum { | 486 | const 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 | }; |
| 515 | | 517 | |
| 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 | }; |
| 645 | | 648 | |
| | 649 | const 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 | |
| 646 | error ParseError; | 674 | error ParseError; |
| 647 | | 675 | |
| 648 | const Parser = struct { | 676 | const 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 | }, |
| 905 | | 935 | |
| 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 | }, |
| 910 | | 940 | |
| ... | @@ -919,6 +949,27 @@ const Parser = struct { | ... | @@ -919,6 +949,27 @@ const Parser = struct { |
| 919 | }, | 949 | }, |
| 920 | | 950 | |
| 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 | }, |
| 967 | | 1018 | |
| 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 | }, |
| 972 | | 1032 | |
| 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 | } |
| 1109 | | 1169 | |
| | 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); |