c-to-zig: less than, negation, ternary

This commit is contained in:
Andrew Kelley 2017-09-01 04:38:57 -04:00
parent ee9d1d0414
commit 46e9d9df51

View File

@ -276,18 +276,22 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
return get_c_int_type(c->codegen, CIntTypeLong);
case BuiltinType::LongLong:
return get_c_int_type(c->codegen, CIntTypeLongLong);
case BuiltinType::UInt128:
return c->codegen->builtin_types.entry_u128;
case BuiltinType::Int128:
return c->codegen->builtin_types.entry_i128;
case BuiltinType::Float:
return c->codegen->builtin_types.entry_f32;
case BuiltinType::Double:
return c->codegen->builtin_types.entry_f64;
case BuiltinType::Float128:
return c->codegen->builtin_types.entry_f128;
case BuiltinType::LongDouble:
return c->codegen->builtin_types.entry_c_longdouble;
case BuiltinType::WChar_U:
case BuiltinType::Char16:
case BuiltinType::Char32:
case BuiltinType::UInt128:
case BuiltinType::WChar_S:
case BuiltinType::Int128:
case BuiltinType::Half:
case BuiltinType::NullPtr:
case BuiltinType::ObjCId:
@ -338,7 +342,6 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
case BuiltinType::OCLImage2dMSAADepthRW:
case BuiltinType::OCLImage2dArrayMSAADepthRW:
case BuiltinType::OCLImage3dRW:
case BuiltinType::Float128:
case BuiltinType::OCLSampler:
case BuiltinType::OCLEvent:
case BuiltinType::OCLClkEvent:
@ -606,13 +609,70 @@ static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *de
#include "ast_render.hpp"
static AstNode * ast_trans_stmt(Context *c, Stmt *stmt);
static AstNode * ast_trans_expr(Context *c, Expr *expr) {
return ast_trans_stmt(c, expr);
static bool c_is_signed_integer(Context *c, QualType qt) {
const Type *c_type = qt.getTypePtr();
if (c_type->getTypeClass() != Type::Builtin)
return false;
const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
switch (builtin_ty->getKind()) {
case BuiltinType::SChar:
case BuiltinType::Short:
case BuiltinType::Int:
case BuiltinType::Long:
case BuiltinType::LongLong:
case BuiltinType::Int128:
case BuiltinType::WChar_S:
return true;
default:
return false;
}
}
static AstNode * ast_create_node(Context *c, const SourceRange &range, NodeType id) {
static bool c_is_unsigned_integer(Context *c, QualType qt) {
const Type *c_type = qt.getTypePtr();
if (c_type->getTypeClass() != Type::Builtin)
return false;
const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
switch (builtin_ty->getKind()) {
case BuiltinType::Char_U:
case BuiltinType::UChar:
case BuiltinType::Char_S:
case BuiltinType::UShort:
case BuiltinType::UInt:
case BuiltinType::ULong:
case BuiltinType::ULongLong:
case BuiltinType::UInt128:
case BuiltinType::WChar_U:
return true;
default:
return false;
}
}
static bool c_is_float(Context *c, QualType qt) {
const Type *c_type = qt.getTypePtr();
if (c_type->getTypeClass() != Type::Builtin)
return false;
const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
switch (builtin_ty->getKind()) {
case BuiltinType::Half:
case BuiltinType::Float:
case BuiltinType::Double:
case BuiltinType::Float128:
case BuiltinType::LongDouble:
return true;
default:
return false;
}
}
static AstNode * trans_stmt(Context *c, Stmt *stmt);
static AstNode * trans_expr(Context *c, Expr *expr) {
return trans_stmt(c, expr);
}
static AstNode * trans_create_node(Context *c, Stmt *stmt, NodeType id) {
AstNode *node = allocate<AstNode>(1);
node->type = id;
node->owner = c->import;
@ -620,22 +680,22 @@ static AstNode * ast_create_node(Context *c, const SourceRange &range, NodeType
return node;
}
static AstNode * ast_trans_compound_stmt(Context *c, CompoundStmt *stmt) {
AstNode *block_node = ast_create_node(c, stmt->getSourceRange(), NodeTypeBlock);
static AstNode * trans_compound_stmt(Context *c, CompoundStmt *stmt) {
AstNode *block_node = trans_create_node(c, stmt, NodeTypeBlock);
for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
AstNode *child_node = ast_trans_stmt(c, *it);
AstNode *child_node = trans_stmt(c, *it);
block_node->data.block.statements.append(child_node);
}
return block_node;
}
static AstNode *ast_trans_return_stmt(Context *c, ReturnStmt *stmt) {
static AstNode *trans_return_stmt(Context *c, ReturnStmt *stmt) {
Expr *value_expr = stmt->getRetValue();
if (value_expr == nullptr) {
zig_panic("TODO handle C return void");
} else {
AstNode *return_node = ast_create_node(c, stmt->getSourceRange(), NodeTypeReturnExpr);
return_node->data.return_expr.expr = ast_trans_expr(c, value_expr);
AstNode *return_node = trans_create_node(c, stmt, NodeTypeReturnExpr);
return_node->data.return_expr.expr = trans_expr(c, value_expr);
return return_node;
}
}
@ -656,8 +716,9 @@ static void aps_int_to_bigint(Context *c, const llvm::APSInt &aps_int, BigInt *b
}
}
}
static AstNode * ast_trans_integer_literal(Context *c, IntegerLiteral *stmt) {
AstNode *node = ast_create_node(c, stmt->getSourceRange(), NodeTypeIntLiteral);
static AstNode * trans_integer_literal(Context *c, IntegerLiteral *stmt) {
AstNode *node = trans_create_node(c, stmt, NodeTypeIntLiteral);
llvm::APSInt result;
if (!stmt->EvaluateAsInt(result, *c->ctx)) {
fprintf(stderr, "TODO unable to convert integer literal to zig\n");
@ -667,15 +728,305 @@ static AstNode * ast_trans_integer_literal(Context *c, IntegerLiteral *stmt) {
return node;
}
static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) {
static AstNode * trans_conditional_operator(Context *c, ConditionalOperator *stmt) {
AstNode *node = trans_create_node(c, stmt, NodeTypeIfBoolExpr);
Expr *cond_expr = stmt->getCond();
Expr *true_expr = stmt->getTrueExpr();
Expr *false_expr = stmt->getFalseExpr();
node->data.if_bool_expr.condition = trans_expr(c, cond_expr);
node->data.if_bool_expr.then_block = trans_expr(c, true_expr);
node->data.if_bool_expr.else_node = trans_expr(c, false_expr);
return node;
}
static AstNode * trans_binary_operator(Context *c, BinaryOperator *stmt) {
switch (stmt->getOpcode()) {
case BO_PtrMemD:
zig_panic("TODO handle more C binary operators: BO_PtrMemD");
case BO_PtrMemI:
zig_panic("TODO handle more C binary operators: BO_PtrMemI");
case BO_Mul:
zig_panic("TODO handle more C binary operators: BO_Mul");
case BO_Div:
zig_panic("TODO handle more C binary operators: BO_Div");
case BO_Rem:
zig_panic("TODO handle more C binary operators: BO_Rem");
case BO_Add:
zig_panic("TODO handle more C binary operators: BO_Add");
case BO_Sub:
zig_panic("TODO handle more C binary operators: BO_Sub");
case BO_Shl:
zig_panic("TODO handle more C binary operators: BO_Shl");
case BO_Shr:
zig_panic("TODO handle more C binary operators: BO_Shr");
case BO_LT:
{
AstNode *node = trans_create_node(c, stmt, NodeTypeBinOpExpr);
node->data.bin_op_expr.bin_op = BinOpTypeCmpLessThan;
node->data.bin_op_expr.op1 = trans_expr(c, stmt->getLHS());
node->data.bin_op_expr.op2 = trans_expr(c, stmt->getRHS());
return node;
}
case BO_GT:
zig_panic("TODO handle more C binary operators: BO_GT");
case BO_LE:
zig_panic("TODO handle more C binary operators: BO_LE");
case BO_GE:
zig_panic("TODO handle more C binary operators: BO_GE");
case BO_EQ:
zig_panic("TODO handle more C binary operators: BO_EQ");
case BO_NE:
zig_panic("TODO handle more C binary operators: BO_NE");
case BO_And:
zig_panic("TODO handle more C binary operators: BO_And");
case BO_Xor:
zig_panic("TODO handle more C binary operators: BO_Xor");
case BO_Or:
zig_panic("TODO handle more C binary operators: BO_Or");
case BO_LAnd:
zig_panic("TODO handle more C binary operators: BO_LAnd");
case BO_LOr:
zig_panic("TODO handle more C binary operators: BO_LOr");
case BO_Assign:
zig_panic("TODO handle more C binary operators: BO_Assign");
case BO_MulAssign:
zig_panic("TODO handle more C binary operators: BO_MulAssign");
case BO_DivAssign:
zig_panic("TODO handle more C binary operators: BO_DivAssign");
case BO_RemAssign:
zig_panic("TODO handle more C binary operators: BO_RemAssign");
case BO_AddAssign:
zig_panic("TODO handle more C binary operators: BO_AddAssign");
case BO_SubAssign:
zig_panic("TODO handle more C binary operators: BO_SubAssign");
case BO_ShlAssign:
zig_panic("TODO handle more C binary operators: BO_ShlAssign");
case BO_ShrAssign:
zig_panic("TODO handle more C binary operators: BO_ShrAssign");
case BO_AndAssign:
zig_panic("TODO handle more C binary operators: BO_AndAssign");
case BO_XorAssign:
zig_panic("TODO handle more C binary operators: BO_XorAssign");
case BO_OrAssign:
zig_panic("TODO handle more C binary operators: BO_OrAssign");
case BO_Comma:
zig_panic("TODO handle more C binary operators: BO_Comma");
}
zig_unreachable();
}
static AstNode * trans_implicit_cast_expr(Context *c, ImplicitCastExpr *stmt) {
switch (stmt->getCastKind()) {
case CK_LValueToRValue:
return trans_expr(c, stmt->getSubExpr());
case CK_Dependent:
zig_panic("TODO handle C translation cast CK_Dependent");
case CK_BitCast:
zig_panic("TODO handle C translation cast CK_BitCast");
case CK_LValueBitCast:
zig_panic("TODO handle C translation cast CK_LValueBitCast");
case CK_NoOp:
zig_panic("TODO handle C translation cast CK_NoOp");
case CK_BaseToDerived:
zig_panic("TODO handle C translation cast CK_BaseToDerived");
case CK_DerivedToBase:
zig_panic("TODO handle C translation cast CK_DerivedToBase");
case CK_UncheckedDerivedToBase:
zig_panic("TODO handle C translation cast CK_UncheckedDerivedToBase");
case CK_Dynamic:
zig_panic("TODO handle C translation cast CK_Dynamic");
case CK_ToUnion:
zig_panic("TODO handle C translation cast CK_ToUnion");
case CK_ArrayToPointerDecay:
zig_panic("TODO handle C translation cast CK_ArrayToPointerDecay");
case CK_FunctionToPointerDecay:
zig_panic("TODO handle C translation cast CK_FunctionToPointerDecay");
case CK_NullToPointer:
zig_panic("TODO handle C translation cast CK_NullToPointer");
case CK_NullToMemberPointer:
zig_panic("TODO handle C translation cast CK_NullToMemberPointer");
case CK_BaseToDerivedMemberPointer:
zig_panic("TODO handle C translation cast CK_BaseToDerivedMemberPointer");
case CK_DerivedToBaseMemberPointer:
zig_panic("TODO handle C translation cast CK_DerivedToBaseMemberPointer");
case CK_MemberPointerToBoolean:
zig_panic("TODO handle C translation cast CK_MemberPointerToBoolean");
case CK_ReinterpretMemberPointer:
zig_panic("TODO handle C translation cast CK_ReinterpretMemberPointer");
case CK_UserDefinedConversion:
zig_panic("TODO handle C translation cast CK_UserDefinedConversion");
case CK_ConstructorConversion:
zig_panic("TODO handle C translation cast CK_ConstructorConversion");
case CK_IntegralToPointer:
zig_panic("TODO handle C translation cast CK_IntegralToPointer");
case CK_PointerToIntegral:
zig_panic("TODO handle C translation cast CK_PointerToIntegral");
case CK_PointerToBoolean:
zig_panic("TODO handle C translation cast CK_PointerToBoolean");
case CK_ToVoid:
zig_panic("TODO handle C translation cast CK_ToVoid");
case CK_VectorSplat:
zig_panic("TODO handle C translation cast CK_VectorSplat");
case CK_IntegralCast:
zig_panic("TODO handle C translation cast CK_IntegralCast");
case CK_IntegralToBoolean:
zig_panic("TODO handle C translation cast CK_IntegralToBoolean");
case CK_IntegralToFloating:
zig_panic("TODO handle C translation cast CK_IntegralToFloating");
case CK_FloatingToIntegral:
zig_panic("TODO handle C translation cast CK_FloatingToIntegral");
case CK_FloatingToBoolean:
zig_panic("TODO handle C translation cast CK_FloatingToBoolean");
case CK_BooleanToSignedIntegral:
zig_panic("TODO handle C translation cast CK_BooleanToSignedIntegral");
case CK_FloatingCast:
zig_panic("TODO handle C translation cast CK_FloatingCast");
case CK_CPointerToObjCPointerCast:
zig_panic("TODO handle C translation cast CK_CPointerToObjCPointerCast");
case CK_BlockPointerToObjCPointerCast:
zig_panic("TODO handle C translation cast CK_BlockPointerToObjCPointerCast");
case CK_AnyPointerToBlockPointerCast:
zig_panic("TODO handle C translation cast CK_AnyPointerToBlockPointerCast");
case CK_ObjCObjectLValueCast:
zig_panic("TODO handle C translation cast CK_ObjCObjectLValueCast");
case CK_FloatingRealToComplex:
zig_panic("TODO handle C translation cast CK_FloatingRealToComplex");
case CK_FloatingComplexToReal:
zig_panic("TODO handle C translation cast CK_FloatingComplexToReal");
case CK_FloatingComplexToBoolean:
zig_panic("TODO handle C translation cast CK_FloatingComplexToBoolean");
case CK_FloatingComplexCast:
zig_panic("TODO handle C translation cast CK_FloatingComplexCast");
case CK_FloatingComplexToIntegralComplex:
zig_panic("TODO handle C translation cast CK_FloatingComplexToIntegralComplex");
case CK_IntegralRealToComplex:
zig_panic("TODO handle C translation cast CK_IntegralRealToComplex");
case CK_IntegralComplexToReal:
zig_panic("TODO handle C translation cast CK_IntegralComplexToReal");
case CK_IntegralComplexToBoolean:
zig_panic("TODO handle C translation cast CK_IntegralComplexToBoolean");
case CK_IntegralComplexCast:
zig_panic("TODO handle C translation cast CK_IntegralComplexCast");
case CK_IntegralComplexToFloatingComplex:
zig_panic("TODO handle C translation cast CK_IntegralComplexToFloatingComplex");
case CK_ARCProduceObject:
zig_panic("TODO handle C translation cast CK_ARCProduceObject");
case CK_ARCConsumeObject:
zig_panic("TODO handle C translation cast CK_ARCConsumeObject");
case CK_ARCReclaimReturnedObject:
zig_panic("TODO handle C translation cast CK_ARCReclaimReturnedObject");
case CK_ARCExtendBlockObject:
zig_panic("TODO handle C translation cast CK_ARCExtendBlockObject");
case CK_AtomicToNonAtomic:
zig_panic("TODO handle C translation cast CK_AtomicToNonAtomic");
case CK_NonAtomicToAtomic:
zig_panic("TODO handle C translation cast CK_NonAtomicToAtomic");
case CK_CopyAndAutoreleaseBlockObject:
zig_panic("TODO handle C translation cast CK_CopyAndAutoreleaseBlockObject");
case CK_BuiltinFnToFnPtr:
zig_panic("TODO handle C translation cast CK_BuiltinFnToFnPtr");
case CK_ZeroToOCLEvent:
zig_panic("TODO handle C translation cast CK_ZeroToOCLEvent");
case CK_ZeroToOCLQueue:
zig_panic("TODO handle C translation cast CK_ZeroToOCLQueue");
case CK_AddressSpaceConversion:
zig_panic("TODO handle C translation cast CK_AddressSpaceConversion");
case CK_IntToOCLSampler:
zig_panic("TODO handle C translation cast CK_IntToOCLSampler");
}
zig_unreachable();
}
static AstNode * trans_decl_ref_expr(Context *c, DeclRefExpr *stmt) {
ValueDecl *value_decl = stmt->getDecl();
const char *name = decl_name(value_decl);
AstNode *node = trans_create_node(c, stmt, NodeTypeSymbol);
node->data.symbol_expr.symbol = buf_create_from_str(name);
return node;
}
static AstNode * trans_create_num_lit_node_unsigned(Context *c, Stmt *stmt, uint64_t x) {
AstNode *node = trans_create_node(c, stmt, NodeTypeIntLiteral);
node->data.int_literal.bigint = allocate<BigInt>(1);
bigint_init_unsigned(node->data.int_literal.bigint, x);
return node;
}
static AstNode * trans_unary_operator(Context *c, UnaryOperator *stmt) {
switch (stmt->getOpcode()) {
case UO_PostInc:
zig_panic("TODO handle C translation UO_PostInc");
case UO_PostDec:
zig_panic("TODO handle C translation UO_PostDec");
case UO_PreInc:
zig_panic("TODO handle C translation UO_PreInc");
case UO_PreDec:
zig_panic("TODO handle C translation UO_PreDec");
case UO_AddrOf:
zig_panic("TODO handle C translation UO_AddrOf");
case UO_Deref:
zig_panic("TODO handle C translation UO_Deref");
case UO_Plus:
zig_panic("TODO handle C translation UO_Plus");
case UO_Minus:
{
Expr *op_expr = stmt->getSubExpr();
if (c_is_signed_integer(c, op_expr->getType()) || c_is_float(c, op_expr->getType())) {
AstNode *node = trans_create_node(c, stmt, NodeTypePrefixOpExpr);
node->data.prefix_op_expr.prefix_op = PrefixOpNegation;
node->data.prefix_op_expr.primary_expr = trans_expr(c, op_expr);
return node;
} else if (c_is_unsigned_integer(c, op_expr->getType())) {
// we gotta emit 0 -% x
AstNode *node = trans_create_node(c, stmt, NodeTypeBinOpExpr);
node->data.bin_op_expr.op1 = trans_create_num_lit_node_unsigned(c, stmt, 0);
node->data.bin_op_expr.op2 = trans_expr(c, op_expr);
node->data.bin_op_expr.bin_op = BinOpTypeSubWrap;
return node;
} else {
zig_panic("TODO translate C negation with non float non integer");
}
}
case UO_Not:
zig_panic("TODO handle C translation UO_Not");
case UO_LNot:
zig_panic("TODO handle C translation UO_LNot");
case UO_Real:
zig_panic("TODO handle C translation UO_Real");
case UO_Imag:
zig_panic("TODO handle C translation UO_Imag");
case UO_Extension:
zig_panic("TODO handle C translation UO_Extension");
case UO_Coawait:
zig_panic("TODO handle C translation UO_Coawait");
}
zig_unreachable();
}
static AstNode *trans_stmt(Context *c, Stmt *stmt) {
Stmt::StmtClass sc = stmt->getStmtClass();
switch (sc) {
case Stmt::ReturnStmtClass:
return ast_trans_return_stmt(c, (ReturnStmt *)stmt);
return trans_return_stmt(c, (ReturnStmt *)stmt);
case Stmt::CompoundStmtClass:
return ast_trans_compound_stmt(c, (CompoundStmt *)stmt);
return trans_compound_stmt(c, (CompoundStmt *)stmt);
case Stmt::IntegerLiteralClass:
return ast_trans_integer_literal(c, (IntegerLiteral *)stmt);
return trans_integer_literal(c, (IntegerLiteral *)stmt);
case Stmt::ConditionalOperatorClass:
return trans_conditional_operator(c, (ConditionalOperator *)stmt);
case Stmt::BinaryOperatorClass:
return trans_binary_operator(c, (BinaryOperator *)stmt);
case Stmt::ImplicitCastExprClass:
return trans_implicit_cast_expr(c, (ImplicitCastExpr *)stmt);
case Stmt::DeclRefExprClass:
return trans_decl_ref_expr(c, (DeclRefExpr *)stmt);
case Stmt::UnaryOperatorClass:
return trans_unary_operator(c, (UnaryOperator *)stmt);
case Stmt::CaseStmtClass:
zig_panic("TODO handle C CaseStmtClass");
case Stmt::DefaultStmtClass:
@ -714,8 +1065,6 @@ static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) {
zig_panic("TODO handle C DoStmtClass");
case Stmt::BinaryConditionalOperatorClass:
zig_panic("TODO handle C BinaryConditionalOperatorClass");
case Stmt::ConditionalOperatorClass:
zig_panic("TODO handle C ConditionalOperatorClass");
case Stmt::AddrLabelExprClass:
zig_panic("TODO handle C AddrLabelExprClass");
case Stmt::ArrayInitIndexExprClass:
@ -730,8 +1079,6 @@ static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) {
zig_panic("TODO handle C AsTypeExprClass");
case Stmt::AtomicExprClass:
zig_panic("TODO handle C AtomicExprClass");
case Stmt::BinaryOperatorClass:
zig_panic("TODO handle C BinaryOperatorClass");
case Stmt::CompoundAssignOperatorClass:
zig_panic("TODO handle C CompoundAssignOperatorClass");
case Stmt::BlockExprClass:
@ -802,8 +1149,6 @@ static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) {
zig_panic("TODO handle C CXXStaticCastExprClass");
case Stmt::ObjCBridgedCastExprClass:
zig_panic("TODO handle C ObjCBridgedCastExprClass");
case Stmt::ImplicitCastExprClass:
zig_panic("TODO handle C ImplicitCastExprClass");
case Stmt::CharacterLiteralClass:
zig_panic("TODO handle C CharacterLiteralClass");
case Stmt::ChooseExprClass:
@ -816,8 +1161,6 @@ static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) {
zig_panic("TODO handle C CoawaitExprClass");
case Stmt::CoyieldExprClass:
zig_panic("TODO handle C CoyieldExprClass");
case Stmt::DeclRefExprClass:
zig_panic("TODO handle C DeclRefExprClass");
case Stmt::DependentCoawaitExprClass:
zig_panic("TODO handle C DependentCoawaitExprClass");
case Stmt::DependentScopeDeclRefExprClass:
@ -926,8 +1269,6 @@ static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) {
zig_panic("TODO handle C TypoExprClass");
case Stmt::UnaryExprOrTypeTraitExprClass:
zig_panic("TODO handle C UnaryExprOrTypeTraitExprClass");
case Stmt::UnaryOperatorClass:
zig_panic("TODO handle C UnaryOperatorClass");
case Stmt::VAArgExprClass:
zig_panic("TODO handle C VAArgExprClass");
case Stmt::ForStmtClass:
@ -1070,7 +1411,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
if (fn_decl->hasBody()) {
fprintf(stderr, "fn %s\n", buf_ptr(fn_name));
Stmt *body = fn_decl->getBody();
AstNode *body_node = ast_trans_stmt(c, body);
AstNode *body_node = trans_stmt(c, body);
ast_render(c->codegen, stderr, body_node, 4);
fprintf(stderr, "\n");
}