wip c to zig stuff

This commit is contained in:
Josh Wolfe 2017-09-11 19:58:14 -07:00
parent 373785ae8d
commit 6f50457b61

View File

@ -126,6 +126,13 @@ static AstNode *trans_create_node_opaque(Context *c) {
return trans_create_node_builtin_fn_call_str(c, "OpaqueType");
}
static AstNode *trans_create_node_fn_call_1(Context *c, AstNode *fn_ref_expr, AstNode *arg1) {
AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
node->data.fn_call_expr.fn_ref_expr = fn_ref_expr;
node->data.fn_call_expr.params.append(arg1);
return node;
}
static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) {
AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr);
node->data.field_access_expr.struct_expr = container;
@ -133,6 +140,10 @@ static AstNode *trans_create_node_field_access(Context *c, AstNode *container, B
return node;
}
static AstNode *trans_create_node_field_access_str(Context *c, AstNode *container, const char *field_name) {
return trans_create_node_field_access(c, container, buf_create_from_str(field_name));
}
static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {
AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
node->data.prefix_op_expr.prefix_op = op;
@ -140,6 +151,14 @@ static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *ch
return node;
}
static AstNode *trans_create_node_bin_op(Context *c, AstNode *lhs_node, BinOpType op, AstNode *rhs_node) {
AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
node->data.bin_op_expr.op1 = lhs_node;
node->data.bin_op_expr.bin_op = op;
node->data.bin_op_expr.op2 = rhs_node;
return node;
}
static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) {
AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr);
node->data.addr_of_expr.is_const = is_const;
@ -155,6 +174,13 @@ static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) {
return node;
}
static AstNode *trans_create_node_str_lit_non_c(Context *c, Buf *buf) {
AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
node->data.string_literal.buf = buf;
node->data.string_literal.c = false;
return node;
}
static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) {
AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
node->data.int_literal.bigint = allocate<BigInt>(1);
@ -286,10 +312,45 @@ static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int)
}
static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
static bool is_c_void_type(AstNode *node) {
return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
}
static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location, const QualType &qt, AstNode *expr) {
// TODO: maybe widen to increase size
// TODO: maybe bitcast to change sign
// TODO: maybe truncate to reduce size
return trans_create_node_fn_call_1(c, trans_qual_type(c, qt, source_location), expr);
}
static AstNode *qual_type_to_log2_int_ref(Context *c, const QualType &qt,
const SourceLocation &source_loc)
{
AstNode *zig_type_node = trans_qual_type(c, qt, source_loc);
// @import("std").math.Log2Int(c_long);
//
// FnCall
// FieldAccess
// FieldAccess
// FnCall (.builtin = true)
// Symbol "import"
// StringLiteral "std"
// Symbol "math"
// Symbol "Log2Int"
// zig_type_node
AstNode *import_fn_call = trans_create_node_builtin_fn_call_str(c, "import");
import_fn_call->data.fn_call_expr.params.append(trans_create_node_str_lit_non_c(c, buf_create_from_str("std")));
AstNode *inner_field_access = trans_create_node_field_access_str(c, import_fn_call, "math");
AstNode *outer_field_access = trans_create_node_field_access_str(c, inner_field_access, "Log2Int");
AstNode *log2int_fn_call = trans_create_node_fn_call_1(c, outer_field_access, zig_type_node);
return log2int_fn_call;
}
static bool qual_type_child_is_fn_proto(const QualType &qt) {
if (qt.getTypePtr()->getTypeClass() == Type::Paren) {
const ParenType *paren_type = static_cast<const ParenType *>(qt.getTypePtr());
@ -361,7 +422,6 @@ static bool c_is_float(Context *c, QualType qt) {
}
static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt);
static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
static AstNode *const skip_add_to_block_node = (AstNode *) 0x2;
static AstNode *trans_expr(Context *c, AstNode *block, Expr *expr) {
@ -877,25 +937,127 @@ static AstNode *trans_binary_operator(Context *c, AstNode *block, BinaryOperator
zig_unreachable();
}
static AstNode *trans_compound_assign_operator(Context *c, AstNode *block, CompoundAssignOperator *stmt) {
switch (stmt->getOpcode()) {
case BO_MulAssign:
emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_MulAssign");
return nullptr;
case BO_DivAssign:
emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_DivAssign");
return nullptr;
case BO_RemAssign:
emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_RemAssign");
return nullptr;
case BO_AddAssign:
emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_AddAssign");
return nullptr;
case BO_SubAssign:
emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_SubAssign");
return nullptr;
case BO_ShlAssign:
emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_ShlAssign");
return nullptr;
case BO_ShrAssign: {
BinOpType bin_op = BinOpTypeBitShiftRight;
// c: lhs >>= rhs;
// zig: {
// zig: const _ref = &lhs;
// zig: *_ref = result_type(operation_type(*_ref) >> u5(rhs));
// zig: *_ref
// zig: };
// where u5 is the appropriate type
// TODO: avoid mess when we don't need the assignment value for chained assignments or anything.
AstNode *child_block = trans_create_node(c, NodeTypeBlock);
// const _ref = &lhs;
AstNode *lhs = trans_expr(c, child_block, stmt->getLHS());
if (lhs == nullptr) return nullptr;
AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs);
// TODO: avoid name collisions with generated variable names
Buf* tmp_var_name = buf_create_from_str("_ref");
AstNode *tmp_var_decl = trans_create_node_var_decl(c, true, tmp_var_name, nullptr, addr_of_lhs);
child_block->data.block.statements.append(tmp_var_decl);
// *_ref = result_type(operation_type(*_ref) >> u5(rhs));
AstNode *rhs = trans_expr(c, child_block, stmt->getRHS());
if (rhs == nullptr) return nullptr;
const SourceLocation &rhs_location = stmt->getRHS()->getLocStart();
AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location);
AstNode *assign_statement = trans_create_node_bin_op(c,
trans_create_node_prefix_op(c, PrefixOpDereference,
trans_create_node_symbol(c, tmp_var_name)),
BinOpTypeAssign,
trans_c_cast(c, rhs_location,
stmt->getComputationResultType(),
trans_create_node_bin_op(c,
trans_c_cast(c, rhs_location,
stmt->getComputationLHSType(),
trans_create_node_prefix_op(c, PrefixOpDereference,
trans_create_node_symbol(c, tmp_var_name))),
bin_op,
trans_create_node_fn_call_1(c,
rhs_type,
rhs))));
child_block->data.block.statements.append(assign_statement);
// *_ref
child_block->data.block.statements.append(
trans_create_node_prefix_op(c, PrefixOpDereference,
trans_create_node_symbol(c, tmp_var_name)));
child_block->data.block.last_statement_is_result_expression = true;
return child_block;
}
case BO_AndAssign:
emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_AndAssign");
return nullptr;
case BO_XorAssign:
emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_XorAssign");
return nullptr;
case BO_OrAssign:
emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_OrAssign");
return nullptr;
case BO_PtrMemD:
case BO_PtrMemI:
case BO_Assign:
case BO_Mul:
case BO_Div:
case BO_Rem:
case BO_Add:
case BO_Sub:
case BO_Shl:
case BO_Shr:
case BO_LT:
case BO_GT:
case BO_LE:
case BO_GE:
case BO_EQ:
case BO_NE:
case BO_And:
case BO_Xor:
case BO_Or:
case BO_LAnd:
case BO_LOr:
case BO_Comma:
zig_panic("compound assign expected to be handled by binary operator");
}
zig_unreachable();
}
static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCastExpr *stmt) {
switch (stmt->getCastKind()) {
case CK_LValueToRValue:
return trans_expr(c, block, stmt->getSubExpr());
case CK_IntegralCast:
{
AstNode *node = trans_create_node_builtin_fn_call_str(c, "bitCast");
AstNode *result_type_node = trans_qual_type(c, stmt->getType(), stmt->getExprLoc());
if (result_type_node == nullptr)
return nullptr;
AstNode *target_node = trans_expr(c, block, stmt->getSubExpr());
if (target_node == nullptr)
return nullptr;
node->data.fn_call_expr.params.append(result_type_node);
node->data.fn_call_expr.params.append(target_node);
return node;
return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(), target_node);
}
case CK_Dependent:
emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_Dependent");
@ -1422,6 +1584,8 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {
return trans_conditional_operator(c, block, (ConditionalOperator *)stmt);
case Stmt::BinaryOperatorClass:
return trans_binary_operator(c, block, (BinaryOperator *)stmt);
case Stmt::CompoundAssignOperatorClass:
return trans_compound_assign_operator(c, block, (CompoundAssignOperator *)stmt);
case Stmt::ImplicitCastExprClass:
return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt);
case Stmt::DeclRefExprClass:
@ -1504,9 +1668,6 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {
case Stmt::AtomicExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C AtomicExprClass");
return nullptr;
case Stmt::CompoundAssignOperatorClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CompoundAssignOperatorClass");
return nullptr;
case Stmt::BlockExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C BlockExprClass");
return nullptr;