diff --git a/src/main/java/chocopy/pa2/TypeChecker.java b/src/main/java/chocopy/pa2/TypeChecker.java
index 08faeb74a2afd82f5481e3da57ef4ac6222b5465..3a915a3df6e4d5c04dbacf5d00240ea8ad027824 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;