This commit is contained in:
Irmen de Jong 2022-09-10 17:06:51 +02:00
parent aacea3e9db
commit 30a42ec1bd
7 changed files with 21 additions and 63 deletions

View File

@ -78,7 +78,7 @@ class CodeGen(internal val program: PtProgram,
// TODO: this makes sure those I/O routines are correct, but this step should be skipped eventually.
IRFileWriter(irProg).writeFile()
val irProgFromDisk = IRFileReader(options.outputDir, irProg.name).readFile()
return AssemblyProgram(irProgFromDisk.name, irProgFromDisk)
return VmAssemblyProgram(irProgFromDisk.name, irProgFromDisk)
}
private fun flattenNestedSubroutines() {

View File

@ -8,36 +8,24 @@ import java.io.BufferedWriter
import kotlin.io.path.bufferedWriter
import kotlin.io.path.div
class AssemblyProgram(override val name: String, val irProgram: IRProgram): IAssemblyProgram {
class VmAssemblyProgram(override val name: String, val irProgram: IRProgram): IAssemblyProgram {
// TODO once this is working, replace the codeGenVirtual by codeGenExperimental
// after that,
// after that, remove the intermediate .p8ir file writing
override fun assemble(options: CompilationOptions): Boolean {
val outfile = options.outputDir / ("$name.p8virt")
println("write code to $outfile")
// at last, allocate the variables in memory.
val allocations = VariableAllocator(irProgram.st, irProgram.encoding, irProgram.options.compTarget)
val allocations = VmVariableAllocator(irProgram.st, irProgram.encoding, irProgram.options.compTarget)
outfile.bufferedWriter().use { out ->
allocations.asVmMemory().forEach { (name, alloc) ->
out.write("; ${name.joinToString(".")}\n")
out.write(alloc + "\n")
}
// with(irProgram.st) {
// allVariables.forEach {
// //TODO("var $it")
// }
// allMemMappedVariables.forEach {
// println("MAPPED ${it.name} ${it.address}")
// // TODO implement proper memory mapped variable in VM - for now put them as regular variable to get it to compile
//
// }
// allMemorySlabs.forEach {
// TODO("implement proper memory slab allocation in VM")
// }
// }
out.write("------PROGRAM------\n")

View File

@ -3,7 +3,7 @@ package prog8.codegen.experimental
import prog8.code.SymbolTable
import prog8.code.core.*
class VariableAllocator(val st: SymbolTable, val encoding: IStringEncoding, memsizer: IMemSizer) {
class VmVariableAllocator(val st: SymbolTable, val encoding: IStringEncoding, memsizer: IMemSizer) {
internal val allocations = mutableMapOf<List<String>, Int>()
private var freeMemoryStart: Int
@ -26,18 +26,6 @@ class VariableAllocator(val st: SymbolTable, val encoding: IStringEncoding, mems
allocations[variable.scopedName] = nextLocation
nextLocation += memsize
}
for (memvar in st.allMemMappedVariables) {
// TODO virtual machine doesn't have memory mapped variables, so treat them as regular allocated variables for now
val memsize =
when (memvar.dt) {
in NumericDatatypes -> memsizer.memorySize(memvar.dt)
in ArrayDatatypes -> memsizer.memorySize(memvar.dt, memvar.length!!)
else -> throw InternalCompilerException("weird dt")
}
allocations[memvar.scopedName] = nextLocation
nextLocation += memsize
}
freeMemoryStart = nextLocation
}
@ -81,25 +69,6 @@ class VariableAllocator(val st: SymbolTable, val encoding: IStringEncoding, mems
}
mm.add(Pair(variable.scopedName, "$location $typeStr $value"))
}
for (variable in st.allMemMappedVariables) {
val location = allocations.getValue(variable.scopedName)
val typeStr = when(variable.dt) {
DataType.UBYTE, DataType.ARRAY_UB, DataType.STR -> "ubyte"
DataType.BYTE, DataType.ARRAY_B -> "byte"
DataType.UWORD, DataType.ARRAY_UW -> "uword"
DataType.WORD, DataType.ARRAY_W -> "word"
DataType.FLOAT, DataType.ARRAY_F -> "float"
else -> throw InternalCompilerException("weird dt")
}
val value = when(variable.dt) {
DataType.FLOAT -> "0.0"
in NumericDatatypes -> "0"
DataType.ARRAY_F -> (1..variable.length!!).joinToString(",") { "0.0" }
in ArrayDatatypes -> (1..variable.length!!).joinToString(",") { "0" }
else -> throw InternalCompilerException("weird dt for mem mapped var")
}
mm.add(Pair(variable.scopedName, "$location $typeStr $value"))
}
return mm
}

View File

@ -50,7 +50,8 @@ a_label:
uword[4] @shared wordzeroarray
qq=4242 ; TODO should generate symbol not allocated address
mapped = 42 ; TODO wrong VMASM code generated... should generate mapped memory address
mapped = 99 ; TODO wrong VMASM code generated... should generate mapped memory address
mappedarray[1]=99
qq=global1
qq=other.global2

View File

@ -217,7 +217,7 @@ class IRFileReader(outputDir: Path, programName: String) {
throw IRParseException("invalid INITGLOBALS")
line = lines.next()
var chunk = IRCodeChunk(Position.DUMMY)
if(line=="<CODE>") {
if(line=="<C>") {
chunk = parseCodeChunk(line, lines)!!
line = lines.next()
}
@ -310,7 +310,7 @@ class IRFileReader(outputDir: Path, programName: String) {
val line = lines.next()
if(line=="</SUB>")
return sub
val chunk = if(line=="<CODE>")
val chunk = if(line=="<C>")
parseCodeChunk(line, lines)
else if(line.startsWith("<INLINEASM "))
parseInlineAssembly(line, lines)
@ -329,16 +329,16 @@ class IRFileReader(outputDir: Path, programName: String) {
}
private fun parseCodeChunk(firstline: String, lines: Iterator<String>): IRCodeChunk? {
if(firstline!="<CODE>") {
if(firstline!="<C>") {
if(firstline=="</SUB>")
return null
else
throw IRParseException("invalid or empty CODE chunk")
throw IRParseException("invalid or empty <C>ODE chunk")
}
val chunk = IRCodeChunk(Position.DUMMY)
while(true) {
var line = lines.next()
if (line == "</CODE>")
if (line == "</C>")
return chunk
if (line.isBlank() || line.startsWith(';'))
continue

View File

@ -20,10 +20,10 @@ class IRFileWriter(private val irProgram: IRProgram) {
out.write("\n<INITGLOBALS>\n")
if(!irProgram.options.dontReinitGlobals) {
out.write("<CODE>\n")
out.write("<C>\n")
// note: this a block of code that loads values and stores them into the global variables to reset their values.
irProgram.globalInits.forEach { out.writeLine(it) }
out.write("</CODE>\n")
out.write("</C>\n")
}
out.write("</INITGLOBALS>\n")
writeBlocks()
@ -44,11 +44,11 @@ class IRFileWriter(private val irProgram: IRProgram) {
if(chunk is IRInlineAsmChunk) {
writeInlineAsm(chunk)
} else {
out.write("<CODE>\n")
out.write("<C>\n")
if (chunk.lines.isEmpty())
throw InternalCompilerException("empty code chunk in ${it.name} ${it.position}")
chunk.lines.forEach { line -> out.writeLine(line) }
out.write("</CODE>\n")
out.write("</C>\n")
}
}
out.write("</SUB>\n")

View File

@ -18,7 +18,7 @@ PROGRAM:
MEMORYMAPPEDVARIABLES (from Symboltable)
MEMORYSLABS (from Symboltable)
INITGLOBALS
CODE
C (CODE)
CODE-LINE (assignment to initialize a variable)
...
BLOCK
@ -27,12 +27,12 @@ PROGRAM:
SUB
INLINEASM
INLINEASM
CODE
C (CODE)
CODE-LINE (label, instruction, comment, inlinebinary)
CODE-LINE
...
CODE
CODE
C (CODE)
C (CODE)
...
SUB
SUB