The attached zip file contains version 0.22 of pfth. This version contains a few more core extension words, plus a few others in ansi.fth. I also added a few useful non-standard words in misc.fth. I ran the ANS Forth conformance tester on pfth, and there are quite a few cases where it fails, but many of these are unusual corner cases. I did fix several failures that could be encountered in normal use.
The zip file includes an install.bat file that will write the required files to you board's EEPROM and SD card. See the readme.txt file for installation instructions, and how you can create a configuration file for non-standard boards. The install will only run under Windows. If you have a different development platform you can use SimpleIDE to install the files. Send me a private message if you need any help with pfth.
Thanks Loopy.
Just a note: I checked swift forth. There is a free version, feature limited but not time limited. The bonus is it installs many pdf docs, including an ans forth reference and a programmer's handbook.
I'm going to put this up on the propforth site too, if thats ok
This is a DRAFT, I have already noted a few significant and minor typos. And no one has yet been allowed to comment on anything that might be a glaring omission on my part. Please don't be in too big a hurry.
Loopy, let us know when we're allowed to comment. I have a few suggestions.
pfth no longer requires SimpleIDE to build. I have included the propeller-load program and the pfth binary executable so that pfth can be installed without having to build it. The source files are included for information purposes only.
@Dave
Okay, I guess I shall just remove comments about needing Simple IDE in regards to pfth. I am not going to document compiling details as they may be subject to frequent changes.
Loopy, let us know when we're allowed to comment. I have a few suggestions.
pfth no longer requires SimpleIDE to build. I have included the propeller-load program and the pfth binary executable so that pfth can be installed without having to build it. The source files are included for information purposes only.
PLEASE keep including the entire source and project for SimpleIDE, there are a number of us operating under Mac and Linux. TNX
Okay, here is the finished (hopefully) version. Lots of little errors removed. A clean presentation really does matter when someone knows very little about the topic.
Since Dave is providing the source code, I presume that Simple IDE will continue to be supported as well as CatalinaC. These details are not discussed in the HOWTO as they just may lead the new user astray from getting started. Binaries can easily be downloaded via the original Propeller IDE, BST, and many be just about through any IDE that supports the Propeller.
Dave,
I got pfth v 022 up and running using an iMac running Mountain Lion and SimpleIDE. The configs are clean and it loaded EEPROM and uSD cleanly.
I setup a BlinkLED and that worked. But maybe it is too late and my brain is on strike or my eyes are too tired. How ... what word(s) are used to save user created words like 'saveforth' in PF or 'BACKUP' in Tachyon.
How ... what word(s) are used to save user created words like 'saveforth' in PF or 'BACKUP' in Tachyon.
Wait, I thought Forth was a write-only language. Why would you need to save anything? pfth currently doesn't have a save command. I could add one, but it will only be useful as long as you don't upgrade. This is because pfth uses absolute pointers for functions, words and jump addresses. When you upgrade these values will change, and you won't be able to run previously saved programs. pfth depends on loading source programs, and compiling them into memory each time you run it. That requires that you edit the source files before running pfth.
I suppose I could save the "see" versions of words as source file. These could then be recompiled back to executable code. The problem is that the "see" version would be saved using primitive words, and not the original words used when writing the code. This would allow the dictionary to be saved, and then reloaded in an updated version.
I think the "saving" behavior problwm you describe is typical to Forth implementations.
Forth should allow you to start with a bare kernel and then add words for your application and then saving the image so that you can reload the kernel PLUS your application without having to go through the process of adding/including/pasting the source .f files back every time you reset.
A version upgrade usually invalidates the kernel you have if you want to move to the update. Then you would start from the base kernel again and add in your application words and save the image with the new kernel and your application words.
A save across versions is difficult for the reasons you mention. The biggest need is to be able to save your working image across resets, crashes, etc. not blending your working dictionary into a new version's dictionary.
Only if you do it very well (needs no change) or very badly (better not change). Typically saving changes is a primary requirement of any forth system.
pfth currently doesn't have a save command.
Is there one in the ANS standard? I don't recall one per se, we usually implement our own method, often a cross compiler, always processor dependent. One of the issues with writing forth in another language, and skipping the step of implementing a target compiler for your own forth on that processor. This might be used as an example how the "standard" differs from a "practical" forth. ...
it will only be useful as long as you don't upgrade.
... for this reason. In this case, UPGRADE also means "extend the forth dictionary", which is typically a primary requirement of of a forth system.
..save the "see" versions of words as source file. These could then be recompiled back to executable code.
This more or less how propforth does it. Using the spin compiler resolved forward reverences, etc. So this is useful, although "different" from "normal".
Gobsmacked? I don't understand...but then I'm far from being in tune with the colloquial speech of youngsters!
From the GForth manual:
[h=3]13.3 Non-Relocatable Image Files[/h] These files are simple memory dumps of the dictionary. They are specific to the executable (i.e., gforth file) they were created with. What's worse, they are specific to the place on which the dictionary resided when the image was created. Now, there is no guarantee that the dictionary will reside at the same place the next time you start Gforth, so there's no guarantee that a non-relocatable image will work the next time (Gforth will complain instead of crashing, though).
You can create a non-relocatable image file with
savesystem "name" – gforth “savesystem”
This point out the problems of the non-relocatable image. gForth also has a way to load these images directly (beware relocation!)
In the Propeller's case, at least the dictionary start should not move between resets of the Propeller with the same kernel version. saveforth is essentially
the savesystem word implemented in Propforth.
Gobsmacked is a 'fun word' for extremely surprised. But the truth is that I've not tried to save anything in GForth or much of anything else at this point -- most of my work is just exploration and would be considered accumulated trash.
It just seemed logical to me that having an equivalent of saving the Dictionary in Hub Ram to EEPROM would happen. But I've had no time to check out pfth, though I wish I did. I have faithfully accumulated copies of all the distributions for a rainy day.
So are you saying that one must formally use the Block editor in GForth to retain work that will later be available? Or should some one use another .txt editior and just use INCLUDE and INCLUDED to insert at starting of GForth?
Maybe the SwiftForth Demo verison is a better choice for all.
pfth uses INCLUDE to load Forth source files. This is a non-standard word used in "Starting Forth", and I prefer it over the ANS word INCLUDED. It just seems more natural to say INCLUDE FILENAME instead of S" FILENAME" INCLUDED. ANS Forth does not specify a word for saving the dictionary. I'll implement a word that will save a binary copy of the dictionary that can be reloaded to the same version of code. I'll probably also implement a word that will save the dictionary as a text file that can be loaded to another version of pfth. This will require converting absolute jump addresses to relative addresses by creating a _jmpr primitive instead of using the _jmp primitive.
I think the "saving" behavior problwm you describe is typical to Forth implementations.
Forth should allow you to start with a bare kernel and then add words for your application and then saving the image so that you can reload the kernel PLUS your application without having to go through the process of adding/including/pasting the source .f files back every time you reset.
A version upgrade usually invalidates the kernel you have if you want to move to the update. Then you would start from the base kernel again and add in your application words and save the image with the new kernel and your application words.
A save across versions is difficult for the reasons you mention. The biggest need is to be able to save your working image across resets, crashes, etc. not blending your working dictionary into a new version's dictionary.
Regarding 'the bare Forth Kernel',
Is the bare Kernel, code without Lexicon, or code with a minimal lexicon? (Or worst of all, can it be both?)
I have a bit of difficulty with what exactly is a Kernel in Forth as it seems to be defined as inclusive of a minimal Dictionary. (I guess this the the ANS Forth 94 view of CORE items in the lexicon).
Just consider that Linux has a very obvious Kernel as it is all code and must be formally compiled and then loaded to run. Forth doesn't have such a precise departure point, so user might easily 'break the Kernel' by redefining or removing lexicon from the Dictionary. In Linux, one can 'break the Kernel' by deleting or modifying key files, but those elements are usually protected by a Superuser log in. '
No such formality is provided in Forth and no waring that one has to take responsibilities of a Superuser.
I am sure for some learners this really creates disasters and frustration. Shouldn't every Forth have a list of 'critical core lexicon' that should be treated with great care? Or is the ANS Forth 94 Core already a description of that so-called 'Kernel Lexicon'.
I suspect developers of microcontroller-based Forths have a very different 'minimalist lexicon' that they desire to use for the sake of tight storage spaces.
David
Saw you post in Bill's Tachyon thread, RE the release of a new Forth kernel. I wonder if its along the lines of your “First “ code with additional words from “Third” and with access to cog registers. . Anyway it will be interesting to see what you have come up with. The icing on the cake would be the “fl” word (see propforth) included as part of the kernel.
A Forth kernel needs to provide a sufficient set of words to be able to build more words and execute them. I think the FIRST Forth kernel is a good example of a minimal kernel. The problem with the FIRST kernel is that it doesn't implement and execute additional words very efficiently. A Forth kernel needs a few more basic words to be efficient.
Another small Forth kernel that I've come across is the Itsy Forth kernel. Its kernel has 28 words, which consist of 23 executable primatives and 5 variables. The kernel is basically the inner interpreter. The outer interpreter is the word INTERPRET, which is built up of the 28 kernel words. After INTERPRET is defined it is then executed, and provides the interface to the user.
The pfth PASM kernel implements the 45 words shown below. The remaining ANS core words are implemented in an external Forth program. I've tested this with the C version of pfth by limiting it to the 45 word vocabulary, and it works fine. I've gotten the PASM kernel running, and am currently working on debugging a problem with conditional jumps.
Interpreter Words Math and Logical Words Memory Access
----------------- ---------------------- -------------
evaluate + !
execute - @
find * c!
word / c@
refill mod
create and Console I/O
_lit or -----------
; xor emit
: < key
= accept
Program Termination >
------------------- lshift Utility
abort rshift -------
exit include
quit Registers bye
--------- see
Stack Operations #tib
---------------- tib
drop >in
pick depth
roll dp
>r last
r> state
base
All of the kernel words are ANS words except for _lit, dp and include. BTW, include, see and bye are used by the C version of the pfth kernel, but they aren't supported by the PASM kernel. I'll implement them in Forth for the PASM version.
dp is the address of the data pointer. HERE is implemented as ": here dp @ ;". _lit is a word used only in execution mode. It loads the value in the next long location onto the data stack.
The PASM kernel reads an init.fth Forth program that is compiled into the binary using the PASM FILE command. I modified my getch routine so that it initially reads from memory instead of from the serial input. It switches to the serial input after it hits the end of the init.fth file. The current contents of init.fth are shown below. As I said in my previous post, I am currently debugging the conditional jump word _JZ.
: immediate 1 last @ C + c! ;
: \ 100 word drop ; immediate
\ The above lines implement the immediate and \ words.
\ It is assumed that the base is currently set for hex mode.
\ DEFINE CELL SIZE
: cellsize 4 ;
: cellmask 3 ;
\ BASIC STACK WORDS
: dup 0 pick ;
: rot 2 roll ;
: swap 1 roll ;
: over 1 pick ;
: 2dup over over ;
: 2drop drop drop ;
: 2swap 3 roll 3 roll ;
: 2over 3 pick 3 pick ;
\ DEFINE BASIC WORD BUILDERS
: here dp @ ;
: allot dp @ + dp ! ;
: source tib #tib @ ;
: , here ! cellsize allot ;
: compile, , ;
: ' 20 word find 0 = 0 = and ;
: _does r> dup >r 8 + last @ 8 + ! ;
: _setjmp A last @ C + c! ;
: >body D + dup c@ + 4 + FFFFFFFC and ;
: literal 0 , , ; immediate
last @ >body dup @ swap 4 + ! \ Patch in address of _lit
: postpone ' , ; immediate
: ['] ' postpone literal ; immediate
: [compile] ' postpone literal ['] , , ; immediate
: does> [compile] _does [compile] exit ; immediate
\ CONDITIONAL EXECUTION AND LOOPING
: _jmp r> 4 + @ >r ; _setjmp
: _jz r> 4 + dup @ rot 0 = 1 + pick >r drop drop ; _setjmp
: if ['] _jz , here >r 4 allot ; immediate
: else ['] _jmp , here r> ! here >r 4 allot ; immediate
: then here 4 - r> ! ; immediate
Everything beyond the bare kernel is extensions. We add extensions until we have enough to do what we want, and then save this as a starting kernel. If we want a general development system on a particular chip, we can stop there. If we want a general solution that is code compatible on all syste4ms, we have to do a little more work.
Mr Sargent shows that from an initial set of words capable of extending the language, any desired set of words can be built.
prof_braino, that's an interesting link. However, it seems like the 3-instruction "Forth" is really just a loader. It seems like a stretch to call it "Forth". The kernel words are basically peek and poke instructions that most simple monitors provide, along with a jump instruction. The real Forth compiler in this case is implemented on a PC.
Comments
The demo files are not in the zip file.
No problems, I wrote a couple of test files and they worked like charm,
@Prof I will that do that for you. So that you can delete the features , I will post it in Propforth thread sometime late today
Ron
Ron
What was it the human torch in the Fantastic Four said? "Flame On!"
The zip file includes an install.bat file that will write the required files to you board's EEPROM and SD card. See the readme.txt file for installation instructions, and how you can create a configuration file for non-standard boards. The install will only run under Windows. If you have a different development platform you can use SimpleIDE to install the files. Send me a private message if you need any help with pfth.
I'm going to put this up on the propforth site too, if thats ok
Just a note: I checked swift forth. There is a free version, feature limited but not time limited. The bonus is it installs many pdf docs, including an ans forth reference and a programmer's handbook.
Massimo
This is a DRAFT, I have already noted a few significant and minor typos. And no one has yet been allowed to comment on anything that might be a glaring omission on my part. Please don't be in too big a hurry.
pfth no longer requires SimpleIDE to build. I have included the propeller-load program and the pfth binary executable so that pfth can be installed without having to build it. The source files are included for information purposes only.
Okay, I guess I shall just remove comments about needing Simple IDE in regards to pfth. I am not going to document compiling details as they may be subject to frequent changes.
PLEASE keep including the entire source and project for SimpleIDE, there are a number of us operating under Mac and Linux. TNX
Since Dave is providing the source code, I presume that Simple IDE will continue to be supported as well as CatalinaC. These details are not discussed in the HOWTO as they just may lead the new user astray from getting started. Binaries can easily be downloaded via the original Propeller IDE, BST, and many be just about through any IDE that supports the Propeller.
I got pfth v 022 up and running using an iMac running Mountain Lion and SimpleIDE. The configs are clean and it loaded EEPROM and uSD cleanly.
I setup a BlinkLED and that worked. But maybe it is too late and my brain is on strike or my eyes are too tired. How ... what word(s) are used to save user created words like 'saveforth' in PF or 'BACKUP' in Tachyon.
I suppose I could save the "see" versions of words as source file. These could then be recompiled back to executable code. The problem is that the "see" version would be saved using primitive words, and not the original words used when writing the code. This would allow the dictionary to be saved, and then reloaded in an updated version.
I think the "saving" behavior problwm you describe is typical to Forth implementations.
Forth should allow you to start with a bare kernel and then add words for your application and then saving the image so that you can reload the kernel PLUS your application without having to go through the process of adding/including/pasting the source .f files back every time you reset.
A version upgrade usually invalidates the kernel you have if you want to move to the update. Then you would start from the base kernel again and add in your application words and save the image with the new kernel and your application words.
A save across versions is difficult for the reasons you mention. The biggest need is to be able to save your working image across resets, crashes, etc. not blending your working dictionary into a new version's dictionary.
Only if you do it very well (needs no change) or very badly (better not change). Typically saving changes is a primary requirement of any forth system.
Is there one in the ANS standard? I don't recall one per se, we usually implement our own method, often a cross compiler, always processor dependent. One of the issues with writing forth in another language, and skipping the step of implementing a target compiler for your own forth on that processor. This might be used as an example how the "standard" differs from a "practical" forth. ...
... for this reason. In this case, UPGRADE also means "extend the forth dictionary", which is typically a primary requirement of of a forth system.
This more or less how propforth does it. Using the spin compiler resolved forward reverences, etc. So this is useful, although "different" from "normal".
From the GForth manual:
[h=3]13.3 Non-Relocatable Image Files[/h] These files are simple memory dumps of the dictionary. They are specific to the executable (i.e., gforth file) they were created with. What's worse, they are specific to the place on which the dictionary resided when the image was created. Now, there is no guarantee that the dictionary will reside at the same place the next time you start Gforth, so there's no guarantee that a non-relocatable image will work the next time (Gforth will complain instead of crashing, though).
You can create a non-relocatable image file with
savesystem "name" – gforth “savesystem”
This point out the problems of the non-relocatable image. gForth also has a way to load these images directly (beware relocation!)
In the Propeller's case, at least the dictionary start should not move between resets of the Propeller with the same kernel version. saveforth is essentially
the savesystem word implemented in Propforth.
It just seemed logical to me that having an equivalent of saving the Dictionary in Hub Ram to EEPROM would happen. But I've had no time to check out pfth, though I wish I did. I have faithfully accumulated copies of all the distributions for a rainy day.
So are you saying that one must formally use the Block editor in GForth to retain work that will later be available? Or should some one use another .txt editior and just use INCLUDE and INCLUDED to insert at starting of GForth?
Maybe the SwiftForth Demo verison is a better choice for all.
Regarding 'the bare Forth Kernel',
Is the bare Kernel, code without Lexicon, or code with a minimal lexicon? (Or worst of all, can it be both?)
I have a bit of difficulty with what exactly is a Kernel in Forth as it seems to be defined as inclusive of a minimal Dictionary. (I guess this the the ANS Forth 94 view of CORE items in the lexicon).
Just consider that Linux has a very obvious Kernel as it is all code and must be formally compiled and then loaded to run. Forth doesn't have such a precise departure point, so user might easily 'break the Kernel' by redefining or removing lexicon from the Dictionary. In Linux, one can 'break the Kernel' by deleting or modifying key files, but those elements are usually protected by a Superuser log in. '
No such formality is provided in Forth and no waring that one has to take responsibilities of a Superuser.
I am sure for some learners this really creates disasters and frustration. Shouldn't every Forth have a list of 'critical core lexicon' that should be treated with great care? Or is the ANS Forth 94 Core already a description of that so-called 'Kernel Lexicon'.
I suspect developers of microcontroller-based Forths have a very different 'minimalist lexicon' that they desire to use for the sake of tight storage spaces.
Saw you post in Bill's Tachyon thread, RE the release of a new Forth kernel. I wonder if its along the lines of your “First “ code with additional words from “Third” and with access to cog registers. . Anyway it will be interesting to see what you have come up with. The icing on the cake would be the “fl” word (see propforth) included as part of the kernel.
Ron
Another small Forth kernel that I've come across is the Itsy Forth kernel. Its kernel has 28 words, which consist of 23 executable primatives and 5 variables. The kernel is basically the inner interpreter. The outer interpreter is the word INTERPRET, which is built up of the 28 kernel words. After INTERPRET is defined it is then executed, and provides the interface to the user.
The pfth PASM kernel implements the 45 words shown below. The remaining ANS core words are implemented in an external Forth program. I've tested this with the C version of pfth by limiting it to the 45 word vocabulary, and it works fine. I've gotten the PASM kernel running, and am currently working on debugging a problem with conditional jumps.
dp is the address of the data pointer. HERE is implemented as ": here dp @ ;". _lit is a word used only in execution mode. It loads the value in the next long location onto the data stack.
The PASM kernel reads an init.fth Forth program that is compiled into the binary using the PASM FILE command. I modified my getch routine so that it initially reads from memory instead of from the serial input. It switches to the serial input after it hits the end of the init.fth file. The current contents of init.fth are shown below. As I said in my previous post, I am currently debugging the conditional jump word _JZ.
http://pygmy.utoh.org/3ins4th.html
The expert's explanation of "bare forth kernel".
Everything beyond the bare kernel is extensions. We add extensions until we have enough to do what we want, and then save this as a starting kernel. If we want a general development system on a particular chip, we can stop there. If we want a general solution that is code compatible on all syste4ms, we have to do a little more work.
Mr Sargent shows that from an initial set of words capable of extending the language, any desired set of words can be built.