mirror of
https://github.com/irmen/prog8.git
synced 2024-12-27 05:29:38 +00:00
reduce dependencies on global compilaiontarget
This commit is contained in:
parent
2412f8c531
commit
9bb5b454e4
@ -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)
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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>
|
||||||
|
@ -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
|
||||||
|
@ -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")
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
|
@ -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.
BIN
examples/cx16/vtui/VTUI0.4.BIN
Normal file
BIN
examples/cx16/vtui/VTUI0.4.BIN
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user