From 29ac160811433a7f9c3d1a6791a79b03a336b6c9 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 19 Mar 2020 22:36:15 +0100 Subject: [PATCH] applying new astwalker for modifications --- compiler/src/prog8/ast/base/Extensions.kt | 11 +- .../AnonScopeVarsToSubroutineMover.kt | 39 ++++ .../src/prog8/ast/processing/AstWalker.kt | 186 +++++++++--------- ...keForeverLoops.kt => ForeverLoopsMaker.kt} | 10 +- .../ImportedModuleDirectiveRemover.kt | 4 +- .../MoveAnonScopeVarsToSubroutine.kt | 41 ---- compiler/src/prog8/compiler/Main.kt | 2 +- ...Folding.kt => ConstantFoldingOptimizer.kt} | 2 +- ...Expressions.kt => ExpressionSimplifier.kt} | 2 +- compiler/src/prog8/optimizer/Extensions.kt | 4 +- ...=> FlattenAnonymousScopesAndNopRemover.kt} | 2 +- examples/test.p8 | 18 ++ 12 files changed, 169 insertions(+), 152 deletions(-) create mode 100644 compiler/src/prog8/ast/processing/AnonScopeVarsToSubroutineMover.kt rename compiler/src/prog8/ast/processing/{MakeForeverLoops.kt => ForeverLoopsMaker.kt} (77%) delete mode 100644 compiler/src/prog8/ast/processing/MoveAnonScopeVarsToSubroutine.kt rename compiler/src/prog8/optimizer/{ConstantFolding.kt => ConstantFoldingOptimizer.kt} (99%) rename compiler/src/prog8/optimizer/{SimplifyExpressions.kt => ExpressionSimplifier.kt} (99%) rename compiler/src/prog8/optimizer/{FlattenAnonymousScopesAndRemoveNops.kt => FlattenAnonymousScopesAndNopRemover.kt} (95%) diff --git a/compiler/src/prog8/ast/base/Extensions.kt b/compiler/src/prog8/ast/base/Extensions.kt index b71970578..09013b01f 100644 --- a/compiler/src/prog8/ast/base/Extensions.kt +++ b/compiler/src/prog8/ast/base/Extensions.kt @@ -4,7 +4,7 @@ import prog8.ast.Module import prog8.ast.Program import prog8.ast.processing.* import prog8.compiler.CompilationOptions -import prog8.optimizer.FlattenAnonymousScopesAndRemoveNops +import prog8.optimizer.FlattenAnonymousScopesAndNopRemover // the name of the subroutine that should be called for every block to initialize its variables @@ -16,9 +16,10 @@ internal fun Program.checkValid(compilerOptions: CompilationOptions, errors: Err checker.visit(this) } -internal fun Program.anonscopeVarsCleanup(errors: ErrorReporter) { - val mover = MoveAnonScopeVarsToSubroutine(errors) +internal fun Program.moveAnonScopeVarsToSubroutine(errors: ErrorReporter) { + val mover = AnonScopeVarsToSubroutineMover(errors) mover.visit(this) + mover.applyModifications() } internal fun Program.reorderStatements() { @@ -56,12 +57,12 @@ internal fun Program.checkIdentifiers(errors: ErrorReporter) { } internal fun Program.makeForeverLoops() { - val checker = MakeForeverLoops() + val checker = ForeverLoopsMaker() checker.visit(this) checker.applyModifications() } internal fun Program.removeNopsFlattenAnonScopes() { - val flattener = FlattenAnonymousScopesAndRemoveNops() + val flattener = FlattenAnonymousScopesAndNopRemover() flattener.visit(this) } diff --git a/compiler/src/prog8/ast/processing/AnonScopeVarsToSubroutineMover.kt b/compiler/src/prog8/ast/processing/AnonScopeVarsToSubroutineMover.kt new file mode 100644 index 000000000..c6c2f118f --- /dev/null +++ b/compiler/src/prog8/ast/processing/AnonScopeVarsToSubroutineMover.kt @@ -0,0 +1,39 @@ +package prog8.ast.processing + +import prog8.ast.Node +import prog8.ast.base.ErrorReporter +import prog8.ast.statements.AnonymousScope +import prog8.ast.statements.Subroutine +import prog8.ast.statements.VarDecl + + +class AnonScopeVarsToSubroutineMover(val errors: ErrorReporter): AstWalker() { + override fun after(scope: AnonymousScope, parent: Node): Iterable { + val decls = scope.statements.filterIsInstance() + val sub = scope.definingSubroutine() + if(sub!=null) { + val existingVariables = sub.statements.filterIsInstance().associateBy { it.name } + var conflicts = false + decls.forEach { + val existing = existingVariables[it.name] + if (existing!=null) { + errors.err("variable ${it.name} already defined in subroutine ${sub.name} at ${existing.position}", it.position) + conflicts = true + } + } + if(!conflicts) + return listOf(MoveVardecl(decls, scope, sub)) + } + return emptyList() + } + + private class MoveVardecl(val decls: Collection, + val scope: AnonymousScope, + val sub: Subroutine) : IAstModification { + override fun perform() { + decls.forEach { scope.remove(it) } + sub.statements.addAll(0, decls) + decls.forEach { it.parent = sub } + } + } +} diff --git a/compiler/src/prog8/ast/processing/AstWalker.kt b/compiler/src/prog8/ast/processing/AstWalker.kt index 8017f6481..6413e2386 100644 --- a/compiler/src/prog8/ast/processing/AstWalker.kt +++ b/compiler/src/prog8/ast/processing/AstWalker.kt @@ -9,10 +9,10 @@ import prog8.ast.expressions.* import prog8.ast.statements.* -abstract class AstModification(val node: Node) { - abstract fun perform() +interface IAstModification { + fun perform() - class Remove(node: Node, val parent: Node) : AstModification(node) { + class Remove(val node: Node, val parent: Node) : IAstModification { override fun perform() { if(parent is INameScope) { if (!parent.statements.remove(node)) @@ -23,10 +23,10 @@ abstract class AstModification(val node: Node) { } } - class Replace(statement: Statement, val replacement: Statement, val parent: Node) : AstModification(statement) { + class Replace(val statement: Statement, val replacement: Statement, val parent: Node) : IAstModification { override fun perform() { if(parent is INameScope) { - val idx = parent.statements.indexOf(node) + val idx = parent.statements.indexOf(statement) parent.statements[idx] = replacement replacement.linkParents(parent) } else { @@ -38,97 +38,97 @@ abstract class AstModification(val node: Node) { abstract class AstWalker { - open fun before(addressOf: AddressOf, parent: Node): Iterable = emptyList() - open fun before(array: ArrayLiteralValue, parent: Node): Iterable = emptyList() - open fun before(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable = emptyList() - open fun before(assignTarget: AssignTarget, parent: Node): Iterable = emptyList() - open fun before(assignment: Assignment, parent: Node): Iterable = emptyList() - open fun before(block: Block, parent: Node): Iterable = emptyList() - open fun before(branchStatement: BranchStatement, parent: Node): Iterable = emptyList() - open fun before(breakStmt: Break, parent: Node): Iterable = emptyList() - open fun before(builtinFunctionStatementPlaceholder: BuiltinFunctionStatementPlaceholder, parent: Node): Iterable = emptyList() - open fun before(contStmt: Continue, parent: Node): Iterable = emptyList() - open fun before(decl: VarDecl, parent: Node): Iterable = emptyList() - open fun before(directive: Directive, parent: Node): Iterable = emptyList() - open fun before(expr: BinaryExpression, parent: Node): Iterable = emptyList() - open fun before(expr: PrefixExpression, parent: Node): Iterable = emptyList() - open fun before(forLoop: ForLoop, parent: Node): Iterable = emptyList() - open fun before(foreverLoop: ForeverLoop, parent: Node): Iterable = emptyList() - open fun before(functionCall: FunctionCall, parent: Node): Iterable = emptyList() - open fun before(functionCallStatement: FunctionCallStatement, parent: Node): Iterable = emptyList() - open fun before(identifier: IdentifierReference, parent: Node): Iterable = emptyList() - open fun before(ifStatement: IfStatement, parent: Node): Iterable = emptyList() - open fun before(inlineAssembly: InlineAssembly, parent: Node): Iterable = emptyList() - open fun before(jump: Jump, parent: Node): Iterable = emptyList() - open fun before(label: Label, parent: Node): Iterable = emptyList() - open fun before(memread: DirectMemoryRead, parent: Node): Iterable = emptyList() - open fun before(memwrite: DirectMemoryWrite, parent: Node): Iterable = emptyList() - open fun before(module: Module, parent: Node): Iterable = emptyList() - open fun before(nopStatement: NopStatement, parent: Node): Iterable = emptyList() - open fun before(numLiteral: NumericLiteralValue, parent: Node): Iterable = emptyList() - open fun before(postIncrDecr: PostIncrDecr, parent: Node): Iterable = emptyList() - open fun before(program: Program, parent: Node): Iterable = emptyList() - open fun before(range: RangeExpr, parent: Node): Iterable = emptyList() - open fun before(registerExpr: RegisterExpr, parent: Node): Iterable = emptyList() - open fun before(repeatLoop: RepeatLoop, parent: Node): Iterable = emptyList() - open fun before(returnStmt: Return, parent: Node): Iterable = emptyList() - open fun before(scope: AnonymousScope, parent: Node): Iterable = emptyList() - open fun before(string: StringLiteralValue, parent: Node): Iterable = emptyList() - open fun before(structDecl: StructDecl, parent: Node): Iterable = emptyList() - open fun before(structLv: StructLiteralValue, parent: Node): Iterable = emptyList() - open fun before(subroutine: Subroutine, parent: Node): Iterable = emptyList() - open fun before(typecast: TypecastExpression, parent: Node): Iterable = emptyList() - open fun before(whenChoice: WhenChoice, parent: Node): Iterable = emptyList() - open fun before(whenStatement: WhenStatement, parent: Node): Iterable = emptyList() - open fun before(whileLoop: WhileLoop, parent: Node): Iterable = emptyList() + open fun before(addressOf: AddressOf, parent: Node): Iterable = emptyList() + open fun before(array: ArrayLiteralValue, parent: Node): Iterable = emptyList() + open fun before(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable = emptyList() + open fun before(assignTarget: AssignTarget, parent: Node): Iterable = emptyList() + open fun before(assignment: Assignment, parent: Node): Iterable = emptyList() + open fun before(block: Block, parent: Node): Iterable = emptyList() + open fun before(branchStatement: BranchStatement, parent: Node): Iterable = emptyList() + open fun before(breakStmt: Break, parent: Node): Iterable = emptyList() + open fun before(builtinFunctionStatementPlaceholder: BuiltinFunctionStatementPlaceholder, parent: Node): Iterable = emptyList() + open fun before(contStmt: Continue, parent: Node): Iterable = emptyList() + open fun before(decl: VarDecl, parent: Node): Iterable = emptyList() + open fun before(directive: Directive, parent: Node): Iterable = emptyList() + open fun before(expr: BinaryExpression, parent: Node): Iterable = emptyList() + open fun before(expr: PrefixExpression, parent: Node): Iterable = emptyList() + open fun before(forLoop: ForLoop, parent: Node): Iterable = emptyList() + open fun before(foreverLoop: ForeverLoop, parent: Node): Iterable = emptyList() + open fun before(functionCall: FunctionCall, parent: Node): Iterable = emptyList() + open fun before(functionCallStatement: FunctionCallStatement, parent: Node): Iterable = emptyList() + open fun before(identifier: IdentifierReference, parent: Node): Iterable = emptyList() + open fun before(ifStatement: IfStatement, parent: Node): Iterable = emptyList() + open fun before(inlineAssembly: InlineAssembly, parent: Node): Iterable = emptyList() + open fun before(jump: Jump, parent: Node): Iterable = emptyList() + open fun before(label: Label, parent: Node): Iterable = emptyList() + open fun before(memread: DirectMemoryRead, parent: Node): Iterable = emptyList() + open fun before(memwrite: DirectMemoryWrite, parent: Node): Iterable = emptyList() + open fun before(module: Module, parent: Node): Iterable = emptyList() + open fun before(nopStatement: NopStatement, parent: Node): Iterable = emptyList() + open fun before(numLiteral: NumericLiteralValue, parent: Node): Iterable = emptyList() + open fun before(postIncrDecr: PostIncrDecr, parent: Node): Iterable = emptyList() + open fun before(program: Program, parent: Node): Iterable = emptyList() + open fun before(range: RangeExpr, parent: Node): Iterable = emptyList() + open fun before(registerExpr: RegisterExpr, parent: Node): Iterable = emptyList() + open fun before(repeatLoop: RepeatLoop, parent: Node): Iterable = emptyList() + open fun before(returnStmt: Return, parent: Node): Iterable = emptyList() + open fun before(scope: AnonymousScope, parent: Node): Iterable = emptyList() + open fun before(string: StringLiteralValue, parent: Node): Iterable = emptyList() + open fun before(structDecl: StructDecl, parent: Node): Iterable = emptyList() + open fun before(structLv: StructLiteralValue, parent: Node): Iterable = emptyList() + open fun before(subroutine: Subroutine, parent: Node): Iterable = emptyList() + open fun before(typecast: TypecastExpression, parent: Node): Iterable = emptyList() + open fun before(whenChoice: WhenChoice, parent: Node): Iterable = emptyList() + open fun before(whenStatement: WhenStatement, parent: Node): Iterable = emptyList() + open fun before(whileLoop: WhileLoop, parent: Node): Iterable = emptyList() - open fun after(addressOf: AddressOf, parent: Node): Iterable = emptyList() - open fun after(array: ArrayLiteralValue, parent: Node): Iterable = emptyList() - open fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable = emptyList() - open fun after(assignTarget: AssignTarget, parent: Node): Iterable = emptyList() - open fun after(assignment: Assignment, parent: Node): Iterable = emptyList() - open fun after(block: Block, parent: Node): Iterable = emptyList() - open fun after(branchStatement: BranchStatement, parent: Node): Iterable = emptyList() - open fun after(breakStmt: Break, parent: Node): Iterable = emptyList() - open fun after(builtinFunctionStatementPlaceholder: BuiltinFunctionStatementPlaceholder, parent: Node): Iterable = emptyList() - open fun after(contStmt: Continue, parent: Node): Iterable = emptyList() - open fun after(decl: VarDecl, parent: Node): Iterable = emptyList() - open fun after(directive: Directive, parent: Node): Iterable = emptyList() - open fun after(expr: BinaryExpression, parent: Node): Iterable = emptyList() - open fun after(expr: PrefixExpression, parent: Node): Iterable = emptyList() - open fun after(forLoop: ForLoop, parent: Node): Iterable = emptyList() - open fun after(foreverLoop: ForeverLoop, parent: Node): Iterable = emptyList() - open fun after(functionCall: FunctionCall, parent: Node): Iterable = emptyList() - open fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable = emptyList() - open fun after(identifier: IdentifierReference, parent: Node): Iterable = emptyList() - open fun after(ifStatement: IfStatement, parent: Node): Iterable = emptyList() - open fun after(inlineAssembly: InlineAssembly, parent: Node): Iterable = emptyList() - open fun after(jump: Jump, parent: Node): Iterable = emptyList() - open fun after(label: Label, parent: Node): Iterable = emptyList() - open fun after(memread: DirectMemoryRead, parent: Node): Iterable = emptyList() - open fun after(memwrite: DirectMemoryWrite, parent: Node): Iterable = emptyList() - open fun after(module: Module, parent: Node): Iterable = emptyList() - open fun after(nopStatement: NopStatement, parent: Node): Iterable = emptyList() - open fun after(numLiteral: NumericLiteralValue, parent: Node): Iterable = emptyList() - open fun after(postIncrDecr: PostIncrDecr, parent: Node): Iterable = emptyList() - open fun after(program: Program, parent: Node): Iterable = emptyList() - open fun after(range: RangeExpr, parent: Node): Iterable = emptyList() - open fun after(registerExpr: RegisterExpr, parent: Node): Iterable = emptyList() - open fun after(repeatLoop: RepeatLoop, parent: Node): Iterable = emptyList() - open fun after(returnStmt: Return, parent: Node): Iterable = emptyList() - open fun after(scope: AnonymousScope, parent: Node): Iterable = emptyList() - open fun after(string: StringLiteralValue, parent: Node): Iterable = emptyList() - open fun after(structDecl: StructDecl, parent: Node): Iterable = emptyList() - open fun after(structLv: StructLiteralValue, parent: Node): Iterable = emptyList() - open fun after(subroutine: Subroutine, parent: Node): Iterable = emptyList() - open fun after(typecast: TypecastExpression, parent: Node): Iterable = emptyList() - open fun after(whenChoice: WhenChoice, parent: Node): Iterable = emptyList() - open fun after(whenStatement: WhenStatement, parent: Node): Iterable = emptyList() - open fun after(whileLoop: WhileLoop, parent: Node): Iterable = emptyList() + open fun after(addressOf: AddressOf, parent: Node): Iterable = emptyList() + open fun after(array: ArrayLiteralValue, parent: Node): Iterable = emptyList() + open fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable = emptyList() + open fun after(assignTarget: AssignTarget, parent: Node): Iterable = emptyList() + open fun after(assignment: Assignment, parent: Node): Iterable = emptyList() + open fun after(block: Block, parent: Node): Iterable = emptyList() + open fun after(branchStatement: BranchStatement, parent: Node): Iterable = emptyList() + open fun after(breakStmt: Break, parent: Node): Iterable = emptyList() + open fun after(builtinFunctionStatementPlaceholder: BuiltinFunctionStatementPlaceholder, parent: Node): Iterable = emptyList() + open fun after(contStmt: Continue, parent: Node): Iterable = emptyList() + open fun after(decl: VarDecl, parent: Node): Iterable = emptyList() + open fun after(directive: Directive, parent: Node): Iterable = emptyList() + open fun after(expr: BinaryExpression, parent: Node): Iterable = emptyList() + open fun after(expr: PrefixExpression, parent: Node): Iterable = emptyList() + open fun after(forLoop: ForLoop, parent: Node): Iterable = emptyList() + open fun after(foreverLoop: ForeverLoop, parent: Node): Iterable = emptyList() + open fun after(functionCall: FunctionCall, parent: Node): Iterable = emptyList() + open fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable = emptyList() + open fun after(identifier: IdentifierReference, parent: Node): Iterable = emptyList() + open fun after(ifStatement: IfStatement, parent: Node): Iterable = emptyList() + open fun after(inlineAssembly: InlineAssembly, parent: Node): Iterable = emptyList() + open fun after(jump: Jump, parent: Node): Iterable = emptyList() + open fun after(label: Label, parent: Node): Iterable = emptyList() + open fun after(memread: DirectMemoryRead, parent: Node): Iterable = emptyList() + open fun after(memwrite: DirectMemoryWrite, parent: Node): Iterable = emptyList() + open fun after(module: Module, parent: Node): Iterable = emptyList() + open fun after(nopStatement: NopStatement, parent: Node): Iterable = emptyList() + open fun after(numLiteral: NumericLiteralValue, parent: Node): Iterable = emptyList() + open fun after(postIncrDecr: PostIncrDecr, parent: Node): Iterable = emptyList() + open fun after(program: Program, parent: Node): Iterable = emptyList() + open fun after(range: RangeExpr, parent: Node): Iterable = emptyList() + open fun after(registerExpr: RegisterExpr, parent: Node): Iterable = emptyList() + open fun after(repeatLoop: RepeatLoop, parent: Node): Iterable = emptyList() + open fun after(returnStmt: Return, parent: Node): Iterable = emptyList() + open fun after(scope: AnonymousScope, parent: Node): Iterable = emptyList() + open fun after(string: StringLiteralValue, parent: Node): Iterable = emptyList() + open fun after(structDecl: StructDecl, parent: Node): Iterable = emptyList() + open fun after(structLv: StructLiteralValue, parent: Node): Iterable = emptyList() + open fun after(subroutine: Subroutine, parent: Node): Iterable = emptyList() + open fun after(typecast: TypecastExpression, parent: Node): Iterable = emptyList() + open fun after(whenChoice: WhenChoice, parent: Node): Iterable = emptyList() + open fun after(whenStatement: WhenStatement, parent: Node): Iterable = emptyList() + open fun after(whileLoop: WhileLoop, parent: Node): Iterable = emptyList() - private val modifications = mutableListOf>() + private val modifications = mutableListOf>() - private fun track(mods: Iterable, node: Node, parent: Node) { + private fun track(mods: Iterable, node: Node, parent: Node) { for (it in mods) modifications += Triple(it, node, parent) } diff --git a/compiler/src/prog8/ast/processing/MakeForeverLoops.kt b/compiler/src/prog8/ast/processing/ForeverLoopsMaker.kt similarity index 77% rename from compiler/src/prog8/ast/processing/MakeForeverLoops.kt rename to compiler/src/prog8/ast/processing/ForeverLoopsMaker.kt index e771cce4d..d8b9938e7 100644 --- a/compiler/src/prog8/ast/processing/MakeForeverLoops.kt +++ b/compiler/src/prog8/ast/processing/ForeverLoopsMaker.kt @@ -7,21 +7,21 @@ import prog8.ast.statements.RepeatLoop import prog8.ast.statements.WhileLoop -internal class MakeForeverLoops: AstWalker() { - override fun before(repeatLoop: RepeatLoop, parent: Node): Iterable { +internal class ForeverLoopsMaker: AstWalker() { + override fun before(repeatLoop: RepeatLoop, parent: Node): Iterable { val numeric = repeatLoop.untilCondition as? NumericLiteralValue if(numeric!=null && numeric.number.toInt() == 0) { val forever = ForeverLoop(repeatLoop.body, repeatLoop.position) - return listOf(AstModification.Replace(repeatLoop, forever, parent)) + return listOf(IAstModification.Replace(repeatLoop, forever, parent)) } return emptyList() } - override fun before(whileLoop: WhileLoop, parent: Node): Iterable { + override fun before(whileLoop: WhileLoop, parent: Node): Iterable { val numeric = whileLoop.condition as? NumericLiteralValue if(numeric!=null && numeric.number.toInt() != 0) { val forever = ForeverLoop(whileLoop.body, whileLoop.position) - return listOf(AstModification.Replace(whileLoop, forever, parent)) + return listOf(IAstModification.Replace(whileLoop, forever, parent)) } return emptyList() } diff --git a/compiler/src/prog8/ast/processing/ImportedModuleDirectiveRemover.kt b/compiler/src/prog8/ast/processing/ImportedModuleDirectiveRemover.kt index 8dd4563f5..2b7c90753 100644 --- a/compiler/src/prog8/ast/processing/ImportedModuleDirectiveRemover.kt +++ b/compiler/src/prog8/ast/processing/ImportedModuleDirectiveRemover.kt @@ -11,9 +11,9 @@ internal class ImportedModuleDirectiveRemover: AstWalker() { private val moduleLevelDirectives = listOf("%output", "%launcher", "%zeropage", "%zpreserved", "%address") - override fun before(directive: Directive, parent: Node): Iterable { + override fun before(directive: Directive, parent: Node): Iterable { if(directive.directive in moduleLevelDirectives) { - return listOf(AstModification.Remove(directive, parent)) + return listOf(IAstModification.Remove(directive, parent)) } return emptyList() } diff --git a/compiler/src/prog8/ast/processing/MoveAnonScopeVarsToSubroutine.kt b/compiler/src/prog8/ast/processing/MoveAnonScopeVarsToSubroutine.kt deleted file mode 100644 index 9e9fadb4e..000000000 --- a/compiler/src/prog8/ast/processing/MoveAnonScopeVarsToSubroutine.kt +++ /dev/null @@ -1,41 +0,0 @@ -package prog8.ast.processing - -import prog8.ast.Program -import prog8.ast.base.ErrorReporter -import prog8.ast.statements.AnonymousScope -import prog8.ast.statements.Statement -import prog8.ast.statements.VarDecl - -class MoveAnonScopeVarsToSubroutine(private val errors: ErrorReporter): IAstModifyingVisitor { - private val varsToMove: MutableMap> = mutableMapOf() - - override fun visit(program: Program) { - varsToMove.clear() - super.visit(program) - for((scope, decls) in varsToMove) { - val sub = scope.definingSubroutine()!! - val existingVariables = sub.statements.filterIsInstance().associateBy { it.name } - var conflicts = false - decls.forEach { - val existing = existingVariables[it.name] - if (existing!=null) { - errors.err("variable ${it.name} already defined in subroutine ${sub.name} at ${existing.position}", it.position) - conflicts = true - } - } - if (!conflicts) { - decls.forEach { scope.remove(it) } - sub.statements.addAll(0, decls) - decls.forEach { it.parent = sub } - } - } - } - - override fun visit(scope: AnonymousScope): Statement { - val scope2 = super.visit(scope) as AnonymousScope - val vardecls = scope2.statements.filterIsInstance() - varsToMove[scope2] = vardecls - return scope2 - } -} - diff --git a/compiler/src/prog8/compiler/Main.kt b/compiler/src/prog8/compiler/Main.kt index 2d69fe7a6..ef8270855 100644 --- a/compiler/src/prog8/compiler/Main.kt +++ b/compiler/src/prog8/compiler/Main.kt @@ -117,7 +117,7 @@ fun compileProgram(filepath: Path, if(writeAssembly) { // asm generation directly from the Ast, no need for intermediate code val zeropage = CompilationTarget.machine.getZeropage(compilerOptions) - programAst.anonscopeVarsCleanup(errors) + programAst.moveAnonScopeVarsToSubroutine(errors) errors.handle() val assembly = CompilationTarget.asmGenerator(programAst, zeropage, compilerOptions, outputDir).compileToAssembly(optimize) assembly.assemble(compilerOptions) diff --git a/compiler/src/prog8/optimizer/ConstantFolding.kt b/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt similarity index 99% rename from compiler/src/prog8/optimizer/ConstantFolding.kt rename to compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt index a84147c07..f5f727460 100644 --- a/compiler/src/prog8/optimizer/ConstantFolding.kt +++ b/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt @@ -11,7 +11,7 @@ import prog8.functions.BuiltinFunctions import kotlin.math.floor -class ConstantFolding(private val program: Program, private val errors: ErrorReporter) : IAstModifyingVisitor { +class ConstantFoldingOptimizer(private val program: Program, private val errors: ErrorReporter) : IAstModifyingVisitor { var optimizationsDone: Int = 0 override fun visit(decl: VarDecl): Statement { diff --git a/compiler/src/prog8/optimizer/SimplifyExpressions.kt b/compiler/src/prog8/optimizer/ExpressionSimplifier.kt similarity index 99% rename from compiler/src/prog8/optimizer/SimplifyExpressions.kt rename to compiler/src/prog8/optimizer/ExpressionSimplifier.kt index 35cb18583..1fb16a03b 100644 --- a/compiler/src/prog8/optimizer/SimplifyExpressions.kt +++ b/compiler/src/prog8/optimizer/ExpressionSimplifier.kt @@ -17,7 +17,7 @@ import kotlin.math.pow */ -internal class SimplifyExpressions(private val program: Program) : IAstModifyingVisitor { +internal class ExpressionSimplifier(private val program: Program) : IAstModifyingVisitor { var optimizationsDone: Int = 0 override fun visit(assignment: Assignment): Statement { diff --git a/compiler/src/prog8/optimizer/Extensions.kt b/compiler/src/prog8/optimizer/Extensions.kt index fdaa6c275..f14767d27 100644 --- a/compiler/src/prog8/optimizer/Extensions.kt +++ b/compiler/src/prog8/optimizer/Extensions.kt @@ -5,7 +5,7 @@ import prog8.ast.base.ErrorReporter internal fun Program.constantFold(errors: ErrorReporter) { - val optimizer = ConstantFolding(this, errors) + val optimizer = ConstantFoldingOptimizer(this, errors) optimizer.visit(this) while(errors.isEmpty() && optimizer.optimizationsDone>0) { @@ -27,7 +27,7 @@ internal fun Program.optimizeStatements(errors: ErrorReporter): Int { } internal fun Program.simplifyExpressions() : Int { - val optimizer = SimplifyExpressions(this) + val optimizer = ExpressionSimplifier(this) optimizer.visit(this) return optimizer.optimizationsDone } diff --git a/compiler/src/prog8/optimizer/FlattenAnonymousScopesAndRemoveNops.kt b/compiler/src/prog8/optimizer/FlattenAnonymousScopesAndNopRemover.kt similarity index 95% rename from compiler/src/prog8/optimizer/FlattenAnonymousScopesAndRemoveNops.kt rename to compiler/src/prog8/optimizer/FlattenAnonymousScopesAndNopRemover.kt index d78931ec3..ecdcb5ef7 100644 --- a/compiler/src/prog8/optimizer/FlattenAnonymousScopesAndRemoveNops.kt +++ b/compiler/src/prog8/optimizer/FlattenAnonymousScopesAndNopRemover.kt @@ -8,7 +8,7 @@ import prog8.ast.statements.AnonymousScope import prog8.ast.statements.NopStatement import prog8.ast.statements.Statement -internal class FlattenAnonymousScopesAndRemoveNops: IAstVisitor { +internal class FlattenAnonymousScopesAndNopRemover: IAstVisitor { private var scopesToFlatten = mutableListOf() private val nopStatements = mutableListOf() diff --git a/examples/test.p8 b/examples/test.p8 index b1ba127d7..08fa1c930 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,12 +4,30 @@ main { sub start() { + ubyte x11=44 + byte bb0=99 + + A=x11 + while true { A=99 } repeat { + ubyte x1 + + x1=A + A=x1 + + if A==44 { + ubyte y1 + A=y1 + } else { + byte bb1=99 + bb1 += A + bb0=bb1 + } A=44 } until false