mirror of
https://github.com/irmen/prog8.git
synced 2025-02-18 05:30:34 +00:00
added string value assignment, leftstr, rightstr, substr functions
This commit is contained in:
parent
68a7f9c665
commit
ceb2c9e4f8
@ -2078,3 +2078,127 @@ ror2_array_uw .proc
|
|||||||
sta (c64.SCRATCH_ZPWORD1),y
|
sta (c64.SCRATCH_ZPWORD1),y
|
||||||
+ rts
|
+ rts
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
|
|
||||||
|
strcpy .proc
|
||||||
|
; copy a string (0-terminated) from A/Y to (ZPWORD1)
|
||||||
|
; it is assumed the target string is large enough.
|
||||||
|
sta c64.SCRATCH_ZPWORD2
|
||||||
|
sty c64.SCRATCH_ZPWORD2+1
|
||||||
|
ldy #$ff
|
||||||
|
- iny
|
||||||
|
lda (c64.SCRATCH_ZPWORD2),y
|
||||||
|
sta (c64.SCRATCH_ZPWORD1),y
|
||||||
|
bne -
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
|
||||||
|
func_leftstr .proc
|
||||||
|
; leftstr(source, target, length) with params on stack
|
||||||
|
inx
|
||||||
|
lda c64.ESTACK_LO,x
|
||||||
|
tay ; length
|
||||||
|
inx
|
||||||
|
lda c64.ESTACK_LO,x
|
||||||
|
sta c64.SCRATCH_ZPWORD2
|
||||||
|
lda c64.ESTACK_HI,x
|
||||||
|
sta c64.SCRATCH_ZPWORD2+1
|
||||||
|
inx
|
||||||
|
lda c64.ESTACK_LO,x
|
||||||
|
sta c64.SCRATCH_ZPWORD1
|
||||||
|
lda c64.ESTACK_HI,x
|
||||||
|
sta c64.SCRATCH_ZPWORD1+1
|
||||||
|
lda #0
|
||||||
|
sta (c64.SCRATCH_ZPWORD2),y
|
||||||
|
- dey
|
||||||
|
cpy #$ff
|
||||||
|
bne +
|
||||||
|
rts
|
||||||
|
+ lda (c64.SCRATCH_ZPWORD1),y
|
||||||
|
sta (c64.SCRATCH_ZPWORD2),y
|
||||||
|
jmp -
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_rightstr .proc
|
||||||
|
; rightstr(source, target, length) with params on stack
|
||||||
|
; make place for the 4 parameters for substr()
|
||||||
|
dex
|
||||||
|
dex
|
||||||
|
dex
|
||||||
|
dex
|
||||||
|
; X-> .
|
||||||
|
; x+1 -> length of segment
|
||||||
|
; x+2 -> start index
|
||||||
|
; X+3 -> target LO+HI
|
||||||
|
; X+4 -> source LO+HI
|
||||||
|
; original parameters:
|
||||||
|
; x+5 -> original length LO
|
||||||
|
; x+6 -> original targetLO + HI
|
||||||
|
; x+7 -> original sourceLO + HI
|
||||||
|
; replicate paramters:
|
||||||
|
lda c64.ESTACK_LO+5,x
|
||||||
|
sta c64.ESTACK_LO+1,x
|
||||||
|
lda c64.ESTACK_LO+6,x
|
||||||
|
sta c64.ESTACK_LO+3,x
|
||||||
|
lda c64.ESTACK_HI+6,x
|
||||||
|
sta c64.ESTACK_HI+3,x
|
||||||
|
lda c64.ESTACK_LO+7,x
|
||||||
|
sta c64.ESTACK_LO+4,x
|
||||||
|
sta c64.SCRATCH_ZPWORD1
|
||||||
|
lda c64.ESTACK_HI+7,x
|
||||||
|
sta c64.ESTACK_HI+4,x
|
||||||
|
sta c64.SCRATCH_ZPWORD1+1
|
||||||
|
; determine string length
|
||||||
|
ldy #0
|
||||||
|
- lda (c64.SCRATCH_ZPWORD1),y
|
||||||
|
beq +
|
||||||
|
iny
|
||||||
|
bne -
|
||||||
|
+ tya
|
||||||
|
sec
|
||||||
|
sbc c64.ESTACK_LO+1,x ; start index = strlen - segment length
|
||||||
|
sta c64.ESTACK_LO+2,x
|
||||||
|
jsr func_substr
|
||||||
|
; unwind original params
|
||||||
|
inx
|
||||||
|
inx
|
||||||
|
inx
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_substr .proc
|
||||||
|
; substr(source, target, start, length) with params on stack
|
||||||
|
inx
|
||||||
|
ldy c64.ESTACK_LO,x ; length
|
||||||
|
inx
|
||||||
|
lda c64.ESTACK_LO,x ; start
|
||||||
|
sta c64.SCRATCH_ZPB1
|
||||||
|
inx
|
||||||
|
lda c64.ESTACK_LO,x
|
||||||
|
sta c64.SCRATCH_ZPWORD2
|
||||||
|
lda c64.ESTACK_HI,x
|
||||||
|
sta c64.SCRATCH_ZPWORD2+1
|
||||||
|
inx
|
||||||
|
lda c64.ESTACK_LO,x
|
||||||
|
sta c64.SCRATCH_ZPWORD1
|
||||||
|
lda c64.ESTACK_HI,x
|
||||||
|
sta c64.SCRATCH_ZPWORD1+1
|
||||||
|
; adjust src location
|
||||||
|
clc
|
||||||
|
lda c64.SCRATCH_ZPWORD1
|
||||||
|
adc c64.SCRATCH_ZPB1
|
||||||
|
sta c64.SCRATCH_ZPWORD1
|
||||||
|
bcc +
|
||||||
|
inc c64.SCRATCH_ZPWORD1+1
|
||||||
|
+ lda #0
|
||||||
|
sta (c64.SCRATCH_ZPWORD2),y
|
||||||
|
jmp _startloop
|
||||||
|
- lda (c64.SCRATCH_ZPWORD1),y
|
||||||
|
sta (c64.SCRATCH_ZPWORD2),y
|
||||||
|
_startloop dey
|
||||||
|
cpy #$ff
|
||||||
|
bne -
|
||||||
|
rts
|
||||||
|
|
||||||
|
.pend
|
||||||
|
@ -1 +1 @@
|
|||||||
2.1
|
2.2-SNAPSHOT
|
||||||
|
@ -773,6 +773,21 @@ internal class AssignmentAsmGen(private val program: Program, private val errors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DataType.STR -> {
|
||||||
|
val identifier = assign.value as? IdentifierReference
|
||||||
|
?: throw AssemblyError("string value assignment expects identifier value")
|
||||||
|
val sourceName = asmgen.asmIdentifierName(identifier)
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$targetName
|
||||||
|
sta ${C64Zeropage.SCRATCH_W1}
|
||||||
|
lda #>$targetName
|
||||||
|
sta ${C64Zeropage.SCRATCH_W1+1}
|
||||||
|
lda #<$sourceName
|
||||||
|
ldy #>$sourceName
|
||||||
|
jsr prog8_lib.strcpy
|
||||||
|
""")
|
||||||
|
return true
|
||||||
|
}
|
||||||
else -> throw AssemblyError("assignment to identifier: invalid target datatype: $targetType")
|
else -> throw AssemblyError("assignment to identifier: invalid target datatype: $targetType")
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
@ -87,7 +87,20 @@ val BuiltinFunctions = mapOf(
|
|||||||
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),
|
||||||
"strlen" to FSignature(true, listOf(FParam("string", setOf(DataType.STR))), DataType.UBYTE, ::builtinStrlen)
|
"strlen" to FSignature(true, listOf(FParam("string", setOf(DataType.STR))), DataType.UBYTE, ::builtinStrlen),
|
||||||
|
"substr" to FSignature(false, listOf(
|
||||||
|
FParam("source", IterableDatatypes + DataType.UWORD),
|
||||||
|
FParam("target", IterableDatatypes + DataType.UWORD),
|
||||||
|
FParam("start", setOf(DataType.UBYTE)),
|
||||||
|
FParam("length", setOf(DataType.UBYTE))), null),
|
||||||
|
"leftstr" to FSignature(false, listOf(
|
||||||
|
FParam("source", IterableDatatypes + DataType.UWORD),
|
||||||
|
FParam("target", IterableDatatypes + DataType.UWORD),
|
||||||
|
FParam("length", setOf(DataType.UBYTE))), null),
|
||||||
|
"rightstr" to FSignature(false, listOf(
|
||||||
|
FParam("source", IterableDatatypes + DataType.UWORD),
|
||||||
|
FParam("target", IterableDatatypes + DataType.UWORD),
|
||||||
|
FParam("length", setOf(DataType.UBYTE))), null)
|
||||||
)
|
)
|
||||||
|
|
||||||
fun builtinMax(array: List<Number>): Number = array.maxBy { it.toDouble() }!!
|
fun builtinMax(array: List<Number>): Number = array.maxBy { it.toDouble() }!!
|
||||||
|
@ -156,7 +156,7 @@ Design principles and features
|
|||||||
- The compiler tries to optimize the program and generated code a bit, but hand-tuning of the
|
- The compiler tries to optimize the program and generated code a bit, but hand-tuning of the
|
||||||
performance or space-critical parts will likely still be required. This is supported by
|
performance or space-critical parts will likely still be required. This is supported by
|
||||||
the ability to easily write embedded assembly code directly in the program source code.
|
the ability to easily write embedded assembly code directly in the program source code.
|
||||||
- There are many built-in functions, such as ``sin``, ``cos``, ``rnd``, ``abs``, ``min``, ``max``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``swap``, ``memset``, ``memcopy``, ``sort`` and ``reverse``
|
- There are many built-in functions, such as ``sin``, ``cos``, ``rnd``, ``abs``, ``min``, ``max``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``swap``, ``memset``, ``memcopy``, ``substr``, ``sort`` and ``reverse`` (and others)
|
||||||
- Assembling the generated code into a program wil be done by an external cross-assembler tool.
|
- Assembling the generated code into a program wil be done by an external cross-assembler tool.
|
||||||
|
|
||||||
|
|
||||||
|
@ -279,16 +279,23 @@ This @-prefix can also be used for character byte values.
|
|||||||
|
|
||||||
|
|
||||||
You can concatenate two string literals using '+' (not very useful though) or repeat
|
You can concatenate two string literals using '+' (not very useful though) or repeat
|
||||||
a string literal a given number of times using '*'::
|
a string literal a given number of times using '*'. You can also assign a new string
|
||||||
|
value to another string. No bounds check is done so be sure the destination string is
|
||||||
|
large enough to contain the new value::
|
||||||
|
|
||||||
str string1 = "first part" + "second part"
|
str string1 = "first part" + "second part"
|
||||||
str string2 = "hello!" * 10
|
str string2 = "hello!" * 10
|
||||||
|
|
||||||
|
string1 = string2
|
||||||
|
string1 = "new value"
|
||||||
|
|
||||||
|
|
||||||
.. caution::
|
.. caution::
|
||||||
Avoid changing strings after they've been created.
|
It's probably best to avoid changing strings after they've been created. This
|
||||||
|
includes changing certain letters by index, or by assigning a new value, or by
|
||||||
|
modifying the string via other means for example ``substr`` function and its cousins.
|
||||||
This is because if your program exits and is restarted (without loading it again),
|
This is because if your program exits and is restarted (without loading it again),
|
||||||
it will then start working with the changed strings instead of the original ones.
|
it will then start working with the changed strings instead of the original ones!
|
||||||
The same is true for arrays.
|
The same is true for arrays.
|
||||||
|
|
||||||
|
|
||||||
@ -802,6 +809,22 @@ memsetw(address, numwords, wordvalue)
|
|||||||
Efficiently set a part of memory to the given (u)word value.
|
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!
|
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.
|
||||||
|
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.
|
||||||
|
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
||||||
|
|
||||||
|
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.
|
||||||
|
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
||||||
|
|
||||||
swap(x, y)
|
swap(x, y)
|
||||||
Swap the values of numerical variables (or memory locations) x and y in a fast way.
|
Swap the values of numerical variables (or memory locations) x and y in a fast way.
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ TODO
|
|||||||
====
|
====
|
||||||
|
|
||||||
- finalize (most) of the still missing "new" assignment asm code generation
|
- finalize (most) of the still missing "new" assignment asm code generation
|
||||||
|
|
||||||
- aliases for imported symbols for example perhaps '%alias print = c64scr.print'
|
- aliases for imported symbols for example perhaps '%alias print = c64scr.print'
|
||||||
- option to load library files from a directory instead of the embedded ones (easier library development/debugging)
|
- option to load library files from a directory instead of the embedded ones (easier library development/debugging)
|
||||||
- investigate support for 8bitguy's Commander X16 platform https://murray2.com/forums/commander-x16.9/ and https://github.com/commanderx16/x16-docs
|
- investigate support for 8bitguy's Commander X16 platform https://murray2.com/forums/commander-x16.9/ and https://github.com/commanderx16/x16-docs
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
%import c64lib
|
|
||||||
%zeropage basicsafe
|
|
||||||
|
|
||||||
main {
|
|
||||||
|
|
||||||
sub start() {
|
|
||||||
|
|
||||||
str s1 = "apple"
|
|
||||||
str s2 = "banana"
|
|
||||||
byte[] a1 = [66,77,88,0]
|
|
||||||
ubyte i1 = 101
|
|
||||||
uword w1 = 000
|
|
||||||
|
|
||||||
c64.STROUT(s1)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
c64.STROUT(a1)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
c64scr.print("bla\n")
|
|
||||||
|
|
||||||
; c64scr.print_uwhex(s1, true)
|
|
||||||
; w1 = &s1
|
|
||||||
; c64scr.print_uwhex(w1, true)
|
|
||||||
;
|
|
||||||
; c64scr.print_uwhex(a1, true)
|
|
||||||
; w1 = &a1
|
|
||||||
; c64scr.print_uwhex(w1, true)
|
|
||||||
;
|
|
||||||
; s1 = s1
|
|
||||||
; s1 = s2
|
|
||||||
; s2 = "zzz"
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user