/
common.html
275 lines (239 loc) · 8.31 KB
/
common.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
<!--
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
</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
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" )
FVARAIABLE ( "name" )
PI ( -- r )
FSQRT ( r r -- r )
</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>