mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
'-vm' option now also reads .p8ir files
This commit is contained in:
parent
5167fdb3f0
commit
d6393cdbe5
@ -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
|
||||||
|
|
||||||
|
@ -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) }
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user