|
|
|
@ -98,17 +98,21 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
|
|
|
|
{
|
|
|
|
|
err(node, "Expression `%s` type inference error.", ex);
|
|
|
|
|
error = true;
|
|
|
|
|
} else if (ex instanceof IndexExpr &&
|
|
|
|
|
((IndexExpr)ex).list.getInferredType().equals(Type.STR_TYPE)){
|
|
|
|
|
}
|
|
|
|
|
else if (ex instanceof IndexExpr &&
|
|
|
|
|
((IndexExpr)ex).list.getInferredType().equals(Type.STR_TYPE))
|
|
|
|
|
{
|
|
|
|
|
err(ex, "`str` is not a list type");
|
|
|
|
|
error = true;
|
|
|
|
|
}
|
|
|
|
|
else if(tr!=null && tl.isListType() && tr.isListType()){
|
|
|
|
|
else if(tr!=null && tl.isListType() && tr.isListType())
|
|
|
|
|
{
|
|
|
|
|
if(!((!tl.elementType().isSpecialType()&&tr.elementType().equals(Type.NONE_TYPE))||
|
|
|
|
|
tl.equals(tr)||tr.elementType().equals(Type.EMPTY_TYPE))){
|
|
|
|
|
err(node, "Expected type `%s`; got type `%s`", tl, tr);
|
|
|
|
|
tl.equals(tr)||tr.elementType().equals(Type.EMPTY_TYPE)))
|
|
|
|
|
{
|
|
|
|
|
err(node, "Expected type `%s`; got type `%s`", tl, tr);
|
|
|
|
|
error = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(tl.isListType() && Type.EMPTY_TYPE.equals(tr)) ; //continue;
|
|
|
|
|
else if(tr != null && !(StudentAnalysis.subClassOf(tl, tr, currentScope) || !tl.isSpecialType() && tr.equals(Type.NONE_TYPE)))
|
|
|
|
@ -302,7 +306,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
|
|
|
|
Type thisArgTy = thisArg.setInferredType(thisArg.dispatch(this)),
|
|
|
|
|
thisParamTy = funcTy.parameters.get(i + 1);
|
|
|
|
|
|
|
|
|
|
if(!thisParamTy.equals(thisArgTy))
|
|
|
|
|
if(!thisParamTy.equals(thisArgTy) && !StudentAnalysis.subClassOf(thisParamTy, thisArgTy, currentScope))
|
|
|
|
|
err(node, "Expected type `%s`; got type `%s` in parameter %d",
|
|
|
|
|
thisParamTy, thisArgTy, i + 1);
|
|
|
|
|
}
|
|
|
|
|