GARTHWILSON wrote:
Is that different from " which puts the string in the pad (if you're in interpretation mode, ie, not compiling a string literal)?
That seems like a reasonable word, but I couldn't find it anywhere in FIG or any of the ANS standards from 79 onwards.
ANS2012 requires the ability to define up to two such strings, so I ended up making my own temporary string handling words, but I did use your suggested name of just " for a temporary string.
Eventually I will need to modify my code to make S" use this temporary string behavior when interpreted and it's original "compile it into the dictionary" behavior when it's compiled. I do like how you can extend a Forth word and use the old word in the definition. I'm still playing around with getting things right, so I haven't taken that step yet.
These are the words I came up with for handling temporary strings as well as filename strings. A filename string comes in like "NAME.EXT" and needs to be expanded out to 11 chars with the . removed, which would look like "NAME(4 spaces here)EXT". This is how the file names are actually stored in a directory entry.
Code:
decimal
( Temporary strings for filenames )
80 constant stringsize ( 80 char strings )
2 constant #strings
create stringsbuff stringsize #strings * allot
variable whichstring
hex
: nextstring ( -- caddr ) ( Determine next string addr )
whichstring @ 1+ #strings mod ( Determine which is next )
dup whichstring ! ( Update the variable for later )
stringsize * stringsbuff + ; ( Calculate address )
: " ( ccc" -- c-addr u ) ( Put a string into stringsbuff )
[char] " parse
stringsize min ( No more than 80 chars )
nextstring ( Use the next available temporary string )
swap 2dup 2>r cmove ( Copy into the current string )
2r> ; ( c-addr u for result left on stack )
: dotindex ( caddr u -- u2 ) ( Find the . in a filename )
( Return 0 if not found - or filename starts with . )
0 ?do
dup c@ [char] . = if drop i unloop exit then 1+
loop ( If we made it here, no . )
drop 0 ;
: string>filename ( caddr u -- caddr2 u2 )
( Convert a regular filename string into diraddr format )
( "FNAME.EXT" becomes "FNAME EXT" )
nextstring dup 0B blank ( Start with blank filename )
dup >r ( Save location for later )
-rot ( ^ dest src u )
0C min ( No more than 12 chars for filename.ext )
2dup dotindex ( See if there is a . in the filename )
( ^ dest src u udot )
?dup 0= if ( No . so copy whole filename )
rot swap move ( Copy whole string )
else
( Figure out how many chars in ext and save )
swap over - 1- >r ( ^ dest src udot )
2dup + 1+ >r ( addr after . ^ dest src udot )
>r over r> move ( ^ dest )
8 + ( Move to extension in destination )
r> swap r> ( Bring back source after . ^ srcext destext uext )
move
then
r> ( Bring back original temp string ) 0B ;
: f" ( ccc" -- caddr u )
( Accept a filename and convert to dirinfo format )
[char] " parse string>filename ;
For now, I'm, using F" to enter filenames and have them converted to dirinfo format for my words that currently expect that. Eventually I will modify the routines that take filenames to all use STRING>FILENAME so that regular "name.ext" type names can be used directly. With the temporary strings out of the way, I can now work on changing directories:
Code:
: cd ( caddr u -- ) ( Change the working directory )
string>filename drop
working_dir init_directory ( Start at the beginning of dir )
( Address of dirname in dirinfo format is on the stack )
['] findfile working_dir walkdirectory
( working_dir_fileid direntry )
?dup 0= if
cr ." Can't find directory: " dup 0B type cr exit
then
( working_dir_fileid direntry )
swap drop ( Get rid of working_dir_fileid for now )
dup >clustLOW @ swap >clustHI @ ( Get starting cluster )
2dup d0= if ( Check for zero - meaning use root dir )
( Replace with correct cluster for root dir )
2drop root_dir_first_cluster 2@
then
( directory_firstcluster.d )
( Save everything to move to the new directory )
working_dir >firstcluster 2! ( Fill in starting cluster )
working_dir init_directory ; ( Fill in all the rest )
And finally, a short demo. My LS word has been modified to show the attributes, which will show a "D" for directories. The names are still case sensitive (on my to-do list), so I have to enter the directory names in uppercase here
Code:
ls
FILENAME ATTRIB SIZE
LCD .FS A 668
REDIRECT.FS A 978
SCREENS .FS A 2579
BLOCK .BLK A 15360
FORTH . D 0
STUFF . D 0 ok
ok
" STUFF" cd ok
ls
FILENAME ATTRIB SIZE
. . D 0
.. . D 0
MORESTUF. D 0
COPYING .TXT A 679 ok
ok
" MORESTUF" cd ok
ls
FILENAME ATTRIB SIZE
. . D 0
.. . D 0
HEADERS .ASM A 55122
NATIVE~1.ASM A 369836
README .MD A 3299 ok
ok
" .." cd ok
ls
FILENAME ATTRIB SIZE
. . D 0
.. . D 0
MORESTUF. D 0
COPYING .TXT A 679 ok
" noexist" cd
Can't find directory: noexist
ok