| ... | ... | @@ -146,6 +146,8 @@ pub const Parser = struct { |
| 146 | 146 | Required, |
| 147 | 147 | |
| 148 | 148 | Expression: DestPtr, |
| 149 | RangeExpressionBegin: DestPtr, |
| 150 | RangeExpressionEnd: DestPtr, |
| 149 | 151 | AssignmentExpressionBegin: DestPtr, |
| 150 | 152 | AssignmentExpressionEnd: DestPtr, |
| 151 | 153 | UnwrapExpressionBegin: DestPtr, |
| ... | ... | @@ -256,7 +258,7 @@ pub const Parser = struct { |
| 256 | 258 | } |
| 257 | 259 | |
| 258 | 260 | const name = try self.createStringLiteral(arena, name_token); |
| 259 | | const block = try self.createBlock(arena, token); |
| 261 | const block = try self.createBlock(arena, (?Token)(null), token); |
| 260 | 262 | const test_decl = try self.createAttachTestDecl(arena, &root_node.decls, token, &name.base, block); |
| 261 | 263 | stack.append(State { .Block = block }) catch unreachable; |
| 262 | 264 | continue; |
| ... | ... | @@ -643,6 +645,27 @@ pub const Parser = struct { |
| 643 | 645 | } |
| 644 | 646 | }, |
| 645 | 647 | |
| 648 | State.RangeExpressionBegin => |dest_ptr| { |
| 649 | stack.append(State { .RangeExpressionEnd = dest_ptr }) catch unreachable; |
| 650 | try stack.append(State { .Expression = dest_ptr }); |
| 651 | continue; |
| 652 | }, |
| 653 | |
| 654 | State.RangeExpressionEnd => |dest_ptr| { |
| 655 | const token = self.getNextToken(); |
| 656 | if (token.id == Token.Id.Ellipsis3) { |
| 657 | const node = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.Range); |
| 658 | node.lhs = dest_ptr.get(); |
| 659 | dest_ptr.store(&node.base); |
| 660 | |
| 661 | stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }) catch unreachable; |
| 662 | continue; |
| 663 | } else { |
| 664 | self.putBackToken(token); |
| 665 | continue; |
| 666 | } |
| 667 | }, |
| 668 | |
| 646 | 669 | State.AssignmentExpressionBegin => |dest_ptr| { |
| 647 | 670 | stack.append(State { .AssignmentExpressionEnd = dest_ptr }) catch unreachable; |
| 648 | 671 | try stack.append(State { .UnwrapExpressionBegin = dest_ptr }); |
| ... | ... | @@ -1205,10 +1228,6 @@ pub const Parser = struct { |
| 1205 | 1228 | try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); |
| 1206 | 1229 | continue; |
| 1207 | 1230 | }, |
| 1208 | | Token.Id.Identifier => { |
| 1209 | | dest_ptr.store(&(try self.createIdentifier(arena, token)).base); |
| 1210 | | continue; |
| 1211 | | }, |
| 1212 | 1231 | Token.Id.Builtin => { |
| 1213 | 1232 | const node = try arena.create(ast.NodeBuiltinCall); |
| 1214 | 1233 | *node = ast.NodeBuiltinCall { |
| ... | ... | @@ -1348,8 +1367,32 @@ pub const Parser = struct { |
| 1348 | 1367 | }, |
| 1349 | 1368 | }) catch unreachable; |
| 1350 | 1369 | }, |
| 1370 | Token.Id.Identifier => { |
| 1371 | const next = self.getNextToken(); |
| 1372 | if (next.id != Token.Id.Colon) { |
| 1373 | self.putBackToken(next); |
| 1374 | dest_ptr.store(&(try self.createIdentifier(arena, token)).base); |
| 1375 | continue; |
| 1376 | } |
| 1377 | |
| 1378 | const block = try self.createBlock(arena, (?Token)(token), Token(undefined)); |
| 1379 | dest_ptr.store(&block.base); |
| 1380 | |
| 1381 | stack.append(State { .Block = block }) catch unreachable; |
| 1382 | try stack.append(State { |
| 1383 | .ExpectTokenSave = ExpectTokenSave { |
| 1384 | .id = Token.Id.LBrace, |
| 1385 | .ptr = &block.lbrace, |
| 1386 | } |
| 1387 | }); |
| 1388 | continue; |
| 1389 | }, |
| 1351 | 1390 | Token.Id.LBrace => { |
| 1352 | | @panic("TODO: Block expr"); |
| 1391 | const block = try self.createBlock(arena, (?Token)(null), token); |
| 1392 | dest_ptr.store(&block.base); |
| 1393 | |
| 1394 | stack.append(State { .Block = block }) catch unreachable; |
| 1395 | continue; |
| 1353 | 1396 | }, |
| 1354 | 1397 | Token.Id.Keyword_fn => { |
| 1355 | 1398 | @panic("TODO: fn proto"); |
| ... | ... | @@ -1618,7 +1661,7 @@ pub const Parser = struct { |
| 1618 | 1661 | const token = self.getNextToken(); |
| 1619 | 1662 | switch(token.id) { |
| 1620 | 1663 | Token.Id.LBrace => { |
| 1621 | | const block = try self.createBlock(arena, token); |
| 1664 | const block = try self.createBlock(arena, (?Token)(null), token); |
| 1622 | 1665 | fn_proto.body_node = &block.base; |
| 1623 | 1666 | stack.append(State { .Block = block }) catch unreachable; |
| 1624 | 1667 | continue; |
| ... | ... | @@ -1635,7 +1678,7 @@ pub const Parser = struct { |
| 1635 | 1678 | const token = self.getNextToken(); |
| 1636 | 1679 | switch (token.id) { |
| 1637 | 1680 | Token.Id.RBrace => { |
| 1638 | | block.end_token = token; |
| 1681 | block.rbrace = token; |
| 1639 | 1682 | continue; |
| 1640 | 1683 | }, |
| 1641 | 1684 | else => { |
| ... | ... | @@ -1648,38 +1691,64 @@ pub const Parser = struct { |
| 1648 | 1691 | }, |
| 1649 | 1692 | |
| 1650 | 1693 | State.Statement => |block| { |
| 1651 | | { |
| 1652 | | // Look for comptime var, comptime const |
| 1653 | | const comptime_token = self.getNextToken(); |
| 1654 | | if (comptime_token.id == Token.Id.Keyword_comptime) { |
| 1694 | const next = self.getNextToken(); |
| 1695 | switch (next.id) { |
| 1696 | Token.Id.Keyword_comptime => { |
| 1655 | 1697 | const mut_token = self.getNextToken(); |
| 1656 | 1698 | if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) { |
| 1657 | 1699 | // TODO shouldn't need these casts |
| 1658 | 1700 | const var_decl = try self.createAttachVarDecl(arena, &block.statements, (?Token)(null), |
| 1659 | | mut_token, (?Token)(comptime_token), (?Token)(null), null); |
| 1701 | mut_token, (?Token)(next), (?Token)(null), null); |
| 1660 | 1702 | stack.append(State { .VarDecl = var_decl }) catch unreachable; |
| 1661 | 1703 | continue; |
| 1704 | } else { |
| 1705 | self.putBackToken(mut_token); |
| 1706 | @panic("TODO: comptime block"); |
| 1662 | 1707 | } |
| 1663 | | self.putBackToken(mut_token); |
| 1664 | | } |
| 1665 | | self.putBackToken(comptime_token); |
| 1666 | | } |
| 1667 | | { |
| 1668 | | // Look for const, var |
| 1669 | | const mut_token = self.getNextToken(); |
| 1670 | | if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) { |
| 1671 | | // TODO shouldn't need these casts |
| 1708 | }, |
| 1709 | Token.Id.Keyword_var, Token.Id.Keyword_const => { |
| 1672 | 1710 | const var_decl = try self.createAttachVarDecl(arena, &block.statements, (?Token)(null), |
| 1673 | | mut_token, (?Token)(null), (?Token)(null), null); |
| 1711 | next, (?Token)(null), (?Token)(null), null); |
| 1674 | 1712 | stack.append(State { .VarDecl = var_decl }) catch unreachable; |
| 1675 | 1713 | continue; |
| 1714 | }, |
| 1715 | Token.Id.Identifier => { |
| 1716 | const maybe_colon = self.getNextToken(); |
| 1717 | if (maybe_colon.id != Token.Id.Colon) { |
| 1718 | self.putBackToken(maybe_colon); |
| 1719 | self.putBackToken(next); |
| 1720 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable; |
| 1721 | try stack.append(State { .Expression = DestPtr{.Field = try block.statements.addOne() } }); |
| 1722 | continue; |
| 1723 | } |
| 1724 | |
| 1725 | const inner_block = try self.createBlock(arena, (?Token)(next), Token(undefined)); |
| 1726 | try block.statements.append(&inner_block.base); |
| 1727 | |
| 1728 | stack.append(State { .Block = inner_block }) catch unreachable; |
| 1729 | try stack.append(State { |
| 1730 | .ExpectTokenSave = ExpectTokenSave { |
| 1731 | .id = Token.Id.LBrace, |
| 1732 | .ptr = &inner_block.lbrace, |
| 1733 | } |
| 1734 | }); |
| 1735 | continue; |
| 1736 | }, |
| 1737 | Token.Id.LBrace => { |
| 1738 | const inner_block = try self.createBlock(arena, (?Token)(null), next); |
| 1739 | try block.statements.append(&inner_block.base); |
| 1740 | |
| 1741 | stack.append(State { .Block = inner_block }) catch unreachable; |
| 1742 | continue; |
| 1743 | }, |
| 1744 | else => { |
| 1745 | self.putBackToken(next); |
| 1746 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable; |
| 1747 | try stack.append(State { .Expression = DestPtr{.Field = try block.statements.addOne() } }); |
| 1748 | continue; |
| 1676 | 1749 | } |
| 1677 | | self.putBackToken(mut_token); |
| 1678 | 1750 | } |
| 1679 | 1751 | |
| 1680 | | stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable; |
| 1681 | | try stack.append(State { .Expression = DestPtr{.Field = try block.statements.addOne() } }); |
| 1682 | | continue; |
| 1683 | 1752 | }, |
| 1684 | 1753 | } |
| 1685 | 1754 | } |
| ... | ... | @@ -1905,14 +1974,15 @@ pub const Parser = struct { |
| 1905 | 1974 | return node; |
| 1906 | 1975 | } |
| 1907 | 1976 | |
| 1908 | | fn createBlock(self: &Parser, arena: &mem.Allocator, begin_token: &const Token) !&ast.NodeBlock { |
| 1977 | fn createBlock(self: &Parser, arena: &mem.Allocator, label: &const ?Token, lbrace: &const Token) !&ast.NodeBlock { |
| 1909 | 1978 | const node = try arena.create(ast.NodeBlock); |
| 1910 | 1979 | |
| 1911 | 1980 | *node = ast.NodeBlock { |
| 1912 | 1981 | .base = self.initNode(ast.Node.Id.Block), |
| 1913 | | .begin_token = *begin_token, |
| 1914 | | .end_token = undefined, |
| 1982 | .label = *label, |
| 1983 | .lbrace = *lbrace, |
| 1915 | 1984 | .statements = ArrayList(&ast.Node).init(arena), |
| 1985 | .rbrace = undefined, |
| 1916 | 1986 | }; |
| 1917 | 1987 | return node; |
| 1918 | 1988 | } |
| ... | ... | @@ -2340,6 +2410,10 @@ pub const Parser = struct { |
| 2340 | 2410 | }, |
| 2341 | 2411 | ast.Node.Id.Block => { |
| 2342 | 2412 | const block = @fieldParentPtr(ast.NodeBlock, "base", base); |
| 2413 | if (block.label) |label| { |
| 2414 | try stream.print("{}: ", self.tokenizer.getTokenSlice(label)); |
| 2415 | } |
| 2416 | |
| 2343 | 2417 | if (block.statements.len == 0) { |
| 2344 | 2418 | try stream.write("{}"); |
| 2345 | 2419 | } else { |
| ... | ... | @@ -2747,6 +2821,8 @@ pub const Parser = struct { |
| 2747 | 2821 | }, |
| 2748 | 2822 | ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"), |
| 2749 | 2823 | ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"), |
| 2824 | ast.Node.Id.Switch => @panic("TODO switch"), |
| 2825 | ast.Node.Id.SwitchCase => @panic("TODO switch case"), |
| 2750 | 2826 | |
| 2751 | 2827 | ast.Node.Id.StructField, |
| 2752 | 2828 | ast.Node.Id.UnionTag, |
| ... | ... | @@ -2791,6 +2867,9 @@ pub const Parser = struct { |
| 2791 | 2867 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", base); |
| 2792 | 2868 | try stack.append(RenderState { .VarDecl = var_decl}); |
| 2793 | 2869 | }, |
| 2870 | ast.Node.Id.Block => { |
| 2871 | try stack.append(RenderState { .Expression = base}); |
| 2872 | }, |
| 2794 | 2873 | else => { |
| 2795 | 2874 | try stack.append(RenderState { .Text = ";"}); |
| 2796 | 2875 | try stack.append(RenderState { .Expression = base}); |
| ... | ... | @@ -3323,6 +3402,28 @@ test "zig fmt: catch" { |
| 3323 | 3402 | ); |
| 3324 | 3403 | } |
| 3325 | 3404 | |
| 3405 | test "zig fmt: blocks" { |
| 3406 | try testCanonical( |
| 3407 | \\test "blocks" { |
| 3408 | \\ { |
| 3409 | \\ const a = 0; |
| 3410 | \\ const b = 0; |
| 3411 | \\ } |
| 3412 | \\ |
| 3413 | \\ blk: { |
| 3414 | \\ const a = 0; |
| 3415 | \\ const b = 0; |
| 3416 | \\ } |
| 3417 | \\ |
| 3418 | \\ const r = blk: { |
| 3419 | \\ const a = 0; |
| 3420 | \\ const b = 0; |
| 3421 | \\ }; |
| 3422 | \\} |
| 3423 | \\ |
| 3424 | ); |
| 3425 | } |
| 3426 | |
| 3326 | 3427 | test "zig fmt: switch" { |
| 3327 | 3428 | try testCanonical( |
| 3328 | 3429 | \\test "switch" { |