'-vm' option now also reads .p8ir files

This commit is contained in:
Irmen de Jong 2022-09-20 12:14:33 +02:00
parent 5167fdb3f0
commit d6393cdbe5
5 changed files with 48 additions and 16 deletions

View File

@ -6,6 +6,8 @@ import prog8.code.core.IMachineDefinition
import prog8.code.core.Zeropage import prog8.code.core.Zeropage
import java.io.File import java.io.File
import java.nio.file.Path import java.nio.file.Path
import kotlin.io.path.name
import kotlin.io.path.readText
class VirtualMachineDefinition: IMachineDefinition { class VirtualMachineDefinition: IMachineDefinition {
@ -32,9 +34,16 @@ class VirtualMachineDefinition: IMachineDefinition {
println("\nStarting Virtual Machine...") println("\nStarting Virtual Machine...")
// to not have external module dependencies we launch the virtual machine via reflection // to not have external module dependencies we launch the virtual machine via reflection
val vm = Class.forName("prog8.vm.VmRunner").getDeclaredConstructor().newInstance() as IVirtualMachineRunner val vm = Class.forName("prog8.vm.VmRunner").getDeclaredConstructor().newInstance() as IVirtualMachineRunner
val source = File("$programNameWithPath.p8virt").readText() val filename = programNameWithPath.name
if(filename.endsWith(".p8virt")) {
vm.runProgram(programNameWithPath.readText(), true)
} else if(File("$filename.p8virt").isFile) {
val source = File("$filename.p8virt").readText()
vm.runProgram(source, true) vm.runProgram(source, true)
} }
else
throw IllegalArgumentException("vm can only run .p8virt or .p8ir files")
}
override fun isIOAddress(address: UInt): Boolean = false override fun isIOAddress(address: UInt): Boolean = false

View File

@ -8,10 +8,10 @@ import java.io.BufferedWriter
import kotlin.io.path.bufferedWriter import kotlin.io.path.bufferedWriter
import kotlin.io.path.div import kotlin.io.path.div
internal class VmAssemblyProgram(override val name: String, val irProgram: IRProgram): IAssemblyProgram { internal class VmAssemblyProgram(override val name: String, private val irProgram: IRProgram): IAssemblyProgram {
override fun assemble(options: CompilationOptions): Boolean { override fun assemble(dummyOptions: CompilationOptions): Boolean {
val outfile = options.outputDir / ("$name.p8virt") val outfile = irProgram.options.outputDir / ("$name.p8virt")
println("write code to $outfile") println("write code to $outfile")
// at last, allocate the variables in memory. // at last, allocate the variables in memory.
@ -24,7 +24,7 @@ internal class VmAssemblyProgram(override val name: String, val irProgram: IRPro
out.write("------PROGRAM------\n") out.write("------PROGRAM------\n")
if(!options.dontReinitGlobals) { if(!irProgram.options.dontReinitGlobals) {
out.write("; global var inits\n") out.write("; global var inits\n")
irProgram.globalInits.forEach { out.writeLine(it) } irProgram.globalInits.forEach { out.writeLine(it) }
} }

View File

@ -9,6 +9,7 @@ import prog8.code.core.IErrorReporter
import prog8.codegen.intermediate.IRCodeGen import prog8.codegen.intermediate.IRCodeGen
import prog8.intermediate.IRFileReader import prog8.intermediate.IRFileReader
import prog8.intermediate.IRFileWriter import prog8.intermediate.IRFileWriter
import java.nio.file.Path
class VmCodeGen(private val program: PtProgram, class VmCodeGen(private val program: PtProgram,
private val symbolTable: SymbolTable, private val symbolTable: SymbolTable,
@ -26,4 +27,11 @@ class VmCodeGen(private val program: PtProgram,
val irProgram2 = IRFileReader(options.outputDir, irProgram.name).readFile() val irProgram2 = IRFileReader(options.outputDir, irProgram.name).readFile()
return VmAssemblyProgram(irProgram2.name, irProgram2) return VmAssemblyProgram(irProgram2.name, irProgram2)
} }
companion object {
fun compileIR(listingFilename: String): IAssemblyProgram {
val irProgram = IRFileReader(Path.of(""), listingFilename).readFile()
return VmAssemblyProgram(irProgram.name, irProgram)
}
}
} }

View File

@ -2,10 +2,10 @@ package prog8
import kotlinx.cli.* import kotlinx.cli.*
import prog8.ast.base.AstException import prog8.ast.base.AstException
import prog8.code.core.CbmPrgLauncherType import prog8.code.core.*
import prog8.code.core.toHex
import prog8.code.target.* import prog8.code.target.*
import prog8.code.target.virtual.VirtualMachineDefinition import prog8.code.target.virtual.VirtualMachineDefinition
import prog8.codegen.virtual.VmCodeGen
import prog8.compiler.CompilationResult import prog8.compiler.CompilationResult
import prog8.compiler.CompilerArguments import prog8.compiler.CompilerArguments
import prog8.compiler.compileProgram import prog8.compiler.compileProgram
@ -45,7 +45,7 @@ private fun compileMain(args: Array<String>): Boolean {
val experimentalCodegen by cli.option(ArgType.Boolean, fullName = "expericodegen", description = "use experimental/alternative codegen") val experimentalCodegen by cli.option(ArgType.Boolean, fullName = "expericodegen", description = "use experimental/alternative codegen")
val compilationTarget by cli.option(ArgType.String, fullName = "target", description = "target output of the compiler (one of '${C64Target.NAME}', '${C128Target.NAME}', '${Cx16Target.NAME}', '${AtariTarget.NAME}', '${VMTarget.NAME}')").default(C64Target.NAME) val compilationTarget by cli.option(ArgType.String, fullName = "target", description = "target output of the compiler (one of '${C64Target.NAME}', '${C128Target.NAME}', '${Cx16Target.NAME}', '${AtariTarget.NAME}', '${VMTarget.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 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 startVm by cli.option(ArgType.Boolean, fullName = "vm", description = "load and run a p8-virt listing in the VM instead") val startVm by cli.option(ArgType.Boolean, fullName = "vm", description = "load and run a p8-virt or p8-ir listing in the VM instead")
val symbolDefs by cli.option(ArgType.String, fullName = "D", description = "define assembly symbol(s) with -D SYMBOL=VALUE").multiple() val symbolDefs by cli.option(ArgType.String, fullName = "D", description = "define assembly symbol(s) with -D SYMBOL=VALUE").multiple()
val evalStackAddrString by cli.option(ArgType.String, fullName = "esa", description = "override the eval-stack base address (must be page aligned)") val evalStackAddrString by cli.option(ArgType.String, fullName = "esa", description = "override the eval-stack base address (must be page aligned)")
val moduleFiles by cli.argument(ArgType.String, fullName = "modules", description = "main module file(s) to compile").multiple(999) val moduleFiles by cli.argument(ArgType.String, fullName = "modules", description = "main module file(s) to compile").multiple(999)
@ -242,12 +242,27 @@ private fun processSymbolDefs(symbolDefs: List<String>): Map<String, String>? {
} }
fun runVm(listingFilename: String): Boolean { fun runVm(listingFilename: String): Boolean {
val name = if(listingFilename.endsWith(".p8ir")) {
if(listingFilename.endsWith(".p8virt")) val withoutSuffix = listingFilename.substring(0, listingFilename.length-5)
listingFilename.substring(0, listingFilename.length-7) val compiled = VmCodeGen.compileIR(withoutSuffix)
else if (!compiled.assemble(CompilationOptions( // these are just dummy options, the actual options are inside the .p8ir file itself:
listingFilename OutputType.PRG,
CbmPrgLauncherType.NONE,
ZeropageType.DONTUSE,
emptyList(),
floats = true,
noSysInit = true,
compTarget = VMTarget(),
loadAddress = VMTarget().machine.PROGRAM_LOAD_ADDRESS
))
) {
return false
}
val vmdef = VirtualMachineDefinition() val vmdef = VirtualMachineDefinition()
vmdef.launchEmulator(0, Paths.get(name)) vmdef.launchEmulator(0, Paths.get(withoutSuffix))
return true
}
val vmdef = VirtualMachineDefinition()
vmdef.launchEmulator(0, Paths.get(listingFilename))
return true return true
} }

View File

@ -170,7 +170,7 @@ One or more .p8 module files
Use experimental code generation backend (*incomplete*). Use experimental code generation backend (*incomplete*).
``-vm`` ``-vm``
load and run a p8-virt listing in the internal VirtualMachine instead of compiling a prog8 program file.. load and run a p8-virt or p8-ir listing in the internal VirtualMachine instead of compiling a prog8 program file..
``-D SYMBOLNAME=VALUE`` ``-D SYMBOLNAME=VALUE``
Add this user-defined symbol directly to the beginning of the generated assembly file. Add this user-defined symbol directly to the beginning of the generated assembly file.