added check for duplicate label definitions

This commit is contained in:
Irmen de Jong 2020-03-15 00:13:58 +01:00
parent 6bd99d63b4
commit a995867deb
3 changed files with 34 additions and 4 deletions

View File

@ -158,6 +158,30 @@ interface INameScope {
if(!statements.remove(stmt))
throw FatalAstException("stmt to remove wasn't found in scope")
}
fun getAllLabels(label: String): List<Label> {
val result = mutableListOf<Label>()
fun find(scope: INameScope) {
scope.statements.forEach {
when(it) {
is Label -> result.add(it)
is INameScope -> find(it)
is IfStatement -> {
find(it.truepart)
find(it.elsepart)
}
is RepeatLoop -> find(it.body)
is ForeverLoop -> find(it.body)
is WhileLoop -> find(it.body)
is WhenStatement -> it.choices.forEach { choice->find(choice.statements) }
}
}
}
find(this)
return result
}
}
interface IAssignable {

View File

@ -165,9 +165,15 @@ internal class AstIdentifiersChecker(private val program: Program,
// the builtin functions can't be redefined
errors.err("builtin function cannot be redefined", label.position)
} else {
val existing = program.namespace.lookup(listOf(label.name), label)
if (existing != null && existing !== label)
nameError(label.name, label.position, existing)
val existing = label.definingSubroutine()?.getAllLabels(label.name) ?: emptyList()
for(el in existing) {
if(el === label || el.name != label.name)
continue
else {
nameError(label.name, label.position, el)
break
}
}
}
return super.visit(label)
}

View File

@ -15,7 +15,7 @@ import kotlin.math.floor
/*
TODO: remove unreachable code?
TODO: remove unreachable code after return and exit()
TODO: proper inlining of tiny subroutines (at first, restrict to subs without parameters and variables in them, and build it up from there: correctly renaming/relocating all variables in them and refs to those as well)
*/