Add comparison and bitwise binary ops in translate-c-2

This commit is contained in:
Merlyn Morgan-Graham 2019-12-14 22:04:07 -08:00
parent 2c7a2aefbf
commit c8c89648b0
2 changed files with 131 additions and 9 deletions

View File

@ -681,15 +681,85 @@ fn transBinaryOperator(
}, },
.Shl, .Shl,
.Shr, .Shr,
.LT, => return revertAndWarn(
.GT, rp,
.LE, error.UnsupportedTranslation,
.GE, ZigClangBinaryOperator_getBeginLoc(stmt),
.EQ, "TODO: handle more C binary operators: {}",
.NE, .{op},
.And, ),
.Xor, .LT => {
.Or, const node = try transCreateNodeInfixOp(rp, scope, stmt, .LessThan, .AngleBracketLeft, "<", true);
return maybeSuppressResult(rp, scope, result_used, TransResult{
.node = node,
.child_scope = scope,
.node_scope = scope,
});
},
.GT => {
const node = try transCreateNodeInfixOp(rp, scope, stmt, .GreaterThan, .AngleBracketRight, ">", true);
return maybeSuppressResult(rp, scope, result_used, TransResult{
.node = node,
.child_scope = scope,
.node_scope = scope,
});
},
.LE => {
const node = try transCreateNodeInfixOp(rp, scope, stmt, .LessOrEqual, .AngleBracketLeftEqual, "<=", true);
return maybeSuppressResult(rp, scope, result_used, TransResult{
.node = node,
.child_scope = scope,
.node_scope = scope,
});
},
.GE => {
const node = try transCreateNodeInfixOp(rp, scope, stmt, .GreaterOrEqual, .AngleBracketRightEqual, ">=", true);
return maybeSuppressResult(rp, scope, result_used, TransResult{
.node = node,
.child_scope = scope,
.node_scope = scope,
});
},
.EQ => {
const node = try transCreateNodeInfixOp(rp, scope, stmt, .EqualEqual, .EqualEqual, "==", true);
return maybeSuppressResult(rp, scope, result_used, TransResult{
.node = node,
.child_scope = scope,
.node_scope = scope,
});
},
.NE => {
const node = try transCreateNodeInfixOp(rp, scope, stmt, .BangEqual, .BangEqual, "!=", true);
return maybeSuppressResult(rp, scope, result_used, TransResult{
.node = node,
.child_scope = scope,
.node_scope = scope,
});
},
.And => {
const node = try transCreateNodeInfixOp(rp, scope, stmt, .BitAnd, .Ampersand, "&", true);
return maybeSuppressResult(rp, scope, result_used, TransResult{
.node = node,
.child_scope = scope,
.node_scope = scope,
});
},
.Xor => {
const node = try transCreateNodeInfixOp(rp, scope, stmt, .BitXor, .Caret, "^", true);
return maybeSuppressResult(rp, scope, result_used, TransResult{
.node = node,
.child_scope = scope,
.node_scope = scope,
});
},
.Or => {
const node = try transCreateNodeInfixOp(rp, scope, stmt, .BitOr, .Pipe, "|", true);
return maybeSuppressResult(rp, scope, result_used, TransResult{
.node = node,
.child_scope = scope,
.node_scope = scope,
});
},
.LAnd, .LAnd,
.LOr, .LOr,
.Comma, .Comma,

View File

@ -871,6 +871,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\} \\}
}); });
cases.add_2("==, !=, no if", // TODO remove this test after `if` conversion supported, and switch "==, !=" to addC_both
\\int max(int a, int b) {
\\ int c = (a == b);
\\ int d = (a != b);
\\ return (c != d);
\\}
, &[_][]const u8{
\\pub export fn max(a: c_int, b: c_int) c_int {
\\ var c: c_int = (a == b);
\\ var d: c_int = (a != b);
\\ return (c != d);
\\}
});
cases.addC("bitwise binary operators", cases.addC("bitwise binary operators",
\\int max(int a, int b) { \\int max(int a, int b) {
\\ return (a & b) ^ (a | b); \\ return (a & b) ^ (a | b);
@ -881,6 +895,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\} \\}
}); });
cases.add_2("bitwise binary operators, simpler parens", // TODO can combine with "bitwise binary operators" when parens are correctly preserved/not added in translate-c-2
\\int max(int a, int b) {
\\ int c = (a & b);
\\ int d = (a | b);
\\ return (c ^ d);
\\}
, &[_][]const u8{
\\pub export fn max(a: c_int, b: c_int) c_int {
\\ var c: c_int = (a & b);
\\ var d: c_int = (a | b);
\\ return (c ^ d);
\\}
});
cases.addC("logical and, logical or", cases.addC("logical and, logical or",
\\int max(int a, int b) { \\int max(int a, int b) {
\\ if (a < b || a == b) \\ if (a < b || a == b)
@ -897,6 +925,30 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\} \\}
}); });
cases.add_2("comparison operators (no if)", // TODO Come up with less contrived tests? Make sure to cover all these comparisons. Can use `if` after it is added to translate-c-2
\\int test_comparisons(int a, int b) {
\\ int c = (a < b);
\\ int d = (a > b);
\\ int e = (a <= b);
\\ int f = (a >= b);
\\ int g = (c < d);
\\ int h = (e < f);
\\ int i = (g < h);
\\ return i;
\\}
, &[_][]const u8{
\\pub export fn test_comparisons(a: c_int, b: c_int) c_int {
\\ var c: c_int = (a < b);
\\ var d: c_int = (a > b);
\\ var e: c_int = (a <= b);
\\ var f: c_int = (a >= b);
\\ var g: c_int = (c < d);
\\ var h: c_int = (e < f);
\\ var i: c_int = (g < h);
\\ return i;
\\}
});
cases.addC("logical and, logical or on none bool values", cases.addC("logical and, logical or on none bool values",
\\int and_or_none_bool(int a, float b, void *c) { \\int and_or_none_bool(int a, float b, void *c) {
\\ if (a && b) return 0; \\ if (a && b) return 0;