| author | |
| committer | |
| log | c8c89648b0d98af07aad88a813a74ff650cf3bbe |
| tree | 348f0739464cae2b45dc0b1e9184828ab838f673 |
| parent | 2c7a2aefbfd0dbab190f912b4fbcbda96fb5ac44 |
2 files changed, 131 insertions(+), 9 deletions(-)
src-self-hosted/translate_c.zig+79-9| ... | ... | @@ -681,15 +681,85 @@ fn transBinaryOperator( |
| 681 | 681 | }, |
| 682 | 682 | .Shl, |
| 683 | 683 | .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 | }, | |
| 693 | 763 | .LAnd, |
| 694 | 764 | .LOr, |
| 695 | 765 | .Comma, |
test/translate_c.zig+52| ... | ... | @@ -871,6 +871,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 871 | 871 | \\} |
| 872 | 872 | }); |
| 873 | 873 | |
| 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 | 888 | cases.addC("bitwise binary operators", |
| 875 | 889 | \\int max(int a, int b) { |
| 876 | 890 | \\ return (a & b) ^ (a | b); |
| ... | ... | @@ -881,6 +895,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 881 | 895 | \\} |
| 882 | 896 | }); |
| 883 | 897 | |
| 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 | 912 | cases.addC("logical and, logical or", |
| 885 | 913 | \\int max(int a, int b) { |
| 886 | 914 | \\ if (a < b || a == b) |
| ... | ... | @@ -897,6 +925,30 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 897 | 925 | \\} |
| 898 | 926 | }); |
| 899 | 927 | |
| 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 | 952 | cases.addC("logical and, logical or on none bool values", |
| 901 | 953 | \\int and_or_none_bool(int a, float b, void *c) { |
| 902 | 954 | \\ if (a && b) return 0; |