| ... | @@ -98,10 +98,15 @@ pub const Parser = struct { | ... | @@ -98,10 +98,15 @@ pub const Parser = struct { |
| 98 | ptr: &?&ast.Node, | 98 | ptr: &?&ast.Node, |
| 99 | }; | 99 | }; |
| 100 | | 100 | |
| 101 | fn ListState(comptime T: type) type { | 101 | const ExprListCtx = struct { |
| | 102 | list: &ArrayList(&ast.Node), |
| | 103 | end: Token.Id, |
| | 104 | ptr: &Token, |
| | 105 | }; |
| | 106 | |
| | 107 | fn ListSave(comptime T: type) type { |
| 102 | return struct { | 108 | return struct { |
| 103 | list: &ArrayList(T), | 109 | list: &ArrayList(T), |
| 104 | end: Token.Id, | | |
| 105 | ptr: &Token, | 110 | ptr: &Token, |
| 106 | }; | 111 | }; |
| 107 | } | 112 | } |
| ... | @@ -129,11 +134,16 @@ pub const Parser = struct { | ... | @@ -129,11 +134,16 @@ pub const Parser = struct { |
| 129 | FnDef: &ast.NodeFnProto, | 134 | FnDef: &ast.NodeFnProto, |
| 130 | Block: &ast.NodeBlock, | 135 | Block: &ast.NodeBlock, |
| 131 | Statement: &ast.NodeBlock, | 136 | Statement: &ast.NodeBlock, |
| 132 | ExprListItemOrEnd: ListState(&ast.Node), | 137 | ExprListItemOrEnd: ExprListCtx, |
| 133 | ExprListCommaOrEnd: ListState(&ast.Node), | 138 | ExprListCommaOrEnd: ExprListCtx, |
| 134 | FieldInitListItemOrEnd: ListState(&ast.NodeFieldInitializer), | 139 | FieldInitListItemOrEnd: ListSave(&ast.NodeFieldInitializer), |
| 135 | FieldInitListCommaOrEnd: ListState(&ast.NodeFieldInitializer), | 140 | FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer), |
| 136 | FieldListCommaOrEnd: &ast.NodeContainerDecl, | 141 | FieldListCommaOrEnd: &ast.NodeContainerDecl, |
| | 142 | SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase), |
| | 143 | SwitchCaseCapture: &?ast.NodeSwitchCase.Capture, |
| | 144 | SwitchCaseCommaOrEnd: ListSave(&ast.NodeSwitchCase), |
| | 145 | SwitchCaseItem: &ArrayList(&ast.Node), |
| | 146 | SwitchCaseItemCommaOrEnd: &ArrayList(&ast.Node), |
| 137 | | 147 | |
| 138 | /// A state that can be appended before any other State. If an error occures, | 148 | /// A state that can be appended before any other State. If an error occures, |
| 139 | /// the parser will first try looking for the closest optional state. If an | 149 | /// the parser will first try looking for the closest optional state. If an |
| ... | @@ -245,17 +255,8 @@ pub const Parser = struct { | ... | @@ -245,17 +255,8 @@ pub const Parser = struct { |
| 245 | Token.Id.Keyword_test => { | 255 | Token.Id.Keyword_test => { |
| 246 | stack.append(State.TopLevel) catch unreachable; | 256 | stack.append(State.TopLevel) catch unreachable; |
| 247 | | 257 | |
| 248 | const name_token = self.getNextToken(); | 258 | const name_token = (try self.eatToken(&stack, Token.Id.StringLiteral)) ?? continue; |
| 249 | if (name_token.id != Token.Id.StringLiteral) { | 259 | const lbrace = (try self.eatToken(&stack, Token.Id.LBrace)) ?? continue; |
| 250 | try self.parseError(&stack, token, "expected {}, found {}", @tagName(Token.Id.StringLiteral), @tagName(name_token.id)); | | |
| 251 | continue; | | |
| 252 | } | | |
| 253 | | | |
| 254 | const lbrace = self.getNextToken(); | | |
| 255 | if (lbrace.id != Token.Id.LBrace) { | | |
| 256 | try self.parseError(&stack, token, "expected {}, found {}", @tagName(Token.Id.LBrace), @tagName(name_token.id)); | | |
| 257 | continue; | | |
| 258 | } | | |
| 259 | | 260 | |
| 260 | const name = try self.createStringLiteral(arena, name_token); | 261 | const name = try self.createStringLiteral(arena, name_token); |
| 261 | const block = try self.createBlock(arena, (?Token)(null), token); | 262 | const block = try self.createBlock(arena, (?Token)(null), token); |
| ... | @@ -974,9 +975,8 @@ pub const Parser = struct { | ... | @@ -974,9 +975,8 @@ pub const Parser = struct { |
| 974 | | 975 | |
| 975 | stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable; | 976 | stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable; |
| 976 | try stack.append(State { | 977 | try stack.append(State { |
| 977 | .FieldInitListItemOrEnd = ListState(&ast.NodeFieldInitializer) { | 978 | .FieldInitListItemOrEnd = ListSave(&ast.NodeFieldInitializer) { |
| 978 | .list = &node.op.StructInitializer, | 979 | .list = &node.op.StructInitializer, |
| 979 | .end = Token.Id.RBrace, | | |
| 980 | .ptr = &node.rtoken, | 980 | .ptr = &node.rtoken, |
| 981 | } | 981 | } |
| 982 | }); | 982 | }); |
| ... | @@ -992,7 +992,7 @@ pub const Parser = struct { | ... | @@ -992,7 +992,7 @@ pub const Parser = struct { |
| 992 | | 992 | |
| 993 | stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable; | 993 | stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable; |
| 994 | try stack.append(State { | 994 | try stack.append(State { |
| 995 | .ExprListItemOrEnd = ListState(&ast.Node) { | 995 | .ExprListItemOrEnd = ExprListCtx { |
| 996 | .list = &node.op.ArrayInitializer, | 996 | .list = &node.op.ArrayInitializer, |
| 997 | .end = Token.Id.RBrace, | 997 | .end = Token.Id.RBrace, |
| 998 | .ptr = &node.rtoken, | 998 | .ptr = &node.rtoken, |
| ... | @@ -1084,7 +1084,7 @@ pub const Parser = struct { | ... | @@ -1084,7 +1084,7 @@ pub const Parser = struct { |
| 1084 | | 1084 | |
| 1085 | stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable; | 1085 | stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable; |
| 1086 | try stack.append(State { | 1086 | try stack.append(State { |
| 1087 | .ExprListItemOrEnd = ListState(&ast.Node) { | 1087 | .ExprListItemOrEnd = ExprListCtx { |
| 1088 | .list = &node.op.Call.params, | 1088 | .list = &node.op.Call.params, |
| 1089 | .end = Token.Id.RParen, | 1089 | .end = Token.Id.RParen, |
| 1090 | .ptr = &node.rtoken, | 1090 | .ptr = &node.rtoken, |
| ... | @@ -1238,7 +1238,7 @@ pub const Parser = struct { | ... | @@ -1238,7 +1238,7 @@ pub const Parser = struct { |
| 1238 | }; | 1238 | }; |
| 1239 | dest_ptr.store(&node.base); | 1239 | dest_ptr.store(&node.base); |
| 1240 | stack.append(State { | 1240 | stack.append(State { |
| 1241 | .ExprListItemOrEnd = ListState(&ast.Node) { | 1241 | .ExprListItemOrEnd = ExprListCtx { |
| 1242 | .list = &node.params, | 1242 | .list = &node.params, |
| 1243 | .end = Token.Id.RParen, | 1243 | .end = Token.Id.RParen, |
| 1244 | .ptr = &node.rparen_token, | 1244 | .ptr = &node.rparen_token, |
| ... | @@ -1400,6 +1400,43 @@ pub const Parser = struct { | ... | @@ -1400,6 +1400,43 @@ pub const Parser = struct { |
| 1400 | Token.Id.Keyword_asm => { | 1400 | Token.Id.Keyword_asm => { |
| 1401 | @panic("TODO: inline asm"); | 1401 | @panic("TODO: inline asm"); |
| 1402 | }, | 1402 | }, |
| | 1403 | Token.Id.Keyword_if => { |
| | 1404 | @panic("TODO: inline if"); |
| | 1405 | }, |
| | 1406 | Token.Id.Keyword_while => { |
| | 1407 | @panic("TODO: inline while"); |
| | 1408 | }, |
| | 1409 | Token.Id.Keyword_for => { |
| | 1410 | @panic("TODO: inline for"); |
| | 1411 | }, |
| | 1412 | Token.Id.Keyword_switch => { |
| | 1413 | const node = try arena.create(ast.NodeSwitch); |
| | 1414 | *node = ast.NodeSwitch { |
| | 1415 | .base = self.initNode(ast.Node.Id.Switch), |
| | 1416 | .switch_token = token, |
| | 1417 | .expr = undefined, |
| | 1418 | .cases = ArrayList(&ast.NodeSwitchCase).init(arena), |
| | 1419 | .rbrace = undefined, |
| | 1420 | }; |
| | 1421 | dest_ptr.store(&node.base); |
| | 1422 | |
| | 1423 | stack.append(State { |
| | 1424 | .SwitchCaseOrEnd = ListSave(&ast.NodeSwitchCase) { |
| | 1425 | .list = &node.cases, |
| | 1426 | .ptr = &node.rbrace, |
| | 1427 | }, |
| | 1428 | }) catch unreachable; |
| | 1429 | try stack.append(State { .ExpectToken = Token.Id.LBrace }); |
| | 1430 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| | 1431 | try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); |
| | 1432 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| | 1433 | }, |
| | 1434 | Token.Id.Keyword_comptime => { |
| | 1435 | @panic("TODO: inline comptime"); |
| | 1436 | }, |
| | 1437 | Token.Id.Keyword_suspend => { |
| | 1438 | @panic("TODO: inline suspend"); |
| | 1439 | }, |
| 1403 | else => { | 1440 | else => { |
| 1404 | try self.parseError(&stack, token, "expected primary expression, found {}", @tagName(token.id)); | 1441 | try self.parseError(&stack, token, "expected primary expression, found {}", @tagName(token.id)); |
| 1405 | continue; | 1442 | continue; |
| ... | @@ -1463,8 +1500,7 @@ pub const Parser = struct { | ... | @@ -1463,8 +1500,7 @@ pub const Parser = struct { |
| 1463 | State.FieldInitListItemOrEnd => |list_state| { | 1500 | State.FieldInitListItemOrEnd => |list_state| { |
| 1464 | var token = self.getNextToken(); | 1501 | var token = self.getNextToken(); |
| 1465 | | 1502 | |
| 1466 | const IdTag = @TagType(Token.Id); | 1503 | if (token.id == Token.Id.RBrace){ |
| 1467 | if (IdTag(list_state.end) == token.id){ | | |
| 1468 | *list_state.ptr = token; | 1504 | *list_state.ptr = token; |
| 1469 | continue; | 1505 | continue; |
| 1470 | } | 1506 | } |
| ... | @@ -1497,13 +1533,82 @@ pub const Parser = struct { | ... | @@ -1497,13 +1533,82 @@ pub const Parser = struct { |
| 1497 | }); | 1533 | }); |
| 1498 | }, | 1534 | }, |
| 1499 | | 1535 | |
| | 1536 | State.SwitchCaseOrEnd => |list_state| { |
| | 1537 | var token = self.getNextToken(); |
| | 1538 | |
| | 1539 | if (token.id == Token.Id.RBrace){ |
| | 1540 | *list_state.ptr = token; |
| | 1541 | continue; |
| | 1542 | } |
| | 1543 | |
| | 1544 | self.putBackToken(token); |
| | 1545 | |
| | 1546 | const node = try arena.create(ast.NodeSwitchCase); |
| | 1547 | *node = ast.NodeSwitchCase { |
| | 1548 | .base = self.initNode(ast.Node.Id.SwitchCase), |
| | 1549 | .items = ArrayList(&ast.Node).init(arena), |
| | 1550 | .capture = null, |
| | 1551 | .expr = undefined, |
| | 1552 | }; |
| | 1553 | try list_state.list.append(node); |
| | 1554 | stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable; |
| | 1555 | try stack.append(State { .Expression = DestPtr{ .Field = &node.expr } }); |
| | 1556 | try stack.append(State { .SwitchCaseCapture = &node.capture }); |
| | 1557 | |
| | 1558 | const maybe_else = self.getNextToken(); |
| | 1559 | if (maybe_else.id == Token.Id.Keyword_else) { |
| | 1560 | const else_node = try arena.create(ast.NodeSwitchElse); |
| | 1561 | *else_node = ast.NodeSwitchElse { |
| | 1562 | .base = self.initNode(ast.Node.Id.SwitchElse), |
| | 1563 | .token = maybe_else, |
| | 1564 | }; |
| | 1565 | try node.items.append(&else_node.base); |
| | 1566 | try stack.append(State { .ExpectToken = Token.Id.EqualAngleBracketRight }); |
| | 1567 | continue; |
| | 1568 | } else { |
| | 1569 | self.putBackToken(maybe_else); |
| | 1570 | try stack.append(State { .SwitchCaseItem = &node.items }); |
| | 1571 | continue; |
| | 1572 | } |
| | 1573 | }, |
| | 1574 | |
| | 1575 | State.SwitchCaseCapture => |capture| { |
| | 1576 | const token = self.getNextToken(); |
| | 1577 | if (token.id != Token.Id.Pipe) { |
| | 1578 | self.putBackToken(token); |
| | 1579 | continue; |
| | 1580 | } |
| | 1581 | |
| | 1582 | const is_ptr = blk: { |
| | 1583 | const asterik = self.getNextToken(); |
| | 1584 | if (asterik.id == Token.Id.Asterisk) { |
| | 1585 | break :blk true; |
| | 1586 | } else { |
| | 1587 | self.putBackToken(asterik); |
| | 1588 | break :blk false; |
| | 1589 | } |
| | 1590 | }; |
| | 1591 | |
| | 1592 | const ident = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue; |
| | 1593 | _ = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue; |
| | 1594 | *capture = ast.NodeSwitchCase.Capture { |
| | 1595 | .symbol = try self.createIdentifier(arena, ident), |
| | 1596 | .is_ptr = is_ptr |
| | 1597 | }; |
| | 1598 | }, |
| | 1599 | |
| | 1600 | State.SwitchCaseItem => |case_items| { |
| | 1601 | stack.append(State { .SwitchCaseItemCommaOrEnd = case_items }) catch unreachable; |
| | 1602 | try stack.append(State { .RangeExpressionBegin = DestPtr{ .Field = try case_items.addOne() } }); |
| | 1603 | }, |
| | 1604 | |
| 1500 | State.ExprListCommaOrEnd => |list_state| { | 1605 | State.ExprListCommaOrEnd => |list_state| { |
| 1501 | try self.commaOrEnd(&stack, list_state.end, list_state.ptr, State { .ExprListItemOrEnd = list_state }); | 1606 | try self.commaOrEnd(&stack, list_state.end, list_state.ptr, State { .ExprListItemOrEnd = list_state }); |
| 1502 | continue; | 1607 | continue; |
| 1503 | }, | 1608 | }, |
| 1504 | | 1609 | |
| 1505 | State.FieldInitListCommaOrEnd => |list_state| { | 1610 | State.FieldInitListCommaOrEnd => |list_state| { |
| 1506 | try self.commaOrEnd(&stack, list_state.end, list_state.ptr, State { .FieldInitListItemOrEnd = list_state }); | 1611 | try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .FieldInitListItemOrEnd = list_state }); |
| 1507 | continue; | 1612 | continue; |
| 1508 | }, | 1613 | }, |
| 1509 | | 1614 | |
| ... | @@ -1513,6 +1618,16 @@ pub const Parser = struct { | ... | @@ -1513,6 +1618,16 @@ pub const Parser = struct { |
| 1513 | continue; | 1618 | continue; |
| 1514 | }, | 1619 | }, |
| 1515 | | 1620 | |
| | 1621 | State.SwitchCaseCommaOrEnd => |list_state| { |
| | 1622 | try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .SwitchCaseOrEnd = list_state }); |
| | 1623 | continue; |
| | 1624 | }, |
| | 1625 | |
| | 1626 | State.SwitchCaseItemCommaOrEnd => |case_items| { |
| | 1627 | try self.commaOrEnd(&stack, Token.Id.EqualAngleBracketRight, null, State { .SwitchCaseItem = case_items }); |
| | 1628 | continue; |
| | 1629 | }, |
| | 1630 | |
| 1516 | State.AddrOfModifiers => |addr_of_info| { | 1631 | State.AddrOfModifiers => |addr_of_info| { |
| 1517 | var token = self.getNextToken(); | 1632 | var token = self.getNextToken(); |
| 1518 | switch (token.id) { | 1633 | switch (token.id) { |
| ... | @@ -1741,6 +1856,11 @@ pub const Parser = struct { | ... | @@ -1741,6 +1856,11 @@ pub const Parser = struct { |
| 1741 | stack.append(State { .Block = inner_block }) catch unreachable; | 1856 | stack.append(State { .Block = inner_block }) catch unreachable; |
| 1742 | continue; | 1857 | continue; |
| 1743 | }, | 1858 | }, |
| | 1859 | Token.Id.Keyword_switch => { |
| | 1860 | self.putBackToken(next); |
| | 1861 | stack.append(State { .Expression = DestPtr{.Field = try block.statements.addOne() } }) catch unreachable; |
| | 1862 | continue; |
| | 1863 | }, |
| 1744 | else => { | 1864 | else => { |
| 1745 | self.putBackToken(next); | 1865 | self.putBackToken(next); |
| 1746 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable; | 1866 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable; |
| ... | @@ -1754,7 +1874,7 @@ pub const Parser = struct { | ... | @@ -1754,7 +1874,7 @@ pub const Parser = struct { |
| 1754 | } | 1874 | } |
| 1755 | } | 1875 | } |
| 1756 | | 1876 | |
| 1757 | fn commaOrEnd(self: &Parser, stack: &ArrayList(State), end: &const Token.Id, ptr: &Token, state_after_comma: &const State) !void { | 1877 | fn commaOrEnd(self: &Parser, stack: &ArrayList(State), end: &const Token.Id, maybe_ptr: ?&Token, state_after_comma: &const State) !void { |
| 1758 | var token = self.getNextToken(); | 1878 | var token = self.getNextToken(); |
| 1759 | switch (token.id) { | 1879 | switch (token.id) { |
| 1760 | Token.Id.Comma => { | 1880 | Token.Id.Comma => { |
| ... | @@ -1763,7 +1883,9 @@ pub const Parser = struct { | ... | @@ -1763,7 +1883,9 @@ pub const Parser = struct { |
| 1763 | else => { | 1883 | else => { |
| 1764 | const IdTag = @TagType(Token.Id); | 1884 | const IdTag = @TagType(Token.Id); |
| 1765 | if (IdTag(*end) == token.id) { | 1885 | if (IdTag(*end) == token.id) { |
| 1766 | *ptr = token; | 1886 | if (maybe_ptr) |ptr| { |
| | 1887 | *ptr = token; |
| | 1888 | } |
| 1767 | return; | 1889 | return; |
| 1768 | } | 1890 | } |
| 1769 | | 1891 | |
| ... | @@ -2498,7 +2620,8 @@ pub const Parser = struct { | ... | @@ -2498,7 +2620,8 @@ pub const Parser = struct { |
| 2498 | ast.NodeInfixOp.InfixOp.Sub => " - ", | 2620 | ast.NodeInfixOp.InfixOp.Sub => " - ", |
| 2499 | ast.NodeInfixOp.InfixOp.SubWrap => " -% ", | 2621 | ast.NodeInfixOp.InfixOp.SubWrap => " -% ", |
| 2500 | ast.NodeInfixOp.InfixOp.UnwrapMaybe => " ?? ", | 2622 | ast.NodeInfixOp.InfixOp.UnwrapMaybe => " ?? ", |
| 2501 | else => unreachable, | 2623 | ast.NodeInfixOp.InfixOp.Range => " ... ", |
| | 2624 | ast.NodeInfixOp.InfixOp.Catch => unreachable, |
| 2502 | }; | 2625 | }; |
| 2503 | | 2626 | |
| 2504 | try stack.append(RenderState { .Text = text }); | 2627 | try stack.append(RenderState { .Text = text }); |
| ... | @@ -2821,8 +2944,73 @@ pub const Parser = struct { | ... | @@ -2821,8 +2944,73 @@ pub const Parser = struct { |
| 2821 | }, | 2944 | }, |
| 2822 | ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"), | 2945 | ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"), |
| 2823 | ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"), | 2946 | ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"), |
| 2824 | ast.Node.Id.Switch => @panic("TODO switch"), | 2947 | ast.Node.Id.Switch => { |
| 2825 | ast.Node.Id.SwitchCase => @panic("TODO switch case"), | 2948 | const switch_node = @fieldParentPtr(ast.NodeSwitch, "base", base); |
| | 2949 | try stream.print("{} (", self.tokenizer.getTokenSlice(switch_node.switch_token)); |
| | 2950 | |
| | 2951 | try stack.append(RenderState { .Text = "}"}); |
| | 2952 | try stack.append(RenderState.PrintIndent); |
| | 2953 | try stack.append(RenderState { .Indent = indent }); |
| | 2954 | try stack.append(RenderState { .Text = "\n"}); |
| | 2955 | |
| | 2956 | const cases = switch_node.cases.toSliceConst(); |
| | 2957 | var i = cases.len; |
| | 2958 | while (i != 0) { |
| | 2959 | i -= 1; |
| | 2960 | const node = cases[i]; |
| | 2961 | try stack.append(RenderState { .Expression = &node.base}); |
| | 2962 | try stack.append(RenderState.PrintIndent); |
| | 2963 | try stack.append(RenderState { |
| | 2964 | .Text = blk: { |
| | 2965 | if (i != 0) { |
| | 2966 | const prev_node = cases[i - 1]; |
| | 2967 | const loc = self.tokenizer.getTokenLocation(prev_node.lastToken().end, node.firstToken()); |
| | 2968 | if (loc.line >= 2) { |
| | 2969 | break :blk "\n\n"; |
| | 2970 | } |
| | 2971 | } |
| | 2972 | break :blk "\n"; |
| | 2973 | }, |
| | 2974 | }); |
| | 2975 | |
| | 2976 | if (i != 0) { |
| | 2977 | try stack.append(RenderState { .Text = "," }); |
| | 2978 | } |
| | 2979 | } |
| | 2980 | try stack.append(RenderState { .Indent = indent + indent_delta}); |
| | 2981 | try stack.append(RenderState { .Text = ") {"}); |
| | 2982 | try stack.append(RenderState { .Expression = switch_node.expr }); |
| | 2983 | }, |
| | 2984 | ast.Node.Id.SwitchCase => { |
| | 2985 | const switch_case = @fieldParentPtr(ast.NodeSwitchCase, "base", base); |
| | 2986 | |
| | 2987 | try stack.append(RenderState { .Expression = switch_case.expr }); |
| | 2988 | if (switch_case.capture) |capture| { |
| | 2989 | try stack.append(RenderState { .Text = "| "}); |
| | 2990 | try stack.append(RenderState { .Expression = &capture.symbol.base }); |
| | 2991 | |
| | 2992 | if (capture.is_ptr) { |
| | 2993 | try stack.append(RenderState { .Text = "*"}); |
| | 2994 | } |
| | 2995 | try stack.append(RenderState { .Text = "|"}); |
| | 2996 | } |
| | 2997 | try stack.append(RenderState { .Text = " => "}); |
| | 2998 | |
| | 2999 | const items = switch_case.items.toSliceConst(); |
| | 3000 | var i = items.len; |
| | 3001 | while (i != 0) { |
| | 3002 | i -= 1; |
| | 3003 | try stack.append(RenderState { .Expression = items[i] }); |
| | 3004 | |
| | 3005 | if (i != 0) { |
| | 3006 | try stack.append(RenderState { .Text = ", " }); |
| | 3007 | } |
| | 3008 | } |
| | 3009 | }, |
| | 3010 | ast.Node.Id.SwitchElse => { |
| | 3011 | const switch_else = @fieldParentPtr(ast.NodeSwitchElse, "base", base); |
| | 3012 | try stream.print("{}", self.tokenizer.getTokenSlice(switch_else.token)); |
| | 3013 | }, |
| 2826 | | 3014 | |
| 2827 | ast.Node.Id.StructField, | 3015 | ast.Node.Id.StructField, |
| 2828 | ast.Node.Id.UnionTag, | 3016 | ast.Node.Id.UnionTag, |
| ... | @@ -2867,7 +3055,7 @@ pub const Parser = struct { | ... | @@ -2867,7 +3055,7 @@ pub const Parser = struct { |
| 2867 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", base); | 3055 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", base); |
| 2868 | try stack.append(RenderState { .VarDecl = var_decl}); | 3056 | try stack.append(RenderState { .VarDecl = var_decl}); |
| 2869 | }, | 3057 | }, |
| 2870 | ast.Node.Id.Block => { | 3058 | ast.Node.Id.Block, ast.Node.Id.Switch => { |
| 2871 | try stack.append(RenderState { .Expression = base}); | 3059 | try stack.append(RenderState { .Expression = base}); |
| 2872 | }, | 3060 | }, |
| 2873 | else => { | 3061 | else => { |
| ... | @@ -3436,24 +3624,24 @@ test "zig fmt: switch" { | ... | @@ -3436,24 +3624,24 @@ test "zig fmt: switch" { |
| 3436 | \\ else => { | 3624 | \\ else => { |
| 3437 | \\ const a = 1; | 3625 | \\ const a = 1; |
| 3438 | \\ const b = a; | 3626 | \\ const b = a; |
| 3439 | \\ }, | 3627 | \\ } |
| 3440 | \\ } | 3628 | \\ } |
| 3441 | \\ | 3629 | \\ |
| 3442 | \\ const res = switch (0) { | 3630 | \\ const res = switch (0) { |
| 3443 | \\ 0 => 0, | 3631 | \\ 0 => 0, |
| 3444 | \\ 1 => 2, | 3632 | \\ 1 => 2, |
| 3445 | \\ else => 4, | 3633 | \\ else => 4 |
| 3446 | \\ }; | 3634 | \\ }; |
| 3447 | \\ | 3635 | \\ |
| 3448 | \\ const Union = union(enum) { | 3636 | \\ const Union = union(enum) { |
| 3449 | \\ Int: i64, | 3637 | \\ Int: i64, |
| 3450 | \\ Float: f64, | 3638 | \\ Float: f64 |
| 3451 | \\ }; | 3639 | \\ }; |
| 3452 | \\ | 3640 | \\ |
| 3453 | \\ const u = Union { .Int = 0 }; | 3641 | \\ const u = Union{ .Int = 0 }; |
| 3454 | \\ switch (u) { | 3642 | \\ switch (u) { |
| 3455 | \\ Union.Int => |int| {}, | 3643 | \\ Union.Int => |int| {}, |
| 3456 | \\ Union.Float => |*float| unreachable, | 3644 | \\ Union.Float => |*float| unreachable |
| 3457 | \\ } | 3645 | \\ } |
| 3458 | \\} | 3646 | \\} |
| 3459 | \\ | 3647 | \\ |