diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index 4f05dae82..638a79e0e 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -540,14 +540,21 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } private fun funcStrlen(fcall: IFunctionCall, resultToStack: Boolean) { - val name = asmgen.asmVariableName(fcall.args[0] as IdentifierReference) - val type = fcall.args[0].inferType(program) - when { - type.istype(DataType.STR) -> asmgen.out(" lda #<$name | ldy #>$name") - type.istype(DataType.UWORD) -> asmgen.out(" lda $name | ldy $name+1") - else -> throw AssemblyError("strlen requires str or uword arg") + if (fcall.args[0] is IdentifierReference) { + // use the address of the variable + val name = asmgen.asmVariableName(fcall.args[0] as IdentifierReference) + val type = fcall.args[0].inferType(program) + when { + type.istype(DataType.STR) -> asmgen.out(" lda #<$name | ldy #>$name") + type.istype(DataType.UWORD) -> asmgen.out(" lda $name | ldy $name+1") + else -> throw AssemblyError("strlen requires str or uword arg") + } } - if(resultToStack) + else { + // use the expression value as address of the string + asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) + } + if (resultToStack) asmgen.out(" jsr prog8_lib.func_strlen_stack") else asmgen.out(" jsr prog8_lib.func_strlen_into_A") diff --git a/compiler/src/prog8/functions/BuiltinFunctions.kt b/compiler/src/prog8/functions/BuiltinFunctions.kt index 2a48755a6..43b2580ae 100644 --- a/compiler/src/prog8/functions/BuiltinFunctions.kt +++ b/compiler/src/prog8/functions/BuiltinFunctions.kt @@ -354,7 +354,7 @@ private fun builtinStrlen(args: List, position: Position, program: P val argument=args[0] if(argument is StringLiteralValue) 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.datatype!=DataType.STR && vardecl.datatype!=DataType.UWORD) throw SyntaxError("strlen must have string argument", position)