diff --git a/compiler/res/prog8lib/prog8lib.asm b/compiler/res/prog8lib/prog8lib.asm index ec35958c9..7e2bf72fe 100644 --- a/compiler/res/prog8lib/prog8lib.asm +++ b/compiler/res/prog8lib/prog8lib.asm @@ -1224,19 +1224,6 @@ _gtequ dey _result_minw .word 0 .pend -func_strlen .proc - ; -- push length of 0-terminated string on stack - jsr peek_address - ldy #0 -- lda (c64.SCRATCH_ZPWORD1),y - beq + - iny - bne - -+ tya - sta c64.ESTACK_LO+1,x - rts - .pend - func_rnd .proc ; -- put a random ubyte on the estack jsr math.randbyte @@ -1325,6 +1312,19 @@ func_memsetw .proc rts .pend +strlen .proc + ; -- put length of 0-terminated string in A/Y into A + sta c64.SCRATCH_ZPWORD1 + sty c64.SCRATCH_ZPWORD1+1 + ldy #0 +- lda (c64.SCRATCH_ZPWORD1),y + beq + + iny + bne - ++ tya + rts + .pend + memcopy16_up .proc ; -- copy memory UP from (SCRATCH_ZPWORD1) to (SCRATCH_ZPWORD2) of length X/Y (16-bit, X=lo, Y=hi) diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index a65705b1d..bc4ae5402 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -11,6 +11,10 @@ import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_HEX import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_PLUS1_HEX import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_HEX import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_PLUS1_HEX +import prog8.compiler.target.c64.codegen.assignment.AsmAssignSource +import prog8.compiler.target.c64.codegen.assignment.AsmAssignTarget +import prog8.compiler.target.c64.codegen.assignment.AsmAssignment +import prog8.compiler.target.c64.codegen.assignment.TargetStorageKind import prog8.compiler.toHex import prog8.functions.FSignature @@ -388,8 +392,13 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } private fun funcStrlen(fcall: IFunctionCall) { - outputPushAddressOfIdentifier(fcall.args[0]) - asmgen.out(" jsr prog8_lib.func_strlen") + val name = asmgen.asmIdentifierName(fcall.args[0] as IdentifierReference) + asmgen.out(""" + lda #<$name + ldy #>$name + jsr prog8_lib.strlen + sta $ESTACK_LO_HEX,x + dex""") } private fun funcSwap(fcall: IFunctionCall) { @@ -500,17 +509,6 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val """) } - private fun outputPushAddressOfIdentifier(arg: Expression) { - val identifierName = asmgen.asmIdentifierName(arg as IdentifierReference) - asmgen.out(""" - lda #<$identifierName - sta $ESTACK_LO_HEX,x - lda #>$identifierName - sta $ESTACK_HI_HEX,x - dex - """) - } - private fun translateFunctionArguments(args: MutableList, signature: FSignature) { args.forEach { asmgen.translateExpression(it) diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt index ed6144919..0d5884a61 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt @@ -318,7 +318,15 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen else -> throw AssemblyError("can't load address in a single 8-bit register") } } - TargetStorageKind.STACK -> TODO() + TargetStorageKind.STACK -> { + val srcname = asmgen.asmIdentifierName(name) + asmgen.out(""" + lda #<$srcname + sta $ESTACK_LO_HEX,x + lda #>$srcname + sta $ESTACK_HI_HEX,x + dex""") + } } } @@ -875,11 +883,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen asmgen.out(""" inx ldy $ESTACK_LO_HEX,x - sty ${C64Zeropage.SCRATCH_W1} + sty ${C64Zeropage.SCRATCH_W2} ldy $ESTACK_HI_HEX,x - sty ${C64Zeropage.SCRATCH_W1+1} + sty ${C64Zeropage.SCRATCH_W2+1} ldy #0 - sta (${C64Zeropage.SCRATCH_W1}),y""") + sta (${C64Zeropage.SCRATCH_W2}),y""") } } } diff --git a/compiler/src/prog8/functions/BuiltinFunctions.kt b/compiler/src/prog8/functions/BuiltinFunctions.kt index bce2ac981..0f238840d 100644 --- a/compiler/src/prog8/functions/BuiltinFunctions.kt +++ b/compiler/src/prog8/functions/BuiltinFunctions.kt @@ -280,11 +280,18 @@ private fun builtinSizeof(args: List, position: Position, program: P private fun builtinStrlen(args: List, position: Position, program: Program): NumericLiteralValue { if (args.size != 1) throw SyntaxError("strlen requires one argument", position) - val argument = args[0].constValue(program) ?: throw NotConstArgumentException() - if(argument.type != DataType.STR) - throw SyntaxError("strlen must have string argument", position) - - throw NotConstArgumentException() // this function is not considering the string argument a constant + val argument=args[0] + if(argument is StringLiteralValue) + return NumericLiteralValue.optimalInteger(argument.value.length, argument.position) + val vardecl = (argument as IdentifierReference).targetVarDecl(program.namespace) + if(vardecl!=null) { + if(vardecl.datatype!=DataType.STR) + throw SyntaxError("strlen must have string argument", position) + if(vardecl.autogeneratedDontRemove) { + return NumericLiteralValue.optimalInteger((vardecl.value as StringLiteralValue).value.length, argument.position) + } + } + throw NotConstArgumentException() } private fun builtinLen(args: List, position: Position, program: Program): NumericLiteralValue { diff --git a/examples/test.p8 b/examples/test.p8 index 856de1a11..8a46929fe 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -5,11 +5,12 @@ main { sub start() { - subje(12345) - } + str tekst = "the quick brown fox" - sub subje(uword xx) { - @($c000) = lsb(xx) + c64scr.print_uw(strlen("aapje")) + c64.CHROUT('\n') + c64scr.print_uw(strlen(tekst)) + c64.CHROUT('\n') } }