From 98d0b955d09d5207b1158e06301f64fa36cf1722 Mon Sep 17 00:00:00 2001
From: Origami404 <Origami404@foxmail.com>
Date: Fri, 5 Aug 2022 22:29:33 +0800
Subject: [PATCH] =?UTF-8?q?ir-gen:=20=E4=BF=AE=E5=A4=8D=E4=BA=86=E4=B8=8D?=
 =?UTF-8?q?=E8=83=BD=E5=9C=A8=20=3D=3D=20=E9=87=8C=E4=BD=BF=E7=94=A8=20=3D?=
 =?UTF-8?q?=3D=20=E7=9A=84=20bug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/frontend/IRGen.java            | 46 +++++++++++++++++++-----------
 test-data/test/02-bool-as-value.sy |  8 ++++++
 2 files changed, 37 insertions(+), 17 deletions(-)
 create mode 100644 test-data/test/02-bool-as-value.sy

diff --git a/src/frontend/IRGen.java b/src/frontend/IRGen.java
index a10d88d..b0e83db 100644
--- a/src/frontend/IRGen.java
+++ b/src/frontend/IRGen.java
@@ -831,37 +831,49 @@ public class IRGen extends SysYBaseVisitor<Object> {
         UnaryOperator<Value> floatMerger
     ) {
         if (arg.getType().isInt()) {
-            return intMerger.apply(arg);
+            final var newArg = insertConvertByType(IRType.IntTy, arg);
+            return intMerger.apply(newArg);
         } else {
-            return floatMerger.apply(arg);
+            final var newArg = insertConvertByType(IRType.FloatTy, arg);
+            return floatMerger.apply(newArg);
         }
     }
 
     private Value insertConvertByType(IRType targetType, Value value) {
-        final var srcType = value.getType();
-        if (targetType.equals(srcType)) {
+        final var valueType = value.getType();
+        if (targetType.equals(valueType)) {
             return value;
+
+        } else if (valueType.isFloat() && targetType.isInt()) {
+            return builder.insertF2I(value);
+
+        } else if (valueType.isInt() && targetType.isFloat()) {
+            return builder.insertI2F(value);
+
+        } else if (valueType.isBool() && targetType.isInt()) {
+            return builder.insertB2I(value);
+
+        } else if (valueType.isBool() && targetType.isFloat()) {
+            return builder.insertI2F(builder.insertB2I(value));
+
         } else {
-            if (targetType.isFloat() && srcType.isInt()) {
-                return builder.insertI2F(value);
-            } else {
-                return builder.insertF2I(value);
-            }
+            Log.ensure(false,
+                "Can NOT convert type for: %s -> %s".formatted(valueType, targetType));
+            throw new RuntimeException();
         }
     }
 
+    private static final Map<IRType, Integer> typeToOrder =
+        Map.of(IRType.BoolTy, 0, IRType.IntTy, 1, IRType.FloatTy, 2);
+    private static final Map<Integer, IRType> orderToType =
+        Map.of(0, IRType.BoolTy, 1, IRType.IntTy, 2, IRType.FloatTy);
     private static IRType findCommonType(IRType ty1, IRType ty2) {
         Log.ensure(ty1.isInt() || ty1.isFloat() || ty1.isBool(), "Except ty1 is Int/Float/Bool, given: " + ty1);
         Log.ensure(ty2.isInt() || ty2.isFloat() || ty2.isBool(), "Except ty2 is Int/Float/Bool, given: " + ty2);
 
-        if (ty1.equals(ty2)) {
-            // 两个都是 Int 或者是两个都 Float 的情况
-            return ty1; // or return ty2
-        } else {
-            Log.ensure(!(ty1.isBool() || ty2.isBool()), "Bool can NOT be convert to other type");
-            // 一个 Int, 一个 Float 的情况
-            return IRType.FloatTy;
-        }
+        final var order1 = typeToOrder.get(ty1);
+        final var order2 = typeToOrder.get(ty2);
+        return orderToType.get(Integer.max(order1, order2));
     }
     //#endregion exp
 
diff --git a/test-data/test/02-bool-as-value.sy b/test-data/test/02-bool-as-value.sy
new file mode 100644
index 0000000..3043c89
--- /dev/null
+++ b/test-data/test/02-bool-as-value.sy
@@ -0,0 +1,8 @@
+int main() {
+    int a = 0, b = 1, c = 2;
+    if (a < 0 == b == c) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
\ No newline at end of file
-- 
GitLab