slight parser rule tweak

This commit is contained in:
Irmen de Jong 2024-10-29 23:18:17 +01:00
parent bbba4b3d60
commit 518e5a30c2
5 changed files with 15 additions and 7 deletions

View File

@ -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

View File

@ -66,6 +66,8 @@ class BuiltinFunctionPlaceholder(override val name: String, override val positio
override fun referencesIdentifier(nameInSource: List<String>): 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<Statement>,
@ -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<DirectiveArg>, override val position: Position) : Statement() {
override lateinit var parent: Node

View File

@ -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
}

View File

@ -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!)

View File

@ -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)* '}';