Commit 67a5a3f3d7
Changed files (2)
src
test
src/parsec.cpp
@@ -951,20 +951,47 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo
emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_PtrMemI");
return nullptr;
case BO_Mul:
- emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Mul");
- return nullptr;
+ return trans_create_bin_op(c, block, stmt->getLHS(),
+ qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult,
+ stmt->getRHS());
case BO_Div:
- emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Div");
- return nullptr;
+ if (qual_type_has_wrapping_overflow(c, stmt->getType())) {
+ // unsigned/float division uses the operator
+ return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeDiv, stmt->getRHS());
+ } else {
+ // signed integer division uses @divTrunc
+ AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "divTrunc");
+ AstNode *lhs = trans_expr(c, true, block, stmt->getLHS(), TransLValue);
+ if (lhs == nullptr) return nullptr;
+ fn_call->data.fn_call_expr.params.append(lhs);
+ AstNode *rhs = trans_expr(c, true, block, stmt->getRHS(), TransLValue);
+ if (rhs == nullptr) return nullptr;
+ fn_call->data.fn_call_expr.params.append(rhs);
+ return fn_call;
+ }
case BO_Rem:
- emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Rem");
- return nullptr;
+ if (qual_type_has_wrapping_overflow(c, stmt->getType())) {
+ // unsigned/float division uses the operator
+ return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeMod, stmt->getRHS());
+ } else {
+ // signed integer division uses @divTrunc
+ AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "rem");
+ AstNode *lhs = trans_expr(c, true, block, stmt->getLHS(), TransLValue);
+ if (lhs == nullptr) return nullptr;
+ fn_call->data.fn_call_expr.params.append(lhs);
+ AstNode *rhs = trans_expr(c, true, block, stmt->getRHS(), TransLValue);
+ if (rhs == nullptr) return nullptr;
+ fn_call->data.fn_call_expr.params.append(rhs);
+ return fn_call;
+ }
case BO_Add:
- emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Add");
- return nullptr;
+ return trans_create_bin_op(c, block, stmt->getLHS(),
+ qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd,
+ stmt->getRHS());
case BO_Sub:
- emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Sub");
- return nullptr;
+ return trans_create_bin_op(c, block, stmt->getLHS(),
+ qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub,
+ stmt->getRHS());
case BO_Shl:
emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Shl");
return nullptr;
test/parsec.zig
@@ -389,6 +389,42 @@ pub fn addCases(cases: &tests.ParseCContext) {
\\}
);
+ cases.add("add, sub, mul, div, rem",
+ \\int s(int a, int b) {
+ \\ int c;
+ \\ c = a + b;
+ \\ c = a - b;
+ \\ c = a * b;
+ \\ c = a / b;
+ \\ c = a % b;
+ \\}
+ \\unsigned u(unsigned a, unsigned b) {
+ \\ unsigned c;
+ \\ c = a + b;
+ \\ c = a - b;
+ \\ c = a * b;
+ \\ c = a / b;
+ \\ c = a % b;
+ \\}
+ ,
+ \\export fn s(a: c_int, b: c_int) -> c_int {
+ \\ var c: c_int;
+ \\ c = (a + b);
+ \\ c = (a - b);
+ \\ c = (a * b);
+ \\ c = @divTrunc(a, b);
+ \\ c = @rem(a, b);
+ \\}
+ \\export fn u(a: c_uint, b: c_uint) -> c_uint {
+ \\ var c: c_uint;
+ \\ c = (a +% b);
+ \\ c = (a -% b);
+ \\ c = (a *% b);
+ \\ c = (a / b);
+ \\ c = (a % b);
+ \\}
+ );
+
cases.add("bitwise binary operators",
\\int max(int a, int b) {
\\ return (a & b) ^ (a | b);