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

master
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,
.Shr,
.LT,
.GT,
.LE,
.GE,
.EQ,
.NE,
.And,
.Xor,
.Or,
=> return revertAndWarn(
rp,
error.UnsupportedTranslation,
ZigClangBinaryOperator_getBeginLoc(stmt),
"TODO: handle more C binary operators: {}",
.{op},
),
.LT => {
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,
.LOr,
.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",
\\int max(int a, int 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",
\\int max(int a, int 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",
\\int and_or_none_bool(int a, float b, void *c) {
\\ if (a && b) return 0;