diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 2e78ab2f0..3eaf99e04 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -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") diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index a1f9d6220..bd5ef3a45 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -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() } } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt index 9122b52ad..5271e7d44 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt @@ -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") diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 685ee9834..4d7a675cf 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -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() } diff --git a/compiler/res/prog8lib/prog8_lib.asm b/compiler/res/prog8lib/prog8_lib.asm index 61bc6d23f..a3aa523f5 100644 --- a/compiler/res/prog8lib/prog8_lib.asm +++ b/compiler/res/prog8lib/prog8_lib.asm @@ -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). diff --git a/examples/test.p8 b/examples/test.p8 index d807b8d55..f4643c441 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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