ir: store labels in blocks, but still useless

This commit is contained in:
Irmen de Jong 2022-11-17 00:15:47 +01:00
parent d8e87bd881
commit 91fdb3e2d4
7 changed files with 30 additions and 16 deletions

View File

@ -95,7 +95,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
processAst(program, args.errors, compilationOptions)
if (compilationOptions.optimize) {
// println("*********** AST RIGHT BEFORE OPTIMIZING *************")
// println("*********** COMPILER AST RIGHT BEFORE OPTIMIZING *************")
// printProgram(program)
optimizeAst(
@ -108,7 +108,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
}
postprocessAst(program, args.errors, compilationOptions)
// println("*********** AST BEFORE ASSEMBLYGEN *************")
// println("*********** COMPILER AST BEFORE ASSEMBLYGEN *************")
// printProgram(program)
determineProgramLoadAddress(program, compilationOptions, args.errors)
@ -402,7 +402,7 @@ private fun createAssemblyAndAssemble(program: Program,
// to help clean up the code that still depends on them.
// removeAllVardeclsFromAst(program)
// println("*********** AST RIGHT BEFORE ASM GENERATION *************")
// println("*********** COMPILER AST RIGHT BEFORE ASM GENERATION *************")
// printProgram(program)
val assembly = asmGeneratorFor(program, errors, symbolTable, compilerOptions).compileToAssembly()

View File

@ -3,8 +3,9 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- ir/vm: allow label in block scope
- ir/vm: allow label in block scope (correct order of block nodes!)
- regression test the various projects
- attempt to fix the expression codegen bug with reused temp vars (github #89)
- 6502 codegen: make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway)
then we can get rid of the instruction lists in the machinedefinitions as well. This is already no problem at all in the IR codegen.
- create BSS section in output program and put StStaticVariables in there with bss=true. Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE! So requires self-modifying code

View File

@ -271,7 +271,7 @@ class IRFileReader {
private fun parseCodeChunk(reader: XMLEventReader): IRCodeChunk {
skipText(reader)
val start = reader.nextEvent().asStartElement()
require(start.name.localPart=="C") { "missing C" }
require(start.name.localPart=="CODE") { "missing CODE" }
val label = start.attributes.asSequence().singleOrNull { it.name.localPart == "LABEL" }?.value?.ifBlank { null }
val text = readText(reader).trim()
val chunk = IRCodeChunk(label, null)
@ -321,6 +321,12 @@ class IRFileReader {
"ASMSUB" -> block += parseAsmSubroutine(reader)
"INLINEASM" -> block += parseInlineAssembly(reader)
"BYTES" -> block += parseBinaryBytes(reader)
"CODE" -> {
val chunk = parseCodeChunk(reader)
if(chunk.isNotEmpty() || chunk.label==null)
throw IRParseException("code chunk in block should only contain a label name")
block += chunk
}
else -> throw IRParseException("invalid line in BLOCK: ${reader.peek()}")
}
skipText(reader)
@ -344,7 +350,7 @@ class IRFileReader {
skipText(reader)
while(reader.peek().isStartElement) {
when(reader.peek().asStartElement().name.localPart) {
"C" -> sub += parseCodeChunk(reader)
"CODE" -> sub += parseCodeChunk(reader)
"BYTES" -> sub += parseBinaryBytes(reader)
"INLINEASM" -> sub += parseInlineAssembly(reader)
else -> throw IRParseException("invalid line in SUB: ${reader.peek()}")

View File

@ -49,6 +49,9 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
block.inlineAssemblies.forEach {
writeInlineAsm(it)
}
block.labels.forEach {
writeCodeChunk(it) // TODO doing it like this isn't useful, block needs to have a list of nodes rather than a few separate collections
}
block.subroutines.forEach {
out.write("<SUB NAME=\"${it.name}\" RETURNTYPE=\"${it.returnType.toString().lowercase()}\" POS=\"${it.position}\">\n")
out.write("<PARAMS>\n")
@ -91,15 +94,15 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
private fun writeCodeChunk(chunk: IRCodeChunk) {
if(chunk.label!=null)
out.write("<C LABEL=\"${chunk.label}\">\n")
out.write("<CODE LABEL=\"${chunk.label}\">\n")
else
out.write("<C>\n")
out.write("<CODE>\n")
chunk.instructions.forEach { instr ->
numInstr++
out.write(instr.toString())
out.write("\n")
}
out.write("</C>\n")
out.write("</CODE>\n")
}
private fun writeInlineBytes(chunk: IRInlineBinaryChunk) {

View File

@ -209,6 +209,7 @@ class IRBlock(
val subroutines = mutableListOf<IRSubroutine>()
val asmSubroutines = mutableListOf<IRAsmSubroutine>()
val inlineBinaries = mutableListOf<IRInlineBinaryChunk>()
val labels = mutableListOf<IRCodeChunk>() // empty code chunks having just a label.
enum class BlockAlignment {
NONE,
@ -225,7 +226,7 @@ class IRBlock(
operator fun plusAssign(irCodeChunk: IRCodeChunk) {
// this is for a separate label in the block scope. (random code statements are not allowed)
require(irCodeChunk.isEmpty() && irCodeChunk.label!=null)
TODO("allow labels in block scope, ${irCodeChunk.label}")
labels += irCodeChunk
}
fun isEmpty(): Boolean {

View File

@ -68,18 +68,18 @@ uword sys.wait.jiffies= zp=DONTCARE
</MEMORYSLABS>
<INITGLOBALS>
<C>
<CODE>
load.b r1,42
</C>
</CODE>
</INITGLOBALS>
<BLOCK NAME="main" ADDRESS="null" ALIGN="NONE" POS="[examples/test.p8: line 2 col 2-5]">
<SUB NAME="main.start" RETURNTYPE="null" POS="[examples/test.p8: line 4 col 6-8]">
<PARAMS>
</PARAMS>
<C LABEL="main.start">
<CODE LABEL="main.start">
return
</C>
</CODE>
</SUB>
</BLOCK>
@ -92,9 +92,9 @@ uword sys.wait.jiffies
loadm.w r0,sys.wait.jiffies
syscall 13
</INLINEASM>
<C>
<CODE>
return
</C>
</CODE>
</SUB>
</BLOCK>
</PROGRAM>

View File

@ -41,6 +41,9 @@ class VmProgramLoader {
val replacement = addAssemblyToProgram(it, programChunks, variableAddresses)
chunkReplacements += replacement
}
block.labels.forEach {
programChunks += it // TODO doing it like this isn't useful, block needs to have a list of nodes rather than a few separate collections
}
block.subroutines.forEach {
it.chunks.forEach { chunk ->
when (chunk) {