| ... | @@ -146,6 +146,8 @@ pub const Parser = struct { | ... | @@ -146,6 +146,8 @@ pub const Parser = struct { |
| 146 | Required, | 146 | Required, |
| 147 | | 147 | |
| 148 | Expression: DestPtr, | 148 | Expression: DestPtr, |
| | 149 | RangeExpressionBegin: DestPtr, |
| | 150 | RangeExpressionEnd: DestPtr, |
| 149 | AssignmentExpressionBegin: DestPtr, | 151 | AssignmentExpressionBegin: DestPtr, |
| 150 | AssignmentExpressionEnd: DestPtr, | 152 | AssignmentExpressionEnd: DestPtr, |
| 151 | UnwrapExpressionBegin: DestPtr, | 153 | UnwrapExpressionBegin: DestPtr, |
| ... | @@ -256,7 +258,7 @@ pub const Parser = struct { | ... | @@ -256,7 +258,7 @@ pub const Parser = struct { |
| 256 | } | 258 | } |
| 257 | | 259 | |
| 258 | const name = try self.createStringLiteral(arena, name_token); | 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 | const test_decl = try self.createAttachTestDecl(arena, &root_node.decls, token, &name.base, block); | 262 | const test_decl = try self.createAttachTestDecl(arena, &root_node.decls, token, &name.base, block); |
| 261 | stack.append(State { .Block = block }) catch unreachable; | 263 | stack.append(State { .Block = block }) catch unreachable; |
| 262 | continue; | 264 | continue; |
| ... | @@ -643,6 +645,27 @@ pub const Parser = struct { | ... | @@ -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 | State.AssignmentExpressionBegin => |dest_ptr| { | 669 | State.AssignmentExpressionBegin => |dest_ptr| { |
| 647 | stack.append(State { .AssignmentExpressionEnd = dest_ptr }) catch unreachable; | 670 | stack.append(State { .AssignmentExpressionEnd = dest_ptr }) catch unreachable; |
| 648 | try stack.append(State { .UnwrapExpressionBegin = dest_ptr }); | 671 | try stack.append(State { .UnwrapExpressionBegin = dest_ptr }); |
| ... | @@ -1205,10 +1228,6 @@ pub const Parser = struct { | ... | @@ -1205,10 +1228,6 @@ pub const Parser = struct { |
| 1205 | try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); | 1228 | try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); |
| 1206 | continue; | 1229 | continue; |
| 1207 | }, | 1230 | }, |
| 1208 | Token.Id.Identifier => { | | |
| 1209 | dest_ptr.store(&(try self.createIdentifier(arena, token)).base); | | |
| 1210 | continue; | | |
| 1211 | }, | | |
| 1212 | Token.Id.Builtin => { | 1231 | Token.Id.Builtin => { |
| 1213 | const node = try arena.create(ast.NodeBuiltinCall); | 1232 | const node = try arena.create(ast.NodeBuiltinCall); |
| 1214 | *node = ast.NodeBuiltinCall { | 1233 | *node = ast.NodeBuiltinCall { |
| ... | @@ -1348,8 +1367,32 @@ pub const Parser = struct { | ... | @@ -1348,8 +1367,32 @@ pub const Parser = struct { |
| 1348 | }, | 1367 | }, |
| 1349 | }) catch unreachable; | 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 | Token.Id.LBrace => { | 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 | Token.Id.Keyword_fn => { | 1397 | Token.Id.Keyword_fn => { |
| 1355 | @panic("TODO: fn proto"); | 1398 | @panic("TODO: fn proto"); |
| ... | @@ -1618,7 +1661,7 @@ pub const Parser = struct { | ... | @@ -1618,7 +1661,7 @@ pub const Parser = struct { |
| 1618 | const token = self.getNextToken(); | 1661 | const token = self.getNextToken(); |
| 1619 | switch(token.id) { | 1662 | switch(token.id) { |
| 1620 | Token.Id.LBrace => { | 1663 | Token.Id.LBrace => { |
| 1621 | const block = try self.createBlock(arena, token); | 1664 | const block = try self.createBlock(arena, (?Token)(null), token); |
| 1622 | fn_proto.body_node = &block.base; | 1665 | fn_proto.body_node = &block.base; |
| 1623 | stack.append(State { .Block = block }) catch unreachable; | 1666 | stack.append(State { .Block = block }) catch unreachable; |
| 1624 | continue; | 1667 | continue; |
| ... | @@ -1635,7 +1678,7 @@ pub const Parser = struct { | ... | @@ -1635,7 +1678,7 @@ pub const Parser = struct { |
| 1635 | const token = self.getNextToken(); | 1678 | const token = self.getNextToken(); |
| 1636 | switch (token.id) { | 1679 | switch (token.id) { |
| 1637 | Token.Id.RBrace => { | 1680 | Token.Id.RBrace => { |
| 1638 | block.end_token = token; | 1681 | block.rbrace = token; |
| 1639 | continue; | 1682 | continue; |
| 1640 | }, | 1683 | }, |
| 1641 | else => { | 1684 | else => { |
| ... | @@ -1648,38 +1691,64 @@ pub const Parser = struct { | ... | @@ -1648,38 +1691,64 @@ pub const Parser = struct { |
| 1648 | }, | 1691 | }, |
| 1649 | | 1692 | |
| 1650 | State.Statement => |block| { | 1693 | State.Statement => |block| { |
| 1651 | { | 1694 | const next = self.getNextToken(); |
| 1652 | // Look for comptime var, comptime const | 1695 | switch (next.id) { |
| 1653 | const comptime_token = self.getNextToken(); | 1696 | Token.Id.Keyword_comptime => { |
| 1654 | if (comptime_token.id == Token.Id.Keyword_comptime) { | | |
| 1655 | const mut_token = self.getNextToken(); | 1697 | const mut_token = self.getNextToken(); |
| 1656 | if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) { | 1698 | if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) { |
| 1657 | // TODO shouldn't need these casts | 1699 | // TODO shouldn't need these casts |
| 1658 | const var_decl = try self.createAttachVarDecl(arena, &block.statements, (?Token)(null), | 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 | stack.append(State { .VarDecl = var_decl }) catch unreachable; | 1702 | stack.append(State { .VarDecl = var_decl }) catch unreachable; |
| 1661 | continue; | 1703 | continue; |
| | 1704 | } else { |
| | 1705 | self.putBackToken(mut_token); |
| | 1706 | @panic("TODO: comptime block"); |
| 1662 | } | 1707 | } |
| 1663 | self.putBackToken(mut_token); | 1708 | }, |
| 1664 | } | 1709 | Token.Id.Keyword_var, Token.Id.Keyword_const => { |
| 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 | | |
| 1672 | const var_decl = try self.createAttachVarDecl(arena, &block.statements, (?Token)(null), | 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 | stack.append(State { .VarDecl = var_decl }) catch unreachable; | 1712 | stack.append(State { .VarDecl = var_decl }) catch unreachable; |
| 1675 | continue; | 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,14 +1974,15 @@ pub const Parser = struct { |
| 1905 | return node; | 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 | const node = try arena.create(ast.NodeBlock); | 1978 | const node = try arena.create(ast.NodeBlock); |
| 1910 | | 1979 | |
| 1911 | *node = ast.NodeBlock { | 1980 | *node = ast.NodeBlock { |
| 1912 | .base = self.initNode(ast.Node.Id.Block), | 1981 | .base = self.initNode(ast.Node.Id.Block), |
| 1913 | .begin_token = *begin_token, | 1982 | .label = *label, |
| 1914 | .end_token = undefined, | 1983 | .lbrace = *lbrace, |
| 1915 | .statements = ArrayList(&ast.Node).init(arena), | 1984 | .statements = ArrayList(&ast.Node).init(arena), |
| | 1985 | .rbrace = undefined, |
| 1916 | }; | 1986 | }; |
| 1917 | return node; | 1987 | return node; |
| 1918 | } | 1988 | } |
| ... | @@ -2340,6 +2410,10 @@ pub const Parser = struct { | ... | @@ -2340,6 +2410,10 @@ pub const Parser = struct { |
| 2340 | }, | 2410 | }, |
| 2341 | ast.Node.Id.Block => { | 2411 | ast.Node.Id.Block => { |
| 2342 | const block = @fieldParentPtr(ast.NodeBlock, "base", base); | 2412 | const block = @fieldParentPtr(ast.NodeBlock, "base", base); |
| | 2413 | if (block.label) |label| { |
| | 2414 | try stream.print("{}: ", self.tokenizer.getTokenSlice(label)); |
| | 2415 | } |
| | 2416 | |
| 2343 | if (block.statements.len == 0) { | 2417 | if (block.statements.len == 0) { |
| 2344 | try stream.write("{}"); | 2418 | try stream.write("{}"); |
| 2345 | } else { | 2419 | } else { |
| ... | @@ -2747,6 +2821,8 @@ pub const Parser = struct { | ... | @@ -2747,6 +2821,8 @@ pub const Parser = struct { |
| 2747 | }, | 2821 | }, |
| 2748 | ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"), | 2822 | ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"), |
| 2749 | ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"), | 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 | ast.Node.Id.StructField, | 2827 | ast.Node.Id.StructField, |
| 2752 | ast.Node.Id.UnionTag, | 2828 | ast.Node.Id.UnionTag, |
| ... | @@ -2791,6 +2867,9 @@ pub const Parser = struct { | ... | @@ -2791,6 +2867,9 @@ pub const Parser = struct { |
| 2791 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", base); | 2867 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", base); |
| 2792 | try stack.append(RenderState { .VarDecl = var_decl}); | 2868 | try stack.append(RenderState { .VarDecl = var_decl}); |
| 2793 | }, | 2869 | }, |
| | 2870 | ast.Node.Id.Block => { |
| | 2871 | try stack.append(RenderState { .Expression = base}); |
| | 2872 | }, |
| 2794 | else => { | 2873 | else => { |
| 2795 | try stack.append(RenderState { .Text = ";"}); | 2874 | try stack.append(RenderState { .Text = ";"}); |
| 2796 | try stack.append(RenderState { .Expression = base}); | 2875 | try stack.append(RenderState { .Expression = base}); |
| ... | @@ -3323,6 +3402,28 @@ test "zig fmt: catch" { | ... | @@ -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 | test "zig fmt: switch" { | 3427 | test "zig fmt: switch" { |
| 3327 | try testCanonical( | 3428 | try testCanonical( |
| 3328 | \\test "switch" { | 3429 | \\test "switch" { |