reorder statments to please the compiler later

This commit is contained in:
Irmen de Jong 2018-09-06 01:35:26 +02:00
parent 1a60119fde
commit 0b4135698e
6 changed files with 61 additions and 15 deletions

View File

@ -115,6 +115,8 @@ A block is also a *scope* in your program so the symbols in the block don't clas
symbols of the same name defined elsewhere in the same file or in another file.
You can refer to the symbols in a particular block by using a *dotted name*: ``blockname.symbolname``.
Labels inside a subroutine are appended again to that; ``blockname.subroutinename.label``.
A symbol name that's not a dotted name is searched for in the current scope, if it's not found there,
one scope higher, and so on until it is found.
Every symbol is 'public' and can be accessed from elsewhere given its dotted name.

View File

@ -124,8 +124,9 @@
sub start () -> () {
word dinges = 0
dinges=round(blerp1)
A=round(blerp1)
word blerp1 =99
dinges=blerp1
A=blerp1
return
}

View File

@ -2,6 +2,6 @@
IL65_LIBDIR=../lib65
IL65CLASSPATH=out/production/il65
LIBJARS=/opt/irmen/idea-2018/plugins/Kotlin/lib/kotlin-stdlib.jar:antlr/lib/antlr-runtime-4.7.1.jar
LIBJARS=/opt/irmen/idea-2018/plugins/Kotlin/lib/kotlin-stdlib.jar:/opt/irmen/idea-2018/plugins/Kotlin/lib/kotlin-reflect.jar:antlr/lib/antlr-runtime-4.7.1.jar
java -Dil65.libdir=${IL65_LIBDIR} -cp ${IL65CLASSPATH}:${LIBJARS} il65.MainKt $*

View File

@ -51,15 +51,14 @@ fun main(args: Array<String>) {
moduleAst.checkValid(globalNameSpaceBeforeOptimization, compilerOptions) // check if tree is valid
val allScopedSymbolDefinitions = moduleAst.checkIdentifiers()
moduleAst.optimizeStatements(globalNameSpaceBeforeOptimization, allScopedSymbolDefinitions)
val globalNamespaceAfterOptimize = moduleAst.definingScope() // it could have changed in the meantime
StatementReorderer().process(moduleAst) // reorder statements to please the compiler later
val globalNamespaceAfterOptimize = moduleAst.definingScope() // create it again, it could have changed in the meantime
moduleAst.checkValid(globalNamespaceAfterOptimize, compilerOptions) // check if final tree is valid
moduleAst.checkRecursion() // check if there are recursive subroutine calls
// globalNamespaceAfterOptimize.debugPrint()
// compile the syntax tree into intermediate form, and optimize that
val compiler = Compiler(compilerOptions)
val intermediate = compiler.compile(moduleAst)
intermediate.optimize()

View File

@ -0,0 +1,51 @@
package il65.ast
class StatementReorderer: IAstProcessor {
// Reorders the statements in a way the compiler needs.
// - 'main' block must be the very first statement.
// - in every scope:
// -- the directives '%output', '%launcher', '%zeropage', '%address' and '%option' will come first.
// -- all vardecls then follow.
// -- the remaining statements then follow in their original order.
// - the 'start' subroutine in the 'main' block will be moved to the top immediately following the directives.
val directivesToMove = setOf("%output", "%launcher", "%zeropage", "%address", "%option")
override fun process(node: Module) {
val mainBlock = node.statements.single { it is Block && it.name=="main" }
node.statements.remove(mainBlock)
node.statements.add(0, mainBlock)
val varDecls = node.statements.filter { it is VarDecl }
node.statements.removeAll(varDecls)
node.statements.addAll(0, varDecls)
val directives = node.statements.filter {it is Directive && directivesToMove.contains(it.directive)}
node.statements.removeAll(directives)
node.statements.addAll(0, directives)
super.process(node)
}
override fun process(node: Block): IStatement {
val startSub = node.statements.singleOrNull {it is Subroutine && it.name=="start"}
if(startSub!=null) {
node.statements.remove(startSub)
node.statements.add(0, startSub)
}
val varDecls = node.statements.filter { it is VarDecl }
node.statements.removeAll(varDecls)
node.statements.addAll(0, varDecls)
val directives = node.statements.filter {it is Directive && directivesToMove.contains(it.directive)}
node.statements.removeAll(directives)
node.statements.addAll(0, directives)
return super.process(node)
}
override fun process(node: Subroutine): IStatement {
val varDecls = node.statements.filter { it is VarDecl }
node.statements.removeAll(varDecls)
node.statements.addAll(0, varDecls)
val directives = node.statements.filter {it is Directive && directivesToMove.contains(it.directive)}
node.statements.removeAll(directives)
node.statements.addAll(0, directives)
return super.process(node)
}
}

View File

@ -1,8 +1,6 @@
package il65.compiler
import il65.ast.Block
import il65.ast.INameScope
import il65.ast.Module
import il65.ast.*
import kotlin.experimental.and
import kotlin.math.absoluteValue
import kotlin.math.pow
@ -92,14 +90,9 @@ class Compiler(private val options: CompilationOptions) {
fun compile(module: Module) : IntermediateForm {
println("\nCompiling parsed source code to intermediate code...")
// make sure the 'main' block is the first block. Statement even.
val mainBlock = module.statements.single { it is Block && it.name=="main" }
module.statements.remove(mainBlock)
module.statements.add(0, mainBlock)
val namespace = module.definingScope()
// todo
val namespace = module.definingScope()
namespace.debugPrint()
module.statements.filter { it is Block }.map {