authorgravatar for kavika@gmail.comMerlyn Morgan-Graham <kavika@gmail.com> 2019-12-14 22:04:07-08:00
committergravatar for kavika@gmail.comMerlyn Morgan-Graham <kavika@gmail.com> 2019-12-16 01:34:04-08:00
logc8c89648b0d98af07aad88a813a74ff650cf3bbe
tree348f0739464cae2b45dc0b1e9184828ab838f673
parent2c7a2aefbfd0dbab190f912b4fbcbda96fb5ac44

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


2 files changed, 131 insertions(+), 9 deletions(-)

src-self-hosted/translate_c.zig+79-9
...@@ -681,15 +681,85 @@ fn transBinaryOperator(...@@ -681,15 +681,85 @@ fn transBinaryOperator(
681 },681 },
682 .Shl,682 .Shl,
683 .Shr,683 .Shr,
684 .LT,684 => return revertAndWarn(
685 .GT,685 rp,
686 .LE,686 error.UnsupportedTranslation,
687 .GE,687 ZigClangBinaryOperator_getBeginLoc(stmt),
688 .EQ,688 "TODO: handle more C binary operators: {}",
689 .NE,689 .{op},
690 .And,690 ),
691 .Xor,691 .LT => {
692 .Or,692 const node = try transCreateNodeInfixOp(rp, scope, stmt, .LessThan, .AngleBracketLeft, "<", true);
693 return maybeSuppressResult(rp, scope, result_used, TransResult{
694 .node = node,
695 .child_scope = scope,
696 .node_scope = scope,
697 });
698 },
699 .GT => {
700 const node = try transCreateNodeInfixOp(rp, scope, stmt, .GreaterThan, .AngleBracketRight, ">", true);
701 return maybeSuppressResult(rp, scope, result_used, TransResult{
702 .node = node,
703 .child_scope = scope,
704 .node_scope = scope,
705 });
706 },
707 .LE => {
708 const node = try transCreateNodeInfixOp(rp, scope, stmt, .LessOrEqual, .AngleBracketLeftEqual, "<=", true);
709 return maybeSuppressResult(rp, scope, result_used, TransResult{
710 .node = node,
711 .child_scope = scope,
712 .node_scope = scope,
713 });
714 },
715 .GE => {
716 const node = try transCreateNodeInfixOp(rp, scope, stmt, .GreaterOrEqual, .AngleBracketRightEqual, ">=", true);
717 return maybeSuppressResult(rp, scope, result_used, TransResult{
718 .node = node,
719 .child_scope = scope,
720 .node_scope = scope,
721 });
722 },
723 .EQ => {
724 const node = try transCreateNodeInfixOp(rp, scope, stmt, .EqualEqual, .EqualEqual, "==", true);
725 return maybeSuppressResult(rp, scope, result_used, TransResult{
726 .node = node,
727 .child_scope = scope,
728 .node_scope = scope,
729 });
730 },
731 .NE => {
732 const node = try transCreateNodeInfixOp(rp, scope, stmt, .BangEqual, .BangEqual, "!=", true);
733 return maybeSuppressResult(rp, scope, result_used, TransResult{
734 .node = node,
735 .child_scope = scope,
736 .node_scope = scope,
737 });
738 },
739 .And => {
740 const node = try transCreateNodeInfixOp(rp, scope, stmt, .BitAnd, .Ampersand, "&", true);
741 return maybeSuppressResult(rp, scope, result_used, TransResult{
742 .node = node,
743 .child_scope = scope,
744 .node_scope = scope,
745 });
746 },
747 .Xor => {
748 const node = try transCreateNodeInfixOp(rp, scope, stmt, .BitXor, .Caret, "^", true);
749 return maybeSuppressResult(rp, scope, result_used, TransResult{
750 .node = node,
751 .child_scope = scope,
752 .node_scope = scope,
753 });
754 },
755 .Or => {
756 const node = try transCreateNodeInfixOp(rp, scope, stmt, .BitOr, .Pipe, "|", true);
757 return maybeSuppressResult(rp, scope, result_used, TransResult{
758 .node = node,
759 .child_scope = scope,
760 .node_scope = scope,
761 });
762 },
693 .LAnd,763 .LAnd,
694 .LOr,764 .LOr,
695 .Comma,765 .Comma,
test/translate_c.zig+52
...@@ -871,6 +871,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -871,6 +871,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
871 \\}871 \\}
872 });872 });
873873
874 cases.add_2("==, !=, no if", // TODO remove this test after `if` conversion supported, and switch "==, !=" to addC_both
875 \\int max(int a, int b) {
876 \\ int c = (a == b);
877 \\ int d = (a != b);
878 \\ return (c != d);
879 \\}
880 , &[_][]const u8{
881 \\pub export fn max(a: c_int, b: c_int) c_int {
882 \\ var c: c_int = (a == b);
883 \\ var d: c_int = (a != b);
884 \\ return (c != d);
885 \\}
886 });
887
874 cases.addC("bitwise binary operators",888 cases.addC("bitwise binary operators",
875 \\int max(int a, int b) {889 \\int max(int a, int b) {
876 \\ return (a & b) ^ (a | b);890 \\ return (a & b) ^ (a | b);
...@@ -881,6 +895,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -881,6 +895,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
881 \\}895 \\}
882 });896 });
883897
898 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
899 \\int max(int a, int b) {
900 \\ int c = (a & b);
901 \\ int d = (a | b);
902 \\ return (c ^ d);
903 \\}
904 , &[_][]const u8{
905 \\pub export fn max(a: c_int, b: c_int) c_int {
906 \\ var c: c_int = (a & b);
907 \\ var d: c_int = (a | b);
908 \\ return (c ^ d);
909 \\}
910 });
911
884 cases.addC("logical and, logical or",912 cases.addC("logical and, logical or",
885 \\int max(int a, int b) {913 \\int max(int a, int b) {
886 \\ if (a < b || a == b)914 \\ if (a < b || a == b)
...@@ -897,6 +925,30 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -897,6 +925,30 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
897 \\}925 \\}
898 });926 });
899927
928 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
929 \\int test_comparisons(int a, int b) {
930 \\ int c = (a < b);
931 \\ int d = (a > b);
932 \\ int e = (a <= b);
933 \\ int f = (a >= b);
934 \\ int g = (c < d);
935 \\ int h = (e < f);
936 \\ int i = (g < h);
937 \\ return i;
938 \\}
939 , &[_][]const u8{
940 \\pub export fn test_comparisons(a: c_int, b: c_int) c_int {
941 \\ var c: c_int = (a < b);
942 \\ var d: c_int = (a > b);
943 \\ var e: c_int = (a <= b);
944 \\ var f: c_int = (a >= b);
945 \\ var g: c_int = (c < d);
946 \\ var h: c_int = (e < f);
947 \\ var i: c_int = (g < h);
948 \\ return i;
949 \\}
950 });
951
900 cases.addC("logical and, logical or on none bool values",952 cases.addC("logical and, logical or on none bool values",
901 \\int and_or_none_bool(int a, float b, void *c) {953 \\int and_or_none_bool(int a, float b, void *c) {
902 \\ if (a && b) return 0;954 \\ if (a && b) return 0;