translate-c-2 macro cast
This commit is contained in:
parent
57170f9eb6
commit
ed2a19dcec
@ -25,6 +25,7 @@ pub const CToken = struct {
|
|||||||
Tilde,
|
Tilde,
|
||||||
Shl,
|
Shl,
|
||||||
Lt,
|
Lt,
|
||||||
|
Comma,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const NumLitSuffix = enum {
|
pub const NumLitSuffix = enum {
|
||||||
@ -191,6 +192,10 @@ fn next(chars: [*]const u8, i: *usize) !CToken {
|
|||||||
result.id = .Tilde;
|
result.id = .Tilde;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
',' => {
|
||||||
|
result.id = .Comma;
|
||||||
|
return result;
|
||||||
|
},
|
||||||
else => return error.TokenizingFailed,
|
else => return error.TokenizingFailed,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2039,7 +2039,7 @@ fn transCreateNodeUnwrapNull(c: *Context, wrapped: *ast.Node) !*ast.Node {
|
|||||||
_ = try appendToken(c, .Period, ".");
|
_ = try appendToken(c, .Period, ".");
|
||||||
const qm = try appendToken(c, .QuestionMark, "?");
|
const qm = try appendToken(c, .QuestionMark, "?");
|
||||||
const node = try c.a().create(ast.Node.SuffixOp);
|
const node = try c.a().create(ast.Node.SuffixOp);
|
||||||
node.* = ast.Node.SuffixOp{
|
node.* = .{
|
||||||
.op = .UnwrapOptional,
|
.op = .UnwrapOptional,
|
||||||
.lhs = .{ .node = wrapped },
|
.lhs = .{ .node = wrapped },
|
||||||
.rtoken = qm,
|
.rtoken = qm,
|
||||||
@ -2047,6 +2047,39 @@ fn transCreateNodeUnwrapNull(c: *Context, wrapped: *ast.Node) !*ast.Node {
|
|||||||
return &node.base;
|
return &node.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transCreateNodeEnumLiteral(c: *Context, name: []const u8) !*ast.Node {
|
||||||
|
const node = try c.a().create(ast.Node.EnumLiteral);
|
||||||
|
node.* = .{
|
||||||
|
.dot = try appendToken(c, .Period, "."),
|
||||||
|
.name = try appendIdentifier(c, name),
|
||||||
|
};
|
||||||
|
return &node.base;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transCreateNodeIf(c: *Context) !*ast.Node.If {
|
||||||
|
const if_tok = try appendToken(c, .Keyword_if, "if");
|
||||||
|
_ = try appendToken(c, .LParen, "(");
|
||||||
|
const node = try c.a().create(ast.Node.If);
|
||||||
|
node.* = .{
|
||||||
|
.if_token = if_tok,
|
||||||
|
.condition = undefined,
|
||||||
|
.payload = null,
|
||||||
|
.body = undefined,
|
||||||
|
.@"else" = null,
|
||||||
|
};
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transCreateNodeElse(c: *Context) !*ast.Node.Else {
|
||||||
|
const node = try c.a().create(ast.Node.Else);
|
||||||
|
node.* = .{
|
||||||
|
.else_token = try appendToken(c, .Keyword_else, "else"),
|
||||||
|
.payload = null,
|
||||||
|
.body = undefined,
|
||||||
|
};
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
const RestorePoint = struct {
|
const RestorePoint = struct {
|
||||||
c: *Context,
|
c: *Context,
|
||||||
token_index: ast.TokenIndex,
|
token_index: ast.TokenIndex,
|
||||||
@ -2722,26 +2755,102 @@ fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc:
|
|||||||
};
|
};
|
||||||
return &node.base;
|
return &node.base;
|
||||||
},
|
},
|
||||||
.Minus => {
|
|
||||||
const node = try transCreateNodePrefixOp(
|
|
||||||
rp.c,
|
|
||||||
.Negation,
|
|
||||||
.Minus,
|
|
||||||
"-",
|
|
||||||
);
|
|
||||||
node.rhs = try parseCNumLit(rp, it.next().?, source_loc);
|
|
||||||
return &node.base;
|
|
||||||
},
|
|
||||||
.NumLitInt, .NumLitFloat => {
|
.NumLitInt, .NumLitFloat => {
|
||||||
return parseCNumLit(rp, tok, source_loc);
|
return parseCNumLit(rp, tok, source_loc);
|
||||||
},
|
},
|
||||||
.Identifier => return transCreateNodeIdentifier(rp.c, tok.bytes),
|
.Identifier => return transCreateNodeIdentifier(rp.c, tok.bytes),
|
||||||
.LParen => {
|
.LParen => {
|
||||||
_ = try appendToken(rp.c, .LParen, "(");
|
|
||||||
const inner_node = try parseCExpr(rp, it, source_loc);
|
const inner_node = try parseCExpr(rp, it, source_loc);
|
||||||
_ = try appendToken(rp.c, .RParen, ")");
|
|
||||||
|
|
||||||
return inner_node; // TODO
|
// hack to get zig fmt to render a comma in builtin calls
|
||||||
|
_ = try appendToken(rp.c, .Comma, ",");
|
||||||
|
|
||||||
|
if (it.peek().?.id == .RParen) {
|
||||||
|
_ = it.next();
|
||||||
|
return inner_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
const node_to_cast = try parseCExpr(rp, it, source_loc);
|
||||||
|
|
||||||
|
if (it.next().?.id != .RParen) {
|
||||||
|
return revertAndWarn(
|
||||||
|
rp,
|
||||||
|
error.ParseError,
|
||||||
|
source_loc,
|
||||||
|
"unable to translate C expr",
|
||||||
|
.{},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (@typeId(@TypeOf(x)) == .Pointer)
|
||||||
|
// @ptrCast(dest, x)
|
||||||
|
//else if (@typeId(@TypeOf(x)) == .Integer)
|
||||||
|
// @intToPtr(dest, x)
|
||||||
|
//else
|
||||||
|
// @as(dest, x)
|
||||||
|
|
||||||
|
const if_1 = try transCreateNodeIf(rp.c);
|
||||||
|
const type_id_1 = try transCreateNodeBuiltinFnCall(rp.c, "@typeId");
|
||||||
|
const type_of_1 = try transCreateNodeBuiltinFnCall(rp.c, "@TypeOf");
|
||||||
|
try type_id_1.params.push(&type_of_1.base);
|
||||||
|
try type_of_1.params.push(node_to_cast);
|
||||||
|
type_of_1.rparen_token = try appendToken(rp.c, .LParen, ")");
|
||||||
|
type_id_1.rparen_token = try appendToken(rp.c, .LParen, ")");
|
||||||
|
|
||||||
|
const cmp_1 = try rp.c.a().create(ast.Node.InfixOp);
|
||||||
|
cmp_1.* = .{
|
||||||
|
.op_token = try appendToken(rp.c, .EqualEqual, "=="),
|
||||||
|
.lhs = &type_id_1.base,
|
||||||
|
.op = .EqualEqual,
|
||||||
|
.rhs = try transCreateNodeEnumLiteral(rp.c, "Pointer"),
|
||||||
|
};
|
||||||
|
if_1.condition = &cmp_1.base;
|
||||||
|
_ = try appendToken(rp.c, .LParen, ")");
|
||||||
|
|
||||||
|
const ptr_cast = try transCreateNodeBuiltinFnCall(rp.c, "@ptrCast");
|
||||||
|
try ptr_cast.params.push(inner_node);
|
||||||
|
try ptr_cast.params.push(node_to_cast);
|
||||||
|
ptr_cast.rparen_token = try appendToken(rp.c, .LParen, ")");
|
||||||
|
if_1.body = &ptr_cast.base;
|
||||||
|
|
||||||
|
const else_1 = try transCreateNodeElse(rp.c);
|
||||||
|
if_1.@"else" = else_1;
|
||||||
|
|
||||||
|
const if_2 = try transCreateNodeIf(rp.c);
|
||||||
|
const type_id_2 = try transCreateNodeBuiltinFnCall(rp.c, "@typeId");
|
||||||
|
const type_of_2 = try transCreateNodeBuiltinFnCall(rp.c, "@TypeOf");
|
||||||
|
try type_id_2.params.push(&type_of_2.base);
|
||||||
|
try type_of_2.params.push(node_to_cast);
|
||||||
|
type_of_2.rparen_token = try appendToken(rp.c, .LParen, ")");
|
||||||
|
type_id_2.rparen_token = try appendToken(rp.c, .LParen, ")");
|
||||||
|
|
||||||
|
const cmp_2 = try rp.c.a().create(ast.Node.InfixOp);
|
||||||
|
cmp_2.* = .{
|
||||||
|
.op_token = try appendToken(rp.c, .EqualEqual, "=="),
|
||||||
|
.lhs = &type_id_2.base,
|
||||||
|
.op = .EqualEqual,
|
||||||
|
.rhs = try transCreateNodeEnumLiteral(rp.c, "Int"),
|
||||||
|
};
|
||||||
|
if_2.condition = &cmp_2.base;
|
||||||
|
else_1.body = &if_2.base;
|
||||||
|
_ = try appendToken(rp.c, .LParen, ")");
|
||||||
|
|
||||||
|
const int_to_ptr = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr");
|
||||||
|
try int_to_ptr.params.push(inner_node);
|
||||||
|
try int_to_ptr.params.push(node_to_cast);
|
||||||
|
int_to_ptr.rparen_token = try appendToken(rp.c, .LParen, ")");
|
||||||
|
if_2.body = &int_to_ptr.base;
|
||||||
|
|
||||||
|
const else_2 = try transCreateNodeElse(rp.c);
|
||||||
|
if_2.@"else" = else_2;
|
||||||
|
|
||||||
|
const as = try transCreateNodeBuiltinFnCall(rp.c, "@as");
|
||||||
|
try as.params.push(inner_node);
|
||||||
|
try as.params.push(node_to_cast);
|
||||||
|
as.rparen_token = try appendToken(rp.c, .LParen, ")");
|
||||||
|
else_2.body = &as.base;
|
||||||
|
|
||||||
|
return &if_1.base;
|
||||||
},
|
},
|
||||||
else => return revertAndWarn(
|
else => return revertAndWarn(
|
||||||
rp,
|
rp,
|
||||||
@ -2780,6 +2889,30 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
|
|||||||
};
|
};
|
||||||
node = &access_node.base;
|
node = &access_node.base;
|
||||||
},
|
},
|
||||||
|
.Asterisk => {
|
||||||
|
if (it.peek().?.id == .RParen) {
|
||||||
|
// type *)
|
||||||
|
|
||||||
|
// hack to get zig fmt to render a comma in builtin calls
|
||||||
|
_ = try appendToken(rp.c, .Comma, ",");
|
||||||
|
|
||||||
|
const ptr = try transCreateNodePtrType(rp.c, false, false, .Identifier);
|
||||||
|
ptr.rhs = node;
|
||||||
|
return &ptr.base;
|
||||||
|
} else {
|
||||||
|
// expr * expr
|
||||||
|
const op_token = try appendToken(rp.c, .Asterisk, "*");
|
||||||
|
const rhs = try parseCPrimaryExpr(rp, it, source_loc);
|
||||||
|
const bitshift_node = try rp.c.a().create(ast.Node.InfixOp);
|
||||||
|
bitshift_node.* = .{
|
||||||
|
.op_token = op_token,
|
||||||
|
.lhs = node,
|
||||||
|
.op = .BitShiftLeft,
|
||||||
|
.rhs = rhs,
|
||||||
|
};
|
||||||
|
node = &bitshift_node.base;
|
||||||
|
}
|
||||||
|
},
|
||||||
.Shl => {
|
.Shl => {
|
||||||
const op_token = try appendToken(rp.c, .AngleBracketAngleBracketLeft, "<<");
|
const op_token = try appendToken(rp.c, .AngleBracketAngleBracketLeft, "<<");
|
||||||
const rhs = try parseCPrimaryExpr(rp, it, source_loc);
|
const rhs = try parseCPrimaryExpr(rp, it, source_loc);
|
||||||
@ -2819,6 +2952,16 @@ fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
|
|||||||
node.rhs = try parseCPrefixOpExpr(rp, it, source_loc);
|
node.rhs = try parseCPrefixOpExpr(rp, it, source_loc);
|
||||||
return &node.base;
|
return &node.base;
|
||||||
},
|
},
|
||||||
|
.Asterisk => {
|
||||||
|
const prefix_op_expr = try parseCPrefixOpExpr(rp, it, source_loc);
|
||||||
|
const node = try rp.c.a().create(ast.Node.SuffixOp);
|
||||||
|
node.* = .{
|
||||||
|
.lhs = .{ .node = prefix_op_expr },
|
||||||
|
.op = .Deref,
|
||||||
|
.rtoken = try appendToken(rp.c, .PeriodAsterisk, ".*"),
|
||||||
|
};
|
||||||
|
return &node.base;
|
||||||
|
},
|
||||||
else => {
|
else => {
|
||||||
_ = it.prev();
|
_ = it.prev();
|
||||||
return try parseCSuffixOpExpr(rp, it, source_loc);
|
return try parseCSuffixOpExpr(rp, it, source_loc);
|
||||||
@ -2833,7 +2976,7 @@ fn tokenSlice(c: *Context, token: ast.TokenIndex) []const u8 {
|
|||||||
|
|
||||||
fn getFnDecl(c: *Context, ref: *ast.Node) ?*ast.Node {
|
fn getFnDecl(c: *Context, ref: *ast.Node) ?*ast.Node {
|
||||||
const init = ref.cast(ast.Node.VarDecl).?.init_node.?;
|
const init = ref.cast(ast.Node.VarDecl).?.init_node.?;
|
||||||
const name = if (init.cast(ast.Node.Identifier)) |id|
|
const name = if (init.cast(ast.Node.Identifier)) |id|
|
||||||
tokenSlice(c, id.token)
|
tokenSlice(c, id.token)
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
|
@ -397,6 +397,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\pub const OpenGLProcs = union_OpenGLProcs;
|
\\pub const OpenGLProcs = union_OpenGLProcs;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cases.add_2("macro pointer cast",
|
||||||
|
\\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
|
||||||
|
, &[_][]const u8{
|
||||||
|
\\pub const NRF_GPIO = if (@typeId(@TypeOf(NRF_GPIO_BASE)) == .Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@TypeOf(NRF_GPIO_BASE)) == .Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);
|
||||||
|
});
|
||||||
|
|
||||||
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
|
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
|
||||||
|
|
||||||
cases.add_both("typedef of function in struct field",
|
cases.add_both("typedef of function in struct field",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user