import bkool.parser._
import bkool.utils._
import java.io.{PrintWriter, File}
import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree._
import scala.collection.JavaConverters._
class StaticChecker(ast: AST) {
def check() = {
try {
val bkdecl = new Global()
val env = bkdecl.visit(ast, null).asInstanceOf[ListSymbol]
} catch {
case Redeclared(k, n) => throw Redeclared(k, n)
}
}
}
case class ListSymbol(list: List[String]) extends Context
class Global extends BKVisitor{
override def visitProgram(ast: Program, c: Context) = ast.decl.foldLeft(ListSymbol(List[String]((""))))((x, y) => visit(y, x).asInstanceOf[ListSymbol])
override def visitClassDecl(ast: ClassDecl, c: Context) = {
val env = c.asInstanceOf[ListSymbol].list
val newenv = if (env.exists(x => x == ast.name.toString())) throw Redeclared(Class, ast.name.toString()) else (ast.name.toString()) :: env
ast.decl.foldLeft(ListSymbol(List[String]()).asInstanceOf[Context])((x, y) => visit(y, x).asInstanceOf[ListSymbol])
ListSymbol(newenv)
}
override def visitMethodDecl(ast: MethodDecl, c: Context) = {
val env = c.asInstanceOf[ListSymbol].list
if (env.exists(x => x == ast.name.toString())) throw Redeclared(Method, ast.name.name)
val newenv = if (env.exists(x => x == ast.name.toString())) throw Redeclared(Method, ast.name.name) else (ast.name.toString()) :: env
ListSymbol(newenv)
}
override def visitAttributeDecl(ast: AttributeDecl, c: Context) = {
val decl = ast.decl
val env = c.asInstanceOf[ListSymbol].list
decl match {
case VarDecl(a, b) => {
val newenv = if (env.exists(x => x == a.toString())) throw Redeclared(Attribute, a.toString()) else (a.toString()) :: env
ListSymbol(newenv)
}
case ConstDecl(a, b, _) => {
val newenv = if (env.exists(x => x == a.toString())) throw Redeclared(Attribute, a.toString()) else (a.toString()) :: env
ListSymbol(newenv)
}
}
}
}
class BKVisitor extends Visitor {
override def visit(ast: AST, c: Context): Object = ast.accept(this, c)
override def visitProgram(ast: Program, c: Context): Object = c
override def visitVarDecl(ast: VarDecl, c: Context): Object = c
override def visitConstDecl(ast: ConstDecl, c: Context): Object = c
override def visitParamDecl(ast: ParamDecl, c: Context): Object = c
override def visitClassDecl(ast: ClassDecl, c: Context): Object = c
override def visitMethodDecl(ast: MethodDecl, c: Context): Object = c
override def visitAttributeDecl(ast: AttributeDecl, c: Context): Object = c
override def visitInstance(ast: Instance.type, c: Context): Object = c
override def visitStatic(ast: Static.type, c: Context): Object = c
override def visitIntType(ast: IntType.type, c: Context): Object = c
override def visitFloatType(ast: FloatType.type, c: Context): Object = c
override def visitBoolType(ast: BoolType.type, c: Context): Object = c
override def visitStringType(ast: StringType.type, c: Context): Object = c
override def visitVoidType(ast: VoidType.type, c: Context): Object = c
override def visitArrayType(ast: ArrayType, c: Context): Object = c
override def visitClassType(ast: ClassType, c: Context): Object = c
override def visitBinaryOp(ast: BinaryOp, c: Context): Object = c
override def visitUnaryOp(ast: UnaryOp, c: Context): Object = c
override def visitNewExpr(ast: NewExpr, c: Context): Object = c
override def visitCallExpr(ast: CallExpr, c: Context): Object = c
override def visitFor(ast: For, c: Context): Object = c
override def visitId(ast: Id, c: Context): Object = c
override def visitArrayCell(ast: ArrayCell, c: Context): Object = c
override def visitFieldAccess(ast: FieldAccess, c: Context): Object = c
override def visitBlock(ast: Block, c: Context): Object = c
override def visitAssign(ast: Assign, c: Context): Object = c
override def visitIf(ast: If, c: Context): Object = c
override def visitCall(ast: Call, c: Context): Object = c
override def visitBreak(ast: Break.type, c: Context): Object = c
override def visitContinue(ast: Continue.type, c: Context): Object = c
override def visitReturn(ast: Return, c: Context): Object = c
override def visitIntLiteral(ast: IntLiteral, c: Context): Object = c
override def visitFloatLiteral(ast: FloatLiteral, c: Context): Object = c
override def visitStringLiteral(ast: StringLiteral, c: Context): Object = c
override def visitBooleanLiteral(ast: BooleanLiteral, c: Context): Object = c
override def visitNullLiteral(ast: NullLiteral.type, c: Context): Object = c
override def visitSelfLiteral(ast: SelfLiteral.type, c: Context): Object = c
}
Be the first to comment
You can use [html][/html], [css][/css], [php][/php] and more to embed the code. Urls are automatically hyperlinked. Line breaks and paragraphs are automatically generated.