fix RPN string comparisons

This commit is contained in:
Irmen de Jong 2023-03-18 16:48:11 +01:00
parent 3a272e998d
commit 3613162d09
6 changed files with 41 additions and 8 deletions

View File

@ -1013,7 +1013,7 @@ $repeatLabel lda $counterVar
when (pointerOffsetExpr) {
is PtRpn -> {
if(pointerOffsetExpr.children.size>3) {
println("TODO: RPN: too complicated pointerViaIndexRegisterPossible") // TODO RPN
println("TODO: RPN: too complicated pointerViaIndexRegisterPossible") // TODO RPN: split expression?
return null // expression is too complex, we need just a pointer var + index
}
val (leftNode, oper, rightNode) = pointerOffsetExpr.finalOperation()
@ -2911,7 +2911,7 @@ $repeatLabel lda $counterVar
is PtRpn -> {
val addrExpr = expr.address as PtRpn
if(addrExpr.children.size>3)
println("TODO: RPN: too complicated translateDirectMemReadExpressionToRegAorStack") // TODO RPN
println("TODO: RPN: too complicated translateDirectMemReadExpressionToRegAorStack") // TODO RPN: split expression?
if(addrExpr.children.size==3 && tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) {
if(pushResultOnEstack)
out(" sta P8ESTACK_LO,x | dex")

View File

@ -683,7 +683,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
}
}
} else {
println("TODO: RPN: too complicated PokeW") // TODO RPN
println("TODO: RPN: too complicated PokeW") // TODO RPN: split expression?
}
}
is PtBinaryExpression -> {
@ -766,7 +766,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
} else fallback()
} else fallback()
} else {
println("TODO: RPN: too complicated PeekW") // TODO RPN
println("TODO: RPN: too complicated PeekW") // TODO RPN: split expression?
fallback()
}
}

View File

@ -287,8 +287,14 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
if(it is PtRpnOperator) {
when(it.leftType) {
in ByteDatatypes -> translateBinaryOperatorBytes(it.operator, it.leftType)
in WordDatatypes, in PassByReferenceDatatypes -> translateBinaryOperatorWords(it.operator, it.leftType)
in WordDatatypes -> translateBinaryOperatorWords(it.operator, it.leftType)
DataType.FLOAT -> translateBinaryOperatorFloats(it.operator)
DataType.STR -> {
if(it.operator !in ComparisonOperators)
throw AssemblyError("expected only comparison operators on string, not ${oper.operator}")
asmgen.out(" jsr prog8_lib.strcmp_stack")
compareStringsProcessResultInA(it.operator)
}
else -> throw AssemblyError("non-numerical datatype ${it.leftType}")
}
depth--
@ -947,6 +953,10 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
asmgen.assignExpressionToVariable(s1, "prog8_lib.strcmp_expression._arg_s1", DataType.UWORD, null)
asmgen.assignExpressionToVariable(s2, "prog8_lib.strcmp_expression._arg_s2", DataType.UWORD, null)
asmgen.out(" jsr prog8_lib.strcmp_expression") // result of compare is in A
compareStringsProcessResultInA(operator)
}
private fun compareStringsProcessResultInA(operator: String) {
when(operator) {
"==" -> asmgen.out(" and #1 | eor #1 | sta P8ESTACK_LO,x")
"!=" -> asmgen.out(" and #1 | sta P8ESTACK_LO,x")

View File

@ -147,7 +147,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
is PtRpn -> {
val addrExpr = value.address as PtRpn
if(addrExpr.children.size>3)
println("TODO: RPN: too complex translateNormalAssignment") // TODO RPN
println("TODO: RPN: too complex translateNormalAssignment") // TODO RPN: split expression?
if(addrExpr.children.size==3 && asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) {
assignRegisterByte(assign.target, CpuRegister.A)
} else {
@ -927,7 +927,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
is PtRpn -> {
val addrExpr = value.address as PtRpn
if(addrExpr.children.size>3) {
println("TODO: RPN: too complex assignTypeCastedValue") // TODO RPN
println("TODO: RPN: too complex assignTypeCastedValue") // TODO RPN : split expression?
}
if(addrExpr.children.size==3 && asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) {
asmgen.out(" ldy #0")
@ -2860,7 +2860,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
addressExpr is PtRpn -> {
if(addressExpr.children.size>3)
println("TODO: RPN: too complex storeRegisterAInMemoryAddress $memoryAddress") // TODO RPN
println("TODO: RPN: too complex storeRegisterAInMemoryAddress $memoryAddress") // TODO RPN: split expression?
if(addressExpr.children.size!=3 || !asmgen.tryOptimizedPointerAccessWithA(addressExpr, addressExpr.finalOperator().operator, true))
storeViaExprEval()
}

View File

@ -997,6 +997,20 @@ _arg_s1 .word 0
_arg_s2 .word 0
.pend
strcmp_stack .proc
; -- compare strings, both on stack.
; Returns -1,0,1 in A, depeding on the ordering. Clobbers Y.
inx
lda P8ESTACK_LO,x
ldy P8ESTACK_HI,x
sta P8ZP_SCRATCH_W2
sty P8ZP_SCRATCH_W2+1
inx
lda P8ESTACK_LO,x
ldy P8ESTACK_HI,x
jmp strcmp_mem
.pend
strcmp_mem .proc
; -- compares strings in s1 (AY) and s2 (P8ZP_SCRATCH_W2).

View File

@ -9,6 +9,15 @@ main {
sub start() {
test_stack.test()
str name = "irmen"
name[3] = 0
if name==".asm" or name=="irm" or name==".src"
txt.print("ok\n")
else
txt.print("fail\n")
uword xx=4000
ubyte a
ubyte b