diff --git a/compiler/res/prog8lib/prog8_lib.asm b/compiler/res/prog8lib/prog8_lib.asm index 6049537a9..805e7aa99 100644 --- a/compiler/res/prog8lib/prog8_lib.asm +++ b/compiler/res/prog8lib/prog8_lib.asm @@ -2133,8 +2133,6 @@ _startloop dey func_strcmp .proc - ; -- compares strings in s1 (AY) and s2 (P8ZP_SCRATCH_W2). - ; Returns -1,0,1 in A, depeding on the ordering. Clobbers Y. inx lda P8ESTACK_LO,x sta P8ZP_SCRATCH_W2 diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt index 52c6de893..2786d743c 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt @@ -90,7 +90,9 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge in ByteDatatypes -> translateByteEquals(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) in WordDatatypes -> translateWordEquals(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) DataType.FLOAT -> translateFloatEquals(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.STR -> throw AssemblyError("can't perform string comparison here") + DataType.STR -> { + TODO("strcmp ==") + } else -> throw AssemblyError("weird operand datatype") } } @@ -132,7 +134,9 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge in ByteDatatypes -> translateByteNotEquals(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) in WordDatatypes -> translateWordNotEquals(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) DataType.FLOAT -> translateFloatNotEquals(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.STR -> throw AssemblyError("can't perform string comparison here") + DataType.STR -> { + TODO("strcmp !=") + } else -> throw AssemblyError("weird operand datatype") } } @@ -147,7 +151,9 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge translateExpression(right) asmgen.out(" jsr floats.less_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") } - DataType.STR -> throw AssemblyError("can't perform string lt") + DataType.STR -> { + TODO("strcmp <") + } else -> throw AssemblyError("weird operand datatype") } } @@ -162,7 +168,9 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge translateExpression(right) asmgen.out(" jsr floats.lesseq_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") } - DataType.STR -> throw AssemblyError("can't perform string le") + DataType.STR -> { + TODO("strcmp <=") + } else -> throw AssemblyError("weird operand datatype") } } @@ -177,7 +185,9 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge translateExpression(right) asmgen.out(" jsr floats.greater_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") } - DataType.STR -> throw AssemblyError("can't perform string gt") + DataType.STR -> { + TODO("strcmp >") + } else -> throw AssemblyError("weird operand datatype") } } @@ -192,7 +202,9 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge translateExpression(right) asmgen.out(" jsr floats.greatereq_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") } - DataType.STR -> throw AssemblyError("can't perform string ge") + DataType.STR -> { + TODO("strcmp >=") + } else -> throw AssemblyError("weird operand datatype") } } @@ -1274,11 +1286,16 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge || (leftDt in WordDatatypes && rightDt !in WordDatatypes)) throw AssemblyError("binary operator ${expr.operator} left/right dt not identical") - when (leftDt) { - in ByteDatatypes -> translateBinaryOperatorBytes(expr.operator, leftDt) - in WordDatatypes -> translateBinaryOperatorWords(expr.operator, leftDt) - DataType.FLOAT -> translateBinaryOperatorFloats(expr.operator) - else -> throw AssemblyError("non-numerical datatype") + if(leftDt==DataType.STR && rightDt==DataType.STR && expr.operator in comparisonOperators) { + translateCompareStrings(expr.operator) + } + else { + when (leftDt) { + in ByteDatatypes -> translateBinaryOperatorBytes(expr.operator, leftDt) + in WordDatatypes -> translateBinaryOperatorWords(expr.operator, leftDt) + DataType.FLOAT -> translateBinaryOperatorFloats(expr.operator) + else -> throw AssemblyError("non-numerical datatype") + } } } @@ -1450,4 +1467,36 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge else -> throw AssemblyError("invalid operator $operator") } } + + private fun translateCompareStrings(operator: String) { + asmgen.out(" jsr prog8_lib.func_strcmp | lda P8ESTACK_LO+1,x") // result of compare in A + when(operator) { + "==" -> asmgen.out(" and #1 | eor #1 | sta P8ESTACK_LO+1,x") + "!=" -> asmgen.out(" and #1 | sta P8ESTACK_LO+1,x") + "<=" -> asmgen.out(""" + bpl + + lda #1 + bne ++ ++ lda #0 ++ sta P8ESTACK_LO+1,x""") + ">=" -> asmgen.out(""" + bmi + + lda #1 + bne ++ ++ lda #0 ++ sta P8ESTACK_LO+1,x""") + "<" -> asmgen.out(""" + bmi + + lda #0 + beq ++ ++ lda #1 ++ sta P8ESTACK_LO+1,x""") + ">" -> asmgen.out(""" + bpl + + lda #0 + beq ++ ++ lda #1 ++ sta P8ESTACK_LO+1,x""") + } + } } diff --git a/examples/test.p8 b/examples/test.p8 index 8d711e5ca..be26b7f13 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -12,18 +12,67 @@ main { str hex3 = "aap1JE" str hex4 = "aap3333" - byte result - result = strcmp(hex1, hex1) - txt.print_b(result) +; byte result +; result = strcmp(hex1, hex1) +; txt.print_b(result) +; txt.chrout('\n') +; result = strcmp(hex1, hex1) +; txt.print_b(result) +; txt.chrout('\n') +; result = strcmp(hex1, hex2) +; txt.print_b(result) +; txt.chrout('\n') +; result = strcmp(hex1, hex3) +; txt.print_b(result) +; txt.chrout('\n') +; result = strcmp(hex1, hex4) +; txt.print_b(result) +; txt.chrout('\n') +; txt.chrout('\n') + + if hex1==hex2 + goto endlab1 + else + txt.print("not ==") +endlab1: + if hex1!=hex2 + goto endlab2 + else + txt.print("not !=") +endlab2: + if hex1>=hex2 + goto endlab3 + else + txt.print("not >=") +endlab3: + if hex1<=hex2 + goto endlab4 + else + txt.print("not <=") +endlab4: + if hex1>hex2 + goto endlab5 + else + txt.print("not >") +endlab5: + if hex1hex2) txt.chrout('\n') - result = strcmp(hex1, hex4) - txt.print_b(result) + txt.print_ub(hex1=hex2) + txt.chrout('\n') + txt.print_ub(hex1<=hex2) txt.chrout('\n') testX()