280 lines
8.5 KiB
HTML
280 lines
8.5 KiB
HTML
<!--
|
|
Copyright 2021 Bradley D. Nelson
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
-->
|
|
|
|
<h5>Null Terminated Strings</h5>
|
|
<p>
|
|
As null terminated strings are used throughout C interfaces,
|
|
their use is supported in Forth by way of several non-standard
|
|
words with the convention of using Z/z to refer to such strings
|
|
in names and stack comments.
|
|
</p>
|
|
<pre>
|
|
Z" ( "string" -- z ) Creates a null terminated string on the heap
|
|
Z>S ( z -- a n ) Convert a null terminated string to a counted string
|
|
S>Z ( a n -- z ) Conver a counted string string to null terminated (copies string to heap)
|
|
</pre>
|
|
|
|
<h5>Raw Strings</h5>
|
|
<p>
|
|
Raw strings are provided better support using a string
|
|
for the duration of the current command, without consuming heap memory.
|
|
</p>
|
|
<pre>
|
|
R" ( "string" -- a n ) Creates a temporary counted string
|
|
R| ( string| -- a n ) Creates a temporary counted string ending with |
|
|
</pre>
|
|
|
|
<h5>Utilities</h5>
|
|
<pre>
|
|
DUMP ( a n -- ) Dump a memory region
|
|
SEE ( "name" -- ) Attempt to decompile a word
|
|
VARIABLE ECHO -- Determines if commands are echoed
|
|
REMAINING ( -- n ) Bytes remaining in Forth heap.
|
|
</pre>
|
|
|
|
<h5>Vocabularies</h5>
|
|
<p>
|
|
{{FORTH}} uses a hybrid of Forth-79 and Forth-83 style vocabularies.
|
|
By default vocabularies chain to the vocabulary in which they were defined,
|
|
as in Forth-79. However, like Forth-83, <code>ALSO</code>
|
|
can be used to add vocabularies to a vocabulary stack of which
|
|
<code>CONTEXT @</code> is the first item.
|
|
The word <code>ONLY</code> clears the vocabulary stack, but as there is
|
|
no separate ONLY vocabulary, it also sets <code>CONTEXT</code>
|
|
to the <code>FORTH</code> vocabulary.
|
|
The word <code>SEALED</code> modifies the most recently defined vocabulary
|
|
such that it does not chain. Note, this must be done before words are added to it.
|
|
</p>
|
|
<pre>
|
|
VOCABULARY ( "name" ) Create a vocabulary with the current vocabulary as parent
|
|
FORTH ( -- ) Make the FORTH vocabulary the context vocabulary
|
|
DEFINITIONS ( -- ) Make the context vocabulary the current vocabulary
|
|
VLIST ( -- ) List the words in the context vocabulary (not chains)
|
|
WORDS ( -- ) List the words in the context vocabulary (including chains)
|
|
TRANSFER ( "name" ) Move a word from its current dictionary to the current vocabulary
|
|
Useful for "hiding" built-in words
|
|
TRANSFER{ ..words.. }TRANSFER ( -- ) Transfer multiple words to the current vocabulary
|
|
ALSO ( -- ) Duplicate the vocabulary at the top of the vocabulary stack
|
|
PREVIOUS ( -- ) Drop the vocabulary at the top of the vocabulary stack
|
|
ONLY ( -- ) Reset context stack to one item, the FORTH dictionary
|
|
Non-standard, as there's no distinct ONLY vocabulary
|
|
ORDER ( -- ) Print the vocabulary search order
|
|
SEALED ( -- ) Alter the last vocabulary defined so it doesn't chain
|
|
</pre>
|
|
|
|
<h5>Interpret Time Conditions</h5>
|
|
<p>
|
|
<code>[I]F</code>, <code>[ELSE]</code>, and <code>[THEN]</code> can be used
|
|
to selectively compile. Used in tandem with <code>DEFINED?</code> they can
|
|
be used to handle the absence of modules gracefully.
|
|
Nesting is supported.
|
|
</p>
|
|
<pre>
|
|
DEFINED? ( "name" -- xt|0 ) Check if a word exists (works at compile time too).
|
|
[IF] ( f -- ) Conditionally interpret the text the follows.
|
|
[ELSE] ( -- ) Interpret time ELSE.
|
|
[THEN] ( -- ) Interpret time THEN.
|
|
</pre>
|
|
|
|
<h5>Blocks</h5>
|
|
<pre>
|
|
USE ( "name" -- ) Use "name" as the blockfile, e.g. USE /spiffs/foo
|
|
OPEN-BLOCKS ( a n -- ) Open a file as the block file
|
|
LOAD ( n -- ) Evaluate a block
|
|
THRU ( a b -- ) Load blocks a thru b
|
|
LIST ( n -- ) List a block
|
|
BLOCK ( n -- a ) Get a 1024 byte block
|
|
BUFFER ( n -- a ) Get a 1024 byte block without regard to old contents
|
|
UPDATE ( -- ) Mark the last block modified
|
|
FLUSH ( -- ) Save and empty all buffers
|
|
EMPTY-BUFFERS ( -- ) Empty all buffers
|
|
SAVE-BUFFERS ( -- ) Save all buffers
|
|
SCR ( -- a ) Pointer to last listed block
|
|
</pre>
|
|
|
|
<h5>Block Editor</h5>
|
|
These words are available inside the <code>EDITOR</code> vocabulary.
|
|
Note the block editor places newlines in the 63rd column of each line
|
|
to make the block file readable in a text editor.
|
|
<pre>
|
|
WIPE ( -- ) Blank out the current block
|
|
L ( -- ) List the current block
|
|
D ( n -- ) Delete a line in the current block
|
|
E ( n -- ) Clear a line in the current block
|
|
R ( n "text" -- ) Replace a line in the current block
|
|
A ( n "text" -- ) Add (insert) a line in the current block
|
|
P ( -- ) Move to the previous block
|
|
N ( -- ) Move to the next block
|
|
</pre>
|
|
|
|
<h5>Utilities</h5>
|
|
<pre>
|
|
SEE ( "name" -- ) Attempt to decompile a word
|
|
ECHO ( -- a ) -- Address of flag that determines if commands are echoed
|
|
</pre>
|
|
|
|
<h5>Floating-Point</h5>
|
|
<p><b>(Requires v7.0.6.5+)</b></p>
|
|
<p>
|
|
Single precision floating-point support is available as a work in progress.
|
|
While initially left out in the name of minimalism,
|
|
hardware support for floating-point argues some advantages to limited support.
|
|
</p>
|
|
<p>
|
|
Floating point is kept on a separate stack.
|
|
</p>
|
|
<p>
|
|
<b>NOTE: Tasks currently don't correctly support floating point.</b>
|
|
A single floating point stack is shared by all tasks.
|
|
</p>
|
|
<pre>
|
|
FLOAT OPCODES
|
|
-------------
|
|
DOFLIT ( --- ) Puts a float from the next cell onto float stack.
|
|
FP@ ( -- a )
|
|
FP! ( a -- )
|
|
SF@ ( a -- r ) Single precision load
|
|
SF! ( r a -- ) Single precision store
|
|
FDUP ( r -- r r )
|
|
FNIP ( ra rb -- rb )
|
|
FDROP ( r -- )
|
|
FOVER ( ra rb -- ra rb ra )
|
|
FSWAP ( ra rb -- rb ra )
|
|
F0< ( r -- f )
|
|
F0= ( r -- f )
|
|
F+ ( r r -- r )
|
|
F- ( r r -- r )
|
|
F* ( r r -- r )
|
|
F/ ( r r -- r )
|
|
1/F ( r -- r )
|
|
S>F ( n -- r )
|
|
F>S ( r -- n )
|
|
|
|
HIGH LEVEL
|
|
----------
|
|
F= ( r r -- f )
|
|
F< ( r r -- f )
|
|
F> ( r r -- f )
|
|
F<= ( r r -- f )
|
|
F>= ( r r -- f )
|
|
F<> ( r r -- f )
|
|
|
|
SFLOAT ( -- 4 )
|
|
SFLOATS ( n -- n*4 )
|
|
SFLOAT+ ( a -- a+4 )
|
|
SF, ( r -- )
|
|
|
|
AFLITERAL ( r -- )
|
|
FLITERAL ( r -- ) IMMEDIATE
|
|
|
|
FCONSTANT ( r "name" )
|
|
FVARIABLE ( "name" )
|
|
|
|
PI ( -- r )
|
|
|
|
FSQRT ( r r -- r )
|
|
|
|
F.S ( -- ) Print float stack.
|
|
</pre>
|
|
|
|
<h5>Locals</h5>
|
|
|
|
<p>
|
|
Locals allow named word local parameters and values.
|
|
</p>
|
|
|
|
<pre>
|
|
Syntax:
|
|
{ local1 local2 .. -- comment }
|
|
or
|
|
{ local1 local2 .. }
|
|
|
|
Locals are ordered to match the stack, examples:
|
|
: 2OVER { a b c d } a b c d a b ;
|
|
: MAX { a b -- biggest } a b < IF b ELSE a THEN ;
|
|
|
|
( Equivalent with DO and FOR )
|
|
: POW2 { n } 1 { s } n FOR AFT s 2* to s THEN NEXT s ;
|
|
: POW2 { n } 1 { s } n 0 DO s 2* to s LOOP s ;
|
|
</pre>
|
|
|
|
<p>
|
|
Capabilities and limitations:
|
|
<ul>
|
|
<li>Support for locals referenced inside DO and FOR loops - OK</li>
|
|
<li>Support for multiple {} uses in one definition - OK</li>
|
|
<li>Support for TO and +TO to modify a local</li>
|
|
<li>Locals mixed with raw return stack operations (<code>>R R></code>) - NOT OK</li>
|
|
<li>Locals defined inside a DO or FOR loop - NOT OK</li>
|
|
<li>The low level ANSForth word <code>(LOCAL)</code> is also supported.</li>
|
|
</ul>
|
|
</p>
|
|
|
|
<p>
|
|
</p>
|
|
|
|
<h5 id="dictimages">Dictionary Images and Startup</h5>
|
|
|
|
<p>
|
|
<b>WARNING: Danger ahead.</b><br/>
|
|
Snapshotting the dictionary may not be stable across reinstallations of the C build of Forth.
|
|
</p>
|
|
|
|
<p>
|
|
A collection of non-standard words is provided that allow snapshotting
|
|
the dictionary and restoring it at startup, with a start word.
|
|
</p>
|
|
|
|
<pre>
|
|
SAVE ( "name" -- ) Saves a snapshot of the current dictionary to a file.
|
|
RESTORE ( "name" -- ) Restore a snapshot from a file.
|
|
REMEMBER ( -- ) Save a snapshot to the default file
|
|
(./myforth or /spiffs/myforth on ESP32).
|
|
STARTUP: ( "name" -- ) Save a snapshot to the default file arranging for
|
|
"name" to be run on startup.
|
|
REVIVE ( -- ) Restore the default filename.
|
|
RESET ( -- ) Delete the default filename.
|
|
</pre>
|
|
|
|
<p>
|
|
Here's an example usage:
|
|
</p>
|
|
|
|
<pre>
|
|
: welcome ." Hello!" cr 100 0 do i . loop cr ;
|
|
startup: welcome
|
|
bye
|
|
|
|
( Next boot will run a custom startup message )
|
|
|
|
reset
|
|
|
|
( Reset removes the custom message )
|
|
</pre>
|
|
|
|
<p>
|
|
The <code>INTERNALS</code> vocabulary has some additional words
|
|
for more control.
|
|
</p>
|
|
|
|
<pre>
|
|
SAVE-NAME ( a n -- ) Save a snapshot if the current vocabulary to a file.
|
|
RESTORE-NAME ( a n -- ) Restore a snapshot from a file.
|
|
'COLD ( -- a ) Address of the word that will be run on startup.
|
|
REMEMBER-FILENAME ( -- a n ) Deferred word specifying the platform specific
|
|
default snapshot filename.
|
|
</pre>
|