|
|
@ -191,8 +191,10 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
|
|
|
for(int i = 0; i < lArgs; ++i){
|
|
|
|
for(int i = 0; i < lArgs; ++i){
|
|
|
|
Type p = fty.parameters.get(i);
|
|
|
|
Type p = fty.parameters.get(i);
|
|
|
|
Type c = types.get(i);
|
|
|
|
Type c = types.get(i);
|
|
|
|
if((p.isSpecialType()&&!p.equals(c)) ||
|
|
|
|
if(((p.isSpecialType()&&!p.equals(c)) ||
|
|
|
|
(!p.isSpecialType()&&!StudentAnalysis.subClassOf(p, c, currentScope)))
|
|
|
|
(!p.isSpecialType()&&!StudentAnalysis.subClassOf(p, c, currentScope)))
|
|
|
|
|
|
|
|
&&!(p.isListType()&&c.equals(Type.EMPTY_TYPE))
|
|
|
|
|
|
|
|
)
|
|
|
|
err(node,"Expected type `%s`; got type `%s` in parameter %d", p, c, i);
|
|
|
|
err(node,"Expected type `%s`; got type `%s` in parameter %d", p, c, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -238,7 +240,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
|
|
|
public Type analyze(IfExpr node) {
|
|
|
|
public Type analyze(IfExpr node) {
|
|
|
|
Type condTy = node.condition.dispatch(this);
|
|
|
|
Type condTy = node.condition.dispatch(this);
|
|
|
|
if(!condTy.equals(Type.BOOL_TYPE)){
|
|
|
|
if(!condTy.equals(Type.BOOL_TYPE)){
|
|
|
|
err(node, "If condition `%s` isn't a boolean expression.", node.condition);
|
|
|
|
err(node, "Condition expression cannot be of type `%s`", condTy.className());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Type ifTy = node.thenExpr.dispatch(this),
|
|
|
|
Type ifTy = node.thenExpr.dispatch(this),
|
|
|
@ -252,7 +254,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
|
|
|
public Type analyze(IfStmt node) {
|
|
|
|
public Type analyze(IfStmt node) {
|
|
|
|
Type condTy = node.condition.dispatch(this);
|
|
|
|
Type condTy = node.condition.dispatch(this);
|
|
|
|
if(!condTy.equals(Type.BOOL_TYPE)){
|
|
|
|
if(!condTy.equals(Type.BOOL_TYPE)){
|
|
|
|
err(node, "If condition `%s` isn't a boolean expression.", node.condition);
|
|
|
|
err(node, "Condition expression cannot be of type `%s`", condTy.className());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
boolean prevReturned = returned, thenReturned;
|
|
|
|
boolean prevReturned = returned, thenReturned;
|
|
|
|
for(Stmt st : node.thenBody)
|
|
|
|
for(Stmt st : node.thenBody)
|
|
|
@ -335,7 +337,8 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
|
|
|
Type thisArgTy = thisArg.setInferredType(thisArg.dispatch(this)),
|
|
|
|
Type thisArgTy = thisArg.setInferredType(thisArg.dispatch(this)),
|
|
|
|
thisParamTy = funcTy.parameters.get(i + 1);
|
|
|
|
thisParamTy = funcTy.parameters.get(i + 1);
|
|
|
|
|
|
|
|
|
|
|
|
if(!thisParamTy.equals(thisArgTy) && !StudentAnalysis.subClassOf(thisParamTy, thisArgTy, currentScope))
|
|
|
|
if(!thisParamTy.equals(thisArgTy) && !StudentAnalysis.subClassOf(thisParamTy, thisArgTy, currentScope)
|
|
|
|
|
|
|
|
&&!(thisParamTy.isListType()&&thisArgTy.equals(Type.EMPTY_TYPE)))
|
|
|
|
err(node, "Expected type `%s`; got type `%s` in parameter %d",
|
|
|
|
err(node, "Expected type `%s`; got type `%s` in parameter %d",
|
|
|
|
thisParamTy, thisArgTy, i + 1);
|
|
|
|
thisParamTy, thisArgTy, i + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|