|
|
|
@ -94,7 +94,7 @@ public final class Checker implements Visitor { |
|
|
|
|
// Always returns null. Does not use the given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitAssignCommand(AssignCommand ast, Object o) { |
|
|
|
|
public Object visitAssignCommand(AssignCommand ast, Object o) { |
|
|
|
|
TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
if (!ast.V.variable) |
|
|
|
@ -105,7 +105,7 @@ public Object visitAssignCommand(AssignCommand ast, Object o) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitCallCommand(CallCommand ast, Object o) { |
|
|
|
|
public Object visitCallCommand(CallCommand ast, Object o) { |
|
|
|
|
|
|
|
|
|
Declaration binding = (Declaration) ast.I.visit(this, null); |
|
|
|
|
if (binding == null) |
|
|
|
@ -115,18 +115,17 @@ public Object visitCallCommand(CallCommand ast, Object o) { |
|
|
|
|
} else if (binding instanceof ProcFormalParameter) { |
|
|
|
|
ast.APS.visit(this, ((ProcFormalParameter) binding).FPS); |
|
|
|
|
} else |
|
|
|
|
reporter.reportError("\"%\" is not a procedure identifier", |
|
|
|
|
ast.I.spelling, ast.I.position); |
|
|
|
|
reporter.reportError("\"%\" is not a procedure identifier", ast.I.spelling, ast.I.position); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitEmptyCommand(EmptyCommand ast, Object o) { |
|
|
|
|
public Object visitEmptyCommand(EmptyCommand ast, Object o) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitIfCommand(IfCommand ast, Object o) { |
|
|
|
|
public Object visitIfCommand(IfCommand ast, Object o) { |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
if (!eType.equals(StdEnvironment.booleanType)) |
|
|
|
|
reporter.reportError("Boolean expression expected here", "", ast.E.position); |
|
|
|
@ -136,7 +135,7 @@ public Object visitIfCommand(IfCommand ast, Object o) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitLetCommand(LetCommand ast, Object o) { |
|
|
|
|
public Object visitLetCommand(LetCommand ast, Object o) { |
|
|
|
|
idTable.openScope(); |
|
|
|
|
ast.D.visit(this, null); |
|
|
|
|
ast.C.visit(this, null); |
|
|
|
@ -145,14 +144,14 @@ public Object visitLetCommand(LetCommand ast, Object o) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSequentialCommand(SequentialCommand ast, Object o) { |
|
|
|
|
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) { |
|
|
|
|
public Object visitWhileCommand(WhileCommand ast, Object o) { |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
if (!eType.equals(StdEnvironment.booleanType)) |
|
|
|
|
reporter.reportError("Boolean expression expected here", "", ast.E.position); |
|
|
|
@ -166,16 +165,15 @@ public Object visitWhileCommand(WhileCommand ast, Object o) { |
|
|
|
|
// not use the given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitArrayExpression(ArrayExpression ast, Object o) { |
|
|
|
|
public Object visitArrayExpression(ArrayExpression ast, Object o) { |
|
|
|
|
TypeDenoter elemType = (TypeDenoter) ast.AA.visit(this, null); |
|
|
|
|
IntegerLiteral il = new IntegerLiteral(Integer.valueOf(ast.AA.elemCount).toString(), |
|
|
|
|
ast.position); |
|
|
|
|
IntegerLiteral il = new IntegerLiteral(Integer.valueOf(ast.AA.elemCount).toString(), ast.position); |
|
|
|
|
ast.type = new ArrayTypeDenoter(il, elemType, ast.position); |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitBinaryExpression(BinaryExpression ast, Object o) { |
|
|
|
|
public Object visitBinaryExpression(BinaryExpression ast, Object o) { |
|
|
|
|
|
|
|
|
|
TypeDenoter e1Type = (TypeDenoter) ast.E1.visit(this, null); |
|
|
|
|
TypeDenoter e2Type = (TypeDenoter) ast.E2.visit(this, null); |
|
|
|
@ -185,27 +183,23 @@ public Object visitBinaryExpression(BinaryExpression ast, Object o) { |
|
|
|
|
reportUndeclared(ast.O); |
|
|
|
|
else { |
|
|
|
|
if (!(binding instanceof BinaryOperatorDeclaration)) |
|
|
|
|
reporter.reportError("\"%\" is not a binary operator", |
|
|
|
|
ast.O.spelling, ast.O.position); |
|
|
|
|
reporter.reportError("\"%\" is not a binary operator", ast.O.spelling, ast.O.position); |
|
|
|
|
BinaryOperatorDeclaration bbinding = (BinaryOperatorDeclaration) binding; |
|
|
|
|
if (bbinding.ARG1 == StdEnvironment.anyType) { |
|
|
|
|
// this operator must be "=" or "\="
|
|
|
|
|
if (!e1Type.equals(e2Type)) |
|
|
|
|
reporter.reportError("incompatible argument types for \"%\"", |
|
|
|
|
ast.O.spelling, ast.position); |
|
|
|
|
reporter.reportError("incompatible argument types for \"%\"", ast.O.spelling, ast.position); |
|
|
|
|
} else if (!e1Type.equals(bbinding.ARG1)) |
|
|
|
|
reporter.reportError("wrong argument type for \"%\"", |
|
|
|
|
ast.O.spelling, ast.E1.position); |
|
|
|
|
reporter.reportError("wrong argument type for \"%\"", ast.O.spelling, ast.E1.position); |
|
|
|
|
else if (!e2Type.equals(bbinding.ARG2)) |
|
|
|
|
reporter.reportError("wrong argument type for \"%\"", |
|
|
|
|
ast.O.spelling, ast.E2.position); |
|
|
|
|
reporter.reportError("wrong argument type for \"%\"", ast.O.spelling, ast.E2.position); |
|
|
|
|
ast.type = bbinding.RES; |
|
|
|
|
} |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitCallExpression(CallExpression ast, Object o) { |
|
|
|
|
public Object visitCallExpression(CallExpression ast, Object o) { |
|
|
|
|
Declaration binding = (Declaration) ast.I.visit(this, null); |
|
|
|
|
if (binding == null) { |
|
|
|
|
reportUndeclared(ast.I); |
|
|
|
@ -217,29 +211,27 @@ public Object visitCallExpression(CallExpression ast, Object o) { |
|
|
|
|
ast.APS.visit(this, ((FuncFormalParameter) binding).FPS); |
|
|
|
|
ast.type = ((FuncFormalParameter) binding).T; |
|
|
|
|
} else |
|
|
|
|
reporter.reportError("\"%\" is not a function identifier", |
|
|
|
|
ast.I.spelling, ast.I.position); |
|
|
|
|
reporter.reportError("\"%\" is not a function identifier", ast.I.spelling, ast.I.position); |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitCharacterExpression(CharacterExpression ast, Object o) { |
|
|
|
|
public Object visitCharacterExpression(CharacterExpression ast, Object o) { |
|
|
|
|
ast.type = StdEnvironment.charType; |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitEmptyExpression(EmptyExpression ast, Object o) { |
|
|
|
|
public Object visitEmptyExpression(EmptyExpression ast, Object o) { |
|
|
|
|
ast.type = null; |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitIfExpression(IfExpression ast, Object o) { |
|
|
|
|
public Object visitIfExpression(IfExpression ast, Object o) { |
|
|
|
|
TypeDenoter e1Type = (TypeDenoter) ast.E1.visit(this, null); |
|
|
|
|
if (!e1Type.equals(StdEnvironment.booleanType)) |
|
|
|
|
reporter.reportError("Boolean expression expected here", "", |
|
|
|
|
ast.E1.position); |
|
|
|
|
reporter.reportError("Boolean expression expected here", "", ast.E1.position); |
|
|
|
|
TypeDenoter e2Type = (TypeDenoter) ast.E2.visit(this, null); |
|
|
|
|
TypeDenoter e3Type = (TypeDenoter) ast.E3.visit(this, null); |
|
|
|
|
if (!e2Type.equals(e3Type)) |
|
|
|
@ -249,13 +241,13 @@ public Object visitIfExpression(IfExpression ast, Object o) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitIntegerExpression(IntegerExpression ast, Object o) { |
|
|
|
|
public Object visitIntegerExpression(IntegerExpression ast, Object o) { |
|
|
|
|
ast.type = StdEnvironment.integerType; |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitLetExpression(LetExpression ast, Object o) { |
|
|
|
|
public Object visitLetExpression(LetExpression ast, Object o) { |
|
|
|
|
idTable.openScope(); |
|
|
|
|
ast.D.visit(this, null); |
|
|
|
|
ast.type = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
@ -264,14 +256,14 @@ public Object visitLetExpression(LetExpression ast, Object o) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitRecordExpression(RecordExpression ast, Object o) { |
|
|
|
|
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) { |
|
|
|
|
public Object visitUnaryExpression(UnaryExpression ast, Object o) { |
|
|
|
|
|
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
Declaration binding = (Declaration) ast.O.visit(this, null); |
|
|
|
@ -279,20 +271,18 @@ public Object visitUnaryExpression(UnaryExpression ast, Object o) { |
|
|
|
|
reportUndeclared(ast.O); |
|
|
|
|
ast.type = StdEnvironment.errorType; |
|
|
|
|
} else if (!(binding instanceof UnaryOperatorDeclaration)) |
|
|
|
|
reporter.reportError("\"%\" is not a unary operator", |
|
|
|
|
ast.O.spelling, ast.O.position); |
|
|
|
|
reporter.reportError("\"%\" is not a unary operator", ast.O.spelling, ast.O.position); |
|
|
|
|
else { |
|
|
|
|
UnaryOperatorDeclaration ubinding = (UnaryOperatorDeclaration) binding; |
|
|
|
|
if (!eType.equals(ubinding.ARG)) |
|
|
|
|
reporter.reportError("wrong argument type for \"%\"", |
|
|
|
|
ast.O.spelling, ast.O.position); |
|
|
|
|
reporter.reportError("wrong argument type for \"%\"", ast.O.spelling, ast.O.position); |
|
|
|
|
ast.type = ubinding.RES; |
|
|
|
|
} |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitVnameExpression(VnameExpression ast, Object o) { |
|
|
|
|
public Object visitVnameExpression(VnameExpression ast, Object o) { |
|
|
|
|
ast.type = (TypeDenoter) ast.V.visit(this, null); |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
@ -301,43 +291,39 @@ public Object visitVnameExpression(VnameExpression ast, Object o) { |
|
|
|
|
|
|
|
|
|
// Always returns null. Does not use the given object.
|
|
|
|
|
@Override |
|
|
|
|
public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o) { |
|
|
|
|
public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitConstDeclaration(ConstDeclaration ast, Object o) { |
|
|
|
|
public Object visitConstDeclaration(ConstDeclaration ast, Object o) { |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); |
|
|
|
|
if (ast.duplicated) |
|
|
|
|
reporter.reportError("identifier \"%\" already declared", |
|
|
|
|
ast.I.spelling, ast.position); |
|
|
|
|
reporter.reportError("identifier \"%\" already declared", ast.I.spelling, ast.position); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitFuncDeclaration(FuncDeclaration ast, Object o) { |
|
|
|
|
public Object visitFuncDeclaration(FuncDeclaration ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); // permits recursion
|
|
|
|
|
if (ast.duplicated) |
|
|
|
|
reporter.reportError("identifier \"%\" already declared", |
|
|
|
|
ast.I.spelling, ast.position); |
|
|
|
|
reporter.reportError("identifier \"%\" already declared", ast.I.spelling, ast.position); |
|
|
|
|
idTable.openScope(); |
|
|
|
|
ast.FPS.visit(this, null); |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
idTable.closeScope(); |
|
|
|
|
if (!ast.T.equals(eType)) |
|
|
|
|
reporter.reportError("body of function \"%\" has wrong type", |
|
|
|
|
ast.I.spelling, ast.E.position); |
|
|
|
|
reporter.reportError("body of function \"%\" has wrong type", ast.I.spelling, ast.E.position); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitProcDeclaration(ProcDeclaration ast, Object o) { |
|
|
|
|
public Object visitProcDeclaration(ProcDeclaration ast, Object o) { |
|
|
|
|
idTable.enter(ast.I.spelling, ast); // permits recursion
|
|
|
|
|
if (ast.duplicated) |
|
|
|
|
reporter.reportError("identifier \"%\" already declared", |
|
|
|
|
ast.I.spelling, ast.position); |
|
|
|
|
reporter.reportError("identifier \"%\" already declared", ast.I.spelling, ast.position); |
|
|
|
|
idTable.openScope(); |
|
|
|
|
ast.FPS.visit(this, null); |
|
|
|
|
ast.C.visit(this, null); |
|
|
|
@ -346,34 +332,32 @@ public Object visitProcDeclaration(ProcDeclaration ast, Object o) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSequentialDeclaration(SequentialDeclaration ast, Object o) { |
|
|
|
|
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) { |
|
|
|
|
public Object visitTypeDeclaration(TypeDeclaration ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); |
|
|
|
|
if (ast.duplicated) |
|
|
|
|
reporter.reportError("identifier \"%\" already declared", |
|
|
|
|
ast.I.spelling, ast.position); |
|
|
|
|
reporter.reportError("identifier \"%\" already declared", ast.I.spelling, ast.position); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o) { |
|
|
|
|
public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitVarDeclaration(VarDeclaration ast, Object o) { |
|
|
|
|
public Object visitVarDeclaration(VarDeclaration ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); |
|
|
|
|
if (ast.duplicated) |
|
|
|
|
reporter.reportError("identifier \"%\" already declared", |
|
|
|
|
ast.I.spelling, ast.position); |
|
|
|
|
reporter.reportError("identifier \"%\" already declared", ast.I.spelling, ast.position); |
|
|
|
|
|
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
@ -384,7 +368,7 @@ public Object visitVarDeclaration(VarDeclaration ast, Object o) { |
|
|
|
|
// given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o) { |
|
|
|
|
public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o) { |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
TypeDenoter elemType = (TypeDenoter) ast.AA.visit(this, null); |
|
|
|
|
ast.elemCount = ast.AA.elemCount + 1; |
|
|
|
@ -394,7 +378,7 @@ public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o) { |
|
|
|
|
public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o) { |
|
|
|
|
TypeDenoter elemType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
ast.elemCount = 1; |
|
|
|
|
return elemType; |
|
|
|
@ -406,19 +390,18 @@ public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o) { |
|
|
|
|
// given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object o) { |
|
|
|
|
public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object o) { |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
FieldTypeDenoter rType = (FieldTypeDenoter) ast.RA.visit(this, null); |
|
|
|
|
TypeDenoter fType = checkFieldIdentifier(rType, ast.I); |
|
|
|
|
if (fType != StdEnvironment.errorType) |
|
|
|
|
reporter.reportError("duplicate field \"%\" in record", |
|
|
|
|
ast.I.spelling, ast.I.position); |
|
|
|
|
reporter.reportError("duplicate field \"%\" in record", ast.I.spelling, ast.I.position); |
|
|
|
|
ast.type = new MultipleFieldTypeDenoter(ast.I, eType, rType, ast.position); |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o) { |
|
|
|
|
public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o) { |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
ast.type = new SingleFieldTypeDenoter(ast.I, eType, ast.position); |
|
|
|
|
return ast.type; |
|
|
|
@ -429,64 +412,60 @@ public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o) { |
|
|
|
|
// Always returns null. Does not use the given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitConstFormalParameter(ConstFormalParameter ast, Object o) { |
|
|
|
|
public Object visitConstFormalParameter(ConstFormalParameter ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); |
|
|
|
|
if (ast.duplicated) |
|
|
|
|
reporter.reportError("duplicated formal parameter \"%\"", |
|
|
|
|
ast.I.spelling, ast.position); |
|
|
|
|
reporter.reportError("duplicated formal parameter \"%\"", ast.I.spelling, ast.position); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitFuncFormalParameter(FuncFormalParameter ast, Object o) { |
|
|
|
|
public Object visitFuncFormalParameter(FuncFormalParameter ast, Object o) { |
|
|
|
|
idTable.openScope(); |
|
|
|
|
ast.FPS.visit(this, null); |
|
|
|
|
idTable.closeScope(); |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); |
|
|
|
|
if (ast.duplicated) |
|
|
|
|
reporter.reportError("duplicated formal parameter \"%\"", |
|
|
|
|
ast.I.spelling, ast.position); |
|
|
|
|
reporter.reportError("duplicated formal parameter \"%\"", ast.I.spelling, ast.position); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitProcFormalParameter(ProcFormalParameter ast, Object o) { |
|
|
|
|
public Object visitProcFormalParameter(ProcFormalParameter ast, Object o) { |
|
|
|
|
idTable.openScope(); |
|
|
|
|
ast.FPS.visit(this, null); |
|
|
|
|
idTable.closeScope(); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); |
|
|
|
|
if (ast.duplicated) |
|
|
|
|
reporter.reportError("duplicated formal parameter \"%\"", |
|
|
|
|
ast.I.spelling, ast.position); |
|
|
|
|
reporter.reportError("duplicated formal parameter \"%\"", ast.I.spelling, ast.position); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitVarFormalParameter(VarFormalParameter ast, Object o) { |
|
|
|
|
public Object visitVarFormalParameter(VarFormalParameter ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
idTable.enter(ast.I.spelling, ast); |
|
|
|
|
if (ast.duplicated) |
|
|
|
|
reporter.reportError("duplicated formal parameter \"%\"", |
|
|
|
|
ast.I.spelling, ast.position); |
|
|
|
|
reporter.reportError("duplicated formal parameter \"%\"", ast.I.spelling, ast.position); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o) { |
|
|
|
|
public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object o) { |
|
|
|
|
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) { |
|
|
|
|
public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object o) { |
|
|
|
|
ast.FP.visit(this, null); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
@ -496,33 +475,28 @@ public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence a |
|
|
|
|
// Always returns null. Uses the given FormalParameter.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitConstActualParameter(ConstActualParameter ast, Object o) { |
|
|
|
|
public Object visitConstActualParameter(ConstActualParameter ast, Object o) { |
|
|
|
|
FormalParameter fp = (FormalParameter) o; |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
|
|
|
|
|
|
if (!(fp instanceof ConstFormalParameter)) |
|
|
|
|
reporter.reportError("const actual parameter not expected here", "", |
|
|
|
|
ast.position); |
|
|
|
|
reporter.reportError("const actual parameter not expected here", "", ast.position); |
|
|
|
|
else if (!eType.equals(((ConstFormalParameter) fp).T)) |
|
|
|
|
reporter.reportError("wrong type for const actual parameter", "", |
|
|
|
|
ast.E.position); |
|
|
|
|
reporter.reportError("wrong type for const actual parameter", "", ast.E.position); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitFuncActualParameter(FuncActualParameter ast, Object o) { |
|
|
|
|
public Object visitFuncActualParameter(FuncActualParameter ast, Object o) { |
|
|
|
|
FormalParameter fp = (FormalParameter) o; |
|
|
|
|
|
|
|
|
|
Declaration binding = (Declaration) ast.I.visit(this, null); |
|
|
|
|
if (binding == null) |
|
|
|
|
reportUndeclared(ast.I); |
|
|
|
|
else if (!(binding instanceof FuncDeclaration || |
|
|
|
|
binding instanceof FuncFormalParameter)) |
|
|
|
|
reporter.reportError("\"%\" is not a function identifier", |
|
|
|
|
ast.I.spelling, ast.I.position); |
|
|
|
|
else if (!(binding instanceof FuncDeclaration || binding instanceof FuncFormalParameter)) |
|
|
|
|
reporter.reportError("\"%\" is not a function identifier", ast.I.spelling, ast.I.position); |
|
|
|
|
else if (!(fp instanceof FuncFormalParameter)) |
|
|
|
|
reporter.reportError("func actual parameter not expected here", "", |
|
|
|
|
ast.position); |
|
|
|
|
reporter.reportError("func actual parameter not expected here", "", ast.position); |
|
|
|
|
else { |
|
|
|
|
FormalParameterSequence FPS = null; |
|
|
|
|
TypeDenoter T = null; |
|
|
|
@ -534,29 +508,24 @@ public Object visitFuncActualParameter(FuncActualParameter ast, Object o) { |
|
|
|
|
T = ((FuncFormalParameter) binding).T; |
|
|
|
|
} |
|
|
|
|
if (!FPS.equals(((FuncFormalParameter) fp).FPS)) |
|
|
|
|
reporter.reportError("wrong signature for function \"%\"", |
|
|
|
|
ast.I.spelling, ast.I.position); |
|
|
|
|
reporter.reportError("wrong signature for function \"%\"", ast.I.spelling, ast.I.position); |
|
|
|
|
else if (!T.equals(((FuncFormalParameter) fp).T)) |
|
|
|
|
reporter.reportError("wrong type for function \"%\"", |
|
|
|
|
ast.I.spelling, ast.I.position); |
|
|
|
|
reporter.reportError("wrong type for function \"%\"", ast.I.spelling, ast.I.position); |
|
|
|
|
} |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitProcActualParameter(ProcActualParameter ast, Object o) { |
|
|
|
|
public Object visitProcActualParameter(ProcActualParameter ast, Object o) { |
|
|
|
|
FormalParameter fp = (FormalParameter) o; |
|
|
|
|
|
|
|
|
|
Declaration binding = (Declaration) ast.I.visit(this, null); |
|
|
|
|
if (binding == null) |
|
|
|
|
reportUndeclared(ast.I); |
|
|
|
|
else if (!(binding instanceof ProcDeclaration || |
|
|
|
|
binding instanceof ProcFormalParameter)) |
|
|
|
|
reporter.reportError("\"%\" is not a procedure identifier", |
|
|
|
|
ast.I.spelling, ast.I.position); |
|
|
|
|
else if (!(binding instanceof ProcDeclaration || binding instanceof ProcFormalParameter)) |
|
|
|
|
reporter.reportError("\"%\" is not a procedure identifier", ast.I.spelling, ast.I.position); |
|
|
|
|
else if (!(fp instanceof ProcFormalParameter)) |
|
|
|
|
reporter.reportError("proc actual parameter not expected here", "", |
|
|
|
|
ast.position); |
|
|
|
|
reporter.reportError("proc actual parameter not expected here", "", ast.position); |
|
|
|
|
else { |
|
|
|
|
FormalParameterSequence FPS = null; |
|
|
|
|
if (binding instanceof ProcDeclaration) |
|
|
|
@ -564,31 +533,27 @@ public Object visitProcActualParameter(ProcActualParameter ast, Object o) { |
|
|
|
|
else |
|
|
|
|
FPS = ((ProcFormalParameter) binding).FPS; |
|
|
|
|
if (!FPS.equals(((ProcFormalParameter) fp).FPS)) |
|
|
|
|
reporter.reportError("wrong signature for procedure \"%\"", |
|
|
|
|
ast.I.spelling, ast.I.position); |
|
|
|
|
reporter.reportError("wrong signature for procedure \"%\"", ast.I.spelling, ast.I.position); |
|
|
|
|
} |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitVarActualParameter(VarActualParameter ast, Object o) { |
|
|
|
|
public Object visitVarActualParameter(VarActualParameter ast, Object o) { |
|
|
|
|
FormalParameter fp = (FormalParameter) o; |
|
|
|
|
|
|
|
|
|
TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); |
|
|
|
|
if (!ast.V.variable) |
|
|
|
|
reporter.reportError("actual parameter is not a variable", "", |
|
|
|
|
ast.V.position); |
|
|
|
|
reporter.reportError("actual parameter is not a variable", "", ast.V.position); |
|
|
|
|
else if (!(fp instanceof VarFormalParameter)) |
|
|
|
|
reporter.reportError("var actual parameter not expected here", "", |
|
|
|
|
ast.V.position); |
|
|
|
|
reporter.reportError("var actual parameter not expected here", "", ast.V.position); |
|
|
|
|
else if (!vType.equals(((VarFormalParameter) fp).T)) |
|
|
|
|
reporter.reportError("wrong type for var actual parameter", "", |
|
|
|
|
ast.V.position); |
|
|
|
|
reporter.reportError("wrong type for var actual parameter", "", ast.V.position); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object o) { |
|
|
|
|
public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object o) { |
|
|
|
|
FormalParameterSequence fps = (FormalParameterSequence) o; |
|
|
|
|
if (!(fps instanceof EmptyFormalParameterSequence)) |
|
|
|
|
reporter.reportError("too few actual parameters", "", ast.position); |
|
|
|
@ -596,7 +561,7 @@ public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object o) { |
|
|
|
|
public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object o) { |
|
|
|
|
FormalParameterSequence fps = (FormalParameterSequence) o; |
|
|
|
|
if (!(fps instanceof MultipleFormalParameterSequence)) |
|
|
|
|
reporter.reportError("too many actual parameters", "", ast.position); |
|
|
|
@ -608,7 +573,7 @@ public Object visitMultipleActualParameterSequence(MultipleActualParameterSequen |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object o) { |
|
|
|
|
public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object o) { |
|
|
|
|
FormalParameterSequence fps = (FormalParameterSequence) o; |
|
|
|
|
if (!(fps instanceof SingleFormalParameterSequence)) |
|
|
|
|
reporter.reportError("incorrect number of actual parameters", "", ast.position); |
|
|
|
@ -624,12 +589,12 @@ public Object visitSingleActualParameterSequence(SingleActualParameterSequence a |
|
|
|
|
// use the given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o) { |
|
|
|
|
public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o) { |
|
|
|
|
return StdEnvironment.anyType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o) { |
|
|
|
|
public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o) { |
|
|
|
|
ast.T = (TypeDenoter) ast.T.visit(this, null); |
|
|
|
|
if ((Integer.valueOf(ast.IL.spelling).intValue()) == 0) |
|
|
|
|
reporter.reportError("arrays must not be empty", "", ast.IL.position); |
|
|
|
@ -637,66 +602,65 @@ public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o) { |
|
|
|
|
public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o) { |
|
|
|
|
return StdEnvironment.booleanType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitCharTypeDenoter(CharTypeDenoter ast, Object o) { |
|
|
|
|
public Object visitCharTypeDenoter(CharTypeDenoter ast, Object o) { |
|
|
|
|
return StdEnvironment.charType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o) { |
|
|
|
|
public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o) { |
|
|
|
|
return StdEnvironment.errorType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object o) { |
|
|
|
|
public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object o) { |
|
|
|
|
Declaration binding = (Declaration) ast.I.visit(this, null); |
|
|
|
|
if (binding == null) { |
|
|
|
|
reportUndeclared(ast.I); |
|
|
|
|
return StdEnvironment.errorType; |
|
|
|
|
} else if (!(binding instanceof TypeDeclaration)) { |
|
|
|
|
reporter.reportError("\"%\" is not a type identifier", |
|
|
|
|
ast.I.spelling, ast.I.position); |
|
|
|
|
reporter.reportError("\"%\" is not a type identifier", ast.I.spelling, ast.I.position); |
|
|
|
|
return StdEnvironment.errorType; |
|
|
|
|
} |
|
|
|
|
return ((TypeDeclaration) binding).T; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitIntTypeDenoter(IntTypeDenoter ast, Object o) { |
|
|
|
|
public Object visitIntTypeDenoter(IntTypeDenoter ast, Object o) { |
|
|
|
|
return StdEnvironment.integerType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o) { |
|
|
|
|
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) { |
|
|
|
|
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) { |
|
|
|
|
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) { |
|
|
|
|
public Object visitCharacterLiteral(CharacterLiteral CL, Object o) { |
|
|
|
|
return StdEnvironment.charType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitIdentifier(Identifier I, Object o) { |
|
|
|
|
public Object visitIdentifier(Identifier I, Object o) { |
|
|
|
|
Declaration binding = idTable.retrieve(I.spelling); |
|
|
|
|
if (binding != null) |
|
|
|
|
I.decl = binding; |
|
|
|
@ -704,12 +668,12 @@ public Object visitIdentifier(Identifier I, Object o) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitIntegerLiteral(IntegerLiteral IL, Object o) { |
|
|
|
|
public Object visitIntegerLiteral(IntegerLiteral IL, Object o) { |
|
|
|
|
return StdEnvironment.integerType; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitOperator(Operator O, Object o) { |
|
|
|
|
public Object visitOperator(Operator O, Object o) { |
|
|
|
|
Declaration binding = idTable.retrieve(O.spelling); |
|
|
|
|
if (binding != null) |
|
|
|
|
O.decl = binding; |
|
|
|
@ -738,7 +702,7 @@ public Object visitOperator(Operator O, Object o) { |
|
|
|
|
// given object.
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitDotVname(DotVname ast, Object o) { |
|
|
|
|
public Object visitDotVname(DotVname ast, Object o) { |
|
|
|
|
ast.type = null; |
|
|
|
|
TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); |
|
|
|
|
ast.variable = ast.V.variable; |
|
|
|
@ -747,14 +711,13 @@ public Object visitDotVname(DotVname ast, Object o) { |
|
|
|
|
else { |
|
|
|
|
ast.type = checkFieldIdentifier(((RecordTypeDenoter) vType).FT, ast.I); |
|
|
|
|
if (ast.type == StdEnvironment.errorType) |
|
|
|
|
reporter.reportError("no field \"%\" in this record type", |
|
|
|
|
ast.I.spelling, ast.I.position); |
|
|
|
|
reporter.reportError("no field \"%\" in this record type", ast.I.spelling, ast.I.position); |
|
|
|
|
} |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSimpleVname(SimpleVname ast, Object o) { |
|
|
|
|
public Object visitSimpleVname(SimpleVname ast, Object o) { |
|
|
|
|
ast.variable = false; |
|
|
|
|
ast.type = StdEnvironment.errorType; |
|
|
|
|
Declaration binding = (Declaration) ast.I.visit(this, null); |
|
|
|
@ -773,13 +736,12 @@ public Object visitSimpleVname(SimpleVname ast, Object o) { |
|
|
|
|
ast.type = ((VarFormalParameter) binding).T; |
|
|
|
|
ast.variable = true; |
|
|
|
|
} else |
|
|
|
|
reporter.reportError("\"%\" is not a const or var identifier", |
|
|
|
|
ast.I.spelling, ast.I.position); |
|
|
|
|
reporter.reportError("\"%\" is not a const or var identifier", ast.I.spelling, ast.I.position); |
|
|
|
|
return ast.type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitSubscriptVname(SubscriptVname ast, Object o) { |
|
|
|
|
public Object visitSubscriptVname(SubscriptVname ast, Object o) { |
|
|
|
|
TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); |
|
|
|
|
ast.variable = ast.V.variable; |
|
|
|
|
TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); |
|
|
|
@ -788,8 +750,7 @@ public Object visitSubscriptVname(SubscriptVname ast, Object o) { |
|
|
|
|
reporter.reportError("array expected here", "", ast.V.position); |
|
|
|
|
else { |
|
|
|
|
if (!eType.equals(StdEnvironment.integerType)) |
|
|
|
|
reporter.reportError("Integer expression expected here", "", |
|
|
|
|
ast.E.position); |
|
|
|
|
reporter.reportError("Integer expression expected here", "", ast.E.position); |
|
|
|
|
ast.type = ((ArrayTypeDenoter) vType).T; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -799,7 +760,7 @@ public Object visitSubscriptVname(SubscriptVname ast, Object o) { |
|
|
|
|
// Programs
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Object visitProgram(Program ast, Object o) { |
|
|
|
|
public Object visitProgram(Program ast, Object o) { |
|
|
|
|
ast.C.visit(this, null); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
@ -890,8 +851,7 @@ public Object visitProgram(Program ast, Object o) { |
|
|
|
|
|
|
|
|
|
ProcDeclaration binding; |
|
|
|
|
|
|
|
|
|
binding = new ProcDeclaration(new Identifier(id, dummyPos), fps, |
|
|
|
|
new EmptyCommand(dummyPos), dummyPos); |
|
|
|
|
binding = new ProcDeclaration(new Identifier(id, dummyPos), fps, new EmptyCommand(dummyPos), dummyPos); |
|
|
|
|
idTable.enter(id, binding); |
|
|
|
|
return binding; |
|
|
|
|
} |
|
|
|
@ -899,13 +859,12 @@ public Object visitProgram(Program ast, Object o) { |
|
|
|
|
// Creates a small AST to represent the "declaration" of a standard
|
|
|
|
|
// type, and enters it in the identification table.
|
|
|
|
|
|
|
|
|
|
private FuncDeclaration declareStdFunc(String id, FormalParameterSequence fps, |
|
|
|
|
TypeDenoter resultType) { |
|
|
|
|
private FuncDeclaration declareStdFunc(String id, FormalParameterSequence fps, TypeDenoter resultType) { |
|
|
|
|
|
|
|
|
|
FuncDeclaration binding; |
|
|
|
|
|
|
|
|
|
binding = new FuncDeclaration(new Identifier(id, dummyPos), fps, resultType, |
|
|
|
|
new EmptyExpression(dummyPos), dummyPos); |
|
|
|
|
binding = new FuncDeclaration(new Identifier(id, dummyPos), fps, resultType, new EmptyExpression(dummyPos), |
|
|
|
|
dummyPos); |
|
|
|
|
idTable.enter(id, binding); |
|
|
|
|
return binding; |
|
|
|
|
} |
|
|
|
@ -918,8 +877,7 @@ public Object visitProgram(Program ast, Object o) { |
|
|
|
|
|
|
|
|
|
UnaryOperatorDeclaration binding; |
|
|
|
|
|
|
|
|
|
binding = new UnaryOperatorDeclaration(new Operator(op, dummyPos), |
|
|
|
|
argType, resultType, dummyPos); |
|
|
|
|
binding = new UnaryOperatorDeclaration(new Operator(op, dummyPos), argType, resultType, dummyPos); |
|
|
|
|
idTable.enter(op, binding); |
|
|
|
|
return binding; |
|
|
|
|
} |
|
|
|
@ -933,8 +891,7 @@ public Object visitProgram(Program ast, Object o) { |
|
|
|
|
|
|
|
|
|
BinaryOperatorDeclaration binding; |
|
|
|
|
|
|
|
|
|
binding = new BinaryOperatorDeclaration(new Operator(op, dummyPos), |
|
|
|
|
arg1Type, arg2type, resultType, dummyPos); |
|
|
|
|
binding = new BinaryOperatorDeclaration(new Operator(op, dummyPos), arg1Type, arg2type, resultType, dummyPos); |
|
|
|
|
idTable.enter(op, binding); |
|
|
|
|
return binding; |
|
|
|
|
} |
|
|
|
@ -986,10 +943,14 @@ public Object visitProgram(Program ast, Object o) { |
|
|
|
|
StdEnvironment.booleanType); |
|
|
|
|
|
|
|
|
|
StdEnvironment.charDecl = declareStdType("Char", StdEnvironment.charType); |
|
|
|
|
StdEnvironment.chrDecl = declareStdFunc("chr", new SingleFormalParameterSequence( |
|
|
|
|
new ConstFormalParameter(dummyI, StdEnvironment.integerType, dummyPos), dummyPos), StdEnvironment.charType); |
|
|
|
|
StdEnvironment.ordDecl = declareStdFunc("ord", new SingleFormalParameterSequence( |
|
|
|
|
new ConstFormalParameter(dummyI, StdEnvironment.charType, dummyPos), dummyPos), StdEnvironment.integerType); |
|
|
|
|
StdEnvironment.chrDecl = declareStdFunc("chr", |
|
|
|
|
new SingleFormalParameterSequence( |
|
|
|
|
new ConstFormalParameter(dummyI, StdEnvironment.integerType, dummyPos), dummyPos), |
|
|
|
|
StdEnvironment.charType); |
|
|
|
|
StdEnvironment.ordDecl = declareStdFunc("ord", |
|
|
|
|
new SingleFormalParameterSequence(new ConstFormalParameter(dummyI, StdEnvironment.charType, dummyPos), |
|
|
|
|
dummyPos), |
|
|
|
|
StdEnvironment.integerType); |
|
|
|
|
StdEnvironment.eofDecl = declareStdFunc("eof", new EmptyFormalParameterSequence(dummyPos), |
|
|
|
|
StdEnvironment.booleanType); |
|
|
|
|
StdEnvironment.eolDecl = declareStdFunc("eol", new EmptyFormalParameterSequence(dummyPos), |
|
|
|
|