The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/boot/ficl/ficl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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.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
   15 ** interpreter is re-entrant, so it can be used in multiple instances
   16 ** in a multitasking system. Unlike Forth, Ficl's outer interpreter
   17 ** expects a text block as input, and returns to the caller after each
   18 ** text block, so the data pump is somewhere in external code in the 
   19 ** style of TCL.
   20 **
   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 **
   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
   42 **    notice, this list of conditions and the following disclaimer in the
   43 **    documentation and/or other materials provided with the distribution.
   44 **
   45 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   46 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   47 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   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.
   56 */
   57 
   58 /* $FreeBSD$ */
   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
   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
   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 */
   80 static int defaultStack = FICL_DEFAULT_STACK;
   81 
   82 
   83 static void ficlSetVersionEnv(FICL_SYSTEM *pSys);
   84 
   85 
   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 **************************************************************************/
   97 FICL_SYSTEM *ficlInitSystemEx(FICL_SYSTEM_INFO *fsi)
   98 {
   99     int nDictCells;
  100     int nEnvCells;
  101     FICL_SYSTEM *pSys = ficlMalloc(sizeof (FICL_SYSTEM));
  102 
  103     assert(pSys);
  104     assert(fsi->size == sizeof (FICL_SYSTEM_INFO));
  105 
  106     memset(pSys, 0, sizeof (FICL_SYSTEM));
  107 
  108     nDictCells = fsi->nDictCells;
  109     if (nDictCells <= 0)
  110         nDictCells = FICL_DEFAULT_DICT;
  111 
  112     nEnvCells = fsi->nEnvCells;
  113     if (nEnvCells <= 0)
  114         nEnvCells = FICL_DEFAULT_DICT;
  115 
  116     pSys->dp = dictCreateHashed((unsigned)nDictCells, HASHSIZE);
  117     pSys->dp->pForthWords->name = "forth-wordlist";
  118 
  119     pSys->envp = dictCreate((unsigned)nEnvCells);
  120     pSys->envp->pForthWords->name = "environment";
  121 
  122     pSys->textOut = fsi->textOut;
  123     pSys->pExtend = fsi->pExtend;
  124 
  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
  130     ** The need to balance search speed with the cost of the 'empty'
  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     /*
  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);
  143 #if FICL_WANT_FLOAT
  144     ficlCompileFloat(pSys);
  145 #endif
  146 #if FICL_PLATFORM_EXTEND
  147     ficlCompilePlatform(pSys);
  148 #endif
  149     ficlSetVersionEnv(pSys);
  150 
  151     /*
  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.
  155     */
  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);
  171     ficlCompileSoftCore(pSys);
  172     ficlFreeVM(pSys->vmList);
  173 
  174 
  175     return pSys;
  176 }
  177 
  178 
  179 FICL_SYSTEM *ficlInitSystem(int nDictCells)
  180 {
  181     FICL_SYSTEM_INFO fsi;
  182     ficlInitInfo(&fsi);
  183     fsi.nDictCells = nDictCells;
  184     return ficlInitSystemEx(&fsi);
  185 }
  186 
  187 
  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 **************************************************************************/
  194 int ficlAddParseStep(FICL_SYSTEM *pSys, FICL_WORD *pFW)
  195 {
  196     int i;
  197     for (i = 0; i < FICL_MAX_PARSE_STEPS; i++)
  198     {
  199         if (pSys->parseList[i] == NULL)
  200         {
  201             pSys->parseList[i] = pFW;
  202             return 0;
  203         }
  204     }
  205 
  206     return 1;
  207 }
  208 
  209 
  210 /*
  211 ** Compile a word into the dictionary that invokes the specified FICL_PARSE_STEP
  212 ** function. It is up to the user (as usual in Forth) to make sure the stack 
  213 ** preconditions are valid (there needs to be a counted string on top of the stack)
  214 ** before using the resulting word.
  215 */
  216 void ficlAddPrecompiledParseStep(FICL_SYSTEM *pSys, char *name, FICL_PARSE_STEP pStep)
  217 {
  218     FICL_DICT *dp = pSys->dp;
  219     FICL_WORD *pFW = dictAppendWord(dp, name, parseStepParen, FW_DEFAULT);
  220     dictAppendCell(dp, LVALUEtoCELL(pStep));
  221     ficlAddParseStep(pSys, pFW);
  222 }
  223 
  224 
  225 /*
  226 ** This word lists the parse steps in order
  227 */
  228 void ficlListParseSteps(FICL_VM *pVM)
  229 {
  230     int i;
  231     FICL_SYSTEM *pSys = pVM->pSys;
  232     assert(pSys);
  233 
  234     vmTextOut(pVM, "Parse steps:", 1);
  235     vmTextOut(pVM, "lookup", 1);
  236 
  237     for (i = 0; i < FICL_MAX_PARSE_STEPS; i++)
  238     {
  239         if (pSys->parseList[i] != NULL)
  240         {
  241             vmTextOut(pVM, pSys->parseList[i]->name, 1);
  242         }
  243         else break;
  244     }
  245     return;
  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 **************************************************************************/
  254 FICL_VM *ficlNewVM(FICL_SYSTEM *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);
  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 **************************************************************************/
  274 void ficlFreeVM(FICL_VM *pVM)
  275 {
  276     FICL_SYSTEM *pSys = pVM->pSys;
  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     }
  285     else for (; pList != NULL; pList = pList->link)
  286     {
  287         if (pList->link == pVM)
  288         {
  289             pList->link = pVM->link;
  290             break;
  291         }
  292     }
  293 
  294     if (pList)
  295         vmDelete(pVM);
  296     return;
  297 }
  298 
  299 
  300 /**************************************************************************
  301                         f i c l B u i l d
  302 ** Builds a word into the dictionary.
  303 ** Preconditions: system must be initialized, and there must
  304 ** be enough space for the new word's header! Operation is
  305 ** controlled by ficlLockDictionary, so any initialization
  306 ** required by your version of the function (if you overrode
  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 **************************************************************************/
  315 int ficlBuild(FICL_SYSTEM *pSys, char *name, FICL_CODE code, char flags)
  316 {
  317 #if FICL_MULTITHREAD
  318     int err = ficlLockDictionary(TRUE);
  319     if (err) return err;
  320 #endif /* FICL_MULTITHREAD */
  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 **************************************************************************/
  334 int 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 /**************************************************************************
  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:
  354 ** VM_OUTOFTEXT is the normal exit condition
  355 ** VM_ERREXIT means that the interp encountered a syntax error
  356 **      and the vm has been reset to recover (some or all
  357 **      of the text block got ignored
  358 ** VM_USEREXIT means that the user executed the "bye" command
  359 **      to shut down the interpreter. This would be a good
  360 **      time to delete the vm, etc -- or you can ignore this
  361 **      signal.
  362 **************************************************************************/
  363 int ficlExec(FICL_VM *pVM, char *pText)
  364 {
  365     return ficlExecC(pVM, pText, -1);
  366 }
  367 
  368 int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT size)
  369 {
  370     FICL_SYSTEM *pSys = pVM->pSys;
  371     FICL_DICT   *dp   = pSys->dp;
  372 
  373     int        except;
  374     jmp_buf    vmState;
  375     jmp_buf   *oldState;
  376     TIB        saveTib;
  377 
  378     assert(pVM);
  379     assert(pSys->pInterp[0]);
  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 
  388     */
  389     oldState = pVM->pState;
  390     pVM->pState = &vmState; /* This has to come before the setjmp! */
  391     except = setjmp(vmState);
  392 
  393     switch (except)
  394     {
  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 */
  403             vmPushIP(pVM, &(pSys->pInterp[0]));
  404         }
  405 
  406         vmInnerLoop(pVM);
  407         break;
  408 
  409     case VM_RESTART:
  410         pVM->fRestart = 1;
  411         except = VM_OUTOFTEXT;
  412         break;
  413 
  414     case VM_OUTOFTEXT:
  415         vmPopIP(pVM);
  416 #ifdef TESTMAIN
  417         if ((pVM->state != COMPILE) && (pVM->sourceID.i == 0))
  418             ficlTextOut(pVM, FICL_PROMPT, 0);
  419 #endif
  420         break;
  421 
  422     case VM_USEREXIT:
  423     case VM_INNEREXIT:
  424     case VM_BREAK:
  425         break;
  426 
  427     case VM_QUIT:
  428         if (pVM->state == COMPILE)
  429         {
  430             dictAbortDefinition(dp);
  431 #if FICL_WANT_LOCALS
  432             dictEmpty(pSys->localp, pSys->localp->pForthWords->size);
  433 #endif
  434         }
  435         vmQuit(pVM);
  436         break;
  437 
  438     case VM_ERREXIT:
  439     case VM_ABORT:
  440     case VM_ABORTQ:
  441     default:    /* user defined exit code?? */
  442         if (pVM->state == COMPILE)
  443         {
  444             dictAbortDefinition(dp);
  445 #if FICL_WANT_LOCALS
  446             dictEmpty(pSys->localp, pSys->localp->pForthWords->size);
  447 #endif
  448         }
  449         dictResetSearchOrder(dp);
  450         vmReset(pVM);
  451         break;
  452    }
  453 
  454     pVM->pState    = oldState;
  455     vmPopTib(pVM, &saveTib);
  456     return (except);
  457 }
  458 
  459 
  460 /**************************************************************************
  461                         f i c l E x e c X T
  462 ** Given a pointer to a FICL_WORD, push an inner interpreter and
  463 ** execute the word to completion. This is in contrast with vmExecute,
  464 ** which does not guarantee that the word will have completed when
  465 ** the function returns (ie in the case of colon definitions, which
  466 ** need an inner interpreter to finish)
  467 **
  468 ** Returns one of the VM_XXXX exception codes listed in ficl.h. Normal
  469 ** exit condition is VM_INNEREXIT, ficl's private signal to exit the
  470 ** inner loop under normal circumstances. If another code is thrown to
  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 **************************************************************************/
  477 int ficlExecXT(FICL_VM *pVM, FICL_WORD *pWord)
  478 {
  479     int        except;
  480     jmp_buf    vmState;
  481     jmp_buf   *oldState;
  482     FICL_WORD *oldRunningWord;
  483 
  484     assert(pVM);
  485     assert(pVM->pSys->pExitInner);
  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
  502         vmPushIP(pVM, &(pVM->pSys->pExitInner));
  503 
  504     switch (except)
  505     {
  506     case 0:
  507         vmExecute(pVM, pWord);
  508         vmInnerLoop(pVM);
  509         break;
  510 
  511     case VM_INNEREXIT:
  512     case VM_BREAK:
  513         break;
  514 
  515     case VM_RESTART:
  516     case VM_OUTOFTEXT:
  517     case VM_USEREXIT:
  518     case VM_QUIT:
  519     case VM_ERREXIT:
  520     case VM_ABORT:
  521     case VM_ABORTQ:
  522     default:    /* user defined exit code?? */
  523         if (oldState)
  524         {
  525             pVM->pState = oldState;
  526             vmThrow(pVM, except);
  527         }
  528         break;
  529     }
  530 
  531     pVM->pState    = oldState;
  532     pVM->runningWord = oldRunningWord;
  533     return (except);
  534 }
  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 **************************************************************************/
  543 FICL_WORD *ficlLookup(FICL_SYSTEM *pSys, char *name)
  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 **************************************************************************/
  555 FICL_DICT *ficlGetDict(FICL_SYSTEM *pSys)
  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 **************************************************************************/
  565 FICL_DICT *ficlGetEnv(FICL_SYSTEM *pSys)
  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 **************************************************************************/
  576 void ficlSetEnv(FICL_SYSTEM *pSys, char *name, FICL_UNS value)
  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 
  585     if (pFW == NULL)
  586     {
  587         dictAppendWord(envp, name, constantParen, FW_DEFAULT);
  588         dictAppendCell(envp, LVALUEtoCELL(value));
  589     }
  590     else
  591     {
  592         pFW->param[0] = LVALUEtoCELL(value);
  593     }
  594 
  595     return;
  596 }
  597 
  598 void ficlSetEnvD(FICL_SYSTEM *pSys, char *name, FICL_UNS hi, FICL_UNS lo)
  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)
  607     {
  608         dictAppendWord(envp, name, twoConstParen, FW_DEFAULT);
  609         dictAppendCell(envp, LVALUEtoCELL(lo));
  610         dictAppendCell(envp, LVALUEtoCELL(hi));
  611     }
  612     else
  613     {
  614         pFW->param[0] = LVALUEtoCELL(lo);
  615         pFW->param[1] = LVALUEtoCELL(hi);
  616     }
  617 
  618     return;
  619 }
  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
  628 FICL_DICT *ficlGetLoc(FICL_SYSTEM *pSys)
  629 {
  630     return pSys->localp;
  631 }
  632 #endif
  633 
  634 
  635 
  636 /**************************************************************************
  637                         f i c l S e t S t a c k S i z e
  638 ** Set the stack sizes (return and parameter) to be used for all
  639 ** subsequently created VMs. Returns actual stack size to be used.
  640 **************************************************************************/
  641 int ficlSetStackSize(int nStackCells)
  642 {
  643     if (nStackCells >= FICL_DEFAULT_STACK)
  644         defaultStack = nStackCells;
  645     else
  646         defaultStack = FICL_DEFAULT_STACK;
  647 
  648     return defaultStack;
  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 **************************************************************************/
  657 void ficlTermSystem(FICL_SYSTEM *pSys)
  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;
  666 
  667 #if FICL_WANT_LOCALS
  668     if (pSys->localp)
  669         dictDelete(pSys->localp);
  670     pSys->localp = NULL;
  671 #endif
  672 
  673     while (pSys->vmList != NULL)
  674     {
  675         FICL_VM *pVM = pSys->vmList;
  676         pSys->vmList = pSys->vmList->link;
  677         vmDelete(pVM);
  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 **************************************************************************/
  690 static 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 

Cache object: 57bed8ce97241d0e98f5011ba176d3b3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.