diff --git a/il65/src/il65/ast/AST.kt b/il65/src/il65/ast/AST.kt index 60d0631a1..c053853b6 100644 --- a/il65/src/il65/ast/AST.kt +++ b/il65/src/il65/ast/AST.kt @@ -48,6 +48,7 @@ data class Position(val file: String, val line: Int, val startCol: Int, val endC interface IAstProcessor { + // override the ones you want to act upon fun process(module: Module) { } fun process(expr: PrefixExpression): IExpression { diff --git a/il65/src/il65/ast/AstChecker.kt b/il65/src/il65/ast/AstChecker.kt index 2f4c792e6..f0da99d83 100644 --- a/il65/src/il65/ast/AstChecker.kt +++ b/il65/src/il65/ast/AstChecker.kt @@ -1,7 +1,6 @@ package il65.ast import il65.ParsingFailedError -import javax.xml.crypto.Data fun Module.checkValid() { @@ -50,6 +49,18 @@ class AstChecker : IAstProcessor { blockNames[block.name] = block.position } block.statements.forEach { it.process(this) } + + // check if labels are unique + val labels = block.statements.filter { it is Label }.map { it as Label } + val labelnames = mutableMapOf() + labels.forEach { + val existing = labelnames[it.name] + if(existing!=null) { + checkResult.add(SyntaxError("label name conflict, first defined on line ${existing.line}", it.position)) + } else { + labelnames[it.name] = it.position + } + } return block } @@ -72,6 +83,18 @@ class AstChecker : IAstProcessor { subroutine.statements.forEach { it.process(this) } + // check if labels are unique + val labels = subroutine.statements.filter { it is Label }.map { it as Label } + val labelnames = mutableMapOf() + labels.forEach { + val existing = labelnames[it.name] + if(existing!=null) { + checkResult.add(SyntaxError("label name conflict, first defined on line ${existing.line}", it.position)) + } else { + labelnames[it.name] = it.position + } + } + // subroutine must contain at least one 'return' or 'goto' // (or if it has an asm block, that must contain a 'rts' or 'jmp') if(subroutine.statements.count { it is Return || it is Jump } == 0) {