Skip to content

Commit

Permalink
Last updates (#44)
Browse files Browse the repository at this point in the history
* Add error message

* Unnecessary hard fail

* Remove useless code

* Remove Base class and a test
  • Loading branch information
Nissen96 authored Jun 1, 2020
1 parent 721d7b2 commit c1ad73a
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 25 deletions.
3 changes: 1 addition & 2 deletions src/main/kotlin/com/egern/ast/BuildASTVisitor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ class BuildASTVisitor : MainBaseVisitor<ASTNode>() {

override fun visitClassDecl(ctx: MainParser.ClassDeclContext): ASTNode {
val classId = ctx.CLASSNAME(0).text
val hasSuperclass = ctx.CLASSNAME(1) != null
val constructor = ctx.constructor()?.let {
it.ID().mapIndexed { index, id ->
Parameter(
Expand All @@ -36,7 +35,7 @@ class BuildASTVisitor : MainBaseVisitor<ASTNode>() {
return ClassDecl(
classId,
constructor,
if (hasSuperclass) ctx.CLASSNAME(1).text else "Base",
ctx.CLASSNAME(1)?.text,
if (ctx.argList() != null) ctx.argList().expr().map { it.accept(this) as Expr } else emptyList(),
ctx.classBody().fieldDecl().map { it.accept(this) as FieldDecl },
ctx.classBody().methodDecl().map { visitMethodDecl(it, classId) as FuncDecl },
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/com/egern/symbols/ClassDefinition.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ class ClassDefinition(
}

fun getSuperclasses(includeInterface: Boolean = true): List<String> {
// Insert interface before Base class
// Optionally insert interface
if (includeInterface && interfaceDecl != null) {
return listOf(className, interfaceDecl!!.id, "Base")
return listOf(className, interfaceDecl!!.id)
}

return listOf(className) + (superclass?.getSuperclasses(includeInterface) ?: emptyList())
Expand Down
12 changes: 2 additions & 10 deletions src/main/kotlin/com/egern/symbols/SymbolVisitor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@ class SymbolVisitor : Visitor() {
private var currentScopeLevel = 0
private var varCountStack = stackOf(0)
private var fieldOffset = 0
private val baseClass = ClassDefinition(
"Base",
ClassDecl("Base", emptyList(), null, null, emptyList(), emptyList())
)
var symbolTable = SymbolTable(0, null)
val classDefinitions = mutableListOf(baseClass)
val classDefinitions = mutableListOf<ClassDefinition>()
val interfaces = mutableListOf<InterfaceDecl>()

private fun returnToParentScope() {
Expand All @@ -24,10 +20,6 @@ class SymbolVisitor : Visitor() {
symbolTable = SymbolTable(currentScopeLevel, symbolTable)
}

override fun preVisit(program: Program) {
baseClass.symbolTable = symbolTable
}

override fun postVisit(program: Program) {
program.variableCount = varCountStack.pop()!!
}
Expand Down Expand Up @@ -128,7 +120,7 @@ class SymbolVisitor : Visitor() {
)
)
}
val classDefinition = ClassDefinition(classDecl.id, classDecl, baseClass)
val classDefinition = ClassDefinition(classDecl.id, classDecl)
classDefinition.symbolTable = symbolTable
classDefinitions.add(classDefinition)
fieldOffset = classDecl.constructor.size
Expand Down
29 changes: 18 additions & 11 deletions src/main/kotlin/com/egern/types/TypeCheckingVisitor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class TypeCheckingVisitor(
}

// Check if method overrides any static methods or overrides without the override modifier
val foundMethod = currentClass!!.superclass!!.lookupMethod(methodDecl.id)
val foundMethod = currentClass!!.superclass?.lookupMethod(methodDecl.id)
if (foundMethod == null) {
// Check if method overrides from interface
val foundInterfaceMethod = currentClass!!.getInterface()?.methodSignatures?.find { it.id == methodDecl.id }
Expand Down Expand Up @@ -175,7 +175,13 @@ class TypeCheckingVisitor(
override fun visit(classField: ClassField) {
val callerClass = getObjectClass(classField.objectId)
val classDefinition = classDefinitions.find { it.className == callerClass.className }
?: throw Exception("Class ${callerClass.className} not defined")
if (classDefinition == null) {
ErrorLogger.log(
classField,
"Class ${callerClass.className} not defined"
)
return
}

// Check if field exists
val fieldDecl = classDefinition.lookupLocalField(classField.fieldId)
Expand Down Expand Up @@ -442,14 +448,8 @@ class TypeCheckingVisitor(
// For each field id, check if it overrides any static field or constructor param
fieldDecl.ids.forEach {
// Check if any superclass contains a field of the same name
val superField = currentClass!!.superclass!!.lookupLocalField(it)
if (superField == null && fieldOverrides) {
// Attempt override of constructor field with local field
ErrorLogger.log(
fieldDecl,
"Constructor field $it cannot be overridden"
)
} else if (superField != null && Modifier.STATIC in superField.modifiers) {
val superField = currentClass!!.superclass?.lookupLocalField(it)
if (superField != null && Modifier.STATIC in superField.modifiers) {
// Attempt override of static super field
ErrorLogger.log(
fieldDecl,
Expand All @@ -462,7 +462,14 @@ class TypeCheckingVisitor(
override fun postVisit(objectInstantiation: ObjectInstantiation) {
// Check arguments fit the constructor parameters in number and types
val nArgs = objectInstantiation.args.size
val classDefinition = classDefinitions.find { it.className == objectInstantiation.classId }!!
val classDefinition = classDefinitions.find { it.className == objectInstantiation.classId }
if (classDefinition == null) {
ErrorLogger.log(
objectInstantiation,
"Class ${objectInstantiation.classId} is undefined"
)
return
}
val constructorFields = classDefinition.getConstructorFields()
val nParams = constructorFields.size
if (nArgs != nParams) {
Expand Down

0 comments on commit c1ad73a

Please sign in to comment.