authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-06 11:03:56+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-06 17:34:37-05:00
log83d27f71ef92d555cc15645bf9d948203ba8af1e
tree681dfe37a5fa5d7d73ac0da20de8c77c4c211edc
parent7df9169081ef570b2560646e2d341e81df1a3976

translate-c more macro ops


2 files changed, 103 insertions(+), 150 deletions(-)

src-self-hosted/translate_c.zig+98-145
...@@ -610,7 +610,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {...@@ -610,7 +610,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
610 try transCreateNodeUndefinedLiteral(c);610 try transCreateNodeUndefinedLiteral(c);
611 } else if (storage_class != .Extern) {611 } else if (storage_class != .Extern) {
612 eq_tok = try appendToken(c, .Equal, "=");612 eq_tok = try appendToken(c, .Equal, "=");
613 init_node = try transCreateNodeTypeIdentifier(c, "undefined");613 init_node = try transCreateNodeIdentifierUnchecked(c, "undefined");
614 }614 }
615615
616 const linksection_expr = blk: {616 const linksection_expr = blk: {
...@@ -4814,7 +4814,7 @@ fn transCreateNodeIdentifier(c: *Context, name: []const u8) !*ast.Node {...@@ -4814,7 +4814,7 @@ fn transCreateNodeIdentifier(c: *Context, name: []const u8) !*ast.Node {
4814 return &identifier.base;4814 return &identifier.base;
4815}4815}
48164816
4817fn transCreateNodeTypeIdentifier(c: *Context, name: []const u8) !*ast.Node {4817fn transCreateNodeIdentifierUnchecked(c: *Context, name: []const u8) !*ast.Node {
4818 const token_index = try appendTokenFmt(c, .Identifier, "{}", .{name});4818 const token_index = try appendTokenFmt(c, .Identifier, "{}", .{name});
4819 const identifier = try c.a().create(ast.Node.Identifier);4819 const identifier = try c.a().create(ast.Node.Identifier);
4820 identifier.* = .{4820 identifier.* = .{
...@@ -5368,15 +5368,15 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5368,15 +5368,15 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5368 return parseCNumLit(c, tok, source, source_loc);5368 return parseCNumLit(c, tok, source, source_loc);
5369 },5369 },
5370 // eventually this will be replaced by std.c.parse which will handle these correctly5370 // eventually this will be replaced by std.c.parse which will handle these correctly
5371 .Keyword_void => return transCreateNodeTypeIdentifier(c, "c_void"),5371 .Keyword_void => return transCreateNodeIdentifierUnchecked(c, "c_void"),
5372 .Keyword_bool => return transCreateNodeTypeIdentifier(c, "bool"),5372 .Keyword_bool => return transCreateNodeIdentifierUnchecked(c, "bool"),
5373 .Keyword_double => return transCreateNodeTypeIdentifier(c, "f64"),5373 .Keyword_double => return transCreateNodeIdentifierUnchecked(c, "f64"),
5374 .Keyword_long => return transCreateNodeTypeIdentifier(c, "c_long"),5374 .Keyword_long => return transCreateNodeIdentifierUnchecked(c, "c_long"),
5375 .Keyword_int => return transCreateNodeTypeIdentifier(c, "c_int"),5375 .Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_int"),
5376 .Keyword_float => return transCreateNodeTypeIdentifier(c, "f32"),5376 .Keyword_float => return transCreateNodeIdentifierUnchecked(c, "f32"),
5377 .Keyword_short => return transCreateNodeTypeIdentifier(c, "c_short"),5377 .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_short"),
5378 .Keyword_char => return transCreateNodeTypeIdentifier(c, "c_char"),5378 .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "c_char"),
5379 .Keyword_unsigned => return transCreateNodeTypeIdentifier(c, "c_uint"),5379 .Keyword_unsigned => return transCreateNodeIdentifierUnchecked(c, "c_uint"),
5380 .Identifier => {5380 .Identifier => {
5381 const mangled_name = scope.getAlias(source[tok.start..tok.end]);5381 const mangled_name = scope.getAlias(source[tok.start..tok.end]);
5382 return transCreateNodeIdentifier(c, mangled_name);5382 return transCreateNodeIdentifier(c, mangled_name);
...@@ -5512,6 +5512,8 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5512,6 +5512,8 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5512 var node = try parseCPrimaryExpr(c, it, source, source_loc, scope);5512 var node = try parseCPrimaryExpr(c, it, source, source_loc, scope);
5513 while (true) {5513 while (true) {
5514 const tok = it.next().?;5514 const tok = it.next().?;
5515 var op_token: ast.TokenIndex = undefined;
5516 var op_id: ast.Node.InfixOp.Op = undefined;
5515 switch (tok.id) {5517 switch (tok.id) {
5516 .Period => {5518 .Period => {
5517 const name_tok = it.next().?;5519 const name_tok = it.next().?;
...@@ -5528,6 +5530,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5528,6 +5530,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5528 }5530 }
55295531
5530 node = try transCreateNodeFieldAccess(c, node, source[name_tok.start..name_tok.end]);5532 node = try transCreateNodeFieldAccess(c, node, source[name_tok.start..name_tok.end]);
5533 continue;
5531 },5534 },
5532 .Arrow => {5535 .Arrow => {
5533 const name_tok = it.next().?;5536 const name_tok = it.next().?;
...@@ -5542,9 +5545,16 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5542,9 +5545,16 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5542 );5545 );
5543 return error.ParseError;5546 return error.ParseError;
5544 }5547 }
55455548 // deref is often used together with casts so we group the lhs expression
5546 const deref = try transCreateNodePtrDeref(c, node);5549 const group = try c.a().create(ast.Node.GroupedExpression);
5550 group.* = .{
5551 .lparen = try appendToken(c, .LParen, "("),
5552 .expr = node,
5553 .rparen = try appendToken(c, .RParen, ")"),
5554 };
5555 const deref = try transCreateNodePtrDeref(c, &group.base);
5547 node = try transCreateNodeFieldAccess(c, deref, source[name_tok.start..name_tok.end]);5556 node = try transCreateNodeFieldAccess(c, deref, source[name_tok.start..name_tok.end]);
5557 continue;
5548 },5558 },
5549 .Asterisk => {5559 .Asterisk => {
5550 if (it.peek().?.id == .RParen) {5560 if (it.peek().?.id == .RParen) {
...@@ -5568,161 +5578,57 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5568,161 +5578,57 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5568 return &ptr.base;5578 return &ptr.base;
5569 } else {5579 } else {
5570 // expr * expr5580 // expr * expr
5571 const op_token = try appendToken(c, .Asterisk, "*");5581 op_token = try appendToken(c, .Asterisk, "*");
5572 const rhs = try parseCPrimaryExpr(c, it, source, source_loc, scope);5582 op_id = .BitShiftLeft;
5573 const mul_node = try c.a().create(ast.Node.InfixOp);
5574 mul_node.* = .{
5575 .op_token = op_token,
5576 .lhs = node,
5577 .op = .BitShiftLeft,
5578 .rhs = rhs,
5579 };
5580 node = &mul_node.base;
5581 }5583 }
5582 },5584 },
5583 .AngleBracketAngleBracketLeft => {5585 .AngleBracketAngleBracketLeft => {
5584 const op_token = try appendToken(c, .AngleBracketAngleBracketLeft, "<<");5586 op_token = try appendToken(c, .AngleBracketAngleBracketLeft, "<<");
5585 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5587 op_id = .BitShiftLeft;
5586 const bitshift_node = try c.a().create(ast.Node.InfixOp);
5587 bitshift_node.* = .{
5588 .op_token = op_token,
5589 .lhs = node,
5590 .op = .BitShiftLeft,
5591 .rhs = rhs,
5592 };
5593 node = &bitshift_node.base;
5594 },5588 },
5595 .AngleBracketAngleBracketRight => {5589 .AngleBracketAngleBracketRight => {
5596 const op_token = try appendToken(c, .AngleBracketAngleBracketRight, ">>");5590 op_token = try appendToken(c, .AngleBracketAngleBracketRight, ">>");
5597 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5591 op_id = .BitShiftRight;
5598 const bitshift_node = try c.a().create(ast.Node.InfixOp);
5599 bitshift_node.* = .{
5600 .op_token = op_token,
5601 .lhs = node,
5602 .op = .BitShiftRight,
5603 .rhs = rhs,
5604 };
5605 node = &bitshift_node.base;
5606 },5592 },
5607 .Pipe => {5593 .Pipe => {
5608 const op_token = try appendToken(c, .Pipe, "|");5594 op_token = try appendToken(c, .Pipe, "|");
5609 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5595 op_id = .BitOr;
5610 const or_node = try c.a().create(ast.Node.InfixOp);
5611 or_node.* = .{
5612 .op_token = op_token,
5613 .lhs = node,
5614 .op = .BitOr,
5615 .rhs = rhs,
5616 };
5617 node = &or_node.base;
5618 },5596 },
5619 .Ampersand => {5597 .Ampersand => {
5620 const op_token = try appendToken(c, .Ampersand, "&");5598 op_token = try appendToken(c, .Ampersand, "&");
5621 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5599 op_id .BitAnd;
5622 const bitand_node = try c.a().create(ast.Node.InfixOp);
5623 bitand_node.* = .{
5624 .op_token = op_token,
5625 .lhs = node,
5626 .op = .BitAnd,
5627 .rhs = rhs,
5628 };
5629 node = &bitand_node.base;
5630 },5600 },
5631 .Plus => {5601 .Plus => {
5632 const op_token = try appendToken(c, .Plus, "+");5602 op_token = try appendToken(c, .Plus, "+");
5633 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5603 op_id = .Add;
5634 const add_node = try c.a().create(ast.Node.InfixOp);
5635 add_node.* = .{
5636 .op_token = op_token,
5637 .lhs = node,
5638 .op = .Add,
5639 .rhs = rhs,
5640 };
5641 node = &add_node.base;
5642 },5604 },
5643 .Minus => {5605 .Minus => {
5644 const op_token = try appendToken(c, .Minus, "-");5606 op_token = try appendToken(c, .Minus, "-");
5645 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5607 op_id .Sub;
5646 const sub_node = try c.a().create(ast.Node.InfixOp);
5647 sub_node.* = .{
5648 .op_token = op_token,
5649 .lhs = node,
5650 .op = .Sub,
5651 .rhs = rhs,
5652 };
5653 node = &sub_node.base;
5654 },5608 },
5655 .AmpersandAmpersand => {5609 .AmpersandAmpersand => {
5656 const op_token = try appendToken(c, .Keyword_and, "and");5610 op_token = try appendToken(c, .Keyword_and, "and");
5657 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5611 op_id = .BoolAnd;
5658 const and_node = try c.a().create(ast.Node.InfixOp);
5659 and_node.* = .{
5660 .op_token = op_token,
5661 .lhs = node,
5662 .op = .BoolAnd,
5663 .rhs = rhs,
5664 };
5665 node = &and_node.base;
5666 },5612 },
5667 .PipePipe => {5613 .PipePipe => {
5668 const op_token = try appendToken(c, .Keyword_or, "or");5614 op_token = try appendToken(c, .Keyword_or, "or");
5669 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5615 op_id = .BoolOr;
5670 const or_node = try c.a().create(ast.Node.InfixOp);
5671 or_node.* = .{
5672 .op_token = op_token,
5673 .lhs = node,
5674 .op = .BoolOr,
5675 .rhs = rhs,
5676 };
5677 node = &or_node.base;
5678 },5616 },
5679 .AngleBracketRight => {5617 .AngleBracketRight => {
5680 const op_token = try appendToken(c, .AngleBracketRight, ">");5618 op_token = try appendToken(c, .AngleBracketRight, ">");
5681 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5619 op_id = .GreaterThan;
5682 const and_node = try c.a().create(ast.Node.InfixOp);
5683 and_node.* = .{
5684 .op_token = op_token,
5685 .lhs = node,
5686 .op = .GreaterThan,
5687 .rhs = rhs,
5688 };
5689 node = &and_node.base;
5690 },5620 },
5691 .AngleBracketRightEqual => {5621 .AngleBracketRightEqual => {
5692 const op_token = try appendToken(c, .AngleBracketRightEqual, ">=");5622 op_token = try appendToken(c, .AngleBracketRightEqual, ">=");
5693 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5623 op_id = .GreaterOrEqual;
5694 const and_node = try c.a().create(ast.Node.InfixOp);
5695 and_node.* = .{
5696 .op_token = op_token,
5697 .lhs = node,
5698 .op = .GreaterOrEqual,
5699 .rhs = rhs,
5700 };
5701 node = &and_node.base;
5702 },5624 },
5703 .AngleBracketLeft => {5625 .AngleBracketLeft => {
5704 const op_token = try appendToken(c, .AngleBracketLeft, "<");5626 op_token = try appendToken(c, .AngleBracketLeft, "<");
5705 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5627 op_id = .LessThan;
5706 const and_node = try c.a().create(ast.Node.InfixOp);
5707 and_node.* = .{
5708 .op_token = op_token,
5709 .lhs = node,
5710 .op = .LessThan,
5711 .rhs = rhs,
5712 };
5713 node = &and_node.base;
5714 },5628 },
5715 .AngleBracketLeftEqual => {5629 .AngleBracketLeftEqual => {
5716 const op_token = try appendToken(c, .AngleBracketLeftEqual, "<=");5630 op_token = try appendToken(c, .AngleBracketLeftEqual, "<=");
5717 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5631 op_id = .LessOrEqual;
5718 const and_node = try c.a().create(ast.Node.InfixOp);
5719 and_node.* = .{
5720 .op_token = op_token,
5721 .lhs = node,
5722 .op = .LessOrEqual,
5723 .rhs = rhs,
5724 };
5725 node = &and_node.base;
5726 },5632 },
5727 .LBracket => {5633 .LBracket => {
5728 const arr_node = try transCreateNodeArrayAccess(c, node);5634 const arr_node = try transCreateNodeArrayAccess(c, node);
...@@ -5740,6 +5646,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5740,6 +5646,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5740 );5646 );
5741 return error.ParseError;5647 return error.ParseError;
5742 }5648 }
5649 continue;
5743 },5650 },
5744 .LParen => {5651 .LParen => {
5745 const call_node = try transCreateNodeFnCall(c, node);5652 const call_node = try transCreateNodeFnCall(c, node);
...@@ -5765,12 +5672,39 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5765,12 +5672,39 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5765 }5672 }
5766 call_node.rtoken = try appendToken(c, .RParen, ")");5673 call_node.rtoken = try appendToken(c, .RParen, ")");
5767 node = &call_node.base;5674 node = &call_node.base;
5675 continue;
5676 },
5677 .BangEqual => {
5678 op_token = try appendToken(c, .BangEqual, "!=");
5679 op_id = .BangEqual;
5680 },
5681 .EqualEqual => {
5682 op_token = try appendToken(c, .EqualEqual, "==");
5683 op_id = .EqualEqual;
5684 },
5685 .Slash => {
5686 // unsigned/float division uses the operator
5687 op_id = .Div;
5688 op_token = try appendToken(c, .Slash, "/");
5689 },
5690 .Percent => {
5691 // unsigned/float division uses the operator
5692 op_id = .Mod;
5693 op_token = try appendToken(c, .Percent, "%");
5768 },5694 },
5769 else => {5695 else => {
5770 _ = it.prev();5696 _ = it.prev();
5771 return node;5697 return node;
5772 },5698 },
5773 }5699 }
5700 const op_node = try c.a().create(ast.Node.InfixOp);
5701 op_node.* = .{
5702 .op_token = op_token,
5703 .lhs = node,
5704 .op = op_id,
5705 .rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope),
5706 };
5707 node = &op_node.base;
5774 }5708 }
5775}5709}
57765710
...@@ -5788,14 +5722,33 @@ fn parseCPrefixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5788,14 +5722,33 @@ fn parseCPrefixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5788 node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5722 node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
5789 return &node.base;5723 return &node.base;
5790 },5724 },
5725 .Plus => return try parseCPrefixOpExpr(c, it, source, source_loc, scope),
5791 .Tilde => {5726 .Tilde => {
5792 const node = try transCreateNodePrefixOp(c, .BitNot, .Tilde, "~");5727 const node = try transCreateNodePrefixOp(c, .BitNot, .Tilde, "~");
5793 node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5728 node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
5794 return &node.base;5729 return &node.base;
5795 },5730 },
5796 .Asterisk => {5731 .Asterisk => {
5797 const prefix_op_expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5732 // deref is often used together with casts so we group the lhs expression
5798 return try transCreateNodePtrDeref(c, prefix_op_expr);5733 const group = try c.a().create(ast.Node.GroupedExpression);
5734 group.* = .{
5735 .lparen = try appendToken(c, .LParen, "("),
5736 .expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope),
5737 .rparen = try appendToken(c, .RParen, ")"),
5738 };
5739 return try transCreateNodePtrDeref(c, &group.base);
5740 },
5741 .Ampersand => {
5742 // address of is often used together with casts so we group the rhs expression
5743 const node = try transCreateNodePrefixOp(c, .AddressOf, .Ampersand, "&");
5744 const group = try c.a().create(ast.Node.GroupedExpression);
5745 group.* = .{
5746 .lparen = try appendToken(c, .LParen, "("),
5747 .expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope),
5748 .rparen = try appendToken(c, .RParen, ")"),
5749 };
5750 node.rhs = &group.base;
5751 return &node.base;
5799 },5752 },
5800 else => {5753 else => {
5801 _ = it.prev();5754 _ = it.prev();
test/translate_c.zig+5-5
...@@ -5,7 +5,7 @@ const CrossTarget = std.zig.CrossTarget;...@@ -5,7 +5,7 @@ const CrossTarget = std.zig.CrossTarget;
5pub fn addCases(cases: *tests.TranslateCContext) void {5pub fn addCases(cases: *tests.TranslateCContext) void {
6 cases.add("macro comma operator",6 cases.add("macro comma operator",
7 \\#define foo (foo, bar)7 \\#define foo (foo, bar)
8 \\#define bar(x) (x, 3, 4, 5 * 6, baz(1, 2), 2, baz(1,2))8 \\#define bar(x) (&x, +3, 4 == 4, 5 * 6, baz(1, 2), 2 % 2, baz(1,2))
9 , &[_][]const u8{9 , &[_][]const u8{
10 \\pub const foo = blk: {10 \\pub const foo = blk: {
11 \\ _ = foo;11 \\ _ = foo;
...@@ -14,12 +14,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -14,12 +14,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14 ,14 ,
15 \\pub inline fn bar(x: var) @TypeOf(baz(1, 2)) {15 \\pub inline fn bar(x: var) @TypeOf(baz(1, 2)) {
16 \\ return blk: {16 \\ return blk: {
17 \\ _ = x;17 \\ _ = &(x);
18 \\ _ = 3;18 \\ _ = 3;
19 \\ _ = 4;19 \\ _ = 4 == 4;
20 \\ _ = 5 * 6;20 \\ _ = 5 * 6;
21 \\ _ = baz(1, 2);21 \\ _ = baz(1, 2);
22 \\ _ = 2;22 \\ _ = 2 % 2;
23 \\ break :blk baz(1, 2);23 \\ break :blk baz(1, 2);
24 \\ };24 \\ };
25 \\}25 \\}
...@@ -1993,7 +1993,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1993,7 +1993,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1993 ,1993 ,
1994 \\pub const DOT = a.b;1994 \\pub const DOT = a.b;
1995 ,1995 ,
1996 \\pub const ARROW = a.*.b;1996 \\pub const ARROW = (a).*.b;
1997 });1997 });
19981998
1999 cases.add("array access",1999 cases.add("array access",