mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
weird condition operator...
This commit is contained in:
parent
c8d0bf27af
commit
374464a1f8
@ -33,9 +33,9 @@ class SymbolTable(astProgram: PtProgram) : StNode(astProgram.name, StNodeType.GL
|
||||
return result
|
||||
}
|
||||
|
||||
// fun resetCachedFlat() {
|
||||
// cachedFlat = null
|
||||
// }
|
||||
fun resetCachedFlat() {
|
||||
cachedFlat = null
|
||||
}
|
||||
|
||||
val allVariables: Collection<StStaticVariable> by lazy {
|
||||
val vars = mutableListOf<StStaticVariable>()
|
||||
|
@ -1174,30 +1174,29 @@ $repeatLabel lda $counterVar
|
||||
|
||||
private fun translateCompareAndJumpIfTrueRPN(expr: PtRpn, jump: PtJump) {
|
||||
val (left, oper, right) = expr.finalOperation()
|
||||
if(expr.children.size>3) {
|
||||
TODO("RPN comparison too complex ${expr.position}")
|
||||
}
|
||||
|
||||
require(left is PtExpression && right is PtExpression)
|
||||
|
||||
if(oper.operator !in ComparisonOperators)
|
||||
throw AssemblyError("must be comparison expression")
|
||||
if(expr.children.size>3) {
|
||||
TODO("RPN comparison too complex ${expr.position} - split off the comparison + compare value")
|
||||
}
|
||||
|
||||
// invert the comparison, so we can reuse the JumpIfFalse code generation routines
|
||||
val invertedComparisonOperator = invertedComparisonOperator(oper.operator)
|
||||
?: throw AssemblyError("can't invert comparison $expr")
|
||||
|
||||
val rightConstVal = right as? PtNumber
|
||||
|
||||
val label = when {
|
||||
jump.generatedLabel!=null -> jump.generatedLabel!!
|
||||
jump.identifier!=null -> asmSymbolName(jump.identifier!!)
|
||||
jump.address!=null -> jump.address!!.toHex()
|
||||
else -> throw AssemblyError("weird jump")
|
||||
}
|
||||
if (rightConstVal!=null && rightConstVal.number == 0.0)
|
||||
val rightConstVal = right as? PtNumber
|
||||
if (rightConstVal!=null && rightConstVal.number == 0.0) {
|
||||
require(left is PtExpression)
|
||||
testZeroAndJump(left, invertedComparisonOperator, label)
|
||||
}
|
||||
else {
|
||||
require(left is PtExpression && right is PtExpression)
|
||||
val leftConstVal = left as? PtNumber
|
||||
testNonzeroComparisonAndJump(left, invertedComparisonOperator, right, label, leftConstVal, rightConstVal)
|
||||
}
|
||||
@ -1206,7 +1205,7 @@ $repeatLabel lda $counterVar
|
||||
private fun translateCompareAndJumpIfFalseRPN(expr: PtRpn, jumpIfFalseLabel: String) {
|
||||
val (left, oper, right) = expr.finalOperation()
|
||||
if(expr.children.size>3) {
|
||||
TODO("RPN comparison too complex ${expr.position}")
|
||||
TODO("RPN comparison too complex ${expr.position} - split off the comparison + compare value")
|
||||
}
|
||||
|
||||
require(left is PtExpression && right is PtExpression)
|
||||
|
@ -365,7 +365,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
private fun attemptAssignOptimizedExprRPN(assign: AsmAssignment, scope: IPtSubroutine): Boolean {
|
||||
val value = assign.source.expression as PtRpn
|
||||
val (left, oper, right) = value.finalOperation()
|
||||
if(oper.operator in ComparisonOperators) {
|
||||
|
||||
// TODO RPN the fallthrough if size>3 seems to generate not 100% correct code... (balls example fills the screen weird)
|
||||
if(value.children.size==3 && oper.operator in ComparisonOperators) {
|
||||
assignRPNComparison(assign, value)
|
||||
return true
|
||||
}
|
||||
@ -424,19 +426,18 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
value.children.forEach {
|
||||
when (it) {
|
||||
is PtRpnOperator -> {
|
||||
val varDt = getVarDt(it.type)
|
||||
val rightvar = evalVars.getValue(varDt).pop()
|
||||
val leftvar = evalVars.getValue(varDt).pop()
|
||||
val rightvar = evalVars.getValue(getVarDt(it.rightType)).pop()
|
||||
val leftvar = evalVars.getValue(getVarDt(it.leftType)).pop()
|
||||
depth-=2
|
||||
val resultVarname = evalVarName(it.type, depth)
|
||||
depth++
|
||||
require(resultVarname==leftvar)
|
||||
// TODO no longer needed? symbolTable.resetCachedFlat()
|
||||
symbolTable.resetCachedFlat()
|
||||
if(it.operator in ComparisonOperators) {
|
||||
val scopeName = (scope as PtNamedNode).scopedName
|
||||
val comparison = PtRpn(DataType.UBYTE, assign.position)
|
||||
comparison.addRpnNode(PtIdentifier("$scopeName.$resultVarname", it.type, value.position))
|
||||
comparison.addRpnNode(PtIdentifier("$scopeName.$rightvar", it.type, value.position))
|
||||
comparison.addRpnNode(PtIdentifier("$scopeName.$rightvar", it.rightType, value.position))
|
||||
comparison.addRpnNode(PtRpnOperator(it.operator, it.type, it.leftType, it.rightType, it.position))
|
||||
comparison.parent = scope
|
||||
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.UBYTE, expression = comparison)
|
||||
@ -577,7 +578,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
else -> throw AssemblyError("invalid dt")
|
||||
}
|
||||
asmgen.out(jumpIfFalseLabel)
|
||||
asmgen.out("; cmp done")
|
||||
}
|
||||
|
||||
private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
||||
|
@ -1,10 +1,12 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
BRANCH: balls.p8 directions are wrong since the comparison operator fallthrough in attemptAssignOptimizedExprRPN
|
||||
BRANCH: Fix the TODO RPN routines to be optimized assembly in RpnExpressionAsmGen.kt
|
||||
BRANCH: check BinExprSplitter disablement any effect for RPN?
|
||||
BRANCH: Implement RPN codegen for IR.
|
||||
|
||||
|
||||
For next minor release
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
|
@ -6,12 +6,15 @@
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
ubyte[255] BC
|
||||
bool[255] DX
|
||||
; ubyte[255] BC
|
||||
; bool[255] DX
|
||||
|
||||
BC[2] = math.rnd() & 15
|
||||
BC[3] = math.rnd() & 15
|
||||
BC[4] = math.rnd() & 15
|
||||
if math.rnd() & 22 {
|
||||
cx16.r0L++
|
||||
}
|
||||
; BC[2] = math.rnd() & 15
|
||||
; BC[3] = math.rnd() & 15
|
||||
; BC[4] = math.rnd() & 15
|
||||
;DX[2] = math.rnd() & 1
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user