Deleted Added
full compact
ficl.h (77443) ficl.h (94290)
1/*******************************************************************
2** f i c l . h
3** Forth Inspired Command Language
4** Author: John Sadler (john_sadler@alum.mit.edu)
5** Created: 19 July 1997
1/*******************************************************************
2** f i c l . h
3** Forth Inspired Command Language
4** Author: John Sadler (john_sadler@alum.mit.edu)
5** Created: 19 July 1997
6** $Id: ficl.h,v 1.11 2001-04-26 21:41:48-07 jsadler Exp jsadler $
6** Dedicated to RHS, in loving memory
7** $Id: ficl.h,v 1.18 2001/12/05 07:21:34 jsadler Exp $
7*******************************************************************/
8/*
9** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
10** All rights reserved.
11**
12** Get the latest Ficl release at http://ficl.sourceforge.net
13**
8*******************************************************************/
9/*
10** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
11** All rights reserved.
12**
13** Get the latest Ficl release at http://ficl.sourceforge.net
14**
15** I am interested in hearing from anyone who uses ficl. If you have
16** a problem, a success story, a defect, an enhancement request, or
17** if you would like to contribute to the ficl release, please
18** contact me by email at the address above.
19**
14** L I C E N S E and D I S C L A I M E R
15**
16** Redistribution and use in source and binary forms, with or without
17** modification, are permitted provided that the following conditions
18** are met:
19** 1. Redistributions of source code must retain the above copyright
20** notice, this list of conditions and the following disclaimer.
21** 2. Redistributions in binary form must reproduce the above copyright

--- 6 unchanged lines hidden (view full) ---

28** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35** SUCH DAMAGE.
20** L I C E N S E and D I S C L A I M E R
21**
22** Redistribution and use in source and binary forms, with or without
23** modification, are permitted provided that the following conditions
24** are met:
25** 1. Redistributions of source code must retain the above copyright
26** notice, this list of conditions and the following disclaimer.
27** 2. Redistributions in binary form must reproduce the above copyright

--- 6 unchanged lines hidden (view full) ---

34** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
35** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41** SUCH DAMAGE.
36**
37** I am interested in hearing from anyone who uses ficl. If you have
38** a problem, a success story, a defect, an enhancement request, or
39** if you would like to contribute to the ficl release, please send
40** contact me by email at the address above.
41**
42** $Id: ficl.h,v 1.11 2001-04-26 21:41:48-07 jsadler Exp jsadler $
43*/
44
42*/
43
45/* $FreeBSD: head/sys/boot/ficl/ficl.h 77443 2001-05-29 23:44:12Z dcs $ */
44/* $FreeBSD: head/sys/boot/ficl/ficl.h 94290 2002-04-09 17:45:28Z dcs $ */
46
47#if !defined (__FICL_H__)
48#define __FICL_H__
49/*
50** Ficl (Forth-inspired command language) is an ANS Forth
51** interpreter written in C. Unlike traditional Forths, this
52** interpreter is designed to be embedded into other systems
53** as a command/macro/development prototype language.

--- 66 unchanged lines hidden (view full) ---

120** ficlLockDictionary, and ficlTextOut to work with your operating system.
121** Finally, use testmain.c as a guide to installing the Ficl system and
122** one or more virtual machines into your code. You do not need to include
123** testmain.c in your build.
124**
125** T o D o L i s t
126**
127** 1. Unimplemented system dependent CORE word: key
45
46#if !defined (__FICL_H__)
47#define __FICL_H__
48/*
49** Ficl (Forth-inspired command language) is an ANS Forth
50** interpreter written in C. Unlike traditional Forths, this
51** interpreter is designed to be embedded into other systems
52** as a command/macro/development prototype language.

--- 66 unchanged lines hidden (view full) ---

119** ficlLockDictionary, and ficlTextOut to work with your operating system.
120** Finally, use testmain.c as a guide to installing the Ficl system and
121** one or more virtual machines into your code. You do not need to include
122** testmain.c in your build.
123**
124** T o D o L i s t
125**
126** 1. Unimplemented system dependent CORE word: key
128** 2. Kludged CORE word: ACCEPT
129** 3. Dictionary locking is full of holes - only one vm at a time
130** can alter the dict.
131** 4. Ficl uses the pad in CORE words - this violates the standard,
127** 2. Ficl uses the PAD in some CORE words - this violates the standard,
132** but it's cleaner for a multithreaded system. I'll have to make a
133** second pad for reference by the word PAD to fix this.
134**
135** F o r M o r e I n f o r m a t i o n
136**
137** Web home of ficl
128** but it's cleaner for a multithreaded system. I'll have to make a
129** second pad for reference by the word PAD to fix this.
130**
131** F o r M o r e I n f o r m a t i o n
132**
133** Web home of ficl
138** http://www.taygeta.com/forth/compilers
134** http://ficl.sourceforge.net
139** Check this website for Forth literature (including the ANSI standard)
140** http://www.taygeta.com/forthlit.html
141** and here for software and more links
142** http://www.taygeta.com/forth.html
143**
144** Obvious Performance enhancement opportunities
145** Compile speed
146** - work on interpret speed
147** - turn off locals (FICL_WANT_LOCALS)
148** Interpret speed
149** - Change inner interpreter (and everything else)
150** so that a definition is a list of pointers to functions
151** and inline data rather than pointers to words. This gets
152** rid of vm->runningWord and a level of indirection in the
153** inner loop. I'll look at it for ficl 3.0
154** - Make the main hash table a bigger prime (HASHSIZE)
155** - FORGET about twiddling the hash function - my experience is
156** that that is a waste of time.
135** Check this website for Forth literature (including the ANSI standard)
136** http://www.taygeta.com/forthlit.html
137** and here for software and more links
138** http://www.taygeta.com/forth.html
139**
140** Obvious Performance enhancement opportunities
141** Compile speed
142** - work on interpret speed
143** - turn off locals (FICL_WANT_LOCALS)
144** Interpret speed
145** - Change inner interpreter (and everything else)
146** so that a definition is a list of pointers to functions
147** and inline data rather than pointers to words. This gets
148** rid of vm->runningWord and a level of indirection in the
149** inner loop. I'll look at it for ficl 3.0
150** - Make the main hash table a bigger prime (HASHSIZE)
151** - FORGET about twiddling the hash function - my experience is
152** that that is a waste of time.
157** - eliminate the need to pass the pVM parameter on the stack
153** - Eliminate the need to pass the pVM parameter on the stack
158** by dedicating a register to it. Most words need access to the
159** vm, but the parameter passing overhead can be reduced. One way
160** requires that the host OS have a task switch callout. Create
161** a global variable for the running VM and refer to it in words
162** that need VM access. Alternative: use thread local storage.
163** For single threaded implementations, you can just use a global.
164** The first two solutions create portability problems, so I
165** haven't considered doing them. Another possibility is to

--- 57 unchanged lines hidden (view full) ---

223
224#include "sysdep.h"
225#include <limits.h> /* UCHAR_MAX */
226
227/*
228** Forward declarations... read on.
229*/
230struct ficl_word;
154** by dedicating a register to it. Most words need access to the
155** vm, but the parameter passing overhead can be reduced. One way
156** requires that the host OS have a task switch callout. Create
157** a global variable for the running VM and refer to it in words
158** that need VM access. Alternative: use thread local storage.
159** For single threaded implementations, you can just use a global.
160** The first two solutions create portability problems, so I
161** haven't considered doing them. Another possibility is to

--- 57 unchanged lines hidden (view full) ---

219
220#include "sysdep.h"
221#include <limits.h> /* UCHAR_MAX */
222
223/*
224** Forward declarations... read on.
225*/
226struct ficl_word;
227typedef struct ficl_word FICL_WORD;
231struct vm;
228struct vm;
229typedef struct vm FICL_VM;
232struct ficl_dict;
230struct ficl_dict;
231typedef struct ficl_dict FICL_DICT;
233struct ficl_system;
234typedef struct ficl_system FICL_SYSTEM;
232struct ficl_system;
233typedef struct ficl_system FICL_SYSTEM;
234struct ficl_system_info;
235typedef struct ficl_system_info FICL_SYSTEM_INFO;
235
236/*
237** the Good Stuff starts here...
238*/
236
237/*
238** the Good Stuff starts here...
239*/
239#define FICL_VER "2.05"
240#define FICL_VER "3.02"
241#define FICL_VER_MAJOR 3
242#define FICL_VER_MINOR 2
240#if !defined (FICL_PROMPT)
241#define FICL_PROMPT "ok> "
242#endif
243
244/*
245** ANS Forth requires false to be zero, and true to be the ones
246** complement of false... that unifies logical and bitwise operations
247** nicely.
248*/
249#define FICL_TRUE ((unsigned long)~(0L))
250#define FICL_FALSE (0)
251#define FICL_BOOL(x) ((x) ? FICL_TRUE : FICL_FALSE)
252
253
254/*
255** A CELL is the main storage type. It must be large enough
256** to contain a pointer or a scalar. In order to accommodate
243#if !defined (FICL_PROMPT)
244#define FICL_PROMPT "ok> "
245#endif
246
247/*
248** ANS Forth requires false to be zero, and true to be the ones
249** complement of false... that unifies logical and bitwise operations
250** nicely.
251*/
252#define FICL_TRUE ((unsigned long)~(0L))
253#define FICL_FALSE (0)
254#define FICL_BOOL(x) ((x) ? FICL_TRUE : FICL_FALSE)
255
256
257/*
258** A CELL is the main storage type. It must be large enough
259** to contain a pointer or a scalar. In order to accommodate
257** 32 bit and 64 bit processors, use abstract types for i and u.
260** 32 bit and 64 bit processors, use abstract types for int,
261** unsigned, and float.
258*/
259typedef union _cell
260{
261 FICL_INT i;
262 FICL_UNS u;
263#if (FICL_WANT_FLOAT)
264 FICL_FLOAT f;
265#endif
266 void *p;
267 void (*fn)(void);
268} CELL;
269
270/*
262*/
263typedef union _cell
264{
265 FICL_INT i;
266 FICL_UNS u;
267#if (FICL_WANT_FLOAT)
268 FICL_FLOAT f;
269#endif
270 void *p;
271 void (*fn)(void);
272} CELL;
273
274/*
271** LVALUEtoCELL does a little pointer trickery to cast any 32 bit
275** LVALUEtoCELL does a little pointer trickery to cast any CELL sized
272** lvalue (informal definition: an expression whose result has an
273** address) to CELL. Remember that constants and casts are NOT
274** themselves lvalues!
275*/
276#define LVALUEtoCELL(v) (*(CELL *)&v)
277
278/*
279** PTRtoCELL is a cast through void * intended to satisfy the

--- 78 unchanged lines hidden (view full) ---

358 CELL *pFrame; /* link reg for stack frame */
359 CELL *sp; /* stack pointer */
360 CELL base[1]; /* Top of stack */
361} FICL_STACK;
362
363/*
364** Stack methods... many map closely to required Forth words.
365*/
276** lvalue (informal definition: an expression whose result has an
277** address) to CELL. Remember that constants and casts are NOT
278** themselves lvalues!
279*/
280#define LVALUEtoCELL(v) (*(CELL *)&v)
281
282/*
283** PTRtoCELL is a cast through void * intended to satisfy the

--- 78 unchanged lines hidden (view full) ---

362 CELL *pFrame; /* link reg for stack frame */
363 CELL *sp; /* stack pointer */
364 CELL base[1]; /* Top of stack */
365} FICL_STACK;
366
367/*
368** Stack methods... many map closely to required Forth words.
369*/
366FICL_STACK *stackCreate(unsigned nCells);
367void stackDelete(FICL_STACK *pStack);
368int stackDepth (FICL_STACK *pStack);
369void stackDrop (FICL_STACK *pStack, int n);
370CELL stackFetch (FICL_STACK *pStack, int n);
371CELL stackGetTop(FICL_STACK *pStack);
372void stackLink (FICL_STACK *pStack, int nCells);
373void stackPick (FICL_STACK *pStack, int n);
374CELL stackPop (FICL_STACK *pStack);
375void *stackPopPtr(FICL_STACK *pStack);
376FICL_UNS stackPopUNS(FICL_STACK *pStack);
377FICL_INT stackPopINT(FICL_STACK *pStack);
378void stackPush (FICL_STACK *pStack, CELL c);
370FICL_STACK *stackCreate (unsigned nCells);
371void stackDelete (FICL_STACK *pStack);
372int stackDepth (FICL_STACK *pStack);
373void stackDrop (FICL_STACK *pStack, int n);
374CELL stackFetch (FICL_STACK *pStack, int n);
375CELL stackGetTop (FICL_STACK *pStack);
376void stackLink (FICL_STACK *pStack, int nCells);
377void stackPick (FICL_STACK *pStack, int n);
378CELL stackPop (FICL_STACK *pStack);
379void *stackPopPtr (FICL_STACK *pStack);
380FICL_UNS stackPopUNS (FICL_STACK *pStack);
381FICL_INT stackPopINT (FICL_STACK *pStack);
382void stackPush (FICL_STACK *pStack, CELL c);
379void stackPushPtr (FICL_STACK *pStack, void *ptr);
383void stackPushPtr (FICL_STACK *pStack, void *ptr);
380void stackPushUNS(FICL_STACK *pStack, FICL_UNS u);
381void stackPushINT(FICL_STACK *pStack, FICL_INT i);
382void stackReset (FICL_STACK *pStack);
383void stackRoll (FICL_STACK *pStack, int n);
384void stackSetTop(FICL_STACK *pStack, CELL c);
385void stackStore (FICL_STACK *pStack, int n, CELL c);
386void stackUnlink(FICL_STACK *pStack);
384void stackPushUNS (FICL_STACK *pStack, FICL_UNS u);
385void stackPushINT (FICL_STACK *pStack, FICL_INT i);
386void stackReset (FICL_STACK *pStack);
387void stackRoll (FICL_STACK *pStack, int n);
388void stackSetTop (FICL_STACK *pStack, CELL c);
389void stackStore (FICL_STACK *pStack, int n, CELL c);
390void stackUnlink (FICL_STACK *pStack);
387
388#if (FICL_WANT_FLOAT)
389float stackPopFloat (FICL_STACK *pStack);
391
392#if (FICL_WANT_FLOAT)
393float stackPopFloat (FICL_STACK *pStack);
390void stackPushFloat(FICL_STACK *pStack, float f);
394void stackPushFloat(FICL_STACK *pStack, FICL_FLOAT f);
391#endif
392
393/*
394** Shortcuts (Guy Carver)
395*/
395#endif
396
397/*
398** Shortcuts (Guy Carver)
399*/
396#define PUSHPTR(p) stackPushPtr(pVM->pStack,p)
397#define PUSHUNS(u) stackPushUNS(pVM->pStack,u)
398#define PUSHINT(i) stackPushINT(pVM->pStack,i)
399#define PUSHFLOAT(f) stackPushFloat(pVM->fStack,f)
400#define PUSH(c) stackPush(pVM->pStack,c)
401#define POPPTR() stackPopPtr(pVM->pStack)
402#define POPUNS() stackPopUNS(pVM->pStack)
403#define POPINT() stackPopINT(pVM->pStack)
404#define POPFLOAT() stackPopFloat(pVM->fStack)
405#define POP() stackPop(pVM->pStack)
406#define GETTOP() stackGetTop(pVM->pStack)
407#define SETTOP(c) stackSetTop(pVM->pStack,LVALUEtoCELL(c))
408#define GETTOPF() stackGetTop(pVM->fStack)
409#define SETTOPF(c) stackSetTop(pVM->fStack,LVALUEtoCELL(c))
410#define STORE(n,c) stackStore(pVM->pStack,n,LVALUEtoCELL(c))
411#define DEPTH() stackDepth(pVM->pStack)
412#define DROP(n) stackDrop(pVM->pStack,n)
413#define DROPF(n) stackDrop(pVM->fStack,n)
414#define FETCH(n) stackFetch(pVM->pStack,n)
415#define PICK(n) stackPick(pVM->pStack,n)
416#define PICKF(n) stackPick(pVM->fStack,n)
417#define ROLL(n) stackRoll(pVM->pStack,n)
418#define ROLLF(n) stackRoll(pVM->fStack,n)
400#define PUSHPTR(p) stackPushPtr(pVM->pStack,p)
401#define PUSHUNS(u) stackPushUNS(pVM->pStack,u)
402#define PUSHINT(i) stackPushINT(pVM->pStack,i)
403#define PUSHFLOAT(f) stackPushFloat(pVM->fStack,f)
404#define PUSH(c) stackPush(pVM->pStack,c)
405#define POPPTR() stackPopPtr(pVM->pStack)
406#define POPUNS() stackPopUNS(pVM->pStack)
407#define POPINT() stackPopINT(pVM->pStack)
408#define POPFLOAT() stackPopFloat(pVM->fStack)
409#define POP() stackPop(pVM->pStack)
410#define GETTOP() stackGetTop(pVM->pStack)
411#define SETTOP(c) stackSetTop(pVM->pStack,LVALUEtoCELL(c))
412#define GETTOPF() stackGetTop(pVM->fStack)
413#define SETTOPF(c) stackSetTop(pVM->fStack,LVALUEtoCELL(c))
414#define STORE(n,c) stackStore(pVM->pStack,n,LVALUEtoCELL(c))
415#define DEPTH() stackDepth(pVM->pStack)
416#define DROP(n) stackDrop(pVM->pStack,n)
417#define DROPF(n) stackDrop(pVM->fStack,n)
418#define FETCH(n) stackFetch(pVM->pStack,n)
419#define PICK(n) stackPick(pVM->pStack,n)
420#define PICKF(n) stackPick(pVM->fStack,n)
421#define ROLL(n) stackRoll(pVM->pStack,n)
422#define ROLLF(n) stackRoll(pVM->fStack,n)
419
420/*
421** The virtual machine (VM) contains the state for one interpreter.
422** Defined operations include:
423** Create & initialize
424** Delete
425** Execute a block of text
426** Parse a word out of the input stream
427** Call return, and branch
428** Text output
429** Throw an exception
430*/
431
423
424/*
425** The virtual machine (VM) contains the state for one interpreter.
426** Defined operations include:
427** Create & initialize
428** Delete
429** Execute a block of text
430** Parse a word out of the input stream
431** Call return, and branch
432** Text output
433** Throw an exception
434*/
435
432typedef struct ficl_word ** IPTYPE; /* the VM's instruction pointer */
436typedef FICL_WORD ** IPTYPE; /* the VM's instruction pointer */
433
434/*
435** Each VM has a placeholder for an output function -
436** this makes it possible to have each VM do I/O
437** through a different device. If you specify no
438** OUTFUNC, it defaults to ficlTextOut.
439*/
437
438/*
439** Each VM has a placeholder for an output function -
440** this makes it possible to have each VM do I/O
441** through a different device. If you specify no
442** OUTFUNC, it defaults to ficlTextOut.
443*/
440typedef void (*OUTFUNC)(struct vm *pVM, char *text, int fNewline);
444typedef void (*OUTFUNC)(FICL_VM *pVM, char *text, int fNewline);
441
442/*
443** Each VM operates in one of two non-error states: interpreting
444** or compiling. When interpreting, words are simply executed.
445** When compiling, most words in the input stream have their
446** addresses inserted into the word under construction. Some words
447** (known as IMMEDIATE) are executed in the compile state, too.
448*/

--- 14 unchanged lines hidden (view full) ---

463*/
464#if !defined nFICLNAME
465#define nFICLNAME 31
466#endif
467
468/*
469** OK - now we can really define the VM...
470*/
445
446/*
447** Each VM operates in one of two non-error states: interpreting
448** or compiling. When interpreting, words are simply executed.
449** When compiling, most words in the input stream have their
450** addresses inserted into the word under construction. Some words
451** (known as IMMEDIATE) are executed in the compile state, too.
452*/

--- 14 unchanged lines hidden (view full) ---

467*/
468#if !defined nFICLNAME
469#define nFICLNAME 31
470#endif
471
472/*
473** OK - now we can really define the VM...
474*/
471typedef struct vm
475struct vm
472{
473 FICL_SYSTEM *pSys; /* Which system this VM belongs to */
476{
477 FICL_SYSTEM *pSys; /* Which system this VM belongs to */
474 struct vm *link; /* Ficl keeps a VM list for simple teardown */
478 FICL_VM *link; /* Ficl keeps a VM list for simple teardown */
475 jmp_buf *pState; /* crude exception mechanism... */
476 OUTFUNC textOut; /* Output callback - see sysdep.c */
479 jmp_buf *pState; /* crude exception mechanism... */
480 OUTFUNC textOut; /* Output callback - see sysdep.c */
477 void * pExtend; /* vm extension pointer */
481 void * pExtend; /* vm extension pointer for app use - initialized from FICL_SYSTEM */
478 short fRestart; /* Set TRUE to restart runningWord */
479 IPTYPE ip; /* instruction pointer */
482 short fRestart; /* Set TRUE to restart runningWord */
483 IPTYPE ip; /* instruction pointer */
480 struct ficl_word
481 *runningWord;/* address of currently running word (often just *(ip-1) ) */
484 FICL_WORD *runningWord;/* address of currently running word (often just *(ip-1) ) */
482 FICL_UNS state; /* compiling or interpreting */
483 FICL_UNS base; /* number conversion base */
484 FICL_STACK *pStack; /* param stack */
485 FICL_STACK *rStack; /* return stack */
486#if FICL_WANT_FLOAT
487 FICL_STACK *fStack; /* float stack (optional) */
488#endif
485 FICL_UNS state; /* compiling or interpreting */
486 FICL_UNS base; /* number conversion base */
487 FICL_STACK *pStack; /* param stack */
488 FICL_STACK *rStack; /* return stack */
489#if FICL_WANT_FLOAT
490 FICL_STACK *fStack; /* float stack (optional) */
491#endif
489 CELL sourceID; /* -1 if string, 0 if normal input */
492 CELL sourceID; /* -1 if EVALUATE, 0 if normal input */
490 TIB tib; /* address of incoming text string */
491#if FICL_WANT_USER
492 CELL user[FICL_USER_CELLS];
493#endif
494 char pad[nPAD]; /* the scratch area (see above) */
493 TIB tib; /* address of incoming text string */
494#if FICL_WANT_USER
495 CELL user[FICL_USER_CELLS];
496#endif
497 char pad[nPAD]; /* the scratch area (see above) */
495} FICL_VM;
498};
496
497/*
498** A FICL_CODE points to a function that gets called to help execute
499** a word in the dictionary. It always gets passed a pointer to the
500** running virtual machine, and from there it can get the address
501** of the parameter area of the word it's supposed to operate on.
502** For precompiled words, the code is all there is. For user defined
503** words, the code assumes that the word's parameter area is a list

--- 9 unchanged lines hidden (view full) ---

513#define VM_ASSERT(pVM)
514#endif
515
516/*
517** Ficl models memory as a contiguous space divided into
518** words in a linked list called the dictionary.
519** A FICL_WORD starts each entry in the list.
520** Version 1.02: space for the name characters is allotted from
499
500/*
501** A FICL_CODE points to a function that gets called to help execute
502** a word in the dictionary. It always gets passed a pointer to the
503** running virtual machine, and from there it can get the address
504** of the parameter area of the word it's supposed to operate on.
505** For precompiled words, the code is all there is. For user defined
506** words, the code assumes that the word's parameter area is a list

--- 9 unchanged lines hidden (view full) ---

516#define VM_ASSERT(pVM)
517#endif
518
519/*
520** Ficl models memory as a contiguous space divided into
521** words in a linked list called the dictionary.
522** A FICL_WORD starts each entry in the list.
523** Version 1.02: space for the name characters is allotted from
521** the dictionary ahead of the word struct - this saves about half
522** the storage on average with very little runtime cost.
524** the dictionary ahead of the word struct, rather than using
525** a fixed size array for each name.
523*/
526*/
524typedef struct ficl_word
527struct ficl_word
525{
526 struct ficl_word *link; /* Previous word in the dictionary */
527 UNS16 hash;
528 UNS8 flags; /* Immediate, Smudge, Compile-only */
529 FICL_COUNT nName; /* Number of chars in word name */
530 char *name; /* First nFICLNAME chars of word name */
531 FICL_CODE code; /* Native code to execute the word */
532 CELL param[1]; /* First data cell of the word */
528{
529 struct ficl_word *link; /* Previous word in the dictionary */
530 UNS16 hash;
531 UNS8 flags; /* Immediate, Smudge, Compile-only */
532 FICL_COUNT nName; /* Number of chars in word name */
533 char *name; /* First nFICLNAME chars of word name */
534 FICL_CODE code; /* Native code to execute the word */
535 CELL param[1]; /* First data cell of the word */
533} FICL_WORD;
536};
534
535/*
536** Worst-case size of a word header: nFICLNAME chars in name
537*/
538#define CELLS_PER_WORD \
539 ( (sizeof (FICL_WORD) + nFICLNAME + sizeof (CELL)) \
540 / (sizeof (CELL)) )
541
542int wordIsImmediate(FICL_WORD *pFW);
543int wordIsCompileOnly(FICL_WORD *pFW);
544
545/* flag values for word header */
546#define FW_IMMEDIATE 1 /* execute me even if compiling */
547#define FW_COMPILE 2 /* error if executed when not compiling */
548#define FW_SMUDGE 4 /* definition in progress - hide me */
537
538/*
539** Worst-case size of a word header: nFICLNAME chars in name
540*/
541#define CELLS_PER_WORD \
542 ( (sizeof (FICL_WORD) + nFICLNAME + sizeof (CELL)) \
543 / (sizeof (CELL)) )
544
545int wordIsImmediate(FICL_WORD *pFW);
546int wordIsCompileOnly(FICL_WORD *pFW);
547
548/* flag values for word header */
549#define FW_IMMEDIATE 1 /* execute me even if compiling */
550#define FW_COMPILE 2 /* error if executed when not compiling */
551#define FW_SMUDGE 4 /* definition in progress - hide me */
552#define FW_ISOBJECT 8 /* word is an object or object member variable */
549
550#define FW_COMPIMMED (FW_IMMEDIATE | FW_COMPILE)
551#define FW_DEFAULT 0
552
553
554/*
555** Exit codes for vmThrow
556*/

--- 4 unchanged lines hidden (view full) ---

561#define VM_ERREXIT -260 /* interp found an error */
562#define VM_BREAK -261 /* debugger breakpoint */
563#define VM_ABORT -1 /* like errexit -- abort */
564#define VM_ABORTQ -2 /* like errexit -- abort" */
565#define VM_QUIT -56 /* like errexit, but leave pStack & base alone */
566
567
568void vmBranchRelative(FICL_VM *pVM, int offset);
553
554#define FW_COMPIMMED (FW_IMMEDIATE | FW_COMPILE)
555#define FW_DEFAULT 0
556
557
558/*
559** Exit codes for vmThrow
560*/

--- 4 unchanged lines hidden (view full) ---

565#define VM_ERREXIT -260 /* interp found an error */
566#define VM_BREAK -261 /* debugger breakpoint */
567#define VM_ABORT -1 /* like errexit -- abort */
568#define VM_ABORTQ -2 /* like errexit -- abort" */
569#define VM_QUIT -56 /* like errexit, but leave pStack & base alone */
570
571
572void vmBranchRelative(FICL_VM *pVM, int offset);
569FICL_VM * vmCreate (FICL_VM *pVM, unsigned nPStack, unsigned nRStack);
570void vmDelete (FICL_VM *pVM);
571void vmExecute(FICL_VM *pVM, FICL_WORD *pWord);
572char * vmGetString(FICL_VM *pVM, FICL_STRING *spDest, char delimiter);
573STRINGINFO vmGetWord(FICL_VM *pVM);
574STRINGINFO vmGetWord0(FICL_VM *pVM);
575int vmGetWordToPad(FICL_VM *pVM);
576STRINGINFO vmParseString(FICL_VM *pVM, char delimiter);
573FICL_VM * vmCreate (FICL_VM *pVM, unsigned nPStack, unsigned nRStack);
574void vmDelete (FICL_VM *pVM);
575void vmExecute (FICL_VM *pVM, FICL_WORD *pWord);
576FICL_DICT *vmGetDict (FICL_VM *pVM);
577char * vmGetString (FICL_VM *pVM, FICL_STRING *spDest, char delimiter);
578STRINGINFO vmGetWord (FICL_VM *pVM);
579STRINGINFO vmGetWord0 (FICL_VM *pVM);
580int vmGetWordToPad (FICL_VM *pVM);
581STRINGINFO vmParseString (FICL_VM *pVM, char delimiter);
577STRINGINFO vmParseStringEx(FICL_VM *pVM, char delimiter, char fSkipLeading);
582STRINGINFO vmParseStringEx(FICL_VM *pVM, char delimiter, char fSkipLeading);
578CELL vmPop(FICL_VM *pVM);
579void vmPush(FICL_VM *pVM, CELL c);
580void vmPopIP (FICL_VM *pVM);
581void vmPushIP (FICL_VM *pVM, IPTYPE newIP);
582void vmQuit (FICL_VM *pVM);
583void vmReset (FICL_VM *pVM);
584void vmSetTextOut(FICL_VM *pVM, OUTFUNC textOut);
585#if FICL_WANT_DEBUGGER
586void vmStep(FICL_VM *pVM);
587#endif
588void vmTextOut(FICL_VM *pVM, char *text, int fNewline);
589void vmThrow (FICL_VM *pVM, int except);
590void vmThrowErr(FICL_VM *pVM, char *fmt, ...);
583CELL vmPop (FICL_VM *pVM);
584void vmPush (FICL_VM *pVM, CELL c);
585void vmPopIP (FICL_VM *pVM);
586void vmPushIP (FICL_VM *pVM, IPTYPE newIP);
587void vmQuit (FICL_VM *pVM);
588void vmReset (FICL_VM *pVM);
589void vmSetTextOut (FICL_VM *pVM, OUTFUNC textOut);
590void vmTextOut (FICL_VM *pVM, char *text, int fNewline);
591void vmTextOut (FICL_VM *pVM, char *text, int fNewline);
592void vmThrow (FICL_VM *pVM, int except);
593void vmThrowErr (FICL_VM *pVM, char *fmt, ...);
591
592#define vmGetRunningWord(pVM) ((pVM)->runningWord)
593
594
595/*
596** The inner interpreter - coded as a macro (see note for
597** INLINE_INNER_LOOP in sysdep.h for complaints about VC++ 5
598*/
599#define M_VM_STEP(pVM) \
600 FICL_WORD *tempFW = *(pVM)->ip++; \
601 (pVM)->runningWord = tempFW; \
594
595#define vmGetRunningWord(pVM) ((pVM)->runningWord)
596
597
598/*
599** The inner interpreter - coded as a macro (see note for
600** INLINE_INNER_LOOP in sysdep.h for complaints about VC++ 5
601*/
602#define M_VM_STEP(pVM) \
603 FICL_WORD *tempFW = *(pVM)->ip++; \
604 (pVM)->runningWord = tempFW; \
602 tempFW->code(pVM); \
605 tempFW->code(pVM);
603
604#define M_INNER_LOOP(pVM) \
605 for (;;) { M_VM_STEP(pVM) }
606
607
608#if INLINE_INNER_LOOP != 0
609#define vmInnerLoop(pVM) M_INNER_LOOP(pVM)
610#else

--- 16 unchanged lines hidden (view full) ---

627** ANS forth seems to require the input buffer to be represented
628** as a pointer to the start of the buffer, and an index to the
629** next character to read.
630** PushTib points the VM to a new input string and optionally
631** returns a copy of the current state
632** PopTib restores the TIB state given a saved TIB from PushTib
633** GetInBuf returns a pointer to the next unused char of the TIB
634*/
606
607#define M_INNER_LOOP(pVM) \
608 for (;;) { M_VM_STEP(pVM) }
609
610
611#if INLINE_INNER_LOOP != 0
612#define vmInnerLoop(pVM) M_INNER_LOOP(pVM)
613#else

--- 16 unchanged lines hidden (view full) ---

630** ANS forth seems to require the input buffer to be represented
631** as a pointer to the start of the buffer, and an index to the
632** next character to read.
633** PushTib points the VM to a new input string and optionally
634** returns a copy of the current state
635** PopTib restores the TIB state given a saved TIB from PushTib
636** GetInBuf returns a pointer to the next unused char of the TIB
637*/
635void vmPushTib(FICL_VM *pVM, char *text, FICL_INT nChars, TIB *pSaveTib);
636void vmPopTib(FICL_VM *pVM, TIB *pTib);
637#define vmGetInBuf(pVM) ((pVM)->tib.cp + (pVM)->tib.index)
638#define vmGetInBufLen(pVM) ((pVM)->tib.end - (pVM)->tib.cp)
639#define vmGetInBufEnd(pVM) ((pVM)->tib.end)
638void vmPushTib (FICL_VM *pVM, char *text, FICL_INT nChars, TIB *pSaveTib);
639void vmPopTib (FICL_VM *pVM, TIB *pTib);
640#define vmGetInBuf(pVM) ((pVM)->tib.cp + (pVM)->tib.index)
641#define vmGetInBufLen(pVM) ((pVM)->tib.end - (pVM)->tib.cp)
642#define vmGetInBufEnd(pVM) ((pVM)->tib.end)
640#define vmGetTibIndex(pVM) (pVM)->tib.index
641#define vmSetTibIndex(pVM, i) (pVM)->tib.index = i
642#define vmUpdateTib(pVM, str) (pVM)->tib.index = (str) - (pVM)->tib.cp
643
644/*
645** Generally useful string manipulators omitted by ANSI C...
646** ltoa complements strtol
647*/

--- 33 unchanged lines hidden (view full) ---

681typedef struct ficl_hash
682{
683 struct ficl_hash *link; /* link to parent class wordlist for OO */
684 char *name; /* optional pointer to \0 terminated wordlist name */
685 unsigned size; /* number of buckets in the hash */
686 FICL_WORD *table[1];
687} FICL_HASH;
688
643#define vmGetTibIndex(pVM) (pVM)->tib.index
644#define vmSetTibIndex(pVM, i) (pVM)->tib.index = i
645#define vmUpdateTib(pVM, str) (pVM)->tib.index = (str) - (pVM)->tib.cp
646
647/*
648** Generally useful string manipulators omitted by ANSI C...
649** ltoa complements strtol
650*/

--- 33 unchanged lines hidden (view full) ---

684typedef struct ficl_hash
685{
686 struct ficl_hash *link; /* link to parent class wordlist for OO */
687 char *name; /* optional pointer to \0 terminated wordlist name */
688 unsigned size; /* number of buckets in the hash */
689 FICL_WORD *table[1];
690} FICL_HASH;
691
689void hashForget(FICL_HASH *pHash, void *where);
690UNS16 hashHashCode(STRINGINFO si);
692void hashForget (FICL_HASH *pHash, void *where);
693UNS16 hashHashCode (STRINGINFO si);
691void hashInsertWord(FICL_HASH *pHash, FICL_WORD *pFW);
694void hashInsertWord(FICL_HASH *pHash, FICL_WORD *pFW);
692FICL_WORD *hashLookup(struct ficl_hash *pHash,
693 STRINGINFO si,
694 UNS16 hashCode);
695void hashReset(FICL_HASH *pHash);
695FICL_WORD *hashLookup (FICL_HASH *pHash, STRINGINFO si, UNS16 hashCode);
696void hashReset (FICL_HASH *pHash);
696
697/*
698** A Dictionary is a linked list of FICL_WORDs. It is also Ficl's
699** memory model. Description of fields:
700**
701** here -- points to the next free byte in the dictionary. This
702** pointer is forced to be CELL-aligned before a definition is added.
703** Do not assume any specific alignment otherwise - Use dictAlign().

--- 16 unchanged lines hidden (view full) ---

720** pSearch -- array of pointers to wordlists. Managed as a stack.
721** Highest index is the first list in the search order.
722** nLists -- number of lists in pSearch. nLists-1 is the highest
723** filled slot in pSearch, and points to the first wordlist
724** in the search order
725** size -- number of cells in the dictionary (total)
726** dict -- start of data area. Must be at the end of the struct.
727*/
697
698/*
699** A Dictionary is a linked list of FICL_WORDs. It is also Ficl's
700** memory model. Description of fields:
701**
702** here -- points to the next free byte in the dictionary. This
703** pointer is forced to be CELL-aligned before a definition is added.
704** Do not assume any specific alignment otherwise - Use dictAlign().

--- 16 unchanged lines hidden (view full) ---

721** pSearch -- array of pointers to wordlists. Managed as a stack.
722** Highest index is the first list in the search order.
723** nLists -- number of lists in pSearch. nLists-1 is the highest
724** filled slot in pSearch, and points to the first wordlist
725** in the search order
726** size -- number of cells in the dictionary (total)
727** dict -- start of data area. Must be at the end of the struct.
728*/
728typedef struct ficl_dict
729struct ficl_dict
729{
730 CELL *here;
731 FICL_WORD *smudge;
732 FICL_HASH *pForthWords;
733 FICL_HASH *pCompile;
734 FICL_HASH *pSearch[FICL_DEFAULT_VOCS];
735 int nLists;
736 unsigned size; /* Number of cells in dict (total)*/
737 CELL *dict; /* Base of dictionary memory */
730{
731 CELL *here;
732 FICL_WORD *smudge;
733 FICL_HASH *pForthWords;
734 FICL_HASH *pCompile;
735 FICL_HASH *pSearch[FICL_DEFAULT_VOCS];
736 int nLists;
737 unsigned size; /* Number of cells in dict (total)*/
738 CELL *dict; /* Base of dictionary memory */
738} FICL_DICT;
739};
739
740void *alignPtr(void *ptr);
741void dictAbortDefinition(FICL_DICT *pDict);
740
741void *alignPtr(void *ptr);
742void dictAbortDefinition(FICL_DICT *pDict);
742void dictAlign(FICL_DICT *pDict);
743int dictAllot(FICL_DICT *pDict, int n);
744int dictAllotCells(FICL_DICT *pDict, int nCells);
745void dictAppendCell(FICL_DICT *pDict, CELL c);
746void dictAppendChar(FICL_DICT *pDict, char c);
747FICL_WORD *dictAppendWord(FICL_DICT *pDict,
743void dictAlign (FICL_DICT *pDict);
744int dictAllot (FICL_DICT *pDict, int n);
745int dictAllotCells (FICL_DICT *pDict, int nCells);
746void dictAppendCell (FICL_DICT *pDict, CELL c);
747void dictAppendChar (FICL_DICT *pDict, char c);
748FICL_WORD *dictAppendWord (FICL_DICT *pDict,
748 char *name,
749 FICL_CODE pCode,
750 UNS8 flags);
751FICL_WORD *dictAppendWord2(FICL_DICT *pDict,
752 STRINGINFO si,
753 FICL_CODE pCode,
754 UNS8 flags);
749 char *name,
750 FICL_CODE pCode,
751 UNS8 flags);
752FICL_WORD *dictAppendWord2(FICL_DICT *pDict,
753 STRINGINFO si,
754 FICL_CODE pCode,
755 UNS8 flags);
755void dictAppendUNS(FICL_DICT *pDict, FICL_UNS u);
756int dictCellsAvail(FICL_DICT *pDict);
757int dictCellsUsed (FICL_DICT *pDict);
758void dictCheck(FICL_DICT *pDict, FICL_VM *pVM, int nCells);
756void dictAppendUNS (FICL_DICT *pDict, FICL_UNS u);
757int dictCellsAvail (FICL_DICT *pDict);
758int dictCellsUsed (FICL_DICT *pDict);
759void dictCheck (FICL_DICT *pDict, FICL_VM *pVM, int n);
759FICL_DICT *dictCreate(unsigned nCELLS);
760FICL_DICT *dictCreateHashed(unsigned nCells, unsigned nHash);
761FICL_HASH *dictCreateWordlist(FICL_DICT *dp, int nBuckets);
760FICL_DICT *dictCreate(unsigned nCELLS);
761FICL_DICT *dictCreateHashed(unsigned nCells, unsigned nHash);
762FICL_HASH *dictCreateWordlist(FICL_DICT *dp, int nBuckets);
762void dictDelete(FICL_DICT *pDict);
763void dictEmpty(FICL_DICT *pDict, unsigned nHash);
764int dictIncludes(FICL_DICT *pDict, void *p);
765FICL_WORD *dictLookup(FICL_DICT *pDict, STRINGINFO si);
763void dictDelete (FICL_DICT *pDict);
764void dictEmpty (FICL_DICT *pDict, unsigned nHash);
765#if FICL_WANT_FLOAT
766void dictHashSummary(FICL_VM *pVM);
767#endif
768int dictIncludes (FICL_DICT *pDict, void *p);
769FICL_WORD *dictLookup (FICL_DICT *pDict, STRINGINFO si);
766#if FICL_WANT_LOCALS
770#if FICL_WANT_LOCALS
767FICL_WORD *dictLookupLoc(FICL_DICT *pDict, STRINGINFO si);
771FICL_WORD *ficlLookupLoc (FICL_SYSTEM *pSys, STRINGINFO si);
768#endif
769void dictResetSearchOrder(FICL_DICT *pDict);
772#endif
773void dictResetSearchOrder(FICL_DICT *pDict);
770void dictSetFlags(FICL_DICT *pDict, UNS8 set, UNS8 clr);
774void dictSetFlags (FICL_DICT *pDict, UNS8 set, UNS8 clr);
771void dictSetImmediate(FICL_DICT *pDict);
775void dictSetImmediate(FICL_DICT *pDict);
772void dictUnsmudge(FICL_DICT *pDict);
773CELL *dictWhere(FICL_DICT *pDict);
776void dictUnsmudge (FICL_DICT *pDict);
777CELL *dictWhere (FICL_DICT *pDict);
774
775
776/*
777** P A R S E S T E P
778** (New for 2.05)
779** See words.c: interpWord
780** By default, ficl goes through two attempts to parse each token from its input
781** stream: it first attempts to match it with a word in the dictionary, and

--- 20 unchanged lines hidden (view full) ---

802** the dictionary. Precompiled parse steps can use (PARSE-STEP) as their
803** CFA - see parenParseStep in words.c.
804*/
805int ficlAddParseStep(FICL_SYSTEM *pSys, FICL_WORD *pFW); /* ficl.c */
806void ficlAddPrecompiledParseStep(FICL_SYSTEM *pSys, char *name, FICL_PARSE_STEP pStep);
807void ficlListParseSteps(FICL_VM *pVM);
808
809/*
778
779
780/*
781** P A R S E S T E P
782** (New for 2.05)
783** See words.c: interpWord
784** By default, ficl goes through two attempts to parse each token from its input
785** stream: it first attempts to match it with a word in the dictionary, and

--- 20 unchanged lines hidden (view full) ---

806** the dictionary. Precompiled parse steps can use (PARSE-STEP) as their
807** CFA - see parenParseStep in words.c.
808*/
809int ficlAddParseStep(FICL_SYSTEM *pSys, FICL_WORD *pFW); /* ficl.c */
810void ficlAddPrecompiledParseStep(FICL_SYSTEM *pSys, char *name, FICL_PARSE_STEP pStep);
811void ficlListParseSteps(FICL_VM *pVM);
812
813/*
814** FICL_BREAKPOINT record.
815** origXT - if NULL, this breakpoint is unused. Otherwise it stores the xt
816** that the breakpoint overwrote. This is restored to the dictionary when the
817** BP executes or gets cleared
818** address - the location of the breakpoint (address of the instruction that
819** has been replaced with the breakpoint trap
820** origXT - The original contents of the location with the breakpoint
821** Note: address is NULL when this breakpoint is empty
822*/
823typedef struct FICL_BREAKPOINT
824{
825 void *address;
826 FICL_WORD *origXT;
827} FICL_BREAKPOINT;
828
829
830/*
810** F I C L _ S Y S T E M
811** The top level data structure of the system - ficl_system ties a list of
812** virtual machines with their corresponding dictionaries. Ficl 3.0 will
813** support multiple Ficl systems, allowing multiple concurrent sessions
814** to separate dictionaries with some constraints.
815** The present model allows multiple sessions to one dictionary provided
816** you implement ficlLockDictionary() as specified in sysdep.h
831** F I C L _ S Y S T E M
832** The top level data structure of the system - ficl_system ties a list of
833** virtual machines with their corresponding dictionaries. Ficl 3.0 will
834** support multiple Ficl systems, allowing multiple concurrent sessions
835** to separate dictionaries with some constraints.
836** The present model allows multiple sessions to one dictionary provided
837** you implement ficlLockDictionary() as specified in sysdep.h
817**
818** RESTRICTIONS: due to the use of static variables in words.c for compiling
819** comtrol structures faster, if you use multiple ficl systems these variables
820** will point into the most recently initialized dictionary - this is probably
821** not a problem provided the precompiled dictionaries are identical for
822** all systems.
838** Note: the pExtend pointer is there to provide context for applications. It is copied
839** to each VM's pExtend field as that VM is created.
823*/
824struct ficl_system
825{
826 FICL_SYSTEM *link;
840*/
841struct ficl_system
842{
843 FICL_SYSTEM *link;
827 FICL_WORD *parseList[FICL_MAX_PARSE_STEPS];
844 void *pExtend; /* Initializes VM's pExtend pointer (for application use) */
828 FICL_VM *vmList;
829 FICL_DICT *dp;
830 FICL_DICT *envp;
831#ifdef FICL_WANT_LOCALS
832 FICL_DICT *localp;
833#endif
834 FICL_WORD *pInterp[3];
845 FICL_VM *vmList;
846 FICL_DICT *dp;
847 FICL_DICT *envp;
848#ifdef FICL_WANT_LOCALS
849 FICL_DICT *localp;
850#endif
851 FICL_WORD *pInterp[3];
852 FICL_WORD *parseList[FICL_MAX_PARSE_STEPS];
853 OUTFUNC textOut;
854
855 FICL_WORD *pBranchParen;
856 FICL_WORD *pDoParen;
857 FICL_WORD *pDoesParen;
858 FICL_WORD *pExitInner;
859 FICL_WORD *pExitParen;
860 FICL_WORD *pIfParen;
861 FICL_WORD *pInterpret;
862 FICL_WORD *pLitParen;
863 FICL_WORD *pTwoLitParen;
864 FICL_WORD *pLoopParen;
865 FICL_WORD *pPLoopParen;
866 FICL_WORD *pQDoParen;
867 FICL_WORD *pSemiParen;
868 FICL_WORD *pStore;
869 FICL_WORD *pCStringLit;
870 FICL_WORD *pStringLit;
871
872#if FICL_WANT_LOCALS
873 FICL_WORD *pGetLocalParen;
874 FICL_WORD *pGet2LocalParen;
875 FICL_WORD *pGetLocal0;
876 FICL_WORD *pGetLocal1;
877 FICL_WORD *pToLocalParen;
878 FICL_WORD *pTo2LocalParen;
879 FICL_WORD *pToLocal0;
880 FICL_WORD *pToLocal1;
881 FICL_WORD *pLinkParen;
882 FICL_WORD *pUnLinkParen;
883 FICL_INT nLocals;
884 CELL *pMarkLocals;
885#endif
886
887 FICL_BREAKPOINT bpStep;
835};
836
888};
889
890struct ficl_system_info
891{
892 int size; /* structure size tag for versioning */
893 int nDictCells; /* Size of system's Dictionary */
894 OUTFUNC textOut; /* default textOut function */
895 void *pExtend; /* Initializes VM's pExtend pointer - for application use */
896 int nEnvCells; /* Size of Environment dictionary */
897};
898
899
900#define ficlInitInfo(x) { memset((x), 0, sizeof(FICL_SYSTEM_INFO)); \
901 (x)->size = sizeof(FICL_SYSTEM_INFO); }
902
837/*
838** External interface to FICL...
839*/
840/*
841** f i c l I n i t S y s t e m
842** Binds a global dictionary to the interpreter system and initializes
843** the dict to contain the ANSI CORE wordset.
903/*
904** External interface to FICL...
905*/
906/*
907** f i c l I n i t S y s t e m
908** Binds a global dictionary to the interpreter system and initializes
909** the dict to contain the ANSI CORE wordset.
844** You specify the address and size of the allocated area.
910** You can specify the address and size of the allocated area.
911** Using ficlInitSystemEx you can also specify the text output function.
845** After that, ficl manages it.
846** First step is to set up the static pointers to the area.
847** Then write the "precompiled" portion of the dictionary in.
848** The dictionary needs to be at least large enough to hold the
849** precompiled part. Try 1K cells minimum. Use "words" to find
850** out how much of the dictionary is used at any time.
851*/
912** After that, ficl manages it.
913** First step is to set up the static pointers to the area.
914** Then write the "precompiled" portion of the dictionary in.
915** The dictionary needs to be at least large enough to hold the
916** precompiled part. Try 1K cells minimum. Use "words" to find
917** out how much of the dictionary is used at any time.
918*/
852void ficlInitSystem(int nDictCells);
919FICL_SYSTEM *ficlInitSystemEx(FICL_SYSTEM_INFO *fsi);
853
920
921/* Deprecated call */
922FICL_SYSTEM *ficlInitSystem(int nDictCells);
923
854/*
855** f i c l T e r m S y s t e m
856** Deletes the system dictionary and all virtual machines that
857** were created with ficlNewVM (see below). Call this function to
858** reclaim all memory used by the dictionary and VMs.
859*/
924/*
925** f i c l T e r m S y s t e m
926** Deletes the system dictionary and all virtual machines that
927** were created with ficlNewVM (see below). Call this function to
928** reclaim all memory used by the dictionary and VMs.
929*/
860void ficlTermSystem(void);
930void ficlTermSystem(FICL_SYSTEM *pSys);
861
862/*
931
932/*
933** f i c l E v a l u a t e
934** Evaluates a block of input text in the context of the
935** specified interpreter. Also sets SOURCE-ID properly.
936**
937** PLEASE USE THIS FUNCTION when throwing a hard-coded
938** string to the FICL interpreter.
939*/
940int ficlEvaluate(FICL_VM *pVM, char *pText);
941
942/*
863** f i c l E x e c
864** Evaluates a block of input text in the context of the
865** specified interpreter. Emits any requested output to the
866** interpreter's output function. If the input string is NULL
867** terminated, you can pass -1 as nChars rather than count it.
868** Execution returns when the text block has been executed,
869** or an error occurs.
870** Returns one of the VM_XXXX codes defined in ficl.h:

--- 4 unchanged lines hidden (view full) ---

875** VM_USEREXIT means that the user executed the "bye" command
876** to shut down the interpreter. This would be a good
877** time to delete the vm, etc -- or you can ignore this
878** signal.
879** VM_ABORT and VM_ABORTQ are generated by 'abort' and 'abort"'
880** commands.
881** Preconditions: successful execution of ficlInitSystem,
882** Successful creation and init of the VM by ficlNewVM (or equiv)
943** f i c l E x e c
944** Evaluates a block of input text in the context of the
945** specified interpreter. Emits any requested output to the
946** interpreter's output function. If the input string is NULL
947** terminated, you can pass -1 as nChars rather than count it.
948** Execution returns when the text block has been executed,
949** or an error occurs.
950** Returns one of the VM_XXXX codes defined in ficl.h:

--- 4 unchanged lines hidden (view full) ---

955** VM_USEREXIT means that the user executed the "bye" command
956** to shut down the interpreter. This would be a good
957** time to delete the vm, etc -- or you can ignore this
958** signal.
959** VM_ABORT and VM_ABORTQ are generated by 'abort' and 'abort"'
960** commands.
961** Preconditions: successful execution of ficlInitSystem,
962** Successful creation and init of the VM by ficlNewVM (or equiv)
963**
964** If you call ficlExec() or one of its brothers, you MUST
965** ensure pVM->sourceID was set to a sensible value.
966** ficlExec() explicitly DOES NOT manage SOURCE-ID for you.
883*/
884int ficlExec (FICL_VM *pVM, char *pText);
885int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT nChars);
886int ficlExecXT(FICL_VM *pVM, FICL_WORD *pWord);
887
888/*
889** ficlExecFD(FICL_VM *pVM, int fd);
890 * Evaluates text from file passed in via fd.
891 * Execution returns when all of file has been executed or an
892 * error occurs.
893 */
894int ficlExecFD(FICL_VM *pVM, int fd);
895
896/*
897** Create a new VM from the heap, and link it into the system VM list.
898** Initializes the VM and binds default sized stacks to it. Returns the
899** address of the VM, or NULL if an error occurs.
900** Precondition: successful execution of ficlInitSystem
901*/
967*/
968int ficlExec (FICL_VM *pVM, char *pText);
969int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT nChars);
970int ficlExecXT(FICL_VM *pVM, FICL_WORD *pWord);
971
972/*
973** ficlExecFD(FICL_VM *pVM, int fd);
974 * Evaluates text from file passed in via fd.
975 * Execution returns when all of file has been executed or an
976 * error occurs.
977 */
978int ficlExecFD(FICL_VM *pVM, int fd);
979
980/*
981** Create a new VM from the heap, and link it into the system VM list.
982** Initializes the VM and binds default sized stacks to it. Returns the
983** address of the VM, or NULL if an error occurs.
984** Precondition: successful execution of ficlInitSystem
985*/
902FICL_VM *ficlNewVM(void);
986FICL_VM *ficlNewVM(FICL_SYSTEM *pSys);
903
904/*
905** Force deletion of a VM. You do not need to do this
906** unless you're creating and discarding a lot of VMs.
907** For systems that use a constant pool of VMs for the life
908** of the system, ficltermSystem takes care of VM cleanup
909** automatically.
910*/

--- 6 unchanged lines hidden (view full) ---

917*/
918int ficlSetStackSize(int nStackCells);
919
920/*
921** Returns the address of the most recently defined word in the system
922** dictionary with the given name, or NULL if no match.
923** Precondition: successful execution of ficlInitSystem
924*/
987
988/*
989** Force deletion of a VM. You do not need to do this
990** unless you're creating and discarding a lot of VMs.
991** For systems that use a constant pool of VMs for the life
992** of the system, ficltermSystem takes care of VM cleanup
993** automatically.
994*/

--- 6 unchanged lines hidden (view full) ---

1001*/
1002int ficlSetStackSize(int nStackCells);
1003
1004/*
1005** Returns the address of the most recently defined word in the system
1006** dictionary with the given name, or NULL if no match.
1007** Precondition: successful execution of ficlInitSystem
1008*/
925FICL_WORD *ficlLookup(char *name);
1009FICL_WORD *ficlLookup(FICL_SYSTEM *pSys, char *name);
926
927/*
928** f i c l G e t D i c t
929** Utility function - returns the address of the system dictionary.
930** Precondition: successful execution of ficlInitSystem
931*/
1010
1011/*
1012** f i c l G e t D i c t
1013** Utility function - returns the address of the system dictionary.
1014** Precondition: successful execution of ficlInitSystem
1015*/
932FICL_DICT *ficlGetDict(void);
933FICL_DICT *ficlGetEnv(void);
934void ficlSetEnv(char *name, FICL_UNS value);
935void ficlSetEnvD(char *name, FICL_UNS hi, FICL_UNS lo);
1016FICL_DICT *ficlGetDict(FICL_SYSTEM *pSys);
1017FICL_DICT *ficlGetEnv (FICL_SYSTEM *pSys);
1018void ficlSetEnv (FICL_SYSTEM *pSys, char *name, FICL_UNS value);
1019void ficlSetEnvD(FICL_SYSTEM *pSys, char *name, FICL_UNS hi, FICL_UNS lo);
936#if FICL_WANT_LOCALS
1020#if FICL_WANT_LOCALS
937FICL_DICT *ficlGetLoc(void);
1021FICL_DICT *ficlGetLoc (FICL_SYSTEM *pSys);
938#endif
939/*
940** f i c l B u i l d
941** Builds a word into the system default dictionary in a thread-safe way.
942** Preconditions: system must be initialized, and there must
943** be enough space for the new word's header! Operation is
944** controlled by ficlLockDictionary, so any initialization
945** required by your version of the function (if you "overrode"
946** it) must be complete at this point.
947** Parameters:
948** name -- the name of the word to be built
949** code -- code to execute when the word is invoked - must take a single param
950** pointer to a FICL_VM
951** flags -- 0 or more of FW_IMMEDIATE, FW_COMPILE, use bitwise OR!
952** Most words can use FW_DEFAULT.
953** nAllot - number of extra cells to allocate in the parameter area (usually zero)
954*/
1022#endif
1023/*
1024** f i c l B u i l d
1025** Builds a word into the system default dictionary in a thread-safe way.
1026** Preconditions: system must be initialized, and there must
1027** be enough space for the new word's header! Operation is
1028** controlled by ficlLockDictionary, so any initialization
1029** required by your version of the function (if you "overrode"
1030** it) must be complete at this point.
1031** Parameters:
1032** name -- the name of the word to be built
1033** code -- code to execute when the word is invoked - must take a single param
1034** pointer to a FICL_VM
1035** flags -- 0 or more of FW_IMMEDIATE, FW_COMPILE, use bitwise OR!
1036** Most words can use FW_DEFAULT.
1037** nAllot - number of extra cells to allocate in the parameter area (usually zero)
1038*/
955int ficlBuild(char *name, FICL_CODE code, char flags);
1039int ficlBuild(FICL_SYSTEM *pSys, char *name, FICL_CODE code, char flags);
956
957/*
958** f i c l C o m p i l e C o r e
959** Builds the ANS CORE wordset into the dictionary - called by
960** ficlInitSystem - no need to waste dict space by doing it again.
961*/
962void ficlCompileCore(FICL_SYSTEM *pSys);
963void ficlCompilePrefix(FICL_SYSTEM *pSys);
964void ficlCompileSearch(FICL_SYSTEM *pSys);
965void ficlCompileSoftCore(FICL_SYSTEM *pSys);
966void ficlCompileTools(FICL_SYSTEM *pSys);
1040
1041/*
1042** f i c l C o m p i l e C o r e
1043** Builds the ANS CORE wordset into the dictionary - called by
1044** ficlInitSystem - no need to waste dict space by doing it again.
1045*/
1046void ficlCompileCore(FICL_SYSTEM *pSys);
1047void ficlCompilePrefix(FICL_SYSTEM *pSys);
1048void ficlCompileSearch(FICL_SYSTEM *pSys);
1049void ficlCompileSoftCore(FICL_SYSTEM *pSys);
1050void ficlCompileTools(FICL_SYSTEM *pSys);
1051void ficlCompileFile(FICL_SYSTEM *pSys);
967#if FICL_WANT_FLOAT
968void ficlCompileFloat(FICL_SYSTEM *pSys);
1052#if FICL_WANT_FLOAT
1053void ficlCompileFloat(FICL_SYSTEM *pSys);
1054int ficlParseFloatNumber( FICL_VM *pVM, STRINGINFO si ); /* float.c */
969#endif
970#if FICL_PLATFORM_EXTEND
971void ficlCompilePlatform(FICL_SYSTEM *pSys);
972#endif
1055#endif
1056#if FICL_PLATFORM_EXTEND
1057void ficlCompilePlatform(FICL_SYSTEM *pSys);
1058#endif
1059int ficlParsePrefix(FICL_VM *pVM, STRINGINFO si);
973
974/*
975** from words.c...
976*/
977void constantParen(FICL_VM *pVM);
978void twoConstParen(FICL_VM *pVM);
979int ficlParseNumber(FICL_VM *pVM, STRINGINFO si);
980void ficlTick(FICL_VM *pVM);
981void parseStepParen(FICL_VM *pVM);
982
983/*
984** From tools.c
985*/
1060
1061/*
1062** from words.c...
1063*/
1064void constantParen(FICL_VM *pVM);
1065void twoConstParen(FICL_VM *pVM);
1066int ficlParseNumber(FICL_VM *pVM, STRINGINFO si);
1067void ficlTick(FICL_VM *pVM);
1068void parseStepParen(FICL_VM *pVM);
1069
1070/*
1071** From tools.c
1072*/
986int isAFiclWord(FICL_WORD *pFW);
1073int isAFiclWord(FICL_DICT *pd, FICL_WORD *pFW);
987
988/*
989** The following supports SEE and the debugger.
990*/
991typedef enum
992{
993 BRANCH,
994 COLON,
995 CONSTANT,
996 CREATE,
997 DO,
998 DOES,
999 IF,
1000 LITERAL,
1001 LOOP,
1002 PLOOP,
1003 PRIMITIVE,
1004 QDO,
1005 STRINGLIT,
1074
1075/*
1076** The following supports SEE and the debugger.
1077*/
1078typedef enum
1079{
1080 BRANCH,
1081 COLON,
1082 CONSTANT,
1083 CREATE,
1084 DO,
1085 DOES,
1086 IF,
1087 LITERAL,
1088 LOOP,
1089 PLOOP,
1090 PRIMITIVE,
1091 QDO,
1092 STRINGLIT,
1093 CSTRINGLIT,
1094#if FICL_WANT_USER
1006 USER,
1095 USER,
1096#endif
1007 VARIABLE,
1008} WORDKIND;
1097 VARIABLE,
1098} WORDKIND;
1099
1009WORDKIND ficlWordClassify(FICL_WORD *pFW);
1010
1011/*
1012** Dictionary on-demand resizing
1013*/
1014extern CELL dictThreshold;
1015extern CELL dictIncrease;
1016

--- 14 unchanged lines hidden (view full) ---

1031extern void ficlCopyin(FICL_VM *pVM);
1032extern void ficlCopyout(FICL_VM *pVM);
1033extern void ficlFindfile(FICL_VM *pVM);
1034extern void ficlPnpdevices(FICL_VM *pVM);
1035extern void ficlPnphandlers(FICL_VM *pVM);
1036extern void ficlCcall(FICL_VM *pVM);
1037#endif
1038
1100WORDKIND ficlWordClassify(FICL_WORD *pFW);
1101
1102/*
1103** Dictionary on-demand resizing
1104*/
1105extern CELL dictThreshold;
1106extern CELL dictIncrease;
1107

--- 14 unchanged lines hidden (view full) ---

1122extern void ficlCopyin(FICL_VM *pVM);
1123extern void ficlCopyout(FICL_VM *pVM);
1124extern void ficlFindfile(FICL_VM *pVM);
1125extern void ficlPnpdevices(FICL_VM *pVM);
1126extern void ficlPnphandlers(FICL_VM *pVM);
1127extern void ficlCcall(FICL_VM *pVM);
1128#endif
1129
1130/*
1131** Used with File-Access wordset.
1132*/
1133#define FICL_FAM_READ 1
1134#define FICL_FAM_WRITE 2
1135#define FICL_FAM_APPEND 4
1136#define FICL_FAM_BINARY 8
1137
1138#define FICL_FAM_OPEN_MODE(fam) ((fam) & (FICL_FAM_READ | FICL_FAM_WRITE | FICL_FAM_APPEND))
1139
1140
1141#if (FICL_WANT_FILE)
1142typedef struct ficlFILE
1143{
1144 FILE *f;
1145 char filename[256];
1146} ficlFILE;
1147#endif
1148
1039#ifdef __cplusplus
1040}
1041#endif
1042
1043#endif /* __FICL_H__ */
1149#ifdef __cplusplus
1150}
1151#endif
1152
1153#endif /* __FICL_H__ */