started making string compares use strcmp() automatically

This commit is contained in:
Irmen de Jong 2020-10-17 01:11:01 +02:00
parent 4d01a78731
commit 2d3b7eb878
3 changed files with 118 additions and 22 deletions

View File

@ -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

View File

@ -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""")
}
}
}

View File

@ -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 hex1<hex2
goto endlab6
else
txt.print("not <")
endlab6:
txt.print_ub(hex1==hex2)
txt.chrout('\n')
result = strcmp(hex1, hex2)
txt.print_b(result)
txt.print_ub(hex1!=hex2)
txt.chrout('\n')
result = strcmp(hex1, hex3)
txt.print_b(result)
txt.print_ub(hex1>hex2)
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')
txt.print_ub(hex1<=hex2)
txt.chrout('\n')
testX()