added strfind()

This commit is contained in:
Irmen de Jong 2021-01-02 16:46:57 +01:00
parent 583428b19c
commit edd3a22848
7 changed files with 79 additions and 11 deletions

View File

@ -1368,3 +1368,41 @@ func_strcopy_to_stack .proc
dex
rts
.pend
func_strfind .proc
lda _arg_string
ldy _arg_string+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldy #0
- lda (P8ZP_SCRATCH_W1),y
beq _notfound
cmp _arg_char
beq _found
iny
bne -
_notfound lda #0
ldy #0
rts
_found sty P8ZP_SCRATCH_B1
lda P8ZP_SCRATCH_W1
clc
adc P8ZP_SCRATCH_B1
sta P8ZP_SCRATCH_W1
bcc +
inc P8ZP_SCRATCH_W1+1
+ ldy P8ZP_SCRATCH_W1+1
rts
_arg_string .word 0
_arg_char .byte 0
.pend
func_strfind_stack .proc
jsr func_strfind
sta P8ESTACK_LO,x
sty P8ESTACK_HI,x
dex
rts
.pend

View File

@ -130,6 +130,7 @@ val WordDatatypes = setOf(DataType.UWORD, DataType.WORD)
val IntegerDatatypes = setOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD)
val NumericDatatypes = setOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT)
val ArrayDatatypes = setOf(DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_F)
val StringlyDatatypes = setOf(DataType.STR, DataType.ARRAY_UB, DataType.ARRAY_B, DataType.UWORD)
val IterableDatatypes = setOf(
DataType.STR,
DataType.ARRAY_UB, DataType.ARRAY_B,

View File

@ -80,6 +80,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
"clear_irqd" -> asmgen.out(" cli")
"set_irqd" -> asmgen.out(" sei")
"strlen" -> funcStrlen(fcall, resultToStack)
"strfind" -> funcStrfind(fcall, func, resultToStack, sscope)
"strcmp" -> funcStrcmp(fcall, func, resultToStack, sscope)
"strcopy" -> {
translateArguments(fcall.args, func, sscope)
@ -197,6 +198,14 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
}
}
private fun funcStrfind(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
translateArguments(fcall.args, func, scope)
if(resultToStack)
asmgen.out(" jsr prog8_lib.func_strfind_stack")
else
asmgen.out(" jsr prog8_lib.func_strfind")
}
private fun funcStrcmp(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
translateArguments(fcall.args, func, scope)
if(resultToStack)

View File

@ -198,7 +198,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
when(returntype.typeOrElse(DataType.STRUCT)) {
in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A) // function's byte result is in A
in WordDatatypes -> assignRegisterpairWord(assign.target, RegisterOrPair.AY) // function's word result is in AY
DataType.STR -> throw AssemblyError("missing code for assign string from builtin func => copy string or assign string address")
DataType.STR -> {
when (assign.target.datatype) {
DataType.STR -> {
asmgen.out("""
pha
lda #<${assign.target.asmVarname}
sta P8ZP_SCRATCH_W1
lda #>${assign.target.asmVarname}
sta P8ZP_SCRATCH_W1+1
pla
jsr prog8_lib.strcpy""")
}
DataType.UWORD -> assignRegisterpairWord(assign.target, RegisterOrPair.AY)
else -> throw AssemblyError("str return value type mismatch with target")
}
}
DataType.FLOAT -> {
// float result from function sits in FAC1
assignFAC1float(assign.target)

View File

@ -160,22 +160,23 @@ private val functionSignatures: List<FSignature> = listOf(
FParam("address", IterableDatatypes + DataType.UWORD),
FParam("numwords", setOf(DataType.UWORD)),
FParam("wordvalue", setOf(DataType.UWORD, DataType.WORD))), null),
FSignature("strlen" , true, listOf(FParam("string", setOf(DataType.STR))), DataType.UBYTE, ::builtinStrlen),
FSignature("strcopy" , false, listOf(FParam("from", IterableDatatypes + DataType.UWORD), FParam("to", IterableDatatypes + DataType.UWORD)), DataType.UBYTE),
FSignature("strlen" , true, listOf(FParam("string", StringlyDatatypes)), DataType.UBYTE, ::builtinStrlen),
FSignature("strcopy" , false, listOf(FParam("from", StringlyDatatypes), FParam("to", StringlyDatatypes)), DataType.UBYTE),
FSignature("substr" , false, listOf(
FParam("source", IterableDatatypes + DataType.UWORD),
FParam("target", IterableDatatypes + DataType.UWORD),
FParam("source", StringlyDatatypes),
FParam("target", StringlyDatatypes),
FParam("start", setOf(DataType.UBYTE)),
FParam("length", setOf(DataType.UBYTE))), null),
FSignature("leftstr" , false, listOf(
FParam("source", IterableDatatypes + DataType.UWORD),
FParam("target", IterableDatatypes + DataType.UWORD),
FParam("source", StringlyDatatypes),
FParam("target", StringlyDatatypes),
FParam("length", setOf(DataType.UBYTE))), null),
FSignature("rightstr" , false, listOf(
FParam("source", IterableDatatypes + DataType.UWORD),
FParam("target", IterableDatatypes + DataType.UWORD),
FParam("source", StringlyDatatypes),
FParam("target", StringlyDatatypes),
FParam("length", setOf(DataType.UBYTE))), null),
FSignature("strcmp" , false, listOf(FParam("s1", IterableDatatypes + DataType.UWORD), FParam("s2", IterableDatatypes + DataType.UWORD)), DataType.BYTE, null)
FSignature("strcmp" , true, listOf(FParam("s1", StringlyDatatypes), FParam("s2", StringlyDatatypes)), DataType.BYTE, null),
FSignature("strfind" , true, listOf(FParam("string", StringlyDatatypes), FParam("char", setOf(DataType.UBYTE))), DataType.STR, null)
)
val BuiltinFunctions = functionSignatures.associateBy { it.name }

View File

@ -833,6 +833,10 @@ strcopy(from, to)
Often you don't have to call this explicitly and can just write ``string1 = string2``
but this function is useful if you're dealing with addresses for instance.
strfind(string, char)
Locates the first position of the given character in the string, returns the string starting
with this character or $0000 if the character is not found.
Miscellaneous
^^^^^^^^^^^^^

View File

@ -14,7 +14,7 @@
<keywords keywords="&amp;;-&gt;;@;\$;and;as;asmsub;break;clobbers;continue;do;downto;else;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;or;repeat;return;romsub;step;sub;to;true;until;when;while;xor;~" ignore_case="false" />
<keywords2 keywords="%address;%asm;%asmbinary;%asminclude;%breakpoint;%import;%launcher;%option;%output;%target;%zeropage;%zpreserved" />
<keywords3 keywords="byte;const;float;str;struct;ubyte;uword;void;word;zp" />
<keywords4 keywords="abs;acos;all;any;asin;atan;avg;ceil;clear_carry;clear_irqd;cos;cos16;cos16u;cos8;cos8u;deg;exit;floor;leftstr;len;ln;log2;lsb;lsl;lsr;max;memcopy;memory;memset;memsetw;min;mkword;msb;progend;rad;read_flags;reverse;rightstr;rnd;rndf;rndw;rol;rol2;ror;ror2;round;rrestore;rsave;set_carry;set_irqd;sgn;sin;sin16;sin16u;sin8;sin8u;sizeof;sort;sqrt;sqrt16;strcmp;strcopy;strlen;substr;sum;swap;tan;target" />
<keywords4 keywords="abs;acos;all;any;asin;atan;avg;ceil;clear_carry;clear_irqd;cos;cos16;cos16u;cos8;cos8u;deg;exit;floor;leftstr;len;ln;log2;lsb;lsl;lsr;max;memcopy;memory;memset;memsetw;min;mkword;msb;progend;rad;read_flags;reverse;rightstr;rnd;rndf;rndw;rol;rol2;ror;ror2;round;rrestore;rsave;set_carry;set_irqd;sgn;sin;sin16;sin16u;sin8;sin8u;sizeof;sort;sqrt;sqrt16;strcmp;strcopy;strfind;strlen;substr;sum;swap;tan;target" />
</highlighting>
<extensionMap>
<mapping ext="p8" />