mirror of
https://github.com/irmen/prog8.git
synced 2024-07-05 22:29:04 +00:00
should not shuffle assignments.
This commit is contained in:
parent
dbe048158c
commit
c1102393bb
@ -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? {
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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???")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user