| ... | @@ -134,6 +134,11 @@ pub const Parser = struct { | ... | @@ -134,6 +134,11 @@ pub const Parser = struct { |
| 134 | dest_ptr: DestPtr, | 134 | dest_ptr: DestPtr, |
| 135 | }; | 135 | }; |
| 136 | | 136 | |
| | 137 | const AsyncEndCtx = struct { |
| | 138 | dest_ptr: DestPtr, |
| | 139 | attribute: &ast.NodeAsyncAttribute, |
| | 140 | }; |
| | 141 | |
| 137 | const State = union(enum) { | 142 | const State = union(enum) { |
| 138 | TopLevel, | 143 | TopLevel, |
| 139 | TopLevelExtern: TopLevelDeclCtx, | 144 | TopLevelExtern: TopLevelDeclCtx, |
| ... | @@ -173,9 +178,11 @@ pub const Parser = struct { | ... | @@ -173,9 +178,11 @@ pub const Parser = struct { |
| 173 | FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer), | 178 | FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer), |
| 174 | FieldListCommaOrEnd: &ast.NodeContainerDecl, | 179 | FieldListCommaOrEnd: &ast.NodeContainerDecl, |
| 175 | SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase), | 180 | SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase), |
| 176 | ErrorPayload: &?&ast.NodeErrorPayload, | 181 | SuspendBody: &ast.NodeSuspend, |
| 177 | ValuePayload: &?&ast.NodeValuePayload, | 182 | AsyncEnd: AsyncEndCtx, |
| 178 | ValueIndexPayload: &?&ast.NodeValueIndexPayload, | 183 | Payload: &?&ast.NodePayload, |
| | 184 | PointerPayload: &?&ast.NodePointerPayload, |
| | 185 | PointerIndexPayload: &?&ast.NodePointerIndexPayload, |
| 179 | SwitchCaseCommaOrEnd: ListSave(&ast.NodeSwitchCase), | 186 | SwitchCaseCommaOrEnd: ListSave(&ast.NodeSwitchCase), |
| 180 | SwitchCaseItem: &ArrayList(&ast.Node), | 187 | SwitchCaseItem: &ArrayList(&ast.Node), |
| 181 | SwitchCaseItemCommaOrEnd: &ArrayList(&ast.Node), | 188 | SwitchCaseItemCommaOrEnd: &ArrayList(&ast.Node), |
| ... | @@ -399,6 +406,45 @@ pub const Parser = struct { | ... | @@ -399,6 +406,45 @@ pub const Parser = struct { |
| 399 | }); | 406 | }); |
| 400 | continue; | 407 | continue; |
| 401 | }, | 408 | }, |
| | 409 | Token.Id.Keyword_async => { |
| | 410 | // TODO shouldn't need this cast |
| | 411 | const fn_proto = try self.createAttachFnProto(arena, ctx.decls, undefined, |
| | 412 | ctx.extern_token, ctx.lib_name, (?Token)(null), (?Token)(null), (?Token)(null)); |
| | 413 | |
| | 414 | const async_node = try arena.create(ast.NodeAsyncAttribute); |
| | 415 | *async_node = ast.NodeAsyncAttribute { |
| | 416 | .base = self.initNode(ast.Node.Id.AsyncAttribute), |
| | 417 | .async_token = token, |
| | 418 | .allocator_type = null, |
| | 419 | .rangle_bracket = null, |
| | 420 | }; |
| | 421 | |
| | 422 | fn_proto.async_attr = async_node; |
| | 423 | stack.append(State { .FnDef = fn_proto }) catch unreachable; |
| | 424 | try stack.append(State { .FnProto = fn_proto }); |
| | 425 | try stack.append(State { |
| | 426 | .ExpectTokenSave = ExpectTokenSave { |
| | 427 | .id = Token.Id.Keyword_fn, |
| | 428 | .ptr = &fn_proto.fn_token, |
| | 429 | } |
| | 430 | }); |
| | 431 | |
| | 432 | const langle_bracket = self.getNextToken(); |
| | 433 | if (langle_bracket.id != Token.Id.AngleBracketLeft) { |
| | 434 | self.putBackToken(langle_bracket); |
| | 435 | continue; |
| | 436 | } |
| | 437 | |
| | 438 | async_node.rangle_bracket = Token(undefined); |
| | 439 | try stack.append(State { |
| | 440 | .ExpectTokenSave = ExpectTokenSave { |
| | 441 | .id = Token.Id.AngleBracketRight, |
| | 442 | .ptr = &??async_node.rangle_bracket, |
| | 443 | } |
| | 444 | }); |
| | 445 | try stack.append(State { .TypeExprBegin = DestPtr { .NullableField = &async_node.allocator_type } }); |
| | 446 | continue; |
| | 447 | }, |
| 402 | else => { | 448 | else => { |
| 403 | try self.parseError(&stack, token, "expected variable declaration or function, found {}", @tagName(token.id)); | 449 | try self.parseError(&stack, token, "expected variable declaration or function, found {}", @tagName(token.id)); |
| 404 | continue; | 450 | continue; |
| ... | @@ -711,13 +757,14 @@ pub const Parser = struct { | ... | @@ -711,13 +757,14 @@ pub const Parser = struct { |
| 711 | continue; | 757 | continue; |
| 712 | }, | 758 | }, |
| 713 | Token.Id.Keyword_cancel => { | 759 | Token.Id.Keyword_cancel => { |
| 714 | @panic("TODO: cancel"); | 760 | const cancel_node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp.Cancel); |
| | 761 | dest_ptr.store(&cancel_node.base); |
| | 762 | stack.append(State { .Expression = DestPtr { .Field = &cancel_node.rhs } }) catch unreachable; |
| 715 | }, | 763 | }, |
| 716 | Token.Id.Keyword_resume => { | 764 | Token.Id.Keyword_resume => { |
| 717 | @panic("TODO: resume"); | 765 | const resume_node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp.Resume); |
| 718 | }, | 766 | dest_ptr.store(&resume_node.base); |
| 719 | Token.Id.Keyword_await => { | 767 | stack.append(State { .Expression = DestPtr { .Field = &resume_node.rhs } }) catch unreachable; |
| 720 | @panic("TODO: await"); | | |
| 721 | }, | 768 | }, |
| 722 | else => { | 769 | else => { |
| 723 | self.putBackToken(token); | 770 | self.putBackToken(token); |
| ... | @@ -786,7 +833,7 @@ pub const Parser = struct { | ... | @@ -786,7 +833,7 @@ pub const Parser = struct { |
| 786 | | 833 | |
| 787 | stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable; | 834 | stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable; |
| 788 | try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }); | 835 | try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }); |
| 789 | try stack.append(State { .ErrorPayload = &node.op.Catch }); | 836 | try stack.append(State { .Payload = &node.op.Catch }); |
| 790 | continue; | 837 | continue; |
| 791 | }, | 838 | }, |
| 792 | Token.Id.QuestionMarkQuestionMark => { | 839 | Token.Id.QuestionMarkQuestionMark => { |
| ... | @@ -1113,6 +1160,9 @@ pub const Parser = struct { | ... | @@ -1113,6 +1160,9 @@ pub const Parser = struct { |
| 1113 | try stack.append(State { .AddrOfModifiers = &node.op.AddrOf }); | 1160 | try stack.append(State { .AddrOfModifiers = &node.op.AddrOf }); |
| 1114 | } | 1161 | } |
| 1115 | continue; | 1162 | continue; |
| | 1163 | //Token.Id.Keyword_await => { |
| | 1164 | // @panic("TODO: await"); |
| | 1165 | //}, |
| 1116 | } else { | 1166 | } else { |
| 1117 | self.putBackToken(token); | 1167 | self.putBackToken(token); |
| 1118 | stack.append(State { .SuffixOpExpressionBegin = dest_ptr }) catch unreachable; | 1168 | stack.append(State { .SuffixOpExpressionBegin = dest_ptr }) catch unreachable; |
| ... | @@ -1124,7 +1174,38 @@ pub const Parser = struct { | ... | @@ -1124,7 +1174,38 @@ pub const Parser = struct { |
| 1124 | const token = self.getNextToken(); | 1174 | const token = self.getNextToken(); |
| 1125 | switch (token.id) { | 1175 | switch (token.id) { |
| 1126 | Token.Id.Keyword_async => { | 1176 | Token.Id.Keyword_async => { |
| 1127 | @panic("TODO: Parse async"); | 1177 | const async_node = try arena.create(ast.NodeAsyncAttribute); |
| | 1178 | *async_node = ast.NodeAsyncAttribute { |
| | 1179 | .base = self.initNode(ast.Node.Id.AsyncAttribute), |
| | 1180 | .async_token = token, |
| | 1181 | .allocator_type = null, |
| | 1182 | .rangle_bracket = null, |
| | 1183 | }; |
| | 1184 | |
| | 1185 | stack.append(State { |
| | 1186 | .AsyncEnd = AsyncEndCtx { |
| | 1187 | .dest_ptr = dest_ptr, |
| | 1188 | .attribute = async_node, |
| | 1189 | } |
| | 1190 | }) catch unreachable; |
| | 1191 | try stack.append(State { .SuffixOpExpressionEnd = dest_ptr }); |
| | 1192 | try stack.append(State { .PrimaryExpression = dest_ptr }); |
| | 1193 | |
| | 1194 | const langle_bracket = self.getNextToken(); |
| | 1195 | if (langle_bracket.id != Token.Id.AngleBracketLeft) { |
| | 1196 | self.putBackToken(langle_bracket); |
| | 1197 | continue; |
| | 1198 | } |
| | 1199 | |
| | 1200 | async_node.rangle_bracket = Token(undefined); |
| | 1201 | try stack.append(State { |
| | 1202 | .ExpectTokenSave = ExpectTokenSave { |
| | 1203 | .id = Token.Id.AngleBracketRight, |
| | 1204 | .ptr = &??async_node.rangle_bracket, |
| | 1205 | } |
| | 1206 | }); |
| | 1207 | try stack.append(State { .TypeExprBegin = DestPtr { .NullableField = &async_node.allocator_type } }); |
| | 1208 | continue; |
| 1128 | }, | 1209 | }, |
| 1129 | else => { | 1210 | else => { |
| 1130 | self.putBackToken(token); | 1211 | self.putBackToken(token); |
| ... | @@ -1142,8 +1223,7 @@ pub const Parser = struct { | ... | @@ -1142,8 +1223,7 @@ pub const Parser = struct { |
| 1142 | const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp { | 1223 | const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp { |
| 1143 | .Call = ast.NodeSuffixOp.CallInfo { | 1224 | .Call = ast.NodeSuffixOp.CallInfo { |
| 1144 | .params = ArrayList(&ast.Node).init(arena), | 1225 | .params = ArrayList(&ast.Node).init(arena), |
| 1145 | .is_async = false, // TODO: ASYNC | 1226 | .async_attr = null, |
| 1146 | .allocator = null, | | |
| 1147 | } | 1227 | } |
| 1148 | }); | 1228 | }); |
| 1149 | node.lhs = dest_ptr.get(); | 1229 | node.lhs = dest_ptr.get(); |
| ... | @@ -1257,6 +1337,19 @@ pub const Parser = struct { | ... | @@ -1257,6 +1337,19 @@ pub const Parser = struct { |
| 1257 | dest_ptr.store(&node.base); | 1337 | dest_ptr.store(&node.base); |
| 1258 | continue; | 1338 | continue; |
| 1259 | }, | 1339 | }, |
| | 1340 | Token.Id.Keyword_suspend => { |
| | 1341 | const node = try arena.create(ast.NodeSuspend); |
| | 1342 | *node = ast.NodeSuspend { |
| | 1343 | .base = self.initNode(ast.Node.Id.Suspend), |
| | 1344 | .suspend_token = token, |
| | 1345 | .payload = null, |
| | 1346 | .body = null, |
| | 1347 | }; |
| | 1348 | dest_ptr.store(&node.base); |
| | 1349 | stack.append(State { .SuspendBody = node }) catch unreachable; |
| | 1350 | try stack.append(State { .Payload = &node.payload }); |
| | 1351 | continue; |
| | 1352 | }, |
| 1260 | Token.Id.MultilineStringLiteralLine => { | 1353 | Token.Id.MultilineStringLiteralLine => { |
| 1261 | const node = try arena.create(ast.NodeMultilineStringLiteral); | 1354 | const node = try arena.create(ast.NodeMultilineStringLiteral); |
| 1262 | *node = ast.NodeMultilineStringLiteral { | 1355 | *node = ast.NodeMultilineStringLiteral { |
| ... | @@ -1477,17 +1570,12 @@ pub const Parser = struct { | ... | @@ -1477,17 +1570,12 @@ pub const Parser = struct { |
| 1477 | continue; | 1570 | continue; |
| 1478 | }, | 1571 | }, |
| 1479 | Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => { | 1572 | Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => { |
| | 1573 | const fn_token = (try self.eatToken(&stack, Token.Id.Keyword_fn)) ?? continue; |
| 1480 | // TODO shouldn't need this cast | 1574 | // TODO shouldn't need this cast |
| 1481 | const fn_proto = try self.createFnProto(arena, undefined, | 1575 | const fn_proto = try self.createFnProto(arena, fn_token, |
| 1482 | (?Token)(null), (?&ast.Node)(null), (?Token)(token), (?Token)(null), (?Token)(null)); | 1576 | (?Token)(null), (?&ast.Node)(null), (?Token)(token), (?Token)(null), (?Token)(null)); |
| 1483 | dest_ptr.store(&fn_proto.base); | 1577 | dest_ptr.store(&fn_proto.base); |
| 1484 | stack.append(State { .FnProto = fn_proto }) catch unreachable; | 1578 | stack.append(State { .FnProto = fn_proto }) catch unreachable; |
| 1485 | try stack.append(State { | | |
| 1486 | .ExpectTokenSave = ExpectTokenSave { | | |
| 1487 | .id = Token.Id.Keyword_fn, | | |
| 1488 | .ptr = &fn_proto.fn_token, | | |
| 1489 | } | | |
| 1490 | }); | | |
| 1491 | continue; | 1579 | continue; |
| 1492 | }, | 1580 | }, |
| 1493 | Token.Id.Keyword_asm => { | 1581 | Token.Id.Keyword_asm => { |
| ... | @@ -1544,7 +1632,7 @@ pub const Parser = struct { | ... | @@ -1544,7 +1632,7 @@ pub const Parser = struct { |
| 1544 | | 1632 | |
| 1545 | stack.append(State { .Else = &node.@"else" }) catch unreachable; | 1633 | stack.append(State { .Else = &node.@"else" }) catch unreachable; |
| 1546 | try stack.append(State { .Expression = DestPtr { .Field = &node.body } }); | 1634 | try stack.append(State { .Expression = DestPtr { .Field = &node.body } }); |
| 1547 | try stack.append(State { .ValuePayload = &node.payload }); | 1635 | try stack.append(State { .PointerPayload = &node.payload }); |
| 1548 | try stack.append(State { .ExpectToken = Token.Id.RParen }); | 1636 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 1549 | try stack.append(State { .Expression = DestPtr { .Field = &node.condition } }); | 1637 | try stack.append(State { .Expression = DestPtr { .Field = &node.condition } }); |
| 1550 | try stack.append(State { .ExpectToken = Token.Id.LParen }); | 1638 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| ... | @@ -1816,7 +1904,7 @@ pub const Parser = struct { | ... | @@ -1816,7 +1904,7 @@ pub const Parser = struct { |
| 1816 | try list_state.list.append(node); | 1904 | try list_state.list.append(node); |
| 1817 | stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable; | 1905 | stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable; |
| 1818 | try stack.append(State { .Expression = DestPtr{ .Field = &node.expr } }); | 1906 | try stack.append(State { .Expression = DestPtr{ .Field = &node.expr } }); |
| 1819 | try stack.append(State { .ValuePayload = &node.payload }); | 1907 | try stack.append(State { .PointerPayload = &node.payload }); |
| 1820 | | 1908 | |
| 1821 | const maybe_else = self.getNextToken(); | 1909 | const maybe_else = self.getNextToken(); |
| 1822 | if (maybe_else.id == Token.Id.Keyword_else) { | 1910 | if (maybe_else.id == Token.Id.Keyword_else) { |
| ... | @@ -1883,7 +1971,7 @@ pub const Parser = struct { | ... | @@ -1883,7 +1971,7 @@ pub const Parser = struct { |
| 1883 | *dest = node; | 1971 | *dest = node; |
| 1884 | | 1972 | |
| 1885 | stack.append(State { .Expression = DestPtr { .Field = &node.body } }) catch unreachable; | 1973 | stack.append(State { .Expression = DestPtr { .Field = &node.body } }) catch unreachable; |
| 1886 | try stack.append(State { .ErrorPayload = &node.payload }); | 1974 | try stack.append(State { .Payload = &node.payload }); |
| 1887 | }, | 1975 | }, |
| 1888 | | 1976 | |
| 1889 | State.WhileContinueExpr => |dest| { | 1977 | State.WhileContinueExpr => |dest| { |
| ... | @@ -1898,7 +1986,41 @@ pub const Parser = struct { | ... | @@ -1898,7 +1986,41 @@ pub const Parser = struct { |
| 1898 | try stack.append(State { .AssignmentExpressionBegin = DestPtr { .NullableField = dest } }); | 1986 | try stack.append(State { .AssignmentExpressionBegin = DestPtr { .NullableField = dest } }); |
| 1899 | }, | 1987 | }, |
| 1900 | | 1988 | |
| 1901 | State.ErrorPayload => |dest| { | 1989 | State.SuspendBody => |suspend_node| { |
| | 1990 | if (suspend_node.payload != null) { |
| | 1991 | try stack.append(State { .AssignmentExpressionBegin = DestPtr { .NullableField = &suspend_node.body } }); |
| | 1992 | } |
| | 1993 | continue; |
| | 1994 | }, |
| | 1995 | |
| | 1996 | State.AsyncEnd => |ctx| { |
| | 1997 | const node = ctx.dest_ptr.get(); |
| | 1998 | |
| | 1999 | switch (node.id) { |
| | 2000 | ast.Node.Id.FnProto => { |
| | 2001 | const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", node); |
| | 2002 | fn_proto.async_attr = ctx.attribute; |
| | 2003 | }, |
| | 2004 | ast.Node.Id.SuffixOp => { |
| | 2005 | const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", node); |
| | 2006 | if (suffix_op.op == ast.NodeSuffixOp.SuffixOp.Call) { |
| | 2007 | suffix_op.op.Call.async_attr = ctx.attribute; |
| | 2008 | continue; |
| | 2009 | } |
| | 2010 | |
| | 2011 | try self.parseError(&stack, node.firstToken(), "expected call or fn proto, found {}.", |
| | 2012 | @tagName(suffix_op.op)); |
| | 2013 | continue; |
| | 2014 | }, |
| | 2015 | else => { |
| | 2016 | try self.parseError(&stack, node.firstToken(), "expected call or fn proto, found {}.", |
| | 2017 | @tagName(node.id)); |
| | 2018 | continue; |
| | 2019 | } |
| | 2020 | } |
| | 2021 | }, |
| | 2022 | |
| | 2023 | State.Payload => |dest| { |
| 1902 | const lpipe = self.getNextToken(); | 2024 | const lpipe = self.getNextToken(); |
| 1903 | if (lpipe.id != Token.Id.Pipe) { | 2025 | if (lpipe.id != Token.Id.Pipe) { |
| 1904 | self.putBackToken(lpipe); | 2026 | self.putBackToken(lpipe); |
| ... | @@ -1907,9 +2029,9 @@ pub const Parser = struct { | ... | @@ -1907,9 +2029,9 @@ pub const Parser = struct { |
| 1907 | | 2029 | |
| 1908 | const error_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue; | 2030 | const error_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue; |
| 1909 | const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue; | 2031 | const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue; |
| 1910 | const node = try arena.create(ast.NodeErrorPayload); | 2032 | const node = try arena.create(ast.NodePayload); |
| 1911 | *node = ast.NodeErrorPayload { | 2033 | *node = ast.NodePayload { |
| 1912 | .base = self.initNode(ast.Node.Id.ErrorPayload), | 2034 | .base = self.initNode(ast.Node.Id.Payload), |
| 1913 | .lpipe = lpipe, | 2035 | .lpipe = lpipe, |
| 1914 | .error_symbol = try self.createIdentifier(arena, error_symbol), | 2036 | .error_symbol = try self.createIdentifier(arena, error_symbol), |
| 1915 | .rpipe = rpipe | 2037 | .rpipe = rpipe |
| ... | @@ -1917,7 +2039,7 @@ pub const Parser = struct { | ... | @@ -1917,7 +2039,7 @@ pub const Parser = struct { |
| 1917 | *dest = node; | 2039 | *dest = node; |
| 1918 | }, | 2040 | }, |
| 1919 | | 2041 | |
| 1920 | State.ValuePayload => |dest| { | 2042 | State.PointerPayload => |dest| { |
| 1921 | const lpipe = self.getNextToken(); | 2043 | const lpipe = self.getNextToken(); |
| 1922 | if (lpipe.id != Token.Id.Pipe) { | 2044 | if (lpipe.id != Token.Id.Pipe) { |
| 1923 | self.putBackToken(lpipe); | 2045 | self.putBackToken(lpipe); |
| ... | @@ -1936,9 +2058,9 @@ pub const Parser = struct { | ... | @@ -1936,9 +2058,9 @@ pub const Parser = struct { |
| 1936 | | 2058 | |
| 1937 | const value_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue; | 2059 | const value_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue; |
| 1938 | const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue; | 2060 | const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue; |
| 1939 | const node = try arena.create(ast.NodeValuePayload); | 2061 | const node = try arena.create(ast.NodePointerPayload); |
| 1940 | *node = ast.NodeValuePayload { | 2062 | *node = ast.NodePointerPayload { |
| 1941 | .base = self.initNode(ast.Node.Id.ValuePayload), | 2063 | .base = self.initNode(ast.Node.Id.PointerPayload), |
| 1942 | .lpipe = lpipe, | 2064 | .lpipe = lpipe, |
| 1943 | .is_ptr = is_ptr, | 2065 | .is_ptr = is_ptr, |
| 1944 | .value_symbol = try self.createIdentifier(arena, value_symbol), | 2066 | .value_symbol = try self.createIdentifier(arena, value_symbol), |
| ... | @@ -1947,7 +2069,7 @@ pub const Parser = struct { | ... | @@ -1947,7 +2069,7 @@ pub const Parser = struct { |
| 1947 | *dest = node; | 2069 | *dest = node; |
| 1948 | }, | 2070 | }, |
| 1949 | | 2071 | |
| 1950 | State.ValueIndexPayload => |dest| { | 2072 | State.PointerIndexPayload => |dest| { |
| 1951 | const lpipe = self.getNextToken(); | 2073 | const lpipe = self.getNextToken(); |
| 1952 | if (lpipe.id != Token.Id.Pipe) { | 2074 | if (lpipe.id != Token.Id.Pipe) { |
| 1953 | self.putBackToken(lpipe); | 2075 | self.putBackToken(lpipe); |
| ... | @@ -1977,9 +2099,9 @@ pub const Parser = struct { | ... | @@ -1977,9 +2099,9 @@ pub const Parser = struct { |
| 1977 | }; | 2099 | }; |
| 1978 | | 2100 | |
| 1979 | const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue; | 2101 | const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue; |
| 1980 | const node = try arena.create(ast.NodeValueIndexPayload); | 2102 | const node = try arena.create(ast.NodePointerIndexPayload); |
| 1981 | *node = ast.NodeValueIndexPayload { | 2103 | *node = ast.NodePointerIndexPayload { |
| 1982 | .base = self.initNode(ast.Node.Id.ValueIndexPayload), | 2104 | .base = self.initNode(ast.Node.Id.PointerIndexPayload), |
| 1983 | .lpipe = lpipe, | 2105 | .lpipe = lpipe, |
| 1984 | .is_ptr = is_ptr, | 2106 | .is_ptr = is_ptr, |
| 1985 | .value_symbol = try self.createIdentifier(arena, value_symbol), | 2107 | .value_symbol = try self.createIdentifier(arena, value_symbol), |
| ... | @@ -2249,7 +2371,7 @@ pub const Parser = struct { | ... | @@ -2249,7 +2371,7 @@ pub const Parser = struct { |
| 2249 | stack.append(State { .Else = &node.@"else" }) catch unreachable; | 2371 | stack.append(State { .Else = &node.@"else" }) catch unreachable; |
| 2250 | try stack.append(State { .Expression = DestPtr { .Field = &node.body } }); | 2372 | try stack.append(State { .Expression = DestPtr { .Field = &node.body } }); |
| 2251 | try stack.append(State { .WhileContinueExpr = &node.continue_expr }); | 2373 | try stack.append(State { .WhileContinueExpr = &node.continue_expr }); |
| 2252 | try stack.append(State { .ValuePayload = &node.payload }); | 2374 | try stack.append(State { .PointerPayload = &node.payload }); |
| 2253 | try stack.append(State { .ExpectToken = Token.Id.RParen }); | 2375 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 2254 | try stack.append(State { .Expression = DestPtr { .Field = &node.condition } }); | 2376 | try stack.append(State { .Expression = DestPtr { .Field = &node.condition } }); |
| 2255 | try stack.append(State { .ExpectToken = Token.Id.LParen }); | 2377 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| ... | @@ -2271,7 +2393,7 @@ pub const Parser = struct { | ... | @@ -2271,7 +2393,7 @@ pub const Parser = struct { |
| 2271 | | 2393 | |
| 2272 | stack.append(State { .Else = &node.@"else" }) catch unreachable; | 2394 | stack.append(State { .Else = &node.@"else" }) catch unreachable; |
| 2273 | try stack.append(State { .Expression = DestPtr { .Field = &node.body } }); | 2395 | try stack.append(State { .Expression = DestPtr { .Field = &node.body } }); |
| 2274 | try stack.append(State { .ValueIndexPayload = &node.payload }); | 2396 | try stack.append(State { .PointerIndexPayload = &node.payload }); |
| 2275 | try stack.append(State { .ExpectToken = Token.Id.RParen }); | 2397 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 2276 | try stack.append(State { .Expression = DestPtr { .Field = &node.array_expr } }); | 2398 | try stack.append(State { .Expression = DestPtr { .Field = &node.array_expr } }); |
| 2277 | try stack.append(State { .ExpectToken = Token.Id.LParen }); | 2399 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| ... | @@ -2374,9 +2496,9 @@ pub const Parser = struct { | ... | @@ -2374,9 +2496,9 @@ pub const Parser = struct { |
| 2374 | ast.Node.Id.EnumTag, | 2496 | ast.Node.Id.EnumTag, |
| 2375 | ast.Node.Id.ParamDecl, | 2497 | ast.Node.Id.ParamDecl, |
| 2376 | ast.Node.Id.Block, | 2498 | ast.Node.Id.Block, |
| 2377 | ast.Node.Id.ErrorPayload, | 2499 | ast.Node.Id.Payload, |
| 2378 | ast.Node.Id.ValuePayload, | 2500 | ast.Node.Id.PointerPayload, |
| 2379 | ast.Node.Id.ValueIndexPayload, | 2501 | ast.Node.Id.PointerIndexPayload, |
| 2380 | ast.Node.Id.Switch, | 2502 | ast.Node.Id.Switch, |
| 2381 | ast.Node.Id.SwitchCase, | 2503 | ast.Node.Id.SwitchCase, |
| 2382 | ast.Node.Id.SwitchElse, | 2504 | ast.Node.Id.SwitchElse, |
| ... | @@ -2422,6 +2544,15 @@ pub const Parser = struct { | ... | @@ -2422,6 +2544,15 @@ pub const Parser = struct { |
| 2422 | const comptime_node = @fieldParentPtr(ast.NodeComptime, "base", n); | 2544 | const comptime_node = @fieldParentPtr(ast.NodeComptime, "base", n); |
| 2423 | n = comptime_node.expr; | 2545 | n = comptime_node.expr; |
| 2424 | }, | 2546 | }, |
| | 2547 | ast.Node.Id.Suspend => { |
| | 2548 | const suspend_node = @fieldParentPtr(ast.NodeSuspend, "base", n); |
| | 2549 | if (suspend_node.body) |body| { |
| | 2550 | n = body; |
| | 2551 | continue; |
| | 2552 | } |
| | 2553 | |
| | 2554 | return true; |
| | 2555 | }, |
| 2425 | else => return true, | 2556 | else => return true, |
| 2426 | } | 2557 | } |
| 2427 | } | 2558 | } |
| ... | @@ -2540,6 +2671,7 @@ pub const Parser = struct { | ... | @@ -2540,6 +2671,7 @@ pub const Parser = struct { |
| 2540 | }, | 2671 | }, |
| 2541 | Token.Id.QuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.MaybeType), | 2672 | Token.Id.QuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.MaybeType), |
| 2542 | Token.Id.QuestionMarkQuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.UnwrapMaybe), | 2673 | Token.Id.QuestionMarkQuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.UnwrapMaybe), |
| | 2674 | Token.Id.Keyword_await => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.Await), |
| 2543 | else => null, | 2675 | else => null, |
| 2544 | }; | 2676 | }; |
| 2545 | } | 2677 | } |
| ... | @@ -2628,6 +2760,7 @@ pub const Parser = struct { | ... | @@ -2628,6 +2760,7 @@ pub const Parser = struct { |
| 2628 | .extern_token = *extern_token, | 2760 | .extern_token = *extern_token, |
| 2629 | .inline_token = *inline_token, | 2761 | .inline_token = *inline_token, |
| 2630 | .cc_token = *cc_token, | 2762 | .cc_token = *cc_token, |
| | 2763 | .async_attr = null, |
| 2631 | .body_node = null, | 2764 | .body_node = null, |
| 2632 | .lib_name = lib_name, | 2765 | .lib_name = lib_name, |
| 2633 | .align_expr = null, | 2766 | .align_expr = null, |
| ... | @@ -3105,6 +3238,30 @@ pub const Parser = struct { | ... | @@ -3105,6 +3238,30 @@ pub const Parser = struct { |
| 3105 | try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_node.comptime_token)); | 3238 | try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_node.comptime_token)); |
| 3106 | try stack.append(RenderState { .Expression = comptime_node.expr }); | 3239 | try stack.append(RenderState { .Expression = comptime_node.expr }); |
| 3107 | }, | 3240 | }, |
| | 3241 | ast.Node.Id.AsyncAttribute => { |
| | 3242 | const async_attr = @fieldParentPtr(ast.NodeAsyncAttribute, "base", base); |
| | 3243 | try stream.print("{}", self.tokenizer.getTokenSlice(async_attr.async_token)); |
| | 3244 | |
| | 3245 | if (async_attr.allocator_type) |allocator_type| { |
| | 3246 | try stack.append(RenderState { .Text = ">" }); |
| | 3247 | try stack.append(RenderState { .Expression = allocator_type }); |
| | 3248 | try stack.append(RenderState { .Text = "<" }); |
| | 3249 | } |
| | 3250 | }, |
| | 3251 | ast.Node.Id.Suspend => { |
| | 3252 | const suspend_node = @fieldParentPtr(ast.NodeSuspend, "base", base); |
| | 3253 | try stream.print("{}", self.tokenizer.getTokenSlice(suspend_node.suspend_token)); |
| | 3254 | |
| | 3255 | if (suspend_node.body) |body| { |
| | 3256 | try stack.append(RenderState { .Expression = body }); |
| | 3257 | try stack.append(RenderState { .Text = " " }); |
| | 3258 | } |
| | 3259 | |
| | 3260 | if (suspend_node.payload) |payload| { |
| | 3261 | try stack.append(RenderState { .Expression = &payload.base }); |
| | 3262 | try stack.append(RenderState { .Text = " " }); |
| | 3263 | } |
| | 3264 | }, |
| 3108 | ast.Node.Id.InfixOp => { | 3265 | ast.Node.Id.InfixOp => { |
| 3109 | const prefix_op_node = @fieldParentPtr(ast.NodeInfixOp, "base", base); | 3266 | const prefix_op_node = @fieldParentPtr(ast.NodeInfixOp, "base", base); |
| 3110 | try stack.append(RenderState { .Expression = prefix_op_node.rhs }); | 3267 | try stack.append(RenderState { .Expression = prefix_op_node.rhs }); |
| ... | @@ -3211,6 +3368,9 @@ pub const Parser = struct { | ... | @@ -3211,6 +3368,9 @@ pub const Parser = struct { |
| 3211 | ast.NodePrefixOp.PrefixOp.Try => try stream.write("try "), | 3368 | ast.NodePrefixOp.PrefixOp.Try => try stream.write("try "), |
| 3212 | ast.NodePrefixOp.PrefixOp.UnwrapMaybe => try stream.write("??"), | 3369 | ast.NodePrefixOp.PrefixOp.UnwrapMaybe => try stream.write("??"), |
| 3213 | ast.NodePrefixOp.PrefixOp.MaybeType => try stream.write("?"), | 3370 | ast.NodePrefixOp.PrefixOp.MaybeType => try stream.write("?"), |
| | 3371 | ast.NodePrefixOp.PrefixOp.Await => try stream.write("await "), |
| | 3372 | ast.NodePrefixOp.PrefixOp.Cancel => try stream.write("cancel "), |
| | 3373 | ast.NodePrefixOp.PrefixOp.Resume => try stream.write("resume "), |
| 3214 | } | 3374 | } |
| 3215 | }, | 3375 | }, |
| 3216 | ast.Node.Id.SuffixOp => { | 3376 | ast.Node.Id.SuffixOp => { |
| ... | @@ -3229,11 +3389,18 @@ pub const Parser = struct { | ... | @@ -3229,11 +3389,18 @@ pub const Parser = struct { |
| 3229 | } | 3389 | } |
| 3230 | } | 3390 | } |
| 3231 | try stack.append(RenderState { .Text = "("}); | 3391 | try stack.append(RenderState { .Text = "("}); |
| | 3392 | try stack.append(RenderState { .Expression = suffix_op.lhs }); |
| | 3393 | |
| | 3394 | if (call_info.async_attr) |async_attr| { |
| | 3395 | try stack.append(RenderState { .Text = " "}); |
| | 3396 | try stack.append(RenderState { .Expression = &async_attr.base }); |
| | 3397 | } |
| 3232 | }, | 3398 | }, |
| 3233 | ast.NodeSuffixOp.SuffixOp.ArrayAccess => |index_expr| { | 3399 | ast.NodeSuffixOp.SuffixOp.ArrayAccess => |index_expr| { |
| 3234 | try stack.append(RenderState { .Text = "]"}); | 3400 | try stack.append(RenderState { .Text = "]"}); |
| 3235 | try stack.append(RenderState { .Expression = index_expr}); | 3401 | try stack.append(RenderState { .Expression = index_expr}); |
| 3236 | try stack.append(RenderState { .Text = "["}); | 3402 | try stack.append(RenderState { .Text = "["}); |
| | 3403 | try stack.append(RenderState { .Expression = suffix_op.lhs }); |
| 3237 | }, | 3404 | }, |
| 3238 | ast.NodeSuffixOp.SuffixOp.Slice => |range| { | 3405 | ast.NodeSuffixOp.SuffixOp.Slice => |range| { |
| 3239 | try stack.append(RenderState { .Text = "]"}); | 3406 | try stack.append(RenderState { .Text = "]"}); |
| ... | @@ -3243,6 +3410,7 @@ pub const Parser = struct { | ... | @@ -3243,6 +3410,7 @@ pub const Parser = struct { |
| 3243 | try stack.append(RenderState { .Text = ".."}); | 3410 | try stack.append(RenderState { .Text = ".."}); |
| 3244 | try stack.append(RenderState { .Expression = range.start}); | 3411 | try stack.append(RenderState { .Expression = range.start}); |
| 3245 | try stack.append(RenderState { .Text = "["}); | 3412 | try stack.append(RenderState { .Text = "["}); |
| | 3413 | try stack.append(RenderState { .Expression = suffix_op.lhs }); |
| 3246 | }, | 3414 | }, |
| 3247 | ast.NodeSuffixOp.SuffixOp.StructInitializer => |field_inits| { | 3415 | ast.NodeSuffixOp.SuffixOp.StructInitializer => |field_inits| { |
| 3248 | try stack.append(RenderState { .Text = " }"}); | 3416 | try stack.append(RenderState { .Text = " }"}); |
| ... | @@ -3257,6 +3425,7 @@ pub const Parser = struct { | ... | @@ -3257,6 +3425,7 @@ pub const Parser = struct { |
| 3257 | } | 3425 | } |
| 3258 | } | 3426 | } |
| 3259 | try stack.append(RenderState { .Text = "{"}); | 3427 | try stack.append(RenderState { .Text = "{"}); |
| | 3428 | try stack.append(RenderState { .Expression = suffix_op.lhs }); |
| 3260 | }, | 3429 | }, |
| 3261 | ast.NodeSuffixOp.SuffixOp.ArrayInitializer => |exprs| { | 3430 | ast.NodeSuffixOp.SuffixOp.ArrayInitializer => |exprs| { |
| 3262 | try stack.append(RenderState { .Text = " }"}); | 3431 | try stack.append(RenderState { .Text = " }"}); |
| ... | @@ -3271,10 +3440,9 @@ pub const Parser = struct { | ... | @@ -3271,10 +3440,9 @@ pub const Parser = struct { |
| 3271 | } | 3440 | } |
| 3272 | } | 3441 | } |
| 3273 | try stack.append(RenderState { .Text = "{"}); | 3442 | try stack.append(RenderState { .Text = "{"}); |
| | 3443 | try stack.append(RenderState { .Expression = suffix_op.lhs }); |
| 3274 | }, | 3444 | }, |
| 3275 | } | 3445 | } |
| 3276 | | | |
| 3277 | try stack.append(RenderState { .Expression = suffix_op.lhs }); | | |
| 3278 | }, | 3446 | }, |
| 3279 | ast.Node.Id.ControlFlowExpression => { | 3447 | ast.Node.Id.ControlFlowExpression => { |
| 3280 | const flow_expr = @fieldParentPtr(ast.NodeControlFlowExpression, "base", base); | 3448 | const flow_expr = @fieldParentPtr(ast.NodeControlFlowExpression, "base", base); |
| ... | @@ -3302,14 +3470,14 @@ pub const Parser = struct { | ... | @@ -3302,14 +3470,14 @@ pub const Parser = struct { |
| 3302 | try stack.append(RenderState { .Expression = rhs }); | 3470 | try stack.append(RenderState { .Expression = rhs }); |
| 3303 | } | 3471 | } |
| 3304 | }, | 3472 | }, |
| 3305 | ast.Node.Id.ErrorPayload => { | 3473 | ast.Node.Id.Payload => { |
| 3306 | const payload = @fieldParentPtr(ast.NodeErrorPayload, "base", base); | 3474 | const payload = @fieldParentPtr(ast.NodePayload, "base", base); |
| 3307 | try stack.append(RenderState { .Text = "|"}); | 3475 | try stack.append(RenderState { .Text = "|"}); |
| 3308 | try stack.append(RenderState { .Expression = &payload.error_symbol.base }); | 3476 | try stack.append(RenderState { .Expression = &payload.error_symbol.base }); |
| 3309 | try stack.append(RenderState { .Text = "|"}); | 3477 | try stack.append(RenderState { .Text = "|"}); |
| 3310 | }, | 3478 | }, |
| 3311 | ast.Node.Id.ValuePayload => { | 3479 | ast.Node.Id.PointerPayload => { |
| 3312 | const payload = @fieldParentPtr(ast.NodeValuePayload, "base", base); | 3480 | const payload = @fieldParentPtr(ast.NodePointerPayload, "base", base); |
| 3313 | try stack.append(RenderState { .Text = "|"}); | 3481 | try stack.append(RenderState { .Text = "|"}); |
| 3314 | try stack.append(RenderState { .Expression = &payload.value_symbol.base }); | 3482 | try stack.append(RenderState { .Expression = &payload.value_symbol.base }); |
| 3315 | | 3483 | |
| ... | @@ -3319,8 +3487,8 @@ pub const Parser = struct { | ... | @@ -3319,8 +3487,8 @@ pub const Parser = struct { |
| 3319 | | 3487 | |
| 3320 | try stack.append(RenderState { .Text = "|"}); | 3488 | try stack.append(RenderState { .Text = "|"}); |
| 3321 | }, | 3489 | }, |
| 3322 | ast.Node.Id.ValueIndexPayload => { | 3490 | ast.Node.Id.PointerIndexPayload => { |
| 3323 | const payload = @fieldParentPtr(ast.NodeValueIndexPayload, "base", base); | 3491 | const payload = @fieldParentPtr(ast.NodePointerIndexPayload, "base", base); |
| 3324 | try stack.append(RenderState { .Text = "|"}); | 3492 | try stack.append(RenderState { .Text = "|"}); |
| 3325 | | 3493 | |
| 3326 | if (payload.index_symbol) |index_symbol| { | 3494 | if (payload.index_symbol) |index_symbol| { |
| ... | @@ -3553,6 +3721,11 @@ pub const Parser = struct { | ... | @@ -3553,6 +3721,11 @@ pub const Parser = struct { |
| 3553 | | 3721 | |
| 3554 | try stack.append(RenderState { .Text = "fn" }); | 3722 | try stack.append(RenderState { .Text = "fn" }); |
| 3555 | | 3723 | |
| | 3724 | if (fn_proto.async_attr) |async_attr| { |
| | 3725 | try stack.append(RenderState { .Text = " " }); |
| | 3726 | try stack.append(RenderState { .Expression = &async_attr.base }); |
| | 3727 | } |
| | 3728 | |
| 3556 | if (fn_proto.cc_token) |cc_token| { | 3729 | if (fn_proto.cc_token) |cc_token| { |
| 3557 | try stack.append(RenderState { .Text = " " }); | 3730 | try stack.append(RenderState { .Text = " " }); |
| 3558 | try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(cc_token) }); | 3731 | try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(cc_token) }); |
| ... | @@ -4789,8 +4962,7 @@ test "zig fmt: coroutines" { | ... | @@ -4789,8 +4962,7 @@ test "zig fmt: coroutines" { |
| 4789 | \\ x += 1; | 4962 | \\ x += 1; |
| 4790 | \\ suspend; | 4963 | \\ suspend; |
| 4791 | \\ x += 1; | 4964 | \\ x += 1; |
| 4792 | \\ suspend |p| { | 4965 | \\ suspend |p| {} |
| 4793 | \\ } | | |
| 4794 | \\ const p = async simpleAsyncFn() catch unreachable; | 4966 | \\ const p = async simpleAsyncFn() catch unreachable; |
| 4795 | \\ await p; | 4967 | \\ await p; |
| 4796 | \\} | 4968 | \\} |
| ... | @@ -4803,10 +4975,3 @@ test "zig fmt: coroutines" { | ... | @@ -4803,10 +4975,3 @@ test "zig fmt: coroutines" { |
| 4803 | \\ | 4975 | \\ |
| 4804 | ); | 4976 | ); |
| 4805 | } | 4977 | } |
| 4806 | | | |
| 4807 | test "zig fmt: zig fmt" { | | |
| 4808 | try testCanonical(@embedFile("ast.zig")); | | |
| 4809 | try testCanonical(@embedFile("index.zig")); | | |
| 4810 | try testCanonical(@embedFile("parser.zig")); | | |
| 4811 | try testCanonical(@embedFile("tokenizer.zig")); | | |
| 4812 | } | | |