mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 22:30:46 +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)
|
processAst(program, args.errors, compilationOptions)
|
||||||
if (compilationOptions.optimize) {
|
if (compilationOptions.optimize) {
|
||||||
// println("*********** AST RIGHT BEFORE OPTIMIZING *************")
|
// println("*********** COMPILER AST RIGHT BEFORE OPTIMIZING *************")
|
||||||
// printProgram(program)
|
// printProgram(program)
|
||||||
|
|
||||||
optimizeAst(
|
optimizeAst(
|
||||||
@ -108,7 +108,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
|||||||
}
|
}
|
||||||
postprocessAst(program, args.errors, compilationOptions)
|
postprocessAst(program, args.errors, compilationOptions)
|
||||||
|
|
||||||
// println("*********** AST BEFORE ASSEMBLYGEN *************")
|
// println("*********** COMPILER AST BEFORE ASSEMBLYGEN *************")
|
||||||
// printProgram(program)
|
// printProgram(program)
|
||||||
|
|
||||||
determineProgramLoadAddress(program, compilationOptions, args.errors)
|
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.
|
// to help clean up the code that still depends on them.
|
||||||
// removeAllVardeclsFromAst(program)
|
// removeAllVardeclsFromAst(program)
|
||||||
|
|
||||||
// println("*********** AST RIGHT BEFORE ASM GENERATION *************")
|
// println("*********** COMPILER AST RIGHT BEFORE ASM GENERATION *************")
|
||||||
// printProgram(program)
|
// printProgram(program)
|
||||||
|
|
||||||
val assembly = asmGeneratorFor(program, errors, symbolTable, compilerOptions).compileToAssembly()
|
val assembly = asmGeneratorFor(program, errors, symbolTable, compilerOptions).compileToAssembly()
|
||||||
|
@ -3,8 +3,9 @@ TODO
|
|||||||
|
|
||||||
For next release
|
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
|
- 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)
|
- 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.
|
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
|
- 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 {
|
private fun parseCodeChunk(reader: XMLEventReader): IRCodeChunk {
|
||||||
skipText(reader)
|
skipText(reader)
|
||||||
val start = reader.nextEvent().asStartElement()
|
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 label = start.attributes.asSequence().singleOrNull { it.name.localPart == "LABEL" }?.value?.ifBlank { null }
|
||||||
val text = readText(reader).trim()
|
val text = readText(reader).trim()
|
||||||
val chunk = IRCodeChunk(label, null)
|
val chunk = IRCodeChunk(label, null)
|
||||||
@ -321,6 +321,12 @@ class IRFileReader {
|
|||||||
"ASMSUB" -> block += parseAsmSubroutine(reader)
|
"ASMSUB" -> block += parseAsmSubroutine(reader)
|
||||||
"INLINEASM" -> block += parseInlineAssembly(reader)
|
"INLINEASM" -> block += parseInlineAssembly(reader)
|
||||||
"BYTES" -> block += parseBinaryBytes(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()}")
|
else -> throw IRParseException("invalid line in BLOCK: ${reader.peek()}")
|
||||||
}
|
}
|
||||||
skipText(reader)
|
skipText(reader)
|
||||||
@ -344,7 +350,7 @@ class IRFileReader {
|
|||||||
skipText(reader)
|
skipText(reader)
|
||||||
while(reader.peek().isStartElement) {
|
while(reader.peek().isStartElement) {
|
||||||
when(reader.peek().asStartElement().name.localPart) {
|
when(reader.peek().asStartElement().name.localPart) {
|
||||||
"C" -> sub += parseCodeChunk(reader)
|
"CODE" -> sub += parseCodeChunk(reader)
|
||||||
"BYTES" -> sub += parseBinaryBytes(reader)
|
"BYTES" -> sub += parseBinaryBytes(reader)
|
||||||
"INLINEASM" -> sub += parseInlineAssembly(reader)
|
"INLINEASM" -> sub += parseInlineAssembly(reader)
|
||||||
else -> throw IRParseException("invalid line in SUB: ${reader.peek()}")
|
else -> throw IRParseException("invalid line in SUB: ${reader.peek()}")
|
||||||
|
@ -49,6 +49,9 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
|||||||
block.inlineAssemblies.forEach {
|
block.inlineAssemblies.forEach {
|
||||||
writeInlineAsm(it)
|
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 {
|
block.subroutines.forEach {
|
||||||
out.write("<SUB NAME=\"${it.name}\" RETURNTYPE=\"${it.returnType.toString().lowercase()}\" POS=\"${it.position}\">\n")
|
out.write("<SUB NAME=\"${it.name}\" RETURNTYPE=\"${it.returnType.toString().lowercase()}\" POS=\"${it.position}\">\n")
|
||||||
out.write("<PARAMS>\n")
|
out.write("<PARAMS>\n")
|
||||||
@ -91,15 +94,15 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
|||||||
|
|
||||||
private fun writeCodeChunk(chunk: IRCodeChunk) {
|
private fun writeCodeChunk(chunk: IRCodeChunk) {
|
||||||
if(chunk.label!=null)
|
if(chunk.label!=null)
|
||||||
out.write("<C LABEL=\"${chunk.label}\">\n")
|
out.write("<CODE LABEL=\"${chunk.label}\">\n")
|
||||||
else
|
else
|
||||||
out.write("<C>\n")
|
out.write("<CODE>\n")
|
||||||
chunk.instructions.forEach { instr ->
|
chunk.instructions.forEach { instr ->
|
||||||
numInstr++
|
numInstr++
|
||||||
out.write(instr.toString())
|
out.write(instr.toString())
|
||||||
out.write("\n")
|
out.write("\n")
|
||||||
}
|
}
|
||||||
out.write("</C>\n")
|
out.write("</CODE>\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun writeInlineBytes(chunk: IRInlineBinaryChunk) {
|
private fun writeInlineBytes(chunk: IRInlineBinaryChunk) {
|
||||||
|
@ -209,6 +209,7 @@ class IRBlock(
|
|||||||
val subroutines = mutableListOf<IRSubroutine>()
|
val subroutines = mutableListOf<IRSubroutine>()
|
||||||
val asmSubroutines = mutableListOf<IRAsmSubroutine>()
|
val asmSubroutines = mutableListOf<IRAsmSubroutine>()
|
||||||
val inlineBinaries = mutableListOf<IRInlineBinaryChunk>()
|
val inlineBinaries = mutableListOf<IRInlineBinaryChunk>()
|
||||||
|
val labels = mutableListOf<IRCodeChunk>() // empty code chunks having just a label.
|
||||||
|
|
||||||
enum class BlockAlignment {
|
enum class BlockAlignment {
|
||||||
NONE,
|
NONE,
|
||||||
@ -225,7 +226,7 @@ class IRBlock(
|
|||||||
operator fun plusAssign(irCodeChunk: IRCodeChunk) {
|
operator fun plusAssign(irCodeChunk: IRCodeChunk) {
|
||||||
// this is for a separate label in the block scope. (random code statements are not allowed)
|
// this is for a separate label in the block scope. (random code statements are not allowed)
|
||||||
require(irCodeChunk.isEmpty() && irCodeChunk.label!=null)
|
require(irCodeChunk.isEmpty() && irCodeChunk.label!=null)
|
||||||
TODO("allow labels in block scope, ${irCodeChunk.label}")
|
labels += irCodeChunk
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isEmpty(): Boolean {
|
fun isEmpty(): Boolean {
|
||||||
|
@ -68,18 +68,18 @@ uword sys.wait.jiffies= zp=DONTCARE
|
|||||||
</MEMORYSLABS>
|
</MEMORYSLABS>
|
||||||
|
|
||||||
<INITGLOBALS>
|
<INITGLOBALS>
|
||||||
<C>
|
<CODE>
|
||||||
load.b r1,42
|
load.b r1,42
|
||||||
</C>
|
</CODE>
|
||||||
</INITGLOBALS>
|
</INITGLOBALS>
|
||||||
|
|
||||||
<BLOCK NAME="main" ADDRESS="null" ALIGN="NONE" POS="[examples/test.p8: line 2 col 2-5]">
|
<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]">
|
<SUB NAME="main.start" RETURNTYPE="null" POS="[examples/test.p8: line 4 col 6-8]">
|
||||||
<PARAMS>
|
<PARAMS>
|
||||||
</PARAMS>
|
</PARAMS>
|
||||||
<C LABEL="main.start">
|
<CODE LABEL="main.start">
|
||||||
return
|
return
|
||||||
</C>
|
</CODE>
|
||||||
</SUB>
|
</SUB>
|
||||||
</BLOCK>
|
</BLOCK>
|
||||||
|
|
||||||
@ -92,9 +92,9 @@ uword sys.wait.jiffies
|
|||||||
loadm.w r0,sys.wait.jiffies
|
loadm.w r0,sys.wait.jiffies
|
||||||
syscall 13
|
syscall 13
|
||||||
</INLINEASM>
|
</INLINEASM>
|
||||||
<C>
|
<CODE>
|
||||||
return
|
return
|
||||||
</C>
|
</CODE>
|
||||||
</SUB>
|
</SUB>
|
||||||
</BLOCK>
|
</BLOCK>
|
||||||
</PROGRAM>
|
</PROGRAM>
|
||||||
|
@ -41,6 +41,9 @@ class VmProgramLoader {
|
|||||||
val replacement = addAssemblyToProgram(it, programChunks, variableAddresses)
|
val replacement = addAssemblyToProgram(it, programChunks, variableAddresses)
|
||||||
chunkReplacements += replacement
|
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 {
|
block.subroutines.forEach {
|
||||||
it.chunks.forEach { chunk ->
|
it.chunks.forEach { chunk ->
|
||||||
when (chunk) {
|
when (chunk) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user