🚀 Usage
Go to src
directory and run the following commands
python run.py gen
python run.py test CheckerSuite
This assignment include two main parts:
Support class
class ExprRet:
def __init__(self, type, isInitialized=None):
self.astType = type
self.isInitialized = isInitialized
Support Methods
getASTName()
### `getASTName` function used to get name of AST object
## @param targetObj can be type of AttributeDecl, MethodDecl, VarDecl, ConstDecl, ClassDecl, FieldAccess, ArrayCell, CallExpr, ClassType
def getASTName(self, targetObj) -> str:
searchClassByName()
### `searchClass` function used to find existed class
def searchClassByName(self, name: str) -> ClassDecl:
getMemDeclType()
### `getMemDeclType` function used to get Type of AST member of class
def getMemDeclType(self, memDecl: MemDecl) -> Type:
searchMemberOfClassByName()
### `searchMemberOfClassByName` search a member of other class in global scope
def searchMemberOfClassByName(self, classDecl: ClassDecl, targetMemberName: str) -> MemDecl:
searchMemberByName()
### `searchMemberByName` search a member of current checking class
def searchMemberByName(self, targetMemberName: str) -> MemDecl:
searchDeclByName()
### `searchVarDecl` function used to search a Decl through name
def searchDeclByName(self, targetname: str, visibleScopeDecls: List[Decl]) -> StoreDecl:
checkIsKidOf()
### `checkIsKidOf` function used to check if an object is a child of another by query bottom down
def checkIsKidOf(self, targetChildName: str, targetParentName: str) -> bool:
checkTypeMatch()
### `checkTypeMatch` function used to check if rhs has the same type to lhs or can be con be coerce to lhs
def checkTypeMatch(self, lhsType: Type, rhsType: Type) -> bool:
Static Checker
visitAccess
## @param memDeclType MethodDecl | AttributeDecl
def visitAccess(self, ast, visibleScopeDecls: List[Decl], memDeclType) -> StoreDecl:
this function is used by visitFieldAccess, visitCallExpr, visitCallStmt, visitAssign
this function return the member searched
- check error
Undeclared(errorKind, fieldname)
,IllegalMemberAccess(ast)
visitId
def visitId(self, ast: Id, visibleScopeDecls: List[Decl]) -> Type:
- check error
Undeclared(Identifier(), ast.name)
(this function only check this type of error because theid
checked here is theid
used inexpr
;id
likeclassname
ormethodname
have to be checked in its own function for example:visitClassDecl
,visitMethodDecl
, ... )
visitBinaryOp
def visitBinaryOp(self, ast: BinaryOp, visibleScopeDecls: List[Decl]) -> Type:
- check error
TypeMisMatch(ast)
visitUnaryOp
def visitUnaryOp(self, ast: UnaryOp, visibleScopeDecls: List[Decl]) -> Type:
visitCallExpr
def visitCallExpr(self, ast: CallExpr, visibleScopeDecls: List[Decl]) -> Type:
- check error in visitAccess(),
TypeMismatchInExpression(ast)
visitNewExpr
def visitNewExpr(self, ast: NewExpr, visibleScopeDecls: List[Decl]) -> ExprRet:
- check error
Undeclared(Class(), name)
,Undeclared(Method(), "<init>")
,TypeMismatchInExpression(ast)
visitArrayCell
def visitArrayCell(self, ast: ArrayCell, visibleScopeDecls: List[Decl]) -> ExprRet:
- check error
TypeMismatchInExpression(ast)
visitFieldAccess
def visitFieldAccess(self, ast: FieldAccess, visibleScopeDecls: List[Decl]) -> ExprRet:
- check error in
visitAccess()
visitIntLiteral()
def visitIntLiteral(
self, ast: IntLiteral, visibleScopeDecls: List[Decl]
) -> ExprRet:
visitFloatLiteral()
def visitFloatLiteral(
self, ast: FloatLiteral, visibleScopeDecls: List[Decl]
) -> ExprRet:
visitStringLiteral()
def visitStringLiteral(
self, ast: StringLiteral, visibleScopeDecls: List[Decl]
) -> ExprRet:
visitBoolLiteral()
def visitBooleanLiteral(
self, ast: BooleanLiteral, visibleScopeDecls: List[Decl]
) -> ExprRet:
visitArrayLiteral
def visitArrayLiteral(self, ast: ArrayLiteral, temp) -> ExprRet:
- check error
IllegalArrayLiteral(ast)
visitAssign
def visitAssign(self, ast: Assign, visibleScopeDecls: List[StoreDecl]) -> None:
- check error
Undeclared(Identifier(), lhsName)
- check error
TypeMismatchInStatement(assignStmt)
- check error
CannotAssignToConstant(assignStmt)
(check if lhs is connstant)
visitIf
def visitIf(self, ast: If, visibleScopeDecls: List[StoreDecl]) -> None:
- check error
TypeMismatchInStatement(ast)
visitFor
def visitFor(self, ast: For, visibleScopeDecls: List[StoreDecl]) -> None:
- check error
TypeMismatchInStatement(ast)
visitBreak
def visitBreak(self, ast: Break, visibleScopeDecls: List[StoreDecl]) -> None:
- check error
MustInLoop(ast)
visitContinue
def visitContinue(self, ast: Continue, visibleScopeDecls: List[StoreDecl]) -> None:
- check error
MustInLoop(ast)
visitReturn()
def visitReturn(self, ast :Return, visibleScopeDecls: List[StoreDecl]) -> None:
- check error
TypeMismatchInStatement(ast)
visitCallStmt()
def visitCallStmt(self, ast: CallStmt, visibleScopeDecls: List[StoreDecl]) -> None:
- check error in
visitAccess
andTypeMismatchInStatement(ast)
visitVarDecl
def visitVarDecl(self, ast: VarDecl, visibleScopeDecls: list[StoreDecl]) -> ExprRet:
- check error
TypeMismatchInStatement(Assign(ast.variable, ast.varInit))
visitBlock
def visitBlock(self, ast: Block, visibleScopeDecls: List[Decl]) -> None:
- check error
Redeclared(errorKind, declName)
(only check between declares in block)
visitConstDecl
def visitConstDecl(self, ast: ConstDecl, visibleScopeDecls: List[Decl]) -> ExprRet:
- check error
TypeMismatchInConstant(ast)
,IllegalConstantExpression(ast.value)
visitClassDecl
def visitClassDecl(self, ast: ClassDecl, globalScopeDecls: List[Decl]) -> ClassDecl:
- check error
Redeclared(Class(), classname)
the new class - check error
Undeclared(Class(), parentname)
the parent of new class
visitMethodDecl
def visitMethodDecl(self, ast: MethodDecl, classScopeDecls: List[Decl]) -> MethodDecl:
- check error
Redeclared(Method(), methodName)
of the new method - check error
Redeclared(Parameter(),paramName)
in list of params - check error
Redeclared(StoreDecl, name)
in list of decls ofBlock
(only ifStoreDecl
exist in list ofparameters
)
visitAttributeDecl
def visitAttributeDecl(self, ast: AttributeDecl, classScopeDecls: List[MemDecl]) -> AttributeDecl:
- check error
Redeclared(Attribute(), attributeName)
visitProgram
def visitProgram(self, ast: Program, c) -> None:
- add one existed class
io
to the completely new program - create
globalScopeDecls
store in global