mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
fixup for memoryslabs
This commit is contained in:
parent
80b630a1e4
commit
a182b13e5a
@ -327,7 +327,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
||||
val align = (call.args[2] as PtNumber).number.toUInt()
|
||||
val label = codeGen.addMemorySlab(name, size, align, call.position)
|
||||
val code = VmCodeChunk()
|
||||
code += VmCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=resultRegister, labelSymbol = label)
|
||||
code += VmCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=resultRegister, labelSymbol = listOf(label))
|
||||
return code
|
||||
}
|
||||
|
||||
|
@ -775,15 +775,13 @@ class CodeGen(internal val program: PtProgram,
|
||||
return code
|
||||
}
|
||||
|
||||
private fun translate(block: PtBlock): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
code += VmCodeComment("BLOCK '${block.name}' addr=${block.address} lib=${block.library}")
|
||||
private fun translate(block: PtBlock): VmBlock {
|
||||
val vmblock = VmBlock(block.name, block.address, block.alignment) // no use for other attributes yet?
|
||||
for (child in block.children) {
|
||||
if(child !is PtAssignment) // global variable initialization is done elsewhere
|
||||
code += translateNode(child)
|
||||
vmblock += translateNode(child)
|
||||
}
|
||||
code += VmCodeComment("BLOCK-END '${block.name}'")
|
||||
return code
|
||||
return vmblock
|
||||
}
|
||||
|
||||
|
||||
@ -813,10 +811,10 @@ class CodeGen(internal val program: PtProgram,
|
||||
|
||||
internal fun isOne(expression: PtExpression): Boolean = expression is PtNumber && expression.number==1.0
|
||||
|
||||
fun addMemorySlab(name: String, size: UInt, align: UInt, position: Position): List<String> {
|
||||
val scopedName = "prog8_memoryslabs.$name"
|
||||
symbolTable.add(StMemorySlab(scopedName, size, align, position))
|
||||
return scopedName.split('.', limit=2)
|
||||
fun addMemorySlab(name: String, size: UInt, align: UInt, position: Position): String {
|
||||
val scopedName = "prog8_memoryslab_$name"
|
||||
symbolTable.add(StMemorySlab(scopedName, size, align, null, position))
|
||||
return scopedName
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package prog8.codegen.experimental
|
||||
|
||||
import prog8.code.SymbolTable
|
||||
import prog8.code.ast.PtBlock
|
||||
import prog8.code.core.*
|
||||
import prog8.vm.Instruction
|
||||
import prog8.vm.Opcode
|
||||
@ -20,28 +21,50 @@ class IRProgram(val name: String,
|
||||
private val st: SymbolTable) {
|
||||
|
||||
private val globalInits = mutableListOf<VmCodeLine>()
|
||||
private val blocks = mutableListOf<VmCodeChunk>()
|
||||
private val blocks = mutableListOf<VmBlock>()
|
||||
|
||||
fun writeFile() {
|
||||
val outfile = options.outputDir / ("$name.p8ir")
|
||||
println("Writing intermediate representation to $outfile")
|
||||
outfile.bufferedWriter().use { out ->
|
||||
|
||||
out.write("; PROGRAM '$name'\n")
|
||||
writeOptions(out)
|
||||
writeVariableAllocations(out)
|
||||
out.write("------PROGRAM------\n")
|
||||
|
||||
if(!options.dontReinitGlobals) {
|
||||
out.write("; global var inits\n")
|
||||
// note: this a block of code that loads values and stores them into the global variables to reset their values.
|
||||
out.write("\n[INITGLOBALS]\n")
|
||||
globalInits.forEach { out.writeLine(it) }
|
||||
out.write("[/INITGLOBALS]\n")
|
||||
}
|
||||
|
||||
out.write("; actual program code\n")
|
||||
blocks.asSequence().flatMap { it.lines }.forEach { line->out.writeLine(line) }
|
||||
out.write("\n[CODE]\n")
|
||||
blocks.forEach { block ->
|
||||
out.write("\n[BLOCK NAME=${block.name} ADDRESS=${block.address} ALIGN=${block.alignment}]\n")
|
||||
block.lines.forEach { out.writeLine(it) }
|
||||
out.write("[/BLOCK]\n")
|
||||
}
|
||||
out.write("[/CODE]\n")
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeOptions(out: BufferedWriter) {
|
||||
out.write("[OPTIONS]\n")
|
||||
out.write("compTarget = ${options.compTarget.name}\n")
|
||||
out.write("output = ${options.output}\n")
|
||||
out.write("launcher = ${options.launcher}\n")
|
||||
out.write("zeropage = ${options.zeropage}\n")
|
||||
out.write("zpReserved = ${options.zpReserved}\n")
|
||||
out.write("loadAddress = ${options.loadAddress}\n")
|
||||
out.write("dontReinitGlobals = ${options.dontReinitGlobals}\n")
|
||||
out.write("evalStackBaseAddress = ${options.evalStackBaseAddress}\n")
|
||||
// other options not yet useful here?
|
||||
out.write("[/OPTIONS]\n")
|
||||
}
|
||||
|
||||
private fun writeVariableAllocations(out: Writer) {
|
||||
out.write("; NORMAL VARIABLES\n")
|
||||
out.write("\n[VARIABLES]\n")
|
||||
for (variable in st.allVariables) {
|
||||
val typeStr = when(variable.dt) {
|
||||
DataType.UBYTE, DataType.ARRAY_UB, DataType.STR -> "ubyte"
|
||||
@ -77,8 +100,9 @@ class IRProgram(val name: String,
|
||||
// TODO have uninitialized variables? (BSS SECTION)
|
||||
out.write("VAR ${variable.scopedName.joinToString(".")} $typeStr = $value\n")
|
||||
}
|
||||
out.write("[/VARIABLES]\n")
|
||||
|
||||
out.write("; MEMORY MAPPED VARIABLES\n")
|
||||
out.write("\n[MEMORYMAPPEDVARIABLES]\n")
|
||||
for (variable in st.allMemMappedVariables) {
|
||||
val typeStr = when(variable.dt) {
|
||||
DataType.UBYTE, DataType.ARRAY_UB, DataType.STR -> "ubyte"
|
||||
@ -90,9 +114,11 @@ class IRProgram(val name: String,
|
||||
}
|
||||
out.write("MAP ${variable.scopedName.joinToString(".")} $typeStr ${variable.address}\n")
|
||||
}
|
||||
out.write("[/MEMORYMAPPEDVARIABLES]\n")
|
||||
|
||||
out.write("; MEMORY SLABS\n")
|
||||
st.allMemorySlabs.forEach{ slab -> out.write("MEMORYSLAB _${slab.name} ${slab.size} ${slab.align}\n") }
|
||||
out.write("\n[MEMORYSLABS]\n")
|
||||
st.allMemorySlabs.forEach{ slab -> out.write("SLAB _${slab.name} ${slab.size} ${slab.align}\n") }
|
||||
out.write("[/MEMORYSLABS]\n")
|
||||
}
|
||||
|
||||
private fun BufferedWriter.writeLine(line: VmCodeLine) {
|
||||
@ -119,8 +145,8 @@ class IRProgram(val name: String,
|
||||
}
|
||||
|
||||
fun addGlobalInits(chunk: VmCodeChunk) = globalInits.addAll(chunk.lines)
|
||||
fun addBlock(block: VmCodeChunk) = blocks.add(block)
|
||||
fun getBlocks(): List<VmCodeChunk> = blocks
|
||||
fun addBlock(block: VmBlock) = blocks.add(block)
|
||||
fun getBlocks(): List<VmBlock> = blocks
|
||||
}
|
||||
|
||||
sealed class VmCodeLine
|
||||
@ -167,7 +193,16 @@ class VmCodeInstruction(
|
||||
class VmCodeLabel(val name: List<String>): VmCodeLine()
|
||||
internal class VmCodeComment(val comment: String): VmCodeLine()
|
||||
|
||||
class VmCodeChunk(initial: VmCodeLine? = null) {
|
||||
|
||||
class VmBlock(
|
||||
val name: String,
|
||||
val address: UInt?,
|
||||
val alignment: PtBlock.BlockAlignment,
|
||||
initial: VmCodeLine? = null
|
||||
): VmCodeChunk(initial)
|
||||
|
||||
|
||||
open class VmCodeChunk(initial: VmCodeLine? = null) {
|
||||
val lines = mutableListOf<VmCodeLine>()
|
||||
|
||||
init {
|
||||
|
@ -49,6 +49,7 @@ class AssemblyProgram(override val name: String, private val allocations: Variab
|
||||
is VmCodeLabel -> write("_" + line.name.joinToString(".") + ":\n")
|
||||
is VmCodeInlineAsm -> {
|
||||
val asm = line.assembly.replace("""\{[a-zA-Z\d_\.]+\}""".toRegex()) { matchResult ->
|
||||
// "{ X }" -> address of X
|
||||
val name = matchResult.value.substring(1, matchResult.value.length-1).split('.')
|
||||
allocations.get(name).toString() }
|
||||
write(asm+"\n")
|
||||
|
@ -1,4 +1,7 @@
|
||||
main {
|
||||
|
||||
uword global1 = 1234
|
||||
|
||||
sub start() {
|
||||
|
||||
; TODO should generate address
|
||||
@ -13,5 +16,14 @@ main {
|
||||
|
||||
qq=4242 ; TODO should generate symbol not allocated address
|
||||
c64.EXTCOL = 42 ; TODO wrong VMASM code generated... should generate mapped memory address
|
||||
|
||||
qq=global1
|
||||
qq=other.global2
|
||||
}
|
||||
}
|
||||
|
||||
other {
|
||||
|
||||
uword global2 = 9999
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user