17.6.1.0245 /STRING slash-string STRING

( c-addr1 u1 n -- c-addr2 u2 )

Adjust the character string at c-addr1 by n characters. The resulting character string, specified by c-addr2 u2, begins at c-addr1 plus n characters and is u1 minus n characters long.

See:

Rationale:

/STRING is used to remove or add characters relative to the current position in the character string. Positive values of n will exclude characters from the string while negative values of n will include characters to the left of the string.

S" ABC" 2 /STRING 2DUP TYPE \ outputs "C"
-1 /STRING TYPE \ outputs "BC"

Testing:

T{ s1  5 /STRING -> s1 SWAP 5 + SWAP 5 - }T
T{ s1 10 /STRING -4 /STRING -> s1 6 /STRING }T
T{ s1  0 /STRING -> s1 }T

ContributeContributions

JimPetersonavatar of JimPeterson [203] Possible Reference ImplementationSuggested reference implementation2021-05-21 17:58:29

Would this be a sufficient reference implementation?:

: /STRING  DUP >R - SWAP R> CHARS + SWAP ;

Are there no checks for when u2 might go negative (or, really, wraps around, as it's considered unsigned)?

ruvavatar of ruv

Are there no checks for when u2 might go negative?

Formally, u2 cannot be negative since it's an unsigned number (a number that is interpreted as an unsigned number). See data type symbols and their meaning.

In some use-cases it could be a problem if n > u1, but it's out of the scope of the standard, if a user tries to shoot himself in the foot. OTOH, it could be a correct and expected intermediate result.

Would this be a sufficient reference implementation?

Yes, I think. Other possible variants:

: /string ( c-addr1 u1 n -- c-addr2 u2 ) tuck - >r chars + r> ;
: /string ( c-addr1 u1 n -- c-addr2 u2 ) tuck - -rot chars + swap ;

AntonErtlavatar of AntonErtl

Gforth, iForth, lxf, SwiftForth 3.11, and VFX 5.11 do not check for n<=u; so if n>u, the result is broken (I explored whether you could do something useful with strings with negative length, but did not come up with anything). I dimly remember that there are systems where /STRING behaves like OVER MIN /STRING, so the resulting string is always valid, but I don't remember which systems behave that way.

JimPetersonavatar of JimPeterson

I prefer your first implementation over the other two options. It seems like it would be the most efficient on many systems.

Reply New Version