mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
added strfind()
This commit is contained in:
parent
583428b19c
commit
edd3a22848
@ -1368,3 +1368,41 @@ func_strcopy_to_stack .proc
|
|||||||
dex
|
dex
|
||||||
rts
|
rts
|
||||||
.pend
|
.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
|
||||||
|
@ -130,6 +130,7 @@ val WordDatatypes = setOf(DataType.UWORD, DataType.WORD)
|
|||||||
val IntegerDatatypes = setOf(DataType.UBYTE, DataType.BYTE, 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 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 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(
|
val IterableDatatypes = setOf(
|
||||||
DataType.STR,
|
DataType.STR,
|
||||||
DataType.ARRAY_UB, DataType.ARRAY_B,
|
DataType.ARRAY_UB, DataType.ARRAY_B,
|
||||||
|
@ -80,6 +80,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
"clear_irqd" -> asmgen.out(" cli")
|
"clear_irqd" -> asmgen.out(" cli")
|
||||||
"set_irqd" -> asmgen.out(" sei")
|
"set_irqd" -> asmgen.out(" sei")
|
||||||
"strlen" -> funcStrlen(fcall, resultToStack)
|
"strlen" -> funcStrlen(fcall, resultToStack)
|
||||||
|
"strfind" -> funcStrfind(fcall, func, resultToStack, sscope)
|
||||||
"strcmp" -> funcStrcmp(fcall, func, resultToStack, sscope)
|
"strcmp" -> funcStrcmp(fcall, func, resultToStack, sscope)
|
||||||
"strcopy" -> {
|
"strcopy" -> {
|
||||||
translateArguments(fcall.args, func, sscope)
|
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?) {
|
private fun funcStrcmp(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
|
||||||
translateArguments(fcall.args, func, scope)
|
translateArguments(fcall.args, func, scope)
|
||||||
if(resultToStack)
|
if(resultToStack)
|
||||||
|
@ -198,7 +198,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
when(returntype.typeOrElse(DataType.STRUCT)) {
|
when(returntype.typeOrElse(DataType.STRUCT)) {
|
||||||
in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A) // function's byte result is in A
|
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
|
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 -> {
|
DataType.FLOAT -> {
|
||||||
// float result from function sits in FAC1
|
// float result from function sits in FAC1
|
||||||
assignFAC1float(assign.target)
|
assignFAC1float(assign.target)
|
||||||
|
@ -160,22 +160,23 @@ private val functionSignatures: List<FSignature> = listOf(
|
|||||||
FParam("address", IterableDatatypes + DataType.UWORD),
|
FParam("address", IterableDatatypes + DataType.UWORD),
|
||||||
FParam("numwords", setOf(DataType.UWORD)),
|
FParam("numwords", setOf(DataType.UWORD)),
|
||||||
FParam("wordvalue", setOf(DataType.UWORD, DataType.WORD))), null),
|
FParam("wordvalue", setOf(DataType.UWORD, DataType.WORD))), null),
|
||||||
FSignature("strlen" , true, listOf(FParam("string", setOf(DataType.STR))), DataType.UBYTE, ::builtinStrlen),
|
FSignature("strlen" , true, listOf(FParam("string", StringlyDatatypes)), DataType.UBYTE, ::builtinStrlen),
|
||||||
FSignature("strcopy" , false, listOf(FParam("from", IterableDatatypes + DataType.UWORD), FParam("to", IterableDatatypes + DataType.UWORD)), DataType.UBYTE),
|
FSignature("strcopy" , false, listOf(FParam("from", StringlyDatatypes), FParam("to", StringlyDatatypes)), DataType.UBYTE),
|
||||||
FSignature("substr" , false, listOf(
|
FSignature("substr" , false, listOf(
|
||||||
FParam("source", IterableDatatypes + DataType.UWORD),
|
FParam("source", StringlyDatatypes),
|
||||||
FParam("target", IterableDatatypes + DataType.UWORD),
|
FParam("target", StringlyDatatypes),
|
||||||
FParam("start", setOf(DataType.UBYTE)),
|
FParam("start", setOf(DataType.UBYTE)),
|
||||||
FParam("length", setOf(DataType.UBYTE))), null),
|
FParam("length", setOf(DataType.UBYTE))), null),
|
||||||
FSignature("leftstr" , false, listOf(
|
FSignature("leftstr" , false, listOf(
|
||||||
FParam("source", IterableDatatypes + DataType.UWORD),
|
FParam("source", StringlyDatatypes),
|
||||||
FParam("target", IterableDatatypes + DataType.UWORD),
|
FParam("target", StringlyDatatypes),
|
||||||
FParam("length", setOf(DataType.UBYTE))), null),
|
FParam("length", setOf(DataType.UBYTE))), null),
|
||||||
FSignature("rightstr" , false, listOf(
|
FSignature("rightstr" , false, listOf(
|
||||||
FParam("source", IterableDatatypes + DataType.UWORD),
|
FParam("source", StringlyDatatypes),
|
||||||
FParam("target", IterableDatatypes + DataType.UWORD),
|
FParam("target", StringlyDatatypes),
|
||||||
FParam("length", setOf(DataType.UBYTE))), null),
|
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 }
|
val BuiltinFunctions = functionSignatures.associateBy { it.name }
|
||||||
|
@ -833,6 +833,10 @@ strcopy(from, to)
|
|||||||
Often you don't have to call this explicitly and can just write ``string1 = string2``
|
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.
|
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
|
Miscellaneous
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<keywords keywords="&;->;@;\$;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" />
|
<keywords keywords="&;->;@;\$;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" />
|
<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" />
|
<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>
|
</highlighting>
|
||||||
<extensionMap>
|
<extensionMap>
|
||||||
<mapping ext="p8" />
|
<mapping ext="p8" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user