CARVIEW |
Navigation Menu
-
Notifications
You must be signed in to change notification settings - Fork 8
Play with the forth kernel on python
Play with the Forth kernel projectk.py, a small file.
projectk.py
This is fun. You don't need to be very familiar with python. Go through the following steps then you will know what this Forth kernel is all about.
I don't know how many different python are out there. I am new too. Python for Windows DOS Box is a target application of projectk.py. You should have installed python 3.6 or newer. So just run it:
python.exe
projectk.py is targeting all python hosts. Here and now we focus on this one.
Type in the following lines to create a project-k VM object, check it out and list its attributes.
import projectk as vm
vm
dir(vm)
The first line creates an instance of project-k VM. Here we call it 'vm' yet you can choose a permanent name for your project. We can see that it has only very few attributes (methods and properties) so it's really very easy to handle.
Let's try some project-k VM methods:
vm.dictate("123")
vm.stack
vm.stack gets you the Forth VM data stack which was empty at first. vm.dictate() method is the way project-k VM receives your commands (a string). It actually is also the way we feed it an entire Forth source code file (also as a string).
So we can start to define new words:
vm.dictate("code hi print('Hello World!!') end-code")
vm.dictate("hi")
Did you know what have we done? We defined a new FORTH code word! There are a few more butilt-in functions in the VM you can use in Forth word definitions. See below Built-in functions and Global variables table for all of them.
vm.dictate("code words print([w.name for w in words['forth'][1:]]) end-code")
vm.dictate("words")
'words' is a basic Forth word (or a Forth command) that lists all words of recent vocabularies. This example shows you how to define it. We have only 4 words so far as shown on the above picture.
vm.dictate("code + push(pop(1)+pop()) end-code")
vm.dictate("code .s print(stack) end-code")
vm.dictate('code s" push(nexttoken(\'"\'));nexttoken() end-code')
vm.dictate('s" Forth" s" is the easist" s" programming langage" .s + + .s')
This example demonstrates how to use built-in functions push(), pop(), nexttoken() and the 'stack' global variable which is the center of a Forth system. Below tables list and explain all of them. Did you find the last line of the above example actually uses new words ( s" .s and + ) that are just defined in prior?
Let me know (hcchen5600@gmail.com, hcchen_1471@hotmail.com) if you couldn't understand anything of the above examples. Let's see how to improve them.
Global variables and built-in functions can be seen and used in code word and colon word definitions. They are not visible outside the project-k VM. You are encouraged to read the projectk.py source code directly. It's short, interesting and with a lot of comments.
No. | Global variable initial definition | Description |
---|---|---|
1 | vm | The project-k module object. |
2 | wordhash = {} | Forth words of recent active vocabularies. Find and get the word object through its name at the highest speed. |
3 | RET=null | The 'ret' instruction code. It marks the end of a colon word. |
4 | EXIT="" | The 'exit' instruction code. Same effect as 'ret' but used in colon definitions (instead of at the end of them). |
5 | stop = False | The flag to stop the outer loop. |
6 | newname = "" | The last new word's name. |
7 | newxt = function() | The last new word's executable. |
Above variables may not found in a traditional Forth system. Following ones are common Forth global variables you probably are very familiar with already .
No. | Global variable initial definition | Description |
---|---|---|
8 | compiling=False | The conventional flag of the Forth system state which is either compiling or interpreting. |
9 | ip=0 | The instruction pointer. Always points to the next word when in the inner loop. |
10 | stack = [] | The data stack. |
11 | rstack = [] | The return stack. |
12 | vocs = [] | The vocabulary list. e.g. ['forth','assembler', ...] |
13 | words = [] | The master word-list. e.g. words['forth'][], words['assembler'][], ... etc. |
14 | current = "forth" | The current definition of word-list or vocabulary. |
15 | context = "forth" | The recent top priority word-list or vocabulary. |
16 | order = [context] | Active vocabularies and their priority order. |
17 | dictionary=[]; dictionary[0]=0; | The Forth VM memory. |
18 | here=1 | Index of the Form VM memory. Next free address. |
19 | tib="" | The conventional Forth system's Terminal Input Buffer string. |
20 | ntib=0 | The index of TIB string. |
No. | Built-in function | Description |
---|---|---|
1 | dictate("commands") | An exported method of the project-k VM. This is where the Forth VM receives commands from the outside world. |
2 | Word(a[]) | The common constructor of all Forth words. |
3 | nextstring("delimitor") | Low level tool to get next string from TIB. |
4 | nexttoken("delimitor") | High level tool to get next string from TIB. |
5 | panic("msg", bool:severe) | Prints the error message. |
6 | reset(void) | Reset the Forth VM to avoid hanging up the computer. |
7 | isReDef("name") | Check if the new word is a re-defined. |
8 | mytypeof(x) | N/A, only needed in projectk.js |
9 | inner(entry, bool:resuming) | The loop that runs through a colon definition as fast as possible. |
10 | outer(entry) | The loop that walks through the command string from dictate(). |
Above functions may not be seen in a traditional Forth system and that's all of them. Following ones are from common Forth words you probably are very familiar with already.
No. | Built-in function | Description |
---|---|---|
11 | current_word_list(void) | Gets words[current]. |
12 | context_word_list(void) | Gets words[context]. |
13 | tick("name") | Find the word object through the given word name. |
14 | comma(x) | Comile x into the dictionary. |
15 | execute(x) | Execte one word. x can be a word name or a word object or simply a function. |
16 | tos(void|index) | Get a value from the data stack w/o removing it. tos() or tos(0) is the Top of the data stack. |
17 | rtos(void|index) | Similar to tos() but works on the return stack. |
18 | pop(void|index) | Get and remove a value from the data stack. pop() or pop(0) is the Top of the data stack. |
19 | push(data,volid|index) | Push a value into the data stack. push(data) or push(data,0) adds the value to the Top of the data stack. |
20 | type("s") | N/A, for projectk.js only |
21 | last(void) | Gets the last defined Forth word. |