diff --git a/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt b/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt index 08521cf05..942556244 100644 --- a/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt +++ b/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt @@ -30,7 +30,7 @@ private fun ParserRuleContext.toPosition() : Position { val customTokensource = this.start.tokenSource as? CustomLexer val filename = when { - customTokensource!=null -> customTokensource.modulePath.fileName.toString() + customTokensource!=null -> customTokensource.modulePath.toString() start.tokenSource.sourceName == IntStream.UNKNOWN_SOURCE_NAME -> "@internal@" else -> File(start.inputStream.sourceName).name } diff --git a/compiler/src/prog8/ast/base/Base.kt b/compiler/src/prog8/ast/base/Base.kt index 6f5c8495d..76b7947a4 100644 --- a/compiler/src/prog8/ast/base/Base.kt +++ b/compiler/src/prog8/ast/base/Base.kt @@ -165,6 +165,7 @@ object ParentSentinel : Node { data class Position(val file: String, val line: Int, val startCol: Int, val endCol: Int) { override fun toString(): String = "[$file: line $line col ${startCol+1}-${endCol+1}]" + fun toClickableStr(): String = "$file:$line:$startCol:" companion object { val DUMMY = Position("", 0, 0, 0) diff --git a/compiler/src/prog8/ast/base/ErrorReporting.kt b/compiler/src/prog8/ast/base/ErrorReporting.kt index 483c6c5e1..30b2d1434 100644 --- a/compiler/src/prog8/ast/base/ErrorReporting.kt +++ b/compiler/src/prog8/ast/base/ErrorReporting.kt @@ -24,7 +24,7 @@ class ErrorReporter { MessageSeverity.ERROR -> System.err.print("\u001b[91m") // bright red MessageSeverity.WARNING -> System.err.print("\u001b[93m") // bright yellow } - val msg = "${it.position} ${it.severity} ${it.message}".trim() + val msg = "${it.position.toClickableStr()} ${it.severity} ${it.message}".trim() if(msg !in alreadyReportedMessages) { System.err.println(msg) alreadyReportedMessages.add(msg) diff --git a/compiler/src/prog8/ast/base/Errors.kt b/compiler/src/prog8/ast/base/Errors.kt index e18a616c0..1313e664f 100644 --- a/compiler/src/prog8/ast/base/Errors.kt +++ b/compiler/src/prog8/ast/base/Errors.kt @@ -7,11 +7,11 @@ open class FatalAstException (override var message: String) : Exception(message) open class AstException (override var message: String) : Exception(message) open class SyntaxError(override var message: String, val position: Position) : AstException(message) { - override fun toString() = "$position Syntax error: $message" + override fun toString() = "${position.toClickableStr()} Syntax error: $message" } class ExpressionError(message: String, val position: Position) : AstException(message) { - override fun toString() = "$position Error: $message" + override fun toString() = "${position.toClickableStr()} Error: $message" } class UndefinedSymbolError(symbol: IdentifierReference) diff --git a/compiler/src/prog8/parser/ModuleParsing.kt b/compiler/src/prog8/parser/ModuleParsing.kt index 809722550..715807819 100644 --- a/compiler/src/prog8/parser/ModuleParsing.kt +++ b/compiler/src/prog8/parser/ModuleParsing.kt @@ -19,14 +19,6 @@ import java.nio.file.Paths internal class ParsingFailedError(override var message: String) : Exception(message) -private class LexerErrorListener: BaseErrorListener() { - var numberOfErrors: Int = 0 - override fun syntaxError(p0: Recognizer<*, *>?, p1: Any?, p2: Int, p3: Int, p4: String?, p5: RecognitionException?) { - numberOfErrors++ - } -} - - internal class CustomLexer(val modulePath: Path, input: CharStream?) : prog8Lexer(input) @@ -60,13 +52,28 @@ internal class ModuleImporter { return executeImportDirective(program, import, Paths.get("")) } + private class MyErrorListener: ConsoleErrorListener() { + var numberOfErrors: Int = 0 + override fun syntaxError(recognizer: Recognizer<*, *>?, offendingSymbol: Any?, line: Int, charPositionInLine: Int, msg: String, e: RecognitionException?) { + numberOfErrors++ + when (recognizer) { + is CustomLexer -> System.err.println("${recognizer.modulePath}:$line:$charPositionInLine: $msg") + is prog8Parser -> System.err.println("${recognizer.inputStream.sourceName}:$line:$charPositionInLine: $msg") + else -> System.err.println("$line:$charPositionInLine $msg") + } + } + } + private fun importModule(program: Program, stream: CharStream, modulePath: Path, isLibrary: Boolean): Module { val moduleName = moduleName(modulePath.fileName) val lexer = CustomLexer(modulePath, stream) - val lexerErrors = LexerErrorListener() + lexer.removeErrorListeners() + val lexerErrors = MyErrorListener() lexer.addErrorListener(lexerErrors) val tokens = CommentHandlingTokenStream(lexer) val parser = prog8Parser(tokens) + parser.removeErrorListeners() + parser.addErrorListener(MyErrorListener()) val parseTree = parser.module() val numberOfErrors = parser.numberOfSyntaxErrors + lexerErrors.numberOfErrors if(numberOfErrors > 0) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 6d102c44e..095a148d2 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -4,7 +4,6 @@ TODO - get rid of all other TODO's in the code ;-) - line-circle-gfx examples are now a few hundred bytes larger than before. Why is that, can it be fixed? -- compiler errors and warnings in standard format so the IDE shows them as clickable links; ./test.asm:2578:3: blablabla - make it possible for array literals to not only contain compile time constants - further optimize assignment codegeneration - auto select correct library to import based on target, instead of having c64- and cx16- prefix variants