reduce dependencies on global compilaiontarget

This commit is contained in:
Irmen de Jong 2021-02-18 23:44:26 +01:00
parent 2412f8c531
commit 9bb5b454e4
18 changed files with 55 additions and 53 deletions

View File

@ -19,7 +19,7 @@
; mode 3 = bitmap 320 x 240 x 16c (unsupported TODO not yet implemented) ; mode 3 = bitmap 320 x 240 x 16c (unsupported TODO not yet implemented)
; mode 4 = bitmap 320 x 240 x 256c ; mode 4 = bitmap 320 x 240 x 256c
; mode 5 = bitmap 640 x 480 monochrome ; mode 5 = bitmap 640 x 480 monochrome
; mode 6 = bitmap 640 x 480 x 4c (unsupported TODO being implemented) ; mode 6 = bitmap 640 x 480 x 4c
; mode 7 = bitmap 640 x 480 x 16c (unsupported due to lack of VRAM) ; mode 7 = bitmap 640 x 480 x 16c (unsupported due to lack of VRAM)
; mode 8 = bitmap 640 x 480 x 256c (unsupported due to lack of VRAM) ; mode 8 = bitmap 640 x 480 x 256c (unsupported due to lack of VRAM)

View File

@ -8,7 +8,6 @@ import prog8.ast.base.AstException
import prog8.compiler.CompilationResult import prog8.compiler.CompilationResult
import prog8.compiler.compileProgram import prog8.compiler.compileProgram
import prog8.compiler.target.C64Target import prog8.compiler.target.C64Target
import prog8.compiler.target.ICompilationTarget
import prog8.compiler.target.Cx16Target import prog8.compiler.target.Cx16Target
import prog8.parser.ParsingFailedError import prog8.parser.ParsingFailedError
import java.nio.file.FileSystems import java.nio.file.FileSystems
@ -117,7 +116,7 @@ private fun compileMain(args: Array<String>) {
if (compilationResult.programName.isEmpty()) if (compilationResult.programName.isEmpty())
println("\nCan't start emulator because no program was assembled.") println("\nCan't start emulator because no program was assembled.")
else { else {
ICompilationTarget.instance.machine.launchEmulator(compilationResult.programName) compilationResult.compTarget.machine.launchEmulator(compilationResult.programName)
} }
} }
} }

View File

@ -59,6 +59,7 @@ class CompilerException(message: String?) : Exception(message)
class CompilationResult(val success: Boolean, class CompilationResult(val success: Boolean,
val programAst: Program, val programAst: Program,
val programName: String, val programName: String,
val compTarget: ICompilationTarget,
val importedFiles: List<Path>) val importedFiles: List<Path>)
@ -92,7 +93,7 @@ fun compileProgram(filepath: Path,
importedFiles = imported importedFiles = imported
processAst(programAst, errors, compilationOptions, ICompilationTarget.instance) processAst(programAst, errors, compilationOptions, ICompilationTarget.instance)
if (compilationOptions.optimize) if (compilationOptions.optimize)
optimizeAst(programAst, errors, BuiltinFunctionsFacade(BuiltinFunctions)) optimizeAst(programAst, errors, BuiltinFunctionsFacade(BuiltinFunctions), ICompilationTarget.instance)
postprocessAst(programAst, errors, compilationOptions, ICompilationTarget.instance) postprocessAst(programAst, errors, compilationOptions, ICompilationTarget.instance)
// printAst(programAst) // printAst(programAst)
@ -103,7 +104,7 @@ fun compileProgram(filepath: Path,
System.out.flush() System.out.flush()
System.err.flush() System.err.flush()
println("\nTotal compilation+assemble time: ${totalTime / 1000.0} sec.") println("\nTotal compilation+assemble time: ${totalTime / 1000.0} sec.")
return CompilationResult(true, programAst, programName, importedFiles) return CompilationResult(true, programAst, programName, ICompilationTarget.instance, importedFiles)
} catch (px: ParsingFailedError) { } catch (px: ParsingFailedError) {
System.err.print("\u001b[91m") // bright red System.err.print("\u001b[91m") // bright red
@ -128,7 +129,7 @@ fun compileProgram(filepath: Path,
} }
val failedProgram = Program("failed", mutableListOf(), BuiltinFunctionsFacade(BuiltinFunctions)) val failedProgram = Program("failed", mutableListOf(), BuiltinFunctionsFacade(BuiltinFunctions))
return CompilationResult(false, failedProgram, programName, emptyList()) return CompilationResult(false, failedProgram, programName, ICompilationTarget.instance, emptyList())
} }
private class BuiltinFunctionsFacade(functions: Map<String, FSignature>): IBuiltinFunctions { private class BuiltinFunctionsFacade(functions: Map<String, FSignature>): IBuiltinFunctions {
@ -242,7 +243,7 @@ private fun processAst(programAst: Program, errors: ErrorReporter, compilerOptio
println("Processing for target ${compTarget.name}...") println("Processing for target ${compTarget.name}...")
programAst.checkIdentifiers(errors, compTarget) programAst.checkIdentifiers(errors, compTarget)
errors.handle() errors.handle()
programAst.constantFold(errors) programAst.constantFold(errors, compTarget)
errors.handle() errors.handle()
programAst.reorderStatements(errors) programAst.reorderStatements(errors)
errors.handle() errors.handle()
@ -255,21 +256,21 @@ private fun processAst(programAst: Program, errors: ErrorReporter, compilerOptio
errors.handle() errors.handle()
} }
private fun optimizeAst(programAst: Program, errors: ErrorReporter, functions: IBuiltinFunctions) { private fun optimizeAst(programAst: Program, errors: ErrorReporter, functions: IBuiltinFunctions, compTarget: ICompilationTarget) {
// optimize the parse tree // optimize the parse tree
println("Optimizing...") println("Optimizing...")
while (true) { while (true) {
// keep optimizing expressions and statements until no more steps remain // keep optimizing expressions and statements until no more steps remain
val optsDone1 = programAst.simplifyExpressions() val optsDone1 = programAst.simplifyExpressions()
val optsDone2 = programAst.splitBinaryExpressions() val optsDone2 = programAst.splitBinaryExpressions(compTarget)
val optsDone3 = programAst.optimizeStatements(errors, functions) val optsDone3 = programAst.optimizeStatements(errors, functions, compTarget)
programAst.constantFold(errors) // because simplified statements and expressions can result in more constants that can be folded away programAst.constantFold(errors, compTarget) // because simplified statements and expressions can result in more constants that can be folded away
errors.handle() errors.handle()
if (optsDone1 + optsDone2 + optsDone3 == 0) if (optsDone1 + optsDone2 + optsDone3 == 0)
break break
} }
val remover = UnusedCodeRemover(programAst, errors) val remover = UnusedCodeRemover(programAst, errors, compTarget)
remover.visit(programAst) remover.visit(programAst)
remover.applyModifications() remover.applyModifications()
errors.handle() errors.handle()

View File

@ -16,7 +16,7 @@ import prog8.compiler.target.cx16.CX16MachineDefinition
import java.nio.file.Path import java.nio.file.Path
internal interface ICompilationTarget: IStringEncoding { interface ICompilationTarget: IStringEncoding {
val name: String val name: String
val machine: IMachineDefinition val machine: IMachineDefinition
override fun encodeString(str: String, altEncoding: Boolean): List<Short> override fun encodeString(str: String, altEncoding: Boolean): List<Short>

View File

@ -4,17 +4,17 @@ import prog8.compiler.CompilationOptions
import prog8.compiler.Zeropage import prog8.compiler.Zeropage
internal interface IMachineFloat { interface IMachineFloat {
fun toDouble(): Double fun toDouble(): Double
fun makeFloatFillAsm(): String fun makeFloatFillAsm(): String
} }
internal enum class CpuType { enum class CpuType {
CPU6502, CPU6502,
CPU65c02 CPU65c02
} }
internal interface IMachineDefinition { interface IMachineDefinition {
val FLOAT_MAX_NEGATIVE: Double val FLOAT_MAX_NEGATIVE: Double
val FLOAT_MAX_POSITIVE: Double val FLOAT_MAX_POSITIVE: Double
val FLOAT_MEM_SIZE: Int val FLOAT_MEM_SIZE: Int

View File

@ -68,7 +68,6 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
private fun funcMemory(fcall: IFunctionCall, discardResult: Boolean, resultToStack: Boolean, resultRegister: RegisterOrPair?) { private fun funcMemory(fcall: IFunctionCall, discardResult: Boolean, resultToStack: Boolean, resultRegister: RegisterOrPair?) {
if(discardResult || fcall !is FunctionCall) if(discardResult || fcall !is FunctionCall)
throw AssemblyError("should not discard result of memory allocation at $fcall") throw AssemblyError("should not discard result of memory allocation at $fcall")
val scope = fcall.definingScope()
val nameRef = fcall.args[0] as IdentifierReference val nameRef = fcall.args[0] as IdentifierReference
val name = (nameRef.targetVarDecl(program)!!.value as StringLiteralValue).value val name = (nameRef.targetVarDecl(program)!!.value as StringLiteralValue).value
val size = (fcall.args[1] as NumericLiteralValue).number.toInt() val size = (fcall.args[1] as NumericLiteralValue).number.toInt()
@ -85,7 +84,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
AsmAssignTarget(TargetStorageKind.STACK, program, asmgen, DataType.UWORD, null) AsmAssignTarget(TargetStorageKind.STACK, program, asmgen, DataType.UWORD, null)
else else
AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, null, program, asmgen) AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, null, program, asmgen)
val assign = AsmAssignment(src, target, false, fcall.position) val assign = AsmAssignment(src, target, false, asmgen.compTarget, fcall.position)
asmgen.translateNormalAssignment(assign) asmgen.translateNormalAssignment(assign)
asmgen.slabs[name] = size asmgen.slabs[name] = size
} }
@ -647,12 +646,12 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
val assignFirst = AsmAssignment( val assignFirst = AsmAssignment(
AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, datatype, variableAsmName = "P8ZP_SCRATCH_W2"), AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, datatype, variableAsmName = "P8ZP_SCRATCH_W2"),
targetFromExpr(first, datatype), targetFromExpr(first, datatype),
false, first.position false, asmgen.compTarget, first.position
) )
val assignSecond = AsmAssignment( val assignSecond = AsmAssignment(
AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, datatype, variableAsmName = "P8ZP_SCRATCH_W1"), AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, datatype, variableAsmName = "P8ZP_SCRATCH_W1"),
targetFromExpr(second, datatype), targetFromExpr(second, datatype),
false, second.position false, asmgen.compTarget, second.position
) )
asmgen.translateNormalAssignment(assignFirst) asmgen.translateNormalAssignment(assignFirst)
asmgen.translateNormalAssignment(assignSecond) asmgen.translateNormalAssignment(assignSecond)
@ -664,12 +663,12 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
val assignFirst = AsmAssignment( val assignFirst = AsmAssignment(
AsmAssignSource(SourceStorageKind.STACK, program, asmgen, DataType.FLOAT), AsmAssignSource(SourceStorageKind.STACK, program, asmgen, DataType.FLOAT),
targetFromExpr(first, datatype), targetFromExpr(first, datatype),
false, first.position false, asmgen.compTarget, first.position
) )
val assignSecond = AsmAssignment( val assignSecond = AsmAssignment(
AsmAssignSource(SourceStorageKind.STACK, program, asmgen, DataType.FLOAT), AsmAssignSource(SourceStorageKind.STACK, program, asmgen, DataType.FLOAT),
targetFromExpr(second, datatype), targetFromExpr(second, datatype),
false, second.position false, asmgen.compTarget, second.position
) )
asmgen.translateNormalAssignment(assignFirst) asmgen.translateNormalAssignment(assignFirst)
asmgen.translateNormalAssignment(assignSecond) asmgen.translateNormalAssignment(assignSecond)
@ -1288,7 +1287,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
} }
} }
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, conv.dt, null, variableAsmName = varname) val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, conv.dt, null, variableAsmName = varname)
val assign = AsmAssignment(src, tgt, false, value.position) val assign = AsmAssignment(src, tgt, false, asmgen.compTarget, value.position)
asmgen.translateNormalAssignment(assign) asmgen.translateNormalAssignment(assign)
} }
conv.reg != null -> { conv.reg != null -> {
@ -1304,7 +1303,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
} }
} }
val tgt = AsmAssignTarget.fromRegisters(conv.reg, null, program, asmgen) val tgt = AsmAssignTarget.fromRegisters(conv.reg, null, program, asmgen)
val assign = AsmAssignment(src, tgt, false, value.position) val assign = AsmAssignment(src, tgt, false, asmgen.compTarget, value.position)
asmgen.translateNormalAssignment(assign) asmgen.translateNormalAssignment(assign)
} }
else -> throw AssemblyError("callconv") else -> throw AssemblyError("callconv")

View File

@ -318,7 +318,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
} else { } else {
AsmAssignSource.fromAstSource(value, program, asmgen).adjustSignedUnsigned(target) AsmAssignSource.fromAstSource(value, program, asmgen).adjustSignedUnsigned(target)
} }
asmgen.translateNormalAssignment(AsmAssignment(src, target, false, Position.DUMMY)) asmgen.translateNormalAssignment(AsmAssignment(src, target, false, asmgen.compTarget, Position.DUMMY))
} }
} }
} }

View File

@ -207,12 +207,13 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
internal class AsmAssignment(val source: AsmAssignSource, internal class AsmAssignment(val source: AsmAssignSource,
val target: AsmAssignTarget, val target: AsmAssignTarget,
val isAugmentable: Boolean, val isAugmentable: Boolean,
compTarget: ICompilationTarget,
val position: Position) { val position: Position) {
init { init {
if(target.register !in setOf(RegisterOrPair.XY, RegisterOrPair.AX, RegisterOrPair.AY)) if(target.register !in setOf(RegisterOrPair.XY, RegisterOrPair.AX, RegisterOrPair.AY))
require(source.datatype != DataType.STRUCT) { "must not be placeholder datatype" } require(source.datatype != DataType.STRUCT) { "must not be placeholder datatype" }
require(ICompilationTarget.instance.memorySize(source.datatype) <= ICompilationTarget.instance.memorySize(target.datatype)) { require(compTarget.memorySize(source.datatype) <= compTarget.memorySize(target.datatype)) {
"source storage size must be less or equal to target datatype storage size" "source storage size must be less or equal to target datatype storage size"
} }
} }

View File

@ -22,7 +22,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
val target = AsmAssignTarget.fromAstAssignment(assignment, program, asmgen) val target = AsmAssignTarget.fromAstAssignment(assignment, program, asmgen)
val source = AsmAssignSource.fromAstSource(assignment.value, program, asmgen).adjustSignedUnsigned(target) val source = AsmAssignSource.fromAstSource(assignment.value, program, asmgen).adjustSignedUnsigned(target)
val assign = AsmAssignment(source, target, assignment.isAugmentable, assignment.position) val assign = AsmAssignment(source, target, assignment.isAugmentable, asmgen.compTarget, assignment.position)
target.origAssign = assign target.origAssign = assign
if(assign.isAugmentable) if(assign.isAugmentable)
@ -441,7 +441,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
val lsb = FunctionCall(IdentifierReference(listOf("lsb"), value.position), mutableListOf(value), value.position) val lsb = FunctionCall(IdentifierReference(listOf("lsb"), value.position), mutableListOf(value), value.position)
lsb.linkParents(value.parent) lsb.linkParents(value.parent)
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.UBYTE, expression = lsb) val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.UBYTE, expression = lsb)
val assign = AsmAssignment(src, target, false, value.position) val assign = AsmAssignment(src, target, false, asmgen.compTarget, value.position)
translateNormalAssignment(assign) translateNormalAssignment(assign)
} }
@ -2109,21 +2109,21 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
internal fun assignExpressionToRegister(expr: Expression, register: RegisterOrPair) { internal fun assignExpressionToRegister(expr: Expression, register: RegisterOrPair) {
val src = AsmAssignSource.fromAstSource(expr, program, asmgen) val src = AsmAssignSource.fromAstSource(expr, program, asmgen)
val tgt = AsmAssignTarget.fromRegisters(register, null, program, asmgen) val tgt = AsmAssignTarget.fromRegisters(register, null, program, asmgen)
val assign = AsmAssignment(src, tgt, false, expr.position) val assign = AsmAssignment(src, tgt, false, asmgen.compTarget, expr.position)
translateNormalAssignment(assign) translateNormalAssignment(assign)
} }
internal fun assignExpressionToVariable(expr: Expression, asmVarName: String, dt: DataType, scope: Subroutine?) { internal fun assignExpressionToVariable(expr: Expression, asmVarName: String, dt: DataType, scope: Subroutine?) {
val src = AsmAssignSource.fromAstSource(expr, program, asmgen) val src = AsmAssignSource.fromAstSource(expr, program, asmgen)
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, dt, scope, variableAsmName = asmVarName) val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, dt, scope, variableAsmName = asmVarName)
val assign = AsmAssignment(src, tgt, false, expr.position) val assign = AsmAssignment(src, tgt, false, asmgen.compTarget, expr.position)
translateNormalAssignment(assign) translateNormalAssignment(assign)
} }
internal fun assignVariableToRegister(asmVarName: String, register: RegisterOrPair) { internal fun assignVariableToRegister(asmVarName: String, register: RegisterOrPair) {
val tgt = AsmAssignTarget.fromRegisters(register, null, program, asmgen) val tgt = AsmAssignTarget.fromRegisters(register, null, program, asmgen)
val src = AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, tgt.datatype, variableAsmName = asmVarName) val src = AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, tgt.datatype, variableAsmName = asmVarName)
val assign = AsmAssignment(src, tgt, false, Position.DUMMY) val assign = AsmAssignment(src, tgt, false, asmgen.compTarget, Position.DUMMY)
translateNormalAssignment(assign) translateNormalAssignment(assign)
} }
} }

View File

@ -245,19 +245,19 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
when(target.datatype) { when(target.datatype) {
in ByteDatatypes -> { in ByteDatatypes -> {
val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.A, null, program, asmgen) val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.A, null, program, asmgen)
val assign = AsmAssignment(target.origAssign.source, tgt, false, value.position) val assign = AsmAssignment(target.origAssign.source, tgt, false, asmgen.compTarget, value.position)
assignmentAsmGen.translateNormalAssignment(assign) assignmentAsmGen.translateNormalAssignment(assign)
assignmentAsmGen.assignRegisterByte(target, CpuRegister.A) assignmentAsmGen.assignRegisterByte(target, CpuRegister.A)
} }
in WordDatatypes -> { in WordDatatypes -> {
val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.AY, null, program, asmgen) val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.AY, null, program, asmgen)
val assign = AsmAssignment(target.origAssign.source, tgt, false, value.position) val assign = AsmAssignment(target.origAssign.source, tgt, false, asmgen.compTarget, value.position)
assignmentAsmGen.translateNormalAssignment(assign) assignmentAsmGen.translateNormalAssignment(assign)
assignmentAsmGen.assignRegisterpairWord(target, RegisterOrPair.AY) assignmentAsmGen.assignRegisterpairWord(target, RegisterOrPair.AY)
} }
DataType.FLOAT -> { DataType.FLOAT -> {
val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.FAC1, null, program, asmgen) val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.FAC1, null, program, asmgen)
val assign = AsmAssignment(target.origAssign.source, tgt, false, value.position) val assign = AsmAssignment(target.origAssign.source, tgt, false, asmgen.compTarget, value.position)
assignmentAsmGen.translateNormalAssignment(assign) assignmentAsmGen.translateNormalAssignment(assign)
assignmentAsmGen.assignFAC1float(target) assignmentAsmGen.assignFAC1float(target)
} }

View File

@ -10,7 +10,7 @@ import prog8.ast.walk.IAstModification
import prog8.compiler.target.ICompilationTarget import prog8.compiler.target.ICompilationTarget
internal class BinExprSplitter(private val program: Program) : AstWalker() { internal class BinExprSplitter(private val program: Program, private val compTarget: ICompilationTarget) : AstWalker() {
private val noModifications = emptyList<IAstModification>() private val noModifications = emptyList<IAstModification>()
// override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> { // override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
@ -80,7 +80,7 @@ X = BinExpr X = LeftExpr
private fun isSimpleTarget(target: AssignTarget, program: Program) = private fun isSimpleTarget(target: AssignTarget, program: Program) =
if (target.identifier!=null || target.memoryAddress!=null) if (target.identifier!=null || target.memoryAddress!=null)
ICompilationTarget.instance.isInRegularRAM(target, program) compTarget.isInRegularRAM(target, program)
else else
false false

View File

@ -13,7 +13,7 @@ import prog8.compiler.target.ICompilationTarget
import kotlin.math.pow import kotlin.math.pow
internal class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { internal class ConstantFoldingOptimizer(private val program: Program, private val compTarget: ICompilationTarget) : AstWalker() {
private val noModifications = emptyList<IAstModification>() private val noModifications = emptyList<IAstModification>()
override fun before(memread: DirectMemoryRead, parent: Node): Iterable<IAstModification> { override fun before(memread: DirectMemoryRead, parent: Node): Iterable<IAstModification> {
@ -224,7 +224,7 @@ internal class ConstantFoldingOptimizer(private val program: Program) : AstWalke
range.step range.step
} }
return RangeExpr(fromCast.valueOrZero(), toCast.valueOrZero(), newStep, ICompilationTarget.instance, range.position) return RangeExpr(fromCast.valueOrZero(), toCast.valueOrZero(), newStep, compTarget, range.position)
} }
// adjust the datatype of a range expression in for loops to the loop variable. // adjust the datatype of a range expression in for loops to the loop variable.

View File

@ -39,7 +39,7 @@ internal class VarConstantValueTypeAdjuster(private val program: Program, privat
// Replace all constant identifiers with their actual value, // Replace all constant identifiers with their actual value,
// and the array var initializer values and sizes. // and the array var initializer values and sizes.
// This is needed because further constant optimizations depend on those. // This is needed because further constant optimizations depend on those.
internal class ConstantIdentifierReplacer(private val program: Program, private val errors: ErrorReporter) : AstWalker() { internal class ConstantIdentifierReplacer(private val program: Program, private val errors: ErrorReporter, private val compTarget: ICompilationTarget) : AstWalker() {
private val noModifications = emptyList<IAstModification>() private val noModifications = emptyList<IAstModification>()
override fun after(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> { override fun after(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> {
@ -192,7 +192,7 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
if(rangeExpr==null && litval!=null) { if(rangeExpr==null && litval!=null) {
// arraysize initializer is a single int, and we know the size. // arraysize initializer is a single int, and we know the size.
val fillvalue = litval.number.toDouble() val fillvalue = litval.number.toDouble()
if (fillvalue < ICompilationTarget.instance.machine.FLOAT_MAX_NEGATIVE || fillvalue > ICompilationTarget.instance.machine.FLOAT_MAX_POSITIVE) if (fillvalue < compTarget.machine.FLOAT_MAX_NEGATIVE || fillvalue > compTarget.machine.FLOAT_MAX_POSITIVE)
errors.err("float value overflow", litval.position) errors.err("float value overflow", litval.position)
else { else {
// create the array itself, filled with the fillvalue. // create the array itself, filled with the fillvalue.

View File

@ -3,15 +3,16 @@ package prog8.optimizer
import prog8.ast.IBuiltinFunctions import prog8.ast.IBuiltinFunctions
import prog8.ast.Program import prog8.ast.Program
import prog8.compiler.ErrorReporter import prog8.compiler.ErrorReporter
import prog8.compiler.target.ICompilationTarget
internal fun Program.constantFold(errors: ErrorReporter) { internal fun Program.constantFold(errors: ErrorReporter, compTarget: ICompilationTarget) {
val valuetypefixer = VarConstantValueTypeAdjuster(this, errors) val valuetypefixer = VarConstantValueTypeAdjuster(this, errors)
valuetypefixer.visit(this) valuetypefixer.visit(this)
if(errors.isEmpty()) { if(errors.isEmpty()) {
valuetypefixer.applyModifications() valuetypefixer.applyModifications()
val replacer = ConstantIdentifierReplacer(this, errors) val replacer = ConstantIdentifierReplacer(this, errors, compTarget)
replacer.visit(this) replacer.visit(this)
if (errors.isEmpty()) { if (errors.isEmpty()) {
replacer.applyModifications() replacer.applyModifications()
@ -20,7 +21,7 @@ internal fun Program.constantFold(errors: ErrorReporter) {
if(errors.isEmpty()) { if(errors.isEmpty()) {
valuetypefixer.applyModifications() valuetypefixer.applyModifications()
val optimizer = ConstantFoldingOptimizer(this) val optimizer = ConstantFoldingOptimizer(this, compTarget)
optimizer.visit(this) optimizer.visit(this)
while (errors.isEmpty() && optimizer.applyModifications() > 0) { while (errors.isEmpty() && optimizer.applyModifications() > 0) {
optimizer.visit(this) optimizer.visit(this)
@ -39,8 +40,8 @@ internal fun Program.constantFold(errors: ErrorReporter) {
} }
internal fun Program.optimizeStatements(errors: ErrorReporter, functions: IBuiltinFunctions): Int { internal fun Program.optimizeStatements(errors: ErrorReporter, functions: IBuiltinFunctions, compTarget: ICompilationTarget): Int {
val optimizer = StatementOptimizer(this, errors, functions) val optimizer = StatementOptimizer(this, errors, functions, compTarget)
optimizer.visit(this) optimizer.visit(this)
val optimizationCount = optimizer.applyModifications() val optimizationCount = optimizer.applyModifications()
@ -55,8 +56,8 @@ internal fun Program.simplifyExpressions() : Int {
return opti.applyModifications() return opti.applyModifications()
} }
internal fun Program.splitBinaryExpressions() : Int { internal fun Program.splitBinaryExpressions(compTarget: ICompilationTarget) : Int {
val opti = BinExprSplitter(this) val opti = BinExprSplitter(this, compTarget)
opti.visit(this) opti.visit(this)
return opti.applyModifications() return opti.applyModifications()
} }

View File

@ -17,7 +17,8 @@ import kotlin.math.floor
internal class StatementOptimizer(private val program: Program, internal class StatementOptimizer(private val program: Program,
private val errors: ErrorReporter, private val errors: ErrorReporter,
private val functions: IBuiltinFunctions private val functions: IBuiltinFunctions,
private val compTarget: ICompilationTarget
) : AstWalker() { ) : AstWalker() {
private val noModifications = emptyList<IAstModification>() private val noModifications = emptyList<IAstModification>()
@ -96,7 +97,7 @@ internal class StatementOptimizer(private val program: Program,
if(string!=null) { if(string!=null) {
val pos = functionCallStatement.position val pos = functionCallStatement.position
if (string.value.length == 1) { if (string.value.length == 1) {
val firstCharEncoded = ICompilationTarget.instance.encodeString(string.value, string.altEncoding)[0] val firstCharEncoded = compTarget.encodeString(string.value, string.altEncoding)[0]
val chrout = FunctionCallStatement( val chrout = FunctionCallStatement(
IdentifierReference(listOf("txt", "chrout"), pos), IdentifierReference(listOf("txt", "chrout"), pos),
mutableListOf(NumericLiteralValue(DataType.UBYTE, firstCharEncoded.toInt(), pos)), mutableListOf(NumericLiteralValue(DataType.UBYTE, firstCharEncoded.toInt(), pos)),
@ -104,7 +105,7 @@ internal class StatementOptimizer(private val program: Program,
) )
return listOf(IAstModification.ReplaceNode(functionCallStatement, chrout, parent)) return listOf(IAstModification.ReplaceNode(functionCallStatement, chrout, parent))
} else if (string.value.length == 2) { } else if (string.value.length == 2) {
val firstTwoCharsEncoded = ICompilationTarget.instance.encodeString(string.value.take(2), string.altEncoding) val firstTwoCharsEncoded = compTarget.encodeString(string.value.take(2), string.altEncoding)
val chrout1 = FunctionCallStatement( val chrout1 = FunctionCallStatement(
IdentifierReference(listOf("txt", "chrout"), pos), IdentifierReference(listOf("txt", "chrout"), pos),
mutableListOf(NumericLiteralValue(DataType.UBYTE, firstTwoCharsEncoded[0].toInt(), pos)), mutableListOf(NumericLiteralValue(DataType.UBYTE, firstTwoCharsEncoded[0].toInt(), pos)),
@ -212,7 +213,7 @@ internal class StatementOptimizer(private val program: Program,
val size = sv.value.length val size = sv.value.length
if(size==1) { if(size==1) {
// loop over string of length 1 -> just assign the single character // loop over string of length 1 -> just assign the single character
val character = ICompilationTarget.instance.encodeString(sv.value, sv.altEncoding)[0] val character = compTarget.encodeString(sv.value, sv.altEncoding)[0]
val byte = NumericLiteralValue(DataType.UBYTE, character, iterable.position) val byte = NumericLiteralValue(DataType.UBYTE, character, iterable.position)
val scope = AnonymousScope(mutableListOf(), forLoop.position) val scope = AnonymousScope(mutableListOf(), forLoop.position)
scope.statements.add(Assignment(AssignTarget(forLoop.loopVar, null, null, forLoop.position), byte, forLoop.position)) scope.statements.add(Assignment(AssignTarget(forLoop.loopVar, null, null, forLoop.position), byte, forLoop.position))

View File

@ -14,7 +14,7 @@ import prog8.ast.walk.IAstModification
import prog8.compiler.target.ICompilationTarget import prog8.compiler.target.ICompilationTarget
internal class UnusedCodeRemover(private val program: Program, private val errors: ErrorReporter): AstWalker() { internal class UnusedCodeRemover(private val program: Program, private val errors: ErrorReporter, private val compTarget: ICompilationTarget): AstWalker() {
override fun before(program: Program, parent: Node): Iterable<IAstModification> { override fun before(program: Program, parent: Node): Iterable<IAstModification> {
val callgraph = CallGraph(program) val callgraph = CallGraph(program)
@ -96,7 +96,7 @@ internal class UnusedCodeRemover(private val program: Program, private val error
val assign1 = stmtPairs[0] as? Assignment val assign1 = stmtPairs[0] as? Assignment
val assign2 = stmtPairs[1] as? Assignment val assign2 = stmtPairs[1] as? Assignment
if (assign1 != null && assign2 != null && !assign2.isAugmentable) { if (assign1 != null && assign2 != null && !assign2.isAugmentable) {
if (assign1.target.isSameAs(assign2.target, program) && ICompilationTarget.instance.isInRegularRAM(assign1.target, program)) { if (assign1.target.isSameAs(assign2.target, program) && compTarget.isInRegularRAM(assign1.target, program)) {
if(assign2.target.identifier==null || !assign2.value.referencesIdentifier(*(assign2.target.identifier!!.nameInSource.toTypedArray()))) if(assign2.target.identifier==null || !assign2.value.referencesIdentifier(*(assign2.target.identifier!!.nameInSource.toTypedArray())))
// only remove the second assignment if its value is a simple expression! // only remove the second assignment if its value is a simple expression!
when(assign2.value) { when(assign2.value) {

Binary file not shown.

Binary file not shown.