Project - RLP Forth - Prototype Proof of Concept

RLP Forth - Prototype Proof of Concept

The attached project contains a RLP implementation of a Forth environment. The code can run compiled as well as interactively from a serial terminal.

The Forth VM runs directly on the hardware device by passing the overheads associated with managed code and providing higher performance at the cost of safety. As with native code, you have full access to all parts of the environment so a stray pointer code bring the environment to its knees.

Forth code can be loaded onto the device stored in a resource within your managed application and at the same time you can connect to the device via a serial port and either add new code functionality or completely change/fix existing functionality while the system is running.

The managed code is responsible for initializing the Forth environment and loading code into the environment the code can be stored in a resource, loaded from a SD card or from a string in your managed code.

Once initialized the managed program can interact with the Forth environment by directly manipulating the stack, executing existing words (functions), replace existing words with or create new words. Replacing a word with a new implementation can be done via the interactive interface and compiled on the device directly.

See the sample code to get an idea of what you can do.


Awesome! Thanks for sharing.

@ Architect - Thanks. I hope to add a debugging interface to the interactive interface which can be used to debug the forth code while it runs. I also want to get a version of this running on the DL40, I think that could be really useful for building DaisyLink code.

When do we get RLP Prolog? :wink:

@ taylorza - Very cool :slight_smile:

The post on SplitToArray ( presented a good opportunity to demonstrate the value of the Forth Interpreter.

Using @ jasdev’s byte array implementation of IndexOf I implemented the corresponding Forth routine and put them head to head.

The both processes a 107 byte array of 27 comma separated values 100 times

Managed Code : 646ms
Forth Code : 28ms

And there was no need to leave visual studio. The code below is the Forth implementation, those of you that are Forth experts will cringe, but I had to do extra stackrobatics just because I have not implemented all the standard core primitives yet. But if I had this would be even faster.

: IndexOf ( c-addr-pattern u2 c-addr-str u1 u3-offset -- u4 )
    DUP >R            \ 1. Copy the initial offset
    /STRING           \ 2. Offset into the string by u3-offset
    DUP >R OVER >R    \ 3. Keep a copy of the new string
    2SWAP             \ 4. Get the two strings in the right order to compare them
    SEARCH            \ 5. Search the substring
    -1 = IF           \ 6. If we found a match
      DROP            \ 7. We do not need the remaining length
      R>              \ 8. Get start of string we saved in (3)
      -               \ 9. Substract the location from the start point      
      R> DROP         \ 10. Get rid of the string length, RDROP would be better
      R> +            \ 11. Add the original offset get final index
      R> R> R>        \ 12. Restore the return stack (again RDROP would be better)
      DROP DROP DROP  \ 13. Drop the temp items from the data stack
      DROP            \ 14. Drop the searched string
      DROP            \     Drop the searched string
      -1              \ 15. Put index -1 on the stack to indicate that the substring was not founf

1 Like


@ taylorza - Wow! That’s an amazing speed increase. How would the Forth IndexOf be used in practice? Would it be loaded from resources once and then available to all code through some sort of static class wrapper?

@ jasdev - The Managed to Forth interface class has a method ‘Forth.PushArray’ which is used to push a byte array onto the stack which the Forth routines can then pick the code up from.

So a direct invocation of the Forth implementation on the IndexOf would be

    public static int ForthIndexOf(byte[] array, byte[] value, int startIndex = 0)
      Forth.Execute(_tokenIndexOf, value, array, startIndex);
      int index = Forth.Pop();
      return index;

_tokenIndexOf is an optimization you could dynamically lookup the code everytime with the following


Note: I do not have overloads of this that take arrays though so it is not useful for this example.

If you are do not need the dynamic invocation, you can resolve the name to a token upfront using

int token = Forth.GetExecutionToken("IndexOf");

I did another test quickly:

Finding a character in a 588 character string, where the character appears near the end of the string

Managed code : 84ms
Forth code : 0.92ms

1 Like

:slight_smile: Well I guess I understand… I showed the devs I work with some Forth back a few years ago and I pretty much got blank reactions. And I will probably rather be progressing my C scripting implementation of this, Forth is just not for everyone. But since I did the code, I thought I would share and who knows introduce a few people to another language.

The pitty is that Forth is generally much more efficient than any interpreted language and the really nice thing is how interactive it is. For example, if you look at the samples in the code share, the LEDON word (function) can be called from Forth, Managed code or from an interactive session via the serial port. Want to try any play with some of the registers and see what happens, open an interactive sessions and start toggling away it all happens immediately. It even crashes immediately :slight_smile:

@ taylorza -
This is great implementation. I will take into for sure as soon I get some spare time.
I used forth when I was young in the Apple ][e times !! It was used to program small bot that fight or match in a virtual arena, simulating sensors and moves … The name of the software if I remind correctly was RobotWar … Now survive a public project named RoboCode, who has bots that can be programmed with .net.

@ dobova - Thanks.

I will upload a newer version by the end of the weekend, I am slowly but surely adding more of the core words and a few of the optional ones. What I really want to do is add an interactive debugger, so you can debug a Forth word from the interactive session.