Deleted Added
full compact
ficl.c (76116) ficl.c (94290)
1/*******************************************************************
2** f i c l . c
3** Forth Inspired Command Language - external interface
4** Author: John Sadler (john_sadler@alum.mit.edu)
5** Created: 19 July 1997
1/*******************************************************************
2** f i c l . c
3** Forth Inspired Command Language - external interface
4** Author: John Sadler (john_sadler@alum.mit.edu)
5** Created: 19 July 1997
6** $Id: ficl.c,v 1.10 2001-04-26 21:41:42-07 jsadler Exp jsadler $
6** $Id: ficl.c,v 1.16 2001/12/05 07:21:34 jsadler Exp $
7*******************************************************************/
8/*
9** This is an ANS Forth interpreter written in C.
10** Ficl uses Forth syntax for its commands, but turns the Forth
11** model on its head in other respects.
12** Ficl provides facilities for interoperating
13** with programs written in C: C functions can be exported to Ficl,
14** and Ficl commands can be executed via a C calling interface. The

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

21** Code is written in ANSI C for portability.
22*/
23/*
24** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
25** All rights reserved.
26**
27** Get the latest Ficl release at http://ficl.sourceforge.net
28**
7*******************************************************************/
8/*
9** This is an ANS Forth interpreter written in C.
10** Ficl uses Forth syntax for its commands, but turns the Forth
11** model on its head in other respects.
12** Ficl provides facilities for interoperating
13** with programs written in C: C functions can be exported to Ficl,
14** and Ficl commands can be executed via a C calling interface. The

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

21** Code is written in ANSI C for portability.
22*/
23/*
24** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
25** All rights reserved.
26**
27** Get the latest Ficl release at http://ficl.sourceforge.net
28**
29** I am interested in hearing from anyone who uses ficl. If you have
30** a problem, a success story, a defect, an enhancement request, or
31** if you would like to contribute to the ficl release, please
32** contact me by email at the address above.
33**
29** L I C E N S E and D I S C L A I M E R
30**
31** Redistribution and use in source and binary forms, with or without
32** modification, are permitted provided that the following conditions
33** are met:
34** 1. Redistributions of source code must retain the above copyright
35** notice, this list of conditions and the following disclaimer.
36** 2. Redistributions in binary form must reproduce the above copyright

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

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

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

48** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55** SUCH DAMAGE.
51**
52** I am interested in hearing from anyone who uses ficl. If you have
53** a problem, a success story, a defect, an enhancement request, or
54** if you would like to contribute to the ficl release, please send
55** contact me by email at the address above.
56**
57** $Id: ficl.c,v 1.10 2001-04-26 21:41:42-07 jsadler Exp jsadler $
58*/
59
56*/
57
60/* $FreeBSD: head/sys/boot/ficl/ficl.c 76116 2001-04-29 02:36:36Z dcs $ */
58/* $FreeBSD: head/sys/boot/ficl/ficl.c 94290 2002-04-09 17:45:28Z dcs $ */
61
62#ifdef TESTMAIN
63#include <stdlib.h>
64#else
65#include <stand.h>
66#endif
67#include <string.h>
68#include "ficl.h"
69
70
71/*
72** System statics
59
60#ifdef TESTMAIN
61#include <stdlib.h>
62#else
63#include <stand.h>
64#endif
65#include <string.h>
66#include "ficl.h"
67
68
69/*
70** System statics
73** The system builds a global dictionary during its start
74** sequence. This is shared by all interpreter instances.
75** Therefore only one instance can update the dictionary
71** Each FICL_SYSTEM builds a global dictionary during its start
72** sequence. This is shared by all virtual machines of that system.
73** Therefore only one VM can update the dictionary
76** at a time. The system imports a locking function that
77** you can override in order to control update access to
78** the dictionary. The function is stubbed out by default,
79** but you can insert one: #define FICL_MULTITHREAD 1
80** and supply your own version of ficlLockDictionary.
81*/
74** at a time. The system imports a locking function that
75** you can override in order to control update access to
76** the dictionary. The function is stubbed out by default,
77** but you can insert one: #define FICL_MULTITHREAD 1
78** and supply your own version of ficlLockDictionary.
79*/
82static FICL_SYSTEM *pSys = NULL;
83
84static int defaultStack = FICL_DEFAULT_STACK;
80static int defaultStack = FICL_DEFAULT_STACK;
85static int defaultDict = FICL_DEFAULT_DICT;
86
87
81
82
83static void ficlSetVersionEnv(FICL_SYSTEM *pSys);
84
85
88/**************************************************************************
89 f i c l I n i t S y s t e m
90** Binds a global dictionary to the interpreter system.
91** You specify the address and size of the allocated area.
92** After that, ficl manages it.
93** First step is to set up the static pointers to the area.
94** Then write the "precompiled" portion of the dictionary in.
95** The dictionary needs to be at least large enough to hold the
96** precompiled part. Try 1K cells minimum. Use "words" to find
97** out how much of the dictionary is used at any time.
98**************************************************************************/
86/**************************************************************************
87 f i c l I n i t S y s t e m
88** Binds a global dictionary to the interpreter system.
89** You specify the address and size of the allocated area.
90** After that, ficl manages it.
91** First step is to set up the static pointers to the area.
92** Then write the "precompiled" portion of the dictionary in.
93** The dictionary needs to be at least large enough to hold the
94** precompiled part. Try 1K cells minimum. Use "words" to find
95** out how much of the dictionary is used at any time.
96**************************************************************************/
99void ficlInitSystem(int nDictCells)
97FICL_SYSTEM *ficlInitSystemEx(FICL_SYSTEM_INFO *fsi)
100{
98{
101 pSys = ficlMalloc(sizeof (FICL_SYSTEM));
99 int nDictCells;
100 int nEnvCells;
101 FICL_SYSTEM *pSys = ficlMalloc(sizeof (FICL_SYSTEM));
102
102 assert(pSys);
103 assert(pSys);
104 assert(fsi->size == sizeof (FICL_SYSTEM_INFO));
103
104 memset(pSys, 0, sizeof (FICL_SYSTEM));
105
105
106 memset(pSys, 0, sizeof (FICL_SYSTEM));
107
108 nDictCells = fsi->nDictCells;
106 if (nDictCells <= 0)
109 if (nDictCells <= 0)
107 nDictCells = defaultDict;
110 nDictCells = FICL_DEFAULT_DICT;
108
111
112 nEnvCells = fsi->nEnvCells;
113 if (nEnvCells <= 0)
114 nEnvCells = FICL_DEFAULT_DICT;
115
109 pSys->dp = dictCreateHashed((unsigned)nDictCells, HASHSIZE);
110 pSys->dp->pForthWords->name = "forth-wordlist";
111
116 pSys->dp = dictCreateHashed((unsigned)nDictCells, HASHSIZE);
117 pSys->dp->pForthWords->name = "forth-wordlist";
118
112 pSys->envp = dictCreate((unsigned)FICL_DEFAULT_ENV);
119 pSys->envp = dictCreate((unsigned)nEnvCells);
113 pSys->envp->pForthWords->name = "environment";
114
120 pSys->envp->pForthWords->name = "environment";
121
122 pSys->textOut = fsi->textOut;
123 pSys->pExtend = fsi->pExtend;
124
115#if FICL_WANT_LOCALS
116 /*
117 ** The locals dictionary is only searched while compiling,
118 ** but this is where speed is most important. On the other
119 ** hand, the dictionary gets emptied after each use of locals
125#if FICL_WANT_LOCALS
126 /*
127 ** The locals dictionary is only searched while compiling,
128 ** but this is where speed is most important. On the other
129 ** hand, the dictionary gets emptied after each use of locals
120 ** The need to balance search speed with the cost of the empty
130 ** The need to balance search speed with the cost of the 'empty'
121 ** operation led me to select a single-threaded list...
122 */
123 pSys->localp = dictCreate((unsigned)FICL_MAX_LOCALS * CELLS_PER_WORD);
124#endif
125
126 /*
131 ** operation led me to select a single-threaded list...
132 */
133 pSys->localp = dictCreate((unsigned)FICL_MAX_LOCALS * CELLS_PER_WORD);
134#endif
135
136 /*
127 ** Establish the parse order. Note that prefixes precede numbers -
128 ** this allows constructs like "0b101010" which would parse as a
129 ** valid hex value otherwise.
130 */
131 ficlCompilePrefix(pSys);
132 ficlAddPrecompiledParseStep(pSys, "number?", ficlParseNumber);
133
134 /*
135 ** Build the precompiled dictionary and load softwords. We need a temporary
136 ** VM to do this - ficlNewVM links one to the head of the system VM list.
137 ** ficlCompilePlatform (defined in win32.c, for example) adds platform specific words.
138 */
139 ficlCompileCore(pSys);
137 ** Build the precompiled dictionary and load softwords. We need a temporary
138 ** VM to do this - ficlNewVM links one to the head of the system VM list.
139 ** ficlCompilePlatform (defined in win32.c, for example) adds platform specific words.
140 */
141 ficlCompileCore(pSys);
142 ficlCompilePrefix(pSys);
140#if FICL_WANT_FLOAT
141 ficlCompileFloat(pSys);
142#endif
143#if FICL_WANT_FLOAT
144 ficlCompileFloat(pSys);
145#endif
143
144#if FICL_PLATFORM_EXTEND
145 ficlCompilePlatform(pSys);
146#endif
146#if FICL_PLATFORM_EXTEND
147 ficlCompilePlatform(pSys);
148#endif
149 ficlSetVersionEnv(pSys);
147
148 /*
150
151 /*
149 ** Now we can create a VM to compile the softwords. Note that the VM initialization
150 ** code needs to be able to find "interpret" in the dictionary in order to
151 ** succeed, so as presently constructed ficlCompileCore has to finish before
152 ** a VM can be created successfully.
152 ** Establish the parse order. Note that prefixes precede numbers -
153 ** this allows constructs like "0b101010" which might parse as a
154 ** hex value otherwise.
153 */
155 */
154 ficlNewVM();
156 ficlAddPrecompiledParseStep(pSys, "?prefix", ficlParsePrefix);
157 ficlAddPrecompiledParseStep(pSys, "?number", ficlParseNumber);
158#if FICL_WANT_FLOAT
159 ficlAddPrecompiledParseStep(pSys, ">float", ficlParseFloatNumber);
160#endif
161
162 /*
163 ** Now create a temporary VM to compile the softwords. Since all VMs are
164 ** linked into the vmList of FICL_SYSTEM, we don't have to pass the VM
165 ** to ficlCompileSoftCore -- it just hijacks whatever it finds in the VM list.
166 ** ficl 2.05: vmCreate no longer depends on the presence of INTERPRET in the
167 ** dictionary, so a VM can be created before the dictionary is built. It just
168 ** can't do much...
169 */
170 ficlNewVM(pSys);
155 ficlCompileSoftCore(pSys);
156 ficlFreeVM(pSys->vmList);
157
158
171 ficlCompileSoftCore(pSys);
172 ficlFreeVM(pSys->vmList);
173
174
159 return;
175 return pSys;
160}
161
162
176}
177
178
179FICL_SYSTEM *ficlInitSystem(int nDictCells)
180{
181 FICL_SYSTEM_INFO fsi;
182 ficlInitInfo(&fsi);
183 fsi.nDictCells = nDictCells;
184 return ficlInitSystemEx(&fsi);
185}
186
187
163/**************************************************************************
164 f i c l A d d P a r s e S t e p
165** Appends a parse step function to the end of the parse list (see
166** FICL_PARSE_STEP notes in ficl.h for details). Returns 0 if successful,
167** nonzero if there's no more room in the list.
168**************************************************************************/
169int ficlAddParseStep(FICL_SYSTEM *pSys, FICL_WORD *pFW)
170{

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

221}
222
223
224/**************************************************************************
225 f i c l N e w V M
226** Create a new virtual machine and link it into the system list
227** of VMs for later cleanup by ficlTermSystem.
228**************************************************************************/
188/**************************************************************************
189 f i c l A d d P a r s e S t e p
190** Appends a parse step function to the end of the parse list (see
191** FICL_PARSE_STEP notes in ficl.h for details). Returns 0 if successful,
192** nonzero if there's no more room in the list.
193**************************************************************************/
194int ficlAddParseStep(FICL_SYSTEM *pSys, FICL_WORD *pFW)
195{

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

246}
247
248
249/**************************************************************************
250 f i c l N e w V M
251** Create a new virtual machine and link it into the system list
252** of VMs for later cleanup by ficlTermSystem.
253**************************************************************************/
229FICL_VM *ficlNewVM(void)
254FICL_VM *ficlNewVM(FICL_SYSTEM *pSys)
230{
231 FICL_VM *pVM = vmCreate(NULL, defaultStack, defaultStack);
232 pVM->link = pSys->vmList;
233 pVM->pSys = pSys;
255{
256 FICL_VM *pVM = vmCreate(NULL, defaultStack, defaultStack);
257 pVM->link = pSys->vmList;
258 pVM->pSys = pSys;
259 pVM->pExtend = pSys->pExtend;
260 vmSetTextOut(pVM, pSys->textOut);
234
235 pSys->vmList = pVM;
236 return pVM;
237}
238
239
240/**************************************************************************
241 f i c l F r e e V M
242** Removes the VM in question from the system VM list and deletes the
243** memory allocated to it. This is an optional call, since ficlTermSystem
244** will do this cleanup for you. This function is handy if you're going to
245** do a lot of dynamic creation of VMs.
246**************************************************************************/
247void ficlFreeVM(FICL_VM *pVM)
248{
261
262 pSys->vmList = pVM;
263 return pVM;
264}
265
266
267/**************************************************************************
268 f i c l F r e e V M
269** Removes the VM in question from the system VM list and deletes the
270** memory allocated to it. This is an optional call, since ficlTermSystem
271** will do this cleanup for you. This function is handy if you're going to
272** do a lot of dynamic creation of VMs.
273**************************************************************************/
274void ficlFreeVM(FICL_VM *pVM)
275{
276 FICL_SYSTEM *pSys = pVM->pSys;
249 FICL_VM *pList = pSys->vmList;
250
251 assert(pVM != 0);
252
253 if (pSys->vmList == pVM)
254 {
255 pSys->vmList = pSys->vmList->link;
256 }

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

279** it) must be complete at this point.
280** Parameters:
281** name -- duh, the name of the word
282** code -- code to execute when the word is invoked - must take a single param
283** pointer to a FICL_VM
284** flags -- 0 or more of F_IMMEDIATE, F_COMPILE, use bitwise OR!
285**
286**************************************************************************/
277 FICL_VM *pList = pSys->vmList;
278
279 assert(pVM != 0);
280
281 if (pSys->vmList == pVM)
282 {
283 pSys->vmList = pSys->vmList->link;
284 }

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

307** it) must be complete at this point.
308** Parameters:
309** name -- duh, the name of the word
310** code -- code to execute when the word is invoked - must take a single param
311** pointer to a FICL_VM
312** flags -- 0 or more of F_IMMEDIATE, F_COMPILE, use bitwise OR!
313**
314**************************************************************************/
287int ficlBuild(char *name, FICL_CODE code, char flags)
315int ficlBuild(FICL_SYSTEM *pSys, char *name, FICL_CODE code, char flags)
288{
316{
317#if FICL_MULTITHREAD
289 int err = ficlLockDictionary(TRUE);
290 if (err) return err;
318 int err = ficlLockDictionary(TRUE);
319 if (err) return err;
320#endif /* FICL_MULTITHREAD */
291
292 assert(dictCellsAvail(pSys->dp) > sizeof (FICL_WORD) / sizeof (CELL));
293 dictAppendWord(pSys->dp, name, code, flags);
294
295 ficlLockDictionary(FALSE);
296 return 0;
297}
298
299
300/**************************************************************************
321
322 assert(dictCellsAvail(pSys->dp) > sizeof (FICL_WORD) / sizeof (CELL));
323 dictAppendWord(pSys->dp, name, code, flags);
324
325 ficlLockDictionary(FALSE);
326 return 0;
327}
328
329
330/**************************************************************************
331 f i c l E v a l u a t e
332** Wrapper for ficlExec() which sets SOURCE-ID to -1.
333**************************************************************************/
334int ficlEvaluate(FICL_VM *pVM, char *pText)
335{
336 int returnValue;
337 CELL id = pVM->sourceID;
338 pVM->sourceID.i = -1;
339 returnValue = ficlExecC(pVM, pText, -1);
340 pVM->sourceID = id;
341 return returnValue;
342}
343
344
345/**************************************************************************
301 f i c l E x e c
302** Evaluates a block of input text in the context of the
303** specified interpreter. Emits any requested output to the
304** interpreter's output function.
305**
306** Contains the "inner interpreter" code in a tight loop
307**
308** Returns one of the VM_XXXX codes defined in ficl.h:

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

317**************************************************************************/
318int ficlExec(FICL_VM *pVM, char *pText)
319{
320 return ficlExecC(pVM, pText, -1);
321}
322
323int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT size)
324{
346 f i c l E x e c
347** Evaluates a block of input text in the context of the
348** specified interpreter. Emits any requested output to the
349** interpreter's output function.
350**
351** Contains the "inner interpreter" code in a tight loop
352**
353** Returns one of the VM_XXXX codes defined in ficl.h:

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

362**************************************************************************/
363int ficlExec(FICL_VM *pVM, char *pText)
364{
365 return ficlExecC(pVM, pText, -1);
366}
367
368int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT size)
369{
325 FICL_WORD **pInterp = pSys->pInterp;
326 FICL_DICT *dp = pSys->dp;
370 FICL_SYSTEM *pSys = pVM->pSys;
371 FICL_DICT *dp = pSys->dp;
327
328 int except;
329 jmp_buf vmState;
330 jmp_buf *oldState;
331 TIB saveTib;
332
372
373 int except;
374 jmp_buf vmState;
375 jmp_buf *oldState;
376 TIB saveTib;
377
333 if (!pInterp[0])
334 {
335 pInterp[0] = ficlLookup("interpret");
336 pInterp[1] = ficlLookup("(branch)");
337 pInterp[2] = (FICL_WORD *)(void *)(-2);
338 }
339
340 assert(pInterp[0]);
341 assert(pVM);
378 assert(pVM);
379 assert(pSys->pInterp[0]);
342
343 if (size < 0)
344 size = strlen(pText);
345
346 vmPushTib(pVM, pText, size, &saveTib);
347
348 /*
349 ** Save and restore VM's jmp_buf to enable nested calls to ficlExec

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

357 case 0:
358 if (pVM->fRestart)
359 {
360 pVM->runningWord->code(pVM);
361 pVM->fRestart = 0;
362 }
363 else
364 { /* set VM up to interpret text */
380
381 if (size < 0)
382 size = strlen(pText);
383
384 vmPushTib(pVM, pText, size, &saveTib);
385
386 /*
387 ** Save and restore VM's jmp_buf to enable nested calls to ficlExec

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

395 case 0:
396 if (pVM->fRestart)
397 {
398 pVM->runningWord->code(pVM);
399 pVM->fRestart = 0;
400 }
401 else
402 { /* set VM up to interpret text */
365 vmPushIP(pVM, &pInterp[0]);
403 vmPushIP(pVM, &(pSys->pInterp[0]));
366 }
367
368 vmInnerLoop(pVM);
369 break;
370
371 case VM_RESTART:
372 pVM->fRestart = 1;
373 except = VM_OUTOFTEXT;

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

433** exit the loop, this function will re-throw it if it's nested under
434** itself or ficlExec.
435**
436** NOTE: this function is intended so that C code can execute ficlWords
437** given their address in the dictionary (xt).
438**************************************************************************/
439int ficlExecXT(FICL_VM *pVM, FICL_WORD *pWord)
440{
404 }
405
406 vmInnerLoop(pVM);
407 break;
408
409 case VM_RESTART:
410 pVM->fRestart = 1;
411 except = VM_OUTOFTEXT;

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

471** exit the loop, this function will re-throw it if it's nested under
472** itself or ficlExec.
473**
474** NOTE: this function is intended so that C code can execute ficlWords
475** given their address in the dictionary (xt).
476**************************************************************************/
477int ficlExecXT(FICL_VM *pVM, FICL_WORD *pWord)
478{
441 static FICL_WORD *pQuit = NULL;
442 int except;
443 jmp_buf vmState;
444 jmp_buf *oldState;
445 FICL_WORD *oldRunningWord;
446
479 int except;
480 jmp_buf vmState;
481 jmp_buf *oldState;
482 FICL_WORD *oldRunningWord;
483
447 if (!pQuit)
448 pQuit = ficlLookup("exit-inner");
449
450 assert(pVM);
484 assert(pVM);
451 assert(pQuit);
485 assert(pVM->pSys->pExitInner);
452
453 /*
454 ** Save the runningword so that RESTART behaves correctly
455 ** over nested calls.
456 */
457 oldRunningWord = pVM->runningWord;
458 /*
459 ** Save and restore VM's jmp_buf to enable nested calls
460 */
461 oldState = pVM->pState;
462 pVM->pState = &vmState; /* This has to come before the setjmp! */
463 except = setjmp(vmState);
464
465 if (except)
466 vmPopIP(pVM);
467 else
486
487 /*
488 ** Save the runningword so that RESTART behaves correctly
489 ** over nested calls.
490 */
491 oldRunningWord = pVM->runningWord;
492 /*
493 ** Save and restore VM's jmp_buf to enable nested calls
494 */
495 oldState = pVM->pState;
496 pVM->pState = &vmState; /* This has to come before the setjmp! */
497 except = setjmp(vmState);
498
499 if (except)
500 vmPopIP(pVM);
501 else
468 vmPushIP(pVM, &pQuit);
502 vmPushIP(pVM, &(pVM->pSys->pExitInner));
469
470 switch (except)
471 {
472 case 0:
473 vmExecute(pVM, pWord);
474 vmInnerLoop(pVM);
475 break;
476

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

501
502
503/**************************************************************************
504 f i c l L o o k u p
505** Look in the system dictionary for a match to the given name. If
506** found, return the address of the corresponding FICL_WORD. Otherwise
507** return NULL.
508**************************************************************************/
503
504 switch (except)
505 {
506 case 0:
507 vmExecute(pVM, pWord);
508 vmInnerLoop(pVM);
509 break;
510

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

535
536
537/**************************************************************************
538 f i c l L o o k u p
539** Look in the system dictionary for a match to the given name. If
540** found, return the address of the corresponding FICL_WORD. Otherwise
541** return NULL.
542**************************************************************************/
509FICL_WORD *ficlLookup(char *name)
543FICL_WORD *ficlLookup(FICL_SYSTEM *pSys, char *name)
510{
511 STRINGINFO si;
512 SI_PSZ(si, name);
513 return dictLookup(pSys->dp, si);
514}
515
516
517/**************************************************************************
518 f i c l G e t D i c t
519** Returns the address of the system dictionary
520**************************************************************************/
544{
545 STRINGINFO si;
546 SI_PSZ(si, name);
547 return dictLookup(pSys->dp, si);
548}
549
550
551/**************************************************************************
552 f i c l G e t D i c t
553** Returns the address of the system dictionary
554**************************************************************************/
521FICL_DICT *ficlGetDict(void)
555FICL_DICT *ficlGetDict(FICL_SYSTEM *pSys)
522{
523 return pSys->dp;
524}
525
526
527/**************************************************************************
528 f i c l G e t E n v
529** Returns the address of the system environment space
530**************************************************************************/
556{
557 return pSys->dp;
558}
559
560
561/**************************************************************************
562 f i c l G e t E n v
563** Returns the address of the system environment space
564**************************************************************************/
531FICL_DICT *ficlGetEnv(void)
565FICL_DICT *ficlGetEnv(FICL_SYSTEM *pSys)
532{
533 return pSys->envp;
534}
535
536
537/**************************************************************************
538 f i c l S e t E n v
539** Create an environment variable with a one-CELL payload. ficlSetEnvD
540** makes one with a two-CELL payload.
541**************************************************************************/
566{
567 return pSys->envp;
568}
569
570
571/**************************************************************************
572 f i c l S e t E n v
573** Create an environment variable with a one-CELL payload. ficlSetEnvD
574** makes one with a two-CELL payload.
575**************************************************************************/
542void ficlSetEnv(char *name, FICL_UNS value)
576void ficlSetEnv(FICL_SYSTEM *pSys, char *name, FICL_UNS value)
543{
544 STRINGINFO si;
545 FICL_WORD *pFW;
546 FICL_DICT *envp = pSys->envp;
547
548 SI_PSZ(si, name);
549 pFW = dictLookup(envp, si);
550

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

556 else
557 {
558 pFW->param[0] = LVALUEtoCELL(value);
559 }
560
561 return;
562}
563
577{
578 STRINGINFO si;
579 FICL_WORD *pFW;
580 FICL_DICT *envp = pSys->envp;
581
582 SI_PSZ(si, name);
583 pFW = dictLookup(envp, si);
584

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

590 else
591 {
592 pFW->param[0] = LVALUEtoCELL(value);
593 }
594
595 return;
596}
597
564void ficlSetEnvD(char *name, FICL_UNS hi, FICL_UNS lo)
598void ficlSetEnvD(FICL_SYSTEM *pSys, char *name, FICL_UNS hi, FICL_UNS lo)
565{
566 FICL_WORD *pFW;
567 STRINGINFO si;
568 FICL_DICT *envp = pSys->envp;
569 SI_PSZ(si, name);
570 pFW = dictLookup(envp, si);
571
572 if (pFW == NULL)

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

586
587
588/**************************************************************************
589 f i c l G e t L o c
590** Returns the address of the system locals dictionary. This dict is
591** only used during compilation, and is shared by all VMs.
592**************************************************************************/
593#if FICL_WANT_LOCALS
599{
600 FICL_WORD *pFW;
601 STRINGINFO si;
602 FICL_DICT *envp = pSys->envp;
603 SI_PSZ(si, name);
604 pFW = dictLookup(envp, si);
605
606 if (pFW == NULL)

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

620
621
622/**************************************************************************
623 f i c l G e t L o c
624** Returns the address of the system locals dictionary. This dict is
625** only used during compilation, and is shared by all VMs.
626**************************************************************************/
627#if FICL_WANT_LOCALS
594FICL_DICT *ficlGetLoc(void)
628FICL_DICT *ficlGetLoc(FICL_SYSTEM *pSys)
595{
596 return pSys->localp;
597}
598#endif
599
600
601
602/**************************************************************************

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

615}
616
617
618/**************************************************************************
619 f i c l T e r m S y s t e m
620** Tear the system down by deleting the dictionaries and all VMs.
621** This saves you from having to keep track of all that stuff.
622**************************************************************************/
629{
630 return pSys->localp;
631}
632#endif
633
634
635
636/**************************************************************************

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

649}
650
651
652/**************************************************************************
653 f i c l T e r m S y s t e m
654** Tear the system down by deleting the dictionaries and all VMs.
655** This saves you from having to keep track of all that stuff.
656**************************************************************************/
623void ficlTermSystem(void)
657void ficlTermSystem(FICL_SYSTEM *pSys)
624{
625 if (pSys->dp)
626 dictDelete(pSys->dp);
627 pSys->dp = NULL;
628
629 if (pSys->envp)
630 dictDelete(pSys->envp);
631 pSys->envp = NULL;

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

644 }
645
646 ficlFree(pSys);
647 pSys = NULL;
648 return;
649}
650
651
658{
659 if (pSys->dp)
660 dictDelete(pSys->dp);
661 pSys->dp = NULL;
662
663 if (pSys->envp)
664 dictDelete(pSys->envp);
665 pSys->envp = NULL;

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

678 }
679
680 ficlFree(pSys);
681 pSys = NULL;
682 return;
683}
684
685
686/**************************************************************************
687 f i c l S e t V e r s i o n E n v
688** Create a double cell environment constant for the version ID
689**************************************************************************/
690static void ficlSetVersionEnv(FICL_SYSTEM *pSys)
691{
692 ficlSetEnvD(pSys, "ficl-version", FICL_VER_MAJOR, FICL_VER_MINOR);
693 ficlSetEnv (pSys, "ficl-robust", FICL_ROBUST);
694 return;
695}
696