From b14177361fafea8ca4c0c4483d7776d9550e8c07 Mon Sep 17 00:00:00 2001
From: Recolic Keghart <root@recolic.net>
Date: Fri, 5 Apr 2019 20:19:14 -0700
Subject: [PATCH] finished all expr. debugging expr, passing 4

---
 src/main/java/chocopy/pa2/TypeChecker.java | 42 ++++++++++++++++++++--
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/src/main/java/chocopy/pa2/TypeChecker.java b/src/main/java/chocopy/pa2/TypeChecker.java
index 08faeb7..3a915a3 100644
--- a/src/main/java/chocopy/pa2/TypeChecker.java
+++ b/src/main/java/chocopy/pa2/TypeChecker.java
@@ -131,12 +131,17 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
                 if(left_type != ValueType.INT_TYPE && left_type != ValueType.STR_TYPE && ! left_type.isListType()) {
                     err(node, "Syntax Error: operand of + should be INT or STR or LIST");
                 }
-                // fallthrough
+                // fallthrough: do left-right match check.
             case "==":
             case "!=":
             case "is":
-                if(node.left.getInferredType() != node.right.getInferredType()) {
-                    err(node, "Syntax Error: binary operator operand type mismatch");
+                if(!left_type.equals(right_type)) {
+                    if(left_type.isListType() && right_type.isListType()) {
+                        System.out.println("debug: left_type=" + left_type.toString() + ", right=" + right_type.toString());
+                        left_type = new ListValueType(OBJECT_TYPE);
+                        break; // list-type mismatch is OK. but you should return [Object]
+                    }
+                    err(node, "Syntax Error: binary operator operand type mismatch: left=" + left_type.toString() + ", right=" + right_type.toString());
                 }
                 break;
             default:
@@ -244,6 +249,20 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
         }
     }
 
+    @Override
+    public SymbolType analyze(ListExpr node) {
+        SymbolType elementType = null;
+        for(Expr expr : node.elements) {
+            SymbolType this_type = expr.dispatch(this);
+            if(elementType == null)
+                elementType = this_type;
+            if(this_type != elementType)
+                err(node, "list elements must have the same type.");
+        }
+        ListValueType resultType = new ListValueType(elementType);
+        return node.setInferredType(resultType);
+    }
+
     @Override
     public SymbolType analyze(MemberExpr node) {
         ClassValueType objType = (ClassValueType) node.object.dispatch(this);
@@ -259,6 +278,23 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
         return resultType;
     }
 
+    @Override
+    public SymbolType analyze(MethodCallExpr node) {
+        FuncType funcType = (FuncType) node.method.dispatch(this);
+        if(funcType == null) {
+            err(node, "method is not callable.");
+            return NONE_TYPE;
+        }
+        List<SymbolType> args_type = new ArrayList<>();
+        for(Expr expr : node.args) {
+            args_type.add(expr.dispatch(this));
+        }
+        if(!args_type.equals(funcType.parameters)) {
+            err(node, "function/method parameter list mismatch");
+        }
+        return funcType.returnType;
+    }
+
     @Override
     public SymbolType analyze(Identifier id) {
         String varName = id.name;
-- 
GitLab