mirror of
				https://github.com/irmen/prog8.git
				synced 2025-11-04 10:16:13 +00:00 
			
		
		
		
	new common ICodeGeneratorBackend interface for all code generator classes
This commit is contained in:
		@@ -1,12 +0,0 @@
 | 
				
			|||||||
package prog8.code.core
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface IAssemblyGenerator {
 | 
					 | 
				
			||||||
    fun compileToAssembly(): IAssemblyProgram?
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface IAssemblyProgram {
 | 
					 | 
				
			||||||
    val name: String
 | 
					 | 
				
			||||||
    fun assemble(options: CompilationOptions): Boolean
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fun viceMonListName(baseFilename: String) = "$baseFilename.vice-mon-list"
 | 
					 | 
				
			||||||
							
								
								
									
										19
									
								
								codeCore/src/prog8/code/core/ICodeGeneratorBackend.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								codeCore/src/prog8/code/core/ICodeGeneratorBackend.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					package prog8.code.core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import prog8.code.SymbolTable
 | 
				
			||||||
 | 
					import prog8.code.ast.PtProgram
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ICodeGeneratorBackend {
 | 
				
			||||||
 | 
					    fun generate(program: PtProgram,
 | 
				
			||||||
 | 
					                 symbolTable: SymbolTable,
 | 
				
			||||||
 | 
					                 options: CompilationOptions,
 | 
				
			||||||
 | 
					                 errors: IErrorReporter): IAssemblyProgram?
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface IAssemblyProgram {
 | 
				
			||||||
 | 
					    val name: String
 | 
				
			||||||
 | 
					    fun assemble(options: CompilationOptions): Boolean
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun viceMonListName(baseFilename: String) = "$baseFilename.vice-mon-list"
 | 
				
			||||||
@@ -14,13 +14,24 @@ import kotlin.io.path.writeLines
 | 
				
			|||||||
internal const val subroutineFloatEvalResultVar1 = "prog8_float_eval_result1"
 | 
					internal const val subroutineFloatEvalResultVar1 = "prog8_float_eval_result1"
 | 
				
			||||||
internal const val subroutineFloatEvalResultVar2 = "prog8_float_eval_result2"
 | 
					internal const val subroutineFloatEvalResultVar2 = "prog8_float_eval_result2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AsmGen6502: ICodeGeneratorBackend {
 | 
				
			||||||
 | 
					    override fun generate(
 | 
				
			||||||
 | 
					        program: PtProgram,
 | 
				
			||||||
 | 
					        symbolTable: SymbolTable,
 | 
				
			||||||
 | 
					        options: CompilationOptions,
 | 
				
			||||||
 | 
					        errors: IErrorReporter
 | 
				
			||||||
 | 
					    ): IAssemblyProgram? {
 | 
				
			||||||
 | 
					        val asmgen = AsmGen6502Internal(program, symbolTable, options, errors)
 | 
				
			||||||
 | 
					        return asmgen.compileToAssembly()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AsmGen(
 | 
					class AsmGen6502Internal (
 | 
				
			||||||
    val program: PtProgram,
 | 
					    val program: PtProgram,
 | 
				
			||||||
    internal val symbolTable: SymbolTable,
 | 
					    internal val symbolTable: SymbolTable,
 | 
				
			||||||
    internal val options: CompilationOptions,
 | 
					    internal val options: CompilationOptions,
 | 
				
			||||||
    internal val errors: IErrorReporter
 | 
					    internal val errors: IErrorReporter
 | 
				
			||||||
): IAssemblyGenerator {
 | 
					) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    internal val optimizedByteMultiplications = setOf(3,5,6,7,9,10,11,12,13,14,15,20,25,40,50,80,100)
 | 
					    internal val optimizedByteMultiplications = setOf(3,5,6,7,9,10,11,12,13,14,15,20,25,40,50,80,100)
 | 
				
			||||||
    internal val optimizedWordMultiplications = setOf(3,5,6,7,9,10,12,15,20,25,40,50,80,100,320,640)
 | 
					    internal val optimizedWordMultiplications = setOf(3,5,6,7,9,10,12,15,20,25,40,50,80,100,320,640)
 | 
				
			||||||
@@ -37,7 +48,7 @@ class AsmGen(
 | 
				
			|||||||
    private val assignmentAsmGen = AssignmentAsmGen(program, this, allocator)
 | 
					    private val assignmentAsmGen = AssignmentAsmGen(program, this, allocator)
 | 
				
			||||||
    private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen)
 | 
					    private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun compileToAssembly(): IAssemblyProgram? {
 | 
					    fun compileToAssembly(): IAssemblyProgram? {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assemblyLines.clear()
 | 
					        assemblyLines.clear()
 | 
				
			||||||
        loopEndLabels.clear()
 | 
					        loopEndLabels.clear()
 | 
				
			||||||
@@ -1076,7 +1087,7 @@ $repeatLabel    lda  $counterVar
 | 
				
			|||||||
        return false
 | 
					        return false
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    internal fun findSubroutineParameter(name: String, asmgen: AsmGen): PtSubroutineParameter? {
 | 
					    internal fun findSubroutineParameter(name: String, asmgen: AsmGen6502Internal): PtSubroutineParameter? {
 | 
				
			||||||
        val node = asmgen.symbolTable.lookup(name)!!.astNode
 | 
					        val node = asmgen.symbolTable.lookup(name)!!.astNode
 | 
				
			||||||
        if(node is PtSubroutineParameter)
 | 
					        if(node is PtSubroutineParameter)
 | 
				
			||||||
            return node
 | 
					            return node
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ import prog8.codegen.cpu6502.assignment.*
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
 | 
					internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
 | 
				
			||||||
                                      private val asmgen: AsmGen,
 | 
					                                      private val asmgen: AsmGen6502Internal,
 | 
				
			||||||
                                      private val assignAsmGen: AssignmentAsmGen) {
 | 
					                                      private val assignAsmGen: AssignmentAsmGen) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    internal fun translateFunctioncallExpression(fcall: PtBuiltinFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?): DataType? {
 | 
					    internal fun translateFunctioncallExpression(fcall: PtBuiltinFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?): DataType? {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@ import prog8.code.core.*
 | 
				
			|||||||
import kotlin.math.absoluteValue
 | 
					import kotlin.math.absoluteValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal class ExpressionsAsmGen(private val program: PtProgram,
 | 
					internal class ExpressionsAsmGen(private val program: PtProgram,
 | 
				
			||||||
                                 private val asmgen: AsmGen,
 | 
					                                 private val asmgen: AsmGen6502Internal,
 | 
				
			||||||
                                 private val allocator: VariableAllocator) {
 | 
					                                 private val allocator: VariableAllocator) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Deprecated("avoid calling this as it generates slow evalstack based code")
 | 
					    @Deprecated("avoid calling this as it generates slow evalstack based code")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ import prog8.code.core.*
 | 
				
			|||||||
import kotlin.math.absoluteValue
 | 
					import kotlin.math.absoluteValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal class ForLoopsAsmGen(private val program: PtProgram,
 | 
					internal class ForLoopsAsmGen(private val program: PtProgram,
 | 
				
			||||||
                              private val asmgen: AsmGen,
 | 
					                              private val asmgen: AsmGen6502Internal,
 | 
				
			||||||
                              private val zeropage: Zeropage) {
 | 
					                              private val zeropage: Zeropage) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    internal fun translate(stmt: PtForLoop) {
 | 
					    internal fun translate(stmt: PtForLoop) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@ import prog8.codegen.cpu6502.assignment.AsmAssignment
 | 
				
			|||||||
import prog8.codegen.cpu6502.assignment.TargetStorageKind
 | 
					import prog8.codegen.cpu6502.assignment.TargetStorageKind
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal class FunctionCallAsmGen(private val program: PtProgram, private val asmgen: AsmGen) {
 | 
					internal class FunctionCallAsmGen(private val program: PtProgram, private val asmgen: AsmGen6502Internal) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    internal fun translateFunctionCallStatement(stmt: PtFunctionCall) {
 | 
					    internal fun translateFunctionCallStatement(stmt: PtFunctionCall) {
 | 
				
			||||||
        saveXbeforeCall(stmt)
 | 
					        saveXbeforeCall(stmt)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ import prog8.code.ast.PtProgram
 | 
				
			|||||||
import prog8.code.core.*
 | 
					import prog8.code.core.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal class PostIncrDecrAsmGen(private val program: PtProgram, private val asmgen: AsmGen) {
 | 
					internal class PostIncrDecrAsmGen(private val program: PtProgram, private val asmgen: AsmGen6502Internal) {
 | 
				
			||||||
    internal fun translate(stmt: PtPostIncrDecr) {
 | 
					    internal fun translate(stmt: PtPostIncrDecr) {
 | 
				
			||||||
        val incr = stmt.operator=="++"
 | 
					        val incr = stmt.operator=="++"
 | 
				
			||||||
        val targetIdent = stmt.target.identifier
 | 
					        val targetIdent = stmt.target.identifier
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,7 @@ internal class ProgramAndVarsGen(
 | 
				
			|||||||
    val errors: IErrorReporter,
 | 
					    val errors: IErrorReporter,
 | 
				
			||||||
    private val symboltable: SymbolTable,
 | 
					    private val symboltable: SymbolTable,
 | 
				
			||||||
    private val functioncallAsmGen: FunctionCallAsmGen,
 | 
					    private val functioncallAsmGen: FunctionCallAsmGen,
 | 
				
			||||||
    private val asmgen: AsmGen,
 | 
					    private val asmgen: AsmGen6502Internal,
 | 
				
			||||||
    private val allocator: VariableAllocator,
 | 
					    private val allocator: VariableAllocator,
 | 
				
			||||||
    private val zeropage: Zeropage
 | 
					    private val zeropage: Zeropage
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ package prog8.codegen.cpu6502.assignment
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import prog8.code.ast.*
 | 
					import prog8.code.ast.*
 | 
				
			||||||
import prog8.code.core.*
 | 
					import prog8.code.core.*
 | 
				
			||||||
import prog8.codegen.cpu6502.AsmGen
 | 
					import prog8.codegen.cpu6502.AsmGen6502Internal
 | 
				
			||||||
import prog8.codegen.cpu6502.asConstInteger
 | 
					import prog8.codegen.cpu6502.asConstInteger
 | 
				
			||||||
import prog8.codegen.cpu6502.returnsWhatWhere
 | 
					import prog8.codegen.cpu6502.returnsWhatWhere
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,7 +26,7 @@ internal enum class SourceStorageKind {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal class AsmAssignTarget(val kind: TargetStorageKind,
 | 
					internal class AsmAssignTarget(val kind: TargetStorageKind,
 | 
				
			||||||
                               private val asmgen: AsmGen,
 | 
					                               private val asmgen: AsmGen6502Internal,
 | 
				
			||||||
                               val datatype: DataType,
 | 
					                               val datatype: DataType,
 | 
				
			||||||
                               val scope: IPtSubroutine?,
 | 
					                               val scope: IPtSubroutine?,
 | 
				
			||||||
                               private val variableAsmName: String? = null,
 | 
					                               private val variableAsmName: String? = null,
 | 
				
			||||||
@@ -52,7 +52,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    companion object {
 | 
					    companion object {
 | 
				
			||||||
        fun fromAstAssignment(assign: PtAssignment, asmgen: AsmGen): AsmAssignTarget {
 | 
					        fun fromAstAssignment(assign: PtAssignment, asmgen: AsmGen6502Internal): AsmAssignTarget {
 | 
				
			||||||
            with(assign.target) {
 | 
					            with(assign.target) {
 | 
				
			||||||
                when {
 | 
					                when {
 | 
				
			||||||
                    identifier != null -> {
 | 
					                    identifier != null -> {
 | 
				
			||||||
@@ -76,7 +76,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fun fromRegisters(registers: RegisterOrPair, signed: Boolean, scope: IPtSubroutine?, asmgen: AsmGen): AsmAssignTarget =
 | 
					        fun fromRegisters(registers: RegisterOrPair, signed: Boolean, scope: IPtSubroutine?, asmgen: AsmGen6502Internal): AsmAssignTarget =
 | 
				
			||||||
                when(registers) {
 | 
					                when(registers) {
 | 
				
			||||||
                    RegisterOrPair.A,
 | 
					                    RegisterOrPair.A,
 | 
				
			||||||
                    RegisterOrPair.X,
 | 
					                    RegisterOrPair.X,
 | 
				
			||||||
@@ -108,7 +108,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
internal class AsmAssignSource(val kind: SourceStorageKind,
 | 
					internal class AsmAssignSource(val kind: SourceStorageKind,
 | 
				
			||||||
                               private val program: PtProgram,
 | 
					                               private val program: PtProgram,
 | 
				
			||||||
                               private val asmgen: AsmGen,
 | 
					                               private val asmgen: AsmGen6502Internal,
 | 
				
			||||||
                               val datatype: DataType,
 | 
					                               val datatype: DataType,
 | 
				
			||||||
                               private val variableAsmName: String? = null,
 | 
					                               private val variableAsmName: String? = null,
 | 
				
			||||||
                               val array: PtArrayIndexer? = null,
 | 
					                               val array: PtArrayIndexer? = null,
 | 
				
			||||||
@@ -125,7 +125,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
 | 
				
			|||||||
            asmgen.asmVariableName(array.variable)
 | 
					            asmgen.asmVariableName(array.variable)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    companion object {
 | 
					    companion object {
 | 
				
			||||||
        fun fromAstSource(value: PtExpression, program: PtProgram, asmgen: AsmGen): AsmAssignSource {
 | 
					        fun fromAstSource(value: PtExpression, program: PtProgram, asmgen: AsmGen6502Internal): AsmAssignSource {
 | 
				
			||||||
            val cv = value as? PtNumber
 | 
					            val cv = value as? PtNumber
 | 
				
			||||||
            if(cv!=null)
 | 
					            if(cv!=null)
 | 
				
			||||||
                return AsmAssignSource(SourceStorageKind.LITERALNUMBER, program, asmgen, cv.type, number = cv)
 | 
					                return AsmAssignSource(SourceStorageKind.LITERALNUMBER, program, asmgen, cv.type, number = cv)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ import prog8.codegen.cpu6502.*
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal class AssignmentAsmGen(private val program: PtProgram,
 | 
					internal class AssignmentAsmGen(private val program: PtProgram,
 | 
				
			||||||
                                private val asmgen: AsmGen, 
 | 
					                                private val asmgen: AsmGen6502Internal,
 | 
				
			||||||
                                private val allocator: VariableAllocator) {
 | 
					                                private val allocator: VariableAllocator) {
 | 
				
			||||||
    private val augmentableAsmGen = AugmentableAssignmentAsmGen(program, this, asmgen, allocator)
 | 
					    private val augmentableAsmGen = AugmentableAssignmentAsmGen(program, this, asmgen, allocator)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,13 +2,13 @@ package prog8.codegen.cpu6502.assignment
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import prog8.code.ast.*
 | 
					import prog8.code.ast.*
 | 
				
			||||||
import prog8.code.core.*
 | 
					import prog8.code.core.*
 | 
				
			||||||
import prog8.codegen.cpu6502.AsmGen
 | 
					import prog8.codegen.cpu6502.AsmGen6502Internal
 | 
				
			||||||
import prog8.codegen.cpu6502.VariableAllocator
 | 
					import prog8.codegen.cpu6502.VariableAllocator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
 | 
					internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
 | 
				
			||||||
                                           private val assignmentAsmGen: AssignmentAsmGen,
 | 
					                                           private val assignmentAsmGen: AssignmentAsmGen,
 | 
				
			||||||
                                           private val asmgen: AsmGen,
 | 
					                                           private val asmgen: AsmGen6502Internal,
 | 
				
			||||||
                                           private val allocator: VariableAllocator
 | 
					                                           private val allocator: VariableAllocator
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    fun translate(assign: AsmAssignment) {
 | 
					    fun translate(assign: AsmAssignment) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,19 +3,19 @@ package prog8.codegen.experimental
 | 
				
			|||||||
import prog8.code.SymbolTable
 | 
					import prog8.code.SymbolTable
 | 
				
			||||||
import prog8.code.ast.PtProgram
 | 
					import prog8.code.ast.PtProgram
 | 
				
			||||||
import prog8.code.core.CompilationOptions
 | 
					import prog8.code.core.CompilationOptions
 | 
				
			||||||
import prog8.code.core.IAssemblyGenerator
 | 
					 | 
				
			||||||
import prog8.code.core.IAssemblyProgram
 | 
					import prog8.code.core.IAssemblyProgram
 | 
				
			||||||
 | 
					import prog8.code.core.ICodeGeneratorBackend
 | 
				
			||||||
import prog8.code.core.IErrorReporter
 | 
					import prog8.code.core.IErrorReporter
 | 
				
			||||||
import prog8.codegen.intermediate.IRCodeGen
 | 
					import prog8.codegen.intermediate.IRCodeGen
 | 
				
			||||||
import prog8.intermediate.IRFileWriter
 | 
					import prog8.intermediate.IRFileWriter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CodeGen(private val program: PtProgram,
 | 
					class ExperiCodeGen: ICodeGeneratorBackend {
 | 
				
			||||||
              private val symbolTable: SymbolTable,
 | 
					    override fun generate(
 | 
				
			||||||
              private val options: CompilationOptions,
 | 
					        program: PtProgram,
 | 
				
			||||||
              private val errors: IErrorReporter
 | 
					        symbolTable: SymbolTable,
 | 
				
			||||||
): IAssemblyGenerator {
 | 
					        options: CompilationOptions,
 | 
				
			||||||
    override fun compileToAssembly(): IAssemblyProgram? {
 | 
					        errors: IErrorReporter
 | 
				
			||||||
 | 
					    ): IAssemblyProgram? {
 | 
				
			||||||
        // you could write a code generator directly on the PtProgram AST,
 | 
					        // you could write a code generator directly on the PtProgram AST,
 | 
				
			||||||
        // but you can also use the Intermediate Representation to build a codegen on:
 | 
					        // but you can also use the Intermediate Representation to build a codegen on:
 | 
				
			||||||
        val irCodeGen = IRCodeGen(program, symbolTable, options, errors)
 | 
					        val irCodeGen = IRCodeGen(program, symbolTable, options, errors)
 | 
				
			||||||
@@ -3,23 +3,22 @@ package prog8.codegen.vm
 | 
				
			|||||||
import prog8.code.SymbolTable
 | 
					import prog8.code.SymbolTable
 | 
				
			||||||
import prog8.code.ast.PtProgram
 | 
					import prog8.code.ast.PtProgram
 | 
				
			||||||
import prog8.code.core.CompilationOptions
 | 
					import prog8.code.core.CompilationOptions
 | 
				
			||||||
import prog8.code.core.IAssemblyGenerator
 | 
					 | 
				
			||||||
import prog8.code.core.IAssemblyProgram
 | 
					import prog8.code.core.IAssemblyProgram
 | 
				
			||||||
 | 
					import prog8.code.core.ICodeGeneratorBackend
 | 
				
			||||||
import prog8.code.core.IErrorReporter
 | 
					import prog8.code.core.IErrorReporter
 | 
				
			||||||
import prog8.codegen.intermediate.IRCodeGen
 | 
					import prog8.codegen.intermediate.IRCodeGen
 | 
				
			||||||
import prog8.intermediate.IRFileWriter
 | 
					import prog8.intermediate.IRFileWriter
 | 
				
			||||||
import prog8.intermediate.IRProgram
 | 
					import prog8.intermediate.IRProgram
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VmCodeGen(private val program: PtProgram,
 | 
					class VmCodeGen: ICodeGeneratorBackend {
 | 
				
			||||||
                private val symbolTable: SymbolTable,
 | 
					    override fun generate(
 | 
				
			||||||
                private val options: CompilationOptions,
 | 
					        program: PtProgram,
 | 
				
			||||||
                private val errors: IErrorReporter
 | 
					        symbolTable: SymbolTable,
 | 
				
			||||||
): IAssemblyGenerator {
 | 
					        options: CompilationOptions,
 | 
				
			||||||
    override fun compileToAssembly(): IAssemblyProgram? {
 | 
					        errors: IErrorReporter
 | 
				
			||||||
 | 
					    ): IAssemblyProgram? {
 | 
				
			||||||
        val irCodeGen = IRCodeGen(program, symbolTable, options, errors)
 | 
					        val irCodeGen = IRCodeGen(program, symbolTable, options, errors)
 | 
				
			||||||
        val irProgram = irCodeGen.generate()
 | 
					        val irProgram = irCodeGen.generate()
 | 
				
			||||||
 | 
					 | 
				
			||||||
        return VmAssemblyProgram(irProgram.name, irProgram)
 | 
					        return VmAssemblyProgram(irProgram.name, irProgram)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -400,7 +400,19 @@ private fun createAssemblyAndAssemble(program: PtProgram,
 | 
				
			|||||||
                                      errors: IErrorReporter,
 | 
					                                      errors: IErrorReporter,
 | 
				
			||||||
                                      compilerOptions: CompilationOptions
 | 
					                                      compilerOptions: CompilationOptions
 | 
				
			||||||
): Boolean {
 | 
					): Boolean {
 | 
				
			||||||
    val assembly = asmGeneratorFor(program, compilerOptions, errors).compileToAssembly()
 | 
					
 | 
				
			||||||
 | 
					    val asmgen = if(compilerOptions.experimentalCodegen)
 | 
				
			||||||
 | 
					        prog8.codegen.experimental.ExperiCodeGen()
 | 
				
			||||||
 | 
					    else if (compilerOptions.compTarget.machine.cpu in arrayOf(CpuType.CPU6502, CpuType.CPU65c02))
 | 
				
			||||||
 | 
					        prog8.codegen.cpu6502.AsmGen6502()
 | 
				
			||||||
 | 
					    else if (compilerOptions.compTarget.name == VMTarget.NAME)
 | 
				
			||||||
 | 
					        VmCodeGen()
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        throw NotImplementedError("no asm generator for cpu ${compilerOptions.compTarget.machine.cpu}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val stMaker = SymbolTableMaker(program, compilerOptions)
 | 
				
			||||||
 | 
					    val symbolTable = stMaker.make()
 | 
				
			||||||
 | 
					    val assembly = asmgen.generate(program, symbolTable, compilerOptions, errors)
 | 
				
			||||||
    errors.report()
 | 
					    errors.report()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return if(assembly!=null && errors.noErrors()) {
 | 
					    return if(assembly!=null && errors.noErrors()) {
 | 
				
			||||||
@@ -409,20 +421,3 @@ private fun createAssemblyAndAssemble(program: PtProgram,
 | 
				
			|||||||
        false
 | 
					        false
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
internal fun asmGeneratorFor(program: PtProgram,
 | 
					 | 
				
			||||||
                             options: CompilationOptions,
 | 
					 | 
				
			||||||
                             errors: IErrorReporter): IAssemblyGenerator
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    val stMaker = SymbolTableMaker(program, options)
 | 
					 | 
				
			||||||
    val symbolTable = stMaker.make()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return if(options.experimentalCodegen)
 | 
					 | 
				
			||||||
        prog8.codegen.experimental.CodeGen(program, symbolTable, options, errors)
 | 
					 | 
				
			||||||
    else if (options.compTarget.machine.cpu in arrayOf(CpuType.CPU6502, CpuType.CPU65c02))
 | 
					 | 
				
			||||||
        prog8.codegen.cpu6502.AsmGen(program, symbolTable, options, errors)
 | 
					 | 
				
			||||||
    else if (options.compTarget.name == VMTarget.NAME)
 | 
					 | 
				
			||||||
        VmCodeGen(program, symbolTable, options, errors)
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        throw NotImplementedError("no asm generator for cpu ${options.compTarget.machine.cpu}")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ import prog8.code.ast.PtProgram
 | 
				
			|||||||
import prog8.code.core.*
 | 
					import prog8.code.core.*
 | 
				
			||||||
import prog8.code.target.C64Target
 | 
					import prog8.code.target.C64Target
 | 
				
			||||||
import prog8.code.target.VMTarget
 | 
					import prog8.code.target.VMTarget
 | 
				
			||||||
import prog8.codegen.cpu6502.AsmGen
 | 
					import prog8.codegen.cpu6502.AsmGen6502Internal
 | 
				
			||||||
import prog8.compiler.astprocessing.IntermediateAstMaker
 | 
					import prog8.compiler.astprocessing.IntermediateAstMaker
 | 
				
			||||||
import prog8tests.helpers.*
 | 
					import prog8tests.helpers.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -72,17 +72,17 @@ class TestAsmGenSymbols: StringSpec({
 | 
				
			|||||||
        return program
 | 
					        return program
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun createTestAsmGen(program: Program): AsmGen {
 | 
					    fun createTestAsmGen6502(program: Program): AsmGen6502Internal {
 | 
				
			||||||
        val errors = ErrorReporterForTests()
 | 
					        val errors = ErrorReporterForTests()
 | 
				
			||||||
        val options = CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, true, C64Target(), 999u)
 | 
					        val options = CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, true, C64Target(), 999u)
 | 
				
			||||||
        val ptProgram = IntermediateAstMaker(program, options).transform()
 | 
					        val ptProgram = IntermediateAstMaker(program, options).transform()
 | 
				
			||||||
        val st = SymbolTableMaker(ptProgram, options).make()
 | 
					        val st = SymbolTableMaker(ptProgram, options).make()
 | 
				
			||||||
        return AsmGen(ptProgram, st, options, errors)
 | 
					        return AsmGen6502Internal(ptProgram, st, options, errors)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    "symbol and variable names from strings" {
 | 
					    "symbol and variable names from strings" {
 | 
				
			||||||
        val program = createTestProgram()
 | 
					        val program = createTestProgram()
 | 
				
			||||||
        val asmgen = createTestAsmGen(program)
 | 
					        val asmgen = createTestAsmGen6502(program)
 | 
				
			||||||
        asmgen.asmSymbolName("name") shouldBe "name"
 | 
					        asmgen.asmSymbolName("name") shouldBe "name"
 | 
				
			||||||
        asmgen.asmSymbolName("name") shouldBe "name"
 | 
					        asmgen.asmSymbolName("name") shouldBe "name"
 | 
				
			||||||
        asmgen.asmSymbolName("<name>") shouldBe "prog8_name"
 | 
					        asmgen.asmSymbolName("<name>") shouldBe "prog8_name"
 | 
				
			||||||
@@ -95,7 +95,7 @@ class TestAsmGenSymbols: StringSpec({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    "symbol and variable names from variable identifiers" {
 | 
					    "symbol and variable names from variable identifiers" {
 | 
				
			||||||
        val program = createTestProgram()
 | 
					        val program = createTestProgram()
 | 
				
			||||||
        val asmgen = createTestAsmGen(program)
 | 
					        val asmgen = createTestAsmGen6502(program)
 | 
				
			||||||
        val sub = asmgen.program.entrypoint()!!
 | 
					        val sub = asmgen.program.entrypoint()!!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val localvarIdent = sub.children.asSequence().filterIsInstance<PtAssignment>().first { it.value is PtIdentifier }.value as PtIdentifier
 | 
					        val localvarIdent = sub.children.asSequence().filterIsInstance<PtAssignment>().first { it.value is PtIdentifier }.value as PtIdentifier
 | 
				
			||||||
@@ -115,7 +115,7 @@ class TestAsmGenSymbols: StringSpec({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    "symbol and variable names from label identifiers" {
 | 
					    "symbol and variable names from label identifiers" {
 | 
				
			||||||
        val program = createTestProgram()
 | 
					        val program = createTestProgram()
 | 
				
			||||||
        val asmgen = createTestAsmGen(program)
 | 
					        val asmgen = createTestAsmGen6502(program)
 | 
				
			||||||
        val sub = asmgen.program.entrypoint()!!
 | 
					        val sub = asmgen.program.entrypoint()!!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val localLabelIdent = (sub.children.asSequence().filterIsInstance<PtAssignment>().first { (it.value as? PtAddressOf)?.identifier?.name=="main.start.locallabel" }.value as PtAddressOf).identifier
 | 
					        val localLabelIdent = (sub.children.asSequence().filterIsInstance<PtAssignment>().first { (it.value as? PtAddressOf)?.identifier?.name=="main.start.locallabel" }.value as PtAddressOf).identifier
 | 
				
			||||||
@@ -144,7 +144,7 @@ main {
 | 
				
			|||||||
        prog8_lib.P8ZP_SCRATCH_W2 = 1
 | 
					        prog8_lib.P8ZP_SCRATCH_W2 = 1
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        val program = createTestProgram()
 | 
					        val program = createTestProgram()
 | 
				
			||||||
        val asmgen = createTestAsmGen(program)
 | 
					        val asmgen = createTestAsmGen6502(program)
 | 
				
			||||||
        asmgen.asmSymbolName("prog8_lib.P8ZP_SCRATCH_REG") shouldBe "P8ZP_SCRATCH_REG"
 | 
					        asmgen.asmSymbolName("prog8_lib.P8ZP_SCRATCH_REG") shouldBe "P8ZP_SCRATCH_REG"
 | 
				
			||||||
        asmgen.asmSymbolName("prog8_lib.P8ZP_SCRATCH_W2") shouldBe "P8ZP_SCRATCH_W2"
 | 
					        asmgen.asmSymbolName("prog8_lib.P8ZP_SCRATCH_W2") shouldBe "P8ZP_SCRATCH_W2"
 | 
				
			||||||
        asmgen.asmSymbolName(listOf("prog8_lib","P8ZP_SCRATCH_REG")) shouldBe "P8ZP_SCRATCH_REG"
 | 
					        asmgen.asmSymbolName(listOf("prog8_lib","P8ZP_SCRATCH_REG")) shouldBe "P8ZP_SCRATCH_REG"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user