Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : CMM2: Forth - proof of concept
Page 2 of 3 | |||||
Author | Message | ||||
Holger Newbie Joined: 04/11/2020 Location: GermanyPosts: 11 |
I totally admire your coding skills and think, your Forth Implementation really "matters" even if you can't make it any faster. |
||||
William Leue Guru Joined: 03/07/2020 Location: United StatesPosts: 382 |
I was never a big Forth fan. So Tom, how about porting a LISP interpreter? (Or did you already do that for Zork?) -Bill |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3841 |
<Blushes>Thank you, one of the nicest things anyone has said to me.</Blushes> I've got to leave something for other people to do Z-MIM / the Z-Machine is not a LISP implementation / specification. You may be thinking of ZIL (Zork Implementation Language) which I undestand was Infocom's in-house LISP like language that they wrote Zork etc. in but then compiled the result into opcodes that ran on the Z-Machine. Best wishes, Tom Edited 2021-03-14 09:55 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3841 |
DEFINEDATA n ascii more ascii as much ascii as you like END DEFINEDATA ? MM.INFO(DATA ADDRESS n) ' gives the address in memory of the start of the ascii data block number n ? MM.INFO(DATA SIZE n) ' gives the length in bytes of the data block number n Hi Peter, I was going to leave commenting further on this until I'd made more progress on optimising SPForth, but then it occurred to me that it wouldn't be unlikely for you to already be working on it despite having said I needed to "make it worthwhile" first. Whilst I believe your proposal has a multitude of uses it has downsides as far as what I would want in order to embed Forth code directly in BASIC which my simpler #if 0 / endif construct (or any multi-line "comment" construct) would not - please bear with me. What I was proposing was that the content of lines within #if 0 / endif would not be sent from the preprocessor to the tokenizer, just send empty (or ' commented out) lines instead to keep the line count correct. My Forth initialisation code would be responsible for opening and scanning the current file MM.INFO(CURRENT) looking within #if 0 / endif blocks to see if it could find any likely looking Forth code to "compile" (probably identified by some sort of marker tags). I could also find and follow any #INCLUDEs myself. One important advantage of this mechanism is I would have filenames and line numbers to include in any Forth parse errors. With regards to the more general use of your proposal could you save yourself the extra tokens by overloading CSUB such that: CSUB CODE name [type [, type] ...] hex [[ hex[...] hex [[ hex[...] END CSUB Is treated as code by the interpreter. CSUB ASCII name ascii ascii more ascii END CSUB Is treated as ASCII CSUB AS_YET_UNDEFINED name ascii ascii more ascii END CSUB Is treated as something else we haven't thought of yet ? If CSUB is not followed immediately by CODE or ASCII (or other keywords not yet invented) then it is assumed to be CSUB CODE. Then add a more generic keyword as a synonym for CSUB, e.g. BLOCK or BLOB with the end result of having both: BLOCK CODE name1 [type [, type] ...] hex [[ hex[...] hex [[ hex[...] END BLOCK BLOCK ASCII name2 ascii ascii more ascii END BLOCK Even if you don't like this and go with your original plan please can I ask you to identify data blocks by name and not number? It would make it much easier to avoid clashes where there is the possibility of datablocks being present in multiple include files from multiple sources. Best wishes, Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8582 |
It doesn't work like that. Either lines leave the preprocessor with tokenised Basic or they are omitted completely. There is no mechanism for "blank" lines. Comments are always removed completely. I think it is easier just to load forth from file with a single command rather than line by line Breaks existing programs so no |
||||
jirsoft Guru Joined: 18/09/2020 Location: Czech RepublicPosts: 532 |
One more idea. Maybe already now could be just used something like this: #DEFINE "FORTH ", "'" FORTH : prime? here @ + c@ 0= ; FORTH : composite! here @ + 1 swap c! ; FORTH : sieve FORTH here @ over erase FORTH 2 FORTH begin FORTH 2dup dup * > FORTH while FORTH dup prime? if FORTH 2dup dup * do FORTH i composite! FORTH dup +loop FORTH then FORTH 1+ FORTH repeat FORTH drop FORTH ." Primes: " 2 do i prime? if i . then loop FORTH ; and then add searching of FORTH prefix into your Forth initialisation code... Jiri Napoleon Commander and SimplEd for CMM2 (GitHub), CMM2.fun |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3841 |
Peter, I am sure we are talking at cross-purposes so you will forgive me if I make another attempt. At the moment there is nothing stopping me from writing the following: #Include "spforth.inc" #Include "foo.inc" #Include "bar.inc" Dim m%(10000) spforth.init(m%(), 10000 * 8) spforth.load_inline(m%()) spforth.run(m%(), "sieve") ' #FORTH ' : PRIME? HERE + C@ 0= ; ' : COMPOSITE! HERE + 1 SWAP C! ; ' : SIEVE ' HERE OVER ERASE ' 2 ' BEGIN ' 2DUP DUP * > ' WHILE ' DUP PRIME? IF ' 2DUP DUP * DO ' I COMPOSITE! ' DUP +LOOP ' THEN ' 1+ ' REPEAT ' DROP ' ." Forth Primes: " 2 DO I PRIME? IF I . THEN LOOP ; ' #ENDFORTH And the implementation of spforth.load_inline(m%()) would, starting from the file identified by MM.INFO(CURRENT) walk through all the includes and then the current .BAS file itself looking for comments between #FORTH and #ENDFORTH tag and pass them to the spforth compiler (along with the corresponding filename and line number). It's not trivial to implement, but it's not particularly difficult either, I believe someone (@vegipete ?) did it to encode a program's help instructions within its .BAS file. All I am asking for is a completely non-Forth specific multiline comment construct (which given you have a preprocessor shouldn't be too challengin) so instead it would be possible to write: #Include "spforth.inc" #Include "foo.inc" #Include "bar.inc" Dim m%(10000) spforth.init(m%(), 10000 * 8) spforth.load_inline(m%()) spforth.run(m%(), "sieve") #If 0 #FORTH : PRIME? HERE + C@ 0= ; : COMPOSITE! HERE + 1 SWAP C! ; : SIEVE HERE OVER ERASE 2 BEGIN 2DUP DUP * > WHILE DUP PRIME? IF 2DUP DUP * DO I COMPOSITE! DUP +LOOP THEN 1+ REPEAT DROP ." Forth Primes: " 2 DO I PRIME? IF I . THEN LOOP ; #ENDFORTH #EndIf This looks nicer to the user than having to comment each line individually, they can just copy and paste directly from Forth code and incidentally the existing default syntax highlighter in the EDITor doesn't do a half bad job of syntax highlighting the Forth. Breaks existing programs so no. It breaks existing CMM2 programs that happen to have a CSUB called CODE ... that doesn't seem likely to be a large number, and you've made larger breaking changes than that. Best wishes, Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3841 |
Addendum: I composed my last comment before seeing Jiri's contribution. In the absence of a multi-line comment I would do as Jiri suggests (thanks) though it (and my version using ') both have the same disadvantage of not allowing Forth code to be pasted directly into a .BAS file, you have to add all the FORTH prefixes. Best wishes, Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8582 |
You can write it but none of the comments are loaded into memory The process of the firmware is as follows: Step 1: read the main file + any include files into memory. Whilst reading strip all comments out completely, convert all text not in quotes to uppercase, strip out as much white space as possible. Add a pseudo comment indicating original line number and include file name if applicable. Implement #DEFINE and #MMDEBUG directives, note in the latter case a line is either included or omitted. The former is just a string substitution mechanism. Step 2: read from memory and program into flash. Whilst reading convert syntactical elements to save command and function slots (e.g. I2C2 becomes I2C 2), tokenise each line and write to flash. Step 2 actually happens in three passes in order to create the data areas for CSUBs and FONTS This whole process is extremely complex, has many many hours of coding in it and is risky to change i.e. not going to happen. My proposal is to create another version of CSUB/FONT for ascii data. That should be easier to do as it can be largely self contained but relies on using two more command slots. It has the advantage of also potentially being useful to replace the catastrophically slow DATA/READ mechanism for other applications. If I do this it would use a numerical reference like a font as I'm not going to build another symbol table for such a limited application. Forth is likely to have a very limited user base so any dedicated support in the firmware doesn't make sense whereas something more generally useful (if it is) could be justified. |
||||
jirsoft Guru Joined: 18/09/2020 Location: Czech RepublicPosts: 532 |
I think that's no problem for Tom: Jiri Napoleon Commander and SimplEd for CMM2 (GitHub), CMM2.fun |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3841 |
Thank you for the multiline comment support, it is always an "interesting" journey It's your call, but by automatically adding a prefix character that is not allowed in other identifiers you may be able to store these new ids in one of the existing symbol tables. YMMV I agree and was thus careful to phrase my requests in a non-Forth specific way. Best wishes, Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Nimue Guru Joined: 06/08/2020 Location: United KingdomPosts: 367 |
So, if Forth is potentially an option..... what about this: https://www.youtube.com/watch?v=X7kJiuD_PFM A Small C compiler written in Forth..... Circular coding? Nim Entropy is not what it used to be |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3841 |
https://www.youtube.com/watch?v=X7kJiuD_PFM A Small C compiler written in Forth..... Circular coding? Nim Hi Nim, I don't really know, but I suspect generating ARM Thumb that will run within the constraints of a CSUB and the firmware is an order of magnitude more difficult than generating 6502 where other than staying out of the way of the ROM the compiler has full rein to stick the code where it likes. Hopefully someone will prove me wrong ... hopefully it will be me ... but probably not for a few years Best wishes, Tom Edited 2021-03-16 10:19 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3659 |
I think that's no problem for Tom: Er, it's a show-stopper for Tom. I think that can't work because there is no spforth at that time. John |
||||
jirsoft Guru Joined: 18/09/2020 Location: Czech RepublicPosts: 532 |
Hi John, maybe I have understand it wrong, but I have though: 1. program is flashed and started (without comements) 2. spforth loading component inside the code is started 3. spforth goes through source code (.BAS) again and reads and compile Forth part 4. spforth runs the code So why should be problem missing Forth code (commented out) in the flashed/RAM prg? Edited 2021-03-16 18:59 by jirsoft Jiri Napoleon Commander and SimplEd for CMM2 (GitHub), CMM2.fun |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3841 |
Jiri has it correct. Advantages of this system: - "Inline Forth" will not consume program memory. - the Forth compiler will have access to file names and line numbers. Disadvantages of this system: - re-parsing the source code from MMBasic is slow - probably want some sort of marker (in a comment) saying stop processing this file as it contains no "Inline Forth". - it would be helpful if CSUBs could do file access, but currently this does not seem to be possible. I don't need this now, but assuming I make more progress with SPForth then I will want it to be able to do file access - so it it something I hope Peter will consider in the future. Best wishes, Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
IanT Regular Member Joined: 29/11/2016 Location: United KingdomPosts: 84 |
Following this thread with great interest but suffering a serious lack of comprehension wrt the technical details I'm afraid. :-( As to interest in Forth - I (painfully) typed Fig-forth into my Nascom II Z80 system nearly four decades ago. It was crucial to using a custom DIY graphics card with a TI graphics chip - featuring hardware sprites and colour! I still play with Forth (Mecrisp Stellaris on Blue Pill) occasionally and now that Mecrisp has been ported to the Raspberry Pico, will most certainly have a play with that version too. Mention has been made of 'Starting Forth' and I've always thought this was one of the best books ever published to help someone understand & learn a programming language. I would also highly recommend 'Thinking Forth' as extremely helpful for anyone wanting to understand good programming practice and design - whatever language you intend to use. I mention these books again as the author - Leo Brodie - has just appeared on the Forth2020 YouTube channel to reminisce about writing the books and his time at Forth Inc. Worth a watch for any Forthers here. PS Both books can be downloaded as PDFs - so if you are curious, have a look. Regards, IanT |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3659 |
maybe I have understand it wrong, but I have though: 1. program is flashed and started (without comements) 2. spforth loading component inside the code is started 3. spforth goes through source code (.BAS) again and reads and compile Forth part 4. spforth runs the code So why should be problem missing Forth code (commented out) in the flashed/RAM prg? Yes, that will work but I thought he didn't want to go through the .BAS again. Instead I thought he wanted the Forth code left in memory. John |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3841 |
That would mean that the Forth took up unnecessary program memory (the dictionary can't be executed from program memory it has to be in the user data) and I would also lose the file/line context unless Peter made more firmware changes - which even *I* don't think are appropriate. Best wishes, Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3841 |
Optimised the . word (number output) by implementing it in C instead of Forth: > run Primes: ... output deleted for brevity... TOTAL: 0.16 s SPFORTH v0.1.0 22296 CELLS REMAINING OK Primes: ... output deleted for brevity... Initialisation time: 0.247 s Compilation time: 0.001 s Execution time: 0.087 s TOTAL: 0.335 s Marginally improved "execution time" (was 0.094 s), but no great shakes - was expecting better. In this example SPForth x1.8 times faster than MMBasic. Unless my C is substantially worse than I think I don't believe there is scope for optimisation shaving off much more than another couple of micro-seconds from the execution time, and in any case the Forth has an unfair advantage in this example because it is only doing 32-bit arithmetic whilst MMBasic is doing 64-bit. My awe for Geoff and Peter's achievement only increases. Note that the significantly longer "initialisation time" over my previous post is because for convenience in editing I am now reading the SPForth dictionary from a file during initialisation instead of having it hardwired into the CSUB. Out of curiosity I also timed just doing the calculation without outputting the results: BASIC primes: TOTAL: 0.048 s SPFORTH v0.1.0 22296 CELLS REMAINING OK Forth Primes: Initialisation time: 0.243 s Compilation time: 0.001 s Execution time: 0.017 s TOTAL: 0.261 s Here SPForth is 2.8x faster than MMBasic. You can also calculate that SPForth takes 0.07 seconds to write the primes compared with 0.112 seconds for MMBasic. Make of this what you will. I'm now going to sit on it for a couple of weeks whilst I finish off the Scott Adams' Adventure Interpreter I was working on with @Turbo64 before I had the urge to scratch this Forth itch. After that I'll try and kick SPForth into shape with the intention of getting it to pass the "Hayes CORE Tests" before making it publicly available. Best wishes, Tom Edited 2021-03-17 07:36 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Page 2 of 3 |
Print this page |