diff --git a/src/main/java/chocopy/pa2/TypeChecker.java b/src/main/java/chocopy/pa2/TypeChecker.java index 75e7c2ff6dfced6fa173b46419f29844987a4f69..ff5519c2f0d6111d691d70b279526d8df76aa048 100644 --- a/src/main/java/chocopy/pa2/TypeChecker.java +++ b/src/main/java/chocopy/pa2/TypeChecker.java @@ -42,7 +42,8 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { * The message is constructed with MESSAGE and ARGS as for * String.format. */ private void err(Node node, String message, Object... args) { - errors.semError(node, message, args); + if(!isFirstRun) + errors.semError(node, message, args); } ///////////////////////////// Program ////////////////////////////////////// @@ -138,11 +139,17 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { stmt.dispatch(this); } + FuncType funcT = new FuncType(args, ValueType.annotationToValueType(funcDef.returnType)); + if(isFirstRun) + sym.put(funcDef.name.name, funcT); // this funcdef should be add to both parentSym and localSym to support recursive func. + + // TA don't like it. OK I won't dispatch this id... + //funcDef.name.dispatch(this); // dispatch it. + // function scope ends.. backtracking... sym = sym.getParent(); if(sym == null) throw new RuntimeException("logic error: sym parent is null while returning.."); - FuncType funcT = new FuncType(args, ValueType.annotationToValueType(funcDef.returnType)); return funcT; } @@ -357,7 +364,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { @Override public SymbolType analyze(CallExpr node) { - SymbolType funcType = sym.get(node.function.name); + SymbolType funcType = node.function.dispatch(this); if(funcType == null) { err(node, "calling undeclared function " + node.function.name); return null; @@ -366,7 +373,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { err(node, "calling non-function variable " + node.function.name); return null; } - FuncType fType = (FuncType)funcType; + FuncType fType = (FuncType) funcType; List<SymbolType> args_type = new ArrayList<SymbolType>(); for(Expr arg : node.args) { args_type.add(arg.dispatch(this)); @@ -374,7 +381,6 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { if(!fType.parameters.equals(args_type)) { err(node, "function parameter type list mismatch: " + node.function.name + ". Expected " + fType.parameters.toString() + ", got " + args_type.toString()); } - System.out.println("debug: callexpr set type = " + fType.returnType.toString()); return node.setInferredType(fType.returnType); } @@ -493,7 +499,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { } System.out.println("var " + varName + "->" + varType.toString()); - if (varType != null && varType.isValueType()) { + if (varType != null) { return id.setInferredType(varType); }