2022-09-26 17:03:54 +00:00
|
|
|
package prog8.vm
|
|
|
|
|
|
|
|
import prog8.intermediate.*
|
|
|
|
import java.lang.IllegalArgumentException
|
|
|
|
|
|
|
|
class VmProgramLoader {
|
|
|
|
|
2022-09-26 17:46:44 +00:00
|
|
|
fun load(irProgram: IRProgram, memory: Memory): Array<IRInstruction> {
|
2022-09-26 17:03:54 +00:00
|
|
|
|
|
|
|
// at long last, allocate the variables in memory.
|
|
|
|
val allocations = VmVariableAllocator(irProgram.st, irProgram.encoding, irProgram.options.compTarget)
|
2022-09-26 17:46:44 +00:00
|
|
|
val program = mutableListOf<IRInstruction>()
|
2022-09-26 17:03:54 +00:00
|
|
|
|
|
|
|
// TODO stuff the allocated variables into memory
|
|
|
|
|
|
|
|
if(!irProgram.options.dontReinitGlobals) {
|
|
|
|
irProgram.globalInits.forEach {
|
|
|
|
// TODO put global init line into program
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// make sure that if there is a "main.start" entrypoint, we jump to it
|
|
|
|
irProgram.blocks.firstOrNull()?.let {
|
|
|
|
if(it.subroutines.any { sub -> sub.name=="main.start" }) {
|
2022-09-26 17:46:44 +00:00
|
|
|
program.add(IRInstruction(Opcode.JUMP, labelSymbol = "main.start"))
|
2022-09-26 17:03:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
irProgram.blocks.forEach { block ->
|
|
|
|
if(block.address!=null)
|
|
|
|
throw IllegalArgumentException("blocks cannot have a load address for vm: ${block.name}")
|
|
|
|
|
|
|
|
block.inlineAssembly.forEach {
|
|
|
|
|
|
|
|
// TODO put it.assembly into program
|
|
|
|
}
|
|
|
|
block.subroutines.forEach {
|
|
|
|
// TODO subroutine label ?
|
|
|
|
it.chunks.forEach { chunk ->
|
|
|
|
if(chunk is IRInlineAsmChunk) {
|
|
|
|
// TODO put it.assembly into program
|
|
|
|
} else {
|
|
|
|
chunk.lines.forEach {
|
|
|
|
// TODO put line into program
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
block.asmSubroutines.forEach {
|
|
|
|
// TODO add asmsub to program
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return emptyArray()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|