authorgravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2017-09-11 19:58:41-07:00
committergravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2017-09-11 19:58:41-07:00
log7e3f45a49f83fb1b9d182bcddeb0b34e49380c8f
treed4b3a265212b03f3eb25c19266d7a32f60159f69
parent4bd23aefe7c96063b31433d26b7135b890996b02
parent6f50457b61b076bee8378c083e01425f7c81c76b

Merge branch 'master' into c-to-zig


1 files changed, 175 insertions(+), 14 deletions(-)

src/parsec.cpp+175-14
...@@ -126,6 +126,13 @@ static AstNode *trans_create_node_opaque(Context *c) {...@@ -126,6 +126,13 @@ static AstNode *trans_create_node_opaque(Context *c) {
126 return trans_create_node_builtin_fn_call_str(c, "OpaqueType");126 return trans_create_node_builtin_fn_call_str(c, "OpaqueType");
127}127}
128128
129static AstNode *trans_create_node_fn_call_1(Context *c, AstNode *fn_ref_expr, AstNode *arg1) {
130 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
131 node->data.fn_call_expr.fn_ref_expr = fn_ref_expr;
132 node->data.fn_call_expr.params.append(arg1);
133 return node;
134}
135
129static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) {136static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) {
130 AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr);137 AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr);
131 node->data.field_access_expr.struct_expr = container;138 node->data.field_access_expr.struct_expr = container;
...@@ -133,6 +140,10 @@ static AstNode *trans_create_node_field_access(Context *c, AstNode *container, B...@@ -133,6 +140,10 @@ static AstNode *trans_create_node_field_access(Context *c, AstNode *container, B
133 return node;140 return node;
134}141}
135142
143static AstNode *trans_create_node_field_access_str(Context *c, AstNode *container, const char *field_name) {
144 return trans_create_node_field_access(c, container, buf_create_from_str(field_name));
145}
146
136static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {147static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {
137 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);148 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
138 node->data.prefix_op_expr.prefix_op = op;149 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...@@ -140,6 +151,14 @@ static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *ch
140 return node;151 return node;
141}152}
142153
154static AstNode *trans_create_node_bin_op(Context *c, AstNode *lhs_node, BinOpType op, AstNode *rhs_node) {
155 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
156 node->data.bin_op_expr.op1 = lhs_node;
157 node->data.bin_op_expr.bin_op = op;
158 node->data.bin_op_expr.op2 = rhs_node;
159 return node;
160}
161
143static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) {162static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) {
144 AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr);163 AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr);
145 node->data.addr_of_expr.is_const = is_const;164 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) {...@@ -155,6 +174,13 @@ static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) {
155 return node;174 return node;
156}175}
157176
177static AstNode *trans_create_node_str_lit_non_c(Context *c, Buf *buf) {
178 AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
179 node->data.string_literal.buf = buf;
180 node->data.string_literal.c = false;
181 return node;
182}
183
158static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) {184static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) {
159 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);185 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
160 node->data.int_literal.bigint = allocate<BigInt>(1);186 node->data.int_literal.bigint = allocate<BigInt>(1);
...@@ -298,10 +324,45 @@ static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int)...@@ -298,10 +324,45 @@ static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int)
298324
299}325}
300326
327static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
328
301static bool is_c_void_type(AstNode *node) {329static bool is_c_void_type(AstNode *node) {
302 return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));330 return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
303}331}
304332
333static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location, const QualType &qt, AstNode *expr) {
334 // TODO: maybe widen to increase size
335 // TODO: maybe bitcast to change sign
336 // TODO: maybe truncate to reduce size
337 return trans_create_node_fn_call_1(c, trans_qual_type(c, qt, source_location), expr);
338}
339
340static AstNode *qual_type_to_log2_int_ref(Context *c, const QualType &qt,
341 const SourceLocation &source_loc)
342{
343 AstNode *zig_type_node = trans_qual_type(c, qt, source_loc);
344
345// @import("std").math.Log2Int(c_long);
346//
347// FnCall
348// FieldAccess
349// FieldAccess
350// FnCall (.builtin = true)
351// Symbol "import"
352// StringLiteral "std"
353// Symbol "math"
354// Symbol "Log2Int"
355// zig_type_node
356
357 AstNode *import_fn_call = trans_create_node_builtin_fn_call_str(c, "import");
358 import_fn_call->data.fn_call_expr.params.append(trans_create_node_str_lit_non_c(c, buf_create_from_str("std")));
359 AstNode *inner_field_access = trans_create_node_field_access_str(c, import_fn_call, "math");
360 AstNode *outer_field_access = trans_create_node_field_access_str(c, inner_field_access, "Log2Int");
361 AstNode *log2int_fn_call = trans_create_node_fn_call_1(c, outer_field_access, zig_type_node);
362
363 return log2int_fn_call;
364}
365
305static bool qual_type_child_is_fn_proto(const QualType &qt) {366static bool qual_type_child_is_fn_proto(const QualType &qt) {
306 if (qt.getTypePtr()->getTypeClass() == Type::Paren) {367 if (qt.getTypePtr()->getTypeClass() == Type::Paren) {
307 const ParenType *paren_type = static_cast<const ParenType *>(qt.getTypePtr());368 const ParenType *paren_type = static_cast<const ParenType *>(qt.getTypePtr());
...@@ -373,7 +434,6 @@ static bool c_is_float(Context *c, QualType qt) {...@@ -373,7 +434,6 @@ static bool c_is_float(Context *c, QualType qt) {
373}434}
374435
375static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt);436static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt);
376static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
377static AstNode *const skip_add_to_block_node = (AstNode *) 0x2;437static AstNode *const skip_add_to_block_node = (AstNode *) 0x2;
378438
379static AstNode *trans_expr(Context *c, AstNode *block, Expr *expr) {439static AstNode *trans_expr(Context *c, AstNode *block, Expr *expr) {
...@@ -889,25 +949,127 @@ static AstNode *trans_binary_operator(Context *c, AstNode *block, BinaryOperator...@@ -889,25 +949,127 @@ static AstNode *trans_binary_operator(Context *c, AstNode *block, BinaryOperator
889 zig_unreachable();949 zig_unreachable();
890}950}
891951
952static AstNode *trans_compound_assign_operator(Context *c, AstNode *block, CompoundAssignOperator *stmt) {
953 switch (stmt->getOpcode()) {
954 case BO_MulAssign:
955 emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_MulAssign");
956 return nullptr;
957 case BO_DivAssign:
958 emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_DivAssign");
959 return nullptr;
960 case BO_RemAssign:
961 emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_RemAssign");
962 return nullptr;
963 case BO_AddAssign:
964 emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_AddAssign");
965 return nullptr;
966 case BO_SubAssign:
967 emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_SubAssign");
968 return nullptr;
969 case BO_ShlAssign:
970 emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_ShlAssign");
971 return nullptr;
972 case BO_ShrAssign: {
973 BinOpType bin_op = BinOpTypeBitShiftRight;
974 // c: lhs >>= rhs;
975 // zig: {
976 // zig: const _ref = &lhs;
977 // zig: *_ref = result_type(operation_type(*_ref) >> u5(rhs));
978 // zig: *_ref
979 // zig: };
980 // where u5 is the appropriate type
981
982 // TODO: avoid mess when we don't need the assignment value for chained assignments or anything.
983 AstNode *child_block = trans_create_node(c, NodeTypeBlock);
984
985 // const _ref = &lhs;
986 AstNode *lhs = trans_expr(c, child_block, stmt->getLHS());
987 if (lhs == nullptr) return nullptr;
988 AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs);
989 // TODO: avoid name collisions with generated variable names
990 Buf* tmp_var_name = buf_create_from_str("_ref");
991 AstNode *tmp_var_decl = trans_create_node_var_decl(c, true, tmp_var_name, nullptr, addr_of_lhs);
992 child_block->data.block.statements.append(tmp_var_decl);
993
994 // *_ref = result_type(operation_type(*_ref) >> u5(rhs));
995
996 AstNode *rhs = trans_expr(c, child_block, stmt->getRHS());
997 if (rhs == nullptr) return nullptr;
998 const SourceLocation &rhs_location = stmt->getRHS()->getLocStart();
999 AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location);
1000
1001 AstNode *assign_statement = trans_create_node_bin_op(c,
1002 trans_create_node_prefix_op(c, PrefixOpDereference,
1003 trans_create_node_symbol(c, tmp_var_name)),
1004 BinOpTypeAssign,
1005 trans_c_cast(c, rhs_location,
1006 stmt->getComputationResultType(),
1007 trans_create_node_bin_op(c,
1008 trans_c_cast(c, rhs_location,
1009 stmt->getComputationLHSType(),
1010 trans_create_node_prefix_op(c, PrefixOpDereference,
1011 trans_create_node_symbol(c, tmp_var_name))),
1012 bin_op,
1013 trans_create_node_fn_call_1(c,
1014 rhs_type,
1015 rhs))));
1016 child_block->data.block.statements.append(assign_statement);
1017
1018 // *_ref
1019 child_block->data.block.statements.append(
1020 trans_create_node_prefix_op(c, PrefixOpDereference,
1021 trans_create_node_symbol(c, tmp_var_name)));
1022 child_block->data.block.last_statement_is_result_expression = true;
1023
1024 return child_block;
1025 }
1026 case BO_AndAssign:
1027 emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_AndAssign");
1028 return nullptr;
1029 case BO_XorAssign:
1030 emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_XorAssign");
1031 return nullptr;
1032 case BO_OrAssign:
1033 emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_OrAssign");
1034 return nullptr;
1035 case BO_PtrMemD:
1036 case BO_PtrMemI:
1037 case BO_Assign:
1038 case BO_Mul:
1039 case BO_Div:
1040 case BO_Rem:
1041 case BO_Add:
1042 case BO_Sub:
1043 case BO_Shl:
1044 case BO_Shr:
1045 case BO_LT:
1046 case BO_GT:
1047 case BO_LE:
1048 case BO_GE:
1049 case BO_EQ:
1050 case BO_NE:
1051 case BO_And:
1052 case BO_Xor:
1053 case BO_Or:
1054 case BO_LAnd:
1055 case BO_LOr:
1056 case BO_Comma:
1057 zig_panic("compound assign expected to be handled by binary operator");
1058 }
1059
1060 zig_unreachable();
1061}
1062
892static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCastExpr *stmt) {1063static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCastExpr *stmt) {
893 switch (stmt->getCastKind()) {1064 switch (stmt->getCastKind()) {
894 case CK_LValueToRValue:1065 case CK_LValueToRValue:
895 return trans_expr(c, block, stmt->getSubExpr());1066 return trans_expr(c, block, stmt->getSubExpr());
896 case CK_IntegralCast:1067 case CK_IntegralCast:
897 {1068 {
898 AstNode *node = trans_create_node_builtin_fn_call_str(c, "bitCast");
899
900 AstNode *result_type_node = trans_qual_type(c, stmt->getType(), stmt->getExprLoc());
901 if (result_type_node == nullptr)
902 return nullptr;
903
904 AstNode *target_node = trans_expr(c, block, stmt->getSubExpr());1069 AstNode *target_node = trans_expr(c, block, stmt->getSubExpr());
905 if (target_node == nullptr)1070 if (target_node == nullptr)
906 return nullptr;1071 return nullptr;
9071072 return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(), target_node);
908 node->data.fn_call_expr.params.append(result_type_node);
909 node->data.fn_call_expr.params.append(target_node);
910 return node;
911 }1073 }
912 case CK_Dependent:1074 case CK_Dependent:
913 emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_Dependent");1075 emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_Dependent");
...@@ -1434,6 +1596,8 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {...@@ -1434,6 +1596,8 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {
1434 return trans_conditional_operator(c, block, (ConditionalOperator *)stmt);1596 return trans_conditional_operator(c, block, (ConditionalOperator *)stmt);
1435 case Stmt::BinaryOperatorClass:1597 case Stmt::BinaryOperatorClass:
1436 return trans_binary_operator(c, block, (BinaryOperator *)stmt);1598 return trans_binary_operator(c, block, (BinaryOperator *)stmt);
1599 case Stmt::CompoundAssignOperatorClass:
1600 return trans_compound_assign_operator(c, block, (CompoundAssignOperator *)stmt);
1437 case Stmt::ImplicitCastExprClass:1601 case Stmt::ImplicitCastExprClass:
1438 return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt);1602 return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt);
1439 case Stmt::DeclRefExprClass:1603 case Stmt::DeclRefExprClass:
...@@ -1516,9 +1680,6 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {...@@ -1516,9 +1680,6 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {
1516 case Stmt::AtomicExprClass:1680 case Stmt::AtomicExprClass:
1517 emit_warning(c, stmt->getLocStart(), "TODO handle C AtomicExprClass");1681 emit_warning(c, stmt->getLocStart(), "TODO handle C AtomicExprClass");
1518 return nullptr;1682 return nullptr;
1519 case Stmt::CompoundAssignOperatorClass:
1520 emit_warning(c, stmt->getLocStart(), "TODO handle C CompoundAssignOperatorClass");
1521 return nullptr;
1522 case Stmt::BlockExprClass:1683 case Stmt::BlockExprClass:
1523 emit_warning(c, stmt->getLocStart(), "TODO handle C BlockExprClass");1684 emit_warning(c, stmt->getLocStart(), "TODO handle C BlockExprClass");
1524 return nullptr;1685 return nullptr;