Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 06:54 28 Apr 2024 Privacy Policy
Jump to

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: Germany
Posts: 11
Posted: 03:57pm 13 Mar 2021
Copy link to clipboard 
Print this post

  thwill said  
  TassyJim said  I still have my copy of Leo Brodie's "Starting Forth"


Might want to give it a few weeks, it's just a "proof of concept", now I need to find out if it can be made fast enough to "matter" and then worry about filling in the gaps and improving its compliance with Brodie's books.

Best wishes,

Tom


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 States
Posts: 382
Posted: 07:31pm 13 Mar 2021
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 3841
Posted: 09:12pm 13 Mar 2021
Copy link to clipboard 
Print this post

  Holger said  I totally admire your coding skills and think, your Forth Implementation really "matters" even if you can't make it any faster.

<Blushes>Thank you, one of the nicest things anyone has said to me.</Blushes>

  William Leue said  I was never a big Forth fan. So Tom, how about porting a LISP interpreter? (Or did you already do that for Zork?)


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 Kingdom
Posts: 3841
Posted: 09:33pm 13 Mar 2021
Copy link to clipboard 
Print this post

  matherp said  I've managed to "acquire" a couple of command slots so my initial thoughts are:

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 Kingdom
Posts: 8582
Posted: 10:41pm 13 Mar 2021
Copy link to clipboard 
Print this post

  Quote  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.


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

  Quote  SUB CODE name [type [, type] ...]


Breaks existing programs so no
 
jirsoft

Guru

Joined: 18/09/2020
Location: Czech Republic
Posts: 532
Posted: 10:44pm 13 Mar 2021
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 3841
Posted: 11:13pm 13 Mar 2021
Copy link to clipboard 
Print this post

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.

  matherp said  CSUB CODE name [type [, type] ...]

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 Kingdom
Posts: 3841
Posted: 11:16pm 13 Mar 2021
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 8582
Posted: 08:46am 14 Mar 2021
Copy link to clipboard 
Print this post

  Quote  At the moment there is nothing stopping me from writing the following:


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 Republic
Posts: 532
Posted: 10:25am 14 Mar 2021
Copy link to clipboard 
Print this post

  Quote  You can write it but none of the comments are loaded into memory


I think that's no problem for Tom:
  Quote  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)

Jiri
Napoleon Commander and SimplEd for CMM2 (GitHub),  CMM2.fun
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 3841
Posted: 02:44pm 14 Mar 2021
Copy link to clipboard 
Print this post

Thank you for the multiline comment support, it is always an "interesting" journey

  matherp said  My proposal is to create another version of CSUB/FONT for ascii data. ... 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.


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

  matherp said  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.


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 Kingdom
Posts: 367
Posted: 11:15pm 15 Mar 2021
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 3841
Posted: 12:03am 16 Mar 2021
Copy link to clipboard 
Print this post

  Nimue said  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


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 Kingdom
Posts: 3659
Posted: 07:50am 16 Mar 2021
Copy link to clipboard 
Print this post

  jirsoft said  
  Quote  You can write it but none of the comments are loaded into memory


I think that's no problem for Tom:


Er, it's a show-stopper for Tom.

  jirsoft said  
  Quote  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)

I think that can't work because there is no spforth at that time.

John
 
jirsoft

Guru

Joined: 18/09/2020
Location: Czech Republic
Posts: 532
Posted: 08:58am 16 Mar 2021
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 3841
Posted: 10:19am 16 Mar 2021
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 84
Posted: 10:46am 16 Mar 2021
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 3659
Posted: 11:02am 16 Mar 2021
Copy link to clipboard 
Print this post

  jirsoft said  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?


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 Kingdom
Posts: 3841
Posted: 11:07am 16 Mar 2021
Copy link to clipboard 
Print this post

  JohnS said  Instead I thought he wanted the Forth code left in memory.


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 Kingdom
Posts: 3841
Posted: 09:29pm 16 Mar 2021
Copy link to clipboard 
Print this post

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
© JAQ Software 2024