working on vm and new ast

This commit is contained in:
Irmen de Jong
2022-03-21 01:01:21 +01:00
parent 9b16d7c786
commit ff57c5e9d3
27 changed files with 161 additions and 76 deletions
@@ -1,15 +1,10 @@
package prog8.codegen.virtual
import com.github.michaelbull.result.Ok
import com.github.michaelbull.result.Result
import com.github.michaelbull.result.mapError
import prog8.code.SymbolTable
import prog8.code.ast.*
import prog8.code.core.*
import prog8.vm.Instruction
import java.io.File
import kotlin.io.path.Path
import kotlin.io.path.isRegularFile
import prog8.vm.Opcode
class CodeGen(internal val program: PtProgram,
internal val symbolTable: SymbolTable,
@@ -19,11 +14,30 @@ class CodeGen(internal val program: PtProgram,
private val instructions = mutableListOf<String>()
init {
if(options.dontReinitGlobals)
TODO("support no globals re-init in vm")
}
override fun compileToAssembly(): IAssemblyProgram? {
instructions.clear()
val allocations = VariableAllocator(symbolTable, program, errors)
for (block in program.allBlocks())
outComment("GLOBAL VARS INITS")
program.allBlocks().forEach {
it.children
.singleOrNull { node->node is PtScopeVarsInit }
?.let { inits->
translateNode(inits)
it.children.remove(inits)
}
}
outComment("PROGRAM CODE")
for (block in program.allBlocks()) {
translateNode(block)
}
return AssemblyProgram(program.name, allocations, instructions)
}
@@ -31,21 +45,22 @@ class CodeGen(internal val program: PtProgram,
instructions.add(ins.toString())
}
private fun out(ins: String) {
instructions.add(ins)
private fun outComment(ins: String) {
instructions.add("; $ins")
}
private fun translateNode(node: PtNode) {
when(node) {
is PtBlock -> translate(node)
is PtSub -> translate(node)
is PtScopeVarsDecls -> { /* vars should be looked up via symbol table */ }
is PtVariable -> { /* var should be looked up via symbol table */ }
is PtMemMapped -> { /* memmapped var should be looked up via symbol table */ }
is PtConstant -> { /* constants have all been folded into the code */ }
is PtAsmSub -> translate(node)
is PtAssignTarget -> TODO()
is PtAssignment -> translate(node)
is PtBreakpoint -> TODO()
is PtScopeVarsInit -> translate(node)
is PtBreakpoint -> translate(node)
is PtConditionalBranch -> TODO()
is PtAddressOf -> TODO()
is PtArrayIndexer -> TODO()
@@ -76,28 +91,42 @@ class CodeGen(internal val program: PtProgram,
is PtSubroutineParameter -> TODO()
is PtWhen -> TODO()
is PtWhenChoice -> TODO()
is PtAsmSub -> throw AssemblyError("asmsub not supported on virtual machine target")
is PtInlineAssembly -> throw AssemblyError("inline assembly not supported on virtual machine target")
else -> TODO("missing codegen for $node")
}
}
private fun translate(sub: PtSub) {
out("; SUB: ${sub.scopedName} -> ${sub.returntype}")
private fun translate(breakpoint: PtBreakpoint) {
out(Instruction(Opcode.BREAKPOINT))
}
private fun translate(asmsub: PtAsmSub) {
out("; ASMSUB: ${asmsub.scopedName} = ${asmsub.address} -> ${asmsub.retvalRegisters}")
private fun translate(init: PtScopeVarsInit) {
init.children.forEach { translateNode(it) }
}
private fun translate(sub: PtSub) {
outComment("SUB: ${sub.scopedName} -> ${sub.returntype}")
sub.children
.singleOrNull { it is PtScopeVarsInit }
?.let { inits ->
sub.children.remove(inits)
translateNode(inits)
}
// TODO rest
outComment("SUB-END ${sub.scopedName}\n")
}
private fun translate(assign: PtAssignment) {
out("; ASSIGN: ${assign.target.identifier?.targetName} = ${assign.value}")
outComment("ASSIGN: ${assign.target.identifier?.targetName} = ${assign.value}")
}
private fun translate(block: PtBlock) {
out("\n; BLOCK '${block.name}' addr=${block.address} lib=${block.library}")
outComment("BLOCK '${block.name}' addr=${block.address} lib=${block.library}")
for (child in block.children) {
translateNode(child)
}
out("; BLOCK-END '${block.name}'\n")
outComment("BLOCK-END '${block.name}'\n")
}
}