mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
IR tweak
This commit is contained in:
parent
aacea3e9db
commit
30a42ec1bd
@ -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() {
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user