Commit 83d27f71ef
Changed files (2)
src-self-hosted
test
src-self-hosted/translate_c.zig
@@ -610,7 +610,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
try transCreateNodeUndefinedLiteral(c);
} else if (storage_class != .Extern) {
eq_tok = try appendToken(c, .Equal, "=");
- init_node = try transCreateNodeTypeIdentifier(c, "undefined");
+ init_node = try transCreateNodeIdentifierUnchecked(c, "undefined");
}
const linksection_expr = blk: {
@@ -4814,7 +4814,7 @@ fn transCreateNodeIdentifier(c: *Context, name: []const u8) !*ast.Node {
return &identifier.base;
}
-fn transCreateNodeTypeIdentifier(c: *Context, name: []const u8) !*ast.Node {
+fn transCreateNodeIdentifierUnchecked(c: *Context, name: []const u8) !*ast.Node {
const token_index = try appendTokenFmt(c, .Identifier, "{}", .{name});
const identifier = try c.a().create(ast.Node.Identifier);
identifier.* = .{
@@ -5368,15 +5368,15 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
return parseCNumLit(c, tok, source, source_loc);
},
// eventually this will be replaced by std.c.parse which will handle these correctly
- .Keyword_void => return transCreateNodeTypeIdentifier(c, "c_void"),
- .Keyword_bool => return transCreateNodeTypeIdentifier(c, "bool"),
- .Keyword_double => return transCreateNodeTypeIdentifier(c, "f64"),
- .Keyword_long => return transCreateNodeTypeIdentifier(c, "c_long"),
- .Keyword_int => return transCreateNodeTypeIdentifier(c, "c_int"),
- .Keyword_float => return transCreateNodeTypeIdentifier(c, "f32"),
- .Keyword_short => return transCreateNodeTypeIdentifier(c, "c_short"),
- .Keyword_char => return transCreateNodeTypeIdentifier(c, "c_char"),
- .Keyword_unsigned => return transCreateNodeTypeIdentifier(c, "c_uint"),
+ .Keyword_void => return transCreateNodeIdentifierUnchecked(c, "c_void"),
+ .Keyword_bool => return transCreateNodeIdentifierUnchecked(c, "bool"),
+ .Keyword_double => return transCreateNodeIdentifierUnchecked(c, "f64"),
+ .Keyword_long => return transCreateNodeIdentifierUnchecked(c, "c_long"),
+ .Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_int"),
+ .Keyword_float => return transCreateNodeIdentifierUnchecked(c, "f32"),
+ .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_short"),
+ .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "c_char"),
+ .Keyword_unsigned => return transCreateNodeIdentifierUnchecked(c, "c_uint"),
.Identifier => {
const mangled_name = scope.getAlias(source[tok.start..tok.end]);
return transCreateNodeIdentifier(c, mangled_name);
@@ -5512,6 +5512,8 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
var node = try parseCPrimaryExpr(c, it, source, source_loc, scope);
while (true) {
const tok = it.next().?;
+ var op_token: ast.TokenIndex = undefined;
+ var op_id: ast.Node.InfixOp.Op = undefined;
switch (tok.id) {
.Period => {
const name_tok = it.next().?;
@@ -5528,6 +5530,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
}
node = try transCreateNodeFieldAccess(c, node, source[name_tok.start..name_tok.end]);
+ continue;
},
.Arrow => {
const name_tok = it.next().?;
@@ -5542,9 +5545,16 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
);
return error.ParseError;
}
-
- const deref = try transCreateNodePtrDeref(c, node);
+ // deref is often used together with casts so we group the lhs expression
+ const group = try c.a().create(ast.Node.GroupedExpression);
+ group.* = .{
+ .lparen = try appendToken(c, .LParen, "("),
+ .expr = node,
+ .rparen = try appendToken(c, .RParen, ")"),
+ };
+ const deref = try transCreateNodePtrDeref(c, &group.base);
node = try transCreateNodeFieldAccess(c, deref, source[name_tok.start..name_tok.end]);
+ continue;
},
.Asterisk => {
if (it.peek().?.id == .RParen) {
@@ -5568,161 +5578,57 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
return &ptr.base;
} else {
// expr * expr
- const op_token = try appendToken(c, .Asterisk, "*");
- const rhs = try parseCPrimaryExpr(c, it, source, source_loc, scope);
- const mul_node = try c.a().create(ast.Node.InfixOp);
- mul_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .BitShiftLeft,
- .rhs = rhs,
- };
- node = &mul_node.base;
+ op_token = try appendToken(c, .Asterisk, "*");
+ op_id = .BitShiftLeft;
}
},
.AngleBracketAngleBracketLeft => {
- const op_token = try appendToken(c, .AngleBracketAngleBracketLeft, "<<");
- const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const bitshift_node = try c.a().create(ast.Node.InfixOp);
- bitshift_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .BitShiftLeft,
- .rhs = rhs,
- };
- node = &bitshift_node.base;
+ op_token = try appendToken(c, .AngleBracketAngleBracketLeft, "<<");
+ op_id = .BitShiftLeft;
},
.AngleBracketAngleBracketRight => {
- const op_token = try appendToken(c, .AngleBracketAngleBracketRight, ">>");
- const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const bitshift_node = try c.a().create(ast.Node.InfixOp);
- bitshift_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .BitShiftRight,
- .rhs = rhs,
- };
- node = &bitshift_node.base;
+ op_token = try appendToken(c, .AngleBracketAngleBracketRight, ">>");
+ op_id = .BitShiftRight;
},
.Pipe => {
- const op_token = try appendToken(c, .Pipe, "|");
- const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const or_node = try c.a().create(ast.Node.InfixOp);
- or_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .BitOr,
- .rhs = rhs,
- };
- node = &or_node.base;
+ op_token = try appendToken(c, .Pipe, "|");
+ op_id = .BitOr;
},
.Ampersand => {
- const op_token = try appendToken(c, .Ampersand, "&");
- const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const bitand_node = try c.a().create(ast.Node.InfixOp);
- bitand_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .BitAnd,
- .rhs = rhs,
- };
- node = &bitand_node.base;
+ op_token = try appendToken(c, .Ampersand, "&");
+ op_id .BitAnd;
},
.Plus => {
- const op_token = try appendToken(c, .Plus, "+");
- const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const add_node = try c.a().create(ast.Node.InfixOp);
- add_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .Add,
- .rhs = rhs,
- };
- node = &add_node.base;
+ op_token = try appendToken(c, .Plus, "+");
+ op_id = .Add;
},
.Minus => {
- const op_token = try appendToken(c, .Minus, "-");
- const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const sub_node = try c.a().create(ast.Node.InfixOp);
- sub_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .Sub,
- .rhs = rhs,
- };
- node = &sub_node.base;
+ op_token = try appendToken(c, .Minus, "-");
+ op_id .Sub;
},
.AmpersandAmpersand => {
- const op_token = try appendToken(c, .Keyword_and, "and");
- const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const and_node = try c.a().create(ast.Node.InfixOp);
- and_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .BoolAnd,
- .rhs = rhs,
- };
- node = &and_node.base;
+ op_token = try appendToken(c, .Keyword_and, "and");
+ op_id = .BoolAnd;
},
.PipePipe => {
- const op_token = try appendToken(c, .Keyword_or, "or");
- const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const or_node = try c.a().create(ast.Node.InfixOp);
- or_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .BoolOr,
- .rhs = rhs,
- };
- node = &or_node.base;
+ op_token = try appendToken(c, .Keyword_or, "or");
+ op_id = .BoolOr;
},
.AngleBracketRight => {
- const op_token = try appendToken(c, .AngleBracketRight, ">");
- const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const and_node = try c.a().create(ast.Node.InfixOp);
- and_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .GreaterThan,
- .rhs = rhs,
- };
- node = &and_node.base;
+ op_token = try appendToken(c, .AngleBracketRight, ">");
+ op_id = .GreaterThan;
},
.AngleBracketRightEqual => {
- const op_token = try appendToken(c, .AngleBracketRightEqual, ">=");
- const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const and_node = try c.a().create(ast.Node.InfixOp);
- and_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .GreaterOrEqual,
- .rhs = rhs,
- };
- node = &and_node.base;
+ op_token = try appendToken(c, .AngleBracketRightEqual, ">=");
+ op_id = .GreaterOrEqual;
},
.AngleBracketLeft => {
- const op_token = try appendToken(c, .AngleBracketLeft, "<");
- const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const and_node = try c.a().create(ast.Node.InfixOp);
- and_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .LessThan,
- .rhs = rhs,
- };
- node = &and_node.base;
+ op_token = try appendToken(c, .AngleBracketLeft, "<");
+ op_id = .LessThan;
},
.AngleBracketLeftEqual => {
- const op_token = try appendToken(c, .AngleBracketLeftEqual, "<=");
- const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const and_node = try c.a().create(ast.Node.InfixOp);
- and_node.* = .{
- .op_token = op_token,
- .lhs = node,
- .op = .LessOrEqual,
- .rhs = rhs,
- };
- node = &and_node.base;
+ op_token = try appendToken(c, .AngleBracketLeftEqual, "<=");
+ op_id = .LessOrEqual;
},
.LBracket => {
const arr_node = try transCreateNodeArrayAccess(c, node);
@@ -5740,6 +5646,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
);
return error.ParseError;
}
+ continue;
},
.LParen => {
const call_node = try transCreateNodeFnCall(c, node);
@@ -5765,12 +5672,39 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
}
call_node.rtoken = try appendToken(c, .RParen, ")");
node = &call_node.base;
+ continue;
+ },
+ .BangEqual => {
+ op_token = try appendToken(c, .BangEqual, "!=");
+ op_id = .BangEqual;
+ },
+ .EqualEqual => {
+ op_token = try appendToken(c, .EqualEqual, "==");
+ op_id = .EqualEqual;
+ },
+ .Slash => {
+ // unsigned/float division uses the operator
+ op_id = .Div;
+ op_token = try appendToken(c, .Slash, "/");
+ },
+ .Percent => {
+ // unsigned/float division uses the operator
+ op_id = .Mod;
+ op_token = try appendToken(c, .Percent, "%");
},
else => {
_ = it.prev();
return node;
},
}
+ const op_node = try c.a().create(ast.Node.InfixOp);
+ op_node.* = .{
+ .op_token = op_token,
+ .lhs = node,
+ .op = op_id,
+ .rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope),
+ };
+ node = &op_node.base;
}
}
@@ -5788,14 +5722,33 @@ fn parseCPrefixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
return &node.base;
},
+ .Plus => return try parseCPrefixOpExpr(c, it, source, source_loc, scope),
.Tilde => {
const node = try transCreateNodePrefixOp(c, .BitNot, .Tilde, "~");
node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
return &node.base;
},
.Asterisk => {
- const prefix_op_expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- return try transCreateNodePtrDeref(c, prefix_op_expr);
+ // deref is often used together with casts so we group the lhs expression
+ const group = try c.a().create(ast.Node.GroupedExpression);
+ group.* = .{
+ .lparen = try appendToken(c, .LParen, "("),
+ .expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope),
+ .rparen = try appendToken(c, .RParen, ")"),
+ };
+ return try transCreateNodePtrDeref(c, &group.base);
+ },
+ .Ampersand => {
+ // address of is often used together with casts so we group the rhs expression
+ const node = try transCreateNodePrefixOp(c, .AddressOf, .Ampersand, "&");
+ const group = try c.a().create(ast.Node.GroupedExpression);
+ group.* = .{
+ .lparen = try appendToken(c, .LParen, "("),
+ .expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope),
+ .rparen = try appendToken(c, .RParen, ")"),
+ };
+ node.rhs = &group.base;
+ return &node.base;
},
else => {
_ = it.prev();
test/translate_c.zig
@@ -5,7 +5,7 @@ const CrossTarget = std.zig.CrossTarget;
pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("macro comma operator",
\\#define foo (foo, bar)
- \\#define bar(x) (x, 3, 4, 5 * 6, baz(1, 2), 2, baz(1,2))
+ \\#define bar(x) (&x, +3, 4 == 4, 5 * 6, baz(1, 2), 2 % 2, baz(1,2))
, &[_][]const u8{
\\pub const foo = blk: {
\\ _ = foo;
@@ -14,12 +14,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\pub inline fn bar(x: var) @TypeOf(baz(1, 2)) {
\\ return blk: {
- \\ _ = x;
+ \\ _ = &(x);
\\ _ = 3;
- \\ _ = 4;
+ \\ _ = 4 == 4;
\\ _ = 5 * 6;
\\ _ = baz(1, 2);
- \\ _ = 2;
+ \\ _ = 2 % 2;
\\ break :blk baz(1, 2);
\\ };
\\}
@@ -1993,7 +1993,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\pub const DOT = a.b;
,
- \\pub const ARROW = a.*.b;
+ \\pub const ARROW = (a).*.b;
});
cases.add("array access",