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. 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``. 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``. 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. Every symbol is 'public' and can be accessed from elsewhere given its dotted name.

View File

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

View File

@@ -2,6 +2,6 @@
IL65_LIBDIR=../lib65 IL65_LIBDIR=../lib65
IL65CLASSPATH=out/production/il65 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 $* 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 moduleAst.checkValid(globalNameSpaceBeforeOptimization, compilerOptions) // check if tree is valid
val allScopedSymbolDefinitions = moduleAst.checkIdentifiers() val allScopedSymbolDefinitions = moduleAst.checkIdentifiers()
moduleAst.optimizeStatements(globalNameSpaceBeforeOptimization, allScopedSymbolDefinitions) 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.checkValid(globalNamespaceAfterOptimize, compilerOptions) // check if final tree is valid
moduleAst.checkRecursion() // check if there are recursive subroutine calls moduleAst.checkRecursion() // check if there are recursive subroutine calls
// globalNamespaceAfterOptimize.debugPrint() // globalNamespaceAfterOptimize.debugPrint()
// compile the syntax tree into intermediate form, and optimize that // compile the syntax tree into intermediate form, and optimize that
val compiler = Compiler(compilerOptions) val compiler = Compiler(compilerOptions)
val intermediate = compiler.compile(moduleAst) val intermediate = compiler.compile(moduleAst)
intermediate.optimize() 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 package il65.compiler
import il65.ast.Block import il65.ast.*
import il65.ast.INameScope
import il65.ast.Module
import kotlin.experimental.and import kotlin.experimental.and
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
import kotlin.math.pow import kotlin.math.pow
@@ -92,14 +90,9 @@ class Compiler(private val options: CompilationOptions) {
fun compile(module: Module) : IntermediateForm { fun compile(module: Module) : IntermediateForm {
println("\nCompiling parsed source code to intermediate code...") 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 // todo
val namespace = module.definingScope()
namespace.debugPrint() namespace.debugPrint()
module.statements.filter { it is Block }.map { module.statements.filter { it is Block }.map {