Simple String Manipulation Words for Forth

  1. Summary

      Here is an old Forth strings library I used many years ago, circa 1987. It was originally used with Forth-79 and Forth-83 kernels. The main inspiration came from the book "Library of Forth Routines and Utilities", ISBN 0-452-25841-3. The code below has been modified to work on GFORTH, a decidedly modern Forth, and other segmented-memory Forths.

  1. Code
       \ Super simple strings package for Forth (circa 1987, Forth79 and Forth83)
       \ Modified for GFORTH 2009-12-10
       \
       \ String Format:
       \	size	byte	alloted string size
       \	count	byte	size of stored string
       \	string	bytes	string data
       \
       \ When executed a string variable returns the address of the count field so
       \ the standard of Forth's counted strings is maintained.
      
       \ because gforth doesn't have it
       : c+! ( n caddr - ) dup c@ rot + swap c! ;
      
       \ create a string variable and allocate it's storage
       \ string length initialized to 0
       \ usage: 55 $variable ted$
       : $variable ( u - ) ( - caddr )
         create   $FF and   dup c, 0 c, allot does> 1+ ;
      
       \ create a string constant
       \ usage: $constant ted$ test string data"
       : $constant ( - ) ( - caddr ) create char " word c@ 1+ allot ;
      
       \ fetch a string (well, just count it)
       \ caddr1 is the address of a counted string
       : $@ ( caddr1 - caddr2 count ) count ;
      
       \ print a string
       \ caddr is the address of a counted string
       : $. ( caddr - ) count type ;
      
       \ return the length of a string
       \ caddr is the address of a counted string
       : len$ ( caddr - n ) c@ ;
      
       \ return the size of a strings allocated space
       \ caddr is the address of a counted string variable (requires size)
       : size$ ( caddr - n ) 1- c@ ;
      
       \ return the unused space in a string variable
       : unused$ ( caddr - u ) dup size$ swap len$ - ;
      
       \ clear a string, just set the length to 0
       : clr$ ( caddr - ) 0 swap c! ;
      
       \ return copy count limited by the string size
       \ count is the count of the desired characters to copy
       : countlimit ( count caddr - u ) unused$ min ;
      
       \ return the address of the end of a string
       \ abcdef
       \       ^ meaning this address (just past the f)
       : end$ ( caddr1 - caddr2 ) dup len$ + 1+ ;
      
       \ append an un-counted string (caddr1 count1) to a string variable (caddr2)
       \ extra characters from caddr1 are lost
       : #$+! ( caddr1 count1 caddr2 - )
         dup >r   dup end$ -rot ( caddr1 caddr2e count1 caddr2 )
         countlimit dup >r   move   r> r> c+! ;
      
       \ append a counted string (caddr1) to a string variable (caddr2)
       \ extra characters from caddr1 are lost
       : $+! ( caddr1 caddr2 - ) swap count rot #$+! ;
      
       \ store a un-counted string (caddr1 count1) into a string variable (caddr2)
       \ extra characters in un-counted string are lost
       : #$! ( caddr1 count1 caddr2 - ) dup clr$ #$+! ;
      
       \ store a counted string (caddr1) into a string variable (caddr2)
       \ extra characters from caddr1 are lost
       : $! ( caddr1 caddr2 - ) swap count rot #$! ;
      
       \ compare a string (caddr1 count1) to a string variable (caddr2)
       : #$= ( caddr1 count1 caddr2 - n ) count compare ;
      
       \ compare two string variables
       : $= ( caddr1 caddr2 - n ) swap count rot #$= ;
      
       \ Words borrowed from BASIC but make me feel comfortable
      
       \ return n characters from left side of a string variable
       \ count will not exceed the actual number of characters in the string
       : left$ ( n caddr1 - caddr2 count ) count rot min ;
      
       \ return n characters from right side of a string variable
       \ count will not exceed the actual number of characters in the string
       : right$ ( n caddr1 - caddr2 count ) count rot over   swap - 0 max   /string ;
      
       \ return n2 characters from string variable starting from n1
       \ count will not exceed the actual number of characters in the string
       : mid$ ( n1 n2 caddr1 - caddr2 count ) -rot over +   rot left$   rot /string ; 
  1. Examples
       100 $variable ted$
       s" 0123456789" ted$ #$!
       ted$ $. 0123456789 ok
       100 $variable ned$
       s" abcdef" ned$ #$!
       ned$ ted$ $+!
       ted$ $. 0123456789abcdef ok
       2 3 ted$ mid$ type 234 ok
       ted$ ned$ $!
       ned$ $. 0123456789abcdef ok 
  1. License

      This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License.

      This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

      You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

  1. Credits
       Copyright © 2009 Noel Henson					Updated: 2009-12-10
       noel@noels-lab.com