reducing dependencies

This commit is contained in:
Irmen de Jong 2021-02-09 01:47:05 +01:00
parent bcd0db984d
commit d6ffb549f6
5 changed files with 15 additions and 10 deletions

View File

@ -91,7 +91,7 @@ fun compileProgram(filepath: Path,
importedFiles = imported
processAst(programAst, errors, compilationOptions)
if (compilationOptions.optimize)
optimizeAst(programAst, errors)
optimizeAst(programAst, errors, BuiltinFunctionsFacade(BuiltinFunctions))
postprocessAst(programAst, errors, compilationOptions)
// printAst(programAst)
@ -134,6 +134,8 @@ private class BuiltinFunctionsFacade(functions: Map<String, FSignature>): IBuilt
lateinit var program: Program
override val names = functions.keys
override val purefunctionNames = functions.filter { it.value.pure }.map { it.key }.toSet()
override fun constValue(name: String, args: List<Expression>, position: Position): NumericLiteralValue? {
val func = BuiltinFunctions[name]
if(func!=null) {
@ -252,14 +254,14 @@ private fun processAst(programAst: Program, errors: ErrorReporter, compilerOptio
errors.handle()
}
private fun optimizeAst(programAst: Program, errors: ErrorReporter) {
private fun optimizeAst(programAst: Program, errors: ErrorReporter, functions: IBuiltinFunctions) {
// optimize the parse tree
println("Optimizing...")
while (true) {
// keep optimizing expressions and statements until no more steps remain
val optsDone1 = programAst.simplifyExpressions()
val optsDone2 = programAst.splitBinaryExpressions()
val optsDone3 = programAst.optimizeStatements(errors)
val optsDone3 = programAst.optimizeStatements(errors, functions)
programAst.constantFold(errors) // because simplified statements and expressions can result in more constants that can be folded away
errors.handle()
if (optsDone1 + optsDone2 + optsDone3 == 0)

View File

@ -1,5 +1,6 @@
package prog8.optimizer
import prog8.ast.IBuiltinFunctions
import prog8.ast.Program
import prog8.compiler.ErrorReporter
@ -38,8 +39,8 @@ internal fun Program.constantFold(errors: ErrorReporter) {
}
internal fun Program.optimizeStatements(errors: ErrorReporter): Int {
val optimizer = StatementOptimizer(this, errors)
internal fun Program.optimizeStatements(errors: ErrorReporter, functions: IBuiltinFunctions): Int {
val optimizer = StatementOptimizer(this, errors, functions)
optimizer.visit(this)
val optimizationCount = optimizer.applyModifications()

View File

@ -1,5 +1,6 @@
package prog8.optimizer
import prog8.ast.IBuiltinFunctions
import prog8.ast.INameScope
import prog8.ast.Node
import prog8.ast.Program
@ -10,18 +11,17 @@ import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
import prog8.ast.walk.IAstVisitor
import prog8.compiler.ErrorReporter
import prog8.compiler.functions.BuiltinFunctions
import prog8.compiler.target.CompilationTarget
import kotlin.math.floor
internal class StatementOptimizer(private val program: Program,
private val errors: ErrorReporter
private val errors: ErrorReporter,
private val functions: IBuiltinFunctions
) : AstWalker() {
private val noModifications = emptyList<IAstModification>()
private val callgraph = CallGraph(program)
private val pureBuiltinFunctions = BuiltinFunctions.filter { it.value.pure }
override fun after(block: Block, parent: Node): Iterable<IAstModification> {
if("force_output" !in block.options()) {
@ -72,9 +72,9 @@ internal class StatementOptimizer(private val program: Program,
}
override fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
if(functionCallStatement.target.nameInSource.size==1 && functionCallStatement.target.nameInSource[0] in BuiltinFunctions) {
if(functionCallStatement.target.nameInSource.size==1 && functionCallStatement.target.nameInSource[0] in functions.names) {
val functionName = functionCallStatement.target.nameInSource[0]
if (functionName in pureBuiltinFunctions) {
if (functionName in functions.purefunctionNames) {
errors.warn("statement has no effect (function return value is discarded)", functionCallStatement.position)
return listOf(IAstModification.Remove(functionCallStatement, functionCallStatement.definingScope()))
}

View File

@ -408,6 +408,7 @@ class TestPetscii {
class TestMemory {
private class DummyFunctions: IBuiltinFunctions {
override val names: Set<String> = emptySet()
override val purefunctionNames: Set<String> = emptySet()
override fun constValue(name: String, args: List<Expression>, position: Position): NumericLiteralValue? = null
override fun returnType(name: String, args: MutableList<Expression>) = InferredTypes.InferredType.unknown()
}

View File

@ -246,6 +246,7 @@ interface IAssignable {
interface IBuiltinFunctions {
val names: Set<String>
val purefunctionNames: Set<String>
fun constValue(name: String, args: List<Expression>, position: Position): NumericLiteralValue?
fun returnType(name: String, args: MutableList<Expression>): InferredTypes.InferredType
}