diff --git a/.idea/modules.xml b/.idea/modules.xml index 634d0b23e..68b9739cd 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,7 @@ + diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen6502.kt similarity index 99% rename from codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt rename to codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen6502.kt index b146fe260..8403ea3ef 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen6502.kt @@ -24,17 +24,17 @@ const val subroutineFloatEvalResultVar1 = "prog8_float_eval_result1" const val subroutineFloatEvalResultVar2 = "prog8_float_eval_result2" -class AsmGen(private val program: Program, - val errors: IErrorReporter, - val zeropage: Zeropage, - val options: CompilationOptions, - private val compTarget: ICompilationTarget, - private val outputDir: Path): IAssemblyGenerator { +class AsmGen6502(internal val program: Program, + internal val errors: IErrorReporter, + internal val options: CompilationOptions, + internal val outputDir: Path): IAssemblyGenerator { // for expressions and augmented assignments: val optimizedByteMultiplications = setOf(3,5,6,7,9,10,11,12,13,14,15,20,25,40,50,80,100) val optimizedWordMultiplications = setOf(3,5,6,7,9,10,12,15,20,25,40,50,80,100,320,640) private val callGraph = CallGraph(program) + private val compTarget = options.compTarget + internal val zeropage = compTarget.machine.zeropage private val assemblyLines = mutableListOf() private val globalFloatConsts = mutableMapOf() // all float values in the entire program (value -> varname) @@ -50,7 +50,7 @@ class AsmGen(private val program: Program, internal val removals = mutableListOf>() private val blockVariableInitializers = program.allBlocks.associateWith { it.statements.filterIsInstance() } - override fun compileToAssembly(): IAssemblyProgram { + override fun compileToAssembly(): IAssemblyProgram? { assemblyLines.clear() loopEndLabels.clear() @@ -90,10 +90,10 @@ class AsmGen(private val program: Program, } return if(errors.noErrors()) - AssemblyProgram(true, program.name, outputDir, compTarget.name) + AssemblyProgram(program.name, outputDir, compTarget.name) else { errors.report() - AssemblyProgram(false, "", outputDir, compTarget.name) + return null } } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AssemblyProgram.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AssemblyProgram.kt index 1b6b84195..8398c63f7 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AssemblyProgram.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AssemblyProgram.kt @@ -15,7 +15,6 @@ import kotlin.io.path.isRegularFile class AssemblyProgram( - override val valid: Boolean, override val name: String, outputDir: Path, private val compTarget: String) : IAssemblyProgram { @@ -26,7 +25,7 @@ class AssemblyProgram( private val viceMonListFile = outputDir.resolve(viceMonListName(name)) private val listFile = outputDir.resolve("$name.list") - override fun assemble(options: CompilationOptions): Int { + override fun assemble(options: CompilationOptions): Boolean { // add "-Wlong-branch" to see warnings about conversion of branch instructions to jumps (default = do this silently) val command = mutableListOf("64tass", "--ascii", "--case-sensitive", "--long-branch", "-Wall", "-Wno-strict-bool", "-Wno-shadow", // "-Werror", @@ -59,7 +58,7 @@ class AssemblyProgram( removeGeneratedLabelsFromMonlist() generateBreakpointList() } - return result + return result==0 } private fun removeGeneratedLabelsFromMonlist() { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index 33946d83e..0ab79ab98 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -17,7 +17,7 @@ import prog8.compilerinterface.CpuType import prog8.compilerinterface.FSignature -internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen: AsmGen, private val assignAsmGen: AssignmentAsmGen) { +internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen: AsmGen6502, private val assignAsmGen: AssignmentAsmGen) { internal fun translateFunctioncallExpression(fcall: FunctionCallExpression, func: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?) { translateFunctioncall(fcall, func, discardResult = false, resultToStack = resultToStack, resultRegister = resultRegister) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt index 3473feae1..a787d9b51 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt @@ -11,7 +11,7 @@ import prog8.compilerinterface.BuiltinFunctions import prog8.compilerinterface.CpuType import kotlin.math.absoluteValue -internal class ExpressionsAsmGen(private val program: Program, private val asmgen: AsmGen, private val functioncallAsmGen: FunctionCallAsmGen) { +internal class ExpressionsAsmGen(private val program: Program, private val asmgen: AsmGen6502, private val functioncallAsmGen: FunctionCallAsmGen) { @Deprecated("avoid calling this as it generates slow evalstack based code") internal fun translateExpression(expression:Expression) { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ForLoopsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ForLoopsAsmGen.kt index 2dcff3e45..4a5be3787 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ForLoopsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ForLoopsAsmGen.kt @@ -12,7 +12,7 @@ import prog8.ast.toHex import prog8.compilerinterface.AssemblyError import kotlin.math.absoluteValue -internal class ForLoopsAsmGen(private val program: Program, private val asmgen: AsmGen) { +internal class ForLoopsAsmGen(private val program: Program, private val asmgen: AsmGen6502) { internal fun translate(stmt: ForLoop) { val iterableDt = stmt.iterable.inferType(program) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt index 5db14a623..b365bbb8c 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt @@ -17,7 +17,7 @@ import prog8.compilerinterface.AssemblyError import prog8.compilerinterface.CpuType -internal class FunctionCallAsmGen(private val program: Program, private val asmgen: AsmGen) { +internal class FunctionCallAsmGen(private val program: Program, private val asmgen: AsmGen6502) { internal fun translateFunctionCallStatement(stmt: IFunctionCall) { saveXbeforeCall(stmt) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/PostIncrDecrAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/PostIncrDecrAsmGen.kt index d5615db23..7d0bfda01 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/PostIncrDecrAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/PostIncrDecrAsmGen.kt @@ -9,7 +9,7 @@ import prog8.ast.toHex import prog8.compilerinterface.AssemblyError -internal class PostIncrDecrAsmGen(private val program: Program, private val asmgen: AsmGen) { +internal class PostIncrDecrAsmGen(private val program: Program, private val asmgen: AsmGen6502) { internal fun translate(stmt: PostIncrDecr) { val incr = stmt.operator=="++" val targetIdent = stmt.target.identifier diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt index e5f4a2045..00698f8c4 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt @@ -4,7 +4,7 @@ import prog8.ast.Program import prog8.ast.base.* import prog8.ast.expressions.* import prog8.ast.statements.* -import prog8.codegen.cpu6502.AsmGen +import prog8.codegen.cpu6502.AsmGen6502 import prog8.compilerinterface.AssemblyError import prog8.compilerinterface.IMemSizer @@ -29,7 +29,7 @@ internal enum class SourceStorageKind { internal class AsmAssignTarget(val kind: TargetStorageKind, private val program: Program, - private val asmgen: AsmGen, + private val asmgen: AsmGen6502, val datatype: DataType, val scope: Subroutine?, private val variableAsmName: String? = null, @@ -56,7 +56,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind, } companion object { - fun fromAstAssignment(assign: Assignment, program: Program, asmgen: AsmGen): AsmAssignTarget { + fun fromAstAssignment(assign: Assignment, program: Program, asmgen: AsmGen6502): AsmAssignTarget { with(assign.target) { val idt = inferType(program) val dt = idt.getOrElse { throw AssemblyError("unknown dt") } @@ -82,7 +82,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind, } } - fun fromRegisters(registers: RegisterOrPair, signed: Boolean, scope: Subroutine?, program: Program, asmgen: AsmGen): AsmAssignTarget = + fun fromRegisters(registers: RegisterOrPair, signed: Boolean, scope: Subroutine?, program: Program, asmgen: AsmGen6502): AsmAssignTarget = when(registers) { RegisterOrPair.A, RegisterOrPair.X, @@ -114,7 +114,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind, internal class AsmAssignSource(val kind: SourceStorageKind, private val program: Program, - private val asmgen: AsmGen, + private val asmgen: AsmGen6502, val datatype: DataType, private val variableAsmName: String? = null, val array: ArrayIndexedExpression? = null, @@ -134,9 +134,9 @@ internal class AsmAssignSource(val kind: SourceStorageKind, asmgen.asmVariableName(array.arrayvar) companion object { - fun fromAstSource(indexer: ArrayIndex, program: Program, asmgen: AsmGen): AsmAssignSource = fromAstSource(indexer.indexExpr, program, asmgen) + fun fromAstSource(indexer: ArrayIndex, program: Program, asmgen: AsmGen6502): AsmAssignSource = fromAstSource(indexer.indexExpr, program, asmgen) - fun fromAstSource(value: Expression, program: Program, asmgen: AsmGen): AsmAssignSource { + fun fromAstSource(value: Expression, program: Program, asmgen: AsmGen6502): AsmAssignSource { val cv = value.constValue(program) if(cv!=null) return AsmAssignSource(SourceStorageKind.LITERALNUMBER, program, asmgen, cv.type, number = cv) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 7f40e1364..8fbaa604f 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -5,14 +5,14 @@ import prog8.ast.base.* import prog8.ast.expressions.* import prog8.ast.statements.* import prog8.ast.toHex -import prog8.codegen.cpu6502.AsmGen +import prog8.codegen.cpu6502.AsmGen6502 import prog8.compilerinterface.AssemblyError import prog8.compilerinterface.BuiltinFunctions import prog8.compilerinterface.CpuType import prog8.compilerinterface.builtinFunctionReturnType -internal class AssignmentAsmGen(private val program: Program, private val asmgen: AsmGen) { +internal class AssignmentAsmGen(private val program: Program, private val asmgen: AsmGen6502) { private val augmentableAsmGen = AugmentableAssignmentAsmGen(program, this, asmgen) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt index faba060a4..6525911b1 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt @@ -5,14 +5,14 @@ import prog8.ast.base.* import prog8.ast.expressions.* import prog8.ast.statements.Subroutine import prog8.ast.toHex -import prog8.codegen.cpu6502.AsmGen +import prog8.codegen.cpu6502.AsmGen6502 import prog8.compilerinterface.AssemblyError import prog8.compilerinterface.CpuType internal class AugmentableAssignmentAsmGen(private val program: Program, private val assignmentAsmGen: AssignmentAsmGen, - private val asmgen: AsmGen + private val asmgen: AsmGen6502 ) { fun translate(assign: AsmAssignment) { require(assign.isAugmentable) diff --git a/codeGenExperimental6502/build.gradle b/codeGenExperimental6502/build.gradle new file mode 100644 index 000000000..7c4ddac06 --- /dev/null +++ b/codeGenExperimental6502/build.gradle @@ -0,0 +1,46 @@ + +plugins { + id 'java' + id 'application' + id "org.jetbrains.kotlin.jvm" +} + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(javaVersion) + } +} + +compileKotlin { + kotlinOptions { + jvmTarget = javaVersion + } +} + +compileTestKotlin { + kotlinOptions { + jvmTarget = javaVersion + } +} + +dependencies { + implementation project(':compilerInterfaces') + implementation project(':compilerAst') + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" + // implementation "org.jetbrains.kotlin:kotlin-reflect" + implementation "com.michael-bull.kotlin-result:kotlin-result-jvm:1.1.12" + +} + +sourceSets { + main { + java { + srcDirs = ["${project.projectDir}/src"] + } + resources { + srcDirs = ["${project.projectDir}/res"] + } + } +} + +// note: there are no unit tests in this module! diff --git a/codeGenExperimental6502/codeGenExperimental6502.iml b/codeGenExperimental6502/codeGenExperimental6502.iml new file mode 100644 index 000000000..f04990594 --- /dev/null +++ b/codeGenExperimental6502/codeGenExperimental6502.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/codeGenExperimental6502/src/prog8/codegen/experimental6502/AssemblyProgram.kt b/codeGenExperimental6502/src/prog8/codegen/experimental6502/AssemblyProgram.kt new file mode 100644 index 000000000..b7681a632 --- /dev/null +++ b/codeGenExperimental6502/src/prog8/codegen/experimental6502/AssemblyProgram.kt @@ -0,0 +1,13 @@ +package prog8.codegen.experimental6502 + +import prog8.compilerinterface.CompilationOptions +import prog8.compilerinterface.IAssemblyProgram + + +class AssemblyProgram(override val name: String) : IAssemblyProgram +{ + override fun assemble(options: CompilationOptions): Boolean { + println("..todo: assemble code into binary..") + return false + } +} diff --git a/codeGenExperimental6502/src/prog8/codegen/experimental6502/ExperimentalAsmGen6502.kt b/codeGenExperimental6502/src/prog8/codegen/experimental6502/ExperimentalAsmGen6502.kt new file mode 100644 index 000000000..43ca1152e --- /dev/null +++ b/codeGenExperimental6502/src/prog8/codegen/experimental6502/ExperimentalAsmGen6502.kt @@ -0,0 +1,22 @@ +package prog8.codegen.experimental6502 + +import prog8.ast.Program +import prog8.compilerinterface.CompilationOptions +import prog8.compilerinterface.IAssemblyGenerator +import prog8.compilerinterface.IAssemblyProgram +import prog8.compilerinterface.IErrorReporter +import java.nio.file.Path + +class ExperimentalAsmGen6502(internal val program: Program, + internal val errors: IErrorReporter, + internal val options: CompilationOptions, + internal val outputDir: Path +): IAssemblyGenerator { + override fun compileToAssembly(): IAssemblyProgram? { + + println("\n** experimental 65(c)02 code generator **\n") + + println("..todo: create assembly code..") + return AssemblyProgram("dummy") + } +} \ No newline at end of file diff --git a/compiler/build.gradle b/compiler/build.gradle index 2df3f84b0..7260713d0 100644 --- a/compiler/build.gradle +++ b/compiler/build.gradle @@ -32,6 +32,7 @@ dependencies { implementation project(':compilerAst') implementation project(':codeGenTargets') implementation project(':codeGenCpu6502') + implementation project(':codeGenExperimental6502') implementation 'org.antlr:antlr4-runtime:4.9.2' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" // implementation "org.jetbrains.kotlin:kotlin-reflect" diff --git a/compiler/compiler.iml b/compiler/compiler.iml index 6f83b7a1e..a27258ff2 100644 --- a/compiler/compiler.iml +++ b/compiler/compiler.iml @@ -21,5 +21,6 @@ + \ No newline at end of file diff --git a/compiler/src/prog8/CompilerMain.kt b/compiler/src/prog8/CompilerMain.kt index 977469148..8288aa7fd 100644 --- a/compiler/src/prog8/CompilerMain.kt +++ b/compiler/src/prog8/CompilerMain.kt @@ -43,6 +43,7 @@ private fun compileMain(args: Array): Boolean { val slowCodegenWarnings by cli.option(ArgType.Boolean, fullName = "slowwarn", description="show debug warnings about slow/problematic assembly code generation") val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results") val asmListfile by cli.option(ArgType.Boolean, fullName = "asmlist", description = "make the assembler produce a listing file as well") + val experimentalCodegen by cli.option(ArgType.Boolean, fullName = "expericodegen", description = "use experimental codegen") val compilationTarget by cli.option(ArgType.String, fullName = "target", description = "target output of the compiler (one of '${C64Target.name}', '${C128Target.name}', '${Cx16Target.name}')").default(C64Target.name) val sourceDirs by cli.option(ArgType.String, fullName="srcdirs", description = "list of extra paths, separated with ${File.pathSeparator}, to search in for imported modules").multiple().delimiter(File.pathSeparator) val moduleFiles by cli.argument(ArgType.String, fullName = "modules", description = "main module file(s) to compile").multiple(999) @@ -93,6 +94,7 @@ private fun compileMain(args: Array): Boolean { slowCodegenWarnings == true, quietAssembler == true, asmListfile == true, + experimentalCodegen == true, compilationTarget, srcdirs, outputPath @@ -143,6 +145,7 @@ private fun compileMain(args: Array): Boolean { slowCodegenWarnings == true, quietAssembler == true, asmListfile == true, + experimentalCodegen == true, compilationTarget, srcdirs, outputPath diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 8e64f8be7..d7053094a 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -9,7 +9,8 @@ import prog8.ast.base.Position import prog8.ast.expressions.Expression import prog8.ast.expressions.NumericLiteralValue import prog8.ast.statements.Directive -import prog8.codegen.cpu6502.AsmGen +import prog8.codegen.cpu6502.AsmGen6502 +import prog8.codegen.experimental6502.ExperimentalAsmGen6502 import prog8.codegen.target.C128Target import prog8.codegen.target.C64Target import prog8.codegen.target.Cx16Target @@ -37,6 +38,7 @@ class CompilerArguments(val filepath: Path, val slowCodegenWarnings: Boolean, val quietAssembler: Boolean, val asmListfile: Boolean, + val experimentalCodegen: Boolean, val compilationTarget: String, val sourceDirs: List = emptyList(), val outputDir: Path = Path(""), @@ -72,6 +74,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult { dontReinitGlobals = args.dontReinitGlobals asmQuiet = args.quietAssembler asmListfile = args.asmListfile + experimentalCodegen = args.experimentalCodegen } program = programresult importedFiles = imported @@ -347,21 +350,18 @@ private fun writeAssembly(program: Program, // printProgram(program) compilerOptions.compTarget.machine.initializeZeropage(compilerOptions) - val assembly = asmGeneratorFor(compilerOptions.compTarget, + val assembly = asmGeneratorFor( program, errors, - compilerOptions.compTarget.machine.zeropage, compilerOptions, outputDir).compileToAssembly() errors.report() - return if(assembly.valid && errors.noErrors()) { - val assemblerReturnStatus = assembly.assemble(compilerOptions) - if(assemblerReturnStatus!=0) - WriteAssemblyResult.Fail("assembler step failed with return code $assemblerReturnStatus") - else { + return if(assembly!=null && errors.noErrors()) { + if(assembly.assemble(compilerOptions)) { WriteAssemblyResult.Ok(assembly.name) - } + } else + WriteAssemblyResult.Fail("assembler step failed") } else { WriteAssemblyResult.Fail("compiler failed with errors") } @@ -375,14 +375,19 @@ fun printProgram(program: Program) { } internal fun asmGeneratorFor( - compTarget: ICompilationTarget, program: Program, errors: IErrorReporter, - zp: Zeropage, options: CompilationOptions, outputDir: Path ): IAssemblyGenerator { - // at the moment we only have one code generation backend (for 6502 and 65c02) - return AsmGen(program, errors, zp, options, compTarget, outputDir) + if(options.experimentalCodegen) { + if (options.compTarget.machine.cpu in arrayOf(CpuType.CPU6502, CpuType.CPU65c02)) + return ExperimentalAsmGen6502(program, errors, options, outputDir) + } else { + if (options.compTarget.machine.cpu in arrayOf(CpuType.CPU6502, CpuType.CPU65c02)) + return AsmGen6502(program, errors, options, outputDir) + } + + throw NotImplementedError("no asm generator for cpu ${options.compTarget.machine.cpu}") } diff --git a/compiler/test/TestCompilerOnExamples.kt b/compiler/test/TestCompilerOnExamples.kt index cb4adeef3..0d342a88d 100644 --- a/compiler/test/TestCompilerOnExamples.kt +++ b/compiler/test/TestCompilerOnExamples.kt @@ -31,6 +31,7 @@ private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilat slowCodegenWarnings = false, quietAssembler = true, asmListfile = false, + experimentalCodegen = false, compilationTarget = target.name, outputDir = outputDir ) diff --git a/compiler/test/TestCompilerOptionLibdirs.kt b/compiler/test/TestCompilerOptionLibdirs.kt index 67c529ab5..3a93a9a6a 100644 --- a/compiler/test/TestCompilerOptionLibdirs.kt +++ b/compiler/test/TestCompilerOptionLibdirs.kt @@ -45,6 +45,7 @@ class TestCompilerOptionSourcedirs: FunSpec({ slowCodegenWarnings = false, quietAssembler = true, asmListfile = false, + experimentalCodegen = false, compilationTarget = Cx16Target.name, sourceDirs, outputDir diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index f761d6863..e790048ed 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -6,6 +6,7 @@ import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import io.kotest.matchers.string.shouldContain +import io.kotest.matchers.string.shouldNotBeBlank import io.kotest.matchers.types.instanceOf import io.kotest.matchers.types.shouldBeSameInstanceAs import prog8.ast.Program @@ -326,7 +327,8 @@ class TestOptimization: FunSpec({ bbAssigns1expr.inferType(result.program).getOrElse { fail("dt") } shouldBe DataType.UBYTE val asm = generateAssembly(result.program, options) - asm.valid shouldBe true + asm shouldNotBe null + asm!!.name.shouldNotBeBlank() } test("intermediate assignment steps generated for typecasted expression") { @@ -384,7 +386,8 @@ class TestOptimization: FunSpec({ value.right shouldBe instanceOf() val asm = generateAssembly(result.program) - asm.valid shouldBe true + asm shouldNotBe null + asm!!.name.shouldNotBeBlank() } test("unused variable removal") { diff --git a/compiler/test/codegeneration/TestAsmGenSymbols.kt b/compiler/test/codegeneration/TestAsmGenSymbols.kt index 1cdb35b5f..9efb2371c 100644 --- a/compiler/test/codegeneration/TestAsmGenSymbols.kt +++ b/compiler/test/codegeneration/TestAsmGenSymbols.kt @@ -12,7 +12,7 @@ import prog8.ast.expressions.AddressOf import prog8.ast.expressions.IdentifierReference import prog8.ast.expressions.NumericLiteralValue import prog8.ast.statements.* -import prog8.codegen.cpu6502.AsmGen +import prog8.codegen.cpu6502.AsmGen6502 import prog8.codegen.target.C64Target import prog8.codegen.target.c64.C64Zeropage import prog8.compilerinterface.CompilationOptions @@ -75,11 +75,11 @@ class TestAsmGenSymbols: StringSpec({ return Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder).addModule(module) } - fun createTestAsmGen(program: Program): AsmGen { + fun createTestAsmGen(program: Program): AsmGen6502 { val errors = ErrorReporterForTests() val options = CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, true, C64Target) - val zp = C64Zeropage(options) - val asmgen = AsmGen(program, errors, zp, options, C64Target, Path.of("")) + options.compTarget.machine.zeropage = C64Zeropage(options) + val asmgen = AsmGen6502(program, errors, options, Path.of("")) return asmgen } diff --git a/compiler/test/helpers/compileXyz.kt b/compiler/test/helpers/compileXyz.kt index b6f451d8e..349394bb0 100644 --- a/compiler/test/helpers/compileXyz.kt +++ b/compiler/test/helpers/compileXyz.kt @@ -3,7 +3,7 @@ package prog8tests.helpers import io.kotest.assertions.withClue import io.kotest.matchers.shouldBe import prog8.ast.Program -import prog8.codegen.cpu6502.AsmGen +import prog8.codegen.cpu6502.AsmGen6502 import prog8.codegen.target.C64Target import prog8.codegen.target.c64.C64Zeropage import prog8.compiler.CompilationResult @@ -53,6 +53,7 @@ internal fun compileFile( slowCodegenWarnings = false, quietAssembler = true, asmListfile = false, + experimentalCodegen = false, platform.name, outputDir = outputDir, errors = errors ?: ErrorReporterForTests() @@ -83,10 +84,9 @@ internal fun compileText( internal fun generateAssembly( program: Program, options: CompilationOptions? = null -): IAssemblyProgram { +): IAssemblyProgram? { val coptions = options ?: CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.DONTUSE, emptyList(), true, true, C64Target) - val zp = C64Zeropage(coptions) - coptions.compTarget.machine.zeropage=zp - val asmgen = AsmGen(program, ErrorReporterForTests(), zp, coptions, C64Target, outputDir) + coptions.compTarget.machine.zeropage = C64Zeropage(coptions) + val asmgen = AsmGen6502(program, ErrorReporterForTests(), coptions, outputDir) return asmgen.compileToAssembly() } diff --git a/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt b/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt index a7b1bf5f8..f56507075 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt @@ -31,5 +31,6 @@ class CompilationOptions(val output: OutputType, var optimizeFloatExpressions: Boolean = false, var dontReinitGlobals: Boolean = false, var asmQuiet: Boolean = false, - var asmListfile: Boolean = false + var asmListfile: Boolean = false, + var experimentalCodegen: Boolean = false ) diff --git a/compilerInterfaces/src/prog8/compilerinterface/IAssemblyGenerator.kt b/compilerInterfaces/src/prog8/compilerinterface/IAssemblyGenerator.kt index ac87649a3..8f16a3592 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/IAssemblyGenerator.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/IAssemblyGenerator.kt @@ -1,13 +1,13 @@ package prog8.compilerinterface + interface IAssemblyGenerator { - fun compileToAssembly(): IAssemblyProgram + fun compileToAssembly(): IAssemblyProgram? } interface IAssemblyProgram { - val valid: Boolean val name: String - fun assemble(options: CompilationOptions): Int + fun assemble(options: CompilationOptions): Boolean } fun viceMonListName(baseFilename: String) = "$baseFilename.vice-mon-list" diff --git a/docs/source/building.rst b/docs/source/building.rst index d4ba9cdf4..bfa331900 100644 --- a/docs/source/building.rst +++ b/docs/source/building.rst @@ -154,6 +154,9 @@ One or more .p8 module files ``-asmlist`` Generate an assembler listing file as well. +``-expericodegen`` + Use experimental code generation backend (*incomplete*). + Module source code files ------------------------ diff --git a/examples/test.p8 b/examples/test.p8 index 37a209a35..6dc232a4a 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -2,12 +2,8 @@ main { sub start() { - word w1 = -10 - byte bb = 2 - w1 -= bb-1 - - - - txt.print_w(w1) + txt.print("ok") txt.nl() - sys.wait(999) } } diff --git a/httpCompilerService/src/prog8/http/TestHttp.kt b/httpCompilerService/src/prog8/http/TestHttp.kt index 3b5b9e434..033b9f83a 100644 --- a/httpCompilerService/src/prog8/http/TestHttp.kt +++ b/httpCompilerService/src/prog8/http/TestHttp.kt @@ -39,7 +39,8 @@ class RequestParser : Take { slowCodegenWarnings = true, compilationTarget = "c64", quietAssembler = false, - asmListfile = false + asmListfile = false, + experimentalCodegen = false ) val compilationResult = compileProgram(args) return RsJson(Jsonding()) diff --git a/settings.gradle b/settings.gradle index b8565579e..6cf8f044d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,6 +5,7 @@ include( ':codeOptimizers', ':codeGenTargets', ':codeGenCpu6502', + ':codeGenExperimental6502', ':compiler', ':dbusCompilerService', ':httpCompilerService'