While implementing the left-MID$ function in Wimbasic, I ran into CBM Basic's behaviour when dealing with string constants.
When a READ A$ or a A$="SOMESTRING" is performed, the A$ variable actually points to the program text. Only when a new string is built using GET A$, A$=STR$(X) or A$="SOME"+"STRING" memory is allocated from the top of Basic RAM and A$ points there.
My current implementation of the left-MID$ function performs the character substitution in-place and it convienently does nothing when A$ is in the program text. To come around this, A$ needs to be built at runtime.
Yet, I want the left-MID$ to work without this workaround, but I have only 15 bytes to spare for the code. How to fix this without inducing unnecessary garbage collections ?
Regards,
Wim.
LMIDSTR JSR $0073 ; READ TOKEN
JSR $CEFA ; CHECK OPEN PARENTHESIS
JSR $D08B ; READ VARNAME, RETURN POINTER
JSR $CD8F ; CHECK DATATYPE FOR STRING
STA $83 ; SAVE VARPTR
STY $84 ; SAVE VARPTR
JSR $CEFD ; CHECK COMMA
JSR $D79E ; READ BYTE
TXA
BEQ LA803
DEX
LDY #0
TXA
CMP ($83),Y
BCS LA803 ; START >= LENGTH OF TRGT$
STX $86 ; SAVE START
LDX #$FF
LDA ($7A),Y
CMP #$2C
BNE LNOLENGTH
JSR $D79B ; READ BYTE
LNOLENGTH STX $85 ; SAVE LENGTH
JSR $CEF7 ; CHECK CLOSED PARENTHESIS
LDA #$B2 ; TOKENIZED '='
JSR $CEFF ; CHECK EQUAL SIGN
JSR LGETSTR
STX $C1
STY $C2
CMP $85 ; LENGTH OF STRING < SPECIFICIED LENGTH
BCS LSHRTR1
STA $85
LSHRTR1 LDY #0
SEC
LDA ($83),Y
SBC $86
CMP $85 ; REMAINING LENGTH < DETERMINED LENGTH
BCS LSHRTR2
STA $85
LSHRTR2 LDA $85 ; DO NOTHING WHEN NOTHING TO DO
BEQ LMIDRET
INY
CLC
LDA ($83),Y ; ADD START TO TARGETBASE
ADC $86
TAX
INY
LDA ($83),Y
ADC #0
STA $B6
CPX $2D ; AND CHECK AGAINST END-OF-PROGRAM
SBC $2E
BCC LMIDRET ; DO NOTHING IF IT IS READONLY
STX $B5
LDY $85
LNXTCHR DEY
LDA ($C1),Y
STA ($B5),Y
TYA
BNE LNXTCHR
LMIDRET RTS