Willsy Posted August 3 Share Posted August 3 (edited) Wow that's great! I learned something about my own Forth system! I actually had to type it in to TF and try it. Worked like a charm Edited August 3 by Willsy 2 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted August 3 Share Posted August 3 I used to read Jeff Fox talking about you can do things in Forth with 10X less code. I didn't believe it because "I" couldn't do it. Over the years I am "starting" to get how you do it but it means really exploring what all these little trivial words do in a Forth system and what else you could use them for. It seems to be more like an instruction set for a CPU where it takes time to figure out the best way to use the instructions for different situations. It's just not obvious what "else" you can do with the wee beasties. One that made say "WHAT?!" was using COUNT to index into a stack string. (not a byte counted string) : TYPE ( addr len -- ) 0 DO COUNT EMIT LOOP DROP ; 3 Quote Link to comment Share on other sites More sharing options...
Willsy Posted August 4 Share Posted August 4 Yep. That works too. Though I'll need to study the code to understand why. I'm somewhat rusty! I've never seen COUNT used in a loop like that, so my eyebrows are on the ceiling right now! 3 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted August 7 Share Posted August 7 On 8/2/2023 at 9:49 PM, TheBF said: I just saw something on comp.lang.forth that I would have never thought of but apparently others have used it. It is not guaranteed to work on all Forth systems. You need the Forth83 style word CREATE so it doesn't work in FbForth without making that word. Let's say you wanted to create a vector table of these actions that you have written up. : FIZZ ; : BUZZ ; : BLEEP ; : HALT ; In many Forth systems you can do this to make the table of executable "tokens" (addresses) CREATE TABLE ] FIZZ BUZZ BLEEP HALT [ For the Forth student: How does it work? Because ] turns on the compiler so the token for each word is looked up in the dictionary and is compiled into memory as each word is parsed. Then [ turns off the compiler ie: turns on the interpreter again And then to run them you might do something like this. : DOIT ( n -- ) CELLS TABLE + @ EXECUTE ; \ Usage: 0 DOIT 1 DOIT etc. (no protection on this example so you can blow up the system if you type 4 DOIT. ) ( I will leave it to the reader to implement protection ) (always wanted to say that) More stuff you'll probably never need but now you know. Yeah... CREATE in Forth83 and beyond is virtually the same as VARIABLE , with the difference that VARIABLE reserves and zeroes one cell for the parameter field. Words created with both of those defining words leave the parameter field address of the defined word on the stack when executed. Whereas, in figForth-based Forths like fbForth, CREATE creates the new word with the same kind of header, viz., no parameter field is reserved. The difference is that fbForth’s CREATE stashes the new word’s pfa into its code field, meaning that, upon execution of the new word, its parameter field (nonexistent, unless you defined it separately) will be executed—not usually what you want to happen when trying to use CREATE on the command line. Furthermore, fbForth’s CREATE sets the new word’s smudge bit ( hides the word from -FIND ). The above two functions of fbForth’s CREATE presume CREATE will only be used by other defining words that will modify the contents of the new word’s code field and toggle its smudge bit before concluding the new word’s definition. fbForth’s VARIABLE differs only in that it expects the initial value of the parameter field on the stack instead of automatically zeroing it. For what it’s worth, here is a definition of CREATE83 for fbForth that will function as the CREATE for Forth83 (and beyond): : CREATE83 <BUILDS DOES> ; That said, we can kill two birds with one stone by using fbForth’s VARIABLE to store the number of entries in TABLE in the first cell and use that in DOIT for bounds checking (the leave-it-to-the-reader poser): : CELLS ( n -- 2n ) 1 SLA ; \ double n (word not yet in fbForth) \ Set up TABLE with count as first word in parameter field followed by \ count cfas to flesh out TABLE. 4 VARIABLE TABLE ] FIZZ BUZZ BLEEP HALT [ : DOIT ( n -- ) DUP 1 < \ n < 1? OVER TABLE @ > \ n > TABLE count? OR ABORT" TABLE range!" \ abort if either test TRUE CELLS TABLE + @ EXECUTE \ execute nth cfa in TABLE ; \ Usage: 1 DOIT 2 DOIT etc. ...lee 2 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted August 7 Share Posted August 7 Very slick using the extra cell. 1 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted August 25 Share Posted August 25 Over on comp.lang.forth I fellow posted a link to this site. It is aruably the cleanest source code to describe a Forth kernel I have ever seen. Primitives are in intel Assembler and then another file shows the high level words as Forth source. T3XFORTH - T3X.ORG (I may just try to cross-compile it on TI99 if I get some time) 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted September 11 Share Posted September 11 Over in another thread @InsaneMultitasker posted some code to detect the presence of a SAMS Card. I am always curious about comparing Assembly Language to Forth. In this case, at least for Camel99 Forth, a couple of extra words are needed from the SAMS library to do this in Forth. For the Forth curious, here is what I came up with. (un tested at time of posting) Edit: Tested and it works. But SAMSINI in the DSK1.SAMS file runs when the file compiles and it burps with an error if SAMS is not present. Again I see the low level semantic power of 9900 Assembly language is about the same as Forth primitives. The gap widens only when we begin making higher level words that we can concatenate to make yet higher level words. Original code H0101 data >0101 SAMSDT DATA PLAYWS,$+2 clr @0(R13) li r12,>1E00 sbo 0 mov @>4008,R2 ;save whatever was in the mapper for >4000-4fff a @H0101,@>4008 ;change the value c r2,@>4008 ;is it still the same? jeq noams ;yes. can't be SAMS seto @0(R13) ;no, assume SAMS mov r2,@>4008 ;restore, for futureproofing noams sbz 0 rtwp A Forth version \ For Camel99 Forth NEEDS 'R12 FROM DSK1.SAMS HEX : SAMSDT ( -- ?) \ returns true FLAG if present 1E00 'R12 ! \ set CRU to SAMS card 0SBO \ Enable the card 4008 @ >R \ save whatever was in the mapper on RETURN stack 0101 4008 +! \ change the value R@ 4008 @ <> \ is it different? (compared to top Rstack) R> 4008 ! \ restore previous value to SAMS card 0SBZ \ disable the card ; 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.