| ... | @@ -942,19 +942,52 @@ static AstNode *trans_create_bin_op(Context *c, AstNode *block, Expr *lhs, BinOp | ... | @@ -942,19 +942,52 @@ static AstNode *trans_create_bin_op(Context *c, AstNode *block, Expr *lhs, BinOp |
| 942 | return node; | 942 | return node; |
| 943 | } | 943 | } |
| 944 | | 944 | |
| 945 | static AstNode *trans_create_assign(Context *c, AstNode *block, Expr *lhs, Expr *rhs) { | 945 | static AstNode *trans_create_assign(Context *c, bool result_used, AstNode *block, Expr *lhs, Expr *rhs) { |
| 946 | AstNode *node = trans_create_node(c, NodeTypeBinOpExpr); | 946 | if (!result_used) { |
| 947 | node->data.bin_op_expr.bin_op = BinOpTypeAssign; | 947 | // common case |
| | 948 | AstNode *node = trans_create_node(c, NodeTypeBinOpExpr); |
| | 949 | node->data.bin_op_expr.bin_op = BinOpTypeAssign; |
| 948 | | 950 | |
| 949 | node->data.bin_op_expr.op1 = trans_expr(c, true, block, lhs, TransLValue); | 951 | node->data.bin_op_expr.op1 = trans_expr(c, true, block, lhs, TransLValue); |
| 950 | if (node->data.bin_op_expr.op1 == nullptr) | 952 | if (node->data.bin_op_expr.op1 == nullptr) |
| 951 | return nullptr; | 953 | return nullptr; |
| 952 | | 954 | |
| 953 | node->data.bin_op_expr.op2 = trans_expr(c, true, block, rhs, TransRValue); | 955 | node->data.bin_op_expr.op2 = trans_expr(c, true, block, rhs, TransRValue); |
| 954 | if (node->data.bin_op_expr.op2 == nullptr) | 956 | if (node->data.bin_op_expr.op2 == nullptr) |
| 955 | return nullptr; | 957 | return nullptr; |
| 956 | | 958 | |
| 957 | return node; | 959 | return node; |
| | 960 | } else { |
| | 961 | // worst case |
| | 962 | // c: lhs = rhs |
| | 963 | // zig: { |
| | 964 | // zig: const _tmp = rhs; |
| | 965 | // zig: lhs = _tmp; |
| | 966 | // zig: _tmp |
| | 967 | // zig: } |
| | 968 | |
| | 969 | AstNode *child_block = trans_create_node(c, NodeTypeBlock); |
| | 970 | |
| | 971 | // const _tmp = rhs; |
| | 972 | AstNode *rhs_node = trans_expr(c, true, child_block, rhs, TransRValue); |
| | 973 | if (rhs_node == nullptr) return nullptr; |
| | 974 | // TODO: avoid name collisions with generated variable names |
| | 975 | Buf* tmp_var_name = buf_create_from_str("_tmp"); |
| | 976 | AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, rhs_node); |
| | 977 | child_block->data.block.statements.append(tmp_var_decl); |
| | 978 | |
| | 979 | // lhs = _tmp; |
| | 980 | AstNode *lhs_node = trans_expr(c, true, child_block, lhs, TransLValue); |
| | 981 | if (lhs_node == nullptr) return nullptr; |
| | 982 | child_block->data.block.statements.append( |
| | 983 | trans_create_node_bin_op(c, lhs_node, BinOpTypeAssign, |
| | 984 | trans_create_node_symbol(c, tmp_var_name))); |
| | 985 | |
| | 986 | // _tmp |
| | 987 | child_block->data.block.statements.append(trans_create_node_symbol(c, tmp_var_name)); |
| | 988 | |
| | 989 | return child_block; |
| | 990 | } |
| 958 | } | 991 | } |
| 959 | | 992 | |
| 960 | static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *block, BinaryOperator *stmt) { | 993 | static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *block, BinaryOperator *stmt) { |
| ... | @@ -1037,11 +1070,7 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo | ... | @@ -1037,11 +1070,7 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo |
| 1037 | // TODO: int vs bool | 1070 | // TODO: int vs bool |
| 1038 | return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS()); | 1071 | return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS()); |
| 1039 | case BO_Assign: | 1072 | case BO_Assign: |
| 1040 | if (result_used) { | 1073 | return trans_create_assign(c, result_used, block, stmt->getLHS(), stmt->getRHS()); |
| 1041 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Assign with result_used"); | | |
| 1042 | return nullptr; | | |
| 1043 | } | | |
| 1044 | return trans_create_assign(c, block, stmt->getLHS(), stmt->getRHS()); | | |
| 1045 | case BO_MulAssign: | 1074 | case BO_MulAssign: |
| 1046 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_MulAssign"); | 1075 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_MulAssign"); |
| 1047 | return nullptr; | 1076 | return nullptr; |