fix strlen on uword (pointer) instead of str

This commit is contained in:
Irmen de Jong 2020-10-10 23:24:05 +02:00
parent 216f48b7c1
commit 458ad1de57
3 changed files with 37 additions and 12 deletions

View File

@ -390,12 +390,22 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
private fun funcStrlen(fcall: IFunctionCall) { private fun funcStrlen(fcall: IFunctionCall) {
val name = asmgen.asmVariableName(fcall.args[0] as IdentifierReference) val name = asmgen.asmVariableName(fcall.args[0] as IdentifierReference)
asmgen.out(""" val type = fcall.args[0].inferType(program)
lda #<$name when {
ldy #>$name type.istype(DataType.STR) -> asmgen.out("""
jsr prog8_lib.strlen lda #<$name
sta P8ESTACK_LO,x ldy #>$name
dex""") jsr prog8_lib.strlen
sta P8ESTACK_LO,x
dex""")
type.istype(DataType.UWORD) -> asmgen.out("""
lda $name
ldy $name+1
jsr prog8_lib.strlen
sta P8ESTACK_LO,x
dex""")
else -> throw AssemblyError("strlen requires str or uword arg")
}
} }
private fun funcSwap(fcall: IFunctionCall) { private fun funcSwap(fcall: IFunctionCall) {

View File

@ -285,9 +285,9 @@ private fun builtinStrlen(args: List<Expression>, position: Position, program: P
return NumericLiteralValue.optimalInteger(argument.value.length, argument.position) return NumericLiteralValue.optimalInteger(argument.value.length, argument.position)
val vardecl = (argument as IdentifierReference).targetVarDecl(program.namespace) val vardecl = (argument as IdentifierReference).targetVarDecl(program.namespace)
if(vardecl!=null) { if(vardecl!=null) {
if(vardecl.datatype!=DataType.STR) if(vardecl.datatype!=DataType.STR && vardecl.datatype!=DataType.UWORD)
throw SyntaxError("strlen must have string argument", position) throw SyntaxError("strlen must have string argument", position)
if(vardecl.autogeneratedDontRemove) { if(vardecl.autogeneratedDontRemove && vardecl.value!=null) {
return NumericLiteralValue.optimalInteger((vardecl.value as StringLiteralValue).value.length, argument.position) return NumericLiteralValue.optimalInteger((vardecl.value as StringLiteralValue).value.length, argument.position)
} }
} }

View File

@ -8,10 +8,25 @@ main {
sub start() { sub start() {
; TODO fix multi- string concatenation: ; TODO fix multi- string concatenation:
txt.print("\nCommands are:\n"+ ; txt.print("\nCommands are:\n"+
"buy jump inf cash\n" + ; "buy jump inf cash\n" +
"sell teleport market hold\n" + ; "sell teleport market hold\n" +
"fuel galhyp local quit\n") ; "fuel galhyp local quit\n")
str name = "irmen de jong"
uword strptr = &name
txt.print_ub(strlen("1234"))
txt.chrout('\n')
txt.print_ub(strlen(name))
txt.chrout('\n')
txt.print_uwhex(strptr, 1)
txt.chrout('\n')
txt.print(strptr)
txt.chrout('\n')
txt.print_ub(strlen(strptr))
txt.chrout('\n')
} }