From 4d01a787312447c290240da2d3edaabf67f30689 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 16 Oct 2020 18:11:25 +0200 Subject: [PATCH] introduced strcmp() builtin function --- compiler/res/prog8lib/prog8_lib.asm | 17 +++++++++++++++++ compiler/res/prog8lib/prog8_lib.p8 | 16 ---------------- .../src/prog8/functions/BuiltinFunctions.kt | 3 ++- docs/source/programming.rst | 12 +++++++++--- docs/source/todo.rst | 1 - examples/test.p8 | 8 ++++---- 6 files changed, 32 insertions(+), 25 deletions(-) diff --git a/compiler/res/prog8lib/prog8_lib.asm b/compiler/res/prog8lib/prog8_lib.asm index 52dbb042d..6049537a9 100644 --- a/compiler/res/prog8lib/prog8_lib.asm +++ b/compiler/res/prog8lib/prog8_lib.asm @@ -2130,3 +2130,20 @@ _startloop dey rts .pend + + +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 + lda P8ESTACK_HI,x + sta P8ZP_SCRATCH_W2+1 + lda P8ESTACK_HI+1,x + tay + lda P8ESTACK_LO+1,x + jsr strcmp_mem + sta P8ESTACK_LO+1,x + rts + .pend diff --git a/compiler/res/prog8lib/prog8_lib.p8 b/compiler/res/prog8lib/prog8_lib.p8 index 66b109a03..4424c1d3e 100644 --- a/compiler/res/prog8lib/prog8_lib.p8 +++ b/compiler/res/prog8lib/prog8_lib.p8 @@ -6,20 +6,4 @@ prog8_lib { %asminclude "library:prog8_lib.asm", "" - - sub strcmp(uword s1, uword s2) -> byte { - ; -- convenience wrapper for plain Prog8 to compare strings TODO turn this into a builtin function - byte result - %asm {{ - lda s2 - sta P8ZP_SCRATCH_W2 - lda s2+1 - sta P8ZP_SCRATCH_W2+1 - lda s1 - ldy s1+1 - jsr prog8_lib.strcmp_mem - sta result - }} - return result - } } diff --git a/compiler/src/prog8/functions/BuiltinFunctions.kt b/compiler/src/prog8/functions/BuiltinFunctions.kt index 0b48fa23e..f7748b901 100644 --- a/compiler/src/prog8/functions/BuiltinFunctions.kt +++ b/compiler/src/prog8/functions/BuiltinFunctions.kt @@ -101,7 +101,8 @@ val BuiltinFunctions = mapOf( "rightstr" to FSignature(false, listOf( FParam("source", IterableDatatypes + DataType.UWORD), FParam("target", IterableDatatypes + DataType.UWORD), - FParam("length", setOf(DataType.UBYTE))), null) + FParam("length", setOf(DataType.UBYTE))), null), + "strcmp" to FSignature(false, listOf(FParam("s1", IterableDatatypes + DataType.UWORD), FParam("s2", IterableDatatypes + DataType.UWORD)), DataType.BYTE, null) ) fun builtinMax(array: List): Number = array.maxByOrNull { it.toDouble() }!! diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 20556ad69..d77e892a1 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -733,9 +733,12 @@ sum(x) sort(array) Sort the array in ascending order (in-place) - Note: sorting a floating-point array is not supported right now, as a general sorting routine for this will - be extremely slow. Either build one yourself or find another solution that doesn't require sorting - floating point values. + Supported are arrays of bytes or word values. + Sorting a floating-point array is not supported right now, as a general sorting routine for this will + be extremely slow. Either build one yourself or find another solution that doesn't require sorting. + Finally, note that sorting an array with strings in it will not do what you might think; + it considers the array as just an array of integer words and sorts the string *pointers* accordingly. + Sorting strings alphabetically has to be programmed yourself if you need it. reverse(array) Reverse the values in the array (in-place). @@ -844,6 +847,9 @@ substr(source, target, start, length) It is assumed the target string buffer is large enough to contain the result. Modifies in-place, doesn't return a value (so can't be used in an expression). +strcmp(string1, string2) + Returns -1, 0 or 1 depeding on wether string1 sorts before, equal or after string2. + swap(x, y) Swap the values of numerical variables (or memory locations) x and y in a fast way. diff --git a/docs/source/todo.rst b/docs/source/todo.rst index a88b764ac..6e75cd39a 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,6 @@ TODO ==== - get rid of all other TODO's in the code ;-) -- introduce strcmp() - modify string comparison expressions to use strcmp() automatically - only allow array indexing via a number, a variable, or a typecast of one of those (eliminate complex expression calcs for array indexing, force explicit use of an index variable) - implement @stack for asmsub parameters diff --git a/examples/test.p8 b/examples/test.p8 index 5f8157407..8d711e5ca 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -13,16 +13,16 @@ main { str hex4 = "aap3333" byte result - result = prog8_lib.strcmp(hex1, hex1) + result = strcmp(hex1, hex1) txt.print_b(result) txt.chrout('\n') - result = prog8_lib.strcmp(hex1, hex2) + result = strcmp(hex1, hex2) txt.print_b(result) txt.chrout('\n') - result = prog8_lib.strcmp(hex1, hex3) + result = strcmp(hex1, hex3) txt.print_b(result) txt.chrout('\n') - result = prog8_lib.strcmp(hex1, hex4) + result = strcmp(hex1, hex4) txt.print_b(result) txt.chrout('\n')