From 518e5a30c2a662999426b2f68c00532bde621196 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 29 Oct 2024 23:18:17 +0100 Subject: [PATCH] slight parser rule tweak --- compiler/src/prog8/compiler/ModuleImporter.kt | 2 -- compilerAst/src/prog8/ast/statements/AstStatements.kt | 4 ++++ compilerAst/src/prog8/parser/Prog8Parser.kt | 8 ++++++-- docs/source/todo.rst | 2 -- parser/antlr/Prog8ANTLR.g4 | 6 +++++- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/compiler/src/prog8/compiler/ModuleImporter.kt b/compiler/src/prog8/compiler/ModuleImporter.kt index da37a3c74..b3401bd6d 100644 --- a/compiler/src/prog8/compiler/ModuleImporter.kt +++ b/compiler/src/prog8/compiler/ModuleImporter.kt @@ -1,11 +1,9 @@ package prog8.compiler import com.github.michaelbull.result.* -import prog8.ast.IStatementContainer import prog8.ast.Module import prog8.ast.Program import prog8.ast.base.SyntaxError -import prog8.ast.statements.Block import prog8.ast.statements.Directive import prog8.ast.statements.DirectiveArg import prog8.code.core.IErrorReporter diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index f15d8bf42..b377f666f 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -66,6 +66,8 @@ class BuiltinFunctionPlaceholder(override val name: String, override val positio override fun referencesIdentifier(nameInSource: List): Boolean = nameInSource.size==1 && name==nameInSource[0] } +// note: a Block is not strictly a Statement (but a Module Element rather) +// however by making it a statement we can reuse the name lookup logic for them (a module *is* name scope that has to do lookups) class Block(override val name: String, val address: UInt?, override val statements: MutableList, @@ -95,6 +97,8 @@ class Block(override val name: String, fun options() = statements.filter { it is Directive && it.directive == "%option" }.flatMap { (it as Directive).args }.map {it.name!!}.toSet() } +// note: a Directive is not strictly always Statement (in module scope, it's a Module Element rather) +// however by making it a statement we can reuse the name lookup logic for them (a module *is* name scope that has to do lookups) data class Directive(val directive: String, val args: List, override val position: Position) : Statement() { override lateinit var parent: Node diff --git a/compilerAst/src/prog8/parser/Prog8Parser.kt b/compilerAst/src/prog8/parser/Prog8Parser.kt index 7419b97fe..387c3d196 100644 --- a/compilerAst/src/prog8/parser/Prog8Parser.kt +++ b/compilerAst/src/prog8/parser/Prog8Parser.kt @@ -27,8 +27,12 @@ object Prog8Parser { val parseTree = parser.module() val module = ParsedModule(src) - parseTree.directive().forEach { module.add(it.toAst()) } - parseTree.block().forEach { module.add(it.toAst(module.isLibrary)) } + parseTree.module_element().forEach { + val block = it.block()?.toAst(module.isLibrary) + val directive = it.directive()?.toAst() + if(directive != null) module.add(directive) + if(block != null) module.add(block) + } return module } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index e2cf79b7e..12b3f1002 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,8 +1,6 @@ TODO ==== -Block node is not a Statement - Improve register load order in subroutine call args assignments: in certain situations, the "wrong" order of evaluation of function call arguments is done which results in overwriting registers that already got their value, which requires a lot of stack juggling (especially on plain 6502 cpu!) diff --git a/parser/antlr/Prog8ANTLR.g4 b/parser/antlr/Prog8ANTLR.g4 index 68b546a5e..eb915529a 100644 --- a/parser/antlr/Prog8ANTLR.g4 +++ b/parser/antlr/Prog8ANTLR.g4 @@ -78,7 +78,11 @@ NOT_IN: 'not' [ \t]+ 'in' [ \t] ; // If there are more than one, then they must be separated by EOL (one or more newlines). // However, trailing EOL is NOT required. // Note: the parser may see *several* consecutive EOLs - this happens when EOL and comments are interleaved (see #47) -module: EOL* ((directive | block) (EOL+ (directive | block))*)? EOL* EOF; +module: EOL* (module_element (EOL+ module_element)*)? EOL* EOF; + +module_element: + directive | block ; + block: identifier integerliteral? EOL? '{' EOL? (block_statement | EOL)* '}';