add string.endswith() to efficiently test for a suffix without copying

add string.startswith() to efficiently test for string prefix without copying
This commit is contained in:
Irmen de Jong 2022-07-21 00:38:30 +02:00
parent 473efbe67a
commit f2d27403c5
7 changed files with 60 additions and 4 deletions

View File

@ -165,6 +165,11 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio
throw AssemblyError("non-array var indexing requires bytes index")
val idxReg = codeGen.vmRegisters.nextFree()
code += expressionEval.translateExpression(array.index, idxReg, -1)
if(zero) {
// there's no STOREZIX instruction
resultRegister = codeGen.vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=0)
}
code += VmCodeInstruction(Opcode.STOREIX, vmDt, reg1=resultRegister, reg2=idxReg, value = variableAddr)
return code
}

View File

@ -60,8 +60,8 @@ class VariableAllocator(private val st: SymbolTable, private val program: PtProg
DataType.FLOAT -> (variable.initialNumericValue ?: 0.0).toString()
in NumericDatatypes -> (variable.initialNumericValue ?: 0).toHex()
DataType.STR -> {
val encoded = program.encoding.encodeString(variable.initialStringValue!!.first, variable.initialStringValue!!.second)
encoded.joinToString(",") { it.toInt().toHex() } + ",0"
val encoded = program.encoding.encodeString(variable.initialStringValue!!.first, variable.initialStringValue!!.second) + listOf(0u)
encoded.joinToString(",") { it.toInt().toHex() }
}
DataType.ARRAY_F -> {
if(variable.initialArrayValue!=null) {

View File

@ -223,6 +223,26 @@ _done rts
}}
}
sub startswith(str st, str prefix) -> bool {
ubyte prefix_len = length(prefix)
ubyte str_len = length(st)
if prefix_len > str_len
return false
cx16.r9L = st[prefix_len]
st[prefix_len] = 0
cx16.r9H = compare(st, prefix) as ubyte
st[prefix_len] = cx16.r9L
return cx16.r9H==0
}
sub endswith(str st, str suffix) -> bool {
ubyte suffix_len = length(suffix)
ubyte str_len = length(st)
if suffix_len > str_len
return false
return compare(st + str_len - suffix_len, suffix) == 0
}
asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> ubyte @A {
%asm {{
; pattern matching of a string.
@ -293,5 +313,4 @@ fail clc ; yes, no match found, return with c=0
rts
}}
}
}

View File

@ -113,4 +113,24 @@ string {
ix++
}
}
sub startswith(str st, str prefix) -> bool {
ubyte prefix_len = length(prefix)
ubyte str_len = length(st)
if prefix_len > str_len
return false
cx16.r9L = st[prefix_len]
st[prefix_len] = 0
cx16.r9H = compare(st, prefix) as ubyte
st[prefix_len] = cx16.r9L
return cx16.r9H==0
}
sub endswith(str st, str suffix) -> bool {
ubyte suffix_len = length(suffix)
ubyte str_len = length(st)
if suffix_len > str_len
return false
return compare(st + str_len - suffix_len, suffix) == 0
}
}

View File

@ -1 +1 @@
8.3.1
8.4-dev

View File

@ -190,6 +190,16 @@ Provides string manipulation routines.
``upper(string)``
Uppercases the petscii-string in place.
``startswith(string, prefix) -> bool``
Returns true if string starts with prefix, otherwise false
``endswith(string, suffix) -> bool``
Returns true if string ends with suffix, otherwise false
``pattern_match(string, pattern) -> ubyte`` (not on Virtual target)
Returns 1 (true) if the string matches the pattern, 0 (false) if not.
'?' in the pattern matches any one character. '*' in the pattern matches any substring.
floats
------

View File

@ -3,6 +3,8 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- can the recursive cycle detector print the actual LINES that do the call?
...