|
|
|
@ -93,6 +93,7 @@ public final class Checker implements Visitor { |
|
|
|
|
|
|
|
|
|
// Always returns null. Does not use the given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitAssignCommand(AssignCommand ast, Object o) { |
|
|
|
|
TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
@ -103,6 +104,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitCallCommand(CallCommand ast, Object o) { |
|
|
|
|
|
|
|
|
|
Declaration binding = (Declaration) ast.I.visit(this, null); |
|
|
|
@ -118,10 +120,12 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitEmptyCommand(EmptyCommand ast, Object o) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitIfCommand(IfCommand ast, Object o) { |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
if (!eType.equals(StdEnvironment.booleanType)) |
|
|
|
@ -131,6 +135,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitLetCommand(LetCommand ast, Object o) { |
|
|
|
|
idTable.openScope(); |
|
|
|
|
ast.D.visit(this, null); |
|
|
|
@ -139,12 +144,14 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSequentialCommand(SequentialCommand ast, Object o) { |
|
|
|
|
ast.C1.visit(this, null); |
|
|
|
|
ast.C2.visit(this, null); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitWhileCommand(WhileCommand ast, Object o) { |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
if (!eType.equals(StdEnvironment.booleanType)) |
|
|
|
@ -158,6 +165,7 @@ public final class Checker implements Visitor { |
|
|
|
|
// Returns the TypeDenoter denoting the type of the expression. Does
|
|
|
|
|
// not use the given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitArrayExpression(ArrayExpression ast, Object o) { |
|
|
|
|
TypeDenoter elemType = (TypeDenoter) ast.AA.visit(this, null); |
|
|
|
|
IntegerLiteral il = new IntegerLiteral(new Integer(ast.AA.elemCount).toString(), |
|
|
|
@ -166,6 +174,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitBinaryExpression(BinaryExpression ast, Object o) { |
|
|
|
|
|
|
|
|
|
TypeDenoter e1Type = (TypeDenoter) ast.E1.visit(this, null); |
|
|
|
@ -195,6 +204,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitCallExpression(CallExpression ast, Object o) { |
|
|
|
|
Declaration binding = (Declaration) ast.I.visit(this, null); |
|
|
|
|
if (binding == null) { |
|
|
|
@ -212,16 +222,19 @@ public final class Checker implements Visitor { |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitCharacterExpression(CharacterExpression ast, Object o) { |
|
|
|
|
ast.type = StdEnvironment.charType; |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitEmptyExpression(EmptyExpression ast, Object o) { |
|
|
|
|
ast.type = null; |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitIfExpression(IfExpression ast, Object o) { |
|
|
|
|
TypeDenoter e1Type = (TypeDenoter) ast.E1.visit(this, null); |
|
|
|
|
if (!e1Type.equals(StdEnvironment.booleanType)) |
|
|
|
@ -235,11 +248,13 @@ public final class Checker implements Visitor { |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitIntegerExpression(IntegerExpression ast, Object o) { |
|
|
|
|
ast.type = StdEnvironment.integerType; |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitLetExpression(LetExpression ast, Object o) { |
|
|
|
|
idTable.openScope(); |
|
|
|
|
ast.D.visit(this, null); |
|
|
|
@ -248,12 +263,14 @@ public final class Checker implements Visitor { |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitRecordExpression(RecordExpression ast, Object o) { |
|
|
|
|
FieldTypeDenoter rType = (FieldTypeDenoter) ast.RA.visit(this, null); |
|
|
|
|
ast.type = new RecordTypeDenoter(rType, ast.position); |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitUnaryExpression(UnaryExpression ast, Object o) { |
|
|
|
|
|
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
@ -274,6 +291,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitVnameExpression(VnameExpression ast, Object o) { |
|
|
|
|
ast.type = (TypeDenoter) ast.V.visit(this, null); |
|
|
|
|
return ast.type; |
|
|
|
@ -282,10 +300,12 @@ public final class Checker implements Visitor { |
|
|
|
|
// Declarations
|
|
|
|
|
|
|
|
|
|
// Always returns null. Does not use the given object.
|
|
|
|
|
@Override |
|
|
|
|
public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitConstDeclaration(ConstDeclaration ast, Object o) { |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); |
|
|
|
@ -295,6 +315,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitFuncDeclaration(FuncDeclaration ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); // permits recursion
|
|
|
|
@ -311,6 +332,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitProcDeclaration(ProcDeclaration ast, Object o) { |
|
|
|
|
idTable.enter(ast.I.spelling, ast); // permits recursion
|
|
|
|
|
if (ast.duplicated) |
|
|
|
@ -323,12 +345,14 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSequentialDeclaration(SequentialDeclaration ast, Object o) { |
|
|
|
|
ast.D1.visit(this, null); |
|
|
|
|
ast.D2.visit(this, null); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitTypeDeclaration(TypeDeclaration ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); |
|
|
|
@ -338,10 +362,12 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitVarDeclaration(VarDeclaration ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); |
|
|
|
@ -357,6 +383,7 @@ public final class Checker implements Visitor { |
|
|
|
|
// Returns the TypeDenoter for the Array Aggregate. Does not use the
|
|
|
|
|
// given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o) { |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
TypeDenoter elemType = (TypeDenoter) ast.AA.visit(this, null); |
|
|
|
@ -366,6 +393,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return elemType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o) { |
|
|
|
|
TypeDenoter elemType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
ast.elemCount = 1; |
|
|
|
@ -377,6 +405,7 @@ public final class Checker implements Visitor { |
|
|
|
|
// Returns the TypeDenoter for the Record Aggregate. Does not use the
|
|
|
|
|
// given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object o) { |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
FieldTypeDenoter rType = (FieldTypeDenoter) ast.RA.visit(this, null); |
|
|
|
@ -388,6 +417,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o) { |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
ast.type = new SingleFieldTypeDenoter(ast.I, eType, ast.position); |
|
|
|
@ -398,6 +428,7 @@ public final class Checker implements Visitor { |
|
|
|
|
|
|
|
|
|
// Always returns null. Does not use the given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitConstFormalParameter(ConstFormalParameter ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); |
|
|
|
@ -407,6 +438,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitFuncFormalParameter(FuncFormalParameter ast, Object o) { |
|
|
|
|
idTable.openScope(); |
|
|
|
|
ast.FPS.visit(this, null); |
|
|
|
@ -419,6 +451,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitProcFormalParameter(ProcFormalParameter ast, Object o) { |
|
|
|
|
idTable.openScope(); |
|
|
|
|
ast.FPS.visit(this, null); |
|
|
|
@ -430,6 +463,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitVarFormalParameter(VarFormalParameter ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); |
|
|
|
@ -439,16 +473,19 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object o) { |
|
|
|
|
ast.FP.visit(this, null); |
|
|
|
|
ast.FPS.visit(this, null); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object o) { |
|
|
|
|
ast.FP.visit(this, null); |
|
|
|
|
return null; |
|
|
|
@ -458,6 +495,7 @@ public final class Checker implements Visitor { |
|
|
|
|
|
|
|
|
|
// Always returns null. Uses the given FormalParameter.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitConstActualParameter(ConstActualParameter ast, Object o) { |
|
|
|
|
FormalParameter fp = (FormalParameter) o; |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
@ -471,6 +509,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitFuncActualParameter(FuncActualParameter ast, Object o) { |
|
|
|
|
FormalParameter fp = (FormalParameter) o; |
|
|
|
|
|
|
|
|
@ -504,6 +543,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitProcActualParameter(ProcActualParameter ast, Object o) { |
|
|
|
|
FormalParameter fp = (FormalParameter) o; |
|
|
|
|
|
|
|
|
@ -530,6 +570,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitVarActualParameter(VarActualParameter ast, Object o) { |
|
|
|
|
FormalParameter fp = (FormalParameter) o; |
|
|
|
|
|
|
|
|
@ -546,6 +587,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object o) { |
|
|
|
|
FormalParameterSequence fps = (FormalParameterSequence) o; |
|
|
|
|
if (!(fps instanceof EmptyFormalParameterSequence)) |
|
|
|
@ -553,6 +595,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object o) { |
|
|
|
|
FormalParameterSequence fps = (FormalParameterSequence) o; |
|
|
|
|
if (!(fps instanceof MultipleFormalParameterSequence)) |
|
|
|
@ -564,6 +607,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object o) { |
|
|
|
|
FormalParameterSequence fps = (FormalParameterSequence) o; |
|
|
|
|
if (!(fps instanceof SingleFormalParameterSequence)) |
|
|
|
@ -579,10 +623,12 @@ public final class Checker implements Visitor { |
|
|
|
|
// Returns the expanded version of the TypeDenoter. Does not
|
|
|
|
|
// use the given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o) { |
|
|
|
|
return StdEnvironment.anyType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
if ((Integer.valueOf(ast.IL.spelling).intValue()) == 0) |
|
|
|
@ -590,18 +636,22 @@ public final class Checker implements Visitor { |
|
|
|
|
return ast; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o) { |
|
|
|
|
return StdEnvironment.booleanType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitCharTypeDenoter(CharTypeDenoter ast, Object o) { |
|
|
|
|
return StdEnvironment.charType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o) { |
|
|
|
|
return StdEnvironment.errorType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object o) { |
|
|
|
|
Declaration binding = (Declaration) ast.I.visit(this, null); |
|
|
|
|
if (binding == null) { |
|
|
|
@ -615,31 +665,37 @@ public final class Checker implements Visitor { |
|
|
|
|
return ((TypeDeclaration) binding).T; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitIntTypeDenoter(IntTypeDenoter ast, Object o) { |
|
|
|
|
return StdEnvironment.integerType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o) { |
|
|
|
|
ast.FT = (FieldTypeDenoter) ast.FT.visit(this, null); |
|
|
|
|
return ast; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
ast.FT.visit(this, null); |
|
|
|
|
return ast; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
return ast; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Literals, Identifiers and Operators
|
|
|
|
|
@Override |
|
|
|
|
public Object visitCharacterLiteral(CharacterLiteral CL, Object o) { |
|
|
|
|
return StdEnvironment.charType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitIdentifier(Identifier I, Object o) { |
|
|
|
|
Declaration binding = idTable.retrieve(I.spelling); |
|
|
|
|
if (binding != null) |
|
|
|
@ -647,10 +703,12 @@ public final class Checker implements Visitor { |
|
|
|
|
return binding; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitIntegerLiteral(IntegerLiteral IL, Object o) { |
|
|
|
|
return StdEnvironment.integerType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitOperator(Operator O, Object o) { |
|
|
|
|
Declaration binding = idTable.retrieve(O.spelling); |
|
|
|
|
if (binding != null) |
|
|
|
@ -679,6 +737,7 @@ public final class Checker implements Visitor { |
|
|
|
|
// Returns the TypeDenoter of the Vname. Does not use the
|
|
|
|
|
// given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitDotVname(DotVname ast, Object o) { |
|
|
|
|
ast.type = null; |
|
|
|
|
TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); |
|
|
|
@ -694,6 +753,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSimpleVname(SimpleVname ast, Object o) { |
|
|
|
|
ast.variable = false; |
|
|
|
|
ast.type = StdEnvironment.errorType; |
|
|
|
@ -718,6 +778,7 @@ public final class Checker implements Visitor { |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSubscriptVname(SubscriptVname ast, Object o) { |
|
|
|
|
TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); |
|
|
|
|
ast.variable = ast.V.variable; |
|
|
|
@ -737,6 +798,7 @@ public final class Checker implements Visitor { |
|
|
|
|
|
|
|
|
|
// Programs
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitProgram(Program ast, Object o) { |
|
|
|
|
ast.C.visit(this, null); |
|
|
|
|
return null; |
|
|
|
|