change many uses of .definingScope to just the parent node

This commit is contained in:
Irmen de Jong 2021-10-26 23:25:16 +02:00
parent 743c8b44a2
commit 141689e697
5 changed files with 32 additions and 31 deletions

View File

@ -19,8 +19,8 @@ class AstPreprocessor : AstWalker() {
// move vardecls in Anonymous scope up to the containing subroutine // move vardecls in Anonymous scope up to the containing subroutine
// and add initialization assignment in its place if needed // and add initialization assignment in its place if needed
val vars = scope.statements.filterIsInstance<VarDecl>() val vars = scope.statements.filterIsInstance<VarDecl>()
if(vars.any() && scope.definingScope !== parent) { val parentscope = scope.definingScope
val parentscope = scope.definingScope if(vars.any() && parentscope !== parent) {
val movements = mutableListOf<IAstModification>() val movements = mutableListOf<IAstModification>()
val replacements = mutableListOf<IAstModification>() val replacements = mutableListOf<IAstModification>()

View File

@ -1,5 +1,6 @@
package prog8.compiler.astprocessing package prog8.compiler.astprocessing
import prog8.ast.IStatementContainer
import prog8.ast.Node import prog8.ast.Node
import prog8.ast.Program import prog8.ast.Program
import prog8.ast.base.DataType import prog8.ast.base.DataType
@ -44,7 +45,7 @@ internal class LiteralsToAutoVars(private val program: Program) : AstWalker() {
val identifier = IdentifierReference(listOf(vardecl2.name), vardecl2.position) val identifier = IdentifierReference(listOf(vardecl2.name), vardecl2.position)
return listOf( return listOf(
IAstModification.ReplaceNode(array, identifier, parent), IAstModification.ReplaceNode(array, identifier, parent),
IAstModification.InsertFirst(vardecl2, array.definingScope) IAstModification.InsertFirst(vardecl2, array.parent as IStatementContainer)
) )
} }
} }

View File

@ -76,7 +76,7 @@ internal class StatementOptimizer(private val program: Program,
val functionName = functionCallStatement.target.nameInSource[0] val functionName = functionCallStatement.target.nameInSource[0]
if (functionName in functions.purefunctionNames) { if (functionName in functions.purefunctionNames) {
errors.warn("statement has no effect (function return value is discarded)", functionCallStatement.position) errors.warn("statement has no effect (function return value is discarded)", functionCallStatement.position)
return listOf(IAstModification.Remove(functionCallStatement, functionCallStatement.definingScope)) return listOf(IAstModification.Remove(functionCallStatement, parent as IStatementContainer))
} }
} }
@ -127,7 +127,7 @@ internal class StatementOptimizer(private val program: Program,
if(subroutine!=null) { if(subroutine!=null) {
val first = subroutine.statements.asSequence().filterNot { it is VarDecl || it is Directive }.firstOrNull() val first = subroutine.statements.asSequence().filterNot { it is VarDecl || it is Directive }.firstOrNull()
if(first is Return) if(first is Return)
return listOf(IAstModification.Remove(functionCallStatement, functionCallStatement.definingScope)) return listOf(IAstModification.Remove(functionCallStatement, parent as IStatementContainer))
} }
return noModifications return noModifications
@ -150,7 +150,7 @@ internal class StatementOptimizer(private val program: Program,
override fun after(ifStatement: IfStatement, parent: Node): Iterable<IAstModification> { override fun after(ifStatement: IfStatement, parent: Node): Iterable<IAstModification> {
// remove empty if statements // remove empty if statements
if(ifStatement.truepart.isEmpty() && ifStatement.elsepart.isEmpty()) if(ifStatement.truepart.isEmpty() && ifStatement.elsepart.isEmpty())
return listOf(IAstModification.Remove(ifStatement, ifStatement.definingScope)) return listOf(IAstModification.Remove(ifStatement, parent as IStatementContainer))
// empty true part? switch with the else part // empty true part? switch with the else part
if(ifStatement.truepart.isEmpty() && ifStatement.elsepart.isNotEmpty()) { if(ifStatement.truepart.isEmpty() && ifStatement.elsepart.isNotEmpty()) {
@ -183,12 +183,12 @@ internal class StatementOptimizer(private val program: Program,
override fun after(forLoop: ForLoop, parent: Node): Iterable<IAstModification> { override fun after(forLoop: ForLoop, parent: Node): Iterable<IAstModification> {
if(forLoop.body.isEmpty()) { if(forLoop.body.isEmpty()) {
errors.warn("removing empty for loop", forLoop.position) errors.warn("removing empty for loop", forLoop.position)
return listOf(IAstModification.Remove(forLoop, forLoop.definingScope)) return listOf(IAstModification.Remove(forLoop, parent as IStatementContainer))
} else if(forLoop.body.statements.size==1) { } else if(forLoop.body.statements.size==1) {
val loopvar = forLoop.body.statements[0] as? VarDecl val loopvar = forLoop.body.statements[0] as? VarDecl
if(loopvar!=null && loopvar.name==forLoop.loopVar.nameInSource.singleOrNull()) { if(loopvar!=null && loopvar.name==forLoop.loopVar.nameInSource.singleOrNull()) {
// remove empty for loop (only loopvar decl in it) // remove empty for loop (only loopvar decl in it)
return listOf(IAstModification.Remove(forLoop, forLoop.definingScope)) return listOf(IAstModification.Remove(forLoop, parent as IStatementContainer))
} }
} }
@ -265,7 +265,7 @@ internal class StatementOptimizer(private val program: Program,
} else { } else {
// always false -> remove the while statement altogether // always false -> remove the while statement altogether
errors.warn("condition is always false", whileLoop.condition.position) errors.warn("condition is always false", whileLoop.condition.position)
listOf(IAstModification.Remove(whileLoop, whileLoop.definingScope)) listOf(IAstModification.Remove(whileLoop, parent as IStatementContainer))
} }
} }
return noModifications return noModifications
@ -276,12 +276,12 @@ internal class StatementOptimizer(private val program: Program,
if(iter!=null) { if(iter!=null) {
if(repeatLoop.body.isEmpty()) { if(repeatLoop.body.isEmpty()) {
errors.warn("empty loop removed", repeatLoop.position) errors.warn("empty loop removed", repeatLoop.position)
return listOf(IAstModification.Remove(repeatLoop, repeatLoop.definingScope)) return listOf(IAstModification.Remove(repeatLoop, parent as IStatementContainer))
} }
val iterations = iter.constValue(program)?.number?.toInt() val iterations = iter.constValue(program)?.number?.toInt()
if (iterations == 0) { if (iterations == 0) {
errors.warn("iterations is always 0, removed loop", iter.position) errors.warn("iterations is always 0, removed loop", iter.position)
return listOf(IAstModification.Remove(repeatLoop, repeatLoop.definingScope)) return listOf(IAstModification.Remove(repeatLoop, parent as IStatementContainer))
} }
if (iterations == 1) { if (iterations == 1) {
errors.warn("iterations is always 1", iter.position) errors.warn("iterations is always 1", iter.position)
@ -293,10 +293,10 @@ internal class StatementOptimizer(private val program: Program,
override fun after(jump: Jump, parent: Node): Iterable<IAstModification> { override fun after(jump: Jump, parent: Node): Iterable<IAstModification> {
// if the jump is to the next statement, remove the jump // if the jump is to the next statement, remove the jump
val scope = jump.definingScope val scope = jump.parent as IStatementContainer
val label = jump.identifier?.targetStatement(program) val label = jump.identifier?.targetStatement(program)
if(label!=null && scope.statements.indexOf(label) == scope.statements.indexOf(jump)+1) if(label!=null && scope.statements.indexOf(label) == scope.statements.indexOf(jump)+1)
return listOf(IAstModification.Remove(jump, jump.definingScope)) return listOf(IAstModification.Remove(jump, scope))
return noModifications return noModifications
} }
@ -329,7 +329,7 @@ internal class StatementOptimizer(private val program: Program,
) )
return listOf( return listOf(
IAstModification.ReplaceNode(binExpr, expr2, binExpr.parent), IAstModification.ReplaceNode(binExpr, expr2, binExpr.parent),
IAstModification.InsertAfter(assignment, addConstant, assignment.definingScope)) IAstModification.InsertAfter(assignment, addConstant, parent as IStatementContainer))
} else if (op2 == "-") { } else if (op2 == "-") {
// A = A +/- B - N // A = A +/- B - N
val expr2 = BinaryExpression(binExpr.left, binExpr.operator, rExpr.left, binExpr.position) val expr2 = BinaryExpression(binExpr.left, binExpr.operator, rExpr.left, binExpr.position)
@ -340,7 +340,7 @@ internal class StatementOptimizer(private val program: Program,
) )
return listOf( return listOf(
IAstModification.ReplaceNode(binExpr, expr2, binExpr.parent), IAstModification.ReplaceNode(binExpr, expr2, binExpr.parent),
IAstModification.InsertAfter(assignment, subConstant, assignment.definingScope)) IAstModification.InsertAfter(assignment, subConstant, parent as IStatementContainer))
} }
} }
} }
@ -362,7 +362,7 @@ internal class StatementOptimizer(private val program: Program,
override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> { override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
if(assignment.target isSameAs assignment.value) { if(assignment.target isSameAs assignment.value) {
// remove assignment to self // remove assignment to self
return listOf(IAstModification.Remove(assignment, assignment.definingScope)) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
} }
val targetIDt = assignment.target.inferType(program) val targetIDt = assignment.target.inferType(program)
@ -382,7 +382,7 @@ internal class StatementOptimizer(private val program: Program,
when (bexpr.operator) { when (bexpr.operator) {
"+" -> { "+" -> {
if (rightCv == 0.0) { if (rightCv == 0.0) {
return listOf(IAstModification.Remove(assignment, assignment.definingScope)) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
} else if (targetDt in IntegerDatatypes && floor(rightCv) == rightCv) { } else if (targetDt in IntegerDatatypes && floor(rightCv) == rightCv) {
if (vardeclDt != VarDeclType.MEMORY && rightCv in 1.0..4.0) { if (vardeclDt != VarDeclType.MEMORY && rightCv in 1.0..4.0) {
// replace by several INCs if it's not a memory address (inc on a memory mapped register doesn't work very well) // replace by several INCs if it's not a memory address (inc on a memory mapped register doesn't work very well)
@ -396,7 +396,7 @@ internal class StatementOptimizer(private val program: Program,
} }
"-" -> { "-" -> {
if (rightCv == 0.0) { if (rightCv == 0.0) {
return listOf(IAstModification.Remove(assignment, assignment.definingScope)) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
} else if (targetDt in IntegerDatatypes && floor(rightCv) == rightCv) { } else if (targetDt in IntegerDatatypes && floor(rightCv) == rightCv) {
if (vardeclDt != VarDeclType.MEMORY && rightCv in 1.0..4.0) { if (vardeclDt != VarDeclType.MEMORY && rightCv in 1.0..4.0) {
// replace by several DECs if it's not a memory address (dec on a memory mapped register doesn't work very well) // replace by several DECs if it's not a memory address (dec on a memory mapped register doesn't work very well)
@ -408,18 +408,18 @@ internal class StatementOptimizer(private val program: Program,
} }
} }
} }
"*" -> if (rightCv == 1.0) return listOf(IAstModification.Remove(assignment, assignment.definingScope)) "*" -> if (rightCv == 1.0) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
"/" -> if (rightCv == 1.0) return listOf(IAstModification.Remove(assignment, assignment.definingScope)) "/" -> if (rightCv == 1.0) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
"**" -> if (rightCv == 1.0) return listOf(IAstModification.Remove(assignment, assignment.definingScope)) "**" -> if (rightCv == 1.0) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
"|" -> if (rightCv == 0.0) return listOf(IAstModification.Remove(assignment, assignment.definingScope)) "|" -> if (rightCv == 0.0) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
"^" -> if (rightCv == 0.0) return listOf(IAstModification.Remove(assignment, assignment.definingScope)) "^" -> if (rightCv == 0.0) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
"<<" -> { "<<" -> {
if (rightCv == 0.0) if (rightCv == 0.0)
return listOf(IAstModification.Remove(assignment, assignment.definingScope)) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
} }
">>" -> { ">>" -> {
if (rightCv == 0.0) if (rightCv == 0.0)
return listOf(IAstModification.Remove(assignment, assignment.definingScope)) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
} }
} }

View File

@ -22,7 +22,7 @@ internal class UnusedCodeRemover(private val program: Program,
override fun before(module: Module, parent: Node): Iterable<IAstModification> { override fun before(module: Module, parent: Node): Iterable<IAstModification> {
return if (!module.isLibrary && (module.containsNoCodeNorVars || callgraph.unused(module))) return if (!module.isLibrary && (module.containsNoCodeNorVars || callgraph.unused(module)))
listOf(IAstModification.Remove(module, module.definingScope)) listOf(IAstModification.Remove(module, parent as IStatementContainer))
else else
noModifications noModifications
} }
@ -84,16 +84,16 @@ internal class UnusedCodeRemover(private val program: Program,
if(subroutine.containsNoCodeNorVars) { if(subroutine.containsNoCodeNorVars) {
if(!subroutine.definingModule.isLibrary) if(!subroutine.definingModule.isLibrary)
errors.warn("removing empty subroutine '${subroutine.name}'", subroutine.position) errors.warn("removing empty subroutine '${subroutine.name}'", subroutine.position)
val removals = mutableListOf(IAstModification.Remove(subroutine, subroutine.definingScope)) val removals = mutableListOf(IAstModification.Remove(subroutine, parent as IStatementContainer))
callgraph.calledBy[subroutine]?.let { callgraph.calledBy[subroutine]?.let {
for(node in it) for(node in it)
removals.add(IAstModification.Remove(node, node.definingScope)) removals.add(IAstModification.Remove(node, node.parent as IStatementContainer))
} }
return removals return removals
} }
if(!subroutine.definingModule.isLibrary) if(!subroutine.definingModule.isLibrary)
errors.warn("removing unused subroutine '${subroutine.name}'", subroutine.position) errors.warn("removing unused subroutine '${subroutine.name}'", subroutine.position)
return listOf(IAstModification.Remove(subroutine, subroutine.definingScope)) return listOf(IAstModification.Remove(subroutine, parent as IStatementContainer))
} }
} }
@ -107,7 +107,7 @@ internal class UnusedCodeRemover(private val program: Program,
if (!forceOutput && !decl.autogeneratedDontRemove && !decl.sharedWithAsm && !decl.definingBlock.isInLibrary) { if (!forceOutput && !decl.autogeneratedDontRemove && !decl.sharedWithAsm && !decl.definingBlock.isInLibrary) {
if (callgraph.unused(decl)) { if (callgraph.unused(decl)) {
errors.warn("removing unused variable '${decl.name}'", decl.position) errors.warn("removing unused variable '${decl.name}'", decl.position)
return listOf(IAstModification.Remove(decl, decl.definingScope)) return listOf(IAstModification.Remove(decl, parent as IStatementContainer))
} }
} }
} }

View File

@ -98,7 +98,7 @@ class AstToSourceCode(val output: (text: String) -> Unit, val program: Program):
override fun visit(decl: VarDecl) { override fun visit(decl: VarDecl) {
// if the vardecl is a parameter of a subroutine, don't output it again // if the vardecl is a parameter of a subroutine, don't output it again
val paramNames = (decl.definingScope as? Subroutine)?.parameters?.map { it.name } val paramNames = decl.definingSubroutine?.parameters?.map { it.name }
if(paramNames!=null && decl.name in paramNames) if(paramNames!=null && decl.name in paramNames)
return return