mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
ir: store labels in blocks, but still useless
This commit is contained in:
parent
d8e87bd881
commit
91fdb3e2d4
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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()}")
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user