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 {
610610 try transCreateNodeUndefinedLiteral(c);
611611 } else if (storage_class != .Extern) {
612612 eq_tok = try appendToken(c, .Equal, "=");
613 init_node = try transCreateNodeTypeIdentifier(c, "undefined");
613 init_node = try transCreateNodeIdentifierUnchecked(c, "undefined");
614614 }
615615
616616 const linksection_expr = blk: {
......@@ -4814,7 +4814,7 @@ fn transCreateNodeIdentifier(c: *Context, name: []const u8) !*ast.Node {
48144814 return &identifier.base;
48154815}
48164816
4817fn transCreateNodeTypeIdentifier(c: *Context, name: []const u8) !*ast.Node {
4817fn transCreateNodeIdentifierUnchecked(c: *Context, name: []const u8) !*ast.Node {
48184818 const token_index = try appendTokenFmt(c, .Identifier, "{}", .{name});
48194819 const identifier = try c.a().create(ast.Node.Identifier);
48204820 identifier.* = .{
......@@ -5368,15 +5368,15 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
53685368 return parseCNumLit(c, tok, source, source_loc);
53695369 },
53705370 // eventually this will be replaced by std.c.parse which will handle these correctly
5371 .Keyword_void => return transCreateNodeTypeIdentifier(c, "c_void"),
5372 .Keyword_bool => return transCreateNodeTypeIdentifier(c, "bool"),
5373 .Keyword_double => return transCreateNodeTypeIdentifier(c, "f64"),
5374 .Keyword_long => return transCreateNodeTypeIdentifier(c, "c_long"),
5375 .Keyword_int => return transCreateNodeTypeIdentifier(c, "c_int"),
5376 .Keyword_float => return transCreateNodeTypeIdentifier(c, "f32"),
5377 .Keyword_short => return transCreateNodeTypeIdentifier(c, "c_short"),
5378 .Keyword_char => return transCreateNodeTypeIdentifier(c, "c_char"),
5379 .Keyword_unsigned => return transCreateNodeTypeIdentifier(c, "c_uint"),
5371 .Keyword_void => return transCreateNodeIdentifierUnchecked(c, "c_void"),
5372 .Keyword_bool => return transCreateNodeIdentifierUnchecked(c, "bool"),
5373 .Keyword_double => return transCreateNodeIdentifierUnchecked(c, "f64"),
5374 .Keyword_long => return transCreateNodeIdentifierUnchecked(c, "c_long"),
5375 .Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_int"),
5376 .Keyword_float => return transCreateNodeIdentifierUnchecked(c, "f32"),
5377 .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_short"),
5378 .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "c_char"),
5379 .Keyword_unsigned => return transCreateNodeIdentifierUnchecked(c, "c_uint"),
53805380 .Identifier => {
53815381 const mangled_name = scope.getAlias(source[tok.start..tok.end]);
53825382 return transCreateNodeIdentifier(c, mangled_name);
......@@ -5512,6 +5512,8 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
55125512 var node = try parseCPrimaryExpr(c, it, source, source_loc, scope);
55135513 while (true) {
55145514 const tok = it.next().?;
5515 var op_token: ast.TokenIndex = undefined;
5516 var op_id: ast.Node.InfixOp.Op = undefined;
55155517 switch (tok.id) {
55165518 .Period => {
55175519 const name_tok = it.next().?;
......@@ -5528,6 +5530,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
55285530 }
55295531
55305532 node = try transCreateNodeFieldAccess(c, node, source[name_tok.start..name_tok.end]);
5533 continue;
55315534 },
55325535 .Arrow => {
55335536 const name_tok = it.next().?;
......@@ -5542,9 +5545,16 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
55425545 );
55435546 return error.ParseError;
55445547 }
5545
5546 const deref = try transCreateNodePtrDeref(c, node);
5548 // deref is often used together with casts so we group the lhs expression
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);
55475556 node = try transCreateNodeFieldAccess(c, deref, source[name_tok.start..name_tok.end]);
5557 continue;
55485558 },
55495559 .Asterisk => {
55505560 if (it.peek().?.id == .RParen) {
......@@ -5568,161 +5578,57 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
55685578 return &ptr.base;
55695579 } else {
55705580 // expr * expr
5571 const op_token = try appendToken(c, .Asterisk, "*");
5572 const rhs = try parseCPrimaryExpr(c, it, source, source_loc, scope);
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 op_token = try appendToken(c, .Asterisk, "*");
5582 op_id = .BitShiftLeft;
55815583 }
55825584 },
55835585 .AngleBracketAngleBracketLeft => {
5584 const op_token = try appendToken(c, .AngleBracketAngleBracketLeft, "<<");
5585 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
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;
5586 op_token = try appendToken(c, .AngleBracketAngleBracketLeft, "<<");
5587 op_id = .BitShiftLeft;
55945588 },
55955589 .AngleBracketAngleBracketRight => {
5596 const op_token = try appendToken(c, .AngleBracketAngleBracketRight, ">>");
5597 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
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;
5590 op_token = try appendToken(c, .AngleBracketAngleBracketRight, ">>");
5591 op_id = .BitShiftRight;
56065592 },
56075593 .Pipe => {
5608 const op_token = try appendToken(c, .Pipe, "|");
5609 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
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;
5594 op_token = try appendToken(c, .Pipe, "|");
5595 op_id = .BitOr;
56185596 },
56195597 .Ampersand => {
5620 const op_token = try appendToken(c, .Ampersand, "&");
5621 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
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;
5598 op_token = try appendToken(c, .Ampersand, "&");
5599 op_id .BitAnd;
56305600 },
56315601 .Plus => {
5632 const op_token = try appendToken(c, .Plus, "+");
5633 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
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;
5602 op_token = try appendToken(c, .Plus, "+");
5603 op_id = .Add;
56425604 },
56435605 .Minus => {
5644 const op_token = try appendToken(c, .Minus, "-");
5645 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
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;
5606 op_token = try appendToken(c, .Minus, "-");
5607 op_id .Sub;
56545608 },
56555609 .AmpersandAmpersand => {
5656 const op_token = try appendToken(c, .Keyword_and, "and");
5657 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
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;
5610 op_token = try appendToken(c, .Keyword_and, "and");
5611 op_id = .BoolAnd;
56665612 },
56675613 .PipePipe => {
5668 const op_token = try appendToken(c, .Keyword_or, "or");
5669 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
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;
5614 op_token = try appendToken(c, .Keyword_or, "or");
5615 op_id = .BoolOr;
56785616 },
56795617 .AngleBracketRight => {
5680 const op_token = try appendToken(c, .AngleBracketRight, ">");
5681 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
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;
5618 op_token = try appendToken(c, .AngleBracketRight, ">");
5619 op_id = .GreaterThan;
56905620 },
56915621 .AngleBracketRightEqual => {
5692 const op_token = try appendToken(c, .AngleBracketRightEqual, ">=");
5693 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
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;
5622 op_token = try appendToken(c, .AngleBracketRightEqual, ">=");
5623 op_id = .GreaterOrEqual;
57025624 },
57035625 .AngleBracketLeft => {
5704 const op_token = try appendToken(c, .AngleBracketLeft, "<");
5705 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
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;
5626 op_token = try appendToken(c, .AngleBracketLeft, "<");
5627 op_id = .LessThan;
57145628 },
57155629 .AngleBracketLeftEqual => {
5716 const op_token = try appendToken(c, .AngleBracketLeftEqual, "<=");
5717 const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
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;
5630 op_token = try appendToken(c, .AngleBracketLeftEqual, "<=");
5631 op_id = .LessOrEqual;
57265632 },
57275633 .LBracket => {
57285634 const arr_node = try transCreateNodeArrayAccess(c, node);
......@@ -5740,6 +5646,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
57405646 );
57415647 return error.ParseError;
57425648 }
5649 continue;
57435650 },
57445651 .LParen => {
57455652 const call_node = try transCreateNodeFnCall(c, node);
......@@ -5765,12 +5672,39 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
57655672 }
57665673 call_node.rtoken = try appendToken(c, .RParen, ")");
57675674 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, "%");
57685694 },
57695695 else => {
57705696 _ = it.prev();
57715697 return node;
57725698 },
57735699 }
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;
57745708 }
57755709}
57765710
......@@ -5788,14 +5722,33 @@ fn parseCPrefixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
57885722 node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
57895723 return &node.base;
57905724 },
5725 .Plus => return try parseCPrefixOpExpr(c, it, source, source_loc, scope),
57915726 .Tilde => {
57925727 const node = try transCreateNodePrefixOp(c, .BitNot, .Tilde, "~");
57935728 node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
57945729 return &node.base;
57955730 },
57965731 .Asterisk => {
5797 const prefix_op_expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
5798 return try transCreateNodePtrDeref(c, prefix_op_expr);
5732 // deref is often used together with casts so we group the lhs expression
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;
57995752 },
58005753 else => {
58015754 _ = it.prev();
test/translate_c.zig+5-5
......@@ -5,7 +5,7 @@ const CrossTarget = std.zig.CrossTarget;
55pub fn addCases(cases: *tests.TranslateCContext) void {
66 cases.add("macro comma operator",
77 \\#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))
99 , &[_][]const u8{
1010 \\pub const foo = blk: {
1111 \\ _ = foo;
......@@ -14,12 +14,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1414 ,
1515 \\pub inline fn bar(x: var) @TypeOf(baz(1, 2)) {
1616 \\ return blk: {
17 \\ _ = x;
17 \\ _ = &(x);
1818 \\ _ = 3;
19 \\ _ = 4;
19 \\ _ = 4 == 4;
2020 \\ _ = 5 * 6;
2121 \\ _ = baz(1, 2);
22 \\ _ = 2;
22 \\ _ = 2 % 2;
2323 \\ break :blk baz(1, 2);
2424 \\ };
2525 \\}
......@@ -1993,7 +1993,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
19931993 ,
19941994 \\pub const DOT = a.b;
19951995 ,
1996 \\pub const ARROW = a.*.b;
1996 \\pub const ARROW = (a).*.b;
19971997 });
19981998
19991999 cases.add("array access",