should not shuffle assignments.

This commit is contained in:
Irmen de Jong 2019-07-08 22:18:25 +02:00
parent dbe048158c
commit c1102393bb
9 changed files with 125 additions and 115 deletions

View File

@ -27,8 +27,8 @@ class PrefixExpression(val operator: String, var expression: IExpression, overri
} }
override fun constValue(program: Program): LiteralValue? = null override fun constValue(program: Program): LiteralValue? = null
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun referencesIdentifier(name: String) = expression.referencesIdentifier(name) override fun referencesIdentifier(name: String) = expression.referencesIdentifier(name)
override fun inferType(program: Program): DataType? = expression.inferType(program) override fun inferType(program: Program): DataType? = expression.inferType(program)
@ -53,8 +53,8 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I
// binary expression should actually have been optimized away into a single value, before const value was requested... // binary expression should actually have been optimized away into a single value, before const value was requested...
override fun constValue(program: Program): LiteralValue? = null override fun constValue(program: Program): LiteralValue? = null
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun referencesIdentifier(name: String) = left.referencesIdentifier(name) || right.referencesIdentifier(name) override fun referencesIdentifier(name: String) = left.referencesIdentifier(name) || right.referencesIdentifier(name)
override fun inferType(program: Program): DataType? { override fun inferType(program: Program): DataType? {
val leftDt = left.inferType(program) val leftDt = left.inferType(program)
@ -221,8 +221,8 @@ class ArrayIndexedExpression(val identifier: IdentifierReference,
} }
override fun constValue(program: Program): LiteralValue? = null override fun constValue(program: Program): LiteralValue? = null
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun referencesIdentifier(name: String) = identifier.referencesIdentifier(name) override fun referencesIdentifier(name: String) = identifier.referencesIdentifier(name)
override fun inferType(program: Program): DataType? { override fun inferType(program: Program): DataType? {
@ -255,8 +255,8 @@ class TypecastExpression(var expression: IExpression, var type: DataType, val im
expression.linkParents(this) expression.linkParents(this)
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun referencesIdentifier(name: String) = expression.referencesIdentifier(name) override fun referencesIdentifier(name: String) = expression.referencesIdentifier(name)
override fun inferType(program: Program): DataType? = type override fun inferType(program: Program): DataType? = type
override fun constValue(program: Program): LiteralValue? { override fun constValue(program: Program): LiteralValue? {
@ -283,8 +283,8 @@ data class AddressOf(val identifier: IdentifierReference, override val position:
override fun constValue(program: Program): LiteralValue? = null override fun constValue(program: Program): LiteralValue? = null
override fun referencesIdentifier(name: String) = false override fun referencesIdentifier(name: String) = false
override fun inferType(program: Program) = DataType.UWORD override fun inferType(program: Program) = DataType.UWORD
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
} }
class DirectMemoryRead(var addressExpression: IExpression, override val position: Position) : IExpression { class DirectMemoryRead(var addressExpression: IExpression, override val position: Position) : IExpression {
@ -295,8 +295,8 @@ class DirectMemoryRead(var addressExpression: IExpression, override val position
this.addressExpression.linkParents(this) this.addressExpression.linkParents(this)
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun referencesIdentifier(name: String) = false override fun referencesIdentifier(name: String) = false
override fun inferType(program: Program): DataType? = DataType.UBYTE override fun inferType(program: Program): DataType? = DataType.UBYTE
override fun constValue(program: Program): LiteralValue? = null override fun constValue(program: Program): LiteralValue? = null
@ -414,8 +414,8 @@ open class LiteralValue(val type: DataType,
return this return this
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun toString(): String { override fun toString(): String {
val vstr = when(type) { val vstr = when(type) {
@ -583,8 +583,8 @@ class RangeExpr(var from: IExpression,
} }
override fun constValue(program: Program): LiteralValue? = null override fun constValue(program: Program): LiteralValue? = null
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun referencesIdentifier(name: String): Boolean = from.referencesIdentifier(name) || to.referencesIdentifier(name) override fun referencesIdentifier(name: String): Boolean = from.referencesIdentifier(name) || to.referencesIdentifier(name)
override fun inferType(program: Program): DataType? { override fun inferType(program: Program): DataType? {
val fromDt=from.inferType(program) val fromDt=from.inferType(program)
@ -652,8 +652,8 @@ class RegisterExpr(val register: Register, override val position: Position) : IE
} }
override fun constValue(program: Program): LiteralValue? = null override fun constValue(program: Program): LiteralValue? = null
override fun accept(processor: IAstModifyingVisitor) = this override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) {} override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun referencesIdentifier(name: String): Boolean = false override fun referencesIdentifier(name: String): Boolean = false
override fun toString(): String { override fun toString(): String {
return "RegisterExpr(register=$register, pos=$position)" return "RegisterExpr(register=$register, pos=$position)"
@ -694,8 +694,8 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
return "IdentifierRef($nameInSource)" return "IdentifierRef($nameInSource)"
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun referencesIdentifier(name: String): Boolean = nameInSource.last() == name // @todo is this correct all the time? override fun referencesIdentifier(name: String): Boolean = nameInSource.last() == name // @todo is this correct all the time?
override fun inferType(program: Program): DataType? { override fun inferType(program: Program): DataType? {
@ -760,8 +760,8 @@ class FunctionCall(override var target: IdentifierReference,
return "FunctionCall(target=$target, pos=$position)" return "FunctionCall(target=$target, pos=$position)"
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun referencesIdentifier(name: String): Boolean = target.referencesIdentifier(name) || arglist.any{it.referencesIdentifier(name)} override fun referencesIdentifier(name: String): Boolean = target.referencesIdentifier(name) || arglist.any{it.referencesIdentifier(name)}
override fun inferType(program: Program): DataType? { override fun inferType(program: Program): DataType? {

View File

@ -193,4 +193,16 @@ interface IAstModifyingVisitor {
fun visit(inlineAssembly: InlineAssembly): IStatement { fun visit(inlineAssembly: InlineAssembly): IStatement {
return inlineAssembly return inlineAssembly
} }
fun visit(registerExpr: RegisterExpr): IExpression {
return registerExpr
}
fun visit(builtinFunctionStatementPlaceholder: BuiltinFunctionStatementPlaceholder): IStatement {
return builtinFunctionStatementPlaceholder
}
fun visit(nopStatement: NopStatement): IStatement {
return nopStatement
}
} }

View File

@ -147,4 +147,13 @@ interface IAstVisitor {
fun visit(inlineAssembly: InlineAssembly) { fun visit(inlineAssembly: InlineAssembly) {
} }
fun visit(registerExpr: RegisterExpr) {
}
fun visit(builtinFunctionStatementPlaceholder: BuiltinFunctionStatementPlaceholder) {
}
fun visit(nopStatement: NopStatement) {
}
} }

View File

@ -56,8 +56,6 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
val directives = module.statements.filter {it is Directive && it.directive in directivesToMove} val directives = module.statements.filter {it is Directive && it.directive in directivesToMove}
module.statements.removeAll(directives) module.statements.removeAll(directives)
module.statements.addAll(0, directives) module.statements.addAll(0, directives)
sortConstantAssignments(module.statements)
} }
override fun visit(block: Block): IStatement { override fun visit(block: Block): IStatement {
@ -106,8 +104,6 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
block.statements.addAll(0, directives) block.statements.addAll(0, directives)
block.linkParents(block.parent) block.linkParents(block.parent)
sortConstantAssignments(block.statements)
// create subroutine that initializes the block's variables (if any) // create subroutine that initializes the block's variables (if any)
val varInits = block.statements.withIndex().filter { it.value is VariableInitializationAssignment } val varInits = block.statements.withIndex().filter { it.value is VariableInitializationAssignment }
if(varInits.isNotEmpty()) { if(varInits.isNotEmpty()) {
@ -129,8 +125,6 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
override fun visit(subroutine: Subroutine): IStatement { override fun visit(subroutine: Subroutine): IStatement {
super.visit(subroutine) super.visit(subroutine)
sortConstantAssignments(subroutine.statements)
val varDecls = subroutine.statements.filterIsInstance<VarDecl>() val varDecls = subroutine.statements.filterIsInstance<VarDecl>()
subroutine.statements.removeAll(varDecls) subroutine.statements.removeAll(varDecls)
subroutine.statements.addAll(0, varDecls) subroutine.statements.addAll(0, varDecls)
@ -153,12 +147,6 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
return subroutine return subroutine
} }
override fun visit(scope: AnonymousScope): AnonymousScope {
scope.statements = scope.statements.map { it.accept(this)}.toMutableList()
sortConstantAssignments(scope.statements)
return scope
}
override fun visit(expr: BinaryExpression): IExpression { override fun visit(expr: BinaryExpression): IExpression {
val leftDt = expr.left.inferType(program) val leftDt = expr.left.inferType(program)
val rightDt = expr.right.inferType(program) val rightDt = expr.right.inferType(program)
@ -182,29 +170,6 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
return super.visit(expr) return super.visit(expr)
} }
private fun sortConstantAssignments(statements: MutableList<IStatement>) {
// sort assignments by datatype and value, so multiple initializations with the isSameAs value can be optimized (to load the value just once)
val result = mutableListOf<IStatement>()
val stmtIter = statements.iterator()
for(stmt in stmtIter) {
if(stmt is Assignment && !stmt.targets.any { it.isMemoryMapped(program.namespace) }) {
val constval = stmt.value.constValue(program)
if(constval!=null) {
val (sorted, trailing) = sortConstantAssignmentSequence(stmt, stmtIter)
result.addAll(sorted)
if(trailing!=null)
result.add(trailing)
}
else
result.add(stmt)
}
else
result.add(stmt)
}
statements.clear()
statements.addAll(result)
}
override fun visit(assignment: Assignment): IStatement { override fun visit(assignment: Assignment): IStatement {
val target=assignment.singleTarget val target=assignment.singleTarget
if(target!=null) { if(target!=null) {

View File

@ -11,8 +11,8 @@ import prog8.compiler.HeapValues
class BuiltinFunctionStatementPlaceholder(val name: String, override val position: Position) : IStatement { class BuiltinFunctionStatementPlaceholder(val name: String, override val position: Position) : IStatement {
override var parent: Node = ParentSentinel override var parent: Node = ParentSentinel
override fun linkParents(parent: Node) {} override fun linkParents(parent: Node) {}
override fun accept(processor: IAstModifyingVisitor): IStatement = this override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) { } override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun definingScope(): INameScope = BuiltinFunctionScopePlaceholder override fun definingScope(): INameScope = BuiltinFunctionScopePlaceholder
override val expensiveToInline = false override val expensiveToInline = false
} }
@ -35,8 +35,8 @@ class Block(override val name: String,
statements.forEach {it.linkParents(this)} statements.forEach {it.linkParents(this)}
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun toString(): String { override fun toString(): String {
return "Block(name=$name, address=$address, ${statements.size} statements)" return "Block(name=$name, address=$address, ${statements.size} statements)"
@ -54,8 +54,8 @@ data class Directive(val directive: String, val args: List<DirectiveArg>, overri
args.forEach{it.linkParents(this)} args.forEach{it.linkParents(this)}
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
} }
data class DirectiveArg(val str: String?, val name: String?, val int: Int?, override val position: Position) : Node { data class DirectiveArg(val str: String?, val name: String?, val int: Int?, override val position: Position) : Node {
@ -74,8 +74,8 @@ data class Label(val name: String, override val position: Position) : IStatement
this.parent = parent this.parent = parent
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun toString(): String { override fun toString(): String {
return "Label(name=$name, pos=$position)" return "Label(name=$name, pos=$position)"
@ -93,8 +93,8 @@ open class Return(var values: List<IExpression>, override val position: Position
values.forEach {it.linkParents(this)} values.forEach {it.linkParents(this)}
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun toString(): String { override fun toString(): String {
return "Return(values: $values, pos=$position)" return "Return(values: $values, pos=$position)"
@ -102,8 +102,8 @@ open class Return(var values: List<IExpression>, override val position: Position
} }
class ReturnFromIrq(override val position: Position) : Return(emptyList(), position) { class ReturnFromIrq(override val position: Position) : Return(emptyList(), position) {
override fun accept(processor: IAstModifyingVisitor) = this override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) {} override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun toString(): String { override fun toString(): String {
return "ReturnFromIrq(pos=$position)" return "ReturnFromIrq(pos=$position)"
@ -118,8 +118,8 @@ class Continue(override val position: Position) : IStatement {
this.parent=parent this.parent=parent
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
} }
class Break(override val position: Position) : IStatement { class Break(override val position: Position) : IStatement {
@ -130,8 +130,8 @@ class Break(override val position: Position) : IStatement {
this.parent=parent this.parent=parent
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
} }
class VarDecl(val type: VarDeclType, class VarDecl(val type: VarDeclType,
@ -168,8 +168,8 @@ class VarDecl(val type: VarDeclType,
value?.linkParents(this) value?.linkParents(this)
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
val scopedname: String by lazy { makeScopedName(name) } val scopedname: String by lazy { makeScopedName(name) }
@ -208,11 +208,11 @@ class ArrayIndex(var index: IExpression, override val position: Position) : Node
} }
} }
fun accept(processor: IAstModifyingVisitor) { fun accept(visitor: IAstModifyingVisitor) {
index = index.accept(processor) index = index.accept(visitor)
} }
fun accept(processor: IAstVisitor) { fun accept(visitor: IAstVisitor) {
index.accept(processor) index.accept(visitor)
} }
override fun toString(): String { override fun toString(): String {
@ -233,8 +233,8 @@ open class Assignment(var targets: List<AssignTarget>, val aug_op : String?, var
value.linkParents(this) value.linkParents(this)
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun toString(): String { override fun toString(): String {
return("Assignment(augop: $aug_op, targets: $targets, value: $value, pos=$position)") return("Assignment(augop: $aug_op, targets: $targets, value: $value, pos=$position)")
@ -265,8 +265,8 @@ data class AssignTarget(val register: Register?,
memoryAddress?.linkParents(this) memoryAddress?.linkParents(this)
} }
fun accept(processor: IAstModifyingVisitor) = processor.visit(this) fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
fun accept(processor: IAstVisitor) = processor.visit(this) fun accept(visitor: IAstVisitor) = visitor.visit(this)
companion object { companion object {
fun fromExpr(expr: IExpression): AssignTarget { fun fromExpr(expr: IExpression): AssignTarget {
@ -381,8 +381,8 @@ class PostIncrDecr(var target: AssignTarget, val operator: String, override val
target.linkParents(this) target.linkParents(this)
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun toString(): String { override fun toString(): String {
return "PostIncrDecr(op: $operator, target: $target, pos=$position)" return "PostIncrDecr(op: $operator, target: $target, pos=$position)"
@ -401,8 +401,8 @@ class Jump(val address: Int?,
identifier?.linkParents(this) identifier?.linkParents(this)
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun toString(): String { override fun toString(): String {
return "Jump(addr: $address, identifier: $identifier, label: $generatedLabel; pos=$position)" return "Jump(addr: $address, identifier: $identifier, label: $generatedLabel; pos=$position)"
@ -422,8 +422,8 @@ class FunctionCallStatement(override var target: IdentifierReference,
arglist.forEach { it.linkParents(this) } arglist.forEach { it.linkParents(this) }
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun toString(): String { override fun toString(): String {
return "FunctionCallStatement(target=$target, pos=$position)" return "FunctionCallStatement(target=$target, pos=$position)"
@ -438,8 +438,8 @@ class InlineAssembly(val assembly: String, override val position: Position) : IS
this.parent = parent this.parent = parent
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
} }
class AnonymousScope(override var statements: MutableList<IStatement>, class AnonymousScope(override var statements: MutableList<IStatement>,
@ -463,8 +463,8 @@ class AnonymousScope(override var statements: MutableList<IStatement>,
statements.forEach { it.linkParents(this) } statements.forEach { it.linkParents(this) }
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
} }
class NopStatement(override val position: Position): IStatement { class NopStatement(override val position: Position): IStatement {
@ -475,8 +475,8 @@ class NopStatement(override val position: Position): IStatement {
this.parent = parent this.parent = parent
} }
override fun accept(processor: IAstModifyingVisitor) = this override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) {} override fun accept(visitor: IAstVisitor) = visitor.visit(this)
} }
// the subroutine class covers both the normal user-defined subroutines, // the subroutine class covers both the normal user-defined subroutines,
@ -509,8 +509,8 @@ class Subroutine(override val name: String,
statements.forEach { it.linkParents(this) } statements.forEach { it.linkParents(this) }
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun toString(): String { override fun toString(): String {
return "Subroutine(name=$name, parameters=$parameters, returntypes=$returntypes, ${statements.size} statements, address=$asmAddress)" return "Subroutine(name=$name, parameters=$parameters, returntypes=$returntypes, ${statements.size} statements, address=$asmAddress)"
@ -582,8 +582,8 @@ class IfStatement(var condition: IExpression,
elsepart.linkParents(this) elsepart.linkParents(this)
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
} }
class BranchStatement(var condition: BranchCondition, class BranchStatement(var condition: BranchCondition,
@ -600,8 +600,8 @@ class BranchStatement(var condition: BranchCondition,
elsepart.linkParents(this) elsepart.linkParents(this)
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
} }
class ForLoop(val loopRegister: Register?, class ForLoop(val loopRegister: Register?,
@ -621,8 +621,8 @@ class ForLoop(val loopRegister: Register?,
body.linkParents(this) body.linkParents(this)
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun toString(): String { override fun toString(): String {
return "ForLoop(loopVar: $loopVar, loopReg: $loopRegister, iterable: $iterable, pos=$position)" return "ForLoop(loopVar: $loopVar, loopReg: $loopRegister, iterable: $iterable, pos=$position)"
@ -645,8 +645,8 @@ class WhileLoop(var condition: IExpression,
body.linkParents(this) body.linkParents(this)
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
} }
class RepeatLoop(var body: AnonymousScope, class RepeatLoop(var body: AnonymousScope,
@ -661,8 +661,8 @@ class RepeatLoop(var body: AnonymousScope,
body.linkParents(this) body.linkParents(this)
} }
override fun accept(processor: IAstModifyingVisitor) = processor.visit(this) override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
override fun accept(processor: IAstVisitor) = processor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)
} }
class DirectMemoryWrite(var addressExpression: IExpression, override val position: Position) : Node { class DirectMemoryWrite(var addressExpression: IExpression, override val position: Position) : Node {
@ -677,6 +677,6 @@ class DirectMemoryWrite(var addressExpression: IExpression, override val positio
return "DirectMemoryWrite($addressExpression)" return "DirectMemoryWrite($addressExpression)"
} }
fun accept(processor: IAstVisitor) = processor.visit(this) fun accept(visitor: IAstVisitor) = visitor.visit(this)
fun accept(processor: IAstModifyingVisitor) = processor.visit(this) fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
} }

View File

@ -86,6 +86,7 @@ class AstToSourceCode(val output: (text: String) -> Unit): IAstVisitor {
else -> "?????" else -> "?????"
} }
} }
override fun visit(decl: VarDecl) { override fun visit(decl: VarDecl) {
if(decl.autoGenerated) { if(decl.autoGenerated) {
// skip autogenerated vardecl // skip autogenerated vardecl
@ -370,4 +371,16 @@ class AstToSourceCode(val output: (text: String) -> Unit): IAstVisitor {
outputln(inlineAssembly.assembly) outputln(inlineAssembly.assembly)
outputlni("}}") outputlni("}}")
} }
override fun visit(registerExpr: RegisterExpr) {
output(registerExpr.register.toString())
}
override fun visit(builtinFunctionStatementPlaceholder: BuiltinFunctionStatementPlaceholder) {
output(builtinFunctionStatementPlaceholder.name)
}
override fun visit(nopStatement: NopStatement) {
TODO("NOP???")
}
} }

View File

@ -64,7 +64,6 @@ fun compileProgram(filepath: Path,
val time3 = measureTimeMillis { val time3 = measureTimeMillis {
programAst.reorderStatements() // reorder statements and add type casts, to please the compiler later programAst.reorderStatements() // reorder statements and add type casts, to please the compiler later
} }
printAst(programAst)
//println(" time3: $time3") //println(" time3: $time3")
val time4 = measureTimeMillis { val time4 = measureTimeMillis {
programAst.checkValid(compilerOptions) // check if tree is valid programAst.checkValid(compilerOptions) // check if tree is valid
@ -87,6 +86,7 @@ fun compileProgram(filepath: Path,
programAst.checkValid(compilerOptions) // check if final tree is valid programAst.checkValid(compilerOptions) // check if final tree is valid
programAst.checkRecursion() // check if there are recursive subroutine calls programAst.checkRecursion() // check if there are recursive subroutine calls
printAst(programAst)
// namespace.debugPrint() // namespace.debugPrint()
// compile the syntax tree into stackvmProg form, and optimize that // compile the syntax tree into stackvmProg form, and optimize that

View File

@ -19,6 +19,7 @@ internal class StatementOptimizer(private val program: Program, private val opti
var optimizationsDone: Int = 0 var optimizationsDone: Int = 0
private set private set
var scopesToFlatten = mutableListOf<INameScope>() var scopesToFlatten = mutableListOf<INameScope>()
val nopStatements = mutableListOf<NopStatement>()
private val pureBuiltinFunctions = BuiltinFunctions.filter { it.value.pure } private val pureBuiltinFunctions = BuiltinFunctions.filter { it.value.pure }
private val callgraph = CallGraph(program) private val callgraph = CallGraph(program)
@ -33,6 +34,9 @@ internal class StatementOptimizer(private val program: Program, private val opti
inlineSubroutines(callgraph) inlineSubroutines(callgraph)
} }
super.visit(program) super.visit(program)
// at the end, remove the encountered NOP statements
this.nopStatements.forEach { it.definingScope().remove(it) }
} }
private fun inlineSubroutines(callgraph: CallGraph) { private fun inlineSubroutines(callgraph: CallGraph) {
@ -421,6 +425,11 @@ internal class StatementOptimizer(private val program: Program, private val opti
return repeatLoop return repeatLoop
} }
override fun visit(nopStatement: NopStatement): IStatement {
this.nopStatements.add(nopStatement)
return nopStatement
}
private fun hasContinueOrBreak(scope: INameScope): Boolean { private fun hasContinueOrBreak(scope: INameScope): Boolean {
class Searcher: IAstModifyingVisitor class Searcher: IAstModifyingVisitor

View File

@ -12,11 +12,13 @@
@(xw) = 1 ; @todo should turn border white @(xw) = 1 ; @todo should turn border white
@(xw) = 1 ; @todo should turn border white @(xw) = 1 ; @todo should turn border white
; Y=12 ; @todo gets removed in assembly???!!! Y=12 ; @todo gets removed in assembly???!!!
; A=Y A=Y
; A=99 A=99
; @($d021)=A A=A
; @(xw) = A A=22
@($d021)=A
@(xw) = A
} }