|
|
|
@ -132,7 +132,8 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
public Void visitCallCommand(CallCommand ast, Void arg) {
|
|
|
|
|
var binding = ast.I.visit(this);
|
|
|
|
|
|
|
|
|
|
if (binding instanceof ProcedureDeclaration procedure) {
|
|
|
|
|
if (binding instanceof ProcedureDeclaration) {
|
|
|
|
|
ProcedureDeclaration procedure = (ProcedureDeclaration)binding;
|
|
|
|
|
ast.APS.visit(this, procedure.getFormals());
|
|
|
|
|
} else {
|
|
|
|
|
reportUndeclaredOrError(binding, ast.I, "\"%\" is not a procedure identifier");
|
|
|
|
@ -203,7 +204,8 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
var e2Type = ast.E2.visit(this);
|
|
|
|
|
var binding = ast.O.visit(this);
|
|
|
|
|
|
|
|
|
|
if (binding instanceof BinaryOperatorDeclaration bbinding) {
|
|
|
|
|
if (binding instanceof BinaryOperatorDeclaration) {
|
|
|
|
|
BinaryOperatorDeclaration bbinding = (BinaryOperatorDeclaration)binding;
|
|
|
|
|
if (bbinding.ARG1.equals(StdEnvironment.anyType)) {
|
|
|
|
|
// this operator must be "=" or "\="
|
|
|
|
|
checkAndReportError(e1Type.equals(e2Type), "incompatible argument types for \"%\"", ast.O, ast);
|
|
|
|
@ -222,7 +224,8 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
public TypeDenoter visitCallExpression(CallExpression ast, Void arg) {
|
|
|
|
|
var binding = ast.I.visit(this);
|
|
|
|
|
|
|
|
|
|
if (binding instanceof FunctionDeclaration function) {
|
|
|
|
|
if (binding instanceof FunctionDeclaration) {
|
|
|
|
|
FunctionDeclaration function = (FunctionDeclaration)binding;
|
|
|
|
|
ast.APS.visit(this, function.getFormals());
|
|
|
|
|
return ast.type = function.getType();
|
|
|
|
|
}
|
|
|
|
@ -277,7 +280,8 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
var eType = ast.E.visit(this);
|
|
|
|
|
var binding = ast.O.visit(this);
|
|
|
|
|
|
|
|
|
|
if (binding instanceof UnaryOperatorDeclaration ubinding) {
|
|
|
|
|
if (binding instanceof UnaryOperatorDeclaration) {
|
|
|
|
|
UnaryOperatorDeclaration ubinding = (UnaryOperatorDeclaration)binding;
|
|
|
|
|
checkAndReportError(eType.equals(ubinding.ARG), "wrong argument type for \"%\"", ast.O);
|
|
|
|
|
return ast.type = ubinding.RES;
|
|
|
|
|
}
|
|
|
|
@ -472,8 +476,9 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
@Override
|
|
|
|
|
public Void visitConstActualParameter(ConstActualParameter ast, FormalParameter arg) {
|
|
|
|
|
var eType = ast.E.visit(this);
|
|
|
|
|
if (arg instanceof ConstFormalParameter param) {
|
|
|
|
|
checkAndReportError(eType.equals(param.T), "wrong type for const actual parameter", ast.E);
|
|
|
|
|
if (arg instanceof ConstFormalParameter) {
|
|
|
|
|
ConstFormalParameter param = (ConstFormalParameter)arg;
|
|
|
|
|
checkAndReportError(eType.equals(((ConstFormalParameter)arg).T), "wrong type for const actual parameter", ast.E);
|
|
|
|
|
} else {
|
|
|
|
|
reportError("const actual parameter not expected here", ast);
|
|
|
|
|
}
|
|
|
|
@ -483,10 +488,12 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
@Override
|
|
|
|
|
public Void visitFuncActualParameter(FuncActualParameter ast, FormalParameter arg) {
|
|
|
|
|
var binding = ast.I.visit(this);
|
|
|
|
|
if (binding instanceof FunctionDeclaration function) {
|
|
|
|
|
if (binding instanceof FunctionDeclaration) {
|
|
|
|
|
FunctionDeclaration function = (FunctionDeclaration)binding;
|
|
|
|
|
var formals = function.getFormals();
|
|
|
|
|
var functionType = function.getType();
|
|
|
|
|
if (arg instanceof FuncFormalParameter param) {
|
|
|
|
|
if (arg instanceof FuncFormalParameter) {
|
|
|
|
|
FuncFormalParameter param = (FuncFormalParameter)arg;
|
|
|
|
|
if (!formals.equals(param.getFormals())) {
|
|
|
|
|
reportError("wrong signature for function \"%\"", ast.I);
|
|
|
|
|
} else if (!functionType.equals(param.T)) {
|
|
|
|
@ -504,9 +511,11 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
@Override
|
|
|
|
|
public Void visitProcActualParameter(ProcActualParameter ast, FormalParameter arg) {
|
|
|
|
|
var binding = ast.I.visit(this);
|
|
|
|
|
if (binding instanceof ProcedureDeclaration procedure) {
|
|
|
|
|
if (binding instanceof ProcedureDeclaration) {
|
|
|
|
|
ProcedureDeclaration procedure = (ProcedureDeclaration)binding;
|
|
|
|
|
var formals = procedure.getFormals();
|
|
|
|
|
if (arg instanceof ProcFormalParameter param) {
|
|
|
|
|
if (arg instanceof ProcFormalParameter) {
|
|
|
|
|
ProcFormalParameter param = (ProcFormalParameter)arg;
|
|
|
|
|
checkAndReportError(formals.equals(param.getFormals()), "wrong signature for procedure \"%\"", ast.I);
|
|
|
|
|
} else {
|
|
|
|
|
reportError("proc actual parameter not expected here", ast);
|
|
|
|
@ -522,7 +531,8 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
var vType = ast.V.visit(this);
|
|
|
|
|
if (!ast.V.variable) {
|
|
|
|
|
reportError("actual parameter is not a variable", ast.V);
|
|
|
|
|
} else if (arg instanceof VarFormalParameter parameter) {
|
|
|
|
|
} else if (arg instanceof VarFormalParameter) {
|
|
|
|
|
VarFormalParameter parameter = (VarFormalParameter)arg;
|
|
|
|
|
checkAndReportError(vType.equals(parameter.T), "wrong type for var actual parameter", ast.V);
|
|
|
|
|
} else {
|
|
|
|
|
reportError("var actual parameter not expected here", ast.V);
|
|
|
|
@ -538,7 +548,8 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Void visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, FormalParameterSequence arg) {
|
|
|
|
|
if (arg instanceof MultipleFormalParameterSequence formals) {
|
|
|
|
|
if (arg instanceof MultipleFormalParameterSequence) {
|
|
|
|
|
MultipleFormalParameterSequence formals = (MultipleFormalParameterSequence)arg;
|
|
|
|
|
ast.AP.visit(this, formals.FP);
|
|
|
|
|
ast.APS.visit(this, formals.FPS);
|
|
|
|
|
} else {
|
|
|
|
@ -549,7 +560,8 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Void visitSingleActualParameterSequence(SingleActualParameterSequence ast, FormalParameterSequence arg) {
|
|
|
|
|
if (arg instanceof SingleFormalParameterSequence formal) {
|
|
|
|
|
if (arg instanceof SingleFormalParameterSequence) {
|
|
|
|
|
SingleFormalParameterSequence formal = (SingleFormalParameterSequence)arg;
|
|
|
|
|
ast.AP.visit(this, formal.FP);
|
|
|
|
|
} else {
|
|
|
|
|
reportError("incorrect number of actual parameters", ast);
|
|
|
|
@ -592,7 +604,8 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
@Override
|
|
|
|
|
public TypeDenoter visitSimpleTypeDenoter(SimpleTypeDenoter ast, Void arg) {
|
|
|
|
|
var binding = ast.I.visit(this);
|
|
|
|
|
if (binding instanceof TypeDeclaration decl) {
|
|
|
|
|
if (binding instanceof TypeDeclaration) {
|
|
|
|
|
TypeDeclaration decl = (TypeDeclaration)binding;
|
|
|
|
|
return decl.T;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -678,7 +691,8 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
public TypeDenoter visitDotVname(DotVname ast, Void arg) {
|
|
|
|
|
ast.type = null;
|
|
|
|
|
var vType = ast.V.visit(this);
|
|
|
|
|
if (vType instanceof RecordTypeDenoter record) {
|
|
|
|
|
if (vType instanceof RecordTypeDenoter) {
|
|
|
|
|
RecordTypeDenoter record = (RecordTypeDenoter)vType;
|
|
|
|
|
ast.type = checkFieldIdentifier(record.FT, ast.I);
|
|
|
|
|
checkAndReportError(!ast.type.equals(StdEnvironment.errorType), "no field \"%\" in this record type",
|
|
|
|
|
ast.I);
|
|
|
|
@ -694,9 +708,11 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
ast.type = StdEnvironment.errorType;
|
|
|
|
|
|
|
|
|
|
var binding = ast.I.visit(this);
|
|
|
|
|
if (binding instanceof ConstantDeclaration constant) {
|
|
|
|
|
if (binding instanceof ConstantDeclaration) {
|
|
|
|
|
ConstantDeclaration constant = (ConstantDeclaration)binding;
|
|
|
|
|
return ast.type = constant.getType();
|
|
|
|
|
} else if (binding instanceof VariableDeclaration variable) {
|
|
|
|
|
} else if (binding instanceof VariableDeclaration) {
|
|
|
|
|
VariableDeclaration variable = (VariableDeclaration)binding;
|
|
|
|
|
return ast.type = variable.getType();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -711,7 +727,8 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
|
|
|
|
|
var eType = ast.E.visit(this);
|
|
|
|
|
if (vType != StdEnvironment.errorType) {
|
|
|
|
|
if (vType instanceof ArrayTypeDenoter arrayType) {
|
|
|
|
|
if (vType instanceof ArrayTypeDenoter) {
|
|
|
|
|
ArrayTypeDenoter arrayType = (ArrayTypeDenoter)vType;
|
|
|
|
|
checkAndReportError(eType.equals(StdEnvironment.integerType), "Integer expression expected here",
|
|
|
|
|
ast.E);
|
|
|
|
|
ast.type = arrayType.T;
|
|
|
|
@ -796,14 +813,16 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static TypeDenoter checkFieldIdentifier(FieldTypeDenoter ast, Identifier I) {
|
|
|
|
|
if (ast instanceof MultipleFieldTypeDenoter ft) {
|
|
|
|
|
if (ast instanceof MultipleFieldTypeDenoter) {
|
|
|
|
|
MultipleFieldTypeDenoter ft = (MultipleFieldTypeDenoter)ast;
|
|
|
|
|
if (ft.I.spelling.compareTo(I.spelling) == 0) {
|
|
|
|
|
I.decl = ast;
|
|
|
|
|
return ft.T;
|
|
|
|
|
} else {
|
|
|
|
|
return checkFieldIdentifier(ft.FT, I);
|
|
|
|
|
}
|
|
|
|
|
} else if (ast instanceof SingleFieldTypeDenoter ft) {
|
|
|
|
|
} else if (ast instanceof SingleFieldTypeDenoter) {
|
|
|
|
|
SingleFieldTypeDenoter ft = (SingleFieldTypeDenoter)ast;
|
|
|
|
|
if (ft.I.spelling.compareTo(I.spelling) == 0) {
|
|
|
|
|
I.decl = ast;
|
|
|
|
|
return ft.T;
|
|
|
|
|