+TheBF Posted October 16, 2020 Author Share Posted October 16, 2020 ?Burnt Neurons? Well it took me long enough but after reviewing the Forth Standard web site and a couple of other implementations I finally have a pretty good version of WORDLISTs and VOCABULARY for Camel99 Forth. Pointers to pointers can make me crazy and I had to make some internal changes to the Camel Forth kernel which was not built for this business. FIND is now a vectored word in the kernel so I can replace its functionality with FIND12 in this file. I also needed a CURRENT variable and CONTEXT array of 9 cells and the word HEADER which creates names in the dictionary needed a tweek as well. WORDLIST and VOCABULARY and this lexicon address the issue of NAMESPACE control in a Forth system. The nice thing about these new ideas is that you can make the search order of the namespaces anything you want, in this case limited to 8 different name spaces. Or you can just make an abstract WORDLIST and use these operations on them more manually. Here is the code. It could use some improvements for SET-ORDER and GET-ORDER which are right off the Forth- Standard.org. The 2012 standard assumes you have a pretty big machine, so it's kind of bulky. But after two weeks of playing with this I am going to leave it working for now. I need to explore the 4 way hashed dictionary concept from F83 Forth too because I really need to burn more brain cells with even more pointers... ? But more seriously speeding up compilation by a factor of 3X would make Camel99 compile at 30 lines/second! I will do a demonstration video at some point of how these wordlists are used. If anyone wants a version of the newest kernel & libs let me know. Otherwise I will hang on until I get this fast compiling working. It doesn't look like much but I had never delved into this area before so it was stretching me. Edit: replaced with final code. Now ONLY puts two copies of the ROOT-WORDLIST in the context array so there is always one copy available to the system. ROOT vocabulary is now not needed. Spoiler \ wordlist.fth for CAMEL99 FORTH Oct 2020 Brian Fox \ Code adapted from Web: https://forth-standard.org/standard/search \ 'wid' is a word-list ID. \ Holds the address of the last Forth word in the list \ In Camel Forth terms, wid is a pointer to a Name field address (NFA) \ This implementation uses a pre-defined CONTEXT array to hold the \ ROOT wordlist plus 8 user defined wordlists \ NEEDS .S FROM DSK1.TOOLS HERE DECIMAL 9 CONSTANT #WIDS \ max no. of wordlists VARIABLE #ORDER \ No. of active wordlists 1 #ORDER ! \ init the #order to 1 VARIABLE WID-LINK \ Pointer to the most recently defined wordlist. : (WORDLIST) ( addr -- wid) 0 , \ "LATEST" for this word list WID-LINK @ , WID-LINK ! \ link to previous wordlist (none) LATEST @ , \ compile NFA of latest word created ; \ non-standard: named wordlist : WORDLIST ( <name> -- wid) CREATE HERE (WORDLIST) ; WORDLIST FORTH-WORDLIST WORDLIST ROOT-WORDLIST HEX ( make ASM version) : ]CONTEXT ( n -- addr) CELLS CONTEXT + ; \ CONTEXT array \ E.16.6.1.1647 GET-ORDER : GET-ORDER ( -- widn ... wid1 n ) \ *Notice reversed order on stack #ORDER @ 0 ?DO #ORDER @ I - 1- ]CONTEXT @ LOOP #ORDER @ ; \ E.16.6.1.2197 SET-ORDER \ This is the complement of E.16.6.1.1647 GET-ORDER. DECIMAL : SET-ORDER ( wid1x ... wid1 n -- ) \ n cannot be 0 DUP TRUE = IF DROP \ drop flag, push default wordlists ROOT-WORDLIST DUP 2 \ 2 copies of ROOT so it's always there THEN DUP 9 1 WITHIN ABORT" #ORDER range[1..8]" DUP #ORDER ! 0 ?DO I ]CONTEXT ! LOOP ; \ E.16.6.2.0715 ALSO : ALSO ( -- ) GET-ORDER OVER SWAP 1+ SET-ORDER ; \ E.16.6.2.1965 ONLY : ONLY ( -- ) TRUE SET-ORDER ; \ sets default search order \ E.16.6.2.2037 PREVIOUS : PREVIOUS ( -- ) GET-ORDER NIP 1- SET-ORDER ; : SET-CURRENT ( wid --) CURRENT ! ; : SET-CONTEXT ( wid -- ) \ place 'wid' at beginning of search order >R GET-ORDER NIP \ remove 1st 'wid' R> \ put this 'wid in the order SWAP SET-ORDER ; \ make it so : DEFINITIONS ( -- ) CONTEXT @ SET-CURRENT ; \ non-standard but nice to have : VOCABULARY ( wid -- ) \ create a named vocabulary CREATE HERE 2+ , \ pointer to the wid HERE (WORDLIST) \ create the wordlist structure DOES> @ SET-CONTEXT ; HEX : .WID ( wid -- ) [ 2 CELLS ] LITERAL + @ COUNT 1F AND TYPE ; : ORDER ( -- ) \ display search order by wordlist name CR ." Order: " GET-ORDER 0 DO .WID SPACE LOOP CR ." Current: " CURRENT @ .WID CR ; \ 6.1.1550 Extend FIND to search all active wordlists \ Find the definition named in the counted string at c-addr. : FIND12 ( c-addr -- c-addr 0 | xt 1 | xt -1 ) FALSE \ default flag CONTEXT #ORDER @ CELLS BOUNDS \ compute end-address,start-address ?DO \ I is the address for faster searches OVER I @ @ (FIND) ?DUP IF 2SWAP 2DROP UNLOOP EXIT THEN DROP 2 +LOOP ; \ : ROOT ( -- ) ROOT-WORDLIST SET-CONTEXT ; : FORTH ( -- ) FORTH-WORDLIST SET-CONTEXT ; LATEST @ FORTH-WORDLIST ! \ patch FORTH-WORDLIST to this point FORTH-WORDLIST SET-CONTEXT ROOT-WORDLIST SET-CURRENT \ compile into ROOT-WORDLIST \ " minimum search order shall include the words FORTH-WORDLIST & SET-ORDER" : FORTH-WORDLIST FORTH-WORDLIST ; : SET-ORDER SET-ORDER ; : FORTH FORTH ; \ : ROOT ROOT ; : ONLY ONLY ; : ALSO ALSO ; : ORDER ORDER ; : DEFINITIONS DEFINITIONS ; ONLY FORTH DEFINITIONS \ patch FIND to become FIND12 ' FIND12 'FIND ! HERE SWAP - DECIMAL SPACE . .( bytes) CR HEX 1 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 16, 2020 Share Posted October 16, 2020 1 hour ago, TheBF said: Well it took me long enough but after reviewing the Forth Standard web site and a couple of other implementations I finally have a pretty good version of WORDLISTs and VOCABULARY for Camel99 Forth. . . . I have only scanned it, so certainly have not assimilated it, but I am confused by a couple of things (doesn’t take much!): I don’t understand the second to last definition. Is it mistyped—( ' FIND12 ' FIND ! )? It is not fair to ask this question without reading what you have read, but what is the ROOT word list for and why would one need re-definitions to place words there? Yeah, my head hurts a little, too—and I have not dug as deep as you have. ...lee Quote Link to comment Share on other sites More sharing options...
GDMike Posted October 16, 2020 Share Posted October 16, 2020 (edited) I too noticed that word and thought, that's, ok, strange looking, maybe it's some part of array or something? But I can't really question it either. But I'll get to using it one day ? Edited October 16, 2020 by GDMike Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 16, 2020 Author Share Posted October 16, 2020 8 hours ago, Lee Stewart said: I have only scanned it, so certainly have not assimilated it, but I am confused by a couple of things (doesn’t take much!): I don’t understand the second to last definition. Is it mistyped—( ' FIND12 ' FIND ! )? It is not fair to ask this question without reading what you have read, but what is the ROOT word list for and why would one need re-definitions to place words there? Yeah, my head hurts a little, too—and I have not dug as deep as you have. ...lee If you look closely you see the second ' is part of find. ' FIND12 'FIND ! 'FIND is a variable. I used the tick to remind me that it is the "address of something". I have seen this mnemonic usage from others. And FIND is defined as : FIND 'FIND PERFORM ; PERFORM is a new word that is like "@ EXECUTE" in ALC so it's a bit faster. So whatever execution token (CFA) I stuff into 'FIND gets executed when you run FIND. It's a manual way to do a DEFER word thing without adding all the overhead to my tiny kernel. I do the same thing for INTERPRET because I needed a forward reference to INTERPRET in the cross-compiling process but that's another story. Suffice to say I had the mechanism so I am using it to patch the FIND word to allow search order control after the kernel has been built. A lot of Forth kernels used DEFER words for multiple parts of the system so that you can change their operation as needed for special cases. ROOT So this is part of the Forth 83 and forward ideas on VOCABULARIES. If the programmer is free to change the search order what happens if they remove FORTH from the search order? The word ONLY is there to revert back to some default set of words that will let you get back home to FORTH. This is actually a bug in my current code. I need to LOCK the ROOT vocabulary in [0]CONTEXT of the CONTEXT array and never move it and allow the programmer to only change 1 .. 8. That's on my list for today. 2 Quote Link to comment Share on other sites More sharing options...
GDMike Posted October 16, 2020 Share Posted October 16, 2020 (edited) "used the tick to remind me that it is the "address of something". " Ooooh, I like that!!! Very interesting Edited October 16, 2020 by GDMike 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 16, 2020 Author Share Posted October 16, 2020 44 minutes ago, TheBF said: This is actually a bug in my current code. I need to LOCK the ROOT vocabulary in [0]CONTEXT of the CONTEXT array and never move it and allow the programmer to only change 1 .. 8. That's on my list for today. Actually simplest thing to do is make ONLY put both the ROOT wordlist and the FORTH-WORDLIST in the search order. That's as easy as: : SET-ORDER ( wid1x ... wid1 n -- ) \ n cannot be 0 DUP TRUE = IF DROP \ drop the flag, push default wordlist and no. of lists ROOT FORTH-WORDLIST 2 \ default to ROOT and FORTH-WORDLIST THEN DUP 10 1 WITHIN ABORT" #ORDER range[1..9]" DUP #ORDER ! 0 ?DO I ]CONTEXT ! LOOP ; Which begs the question do I even need a ROOT wordlist? Just make Forth the default. when ONLY is executed. Things to consider. 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 16, 2020 Author Share Posted October 16, 2020 So I have played around with this version and it seems pretty stable. It's also pretty big at 806 bytes. BUT... With the ability to search across 9 wordlists what if I put each wordlist in it's own 8K SAMS space? FORTH vocabulary would use the pass-through SAMS values. The would give me 72K of total code space! And the compiler can search all of it... I think I have the code to make that work pretty quickly. There goes another week... Edit: Final version is here 1 1 Quote Link to comment Share on other sites More sharing options...
GDMike Posted October 16, 2020 Share Posted October 16, 2020 Lol Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 19, 2020 Author Share Posted October 19, 2020 ? Give that CAMEL a Bigger Hump! -> ? So I have been tardy in doing this but it was time I made a way to save the Camel99 Forth system from memory to EA5 files. This allows a developer to compile their favourite tools and then save the entire image as a custom Forth configuration. Really speeds up getting started versus re-compiling all the tools. I had the beginnings of it in the cross-assembler demo so I just started today to "git 'er done". Traditional Forth systems use blocks to save the binary data with the command BSAVE and then you can reload the code back to memory from Forth like an overlay with BLOAD. Camel99 doesn't use block files unless they are loaded. I wanted to save in EA5 format and I thought it might get awkward. It turned out that by taking the Forth approach and making a meta-language to compute the file properties it got simpler. These words are the key: \ words to compute Forth system properties : SYS-SIZE ( -- n) 'ORG HERE SWAP - ; : #FILES ( -- n) SYS-SIZE 8K /MOD SWAP IF 1+ THEN ; : CODECHUNK ( n -- start) 8K * 'ORG + ; : CHUNKSIZE ( n -- n ) HERE SWAP CODECHUNK - 8K MIN ; SYS-SIZE gives you the number bytes the Forth dictionary is using #FILES computes how many 8K files will it take to store the dictionary CODECHUNK takes an index 0..n and returns where that 8K section is in memory CHUNKSIZE takes an index 0..n and returns how many bytes the chunk size is. (the lesser of the CHUNKsize and 8K, for that last CHUNK) With these it was mostly just looping #FILES times and setting up the header, writing the chunks to VDP RAM and saving as a program file. There are some rules. You must create a startup word. If it's Forth it must start with WARM to init the system and end with ABORT to reset the command line interpreter. In between put whatever you like. You must pass the "execution token" (XT) of your startup word to SAVESYS on the data stack. You get that XT with the tick (') operator. See the bottom of the spoiler. You must use the LOCK command at the point where you want the system to remember the dictionary. Everything after LOCK will not be present when you restart the image. You must give SAVESYS a valid path to save the files. The video shows the spoiler being pasted into Classic99 creating a system binary called BIGCAMEL. Then we bounce out and load BIGCAMEL from the main menu. Only took me 4 years to get here. Edit: Removed line of code from older thinking... Spoiler \ SAVESYS.FTH save Forth dictionary as EA5 program B Fox Oct 2020 \ creates a binary program E/A 5 format. \ Makes as many files as needed to save the system \ put your include options here INCLUDE DSK1.TOOLS INCLUDE DSK1.WORDLISTS INCLUDE DSK1.ASM9900 INCLUDE DSK1.LOADSAVE \ Make your BOOT routine. it must start with WARM and end with ABORT : NEW-START WARM CR ." Includes TOOLS,WORDLISTS and ASSEMBLER" ABORT ; \ the simplest start-up routine LOCK \ everything compiled before this will restore when \ this saved system is reloaded. \ The SAVESYS code will not be in the dictionary on restart \ UNLESS you put LOCK at the end of this file. MARKER /SAVESYS HEX A000 CONSTANT 'ORG \ start of Camel99 Forth program in CPU RAM 1000 CONSTANT VDPBUFF \ Programs write to file from VDP Ram 2000 CONSTANT 8K 0013 CONSTANT <PROGRAM> \ file type \ define the file header fields *THESE ARE VDP ADDRESSES* VDPBUFF CONSTANT MULTIFLAG VDPBUFF 1 CELLS + CONSTANT PROGSIZE VDPBUFF 2 CELLS + CONSTANT LOADADDRESS VDPBUFF 3 CELLS + CONSTANT CODEORG \ COPY 8K program chunks to here \ words to compute Forth system properties : SYS-SIZE ( -- n) 'ORG HERE SWAP - ; : #FILES ( -- n) SYS-SIZE 8K /MOD SWAP IF 1+ THEN ; : CODECHUNK ( n -- start) 8K * 'ORG + ; : CHUNKSIZE ( n -- n ) HERE SWAP CODECHUNK - 8K MIN ; : LASTCHAR++ ( addr len) 1- + 1 SWAP C+! ; CREATE FBUFF ( -- addr) 20 ALLOT : FILE$ ( -- addr len) FBUFF COUNT ; HEX : SAVESYS ( XT -- <textpath> ) BOOT ! BL PARSE-WORD ?PATH FBUFF PLACE #FILES 0 ?DO CR ." Writing file " 0 . ." of " #FILES . CR ." Init header " I . CR I 1+ #FILES <> DUP . MULTIFLAG V! I CHUNKSIZE DUP . PROGSIZE V! I CODECHUNK DUP . LOADADDRESS V! CR ." Erase CODE buffer" CODEORG 8K 0 VFILL CR ." Copy CODE chunk to VDP" I CODECHUNK CODEORG PROGSIZE V@ VWRITE CR ." Write to disk ..." FILE$ VDPBUFF PROGSIZE V@ <PROGRAM> SAVE-FILE CR ." Update file name" FILE$ LASTCHAR++ CR LOOP CR ." System Save complete" CR ." In " #FILES . ." EA5 files" ; ' NEW-START SAVESYS DSK1.BIGCAMEL CAMEL99_SAVESYS_DEMO.mp4 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 19, 2020 Author Share Posted October 19, 2020 SAVESYS Update Well... it works mostly. It does not play nicely with my recent WORDLIST code. Something else needs initializing. I quickly realized I needed to patch in the multiple-wordlist search routine but there something more to connect. Pointers pointers everywhere. I am done for the night. 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 19, 2020 Author Share Posted October 19, 2020 On 10/16/2020 at 10:45 AM, GDMike said: "used the tick to remind me that it is the "address of something". " Ooooh, I like that!!! Very interesting This is an interesting area in Forth. Since a Forth word can me made of any ascii characters there have been some naming "conventions" that evolved over time. So ' mentioned is used to indicate addresses or execution tokens (which are just addresses in threaded Forth) Here are a few more with examples: Leading question mark: means this word will do something conditionally based on the input parameter (?ABORT ?PATH) Trailing question mark: This word returns a flag ( KEY? READY? CTS? ) Leading Dot character: This word prints something ( .NAME .ADDRESS .CITY) @ character: These words fetch something from memory or an I/O channel ( RECORD@ FREQUENCY@ ) ! character: Store something. ( RECORD! FREQUENCY!) '/' character: Used like 'per' in English. ("characters per line" C/L BYTES/RECORD ) Bracketed words: Internal words for the system. Not normally used directly. (TYPE) (EMIT) (KEY) Square bracketed words: These word execute immediately even when the compiler is on. [CHAR] [COMPILE] : and ; These words compile new things and end the compilation. ( ASM: ;ASM) # trailing usually means this word returns a number. ( PHONE# REC# ) This one I have only seen in Open-Firmware code by Mitch Bradley but I use it Leading bracket: These words require an index. ( ]MYARRAY ]PHONE# ) This one is frowned upon by Forth purists but I find it handy. Trailing $: the word is a string. ( A$ B$ C$ ) Leading $: This word is a string function ( $RIGHT $POS ) 1 Quote Link to comment Share on other sites More sharing options...
GDMike Posted October 19, 2020 Share Posted October 19, 2020 Do most FORTHs use "/" as a comment on First line or "(" as a remark,? Ended with ")"? Or is that something that can be defined? Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 19, 2020 Author Share Posted October 19, 2020 7 minutes ago, GDMike said: Do most FORTHs use "/" as a comment on First line or "(" as a remark,? Ended with ")"? Or is that something that can be defined? '\' is the single line comment. ( your comment goes here ) is the inside some code comment. But it you want your own comment do this: : \\ BL WORD DROP ; ( C++ ) : -- BL WORD DROP ; ( ADA ) : REM BL WORD DROP ; ( YOU KNOW...) Oops I think C++ is // Quote Link to comment Share on other sites More sharing options...
GDMike Posted October 19, 2020 Share Posted October 19, 2020 11 minutes ago, TheBF said: This one is frowned upon by Forth purists but I find it handy. Trailing $: the word is a string. ( A$ B$ C$ ) Haha, I wonder why it matters because you can't beat one character if production is what your looking for? I find"." Period odd too, bit that's me. For displaying an output stream or whatever you call it, DOS uses a pipe I think, maybe not it's been awhile. Quote Link to comment Share on other sites More sharing options...
GDMike Posted October 19, 2020 Share Posted October 19, 2020 Hmm I'll have to see what"word" doos Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 19, 2020 Author Share Posted October 19, 2020 Chuck went with things that were fast to type. Not FETCH but @ Not STORE but ! Not PRINT but . It's odd until it's not. Like Russian. 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 19, 2020 Author Share Posted October 19, 2020 1 minute ago, GDMike said: Hmm I'll have to see what"word" doos Remember it these characters don't "do" anything. They are just names in the dictionary. "word" could also be the name of the text for a string that spells "word" I do things like this too: CHAR A CONSTANT 'A' CHAR Q CONSTANT 'Q' It can make the code more readable but it does not affect what happens. After these definitions 'A' will just put the ascii value 65 on the stack. You could have just typed 65. 1 Quote Link to comment Share on other sites More sharing options...
GDMike Posted October 20, 2020 Share Posted October 20, 2020 (edited) Or dec 65..I don't think ti Forth knows dec as decimal, but I'd create it. Like gotoxy I've shortened to GXY Edited October 20, 2020 by GDMike Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 21, 2020 Author Share Posted October 21, 2020 Create an Executable Program in Camel99 Forth I of course discovered some bugs in my SAVESYS command that involved compensating for the 6 byte header at the top of an EA5 program file. It was subtle. It meant that everything in the saved Forth system worked normally except for that one routine that crossed the gap between the 1st file chunk and the 2nd file chunk. Fortunately with the excellent tools provided by TI99DIR I could clearly see what was missing and add the 6 byte offsets (positive and negative) where they were needed. The spoiler has the finished working code. It worked so well I made a video for my channel. Spoiler \ SAVESYS.FTH save Forth dictionary as EA5 program B Fox Oct 2020 \ creates a binary program E/A 5 format. \ Makes as many files as needed to save the system \ typically load your include options first \ INCLUDE DSK1.TOOLS \ INCLUDE DSK1.SHELL MARKER /SAVESYS INCLUDE DSK1.LOADSAVE \ we use SAVE-FILE from this library HEX A000 CONSTANT 'ORG \ start of Camel99 Forth program in CPU RAM 1000 CONSTANT VDPBUFF \ Programs write to file from VDP Ram 2000 CONSTANT 8K 13 CONSTANT PROG \ file mode for Program files \ define the file header fields *THESE ARE VDP ADDRESSES* VDPBUFF CONSTANT MULTIFLAG VDPBUFF 1 CELLS + CONSTANT PROGSIZE VDPBUFF 2 CELLS + CONSTANT LOADADDR VDPBUFF 3 CELLS + CONSTANT CODEORG \ COPY 8K program chunks to here \ words to compute Forth system properties : SYS-SIZE ( -- n) 'ORG HERE SWAP - ; : #FILES ( -- n) SYS-SIZE 8K /MOD SWAP IF 1+ THEN ; : CODECHUNK ( n -- addr) DUP 8K * ( -- n addr) SWAP IF \ if n <> 0 ie: 2nd, 3rd, chunks 3 CELLS - \ subtract header space THEN 'ORG + ; : CHUNKSIZE ( n -- n ) HERE SWAP CODECHUNK - \ compute size 3 CELLS + \ add 6 bytes for header 8K MIN ; \ take lesser of size or 8K : LASTCHAR++ ( Caddr --) COUNT 1- + 1 SWAP C+! ; HEX : SAVESYS ( XT -- <textpath> ) CR BOOT ! BL PARSE-WORD ?PATH PAD PLACE #FILES 0 ?DO CR ." Writing file " I . ." of " #FILES . CR ." Init file header " I . ." : " I 1+ #FILES <> DUP . MULTIFLAG V! I CHUNKSIZE DUP . PROGSIZE V! I CODECHUNK DUP . LOADADDR V! CR ." Copy CODE chunk to VDP" CODEORG 8K 0 VFILL LOADADDR V@ CODEORG PROGSIZE V@ VWRITE CR ." Write to disk ..." PAD COUNT VDPBUFF PROGSIZE V@ PROG SAVE-FILE CR ." Update file name" PAD LASTCHAR++ CR LOOP CR ." System size=" DECIMAL SYS-SIZE U. ." bytes" CR ." Saved in " #FILES . ." EA5 files" CR ; \ Make your BOOT routine. it must start with WARM and end with ABORT \ -OR- the word that starts your application. HEX : COLD \ A simple start-up routine WARM ( this also sets 40 col. TEXT mode) 17 7 VWTR ( set screen color) CR ." Includes TOOLS,SHELL,SAVESYS" ABORT ; LOCK \ everything compiled before this will restore when \ this saved system is reloaded. \ The SAVESYS code will not be in the dictionary on restart \ UNLESS you put LOCK at the end of this file. ' COLD SAVESYS DSK1.FXFORTH 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 21, 2020 Author Share Posted October 21, 2020 On 10/19/2020 at 8:03 PM, GDMike said: Or dec 65..I don't think ti Forth knows dec as decimal, but I'd create it. Like gotoxy I've shortened to GXY On our favourite little computer you have to be careful redefining lots of stuff. Each Name you add to the dictionary takes space for the text and the header that makes it into a linked list, plus the EXIT (2 bytes) that is compiled by the ';' It can add up quickly. Just doing this in FbForth, Turbo Forth or Camel99 Forth uses 12 extra bytes. : TEST ; 1 Quote Link to comment Share on other sites More sharing options...
GDMike Posted October 21, 2020 Share Posted October 21, 2020 (edited) 4 hours ago, TheBF said: On our favourite little computer you have to be careful redefining lots of stuff. Each Name you add to the dictionary takes space for the text and the header that makes it into a linked list, plus the EXIT (2 bytes) that is compiled by the ';' It can add up quickly. Just doing this in FbForth, Turbo Forth or Camel99 Forth uses 12 extra bytes. : TEST ; And I thought memory was free.. Good to know.thx Edited October 22, 2020 by GDMike Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 27, 2020 Author Share Posted October 27, 2020 On 10/19/2020 at 7:48 PM, GDMike said: Hmm I'll have to see what"word" doos Just realized I didn't respond to this one. If you didn't already look it up WORD is the primary text parser in Forth83,Forth79 and Fig Forth (Like TI-Forth and FbForth are Fig descendants) It is used by the compiler and interpreter to get each word from the string we feed to them, one word at a time. Here is the "official definition" for Forth 2012. WORD ( char "<chars>ccc<char>" -- c-addr ) Skip leading delimiters. Parse characters ccc delimited by char. An ambiguous condition exists if the length of the parsed string is greater than the implementation-defined length of a counted string. c-addr is the address of a transient region containing the parsed word as a counted string. If the parse area was empty or contained no characters other than the delimiter, the resulting string has a zero length. A program may replace characters within the string. So if that doesn't help you... (amazing) Here is what they are trying to tell us: Take a character delimiter parameter from the data stack. Read the text after the word WORD until you encounter that delimiter character. While reading the text, skip any leading spaces (blanks). Typically WORD stores the string at the address called HERE and appends a space to the end of the string it read. It leaves behind a *byte counted string on the data stack with the delimited text. ( *string where the 1st byte is the length) It is not like INPUT in BASIC. It is really best used if you want to make your own compiler extensions. If you are careful you can use WORD to make commands like the Assembler DATA and BYTE directives for example. 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 27, 2020 Share Posted October 27, 2020 1 hour ago, TheBF said: WORD ( char "<chars>ccc<char>" -- c-addr ) I do not believe the counted string is left on the stack, but, rather, its address. figForth (and its descendants TI Forth, fbForth, et al.) always stashes the parsed char-delimited token as a counted string at HERE and des not leave the address because it is already known. Pretty much the only useful place for WORD in figForth is in a definition because the very next token in the input stream is processed by INTERPRET , which uses WORD to parse it and store it at HERE , overwriting the token you were interested in before you can use it. A word that is more like Basic’s INPUT is EXPECT , which requires the storage address and maximum character count on the stack. Only the entered string is stored. ...lee 2 Quote Link to comment Share on other sites More sharing options...
GDMike Posted October 27, 2020 Share Posted October 27, 2020 I expect, that "EXPECT" is a pretty powerful player. Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 28, 2020 Author Share Posted October 28, 2020 1 hour ago, Lee Stewart said: I do not believe the counted string is left on the stack, but, rather, its address. figForth (and its descendants TI Forth, fbForth, et al.) always stashes the parsed char-delimited token as a counted string at HERE and des not leave the address because it is already known. Pretty much the only useful place for WORD in figForth is in a definition because the very next token in the input stream is processed by INTERPRET , which uses WORD to parse it and store it at HERE , overwriting the token you were interested in before you can use it. A word that is more like Basic’s INPUT is EXPECT , which requires the storage address and maximum character count on the stack. Only the entered string is stored. ...lee Yes I misspoke. It is the address of course. Since that is how Forth uses strings I tend to forget that detail in common parlance. I also forgot about that FigForth WORD doesn't leave the address on the stack. There are a lot of small differences between the old systems and Forth83 and forward. Small wonder it makes folks skittish. 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.