mirror of
https://github.com/irmen/prog8.git
synced 2024-09-10 09:54:32 +00:00
IR: optimized when statement translation
This commit is contained in:
parent
b3cb9b7fe2
commit
c1aa5d4e47
@ -399,42 +399,35 @@ class IRCodeGen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(whenStmt: PtWhen): IRCodeChunks {
|
private fun translate(whenStmt: PtWhen): IRCodeChunks {
|
||||||
if(whenStmt.choices.children.isEmpty())
|
|
||||||
return emptyList()
|
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val valueDt = irType(whenStmt.value.type)
|
val valueDt = irType(whenStmt.value.type)
|
||||||
val valueTr = expressionEval.translateExpression(whenStmt.value)
|
val valueTr = expressionEval.translateExpression(whenStmt.value)
|
||||||
addToResult(result, valueTr, valueTr.resultReg, -1)
|
addToResult(result, valueTr, valueTr.resultReg, -1)
|
||||||
val choices = whenStmt.choices.children.map {it as PtWhenChoice }
|
|
||||||
|
val choices = mutableListOf<Pair<String, PtWhenChoice>>()
|
||||||
val endLabel = createLabelName()
|
val endLabel = createLabelName()
|
||||||
for (choice in choices) {
|
whenStmt.choices.children.forEach {
|
||||||
|
val choice = it as PtWhenChoice
|
||||||
if(choice.isElse) {
|
if(choice.isElse) {
|
||||||
result += translateNode(choice.statements)
|
result += translateNode(choice.statements)
|
||||||
} else {
|
|
||||||
val skipLabel = createLabelName()
|
|
||||||
val values = choice.values.children.map {it as PtNumber}
|
|
||||||
if(values.size==1) {
|
|
||||||
val chunk = IRCodeChunk(null, null)
|
|
||||||
chunk += IRInstruction(Opcode.BNE, valueDt, reg1=valueTr.resultReg, immediate = values[0].number.toInt(), labelSymbol = skipLabel)
|
|
||||||
result += chunk
|
|
||||||
result += translateNode(choice.statements)
|
|
||||||
if(choice.statements.children.last() !is PtReturn)
|
|
||||||
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
|
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
|
||||||
} else {
|
} else {
|
||||||
val matchLabel = createLabelName()
|
val choiceLabel = createLabelName()
|
||||||
val chunk = IRCodeChunk(null, null)
|
choices.add(choiceLabel to choice)
|
||||||
for (value in values) {
|
choice.values.children.map { it as PtNumber }.sortedBy { it.number }.forEach { value ->
|
||||||
chunk += IRInstruction(Opcode.BEQ, valueDt, reg1=valueTr.resultReg, immediate = value.number.toInt(), labelSymbol = matchLabel)
|
addInstr(result, IRInstruction(Opcode.BEQ, valueDt, reg1=valueTr.resultReg, immediate = value.number.toInt(), labelSymbol = choiceLabel), null)
|
||||||
}
|
}
|
||||||
chunk += IRInstruction(Opcode.JUMP, labelSymbol = skipLabel)
|
}
|
||||||
result += chunk
|
}
|
||||||
result += labelFirstChunk(translateNode(choice.statements), matchLabel)
|
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
|
||||||
if(choice.statements.children.last() !is PtReturn)
|
|
||||||
|
choices.forEach { (label, choice) ->
|
||||||
|
result += labelFirstChunk(translateNode(choice.statements), label)
|
||||||
|
val lastStatement = choice.statements.children.last()
|
||||||
|
if(lastStatement !is PtReturn && lastStatement !is PtJump)
|
||||||
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
|
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
|
||||||
}
|
}
|
||||||
result += IRCodeChunk(skipLabel, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result += IRCodeChunk(endLabel, null)
|
result += IRCodeChunk(endLabel, null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,27 @@ main
|
|||||||
{
|
{
|
||||||
sub start()
|
sub start()
|
||||||
{
|
{
|
||||||
ubyte a=1
|
ubyte res
|
||||||
ubyte b=2
|
ubyte val=3
|
||||||
ubyte c=3
|
when val*10 {
|
||||||
ubyte d=4
|
1 -> res=1
|
||||||
|
10 -> res=10
|
||||||
|
20 -> res=20
|
||||||
|
30 -> res=30
|
||||||
|
40 -> res=40
|
||||||
|
else -> res=0
|
||||||
|
}
|
||||||
|
|
||||||
ubyte xx = (a*b)+(c*d)
|
txt.print_ub(res) ; 30
|
||||||
xx++
|
txt.nl()
|
||||||
|
|
||||||
|
when val {
|
||||||
|
5,7,9,1,3 -> res=100
|
||||||
|
2,4,6,8 -> res=200
|
||||||
|
else -> res=0
|
||||||
|
}
|
||||||
|
|
||||||
|
txt.print_ub(res) ; 100
|
||||||
|
; 102 instructions, 31 registers, 122 steps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user