weird condition operator...

This commit is contained in:
Irmen de Jong 2023-03-19 01:12:48 +01:00
parent c8d0bf27af
commit 374464a1f8
5 changed files with 29 additions and 25 deletions

View File

@ -33,9 +33,9 @@ class SymbolTable(astProgram: PtProgram) : StNode(astProgram.name, StNodeType.GL
return result return result
} }
// fun resetCachedFlat() { fun resetCachedFlat() {
// cachedFlat = null cachedFlat = null
// } }
val allVariables: Collection<StStaticVariable> by lazy { val allVariables: Collection<StStaticVariable> by lazy {
val vars = mutableListOf<StStaticVariable>() val vars = mutableListOf<StStaticVariable>()

View File

@ -1174,30 +1174,29 @@ $repeatLabel lda $counterVar
private fun translateCompareAndJumpIfTrueRPN(expr: PtRpn, jump: PtJump) { private fun translateCompareAndJumpIfTrueRPN(expr: PtRpn, jump: PtJump) {
val (left, oper, right) = expr.finalOperation() 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) if(oper.operator !in ComparisonOperators)
throw AssemblyError("must be comparison expression") 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 // invert the comparison, so we can reuse the JumpIfFalse code generation routines
val invertedComparisonOperator = invertedComparisonOperator(oper.operator) val invertedComparisonOperator = invertedComparisonOperator(oper.operator)
?: throw AssemblyError("can't invert comparison $expr") ?: throw AssemblyError("can't invert comparison $expr")
val rightConstVal = right as? PtNumber
val label = when { val label = when {
jump.generatedLabel!=null -> jump.generatedLabel!! jump.generatedLabel!=null -> jump.generatedLabel!!
jump.identifier!=null -> asmSymbolName(jump.identifier!!) jump.identifier!=null -> asmSymbolName(jump.identifier!!)
jump.address!=null -> jump.address!!.toHex() jump.address!=null -> jump.address!!.toHex()
else -> throw AssemblyError("weird jump") 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) testZeroAndJump(left, invertedComparisonOperator, label)
}
else { else {
require(left is PtExpression && right is PtExpression)
val leftConstVal = left as? PtNumber val leftConstVal = left as? PtNumber
testNonzeroComparisonAndJump(left, invertedComparisonOperator, right, label, leftConstVal, rightConstVal) testNonzeroComparisonAndJump(left, invertedComparisonOperator, right, label, leftConstVal, rightConstVal)
} }
@ -1206,7 +1205,7 @@ $repeatLabel lda $counterVar
private fun translateCompareAndJumpIfFalseRPN(expr: PtRpn, jumpIfFalseLabel: String) { private fun translateCompareAndJumpIfFalseRPN(expr: PtRpn, jumpIfFalseLabel: String) {
val (left, oper, right) = expr.finalOperation() val (left, oper, right) = expr.finalOperation()
if(expr.children.size>3) { 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) require(left is PtExpression && right is PtExpression)

View File

@ -365,7 +365,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
private fun attemptAssignOptimizedExprRPN(assign: AsmAssignment, scope: IPtSubroutine): Boolean { private fun attemptAssignOptimizedExprRPN(assign: AsmAssignment, scope: IPtSubroutine): Boolean {
val value = assign.source.expression as PtRpn val value = assign.source.expression as PtRpn
val (left, oper, right) = value.finalOperation() 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) assignRPNComparison(assign, value)
return true return true
} }
@ -424,19 +426,18 @@ internal class AssignmentAsmGen(private val program: PtProgram,
value.children.forEach { value.children.forEach {
when (it) { when (it) {
is PtRpnOperator -> { is PtRpnOperator -> {
val varDt = getVarDt(it.type) val rightvar = evalVars.getValue(getVarDt(it.rightType)).pop()
val rightvar = evalVars.getValue(varDt).pop() val leftvar = evalVars.getValue(getVarDt(it.leftType)).pop()
val leftvar = evalVars.getValue(varDt).pop()
depth-=2 depth-=2
val resultVarname = evalVarName(it.type, depth) val resultVarname = evalVarName(it.type, depth)
depth++ depth++
require(resultVarname==leftvar) require(resultVarname==leftvar)
// TODO no longer needed? symbolTable.resetCachedFlat() symbolTable.resetCachedFlat()
if(it.operator in ComparisonOperators) { if(it.operator in ComparisonOperators) {
val scopeName = (scope as PtNamedNode).scopedName val scopeName = (scope as PtNamedNode).scopedName
val comparison = PtRpn(DataType.UBYTE, assign.position) val comparison = PtRpn(DataType.UBYTE, assign.position)
comparison.addRpnNode(PtIdentifier("$scopeName.$resultVarname", it.type, value.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.addRpnNode(PtRpnOperator(it.operator, it.type, it.leftType, it.rightType, it.position))
comparison.parent = scope comparison.parent = scope
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.UBYTE, expression = comparison) 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") else -> throw AssemblyError("invalid dt")
} }
asmgen.out(jumpIfFalseLabel) asmgen.out(jumpIfFalseLabel)
asmgen.out("; cmp done")
} }
private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean { private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {

View File

@ -1,10 +1,12 @@
TODO 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: Fix the TODO RPN routines to be optimized assembly in RpnExpressionAsmGen.kt
BRANCH: check BinExprSplitter disablement any effect for RPN? BRANCH: check BinExprSplitter disablement any effect for RPN?
BRANCH: Implement RPN codegen for IR. BRANCH: Implement RPN codegen for IR.
For next minor release For next minor release
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
... ...

View File

@ -6,12 +6,15 @@
main { main {
sub start() { sub start() {
ubyte[255] BC ; ubyte[255] BC
bool[255] DX ; bool[255] DX
BC[2] = math.rnd() & 15 if math.rnd() & 22 {
BC[3] = math.rnd() & 15 cx16.r0L++
BC[4] = math.rnd() & 15 }
; BC[2] = math.rnd() & 15
; BC[3] = math.rnd() & 15
; BC[4] = math.rnd() & 15
;DX[2] = math.rnd() & 1 ;DX[2] = math.rnd() & 1
} }
} }