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(
681681 },
682682 .Shl,
683683 .Shr,
684 .LT,
685 .GT,
686 .LE,
687 .GE,
688 .EQ,
689 .NE,
690 .And,
691 .Xor,
692 .Or,
684 => return revertAndWarn(
685 rp,
686 error.UnsupportedTranslation,
687 ZigClangBinaryOperator_getBeginLoc(stmt),
688 "TODO: handle more C binary operators: {}",
689 .{op},
690 ),
691 .LT => {
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 },
693763 .LAnd,
694764 .LOr,
695765 .Comma,
test/translate_c.zig+52
......@@ -871,6 +871,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
871871 \\}
872872 });
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
874888 cases.addC("bitwise binary operators",
875889 \\int max(int a, int b) {
876890 \\ return (a & b) ^ (a | b);
......@@ -881,6 +895,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
881895 \\}
882896 });
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
884912 cases.addC("logical and, logical or",
885913 \\int max(int a, int b) {
886914 \\ if (a < b || a == b)
......@@ -897,6 +925,30 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
897925 \\}
898926 });
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
900952 cases.addC("logical and, logical or on none bool values",
901953 \\int and_or_none_bool(int a, float b, void *c) {
902954 \\ if (a && b) return 0;