mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +00:00
removed all string related builtin functions and moved them to separate routines in new 'string' library module
This commit is contained in:
parent
ee7f9d457d
commit
58f37513e7
@ -7,16 +7,14 @@ indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_line_length = 120
|
||||
tab_width = 4
|
||||
tab_width = 8
|
||||
trim_trailing_whitespace = true
|
||||
ij_smart_tabs = true
|
||||
|
||||
[*.p8]
|
||||
tab_width = 4
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
|
||||
[*.asm]
|
||||
tab_width = 8
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
|
@ -3,6 +3,7 @@
|
||||
; Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
||||
|
||||
%import textio
|
||||
%import string
|
||||
%import syslib
|
||||
|
||||
diskio {
|
||||
@ -84,7 +85,7 @@ io_error:
|
||||
name_ptrs++
|
||||
@(name_ptrs) = msb(names_buffer)
|
||||
name_ptrs++
|
||||
names_buffer += strcopy(diskio.list_filename, names_buffer) + 1
|
||||
names_buffer += string.copy(diskio.list_filename, names_buffer) + 1
|
||||
files_found++
|
||||
if names_buffer - buffer_start > 512-18
|
||||
break
|
||||
@ -204,7 +205,7 @@ close_end:
|
||||
; note: only a single iteration loop can be active at a time!
|
||||
f_close()
|
||||
|
||||
c64.SETNAM(strlen(filenameptr), filenameptr)
|
||||
c64.SETNAM(string.length(filenameptr), filenameptr)
|
||||
c64.SETLFS(11, drivenumber, 3)
|
||||
void c64.OPEN() ; open 11,8,0,"filename"
|
||||
if_cc {
|
||||
@ -373,7 +374,7 @@ io_error:
|
||||
|
||||
|
||||
sub save(ubyte drivenumber, uword filenameptr, uword address, uword size) -> ubyte {
|
||||
c64.SETNAM(strlen(filenameptr), filenameptr)
|
||||
c64.SETNAM(string.length(filenameptr), filenameptr)
|
||||
c64.SETLFS(1, drivenumber, 0)
|
||||
uword end_address = address + size
|
||||
|
||||
@ -403,7 +404,7 @@ io_error:
|
||||
}
|
||||
|
||||
sub load(ubyte drivenumber, uword filenameptr, uword address_override) -> uword {
|
||||
c64.SETNAM(strlen(filenameptr), filenameptr)
|
||||
c64.SETNAM(string.length(filenameptr), filenameptr)
|
||||
ubyte secondary = 1
|
||||
uword end_of_load = 0
|
||||
if address_override
|
||||
@ -435,7 +436,7 @@ io_error:
|
||||
|
||||
sub delete(ubyte drivenumber, uword filenameptr) {
|
||||
; -- delete a file on the drive
|
||||
ubyte flen = strlen(filenameptr)
|
||||
ubyte flen = string.length(filenameptr)
|
||||
filename[0] = 's'
|
||||
filename[1] = ':'
|
||||
memcopy(filenameptr, &filename+2, flen+1)
|
||||
@ -448,8 +449,8 @@ io_error:
|
||||
|
||||
sub rename(ubyte drivenumber, uword oldfileptr, uword newfileptr) {
|
||||
; -- rename a file on the drive
|
||||
ubyte flen_old = strlen(oldfileptr)
|
||||
ubyte flen_new = strlen(newfileptr)
|
||||
ubyte flen_old = string.length(oldfileptr)
|
||||
ubyte flen_new = string.length(newfileptr)
|
||||
filename[0] = 'r'
|
||||
filename[1] = ':'
|
||||
memcopy(newfileptr, &filename+2, flen_new)
|
||||
|
@ -1204,205 +1204,3 @@ func_memcopy255 .proc
|
||||
ldx P8ZP_SCRATCH_REG
|
||||
rts
|
||||
.pend
|
||||
|
||||
|
||||
func_leftstr .proc
|
||||
; leftstr(source, target, length)
|
||||
lda _arg_source
|
||||
ldy _arg_source+1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda _arg_target
|
||||
ldy _arg_target+1
|
||||
sta P8ZP_SCRATCH_W2
|
||||
sty P8ZP_SCRATCH_W2+1
|
||||
ldy _arg_length
|
||||
lda #0
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
cpy #0
|
||||
bne _loop
|
||||
rts
|
||||
_loop dey
|
||||
lda (P8ZP_SCRATCH_W1),y
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
cpy #0
|
||||
bne _loop
|
||||
+ rts
|
||||
|
||||
_arg_source .word 0
|
||||
_arg_target .word 0
|
||||
_arg_length .byte 0
|
||||
.pend
|
||||
|
||||
|
||||
func_rightstr .proc
|
||||
; rightstr(source, target, length)
|
||||
lda _arg_source
|
||||
ldy _arg_source+1
|
||||
jsr func_strlen_into_A
|
||||
sec
|
||||
sbc _arg_length
|
||||
sta P8ZP_SCRATCH_B1
|
||||
lda _arg_source
|
||||
ldy _arg_source+1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda _arg_target
|
||||
ldy _arg_target+1
|
||||
sta P8ZP_SCRATCH_W2
|
||||
sty P8ZP_SCRATCH_W2+1
|
||||
ldy #0
|
||||
sty P8ZP_SCRATCH_REG
|
||||
- ldy P8ZP_SCRATCH_B1
|
||||
lda (P8ZP_SCRATCH_W1),y
|
||||
inc P8ZP_SCRATCH_B1
|
||||
ldy P8ZP_SCRATCH_REG
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
inc P8ZP_SCRATCH_REG
|
||||
cmp #0
|
||||
bne -
|
||||
rts
|
||||
|
||||
_arg_source .word 0
|
||||
_arg_target .word 0
|
||||
_arg_length .byte 0
|
||||
.pend
|
||||
|
||||
|
||||
func_strlen_into_A .proc
|
||||
; -- put length of 0-terminated string in A/Y into A
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldy #0
|
||||
- lda (P8ZP_SCRATCH_W1),y
|
||||
beq +
|
||||
iny
|
||||
bne -
|
||||
+ tya
|
||||
rts
|
||||
.pend
|
||||
|
||||
func_strlen_stack .proc
|
||||
jsr func_strlen_into_A
|
||||
sta P8ESTACK_LO,x
|
||||
dex
|
||||
rts
|
||||
.pend
|
||||
|
||||
|
||||
func_substr .proc
|
||||
; substr(source, target, start, length)
|
||||
lda _arg_source
|
||||
ldy _arg_source+1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda _arg_target
|
||||
ldy _arg_target+1
|
||||
sta P8ZP_SCRATCH_W2
|
||||
sty P8ZP_SCRATCH_W2+1
|
||||
ldy _arg_length
|
||||
lda _arg_start
|
||||
sta P8ZP_SCRATCH_B1
|
||||
|
||||
; adjust src location
|
||||
clc
|
||||
lda P8ZP_SCRATCH_W1
|
||||
adc P8ZP_SCRATCH_B1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
bcc +
|
||||
inc P8ZP_SCRATCH_W1+1
|
||||
+ lda #0
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
jmp _startloop
|
||||
- lda (P8ZP_SCRATCH_W1),y
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
_startloop dey
|
||||
cpy #$ff
|
||||
bne -
|
||||
rts
|
||||
|
||||
_arg_source .word 0
|
||||
_arg_target .word 0
|
||||
_arg_start .byte 0
|
||||
_arg_length .byte 0
|
||||
.pend
|
||||
|
||||
|
||||
func_strcmp .proc
|
||||
; -- compare 2 strings -> A
|
||||
lda _arg_s2
|
||||
ldy _arg_s2+1
|
||||
sta P8ZP_SCRATCH_W2
|
||||
sty P8ZP_SCRATCH_W2+1
|
||||
lda _arg_s1
|
||||
ldy _arg_s1+1
|
||||
jmp strcmp_mem
|
||||
_arg_s1 .word 0
|
||||
_arg_s2 .word 0
|
||||
.pend
|
||||
|
||||
func_strcmp_stack .proc
|
||||
jsr func_strcmp
|
||||
sta P8ESTACK_LO,x
|
||||
dex
|
||||
rts
|
||||
.pend
|
||||
|
||||
func_strcopy .proc
|
||||
lda _arg_to
|
||||
ldy _arg_to+1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda _arg_from
|
||||
ldy _arg_from+1
|
||||
jsr strcpy
|
||||
tya
|
||||
rts
|
||||
_arg_from .word 0
|
||||
_arg_to .word 0
|
||||
.pend
|
||||
|
||||
func_strcopy_to_stack .proc
|
||||
jsr func_strcopy
|
||||
sta P8ESTACK_LO,x
|
||||
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
|
||||
|
@ -5,5 +5,189 @@
|
||||
|
||||
string {
|
||||
|
||||
asmsub length(uword string @AY) clobbers(A) -> ubyte @Y {
|
||||
; Returns the number of bytes in the string.
|
||||
; This value is determined during runtime and counts upto the first terminating 0 byte in the string,
|
||||
; regardless of the size of the string during compilation time. Don’t confuse this with len and sizeof!
|
||||
|
||||
%asm {{
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldy #0
|
||||
- lda (P8ZP_SCRATCH_W1),y
|
||||
beq +
|
||||
iny
|
||||
bne -
|
||||
+ rts
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub left(uword source @R0, ubyte length @A, uword target @R1) clobbers(A, Y) {
|
||||
; Copies the left side of the source string of the given length to target string.
|
||||
; It is assumed the target string buffer is large enough to contain the result.
|
||||
; Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
|
||||
; Modifies in-place, doesn’t return a value (so can’t be used in an expression).
|
||||
%asm {{
|
||||
; need to copy the the cx16 virtual registers to zeropage to be compatible with C64...
|
||||
ldy cx16.r0
|
||||
sty P8ZP_SCRATCH_W1
|
||||
ldy cx16.r0+1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldy cx16.r1
|
||||
sty P8ZP_SCRATCH_W2
|
||||
ldy cx16.r1+1
|
||||
sty P8ZP_SCRATCH_W2+1
|
||||
tay
|
||||
lda #0
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
cpy #0
|
||||
bne _loop
|
||||
rts
|
||||
_loop dey
|
||||
lda (P8ZP_SCRATCH_W1),y
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
cpy #0
|
||||
bne _loop
|
||||
+ rts
|
||||
}}
|
||||
; asmgen.out(" jsr prog8_lib.func_leftstr")
|
||||
}
|
||||
|
||||
asmsub right(uword source @R0, ubyte length @A, uword target @R1) clobbers(A,Y) {
|
||||
; Copies the right side of the source string of the given length to target string.
|
||||
; It is assumed the target string buffer is large enough to contain the result.
|
||||
; Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
|
||||
; Modifies in-place, doesn’t return a value (so can’t be used in an expression).
|
||||
%asm {{
|
||||
; need to copy the the cx16 virtual registers to zeropage to be compatible with C64...
|
||||
sta P8ZP_SCRATCH_B1
|
||||
lda cx16.r0
|
||||
ldy cx16.r0+1
|
||||
jsr string.length
|
||||
tya
|
||||
sec
|
||||
sbc P8ZP_SCRATCH_B1
|
||||
clc
|
||||
adc cx16.r0
|
||||
sta P8ZP_SCRATCH_W1
|
||||
lda cx16.r0+1
|
||||
adc #0
|
||||
sta P8ZP_SCRATCH_W1+1
|
||||
ldy cx16.r1
|
||||
sty P8ZP_SCRATCH_W2
|
||||
ldy cx16.r1+1
|
||||
sty P8ZP_SCRATCH_W2+1
|
||||
ldy P8ZP_SCRATCH_B1
|
||||
lda #0
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
cpy #0
|
||||
bne _loop
|
||||
rts
|
||||
_loop dey
|
||||
lda (P8ZP_SCRATCH_W1),y
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
cpy #0
|
||||
bne _loop
|
||||
+ rts
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub slice(uword source @R0, ubyte start @A, ubyte length @Y, uword target @R1) clobbers(A, Y) {
|
||||
; Copies a segment from the source string, starting at the given index,
|
||||
; and of the given length to target string.
|
||||
; It is assumed the target string buffer is large enough to contain the result.
|
||||
; Also, you have to make sure yourself that start and length are within bounds of the strings.
|
||||
; Modifies in-place, doesn’t return a value (so can’t be used in an expression).
|
||||
%asm {{
|
||||
; need to copy the the cx16 virtual registers to zeropage to be compatible with C64...
|
||||
; substr(source, target, start, length)
|
||||
sta P8ZP_SCRATCH_B1
|
||||
lda cx16.r0
|
||||
sta P8ZP_SCRATCH_W1
|
||||
lda cx16.r0+1
|
||||
sta P8ZP_SCRATCH_W1+1
|
||||
lda cx16.r1
|
||||
sta P8ZP_SCRATCH_W2
|
||||
lda cx16.r1+1
|
||||
sta P8ZP_SCRATCH_W2+1
|
||||
|
||||
; adjust src location
|
||||
clc
|
||||
lda P8ZP_SCRATCH_W1
|
||||
adc P8ZP_SCRATCH_B1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
bcc +
|
||||
inc P8ZP_SCRATCH_W1+1
|
||||
+ lda #0
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
beq _startloop
|
||||
- lda (P8ZP_SCRATCH_W1),y
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
_startloop dey
|
||||
cpy #$ff
|
||||
bne -
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub find(uword string @R0, ubyte character @A) -> uword @AY {
|
||||
; 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.
|
||||
%asm {{
|
||||
; need to copy the the cx16 virtual registers to zeropage to be compatible with C64...
|
||||
sta P8ZP_SCRATCH_B1
|
||||
lda cx16.r0
|
||||
ldy cx16.r0+1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldy #0
|
||||
- lda (P8ZP_SCRATCH_W1),y
|
||||
beq _notfound
|
||||
cmp P8ZP_SCRATCH_B1
|
||||
beq _found
|
||||
iny
|
||||
bne -
|
||||
_notfound lda #0
|
||||
ldy #0
|
||||
rts
|
||||
_found sty P8ZP_SCRATCH_B1
|
||||
ldy P8ZP_SCRATCH_W1+1
|
||||
lda P8ZP_SCRATCH_W1
|
||||
clc
|
||||
adc P8ZP_SCRATCH_B1
|
||||
bcc +
|
||||
iny
|
||||
+ rts
|
||||
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub copy(uword source @R0, uword target @AY) clobbers(A) -> ubyte @Y {
|
||||
; Copy a string to another, overwriting that one.
|
||||
; Returns the length of the string that was copied.
|
||||
; 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.
|
||||
%asm {{
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda cx16.r0
|
||||
ldy cx16.r0+1
|
||||
jmp prog8_lib.strcpy
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub compare(uword string1 @R0, uword string2 @AY) clobbers(Y) -> ubyte @A {
|
||||
; Compares two strings for sorting.
|
||||
; Returns -1 (255), 0 or 1 depeding on wether string1 sorts before, equal or after string2.
|
||||
; Note that you can also directly compare strings and string values with eachother using
|
||||
; comparison operators ==, < etcetera (it will use strcmp for you under water automatically).
|
||||
%asm {{
|
||||
sta P8ZP_SCRATCH_W2
|
||||
sty P8ZP_SCRATCH_W2+1
|
||||
lda cx16.r0
|
||||
ldy cx16.r0+1
|
||||
jmp prog8_lib.strcmp_mem
|
||||
}}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -79,21 +79,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
"set_carry" -> asmgen.out(" sec")
|
||||
"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)
|
||||
if(resultToStack)
|
||||
asmgen.out(" jsr prog8_lib.func_strcopy_to_stack")
|
||||
else
|
||||
asmgen.out(" jsr prog8_lib.func_strcopy")
|
||||
}
|
||||
"memcopy", "memset", "memsetw" -> funcMemSetCopy(fcall, func, sscope)
|
||||
"substr", "leftstr", "rightstr" -> {
|
||||
translateArguments(fcall.args, func, sscope)
|
||||
asmgen.out(" jsr prog8_lib.func_${func.name}")
|
||||
}
|
||||
"exit" -> {
|
||||
translateArguments(fcall.args, func, sscope)
|
||||
asmgen.out(" jmp prog8_lib.func_exit")
|
||||
@ -198,22 +184,6 @@ 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)
|
||||
asmgen.out(" jsr prog8_lib.func_strcmp_stack")
|
||||
else
|
||||
asmgen.out(" jsr prog8_lib.func_strcmp")
|
||||
}
|
||||
|
||||
private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
|
||||
translateArguments(fcall.args, func, scope)
|
||||
if(resultToStack)
|
||||
@ -588,27 +558,6 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
}
|
||||
}
|
||||
|
||||
private fun funcStrlen(fcall: IFunctionCall, resultToStack: Boolean) {
|
||||
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")
|
||||
}
|
||||
}
|
||||
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")
|
||||
}
|
||||
|
||||
private fun funcSwap(fcall: IFunctionCall) {
|
||||
val first = fcall.args[0]
|
||||
val second = fcall.args[1]
|
||||
|
@ -159,24 +159,7 @@ private val functionSignatures: List<FSignature> = listOf(
|
||||
FSignature("memsetw" , false, 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", StringlyDatatypes)), DataType.UBYTE, ::builtinStrlen),
|
||||
FSignature("strcopy" , false, listOf(FParam("from", StringlyDatatypes), FParam("to", StringlyDatatypes)), DataType.UBYTE),
|
||||
FSignature("substr" , false, listOf(
|
||||
FParam("source", StringlyDatatypes),
|
||||
FParam("target", StringlyDatatypes),
|
||||
FParam("start", setOf(DataType.UBYTE)),
|
||||
FParam("length", setOf(DataType.UBYTE))), null),
|
||||
FSignature("leftstr" , false, listOf(
|
||||
FParam("source", StringlyDatatypes),
|
||||
FParam("target", StringlyDatatypes),
|
||||
FParam("length", setOf(DataType.UBYTE))), null),
|
||||
FSignature("rightstr" , false, listOf(
|
||||
FParam("source", StringlyDatatypes),
|
||||
FParam("target", StringlyDatatypes),
|
||||
FParam("length", setOf(DataType.UBYTE))), 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)
|
||||
FParam("wordvalue", setOf(DataType.UWORD, DataType.WORD))), null)
|
||||
)
|
||||
|
||||
val BuiltinFunctions = functionSignatures.associateBy { it.name }
|
||||
@ -355,23 +338,6 @@ private fun builtinSizeof(args: List<Expression>, position: Position, program: P
|
||||
}
|
||||
}
|
||||
|
||||
private fun builtinStrlen(args: List<Expression>, position: Position, program: Program): NumericLiteralValue {
|
||||
if (args.size != 1)
|
||||
throw SyntaxError("strlen requires one argument", position)
|
||||
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 && vardecl.datatype!=DataType.UWORD)
|
||||
throw SyntaxError("strlen must have string argument", position)
|
||||
if(vardecl.autogeneratedDontRemove && vardecl.value!=null) {
|
||||
return NumericLiteralValue.optimalInteger((vardecl.value as StringLiteralValue).value.length, argument.position)
|
||||
}
|
||||
}
|
||||
throw NotConstArgumentException()
|
||||
}
|
||||
|
||||
private fun builtinLen(args: List<Expression>, position: Position, program: Program): NumericLiteralValue {
|
||||
// note: in some cases the length is > 255 and then we have to return a UWORD type instead of a UBYTE.
|
||||
if(args.size!=1)
|
||||
|
@ -65,6 +65,49 @@ Provides several routines that deal with disk drive I/O, such as:
|
||||
- delete and rename files on the disk
|
||||
|
||||
|
||||
string
|
||||
------
|
||||
Provides string manipulation routines.
|
||||
|
||||
length(str) -> ubyte length
|
||||
Number of bytes in the string. This value is determined during runtime and counts upto
|
||||
the first terminating 0 byte in the string, regardless of the size of the string during compilation time.
|
||||
Don't confuse this with ``len`` and ``sizeof``
|
||||
|
||||
left(source, length, target)
|
||||
Copies the left side of the source string of the given length to target string.
|
||||
It is assumed the target string buffer is large enough to contain the result.
|
||||
Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
|
||||
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
||||
|
||||
right(source, length, target)
|
||||
Copies the right side of the source string of the given length to target string.
|
||||
It is assumed the target string buffer is large enough to contain the result.
|
||||
Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
|
||||
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
||||
|
||||
slice(source, start, length, target)
|
||||
Copies a segment from the source string, starting at the given index,
|
||||
and of the given length to target string.
|
||||
It is assumed the target string buffer is large enough to contain the result.
|
||||
Also, you have to make sure yourself that start and length are within bounds of the strings.
|
||||
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
||||
|
||||
find(string, char) -> uword address
|
||||
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.
|
||||
|
||||
compare(string1, string2) -> ubyte result
|
||||
Returns -1, 0 or 1 depeding on wether string1 sorts before, equal or after string2.
|
||||
Note that you can also directly compare strings and string values with eachother
|
||||
using ``==``, ``<`` etcetera (it will use string.compare for you under water automatically).
|
||||
|
||||
copy(from, to) -> ubyte length
|
||||
Copy a string to another, overwriting that one. Returns the length of the string that was copied.
|
||||
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.
|
||||
|
||||
|
||||
floats
|
||||
------
|
||||
Provides definitions for the ROM/kernel subroutines and utility routines dealing with floating
|
||||
|
@ -799,44 +799,6 @@ memsetw(address, numwords, wordvalue)
|
||||
Efficiently set a part of memory to the given (u)word value.
|
||||
But the most efficient will always be to write a specialized fill routine in assembly yourself!
|
||||
|
||||
leftstr(source, target, length)
|
||||
Copies the left side of the source string of the given length to target string.
|
||||
It is assumed the target string buffer is large enough to contain the result.
|
||||
Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
|
||||
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
||||
|
||||
rightstr(source, target, length)
|
||||
Copies the right side of the source string of the given length to target string.
|
||||
It is assumed the target string buffer is large enough to contain the result.
|
||||
Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
|
||||
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
||||
|
||||
strlen(str)
|
||||
Number of bytes in the string. This value is determined during runtime and counts upto
|
||||
the first terminating 0 byte in the string, regardless of the size of the string during compilation time.
|
||||
Don't confuse this with ``len`` and ``sizeof``
|
||||
|
||||
strcmp(string1, string2)
|
||||
Returns -1, 0 or 1 depeding on wether string1 sorts before, equal or after string2.
|
||||
Note that you can also directly compare strings and string values with eachother
|
||||
using ``==``, ``<`` etcetera (it will use strcmp for you under water automatically).
|
||||
|
||||
substr(source, target, start, length)
|
||||
Copies a segment from the source string, starting at the given index,
|
||||
and of the given length to target string.
|
||||
It is assumed the target string buffer is large enough to contain the result.
|
||||
Also, you have to make sure yourself that start and length are within bounds of the strings.
|
||||
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
||||
|
||||
strcopy(from, to)
|
||||
Copy a string to another, overwriting that one. Returns the length of the string that was copied.
|
||||
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
|
||||
^^^^^^^^^^^^^
|
||||
|
@ -3,8 +3,10 @@ TODO
|
||||
====
|
||||
|
||||
- move all str* builtin functions to a strings library module, mem* to the sys module. update docs.
|
||||
- move target() builtin to sys.target constant
|
||||
- use (zp) addressing mode on 65c02 specific code rather than ldy#0 / lda (zp),y
|
||||
- optimize pointer access code @(pointer)? use a subroutine? macro? 65c02 vs 6502?
|
||||
- allow byte return type with single register for asmsubs, for instance string.compare
|
||||
- can we get rid of the --longOptionName command line options and only keep the short versions? https://github.com/Kotlin/kotlinx-cli/issues/50
|
||||
- optimizer: detect variables that are written but never read - mark those as unused too and remove them, such as uword unused = memory("unused222", 20) - also remove the memory slab allocation
|
||||
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
|
||||
|
@ -7,16 +7,14 @@ indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_line_length = 120
|
||||
tab_width = 4
|
||||
tab_width = 8
|
||||
trim_trailing_whitespace = true
|
||||
ij_smart_tabs = true
|
||||
|
||||
[*.p8]
|
||||
tab_width = 4
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
|
||||
[*.asm]
|
||||
tab_width = 8
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
|
@ -1,5 +1,6 @@
|
||||
%import floats
|
||||
%import textio
|
||||
%import string
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
@ -22,10 +23,10 @@ main {
|
||||
if length!=5 txt.print("error len1\n")
|
||||
length = len(uwarr)
|
||||
if length!=5 txt.print("error len2\n")
|
||||
length=strlen(name)
|
||||
length=string.length(name)
|
||||
if length!=5 txt.print("error strlen1\n")
|
||||
name[3] = 0
|
||||
length=strlen(name)
|
||||
length=string.length(name)
|
||||
if length!=3 txt.print("error strlen2\n")
|
||||
|
||||
; MAX
|
||||
|
@ -477,6 +477,7 @@ main {
|
||||
|
||||
|
||||
|
||||
; @TODO fix type errors
|
||||
|
||||
sub shiftrsw0() -> word {
|
||||
word q = -12345
|
||||
|
@ -1,5 +1,6 @@
|
||||
%import textio
|
||||
%import floats
|
||||
%import string
|
||||
%import syslib
|
||||
%import test_stack
|
||||
%zeropage basicsafe
|
||||
@ -8,7 +9,6 @@ main {
|
||||
|
||||
sub start() {
|
||||
rotations()
|
||||
strings()
|
||||
integers()
|
||||
floatingpoint()
|
||||
|
||||
@ -256,82 +256,6 @@ main {
|
||||
|
||||
}
|
||||
|
||||
sub strings() {
|
||||
const uword ADDR = $8400
|
||||
const uword ADDR2 = $8000
|
||||
|
||||
memset(ADDR2, 40*25, '*')
|
||||
memset(ADDR2, 40, '1')
|
||||
memset(ADDR2+24*40, 39, '2')
|
||||
memsetw(ADDR2, 40*25/2, $3132)
|
||||
memsetw(ADDR2, 20, $4142)
|
||||
memsetw(ADDR2+24*40, 19, $4241)
|
||||
memcopy(ADDR2, ADDR, 200)
|
||||
|
||||
str result = "?" *10
|
||||
str s1 = "irmen"
|
||||
str s2 = "hello"
|
||||
str dots = "....."
|
||||
|
||||
ubyte ub
|
||||
byte bb
|
||||
ubyte zero=0
|
||||
|
||||
bb = strcmp(s1, s2)
|
||||
txt.print_b(bb)
|
||||
txt.chrout('\n')
|
||||
bb = strcmp(s2, s1)
|
||||
txt.print_b(bb)
|
||||
txt.chrout('\n')
|
||||
txt.print_ub(s1==s2)
|
||||
txt.chrout('\n')
|
||||
txt.print_ub(s1<s2)
|
||||
txt.chrout('\n')
|
||||
txt.print_ub(s1>s2)
|
||||
txt.chrout('\n')
|
||||
bb = zero+strcmp(s1,s2)*1+zero
|
||||
txt.print_b(bb)
|
||||
txt.chrout('\n')
|
||||
bb = zero+strcmp(s2,s1)*1+zero
|
||||
txt.print_b(bb)
|
||||
txt.chrout('\n')
|
||||
|
||||
ub = strlen(s1)
|
||||
txt.print_ub(ub)
|
||||
txt.chrout('\n')
|
||||
ub = zero+strlen(s1)*1+zero
|
||||
txt.print_ub(ub)
|
||||
txt.chrout('\n')
|
||||
|
||||
leftstr(s1, result, 3)
|
||||
txt.print(result)
|
||||
txt.chrout('\n')
|
||||
leftstr(s1, result, len(s1))
|
||||
txt.print(result)
|
||||
txt.chrout('\n')
|
||||
txt.chrout('\n')
|
||||
|
||||
result = "x"*8
|
||||
rightstr(s2, result, 3)
|
||||
txt.print(result)
|
||||
txt.chrout('\n')
|
||||
rightstr(s2, result, len(s1))
|
||||
txt.print(result)
|
||||
txt.chrout('\n')
|
||||
|
||||
result = "y"*10
|
||||
substr(s2, result, 1, 3)
|
||||
txt.print(result)
|
||||
txt.chrout('\n')
|
||||
|
||||
void strcopy(s2, s1)
|
||||
txt.print_ub(99+strcopy(s2,s1))
|
||||
txt.chrout('\n')
|
||||
|
||||
test_stack.test()
|
||||
|
||||
}
|
||||
|
||||
sub integers() {
|
||||
ubyte[] ubarr = [1,2,3,4,5,0,4,3,2,1, 255, 255, 255]
|
||||
byte[] barr = [1,2,3,4,5,-4,0,-3,2,1, -128, -128, -127]
|
||||
|
@ -6,6 +6,7 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import diskio
|
||||
%import string
|
||||
%import test_stack
|
||||
%import perf2
|
||||
%import perf3
|
||||
@ -954,7 +955,7 @@ util {
|
||||
}
|
||||
|
||||
sub print_right(ubyte width, uword string) {
|
||||
repeat width - strlen(string) {
|
||||
repeat width - string.length(string) {
|
||||
txt.chrout(' ')
|
||||
}
|
||||
txt.print(string)
|
||||
|
@ -1,6 +1,7 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import diskio
|
||||
%import string
|
||||
%import test_stack
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
@ -944,7 +945,7 @@ util10 {
|
||||
}
|
||||
|
||||
sub print_right(ubyte width, uword string) {
|
||||
repeat width - strlen(string) {
|
||||
repeat width - string.length(string) {
|
||||
txt.chrout(' ')
|
||||
}
|
||||
txt.print(string)
|
||||
|
@ -1,6 +1,7 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import diskio
|
||||
%import string
|
||||
%import test_stack
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
@ -944,7 +945,7 @@ util2 {
|
||||
}
|
||||
|
||||
sub print_right(ubyte width, uword string) {
|
||||
repeat width - strlen(string) {
|
||||
repeat width - string.length(string) {
|
||||
txt.chrout(' ')
|
||||
}
|
||||
txt.print(string)
|
||||
|
@ -1,6 +1,7 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import diskio
|
||||
%import string
|
||||
%import test_stack
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
@ -944,7 +945,7 @@ util3 {
|
||||
}
|
||||
|
||||
sub print_right(ubyte width, uword string) {
|
||||
repeat width - strlen(string) {
|
||||
repeat width - string.length(string) {
|
||||
txt.chrout(' ')
|
||||
}
|
||||
txt.print(string)
|
||||
|
@ -1,6 +1,7 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import diskio
|
||||
%import string
|
||||
%import test_stack
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
@ -944,7 +945,7 @@ util4 {
|
||||
}
|
||||
|
||||
sub print_right(ubyte width, uword string) {
|
||||
repeat width - strlen(string) {
|
||||
repeat width - string.length(string) {
|
||||
txt.chrout(' ')
|
||||
}
|
||||
txt.print(string)
|
||||
|
@ -1,6 +1,7 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import diskio
|
||||
%import string
|
||||
%import test_stack
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
@ -944,7 +945,7 @@ util5 {
|
||||
}
|
||||
|
||||
sub print_right(ubyte width, uword string) {
|
||||
repeat width - strlen(string) {
|
||||
repeat width - string.length(string) {
|
||||
txt.chrout(' ')
|
||||
}
|
||||
txt.print(string)
|
||||
|
@ -1,6 +1,7 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import diskio
|
||||
%import string
|
||||
%import test_stack
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
@ -944,7 +945,7 @@ util6 {
|
||||
}
|
||||
|
||||
sub print_right(ubyte width, uword string) {
|
||||
repeat width - strlen(string) {
|
||||
repeat width - string.length(string) {
|
||||
txt.chrout(' ')
|
||||
}
|
||||
txt.print(string)
|
||||
|
@ -1,6 +1,7 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import diskio
|
||||
%import string
|
||||
%import test_stack
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
@ -944,7 +945,7 @@ util7 {
|
||||
}
|
||||
|
||||
sub print_right(ubyte width, uword string) {
|
||||
repeat width - strlen(string) {
|
||||
repeat width - string.length(string) {
|
||||
txt.chrout(' ')
|
||||
}
|
||||
txt.print(string)
|
||||
|
@ -1,6 +1,7 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import diskio
|
||||
%import string
|
||||
%import test_stack
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
@ -944,7 +945,7 @@ util8 {
|
||||
}
|
||||
|
||||
sub print_right(ubyte width, uword string) {
|
||||
repeat width - strlen(string) {
|
||||
repeat width - string.length(string) {
|
||||
txt.chrout(' ')
|
||||
}
|
||||
txt.print(string)
|
||||
|
@ -1,6 +1,7 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import diskio
|
||||
%import string
|
||||
%import test_stack
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
@ -944,7 +945,7 @@ util9 {
|
||||
}
|
||||
|
||||
sub print_right(ubyte width, uword string) {
|
||||
repeat width - strlen(string) {
|
||||
repeat width - string.length(string) {
|
||||
txt.chrout(' ')
|
||||
}
|
||||
txt.print(string)
|
||||
|
@ -1,6 +1,7 @@
|
||||
%target cx16
|
||||
%import test_stack
|
||||
%import textio
|
||||
%import string
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
@ -61,7 +62,7 @@ textparse {
|
||||
}
|
||||
|
||||
uword value = conv.any2uword(word_addrs[2])
|
||||
if strcmp("*", word_addrs[0])==0 {
|
||||
if word_addrs[0] == "*" { ; TODO does this string compare work?
|
||||
program_counter = value
|
||||
} else {
|
||||
set_symbol(word_addrs[0], value)
|
||||
@ -96,7 +97,7 @@ textparse {
|
||||
}
|
||||
|
||||
if label_ptr {
|
||||
uword lastlabelchar = label_ptr + strlen(label_ptr)-1
|
||||
uword lastlabelchar = label_ptr + string.length(label_ptr)-1
|
||||
if @(lastlabelchar) == ':'
|
||||
@(lastlabelchar) = 0
|
||||
if instructions.match(label_ptr) {
|
||||
@ -346,7 +347,7 @@ textparse {
|
||||
}
|
||||
if changed {
|
||||
@(dest)=0
|
||||
void strcopy(input_line2, src)
|
||||
string.copy(input_line2, src)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
%import gfx2
|
||||
%import textio
|
||||
%import diskio
|
||||
%import string
|
||||
%import koala_module
|
||||
%import iff_module
|
||||
%import pcx_module
|
||||
@ -14,7 +15,7 @@ main {
|
||||
sub start() {
|
||||
; trick to check if we're running on sdcard or host system shared folder
|
||||
txt.print("\nimage viewer for commander x16\nformats supported: .iff, .pcx, .bmp, .koa (c64 koala)\n\n")
|
||||
if strlen(diskio.status(8)) {
|
||||
if string.length(diskio.status(8)) {
|
||||
txt.print("enter image file name or just enter for all on disk: ")
|
||||
ubyte i = txt.input_chars(diskio.filename)
|
||||
gfx2.screen_mode(1) ; 320*240, 256c
|
||||
@ -54,7 +55,7 @@ main {
|
||||
;txt.print(filenameptr)
|
||||
;txt.chrout('\n')
|
||||
uword extension = filenameptr + rfind(filenameptr, '.')
|
||||
if strcmp(extension, ".iff")==0 {
|
||||
if extension == ".iff" { ; TODO does this compare work?
|
||||
;txt.print("loading ")
|
||||
;txt.print("iff\n")
|
||||
if iff_module.show_image(filenameptr) {
|
||||
@ -70,7 +71,7 @@ main {
|
||||
load_error(filenameptr)
|
||||
}
|
||||
}
|
||||
else if strcmp(extension, ".pcx")==0 {
|
||||
else if extension == ".pcx" { ; TODO works?
|
||||
;txt.print("loading ")
|
||||
;txt.print("pcx\n")
|
||||
if pcx_module.show_image(filenameptr) {
|
||||
@ -79,7 +80,7 @@ main {
|
||||
load_error(filenameptr)
|
||||
}
|
||||
}
|
||||
else if strcmp(extension, ".koa")==0 {
|
||||
else if extension == ".koa" { ; TODO works?
|
||||
;txt.print("loading ")
|
||||
;txt.print("koala\n")
|
||||
if koala_module.show_image(filenameptr) {
|
||||
@ -88,7 +89,7 @@ main {
|
||||
load_error(filenameptr)
|
||||
}
|
||||
}
|
||||
else if strcmp(extension, ".bmp")==0 {
|
||||
else if extension == ".bmp" { ; TODO works?
|
||||
;txt.print("loading ")
|
||||
;txt.print("bmp\n")
|
||||
if bmp_module.show_image(filenameptr) {
|
||||
@ -97,7 +98,7 @@ main {
|
||||
load_error(filenameptr)
|
||||
}
|
||||
}
|
||||
; else if strcmp(extension, ".ci")==0 {
|
||||
; else if extension == ".ci" {
|
||||
;; txt.print("loading ")
|
||||
;; txt.print("ci\n")
|
||||
; if ci_module.show_image(filenameptr) {
|
||||
@ -117,12 +118,12 @@ main {
|
||||
|
||||
sub extension_equals(uword stringptr, uword extensionptr) -> ubyte {
|
||||
ubyte ix = rfind(stringptr, '.')
|
||||
return ix<255 and strcmp(stringptr+ix, extensionptr)==0
|
||||
return ix<255 and string.compare(stringptr+ix, extensionptr)==0
|
||||
}
|
||||
|
||||
sub rfind(uword stringptr, ubyte char) -> ubyte {
|
||||
ubyte i
|
||||
for i in strlen(stringptr)-1 downto 0 {
|
||||
for i in string.length(stringptr)-1 downto 0 {
|
||||
if @(stringptr+i)==char
|
||||
return i
|
||||
}
|
||||
|
@ -1,11 +1,99 @@
|
||||
%import test_stack
|
||||
%import textio
|
||||
%import string
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
|
||||
; TODO: error when a parameter has the same name as an existing module/block/subroutine: sub print_right(ubyte width, uword string) {
|
||||
|
||||
|
||||
sub start() {
|
||||
str s1 = "irmen"
|
||||
str s2 = "what"
|
||||
str s3 = "irmen2"
|
||||
|
||||
s3[5] = 0
|
||||
|
||||
txt.print("length:\n")
|
||||
txt.print_ub(len(s1))
|
||||
txt.chrout('\n')
|
||||
txt.print_ub(string.length(s1))
|
||||
|
||||
txt.print("\n\ncopy:\n")
|
||||
txt.print(s3)
|
||||
txt.chrout('\n')
|
||||
s3 = s2
|
||||
txt.print(s3)
|
||||
txt.chrout('\n')
|
||||
txt.print_ub(string.copy("new", s3))
|
||||
txt.print(s3)
|
||||
|
||||
txt.print("\n\ncompare:\n")
|
||||
txt.chrout('\n')
|
||||
txt.print_ub(string.compare(s1, s2))
|
||||
txt.chrout('\n')
|
||||
txt.print_ub(string.compare(s2, s1))
|
||||
txt.chrout('\n')
|
||||
txt.print_ub(string.compare(s1, s3))
|
||||
txt.chrout('\n')
|
||||
txt.chrout('\n')
|
||||
txt.print_ub(s1==s2)
|
||||
txt.chrout('\n')
|
||||
txt.print_ub(s1<s2)
|
||||
txt.chrout('\n')
|
||||
txt.print_ub(s1>s2)
|
||||
txt.chrout('\n')
|
||||
|
||||
txt.print("\n\nleft:")
|
||||
string.left(s2,2,s3)
|
||||
txt.print(s3)
|
||||
txt.chrout('\n')
|
||||
txt.print("\n\nright:\n")
|
||||
txt.print(s2)
|
||||
txt.chrout('\n')
|
||||
string.right(s2,2,s3)
|
||||
txt.print(s3)
|
||||
txt.chrout('\n')
|
||||
|
||||
txt.print("\n\nfind:\n")
|
||||
txt.print(s1)
|
||||
txt.chrout('\n')
|
||||
uword found = string.find(s1, 'e')
|
||||
txt.print_uwhex(found, 1)
|
||||
if found
|
||||
txt.print(found)
|
||||
txt.chrout('\n')
|
||||
found = string.find(s1, 'i')
|
||||
txt.print_uwhex(found, 1)
|
||||
if found
|
||||
txt.print(found)
|
||||
txt.chrout('\n')
|
||||
found = string.find(s1, 'x')
|
||||
txt.print_uwhex(found, 1)
|
||||
if found
|
||||
txt.print(found)
|
||||
txt.chrout('\n')
|
||||
|
||||
txt.print("\n\nslice:\n")
|
||||
string.slice(s1, 0, 5, s2)
|
||||
txt.print(s2)
|
||||
txt.chrout('\n')
|
||||
string.slice(s1, 1, 4, s2)
|
||||
txt.print(s2)
|
||||
txt.chrout('\n')
|
||||
string.slice(s1, 2, 2, s2)
|
||||
txt.print(s2)
|
||||
txt.chrout('\n')
|
||||
string.slice(s1, 3, 2, s2)
|
||||
txt.print(s2)
|
||||
txt.chrout('\n')
|
||||
|
||||
test_stack.test()
|
||||
}
|
||||
|
||||
sub start2 () {
|
||||
str[] binstrings = [
|
||||
"",
|
||||
"%",
|
||||
@ -151,16 +239,16 @@ main {
|
||||
}
|
||||
|
||||
|
||||
; found = strfind("irmen de jong", ' ')
|
||||
; found = string.find("irmen de jong", ' ')
|
||||
; txt.print_uwhex(found, 1)
|
||||
; txt.chrout('\n')
|
||||
; found = strfind(" irmen-de-jong", ' ')
|
||||
; found = string.find(" irmen-de-jong", ' ')
|
||||
; txt.print_uwhex(found, 1)
|
||||
; txt.chrout('\n')
|
||||
; found = strfind("irmen-de-jong ", ' ')
|
||||
; found = string.find("irmen-de-jong ", ' ')
|
||||
; txt.print_uwhex(found, 1)
|
||||
; txt.chrout('\n')
|
||||
; found = strfind("irmen-de-jong", ' ')
|
||||
; found = string.find("irmen-de-jong", ' ')
|
||||
; txt.print_uwhex(found, 1)
|
||||
; txt.chrout('\n')
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import diskio
|
||||
%import string
|
||||
%import test_stack
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
@ -943,11 +944,11 @@ util {
|
||||
return false
|
||||
}
|
||||
|
||||
sub print_right(ubyte width, uword string) {
|
||||
repeat width - strlen(string) {
|
||||
sub print_right(ubyte width, uword s) {
|
||||
repeat width - string.length(s) {
|
||||
txt.chrout(' ')
|
||||
}
|
||||
txt.print(string)
|
||||
txt.print(s)
|
||||
}
|
||||
|
||||
asmsub print_10s(uword value @AY) clobbers(A, X, Y) {
|
||||
|
Loading…
Reference in New Issue
Block a user