Imported Upstream version 21
[debian/pforth] / docs / pf_ref.htm
1 <HTML>\r
2 <HEAD>\r
3    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">\r
4    <META NAME="Author" CONTENT="Phil Burk">\r
5    <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (Win95; I) [Netscape]">\r
6    <META NAME="Description" CONTENT="Reference Manual for pForth, a Portable ANSI Forth environment written in ANSI 'C'.">\r
7    <META NAME="KeyWords" CONTENT="pForth, Forth, Reference, portable, ANS">\r
8    <TITLE> pForth Reference</TITLE>\r
9 </HEAD>\r
10 <BODY>\r
11 \r
12 <CENTER>\r
13 <H1>\r
14 \r
15 <HR WIDTH="100%"></H1></CENTER>\r
16 \r
17 <CENTER>\r
18 <H1>\r
19 pForth Reference Manual</H1></CENTER>\r
20 \r
21 <CENTER>\r
22 <HR WIDTH="100%"></CENTER>\r
23 \r
24 <H3>\r
25 pForth - a Portable ANSI style Forth written in ANSI 'C'.&nbsp; <B>Last\r
26 updated: August 20th, 1998 V20</B></H3>\r
27 by <A HREF="mailto:philburk@softsynth.com">Phil Burk</A> with Larry Polansky,\r
28 David Rosenboom. Special thanks to contributors Darren Gibbs, Herb Maeder,\r
29 Gary Arakaki, Mike Haas.\r
30 \r
31 <P>PForth source code is freely available.&nbsp; The author is available\r
32 for customization of pForth, porting to new platforms, or developing pForth\r
33 applications on a contractual basis.&nbsp; If interested, contact&nbsp;\r
34 Phil Burk at <A HREF="mailto:philburk@softsynth.com">philburk@softsynth.com</A>\r
35 \r
36 <P>Back to <A HREF="pforth.html">pForth Home Page</A>\r
37 <CENTER>\r
38 <H2>\r
39 LEGAL NOTICE</H2></CENTER>\r
40 The pForth software code is dedicated to the public domain, and any third\r
41 party may reproduce, distribute and modify the pForth software code or\r
42 any derivative works thereof without any compensation or license. The pForth\r
43 software code is provided on an "as is" basis without any warranty of any\r
44 kind, including, without limitation, the implied warranties of merchantability\r
45 and fitness for a particular purpose and their equivalents under the laws\r
46 of any jurisdiction.\r
47 \r
48 <P>\r
49 <HR WIDTH="100%">\r
50 <H2>\r
51 Table of Contents</H2>\r
52 \r
53 <UL>\r
54 <LI>\r
55 <A HREF="#What is pForth">What is pForth?</A></LI>\r
56 \r
57 <LI>\r
58 <A HREF="#Compiling pForth for your System">Compiling pForth for your System</A></LI>\r
59 \r
60 <UL>\r
61 <LI>\r
62 <A HREF="#Description of Source Files">Description of Source Files</A></LI>\r
63 </UL>\r
64 \r
65 <LI>\r
66 <A HREF="#Running pForth">Running pForth</A></LI>\r
67 \r
68 <LI>\r
69 <A HREF="#ANSI Compliance">ANSI Compliance</A></LI>\r
70 \r
71 <LI>\r
72 <A HREF="#pForth Special Features">pForth Special Features</A></LI>\r
73 \r
74 <UL>\r
75 <LI>\r
76 <A HREF="#Compiling from a File">Compiling from a File - INCLUDE</A></LI>\r
77 \r
78 <LI>\r
79 <A HREF="#Saving Precompiled Dictionaries">Saving Precompiled Dictionaries</A></LI>\r
80 \r
81 <LI>\r
82 <A HREF="#Recompiling Code - ANEW INCLUDE?">Recompiling Code - ANEW INCLUDE?</A></LI>\r
83 \r
84 <LI>\r
85 <A HREF="#Customising FORGET with [FORGET]">Customising Forget with [FORGET]</A></LI>\r
86 \r
87 <LI>\r
88 <A HREF="#Smart Conditionals">Smart Conditionals</A></LI>\r
89 \r
90 <LI>\r
91 <A HREF="#Development Tools">Development Tools</A></LI>\r
92 \r
93 <UL>\r
94 <LI>\r
95 <A HREF="#WORDS.LIKE">WORDS.LIKE</A></LI>\r
96 \r
97 <LI>\r
98 <A HREF="#FILE?">FILE?</A></LI>\r
99 \r
100 <LI>\r
101 <A HREF="#SEE">SEE</A></LI>\r
102 \r
103 <LI>\r
104 <A HREF="#Single Step Trace">Single Step Trace and Debug</A></LI>\r
105 </UL>\r
106 \r
107 <LI>\r
108 <A HREF="#Conditional Compilation [IF] [ELSE] [THEN]">Conditional Compilation\r
109 - [IF] [ELSE] [THEN]</A></LI>\r
110 \r
111 <LI>\r
112 <A HREF="#Miscellaneous Handy Words">Miscellaneous Handy Words</A></LI>\r
113 \r
114 <LI>\r
115 <A HREF="#Local Variables { foo --}">Local Variables { foo -- }</A></LI>\r
116 \r
117 <LI>\r
118 <A HREF="#'C' like Structures. :STRUCT">'C' like Structures. :STRUCT</A></LI>\r
119 \r
120 <LI>\r
121 <A HREF="#Vectorred Execution - DEFER">Vectorred execution - DEFER</A></LI>\r
122 \r
123 <LI>\r
124 <A HREF="#Floating Point">Floating Point</A></LI>\r
125 </UL>\r
126 \r
127 <LI>\r
128 <A HREF="#pForth Design">pForth Design</A></LI>\r
129 \r
130 <UL>\r
131 <LI>\r
132 <A HREF="#'C' kernel">'C' kernel</A></LI>\r
133 \r
134 <LI>\r
135 <A HREF="#Dictionary Structures">Dictionary Structures</A></LI>\r
136 </UL>\r
137 \r
138 <LI>\r
139 <A HREF="#Custom Compilation of pForth">Custom Compilation of pForth</A></LI>\r
140 \r
141 <UL>\r
142 <LI>\r
143 <A HREF="#Compiler Options">Compiler Options</A></LI>\r
144 \r
145 <LI>\r
146 <A HREF="#Building pForth on Supported Hosts">Building pForth on Supported\r
147 Hosts</A></LI>\r
148 \r
149 <LI>\r
150 <A HREF="#Compiling for Embedded Systems">Compiling for Embedded Systems</A></LI>\r
151 \r
152 <LI>\r
153 <A HREF="#Linking with Custom 'C' Functions">Linking with Custom 'C' Functions</A></LI>\r
154 \r
155 <LI>\r
156 <A HREF="#Minimal Executables - CLONE">Minimal executables. CLONE</A></LI>\r
157 \r
158 <LI>\r
159 <A HREF="#Testing your Compiled pForth">Testing your Compiled pForth</A></LI>\r
160 </UL>\r
161 </UL>\r
162 \r
163 <HR WIDTH="100%">\r
164 <H2>\r
165 <A NAME="What is pForth"></A>What is pForth?</H2>\r
166 PForth is an ANSI style Forth designed to be portable across many platforms.\r
167 The 'P' in pForth stands for "Portable". PForth is based on a Forth kernel\r
168 written in ANSI standard 'C'.\r
169 <H3>\r
170 What is Forth?</H3>\r
171 Forth is a stack based language invented by astronomer Charles Moore for\r
172 controlling telescopes. Forth is an interactive language. You can enter\r
173 commands at the keyboard and have them be immediately executed, similar\r
174 to BASIC or LISP. Forth has a dictionary of words that can be executed\r
175 or used to construct new words that are then added to the dictionary. Forth\r
176 words operate on a data stack that contains numbers and addresses.\r
177 \r
178 <P>To learn more about Forth, see the <A HREF="pf_tut.htm">Forth Tutorial</A>.\r
179 <H3>\r
180 The Origins of pForth</H3>\r
181 PForth began as a JSR threaded 68000 Forth called HForth that was used\r
182 to support HMSL, the Hierarchical Music Specification Language. HMSL was\r
183 a music experimentation language developed by Phil Burk, Larry Polansky\r
184 and David Rosenboom while working at the Mills College Center for Contemporary\r
185 Music. Phil moved from Mills to the 3DO Company where he ported the Forth\r
186 kernel to 'C'. It was used at 3DO as a tool for verifying ASIC design and\r
187 for bringing up new hardware platforms. At 3DO, the Forth had to run on\r
188 many systems including SUN, SGI, Macintosh, PC, Amiga, the 3DO ARM based\r
189 Opera system, and the 3DO PowerPC based M2 system. PForth is now being\r
190 developed for use at CagEnt, a spinoff of 3DO.\r
191 <H3>\r
192 pForth Design Goals</H3>\r
193 PForth has been designed with portability as the primary design goal. As\r
194 a result, pForth avoids any fancy UNIX calls. pForth also avoids using\r
195 any clever and original ways of constructing the Forth dictionary. It just\r
196 compiles its kernel from ANSI compatible 'C' code then loads ANS compatible\r
197 Forth code to build the dictionary. Very boring but very likely to work\r
198 on almost any platform.\r
199 \r
200 <P>The dictionary files that can be saved from pForth are almost host independant.\r
201 They can be compiled on one processor, and then run on another processor.\r
202 as long as the endian-ness is the same. In other words, dictionaries built\r
203 on a PC will only work on a PC. Dictionaries built on almost any other\r
204 computer will work on almost any other computer.\r
205 \r
206 <P>PForth can be used to bring up minimal hardware systems that have very\r
207 few system services implemented. It is possible to compile pForth for systems\r
208 that only support routines to send and receive a single character. If malloc()\r
209 and free() are not available, equivalent functions are available in standard\r
210 'C' code. If file I/O is not available, the dictionary can be saved as\r
211 a static data array in 'C' source format on a host system. The dictionary\r
212 in 'C' source form is then compiled with a custom pForth kernel to avoid\r
213 having to read the dictionary from disk.\r
214 \r
215 <P>\r
216 <HR WIDTH="100%">\r
217 <H2>\r
218 <A NAME="Compiling pForth for your System"></A>Compiling pForth for your\r
219 System</H2>\r
220 The process of building pForth involves several steps. This process is\r
221 typically handled automatically by the Makefile or IDE Project.\r
222 <OL>\r
223 <LI>\r
224 Compile the 'C' based pForth kernel called "pforth".</LI>\r
225 \r
226 <LI>\r
227 Execute "pforth" with the -i option to build the dictionary from scratch.</LI>\r
228 \r
229 <LI>\r
230 Compile the "system.fth" file which will add all the top level Forth words.</LI>\r
231 \r
232 <LI>\r
233 Save the compiled dictionary as "pforth.dic".</LI>\r
234 \r
235 <LI>\r
236 The next time you run pforth, the precompiled pforth.dic file will be loaded\r
237 automatically.</LI>\r
238 </OL>\r
239 \r
240 <H3>\r
241 UNIX</H3>\r
242 A Makefile has been provided that should work on most UNIX platforms.\r
243 <OL>\r
244 <LI>\r
245 cd to top directory of pForth</LI>\r
246 \r
247 <LI>\r
248 Enter: make all</LI>\r
249 </OL>\r
250 \r
251 <H3>\r
252 Macintosh</H3>\r
253 A precompiled PPC binary for pForth is provided. A Code Warrior Project\r
254 has been provided that will rebuild pForth for PPC if desired. Alternatively\r
255 you could use MPW to make pForth as an MPW Tool.&nbsp; Make sure that you\r
256 provide at least 1 Meg of heap space. If you build for 68K, make sure you\r
257 use 32 bit integers, and select the appropriate libraries.&nbsp; To rebuild\r
258 pForth for PPC:\r
259 <OL>\r
260 <LI>\r
261 Open pForthCW</LI>\r
262 \r
263 <LI>\r
264 Make target "pForthApp"</LI>\r
265 \r
266 <LI>\r
267 Run pForthApp</LI>\r
268 \r
269 <LI>\r
270 Enter "-i" as Argumant in starting dialog to initialize dictionary.</LI>\r
271 \r
272 <LI>\r
273 To compile system.fth, enter "loadsys".</LI>\r
274 \r
275 <LI>\r
276 Quit pForth using File menu.</LI>\r
277 \r
278 <LI>\r
279 From now on, just double click pForthApp icon to run pForth.</LI>\r
280 </OL>\r
281 \r
282 <H3>\r
283 PC Compatible</H3>\r
284 A precompiled binary for pForth is provided. <FONT COLOR="#000000">To rebuild\r
285 under Windows NT or Win95 using Microsoft Visual C++:</FONT>\r
286 <OL>\r
287 <LI>\r
288 <FONT COLOR="#000000">Double click on the pForth.dsw icon in "pForth\pcbuild".</FONT></LI>\r
289 \r
290 <LI>\r
291 <FONT COLOR="#000000">Select the "MakeDic" configuration.</FONT></LI>\r
292 \r
293 <LI>\r
294 <FONT COLOR="#000000">Select "Rebuild All" from the Build menu.This will\r
295 build the pForth.exe file.</FONT></LI>\r
296 \r
297 <LI>\r
298 <FONT COLOR="#000000">Run the app with CTRL-F5 which will build the pforth.dic\r
299 file.</FONT></LI>\r
300 \r
301 <LI>\r
302 <FONT COLOR="#000000">Select the "Release" configuration.</FONT></LI>\r
303 \r
304 <LI>\r
305 <FONT COLOR="#000000">Run the app with CTRL-F5 which will drop you into\r
306 Forth.</FONT></LI>\r
307 \r
308 <LI>\r
309 <FONT COLOR="#000000">From now on, to run pForth, just double click on\r
310 the pforth.exe file.</FONT></LI>\r
311 </OL>\r
312 \r
313 <H3>\r
314 <A NAME="Description of Source Files"></A>Description of Source Files</H3>\r
315 \r
316 <H4>\r
317 Forth Source</H4>\r
318 \r
319 <PRE>ansilocs.fth&nbsp;&nbsp;&nbsp; = support for ANSI (LOCAL) word\r
320 c_struct.fth&nbsp;&nbsp;&nbsp; = 'C' like data structures\r
321 case.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = CASE OF ENDOF ENDCASE\r
322 catch.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = CATCH and THROW\r
323 condcomp.fth&nbsp;&nbsp;&nbsp; = [IF] [ELSE] [THEN] conditional compiler\r
324 filefind.fth&nbsp;&nbsp;&nbsp; = FILE?\r
325 floats.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = floating point support\r
326 forget.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = FORGET [FORGET] IF.FORGOTTEN\r
327 loadp4th.fth&nbsp;&nbsp;&nbsp; = loads basic dictionary\r
328 locals.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = { } style locals using (LOCAL)\r
329 math.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = misc math words\r
330 member.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = additional 'C' like data structure support\r
331 misc1.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = miscellaneous words\r
332 misc2.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = miscellaneous words\r
333 numberio.fth&nbsp;&nbsp;&nbsp; = formatted numeric input/output\r
334 private.fth&nbsp;&nbsp;&nbsp;&nbsp; = hide low level words\r
335 quit.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = QUIT EVALUATE INTERPRET in high level\r
336 smart_if.fth&nbsp;&nbsp;&nbsp; = allows conditionals outside colon definition\r
337 see.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = Forth "disassembler".&nbsp; Eg.&nbsp; SEE SPACES\r
338 strings.fth&nbsp;&nbsp;&nbsp;&nbsp; = string support\r
339 system.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = bootstraps pForth dictionary\r
340 trace.fth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = single step trace for debugging</PRE>\r
341 \r
342 <H4>\r
343 'C' Source</H4>\r
344 csrc/pfcompil.c = pForth compiler support\r
345 <BR>csrc/pfcustom.c = example of 'C' functions callable from pForth\r
346 <BR>csrc/pfinnrfp.h = float extensions to interpreter\r
347 <BR>csrc/pforth.h = include this in app that embeds pForth\r
348 <BR>csrc/pf_cglue.c = glue for pForth calling 'C'\r
349 <BR>csrc/pf_clib.c = replacement routines for 'C' stdlib\r
350 <BR>csrc/pf_core.c = primary words called from 'C' app that embeds pForth\r
351 <BR>csrc/pf_float.h = defines PF_FLOAT, and the floating point math functions\r
352 such as fp_sin\r
353 <BR>csrc/pf_inner.c = inner interpreter\r
354 <BR>csrc/pf_guts.h = primary include file, define structures\r
355 <BR>csrc/pf_io.c = input/output\r
356 <BR>csrc/pf_main.c = basic application for standalone pForth\r
357 <BR>csrc/pf_mem.c = optional malloc() implementation\r
358 <BR>csrc/pf_save.c = save and load dictionaries\r
359 <BR>csrc/pf_text.c = string tools, error message text\r
360 <BR>csrc/pf_words.c = miscellaneous pForth words implemented\r
361 <BR>\r
362 <HR WIDTH="100%">\r
363 <H2>\r
364 <A NAME="Running pForth"></A>Running pForth</H2>\r
365 PForth can be run from a shell or by double clicking on its icon, depending\r
366 on the system you are using. The execution options for pForth are described\r
367 assuming that you are running it from a shell.\r
368 \r
369 <P>Usage:\r
370 <UL>\r
371 <PRE>pforth [-i] [-dDictionaryFilename] [SourceFilename]</PRE>\r
372 </UL>\r
373 \r
374 <DT>\r
375 -i</DT>\r
376 \r
377 <DD>\r
378 Initialize pForth by building dictionary from scratch. Used when building\r
379 pForth or when debugging pForth on new systems.</DD>\r
380 \r
381 <DT>\r
382 -dDictionaryFilename</DT>\r
383 \r
384 <DD>\r
385 Specify a custom dictionary to be loaded in place of the default "pforth.dic".\r
386 For example:</DD>\r
387 \r
388 <UL>\r
389 <UL>\r
390 <PRE>pforth -dgame.dic</PRE>\r
391 </UL>\r
392 </UL>\r
393 \r
394 <DT>\r
395 SourceFilename</DT>\r
396 \r
397 <DD>\r
398 A Forth source file can be automatically compiled by passing its name to\r
399 pForth. This is useful when using Forth as an assembler or for automated\r
400 hardware testing. Remember that the source file can compile code and execute\r
401 it all in the same file.</DD>\r
402 \r
403 <H4>\r
404 Quick Verification of pForth</H4>\r
405 To verify that PForth is working, enter:\r
406 <UL>\r
407 <PRE>3 4 + .</PRE>\r
408 </UL>\r
409 It should print "7 ok". Now enter:\r
410 <UL>WORDS</UL>\r
411 You should see a long list of all the words in the pForth dictionary. Don't\r
412 worry. You won't need to learn all of these.&nbsp; More tests are described\r
413 in the README.txt file.\r
414 \r
415 <P>\r
416 <HR WIDTH="100%">\r
417 <H2>\r
418 <A NAME="ANSI Compliance"></A>ANSI Compliance</H2>\r
419 This Forth is intended to be ANS compatible. I will not claim that it is\r
420 compatible until more people bang on it. If you find areas where it deviates\r
421 from the standard, please let me know.\r
422 \r
423 <P>Word sets supported include:\r
424 <UL>\r
425 <LI>\r
426 FLOAT</LI>\r
427 \r
428 <LI>\r
429 LOCAL with support for { lv1 lv2 | lv3 -- } style locals</LI>\r
430 \r
431 <LI>\r
432 EXCEPTION but standard throw codes not implemented</LI>\r
433 \r
434 <LI>\r
435 FILE ACCESS</LI>\r
436 \r
437 <LI>\r
438 MEMORY ALLOCATION</LI>\r
439 </UL>\r
440 Here are the areas that I know are not compatible:\r
441 \r
442 <P>The ENVIRONMENT queries are not implemented.\r
443 \r
444 <P>Word sets NOT supported include:\r
445 <UL>\r
446 <LI>\r
447 BLOCK - a matter of religion</LI>\r
448 \r
449 <LI>\r
450 SEARCH ORDER - coming soon</LI>\r
451 \r
452 <LI>\r
453 PROGRAMMING TOOLS - only has .S ? DUMP WORDS BYE</LI>\r
454 \r
455 <LI>\r
456 STRING - only has CMOVE CMOVE> COMPARE</LI>\r
457 \r
458 <LI>\r
459 DOUBLE NUMBER - but cell is 32 bits</LI>\r
460 </UL>\r
461 \r
462 <HR WIDTH="100%">\r
463 <H2>\r
464 <A NAME="pForth Special Features"></A>pForth Special Features</H2>\r
465 These features are not part of the ANS standard for Forth.&nbsp; They have\r
466 been added to assist developers.\r
467 <H3>\r
468 <A NAME="Compiling from a File"></A>Compiling from a File</H3>\r
469 Use INCLUDE to compile source code from a file:\r
470 <UL>\r
471 <PRE>INCLUDE filename</PRE>\r
472 </UL>\r
473 You can nest calls to INCLUDE. INCLUDE simply redirects Forth to takes\r
474 its input from the file instead of the keyboard so you can place any legal\r
475 Forth code in the source code file.\r
476 <H3>\r
477 <A NAME="Saving Precompiled Dictionaries"></A>Saving Precompiled Dictionaries</H3>\r
478 Use SAVE-FORTH save your precompiled code to a file. To save the current\r
479 dictionary to a file called "custom.dic", enter:\r
480 <UL>\r
481 <PRE>c" custom.dic" SAVE-FORTH</PRE>\r
482 </UL>\r
483 You can then leave pForth and use your custom dictionary by enterring:\r
484 <UL>\r
485 <PRE>pforth -dcustom.dic</PRE>\r
486 </UL>\r
487 On icon based systems, you may wish to name your custom dictionary "pforth.dic"\r
488 so that it will be loaded automatically.\r
489 \r
490 <P>Be careful that you do not leave absolute addresses stored in the dictionary\r
491 because they will not work when you reload pForth at a different address.\r
492 Use A! to store an address in a variable in a relocatable form and A@ to\r
493 get it back if you need to.\r
494 <UL>\r
495 <PRE>VARIABLE DATA-PTR\r
496 CREATE DATA 100 ALLOT\r
497 DATA DATA-PTR !&nbsp;&nbsp;&nbsp; \ storing absolute address!&nbsp; BAD\r
498 DATA DATA-PTR A!&nbsp;&nbsp; \ storing relocatable address!&nbsp; GOOD\r
499 DATA-PTR A@&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \ fetch relocatable address</PRE>\r
500 </UL>\r
501 \r
502 <H3>\r
503 <A NAME="Recompiling Code - ANEW INCLUDE?"></A>Recompiling Code - ANEW\r
504 INCLUDE?</H3>\r
505 When you are testing a file full of code, you will probably recompile many\r
506 times. You will probably want to FORGET the old code before loading the\r
507 new code. You could put a line at the beginning of your file like this:\r
508 <UL>\r
509 <PRE>FORGET XXXX-MINE&nbsp;&nbsp;&nbsp;&nbsp; : XXXX-MINE ;</PRE>\r
510 </UL>\r
511 This would automatically FORGET for you every time you load. Unfortunately,\r
512 you must define XXXX-MINE before you can ever load this file. We have a\r
513 word that will automatically define a word for you the first time, then\r
514 FORGET and redefine it each time after that. It is called ANEW and can\r
515 be found at the beginning of most Forth source files. We use a prefix of\r
516 TASK- followed by the filename just to be consistent. This TASK-name word\r
517 is handy when working with INCLUDE? as well. Here is an example:\r
518 <UL>\r
519 <PRE>\ Start of file\r
520 INCLUDE? TASK-MYTHING.FTH MYTHING.FTH\r
521 ANEW TASK-THISFILE.FTH\r
522 \ the rest of the file follows...</PRE>\r
523 </UL>\r
524 Notice that the INCLUDE? comes before the call to ANEW so that we don't\r
525 FORGET MYTHING.FTH every time we recompile.\r
526 \r
527 <P>FORGET allows you to get rid of code that you have already compiled.\r
528 This is an unusual feature in a programming language. It is very convenient\r
529 in Forth but can cause problems. Most problems with FORGET involve leaving\r
530 addresses that point to the forgotten code that are not themselves forgotten.\r
531 This can occur if you set a deferred system word to your word then FORGET\r
532 your word. The system word which is below your word in the dictionary is\r
533 pointing up to code that no longer exists. It will probably crash if called.\r
534 (See discussion of DEFER below.) Another problem is if your code allocates\r
535 memory, opens files, or opens windows. If your code is forgotten you may\r
536 have no way to free or close these thing. You could also have a problems\r
537 if you add addresses from your code to a table that is below your code.\r
538 This might be a jump table or data table.\r
539 \r
540 <P>Since this is a common problem we have provided a tool for handling\r
541 it. If you have some code that you know could potentially cause a problem\r
542 if forgotten, then write a cleanup word that will eliminate the problem.\r
543 This word could UNdefer words, free memory, etc. Then tell the system to\r
544 call this word if the code is forgotten. Here is how:\r
545 <UL>\r
546 <PRE>: MY.CLEANUP&nbsp; ( -- , do whatever )\r
547 &nbsp;&nbsp;&nbsp; MY-MEM @ FREE DROP\r
548 &nbsp;&nbsp;&nbsp; 0 MY-MEM !\r
549 ;\r
550 IF.FORGOTTEN&nbsp; MY.CLEANUP</PRE>\r
551 </UL>\r
552 IF.FORGOTTEN creates a linked list node containing your CFA that is checked\r
553 by FORGET. Any nodes that end up above HERE (the Forth pointer to the top\r
554 of the dictionary) after FORGET is done are executed.\r
555 <H3>\r
556 <A NAME="Customising FORGET with [FORGET]"></A>Customising FORGET with\r
557 [FORGET]</H3>\r
558 Sometimes, you may need to extend the way that FORGET works. FORGET is\r
559 not deferred, however, because that could cause some real problems. Instead,\r
560 you can define a new version of [FORGET] which is searched for and executed\r
561 by FORGET. You MUST call [FORGET] from your program or FORGET will not\r
562 actually FORGET. Here is an example.\r
563 <UL>\r
564 <PRE>: [FORGET]&nbsp; ( -- , my version )\r
565 &nbsp;&nbsp;&nbsp; ." Change things around!" CR\r
566 &nbsp;&nbsp;&nbsp; [FORGET]&nbsp; ( must be called )\r
567 &nbsp;&nbsp;&nbsp; ." Now put them back!" CR\r
568 ;\r
569 : FOO ." Hello!" ;\r
570 FORGET FOO&nbsp; ( Will print "Change things around!", etc.)</PRE>\r
571 </UL>\r
572 This is recommended over redefining FORGET because words like ANEW that\r
573 call FORGET will now pick up your changes.\r
574 <H3>\r
575 <A NAME="Smart Conditionals"></A>Smart Conditionals</H3>\r
576 In pForth, you can use IF THEN DO LOOP and other conditionals outside of\r
577 colon definitions. PForth will switch temporarily into the compile state,\r
578 then automatically execute the conditional code. (Thank you Mitch Bradley)\r
579 For example, just enter this at the keyboard.\r
580 <UL>\r
581 <PRE>10 0 DO I . LOOP</PRE>\r
582 </UL>\r
583 \r
584 <H3>\r
585 <A NAME="Development Tools"></A>Development Tools</H3>\r
586 \r
587 <H4>\r
588 <A NAME="WORDS.LIKE"></A>WORDS.LIKE</H4>\r
589 If you cannot remember the exact name of a word, you can use WORDS.LIKE\r
590 to search the dictionary for all words that contain a substring. For an\r
591 example, enter:\r
592 <UL>\r
593 <PRE>WORDS.LIKE&nbsp;&nbsp; FOR\r
594 WORDS.LIKE&nbsp;&nbsp; EMIT</PRE>\r
595 </UL>\r
596 \r
597 <H4>\r
598 <A NAME="FILE?"></A>FILE?</H4>\r
599 You can use FILE? to find out what file a word was compiled from. If a\r
600 word was defined in multiple files then it will list each file. The execution\r
601 token of each definition of the word is listed on the same line.\r
602 <UL>FILE? IF\r
603 <BR>FILE? AUTO.INIT</UL>\r
604 \r
605 <H4>\r
606 <A NAME="SEE"></A>SEE</H4>\r
607 You can use SEE to "disassemble" a word in the pForth dictionary. SEE will\r
608 attempt to print out Forth source in a form that is similar to the source\r
609 code. SEE will give you some idea of how the word was defined but is not\r
610 perfect. Certain compiler words, like BEGIN and LITERAL, are difficult\r
611 to disassemble and may not print properly. For an example, enter:\r
612 <UL>\r
613 <PRE>SEE SPACES\r
614 SEE WORDS</PRE>\r
615 </UL>\r
616 \r
617 <H4>\r
618 <A NAME="Single Step Trace"></A>Single Step Trace and Debug</H4>\r
619 It is often useful to proceed step by step through your code when debugging.&nbsp;\r
620 PForth provides a simple single step trace facility for this purpose.&nbsp;\r
621 Here is an example of using TRACE to debug a simple program.&nbsp; Enter\r
622 the following program:\r
623 <BR>&nbsp;\r
624 <UL>\r
625 <PRE>: SQUARE ( n -- n**2 )\r
626 &nbsp;&nbsp;&nbsp; DUP&nbsp; *\r
627 ;\r
628 : TSQ&nbsp; ( n -- , test square )\r
629 &nbsp;&nbsp;&nbsp; ." Square of "&nbsp;&nbsp; DUP&nbsp;&nbsp; .\r
630 &nbsp;&nbsp;&nbsp; ." is "&nbsp;&nbsp; SQUARE&nbsp;&nbsp; .&nbsp;&nbsp; CR\r
631 ;</PRE>\r
632 </UL>\r
633 Even though this program should work, let's pretend it doesn't and try\r
634 to debug it.&nbsp; Enter:\r
635 <UL>7&nbsp; TRACE&nbsp; TSQ</UL>\r
636 You should see:\r
637 <UL>\r
638 <PRE>7 trace tsq\r
639 &lt;&lt;&nbsp; TSQ +0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;10:1> 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ||&nbsp; (.")&nbsp; Square of "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; >>&nbsp;&nbsp;&nbsp; ok</PRE>\r
640 </UL>\r
641 The "TSQ +0" means that you are about to execute code at an offset of "+0"\r
642 from the beginning of TSQ.&nbsp; The &lt;10:1> means that we are in base\r
643 10, and that there is 1 item on the stack, which is shown to be "7". The\r
644 (.") is the word that is about to be executed.&nbsp; (.") is the word that\r
645 is compiled when use use .".&nbsp; Now to single step, enter:\r
646 <UL>\r
647 <PRE>s</PRE>\r
648 </UL>\r
649 You should see:\r
650 <UL>\r
651 <PRE>Square of\r
652 &lt;&lt;&nbsp; TSQ +16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;10:1> 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ||&nbsp; DUP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; >>&nbsp;&nbsp;&nbsp; ok</PRE>\r
653 </UL>\r
654 \r
655 <PRE>The "Square os" was printed by (."). We can step multiple times using the "sm" command. Enter:</PRE>\r
656 \r
657 <UL>\r
658 <PRE>3 sm</PRE>\r
659 </UL>\r
660 You should see:\r
661 <UL>\r
662 <PRE>&lt;&lt;&nbsp; TSQ +20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;10:2> 7 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ||&nbsp; .&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; >> 7&nbsp;\r
663 &lt;&lt;&nbsp; TSQ +24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;10:1> 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ||&nbsp; (.")&nbsp; is "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; >> is&nbsp;\r
664 &lt;&lt;&nbsp; TSQ +32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;10:1> 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ||&nbsp; SQUARE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; >>&nbsp;&nbsp;&nbsp; ok</PRE>\r
665 </UL>\r
666 The "7" after the ">>" was printed by the . word. If we entered "s", we\r
667 would step over the SQUARE word. If we want to dive down into SQUARE, we\r
668 can enter:\r
669 <UL>\r
670 <PRE>sd</PRE>\r
671 </UL>\r
672 \r
673 <PRE>You should see:</PRE>\r
674 \r
675 <UL>\r
676 <PRE>&lt;&lt;&nbsp; SQUARE +0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;10:1> 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ||&nbsp;&nbsp;&nbsp; DUP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; >>&nbsp;&nbsp;&nbsp; ok</PRE>\r
677 </UL>\r
678 \r
679 <PRE>To step once in SQUARE, enter:</PRE>\r
680 \r
681 <UL>\r
682 <PRE>s</PRE>\r
683 </UL>\r
684 You should see:\r
685 <UL>\r
686 <PRE>&lt;&lt;&nbsp; SQUARE +4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;10:2> 7 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ||&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; >>&nbsp;&nbsp;&nbsp; ok</PRE>\r
687 </UL>\r
688 \r
689 <PRE>To go to the end of the current word, enter:</PRE>\r
690 \r
691 <UL>\r
692 <PRE>g</PRE>\r
693 </UL>\r
694 \r
695 <PRE>You should see:</PRE>\r
696 \r
697 <UL>\r
698 <PRE>&lt;&lt;&nbsp; SQUARE +8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;10:1> 49&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ||&nbsp;&nbsp;&nbsp; EXIT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; >>&nbsp;\r
699 &lt;&lt;&nbsp; TSQ +36&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;10:1> 49&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ||&nbsp; .&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; >>&nbsp;&nbsp;&nbsp; ok</PRE>\r
700 </UL>\r
701 EXIT is compiled at the end of every Forth word. For more information on\r
702 TRACE, enter TRACE.HELP:\r
703 <UL>\r
704 <PRE>TRACE&nbsp; ( i*x &lt;name> -- , setup trace for Forth word )\r
705 S&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( -- , step over )\r
706 SM&nbsp;&nbsp;&nbsp;&nbsp; ( many -- , step over many times )\r
707 SD&nbsp;&nbsp;&nbsp;&nbsp; ( -- , step down )\r
708 G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( -- , go to end of word )\r
709 GD&nbsp;&nbsp;&nbsp;&nbsp; ( n -- , go down N levels from current level,\r
710 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stop at end of this level )</PRE>\r
711 </UL>\r
712 \r
713 <H3>\r
714 <A NAME="Conditional Compilation [IF] [ELSE] [THEN]"></A>Conditional Compilation\r
715 [IF] [ELSE] [THEN]</H3>\r
716 PForth supports conditional compilation words similar to 'C''s #if, #else,\r
717 and #endif.\r
718 <DT>\r
719 [IF] ( flag -- , if true, skip to [ELSE] or [THEN] )</DT>\r
720 \r
721 <DT>\r
722 [ELSE] ( -- , skip to [THEN] )</DT>\r
723 \r
724 <DT>\r
725 [THEN] ( -- , noop, used to terminate [IF] and [ELSE] section )</DT>\r
726 \r
727 <BR>&nbsp;\r
728 <BR>For example:\r
729 <UL>\r
730 <PRE>TRUE constant USE_FRENCH\r
731 \r
732 USE_FRENCH&nbsp; [IF]\r
733 &nbsp; : WELCOME&nbsp; ." Bienvenue!" cr ;\r
734 [ELSE]\r
735 &nbsp; : WELCOME&nbsp; ." Welcome!" cr ;\r
736 [THEN]</PRE>\r
737 </UL>\r
738 Here is how to conditionally compile within a colon definition by using\r
739 [ and ].\r
740 <UL>\r
741 <PRE>: DOIT&nbsp; ( -- )\r
742 &nbsp;&nbsp;&nbsp; START.REACTOR\r
743 &nbsp;&nbsp;&nbsp; IF\r
744 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ USE_FRENCH [IF] ] ." Zut alors!"\r
745 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ [ELSE] ] ." Uh oh!"\r
746 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [THEN]\r
747 &nbsp;&nbsp;&nbsp; THEN cr\r
748 ;</PRE>\r
749 </UL>\r
750 \r
751 <H3>\r
752 <A NAME="Miscellaneous Handy Words"></A>Miscellaneous Handy Words</H3>\r
753 \r
754 <DT>\r
755 .HEX ( n -- , print N as hex number )</DT>\r
756 \r
757 <DT>\r
758 CHOOSE ( n -- rand , select random number between 0 and N )</DT>\r
759 \r
760 <DT>\r
761 MAP ( -- , print dictionary information )</DT>\r
762 \r
763 <H3>\r
764 <A NAME="Local Variables { foo --}"></A>Local Variables { foo --}</H3>\r
765 In a complicated Forth word it is sometimes hard to keep track of where\r
766 things are on the stack. If you find you are doing a lot of stack operations\r
767 like DUP SWAP ROT PICK etc. then you may want to use local variables. They\r
768 can greatly simplify your code. You can declare local variables for a word\r
769 using a syntax similar to the stack diagram. These variables will only\r
770 be accessible within that word. Thus they are "local" as opposed to "global"\r
771 like regular variables. Local variables are self-fetching. They automatically\r
772 put their values on the stack when you give their name. You don't need\r
773 to @ the contents. Local variables do not take up space in the dictionary.\r
774 They reside on the return stack where space is made for them as needed.\r
775 Words written with them can be reentrant and recursive.\r
776 \r
777 <P>Consider a word that calculates the difference of two squares, Here\r
778 are two ways of writing the same word.\r
779 <UL>\r
780 <PRE>: DIFF.SQUARES ( A B -- A*A-B*B )&nbsp;\r
781 &nbsp;&nbsp;&nbsp; DUP *&nbsp;\r
782 &nbsp;&nbsp;&nbsp; SWAP DUP *&nbsp;\r
783 &nbsp;&nbsp;&nbsp; SWAP -&nbsp;\r
784 ;&nbsp;\r
785 &nbsp; ( or )&nbsp;\r
786 : DIFF.SQUARES { A B -- A*A-B*B }&nbsp;\r
787 &nbsp;&nbsp;&nbsp; A A *&nbsp;\r
788 &nbsp;&nbsp;&nbsp; B B * -&nbsp;\r
789 ;&nbsp;\r
790 3 2 DIFF.SQUARES&nbsp; ( would return 5 )</PRE>\r
791 </UL>\r
792 In the second definition of DIFF.SQUARES the curly bracket '{' told the\r
793 compiler to start declaring local variables. Two locals were defined, A\r
794 and B. The names could be as long as regular Forth words if desired. The\r
795 "--" marked the end of the local variable list. When the word is executed,\r
796 the values will automatically be pulled from the stack and placed in the\r
797 local variables. When a local variable is executed it places its value\r
798 on the stack instead of its address. This is called self-fetching. Since\r
799 there is no address, you may wonder how you can store into a local variable.\r
800 There is a special operator for local variables that does a store. It looks\r
801 like -> and is pronounced "to".\r
802 \r
803 <P>Local variables need not be passed on the stack. You can declare a local\r
804 variable by placing it after a "vertical bar" ( | )character. These are\r
805 automatically set to zero when created. Here is a simple example that uses\r
806 -> and | in a word:\r
807 <UL>\r
808 <PRE>: SHOW2*&nbsp;&nbsp;\r
809 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { loc1 | unvar --&nbsp; , 1 regular, 1 uninitialized }\r
810 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOC1&nbsp; 2*&nbsp; ->&nbsp; UNVAR&nbsp;\r
811 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (set unver to 2*LOC1 )\r
812 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UNVAR&nbsp;&nbsp; .&nbsp;&nbsp; ( print UNVAR )\r
813 ;\r
814 3 SHOW2*&nbsp;&nbsp; ( pass only 1 parameter, prints 6 )</PRE>\r
815 </UL>\r
816 Since local variable often used as counters or accumulators, we have a\r
817 special operator for adding to a local variable It is +-> which is pronounced\r
818 "plus to". These next two lines are functionally equivalent but the second\r
819 line is faster and smaller:\r
820 <UL>\r
821 <PRE>ACCUM&nbsp;&nbsp; 10 +&nbsp;&nbsp; -> ACCUM\r
822 10 +-> ACCUM</PRE>\r
823 </UL>\r
824 If you name a local variable the same as a Forth word in the dictionary,\r
825 eg. INDEX or COUNT, you will be given a warning message. The local variable\r
826 will still work but one could easily get confused so we warn you about\r
827 this. Other errors that can occur include, missing a closing '}', missing\r
828 '--', or having too many local variables.\r
829 <H3>\r
830 <A NAME="'C' like Structures. :STRUCT"></A>'C' like Structures. :STRUCT</H3>\r
831 You can define 'C' like data structures in pForth using :STRUCT. For example:\r
832 <UL>\r
833 <PRE>:STRUCT&nbsp; SONG\r
834 &nbsp;&nbsp;&nbsp; LONG&nbsp;&nbsp;&nbsp;&nbsp; SONG_NUMNOTES&nbsp; \ define 32 bit structure member named SONG_NUMNOTES\r
835 &nbsp;&nbsp;&nbsp; SHORT&nbsp;&nbsp;&nbsp; SONG_SECONDS&nbsp;&nbsp; \ define 16 bit structure member\r
836 &nbsp;&nbsp;&nbsp; BYTE&nbsp;&nbsp;&nbsp;&nbsp; SONG_QUALITY&nbsp;&nbsp; \ define 8 bit member\r
837 &nbsp;&nbsp;&nbsp; LONG&nbsp;&nbsp;&nbsp;&nbsp; SONG_NUMBYTES&nbsp; \ auto aligns after SHORT or BYTE\r
838 &nbsp;&nbsp;&nbsp; RPTR&nbsp;&nbsp;&nbsp;&nbsp; SONG_DATA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \ relocatable pointer to data\r
839 ;STRUCT</PRE>\r
840 \r
841 <PRE>SONG&nbsp; HAPPY&nbsp;&nbsp; \ define a song structure called happy</PRE>\r
842 \r
843 <PRE>400&nbsp; HAPPY&nbsp; S!&nbsp; SONG_NUMNOTES&nbsp; \ set number of notes to 400\r
844 17&nbsp;&nbsp; HAPPY&nbsp; S!&nbsp; SONG_SECONDS&nbsp;&nbsp; \ S! works with all size members</PRE>\r
845 \r
846 <PRE>CREATE&nbsp; SONG-DATA&nbsp; 23 , 17 , 19 , 27 ,\r
847 SONG-DATA&nbsp; HAPPY S! SONG_DATA&nbsp; \ store pointer in relocatable form</PRE>\r
848 \r
849 <PRE>HAPPY&nbsp; DST&nbsp; SONG&nbsp;&nbsp;&nbsp; \ dump HAPPY as a SONG structure</PRE>\r
850 \r
851 <PRE>HAPPY&nbsp;&nbsp; S@&nbsp; SONG_NUMNOTES .&nbsp; \ fetch numnotes and print</PRE>\r
852 </UL>\r
853 See the file "c_struct.fth" for more information.\r
854 <H3>\r
855 <A NAME="Vectorred Execution - DEFER"></A>Vectorred Execution - DEFER</H3>\r
856 Using DEFER for vectored words. In Forth and other languages you can save\r
857 the address of a function in a variable. You can later fetch from that\r
858 variable and execute the function it points to.This is called vectored\r
859 execution. PForth provides a tool that simplifies this process. You can\r
860 define a word using DEFER. This word will contain the execution token of\r
861 another Forth function. When you execute the deferred word, it will execute\r
862 the function it points to. By changing the contents of this deferred word,\r
863 you can change what it will do. There are several words that support this\r
864 process.\r
865 <DL>\r
866 <DT>\r
867 DEFER ( &lt;name> -- , define a deferred word )</DT>\r
868 \r
869 <DT>\r
870 IS ( CFA &lt;name> -- , set the function for a deferred word )</DT>\r
871 \r
872 <DT>\r
873 WHAT'S ( &lt;name> -- CFA , return the CFA set by IS )</DT>\r
874 </DL>\r
875 \r
876 <DD>\r
877 Simple way to see the name of what's in a deferred word:</DD>\r
878 \r
879 <UL>\r
880 <UL>\r
881 <PRE>WHAT'S EMIT >NAME ID.</PRE>\r
882 </UL>\r
883 </UL>\r
884 \r
885 <DD>\r
886 should print name of current word that's in EMIT.</DD>\r
887 \r
888 <BR>&nbsp;\r
889 <BR>Here is an example that uses a deferred word.\r
890 <UL>\r
891 <PRE>DEFER PRINTIT\r
892 ' . IS PRINTIT&nbsp;&nbsp; ( make PRINTIT use . )\r
893 8 3 + PRINTIT\r
894 \r
895 : COUNTUP&nbsp; ( -- , call deferred word )\r
896 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ." Hit RETURN to stop!" CR\r
897 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 ( first value )\r
898 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BEGIN 1+ DUP PRINTIT CR\r
899 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ?TERMINAL\r
900 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UNTIL\r
901 ;\r
902 COUNTUP&nbsp; ( uses simple . )\r
903 \r
904 : FANCY.PRINT&nbsp; ( N -- , print in DECIMAL and HEX)\r
905 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DUP ." DECIMAL = " .\r
906 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ." , HEX = " .HEX\r
907 ;\r
908 ' FANCY.PRINT&nbsp; IS PRINTIT&nbsp; ( change printit )\r
909 WHAT'S PRINTIT >NAME ID. ( shows use of WHAT'S )\r
910 8 3 + PRINTIT\r
911 COUNTUP&nbsp; ( notice that it now uses FANCY.PRINT )</PRE>\r
912 </UL>\r
913 Many words in the system have been defined using DEFER which means that\r
914 we can change how they work without recompiling the entire system. Here\r
915 is a partial list of those words\r
916 <UL>\r
917 <PRE>ABORT EMIT NUMBER?</PRE>\r
918 </UL>\r
919 \r
920 <H4>\r
921 Potential Problems with Defer</H4>\r
922 Deferred words are very handy to use, however, you must be careful with\r
923 them. One problem that can occur is if you initialize a deferred system\r
924 more than once. In the below example, suppose we called STUTTER twice.\r
925 The first time we would save the original EMIT vector in OLD-EMIT and put\r
926 in a new one. The second time we called it we would take our new function\r
927 from EMIT and save it in OLD-EMIT overwriting what we had saved previously.\r
928 Thus we would lose the original vector for EMIT . You can avoid this if\r
929 you check to see whether you have already done the defer. Here's an example\r
930 of this technique.\r
931 <UL>\r
932 <PRE>DEFER OLD-EMIT\r
933 ' QUIT&nbsp; IS OLD-EMIT&nbsp; ( set to known value )\r
934 : EEMMIITT&nbsp; ( char --- , our fun EMIT )\r
935 &nbsp;&nbsp;&nbsp; DUP OLD-EMIT OLD-EMIT\r
936 ;&nbsp;\r
937 : STUTTER&nbsp;&nbsp; ( --- )\r
938 &nbsp;&nbsp;&nbsp; WHAT'S OLD-EMIT&nbsp; 'C QUIT =&nbsp; ( still the same? )\r
939 &nbsp;&nbsp;&nbsp; IF&nbsp; ( this must be the first time )\r
940 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHAT'S EMIT&nbsp; ( get the current value of EMIT )&nbsp;&nbsp;\r
941 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IS OLD-EMIT&nbsp; ( save this value in OLD-EMIT )&nbsp;&nbsp;\r
942 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'C EEMMIITT IS EMIT\r
943 &nbsp;&nbsp;&nbsp; ELSE ."&nbsp; Attempt to STUTTER twice!" CR\r
944 &nbsp;&nbsp;&nbsp; THEN\r
945 ;&nbsp;\r
946 : STOP-IT!&nbsp; ( --- )\r
947 &nbsp;&nbsp;&nbsp; WHAT'S OLD-EMIT ' QUIT =\r
948 &nbsp;&nbsp;&nbsp; IF&nbsp; ." STUTTER not installed!" CR\r
949 &nbsp;&nbsp;&nbsp; ELSE&nbsp; WHAT'S OLD-EMIT IS EMIT\r
950 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'C QUIT IS OLD-EMIT&nbsp;&nbsp;\r
951 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( reset to show termination )\r
952 &nbsp;&nbsp;&nbsp; THEN\r
953 ;</PRE>\r
954 </UL>\r
955 In the above example, we could call STUTTER or STOP-IT! as many times as\r
956 we want and still be safe.\r
957 \r
958 <P>Suppose you forget your word that EMIT now calls. As you compile new\r
959 code you will overwrite the code that EMIT calls and it will crash miserably.\r
960 You must reset any deferred words that call your code before you FORGET\r
961 your code. The easiest way to do this is to use the word IF.FORGOTTEN to\r
962 specify a cleanup word to be called if you ever FORGET the code in question.\r
963 In the above example using EMIT , we could have said:\r
964 <UL>\r
965 <PRE>IF.FORGOTTEN STOP-IT!</PRE>\r
966 </UL>\r
967 \r
968 <H3>\r
969 <A NAME="Floating Point"></A>Floating Point</H3>\r
970 PForth supports the FLOAT word set and much of the FLOATEXT word set as\r
971 a compile time option.&nbsp; You can select single or double precision\r
972 as the default by changing the typedef of PF_FLOAT.\r
973 <DL>PForth has several options for floating point output.\r
974 <DT>\r
975 FS. ( r -f- , prints in scientific/exponential format )</DT>\r
976 \r
977 <DT>\r
978 FE. ( r -f- , prints in engineering format, exponent if multiple of 3&nbsp;\r
979 )</DT>\r
980 \r
981 <DT>\r
982 FG. ( r -f- , prints in normal or exponential format depending on size\r
983 )</DT>\r
984 \r
985 <DT>\r
986 F. ( r -f- , as defined by the standard )</DT>\r
987 \r
988 <DT>\r
989 Here is an example of output from each word for a number ranging from large\r
990 to very small.</DT>\r
991 \r
992 <DL>\r
993 <PRE>&nbsp;&nbsp;&nbsp;&nbsp; FS.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FE.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FG.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F.\r
994 1.234000e+12&nbsp;&nbsp;&nbsp;&nbsp; 1.234000e+12&nbsp;&nbsp;&nbsp;&nbsp; 1.234e+12&nbsp;&nbsp;&nbsp;&nbsp; 1234000000000.&nbsp;\r
995 1.234000e+11&nbsp;&nbsp;&nbsp;&nbsp; 123.4000e+09&nbsp;&nbsp;&nbsp;&nbsp; 1.234e+11&nbsp;&nbsp;&nbsp;&nbsp; 123400000000.&nbsp;\r
996 1.234000e+10&nbsp;&nbsp;&nbsp;&nbsp; 12.34000e+09&nbsp;&nbsp;&nbsp;&nbsp; 1.234e+10&nbsp;&nbsp;&nbsp;&nbsp; 12340000000.&nbsp;\r
997 1.234000e+09&nbsp;&nbsp;&nbsp;&nbsp; 1.234000e+09&nbsp;&nbsp;&nbsp;&nbsp; 1.234e+09&nbsp;&nbsp;&nbsp;&nbsp; 1234000000.&nbsp;\r
998 1.234000e+08&nbsp;&nbsp;&nbsp;&nbsp; 123.4000e+06&nbsp;&nbsp;&nbsp;&nbsp; 1.234e+08&nbsp;&nbsp;&nbsp;&nbsp; 123400000.&nbsp;\r
999 1.234000e+07&nbsp;&nbsp;&nbsp;&nbsp; 12.34000e+06&nbsp;&nbsp;&nbsp;&nbsp; 1.234e+07&nbsp;&nbsp;&nbsp;&nbsp; 12340000.&nbsp;\r
1000 1.234000e+06&nbsp;&nbsp;&nbsp;&nbsp; 1.234000e+06&nbsp;&nbsp;&nbsp;&nbsp; 1234000.&nbsp;&nbsp;&nbsp;&nbsp; 1234000.&nbsp;\r
1001 1.234000e+05&nbsp;&nbsp;&nbsp;&nbsp; 123.4000e+03&nbsp;&nbsp;&nbsp;&nbsp; 123400.&nbsp;&nbsp;&nbsp;&nbsp; 123400.0&nbsp;\r
1002 1.234000e+04&nbsp;&nbsp;&nbsp;&nbsp; 12.34000e+03&nbsp;&nbsp;&nbsp;&nbsp; 12340.&nbsp;&nbsp;&nbsp;&nbsp; 12340.00&nbsp;\r
1003 1.234000e+03&nbsp;&nbsp;&nbsp;&nbsp; 1.234000e+03&nbsp;&nbsp;&nbsp;&nbsp; 1234.&nbsp;&nbsp;&nbsp;&nbsp; 1234.000&nbsp;\r
1004 1.234000e+02&nbsp;&nbsp;&nbsp;&nbsp; 123.4000e+00&nbsp;&nbsp;&nbsp;&nbsp; 123.4&nbsp;&nbsp;&nbsp;&nbsp; 123.4000&nbsp;\r
1005 1.234000e+01&nbsp;&nbsp;&nbsp;&nbsp; 12.34000e+00&nbsp;&nbsp;&nbsp;&nbsp; 12.34&nbsp;&nbsp;&nbsp;&nbsp; 12.34000&nbsp;\r
1006 1.234000e+00&nbsp;&nbsp;&nbsp;&nbsp; 1.234000e+00&nbsp;&nbsp;&nbsp;&nbsp; 1.234&nbsp;&nbsp;&nbsp;&nbsp; 1.234000&nbsp;\r
1007 1.234000e-01&nbsp;&nbsp;&nbsp;&nbsp; 123.4000e-03&nbsp;&nbsp;&nbsp;&nbsp; 0.1234&nbsp;&nbsp;&nbsp;&nbsp; 0.1234000&nbsp;\r
1008 1.234000e-02&nbsp;&nbsp;&nbsp;&nbsp; 12.34000e-03&nbsp;&nbsp;&nbsp;&nbsp; 0.01234&nbsp;&nbsp;&nbsp;&nbsp; 0.0123400&nbsp;\r
1009 1.234000e-03&nbsp;&nbsp;&nbsp;&nbsp; 1.234000e-03&nbsp;&nbsp;&nbsp;&nbsp; 0.001234&nbsp;&nbsp;&nbsp;&nbsp; 0.0012340&nbsp;\r
1010 1.234000e-04&nbsp;&nbsp;&nbsp;&nbsp; 123.4000e-06&nbsp;&nbsp;&nbsp;&nbsp; 0.0001234&nbsp;&nbsp;&nbsp;&nbsp; 0.0001234&nbsp;\r
1011 1.234000e-05&nbsp;&nbsp;&nbsp;&nbsp; 12.34000e-06&nbsp;&nbsp;&nbsp;&nbsp; 1.234e-05&nbsp;&nbsp;&nbsp;&nbsp; 0.0000123&nbsp;\r
1012 1.234000e-06&nbsp;&nbsp;&nbsp;&nbsp; 1.234000e-06&nbsp;&nbsp;&nbsp;&nbsp; 1.234e-06&nbsp;&nbsp;&nbsp;&nbsp; 0.0000012&nbsp;\r
1013 1.234000e-07&nbsp;&nbsp;&nbsp;&nbsp; 123.4000e-09&nbsp;&nbsp;&nbsp;&nbsp; 1.234e-07&nbsp;&nbsp;&nbsp;&nbsp; 0.0000001&nbsp;\r
1014 1.234000e-08&nbsp;&nbsp;&nbsp;&nbsp; 12.34000e-09&nbsp;&nbsp;&nbsp;&nbsp; 1.234e-08&nbsp;&nbsp;&nbsp;&nbsp; 0.0000000&nbsp;\r
1015 1.234000e-09&nbsp;&nbsp;&nbsp;&nbsp; 1.234000e-09&nbsp;&nbsp;&nbsp;&nbsp; 1.234e-09&nbsp;&nbsp;&nbsp;&nbsp; 0.0000000&nbsp;\r
1016 1.234000e-10&nbsp;&nbsp;&nbsp;&nbsp; 123.4000e-12&nbsp;&nbsp;&nbsp;&nbsp; 1.234e-10&nbsp;&nbsp;&nbsp;&nbsp; 0.0000000&nbsp;\r
1017 1.234000e-11&nbsp;&nbsp;&nbsp;&nbsp; 12.34000e-12&nbsp;&nbsp;&nbsp;&nbsp; 1.234e-11&nbsp;&nbsp;&nbsp;&nbsp; 0.0000000\r
1018 \r
1019 1.234568e+12&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e+12&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e+12&nbsp;&nbsp;&nbsp;&nbsp; 1234567890000.&nbsp;\r
1020 1.234568e+11&nbsp;&nbsp;&nbsp;&nbsp; 123.4568e+09&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e+11&nbsp;&nbsp;&nbsp;&nbsp; 123456789000.&nbsp;\r
1021 1.234568e+10&nbsp;&nbsp;&nbsp;&nbsp; 12.34568e+09&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e+10&nbsp;&nbsp;&nbsp;&nbsp; 12345678900.&nbsp;\r
1022 1.234568e+09&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e+09&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e+09&nbsp;&nbsp;&nbsp;&nbsp; 1234567890.&nbsp;\r
1023 1.234568e+08&nbsp;&nbsp;&nbsp;&nbsp; 123.4568e+06&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e+08&nbsp;&nbsp;&nbsp;&nbsp; 123456789.&nbsp;\r
1024 1.234568e+07&nbsp;&nbsp;&nbsp;&nbsp; 12.34568e+06&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e+07&nbsp;&nbsp;&nbsp;&nbsp; 12345679.&nbsp;\r
1025 1.234568e+06&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e+06&nbsp;&nbsp;&nbsp;&nbsp; 1234568.&nbsp;&nbsp;&nbsp;&nbsp; 1234568.&nbsp;\r
1026 1.234568e+05&nbsp;&nbsp;&nbsp;&nbsp; 123.4568e+03&nbsp;&nbsp;&nbsp;&nbsp; 123456.8&nbsp;&nbsp;&nbsp;&nbsp; 123456.8&nbsp;\r
1027 1.234568e+04&nbsp;&nbsp;&nbsp;&nbsp; 12.34568e+03&nbsp;&nbsp;&nbsp;&nbsp; 12345.68&nbsp;&nbsp;&nbsp;&nbsp; 12345.68&nbsp;\r
1028 1.234568e+03&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e+03&nbsp;&nbsp;&nbsp;&nbsp; 1234.568&nbsp;&nbsp;&nbsp;&nbsp; 1234.568&nbsp;\r
1029 1.234568e+02&nbsp;&nbsp;&nbsp;&nbsp; 123.4568e+00&nbsp;&nbsp;&nbsp;&nbsp; 123.4568&nbsp;&nbsp;&nbsp;&nbsp; 123.4568&nbsp;\r
1030 1.234568e+01&nbsp;&nbsp;&nbsp;&nbsp; 12.34568e+00&nbsp;&nbsp;&nbsp;&nbsp; 12.34568&nbsp;&nbsp;&nbsp;&nbsp; 12.34568&nbsp;\r
1031 1.234568e+00&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e+00&nbsp;&nbsp;&nbsp;&nbsp; 1.234568&nbsp;&nbsp;&nbsp;&nbsp; 1.234568&nbsp;\r
1032 1.234568e-01&nbsp;&nbsp;&nbsp;&nbsp; 123.4568e-03&nbsp;&nbsp;&nbsp;&nbsp; 0.1234568&nbsp;&nbsp;&nbsp;&nbsp; 0.1234568&nbsp;\r
1033 1.234568e-02&nbsp;&nbsp;&nbsp;&nbsp; 12.34568e-03&nbsp;&nbsp;&nbsp;&nbsp; 0.01234568&nbsp;&nbsp;&nbsp;&nbsp; 0.0123456&nbsp;\r
1034 1.234568e-03&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e-03&nbsp;&nbsp;&nbsp;&nbsp; 0.001234568&nbsp;&nbsp;&nbsp;&nbsp; 0.0012345&nbsp;\r
1035 1.234568e-04&nbsp;&nbsp;&nbsp;&nbsp; 123.4568e-06&nbsp;&nbsp;&nbsp;&nbsp; 0.0001234568&nbsp;&nbsp;&nbsp;&nbsp; 0.0001234&nbsp;\r
1036 1.234568e-05&nbsp;&nbsp;&nbsp;&nbsp; 12.34568e-06&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e-05&nbsp;&nbsp;&nbsp;&nbsp; 0.0000123&nbsp;\r
1037 1.234568e-06&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e-06&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e-06&nbsp;&nbsp;&nbsp;&nbsp; 0.0000012&nbsp;\r
1038 1.234568e-07&nbsp;&nbsp;&nbsp;&nbsp; 123.4568e-09&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e-07&nbsp;&nbsp;&nbsp;&nbsp; 0.0000001&nbsp;\r
1039 1.234568e-08&nbsp;&nbsp;&nbsp;&nbsp; 12.34568e-09&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e-08&nbsp;&nbsp;&nbsp;&nbsp; 0.0000000&nbsp;\r
1040 1.234568e-09&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e-09&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e-09&nbsp;&nbsp;&nbsp;&nbsp; 0.0000000&nbsp;\r
1041 1.234568e-10&nbsp;&nbsp;&nbsp;&nbsp; 123.4568e-12&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e-10&nbsp;&nbsp;&nbsp;&nbsp; 0.0000000&nbsp;\r
1042 1.234568e-11&nbsp;&nbsp;&nbsp;&nbsp; 12.34568e-12&nbsp;&nbsp;&nbsp;&nbsp; 1.234568e-11&nbsp;&nbsp;&nbsp;&nbsp; 0.0000000</PRE>\r
1043 </DL>\r
1044 </DL>\r
1045 \r
1046 <PRE>\r
1047 <HR WIDTH="100%"></PRE>\r
1048 \r
1049 <H2>\r
1050 <A NAME="pForth Design"></A>pForth Design</H2>\r
1051 \r
1052 <H3>\r
1053 <A NAME="'C' kernel"></A>'C' kernel</H3>\r
1054 The pForth kernel is written in 'C' for portability. The inner interpreter\r
1055 is implemented in the function ExecuteToken() which is in pf_inner.c.\r
1056 <UL>\r
1057 <PRE>void pfExecuteToken( ExecToken XT );</PRE>\r
1058 </UL>\r
1059 It is passed an execution token the same as EXECUTE would accept. It handles\r
1060 threading of secondaries and also has a large switch() case statement to\r
1061 interpret primitives. It is in one huge routine to take advantage of register\r
1062 variables, and to reduce calling overhead. Hopefully, your compiler will\r
1063 optimise the switch() statement into a jump table so it will run fast.\r
1064 <H3>\r
1065 <A NAME="Dictionary Structures"></A>Dictionary Structures</H3>\r
1066 This Forth supports multiple dictionaries. Each dictionary consists of\r
1067 a header segment and a seperate code segment. The header segment contains\r
1068 link fields and names. The code segment contains tokens and data. The headers,\r
1069 as well as some entire dictionaries such as the compiler support words,\r
1070 can be discarded when creating a stand-alone app.\r
1071 \r
1072 <P>[NOT IMPLEMENTED] Dictionaries can be split so that the compile time\r
1073 words can be placed above the main dictionary. Thus they can use the same\r
1074 relative addressing but be discarded when turnkeying.\r
1075 \r
1076 <P>Execution tokens are either an index of a primitive ( n &lt; NUM_PRIMITIVES),\r
1077 or the offset of a secondary in the code segment. ( n >= NUM_PRIMITIVES\r
1078 )\r
1079 \r
1080 <P>The NAME HEADER portion of the dictionary contains a structure for each\r
1081 named word in the dictionary. It contains the following fields:\r
1082 <UL>\r
1083 <PRE>bytes 4 Link Field relative address of previous name header\r
1084 4 Code Pointer relative address of corresponding code\r
1085 n Name Field name as counted string Headers are quad byte aligned.</PRE>\r
1086 </UL>\r
1087 The CODE portion of the dictionary consists of the following structures:\r
1088 <H4>\r
1089 Primitive</H4>\r
1090 No Forth code. 'C' code in "pf_inner.c".\r
1091 <H4>\r
1092 Secondary</H4>\r
1093 \r
1094 <UL>\r
1095 <PRE>4*n Parameter Field execution tokens\r
1096 4 ID_NEXT = 0 terminates secondary</PRE>\r
1097 </UL>\r
1098 \r
1099 <H4>\r
1100 CREATE DOES></H4>\r
1101 \r
1102 <UL>\r
1103 <PRE>4 ID_CREATE_P token\r
1104 4 Token for optional DOES> code, OR ID_NEXT = 0\r
1105 4 ID_NEXT = 0\r
1106 n Body = arbitrary data</PRE>\r
1107 </UL>\r
1108 \r
1109 <H4>\r
1110 Deferred Word</H4>\r
1111 \r
1112 <UL>\r
1113 <PRE>4 ID_DEFER_P same action as ID_NOOP, identifies deferred words\r
1114 4 Execution Token of word to execute.\r
1115 4 ID_NEXT = 0</PRE>\r
1116 </UL>\r
1117 \r
1118 <H4>\r
1119 Call to custom 'C' function.</H4>\r
1120 \r
1121 <UL>\r
1122 <PRE>4 ID_CALL_C\r
1123 4 Pack C Call Info Bits</PRE>\r
1124 \r
1125 <UL>\r
1126 <PRE>0-15 = Function Index Bits\r
1127 16-23 = FunctionTable Index (Unused) Bits\r
1128 24-30 = NumParams Bit\r
1129 31 = 1 if function returns value</PRE>\r
1130 </UL>\r
1131 \r
1132 <PRE>4 ID_NEXT = 0</PRE>\r
1133 </UL>\r
1134 \r
1135 <HR WIDTH="100%">\r
1136 <H2>\r
1137 <A NAME="Custom Compilation of pForth"></A>Custom Compilation of pForth</H2>\r
1138 \r
1139 <H3>\r
1140 <A NAME="Compiler Options"></A>Compiler Options</H3>\r
1141 There are several versions of PForth that can be built. By default, the\r
1142 full kernel will be built. For custom builds, define the following options\r
1143 in the Makefile before compiling the 'C' code:\r
1144 \r
1145 <P>PF_NO_INIT\r
1146 <UL>Don't compile the code used to initially build the dictionary. This\r
1147 can be used to save space if you already have a prebuilt dictionary.</UL>\r
1148 PF_NO_SHELL\r
1149 <UL>Don't compile the outer interpreter and Forth compiler. This can be\r
1150 used with Cloned dictionaries.</UL>\r
1151 PF_NO_MALLOC\r
1152 <UL>Replace malloc() and free() function with pForth's own version. See\r
1153 pf_mem.c for more details.</UL>\r
1154 PF_USER_MALLOC='"filename.h"'\r
1155 <UL>Replace malloc() and free() function with users custom version. See\r
1156 pf_mem.h for details.</UL>\r
1157 PF_MEM_POOL_SIZE=numbytes\r
1158 <UL>Size of array in bytes used by pForth custom allocator.</UL>\r
1159 PF_NO_GLOBAL_INIT\r
1160 <UL>Define this if you want pForth to not rely on initialization of global\r
1161 variables by the loader. This may be required for some embedded systems\r
1162 that may not have a fully functioning loader.&nbsp; Take a look in "pfcustom.c"\r
1163 for an example of its use.</UL>\r
1164 PF_USER_INC1='"filename.h"'\r
1165 <UL>File to include BEFORE other include files. Generally set to host dependent\r
1166 files such as "pf_mac.h".</UL>\r
1167 PF_USER_INC2='"filename.h"'\r
1168 <UL>File to include AFTER other include files. Generally used to #undef\r
1169 and re#define symbols. See "pf_win32.h" for an example.</UL>\r
1170 PF_NO_CLIB\r
1171 <UL>Replace 'C' lib calls like toupper and memcpy with pForth's own version.\r
1172 This is useful for embedded systems.</UL>\r
1173 PF_USER_CLIB='"filename.h"'\r
1174 <UL>Rreplace 'C' lib calls like toupper and memcpy with users custom version.\r
1175 See pf_clib.h for details.</UL>\r
1176 PF_NO_FILEIO\r
1177 <UL>System does not support standard file I/O so stub it out. Setting this\r
1178 flag will automatically set PF_STATIC_DIC.</UL>\r
1179 PF_USER_CHARIO='"filename.h"'\r
1180 <UL>Replace stdio terminal calls like getchar() and putchar() with users\r
1181 custom version. See pf_io.h for details.</UL>\r
1182 PF_USER_FILEIO='"filename.h"'\r
1183 <UL>Replace stdio file calls like fopen and fread with users custom version.\r
1184 See pf_io.h for details.</UL>\r
1185 PF_USER_FLOAT='"filename.h"'\r
1186 <UL>Replace floating point math calls like sin and pow with users custom\r
1187 version. Also defines PF_FLOAT.</UL>\r
1188 PF_USER_INIT=MyInit()\r
1189 <UL>Call a user defined initialization function that returns a negative\r
1190 error code if it fails.</UL>\r
1191 PF_USER_TERM=MyTerm()\r
1192 <UL>Call a user defined void termination function.</UL>\r
1193 PF_STATIC_DIC\r
1194 <UL>Compile in static dictionary instead of loading dictionary. from file.\r
1195 Use "utils/savedicd.fth" to save a dictionary as 'C' source code in a file\r
1196 called "pfdicdat.h".</UL>\r
1197 PF_SUPPORT_FP\r
1198 <UL>Compile ANSI floating point support.</UL>\r
1199 \r
1200 <H3>\r
1201 <A NAME="Building pForth on Supported Hosts"></A>Building pForth on Supported\r
1202 Hosts</H3>\r
1203 To build on UNIX, do nothing, system will default to "pf_unix.h".\r
1204 \r
1205 <P>To build on Macintosh:\r
1206 <UL>\r
1207 <PRE>-DPF_USER_INC1='"pf_mac.h"'</PRE>\r
1208 </UL>\r
1209 To build on PCs:\r
1210 <UL>\r
1211 <PRE>-DPF_USER_INC2='"pf_win32.h"'</PRE>\r
1212 </UL>\r
1213 To build a system that only runs turnkey or cloned binaries:\r
1214 <UL>\r
1215 <PRE>-DPF_NO_INIT -DPF_NO_SHELL</PRE>\r
1216 </UL>\r
1217 \r
1218 <H3>\r
1219 <A NAME="Compiling for Embedded Systems"></A>Compiling for Embedded Systems</H3>\r
1220 You may want to create a version of pForth that can be run on a small system\r
1221 that does not support file I/O. This is useful when bringing up new computer\r
1222 systems. On UNIX systems, you can use the supplied gmake target. Simply\r
1223 enter:\r
1224 <UL>\r
1225 <PRE>gmake pfemb</PRE>\r
1226 </UL>\r
1227 For other systems, here are the steps to create an embedded pForth.\r
1228 <OL>\r
1229 <LI>\r
1230 Determine whether your target system has a different endian-ness than your\r
1231 host system.&nbsp; If the address of a long word is the address of the\r
1232 most significant byte, then it is "big endian". Examples of big endian\r
1233 processors are Sparc, Motorola 680x0 and PowerPC60x.&nbsp; If the address\r
1234 of a long word is the address of the lest significant byte, then it is\r
1235 "Little Endian". Examples of little endian processors are Intel 8088 and\r
1236 derivatives such as the Intel Pentium.</LI>\r
1237 \r
1238 <LI>\r
1239 If your target system has a different endian-ness than your host system,\r
1240 then you must compile a version of pForth for your host that matches the\r
1241 target.&nbsp; Rebuild pForth with either PF_BIG_ENDIAN_DIC or PF_LITTLE_ENDIAN_DIC\r
1242 defined.&nbsp; You will need to rebuild pforth.dic as well as the executable\r
1243 Forth.&nbsp; If you do not specify one of these variables, then the dictionary\r
1244 will match the native endian-ness of the processor (and run faster as a\r
1245 result).</LI>\r
1246 \r
1247 <LI>\r
1248 Execute pForth. Notice the message regarding the endian-ness of the dictionary.</LI>\r
1249 \r
1250 <LI>\r
1251 Compile your custom Forth words on the host development system.</LI>\r
1252 \r
1253 <LI>\r
1254 Compile the pForth utulity "utils/savedicd.fth".</LI>\r
1255 \r
1256 <LI>\r
1257 Enter in pForth: SDAD</LI>\r
1258 \r
1259 <LI>\r
1260 SDAD will generate a file called "pfdicdat.h" that contains your dictionary\r
1261 in source code form.</LI>\r
1262 \r
1263 <LI>\r
1264 Rewrite the character primitives sdTerminalOut(), sdTerminalIn() and sdTerminalFlush()\r
1265 defined in pf_io.h to use your new computers communications port.</LI>\r
1266 \r
1267 <LI>\r
1268 Write a "user_chario.h" file based on the API defined in "pf_io.h".</LI>\r
1269 \r
1270 <LI>\r
1271 Compile a new version of pForth for your target machine with the following\r
1272 options:</LI>\r
1273 \r
1274 <OL>\r
1275 <PRE>-DPF_NO_INIT -DPF_NO_MALLOC -DPF_NO_FILEIO \\r
1276 -DPF_USER_CHARIO="user_chario.h" \\r
1277 -DPF_NO_CLIB -DPF_STATIC_DIC</PRE>\r
1278 </OL>\r
1279 \r
1280 <LI>\r
1281 The file "pfdicdat.h" will be compiled into this executable and your dictionary\r
1282 will thus be included in the pForth executable as a static array.</LI>\r
1283 \r
1284 <LI>\r
1285 Burn a ROM with your new pForth and run it on your target machine.</LI>\r
1286 \r
1287 <LI>\r
1288 If you compiled a version of pForth with different endian-ness than your\r
1289 host system, do not use it for daily operation because it will be much\r
1290 slower than a native version.</LI>\r
1291 </OL>\r
1292 \r
1293 <H3>\r
1294 <A NAME="Linking with Custom 'C' Functions"></A>Linking with Custom 'C'\r
1295 Functions</H3>\r
1296 You can call the pForth interpreter as an embedded tool in a 'C' application.\r
1297 For an example of this, see the file pf_main.c. This application does nothing\r
1298 but load the dictionary and call the pForth interpreter.\r
1299 \r
1300 <P>You can call 'C' from pForth by adding your own custom 'C' functions\r
1301 to a dispatch table, and then adding Forth words to the dictionary that\r
1302 call those functions. See the file "pfcustom.c" for more information.\r
1303 <H3>\r
1304 <A NAME="Testing your Compiled pForth"></A>Testing your Compiled pForth</H3>\r
1305 Once you have compiled pForth, you can test it using the small verification\r
1306 suite we provide.&nbsp; The first test you should run was written by John\r
1307 Hayes at John Hopkins University.&nbsp; Enter:\r
1308 <UL>\r
1309 <PRE>pforth\r
1310 include tester.fth\r
1311 include coretest.fth\r
1312 bye</PRE>\r
1313 </UL>\r
1314 The output will be self explanatory.&nbsp; There are also a number of tests\r
1315 that I have added that print the number of successes and failures. Enter:\r
1316 <UL>\r
1317 <PRE>pforth t_corex.fth\r
1318 pforth t_locals.fth\r
1319 pforth t_strings.fth\r
1320 pforth t_floats.ft</PRE>\r
1321 </UL>\r
1322 Note that t_corex.fth reveals an expected error because SAVE-INPUT is not\r
1323 fully implemented. (FIXME)\r
1324 <BR>\r
1325 <HR WIDTH="100%">\r
1326 <BR>PForth source code is freely available.&nbsp; The author is available\r
1327 for customization of pForth, porting to new platforms, or developing pForth\r
1328 applications on a contractual basis.&nbsp; If interested, contact&nbsp;\r
1329 Phil Burk at <A HREF="mailto:philburk@softsynth.com">philburk@softsynth.com</A>\r
1330 \r
1331 <P>Back to <A HREF="pforth.html">pForth Home Page</A>\r
1332 </BODY>\r
1333 </HTML>\r