mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
translate-c more macro ops
This commit is contained in:
parent
7df9169081
commit
83d27f71ef
@ -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();
|
||||
|
||||
@ -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",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user