LTP GCOV extension - code coverage report
Current view: directory - fcode-utils/toke - dictionary.c
Test: toke.info
Date: 2006-08-18 Instrumented lines: 146
Code covered: 87.7 % Executed lines: 128

       1                 : /*
       2                 :  *                     OpenBIOS - free your system!
       3                 :  *                         ( FCode tokenizer )
       4                 :  *
       5                 :  *  dictionary.c - dictionary initialization and functions.
       6                 :  *
       7                 :  *  This program is part of a free implementation of the IEEE 1275-1994
       8                 :  *  Standard for Boot (Initialization Configuration) Firmware.
       9                 :  *
      10                 :  *  Copyright (C) 2001-2005 Stefan Reinauer, <stepan@openbios.org>
      11                 :  *
      12                 :  *  This program is free software; you can redistribute it and/or modify
      13                 :  *  it under the terms of the GNU General Public License as published by
      14                 :  *  the Free Software Foundation; version 2 of the License.
      15                 :  *
      16                 :  *  This program is distributed in the hope that it will be useful,
      17                 :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :  *  GNU General Public License for more details.
      20                 :  *
      21                 :  *  You should have received a copy of the GNU General Public License
      22                 :  *  along with this program; if not, write to the Free Software
      23                 :  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
      24                 :  *
      25                 :  */
      26                 : 
      27                 : /* **************************************************************************
      28                 :  *         Modifications made in 2005 by IBM Corporation
      29                 :  *      (C) Copyright 2005 IBM Corporation.  All Rights Reserved.
      30                 :  *      Modifications Author:  David L. Paktor    dlpaktor@us.ibm.com
      31                 :  **************************************************************************** */
      32                 : 
      33                 : #include <stdio.h>
      34                 : #include <stdlib.h>
      35                 : #if defined(__linux__) && ! defined(__USE_BSD)
      36                 : #define __USE_BSD
      37                 : #endif
      38                 : #include <string.h>
      39                 : #include <errno.h>
      40                 : 
      41                 : #include "emit.h"
      42                 : #include "macros.h"
      43                 : #include "scanner.h"
      44                 : #include "ticvocab.h"
      45                 : #include "dictionary.h"
      46                 : #include "vocabfuncts.h"
      47                 : #include "devnode.h"
      48                 : #include "clflags.h"
      49                 : #include "parselocals.h"
      50                 : #include "errhandler.h"
      51                 : #include "tokzesc.h"
      52                 : #include "conditl.h"
      53                 : 
      54                 : /* **************************************************************************
      55                 :  *
      56                 :  *      Revision History:
      57                 :  *          Updated Fri, 29 Jul 2005 by David L. Paktor
      58                 :  *          Retrofit to handle "Current Device" as a separate vocabulary;
      59                 :  *              if one is in effect, searches through it occur first, as
      60                 :  *              do definitions to it, ahead of the general vocabulary.  This
      61                 :  *              is to support managing device-node vocabularies correctly.
      62                 :  *          Updated Mon, 12 Dec 2005 by David L. Paktor
      63                 :  *          Allow the user to specify a group of exceptions, words whose
      64                 :  *              scope will be "global" within the tokenization.  Under "global"
      65                 :  *              scope, definitions will be made to the "core" vocabulary.
      66                 :  *
      67                 :  *          Wed, 14 Dec 2005 by David L. Paktor
      68                 :  *          Found a problem with the current approach.  Need to be able to
      69                 :  *              temporarily suspend meaning of "instance".  Define:  (1) an
      70                 :  *              alias for  INSTANCE  called  GENERIC_INSTANCE  (2) a macro
      71                 :  *              called  INSTANCE  that effectively no-ops it out; and, when
      72                 :  *              it is time to restore "INSTANCE" to normal functionality,
      73                 :  *              (3) an alias for  GENERIC_INSTANCE  called  INSTANCE .
      74                 :  *          Problem is that macros are treated as a separate vocabulary
      75                 :  *              from FWords (and their aliases) and searching one before the
      76                 :  *              other (either way) renders the second one searched unable to
      77                 :  *              supercede the first one:  If macros are searched first, (2)
      78                 :  *              will be found ahead of the built-in FWord (which is what we
      79                 :  *              want) but later, when we search for (3) among the FWords, it
      80                 :  *              will not be found ahead of (2).  If, on the other hand, we
      81                 :  *              search FWords first, the macro defined in (2) will never be
      82                 :  *              found.
      83                 :  *          We need a way to define both (all?) types of definitions in a
      84                 :  *              single vocabulary that will honor the LIFO order of def'ns.
      85                 :  *
      86                 :  *          Mon, 19 Dec 2005 by David L. Paktor
      87                 :  *          Begin development of implementation of a way to define both (all?)
      88                 :  *              types of definitions in a single  tic_hdr_t  type vocabulary.
      89                 :  *
      90                 :  **************************************************************************** */
      91                 : 
      92                 : 
      93                 : 
      94                 : /* **************************************************************************
      95                 :  *
      96                 :  *      We will be creating several different lists of initial built-in
      97                 :  *          definitions; together, they constitute the Global Vocabulary.
      98                 :  *          (We will avoid the term "dictionary", since, in classical
      99                 :  *          Forth terminology, it refers to the complete collection of
     100                 :  *          vocabularies in an application.)  The usage of the pointer
     101                 :  *          to the Global Vocabulary is central to the operation of this
     102                 :  *          program and the maintenance programmer needs to understand it.
     103                 :  *          We may also refer to the Global Vocabulary as the "core" vocab.
     104                 :  *
     105                 :  *      Each initial list will be created as an array of TIC-header entries.
     106                 :  *          Because the global vocabulary is expandable by the user,
     107                 :  *          we will not be searching the lists as arrays but rather as
     108                 :  *          linked-lists; the run-time initialization routine will fill
     109                 :  *          in their link-fields and also will link the various lists
     110                 :  *          together, so we can group their initial declarations according
     111                 :  *          to our convenience.
     112                 :  *
     113                 :  *      A single pointer, called the "Global Vocabulary Dictionary Pointer"
     114                 :  *          (okay, so classical Forth terminology isn't completely rigorous...)
     115                 :  *          and abbreviated GV_DP, will point to the "tail" of the "thread".
     116                 :  *          Similar vocabularies will be created for the device-nodes; look
     117                 :  *          in the file  devnode.fth  for a more detailed discussion of those.
     118                 :  *
     119                 :  *      The "FC-Tokens" list contains the names and FCode numeric tokens
     120                 :  *          of the straightforward FORTH words that simply write a token
     121                 :  *          directly to the tokenized output.  We need to access these
     122                 :  *          without being confused by aliases or other distractions, so
     123                 :  *          we will keep a pointer to them especially for that purpose.
     124                 :  *      Therefore it is IMPORTANT:  that the "FC-Tokens" list MUST be the
     125                 :  *          first table linked by the initialization routine, so that its
     126                 :  *          last-searched entry's link-field is NULL.
     127                 :  *
     128                 :  *      The "FWords" list contains FORTH words that require additional
     129                 :  *          special action at tokenization-time.  Their numeric values
     130                 :  *          are derived from the  fword_token  enumeration declaration,
     131                 :  *          and are used as the control-expression for a SWITCH statement
     132                 :  *          with a large number of CASE labels in the  handle_internal()
     133                 :  *          function.
     134                 :  *
     135                 :  *      The "Shared Words" list contains FORTH words that can be executed
     136                 :  *          similarly both during "Tokenizer Escape" mode (i.e., the scope
     137                 :  *          of the special brackets:  tokenizer[  ...   ]tokenizer ) and
     138                 :  *          also within "Normal Tokenization" mode.  Their numeric values
     139                 :  *          are derived and used the same way as the "FWords".  Since we
     140                 :  *          will be needing to do a separate search through them at times,
     141                 :  *          we will also need a lower-bracket pointer for them.  (An upper
     142                 :  *          bracket is irrelevant for these, because aliases can be added.
     143                 :  *          This is not the case for the "FC-Tokens" list, because searches
     144                 :  *          through those will be conducted from within this program.)
     145                 :  *
     146                 :  *      The "definer" field in the TIC-header structure is primarily used to
     147                 :  *          detect attempts to apply the  TO  directive to an inappropriate
     148                 :  *          target.  Its numeric values are a subset of the "FWord tokens".
     149                 :  *          Certain "FC-Token" names are specified to be valid  TO  targets;
     150                 :  *          their entries' "definer" fields will be initialized accordingly.
     151                 :  *          Entries in FWord Token lists that are "shared" between "Normal
     152                 :  *          Tokenization" and "Tokenizer Escape" modes will have their
     153                 :  *          "definer" fields initialized to  COMMON_FWORD .  All other
     154                 :  *          entries' "definer" fields will be initialized to  UNSPECIFIED .
     155                 :  *
     156                 :  *      Other files maintain and support additional lists with the same
     157                 :  *          structure, which need to be linked together with the lists
     158                 :  *          declared here.  We prefer to keep the  GV_DP  private to this
     159                 :  *          file, so it will be passed as a parameter where needed.  (I'm
     160                 :  *          not pleased to note, however, that it can't be kept completely
     161                 :  *          private; it's needed for add_user_macro() and possibly other
     162                 :  *          functions outside this file.)
     163                 :  *
     164                 :  *      The words that can only be used during "Tokenizer Escape" mode and
     165                 :  *          the IBM-style "Locals", as well as the device-node vocabularies,
     166                 :  *          will need to be separate and will not be linked together with
     167                 :  *          the Global Vocabulary.
     168                 :  *
     169                 :  **************************************************************************** */
     170                 : 
     171                 : /* **************************************************************************
     172                 :  *
     173                 :  *      We'll be initializing the lists later, but will be referencing
     174                 :  *          the pointers sooner, so we need to declare the pointers here.
     175                 :  *
     176                 :  *      We will keep all of these pointers private to this file.
     177                 :  *
     178                 :  **************************************************************************** */
     179                 : 
     180                 : static tic_hdr_t *global_voc_dict_ptr  = NULL;  /*  The Global Vocabulary    */
     181                 : static tic_hdr_t *fc_tokens_list_ender = NULL;  /*  Tokens search ends here  */
     182                 : static tic_hdr_t *fc_tokens_list_start = NULL;  /*  Start the search here    */
     183                 : static tic_hdr_t *shared_fwords_ender  = NULL;  /*  Shared FWords search end */
     184                 : static tic_hdr_t *global_voc_reset_ptr = NULL;  /*  Reset-point for G.V.     */
     185                 : 
     186                 : 
     187                 : /* **************************************************************************
     188                 :  *
     189                 :  *      Function name:  lookup_core_word
     190                 :  *      Synopsis:       Return a pointer to the data-structure of the named
     191                 :  *                      word in the "Global" Vocabulary
     192                 :  *
     193                 :  *      Inputs:
     194                 :  *         Parameters:
     195                 :  *             tname                     The name to look up
     196                 :  *         Local Static Variables:
     197                 :  *             global_voc_dict_ptr       "Tail" of Global Vocabulary
     198                 :  *
     199                 :  *      Outputs:
     200                 :  *         Returned Value:                Pointer to the data-structure, or
     201                 :  *                                            NULL if not found.
     202                 :  *
     203                 :  **************************************************************************** */
     204                 : 
     205                 : tic_hdr_t *lookup_core_word( char *tname)
     206          151319 : {
     207                 :     tic_hdr_t *found ;
     208                 : 
     209          151319 :     found = lookup_tic_entry( tname, global_voc_dict_ptr);
     210          151319 :     return ( found ) ;
     211                 : }
     212                 : 
     213                 : /* **************************************************************************
     214                 :  *
     215                 :  *      Function name:  exists_in_core
     216                 :  *      Synopsis:       Confirm whether the given name exists in the
     217                 :  *                      Global (aka "core") Vocabulary.  Search the
     218                 :  *                      Global Vocabulary exclusively.
     219                 :  *
     220                 :  *      Inputs:
     221                 :  *         Parameters:
     222                 :  *             name                      The name for which to look
     223                 :  *         Local Static Variables:
     224                 :  *             global_voc_dict_ptr       "Tail" of Global Vocabulary
     225                 :  *
     226                 :  *      Outputs:
     227                 :  *         Returned Value:               TRUE if name is found.
     228                 :  *
     229                 :  **************************************************************************** */
     230                 : 
     231                 : bool exists_in_core( char *name)
     232               0 : {
     233               0 :     return exists_in_tic_vocab( name, global_voc_dict_ptr );
     234                 : }
     235                 : 
     236                 : /* **************************************************************************
     237                 :  *
     238                 :  *      Function name:  handle_core_word
     239                 :  *      Synopsis:       Perform a function in the "Global" Vocabulary and
     240                 :  *                      indicate whether the name is valid.
     241                 :  *
     242                 :  *      Inputs:
     243                 :  *         Parameters:
     244                 :  *             tname                     The name to handle
     245                 :  *         Local Static Variables:
     246                 :  *             global_voc_dict_ptr       "Tail" of Global Vocabulary
     247                 :  *
     248                 :  *      Outputs:
     249                 :  *         Returned Value:   TRUE if the given name is valid in Global Vocab
     250                 :  *
     251                 :  *      Error Detection:
     252                 :  *          If the name is not in the "Global" Vocabulary, let the calling
     253                 :  *              routine determine whether to print an error message or to
     254                 :  *              try it out as a number.
     255                 :  *
     256                 :  **************************************************************************** */
     257                 : 
     258                 : bool handle_core_word( char *tname )
     259               0 : {
     260                 :     bool retval;
     261                 : 
     262               0 :     retval = handle_tic_vocab( tname, global_voc_dict_ptr );
     263                 : 
     264               0 :     return ( retval ) ;
     265                 : }
     266                 : 
     267                 : 
     268                 : /* **************************************************************************
     269                 :  *
     270                 :  *      Function name:  create_core_alias
     271                 :  *      Synopsis:       Create, in the "Global" ("core") Vocabulary, an entry
     272                 :  *                          for NEW_NAME that behaves the same as the latest
     273                 :  *                          definition of OLD_NAME, and whose behavior will
     274                 :  *                          not change even if a new definition of OLD_NAME
     275                 :  *                          is overlaid.  Indicate if successful.
     276                 :  *
     277                 :  *      Inputs:
     278                 :  *         Parameters:
     279                 :  *             new_name          The name for the new alias to be created
     280                 :  *             old_name          The name of the old function to be duplicated
     281                 :  *         Local Static Variables:
     282                 :  *             global_voc_dict_ptr        "Tail" of Global Vocabulary
     283                 :  *
     284                 :  *      Outputs:
     285                 :  *         Returned Value:                TRUE if OLD_NAME was found.
     286                 :  *         Local Static Variables:
     287                 :  *             global_voc_dict_ptr        Updated with the new entry
     288                 :  *         Memory Allocated
     289                 :  *             By support routine.
     290                 :  *
     291                 :  *      Process Explanation:
     292                 :  *          Both the "old" and "new" names are presumed to already point to
     293                 :  *              stable, freshly allocated memory-spaces.
     294                 :  *
     295                 :  **************************************************************************** */
     296                 : 
     297                 : bool create_core_alias( char *new_name, char *old_name)
     298               4 : {
     299               4 :     bool retval = create_tic_alias( new_name, old_name, &global_voc_dict_ptr);
     300               4 :     return ( retval );
     301                 : }
     302                 : 
     303                 : /* **************************************************************************
     304                 :  *
     305                 :  *      The functions that go into the various lists' FUNCT field may be
     306                 :  *           defined below, or might be defined externally.
     307                 :  *
     308                 :  *      Often, we will need a function that merely recasts the type of the
     309                 :  *           parameter field before passing it to the function that does
     310                 :  *           the actual work.
     311                 :  *
     312                 :  *      Prologs will be brief or even non-existent.
     313                 :  *
     314                 :  *      Initialization macro definitions will accompany the functions.
     315                 :  *
     316                 :  **************************************************************************** */
     317                 : 
     318                 : /* **************************************************************************
     319                 :  *
     320                 :  *      For the "FCode-Tokens" list, simply generate the token directly.
     321                 :  *      We need this layer for param type conversion.
     322                 :  *      In case we're ever able to eliminate it, (or just on General
     323                 :  *          Principles) we'll invoke it via a macro...
     324                 :  *
     325                 :  **************************************************************************** */
     326                 : 
     327                 : static void emit_fc_token( tic_param_t pfield)
     328          145254 : {
     329          145254 :     u16 fc_tok = (u16)pfield.deflt_elem;
     330          145254 :     emit_fcode( fc_tok);
     331          145254 : }
     332                 : 
     333                 : #define FC_TOKEN_FUNC  emit_fc_token
     334                 : 
     335                 : #define BUILTIN_FCODE( tok, nam)   \
     336                 :      VALPARAM_TIC(nam, FC_TOKEN_FUNC, tok , UNSPECIFIED )
     337                 : 
     338                 : /*  Built-in FCodes with known definers:  */
     339                 : #define BI_FCODE_VALUE( tok, nam)   \
     340                 :      VALPARAM_TIC(nam, FC_TOKEN_FUNC, tok , VALUE )
     341                 : 
     342                 : #define BI_FCODE_VRBLE( tok, nam)   \
     343                 :      VALPARAM_TIC(nam, FC_TOKEN_FUNC, tok , VARIABLE )
     344                 : 
     345                 : #define BI_FCODE_DEFER( tok, nam)   \
     346                 :      VALPARAM_TIC(nam, FC_TOKEN_FUNC, tok , DEFER )
     347                 : 
     348                 : #define BI_FCODE_CONST( tok, nam)   \
     349                 :      VALPARAM_TIC(nam, FC_TOKEN_FUNC, tok , CONST )
     350                 : 
     351                 : /* **************************************************************************
     352                 :  *
     353                 :  *      The "FCode-Tokens" list includes tokens that are identified
     354                 :  *         in the Standard as Obsolete.  We will define a function
     355                 :  *         that issues a WARNING before generating the token, and
     356                 :  *         assign it to those elements of the list.
     357                 :  *
     358                 :  *      Control the message via a command-line flag.
     359                 :  *
     360                 :  **************************************************************************** */
     361                 : 
     362                 : static void obsolete_warning( void)
     363              72 : {
     364              72 :     if ( obso_fcode_warning )
     365                 :     {
     366              36 :         tokenization_error( WARNING, "%s is an Obsolete FCode.\n",
     367                 :             strupr(statbuf) );
     368                 :     }
     369              72 : }
     370                 : 
     371                 : static void obsolete_fc_token( tic_param_t pfield)
     372              70 : {
     373              70 :     obsolete_warning();
     374              70 :     emit_fc_token( pfield);
     375              70 : }
     376                 : 
     377                 : #define OBSO_FC_FUNC  obsolete_fc_token
     378                 : 
     379                 : #define OBSOLETE_FCODE( tok, nam)   \
     380                 :      VALPARAM_TIC(nam, OBSO_FC_FUNC, tok , UNSPECIFIED )
     381                 : 
     382                 : #define OBSOLETE_VALUE( tok, nam)   \
     383                 :      VALPARAM_TIC(nam, OBSO_FC_FUNC, tok , VALUE )
     384                 : 
     385                 : 
     386                 : /* **************************************************************************
     387                 :  *
     388                 :  *      The function for most of the "FWords" list,  handle_internal() ,
     389                 :  *          is defined externally, but not exported in a  .h  file,
     390                 :  *          because we want to keep it as private as possible.
     391                 :  *      We will declare its prototype here.
     392                 :  *
     393                 :  *      Initialization macros for both "Normal Mode"-only and
     394                 :  *          "Shared" entries are also defined here.
     395                 :  *
     396                 :  *   Arguments:
     397                 :  *       fwt      (fword_token)    Value of the FWord Token (from Enum list)
     398                 :  *       nam      (string)         Name of the entry as seen in the source
     399                 :  *
     400                 :  **************************************************************************** */
     401                 : 
     402                 : void handle_internal( tic_param_t pfield);
     403                 : /*  "Skip-a-string when Ignoring" function.  Same args and limited-proto ...  */
     404                 : void skip_string( tic_param_t pfield);
     405                 : 
     406                 : #define FWORD_EXEC_FUNC  handle_internal
     407                 : 
     408                 : #define BUILTIN_FWORD( fwt, nam)   \
     409                 :      FWORD_TKN_TIC(nam, FWORD_EXEC_FUNC, fwt, BI_FWRD_DEFN )
     410                 : 
     411                 : #define SHARED_FWORD( fwt, nam)   \
     412                 :      FWORD_TKN_TIC(nam, FWORD_EXEC_FUNC, fwt, COMMON_FWORD )
     413                 : 
     414                 : /*  Variants:  When Ignoring, SKip One Word  */
     415                 : #define SHR_FWD_SKOW( fwt, nam)   \
     416                 :      DUALFUNC_FWT_TIC(nam, FWORD_EXEC_FUNC, fwt, skip_a_word, COMMON_FWORD )
     417                 : 
     418                 : /*  Variants:  When Ignoring, SKip one Word in line  */
     419                 : #define SH_FW_SK_WIL( fwt, nam)   \
     420                 :      DUALFUNC_FWT_TIC(nam, FWORD_EXEC_FUNC, fwt,     \
     421                 :          skip_a_word_in_line, COMMON_FWORD )
     422                 : 
     423                 : /*  When Ignoring, SKip Two Words in line  */
     424                 : #define SH_FW_SK2WIL( fwt, nam)   \
     425                 :      DUALFUNC_FWT_TIC(nam, FWORD_EXEC_FUNC, fwt,     \
     426                 :          skip_two_words_in_line, COMMON_FWORD )
     427                 : 
     428                 : /* **************************************************************************
     429                 :  *
     430                 :  *      Some of the entries in the "FWords" list -- both "Normal" (Built-in)
     431                 :  *          and "Shared" also act as an "Ignore-handler".
     432                 :  *          
     433                 :  *   Arguments:
     434                 :  *       nam      (string)         Name of the entry as seen in the source
     435                 :  *       afunc    (routine-name)   Name of internal "active" function
     436                 :  *       pval     (integer)        The "param field" item
     437                 :  *       ifunc    (routine-name)   Name of "ignore-handling" function
     438                 :  *
     439                 :  **************************************************************************** */
     440                 : 
     441                 : #define SHARED_IG_HDLR(nam, afunc, pval, ifunc)     \
     442                 :     DUFNC_FWT_PARM(nam, afunc, pval, ifunc, COMMON_FWORD )
     443                 : 
     444                 : /*  A "Shared" entry that uses the same routine for both of its functions  */
     445                 : #define SHR_SAMIG_FWRD( fwt, nam)   \
     446                 :     DUFNC_FWT_PARM(nam, FWORD_EXEC_FUNC, fwt, FWORD_EXEC_FUNC, COMMON_FWORD )
     447                 : 
     448                 : /* **************************************************************************
     449                 :  *
     450                 :  *     But the "Normal" (Built-in) FWord Ignore-handler uses the same
     451                 :  *          routine as the  BUILTIN_FWORD for both of its functions.
     452                 :  *
     453                 :  *   Arguments:
     454                 :  *       fwt      (fword_token)    Value of the FWord Token (from Enum list)
     455                 :  *       nam      (string)         Name of the entry as seen in the source
     456                 :  *
     457                 :  **************************************************************************** */
     458                 : #define BI_IG_FW_HDLR( fwt, nam)   \
     459                 :     DUALFUNC_FWT_TIC(nam, FWORD_EXEC_FUNC, fwt, FWORD_EXEC_FUNC, BI_FWRD_DEFN )
     460                 : 
     461                 : /*  A variant:  A "Built-In FWorD that SKiPs One Word", when Ignoring  */
     462                 : #define BI_FWD_SKP_OW( fwt, nam)   \
     463                 :      DUALFUNC_FWT_TIC(nam, FWORD_EXEC_FUNC, fwt, skip_a_word, BI_FWRD_DEFN )
     464                 : 
     465                 : /*  Another variant:  A "Built-In FWorD String".  skip_string when Ignoring  */
     466                 : #define BI_FWD_STRING( fwt, nam)   \
     467                 :      DUALFUNC_FWT_TIC(nam, FWORD_EXEC_FUNC, fwt, skip_string, BI_FWRD_DEFN )
     468                 : 
     469                 : /* **************************************************************************
     470                 :  *
     471                 :  *      In order to protect device-nodes' methods from being accessed 
     472                 :  *          by other device-nodes (with the attendant potential for
     473                 :  *          disastrous consequences), we must establish a few rules:
     474                 :  *
     475                 :  *      Each device-node has a separate vocabulary for its methods.
     476                 :  *          New definitions are made to the "current" device's vocabulary.
     477                 :  *          Searches for names go through the "current" device-node's
     478                 :  *              vocabulary first, then through the core dictionary.
     479                 :  *
     480                 :  *      A new-device (in interpretation-mode) creates a new device-node
     481                 :  *          vocabulary.  The node that had been current (presumably its
     482                 :  *          parent) remains in memory but inactive.
     483                 :  *
     484                 :  *      A finish-device (again, only in interpretation-mode) removes the
     485                 :  *          current device-node's vocabulary from memory; its presumed
     486                 :  *          parent once again becomes current.
     487                 :  *
     488                 :  *      Tokenization starts with an implicit "new-device" in effect.
     489                 :  *          The top-level device-node is never removed.
     490                 :  *
     491                 :  *      The Global Variable  current_definitions  points to the vocabulary
     492                 :  *          to which we will add and through which we will search first.
     493                 :  *
     494                 :  *      If "global" scope is in effect, then  current_definitions  will
     495                 :  *           point to the "Global" (also called "core") vocabulary.
     496                 :  *
     497                 :  **************************************************************************** */
     498                 : 
     499                 : /* **************************************************************************
     500                 :  *
     501                 :  *      Support for operations in "current" -- i.e., "global" vis-a-vis
     502                 :  *          "device" -- scope.
     503                 :  *      "Global" scope will not recognize words defined in "device" scope,
     504                 :  *           but "device" scope will recognize "global" words.
     505                 :  *
     506                 :  **************************************************************************** */
     507                 : 
     508                 : /* **************************************************************************
     509                 :  *
     510                 :  *      Functions to enter "global" scope and resume "device" scope.
     511                 :  *
     512                 :  **************************************************************************** */
     513                 : 
     514                 : static tic_hdr_t **save_device_definitions;
     515                 : /* Export the indication that "global" scope is in effect  */
     516                 : bool scope_is_global = FALSE;
     517                 : 
     518                 : 
     519                 : void enter_global_scope( void )
     520              63 : {
     521              63 :     if ( scope_is_global )
     522                 : {
     523               1 :         tokenization_error( WARNING,
     524                 :             "%s -- Global Scope already in effect; ignoring.\n",
     525                 :                 strupr(statbuf) );
     526                 :     }else{
     527              62 :         tokenization_error( INFO,
     528                 :             "Initiating Global Scope definitions.\n" );
     529              62 :         scope_is_global = TRUE;
     530              62 :         save_device_definitions = current_definitions;
     531              62 :         current_definitions = &global_voc_dict_ptr;
     532                 :     }
     533              63 : }
     534                 : 
     535                 : void resume_device_scope( void )
     536              62 : {
     537              62 :     if ( scope_is_global )
     538                 :     {
     539              60 :         tokenization_error( INFO,
     540                 :             "Terminating Global Scope definitions; "
     541                 :                 "resuming Device-node definitions.\n" );
     542              60 :         current_definitions = save_device_definitions;
     543              60 :         scope_is_global = FALSE;
     544                 :     }else{
     545               2 :         tokenization_error( WARNING,
     546                 :             "%s -- Device-node Scope already in effect; ignoring.\n",
     547                 :                 strupr(statbuf) );
     548                 :     }
     549                 : 
     550              62 : }
     551                 : 
     552                 : /* **************************************************************************
     553                 :  *
     554                 :  *      Function name:  lookup_current
     555                 :  *      Synopsis:       Return a pointer to the data-structure of the named
     556                 :  *                          word, either in the Current Device-Node vocab,
     557                 :  *                          or in the Global ("core") Vocabulary.
     558                 :  *
     559                 :  *      Inputs:
     560                 :  *         Parameters:
     561                 :  *             tname                     The name to look for
     562                 :  *         Global Variables:
     563                 :  *             current_definitions       Current vocabulary:  Device-Node, or
     564                 :  *                                           "core" if "global" scope in effect.
     565                 :  *             scope_is_global           TRUE if "global" scope is in effect
     566                 :  *         Local Static Variables:
     567                 :  *             global_voc_dict_ptr       "Tail" of Global Vocabulary
     568                 :  *
     569                 :  *      Outputs:
     570                 :  *         Returned Value:               Pointer to the data-structure, or
     571                 :  *                                           NULL if not found.
     572                 :  *
     573                 :  *      Process Explanation:
     574                 :  *          If a current Device-Node Vocabulary in effect, search through it.
     575                 :  *          If the given name was not found, and "global" scope is not in
     576                 :  *              effect (i.e., "core" was not already searched), make a
     577                 :  *              separate search through the Global ("core") Vocabulary
     578                 :  *
     579                 :  *      Extraneous Remarks:
     580                 :  *          This is the central routine for doing general word-searches that
     581                 :  *              make use of the "normal"-mode search-list.
     582                 :  *
     583                 :  **************************************************************************** */
     584                 : 
     585                 : tic_hdr_t *lookup_current( char *tname)
     586           33173 : {
     587                 :     /*  Search Current Device Vocabulary ahead of global (core) vocabulary  */
     588                 :     tic_hdr_t *retval;
     589           33173 :     retval = lookup_tic_entry( tname, *current_definitions);
     590           33173 :     if ( (retval == NULL) && INVERSE(scope_is_global) )
     591                 : {
     592           32596 :         retval = lookup_core_word( tname);
     593                 :     }
     594           33173 :     return ( retval );
     595                 : }
     596                 : 
     597                 : /* **************************************************************************
     598                 :  *
     599                 :  *      Function name:  exists_in_current
     600                 :  *      Synopsis:       Confirm whether the given name exists either
     601                 :  *                          in the Current Device-Node vocab,
     602                 :  *                          or in the Global ("core") Vocabulary,
     603                 :  *                          or in Tokenizer Escape Mode, if that's current.
     604                 :  *
     605                 :  *      Inputs:
     606                 :  *         Parameters:
     607                 :  *             tname                     The name to look for
     608                 :  *
     609                 :  *      Outputs:
     610                 :  *         Returned Value:               TRUE if name is found
     611                 :  *
     612                 :  **************************************************************************** */
     613                 : 
     614                 : bool exists_in_current( char *tname)
     615              95 : {
     616              95 :     tic_hdr_t *found = lookup_word( tname, NULL, NULL);
     617              95 :     bool retval = BOOLVAL ( found != NULL);
     618              95 :     return( retval);
     619                 :         }
     620                 : 
     621                 : 
     622                 : /* **************************************************************************
     623                 :  *
     624                 :  *      Function name:  handle_current
     625                 :  *      Synopsis:       Perform a function in the current device-node vocab,
     626                 :  *                      if one is in effect, or in the "Global" Vocabulary.
     627                 :  *                      Indicate whether the name is valid.
     628                 :  *
     629                 :  *      Inputs:
     630                 :  *         Parameters:
     631                 :  *             tname                      The name to handle
     632                 :  *         Global Variables:
     633                 :  *             current_definitions        Device-Node (or Global) Vocabulary
     634                 :  *                                            currently in effect.
     635                 :  *             scope_is_global            TRUE if "global" scope is in effect
     636                 :  *         Local Static Variables:
     637                 :  *
     638                 :  *      Outputs:
     639                 :  *         Returned Value:                TRUE if the given name is valid
     640                 :  *
     641                 :  **************************************************************************** */
     642                 : 
     643                 : bool handle_current( char *tname )
     644               0 : {
     645               0 :     bool retval = handle_tic_vocab( tname, *current_definitions );
     646                 : 
     647               0 :     if ( INVERSE(retval) && INVERSE(scope_is_global) )
     648                 :     {
     649               0 :         retval = handle_core_word( tname );
     650                 :     }
     651               0 :     return ( retval );
     652                 : 
     653                 : }
     654                 : 
     655                 : 
     656                 : /* **************************************************************************
     657                 :  *
     658                 :  *      Function name:  lookup_in_dev_node
     659                 :  *      Synopsis:       Return a pointer to the data-structure of the
     660                 :  *                          named word in the Current device node, if
     661                 :  *                          in "Device" scope.  Used for error-reporting.
     662                 :  *
     663                 :  *      Inputs:
     664                 :  *         Parameters:
     665                 :  *             tname                     The name to look for
     666                 :  *         Global Variables:
     667                 :  *             current_definitions        Device-Node (or Global) Vocabulary
     668                 :  *                                            currently in effect.
     669                 :  *             scope_is_global            FALSE if "Device" scope is in effect
     670                 :  *
     671                 :  *      Outputs:
     672                 :  *         Returned Value:                Pointer to the data-structure, or
     673                 :  *                                            NULL if not found.
     674                 :  *
     675                 :  **************************************************************************** */
     676                 : 
     677                 : tic_hdr_t *lookup_in_dev_node( char *tname)
     678          119983 : {
     679          119983 :     tic_hdr_t *retval = NULL;
     680                 : 
     681          119983 :     if ( INVERSE(scope_is_global) )
     682                 : {
     683          117186 :         retval = lookup_tic_entry( tname, *current_definitions);
     684                 : }
     685          119983 :     return ( retval );
     686                 : }
     687                 : 
     688                 : 
     689                 : /* **************************************************************************
     690                 :  *
     691                 :  *     In order to avoid unintentional "recursive"-ness, we need a way
     692                 :  *          to render a newly created colon-definition non-findable
     693                 :  *          until it's completed.
     694                 :  *
     695                 :  *      We will accomplish this by saving and reverting the pointer to
     696                 :  *          the newest entry, when we call the  hide_last_colon() , and
     697                 :  *          by restoring the pointer when we call  reveal_last_colon()
     698                 :  *
     699                 :  *      We need, therefore, to save the pointer to the last entry before
     700                 :  *          we create the new entry.
     701                 :  *
     702                 :  **************************************************************************** */
     703                 : 
     704                 : /*  Update this each time a new definition is entered  */
     705                 : static tic_hdr_t *save_current = NULL;
     706                 : 
     707                 : /* **************************************************************************
     708                 :  *
     709                 :  *      Function name:  add_to_current
     710                 :  *      Synopsis:       Add a new entry to the "current" scope of definitions,
     711                 :  *                          which may be either the Global Vocabulary or the
     712                 :  *                          current Device-Node Vocabulary.
     713                 :  *
     714                 :  *      Inputs:
     715                 :  *         Parameters:
     716                 :  *             name                      The name of the new entry
     717                 :  *             fc_token                  The new entry's assigned FCode-number
     718                 :  *             fw_definer                The new entry's definer
     719                 :  *             define_token              If FALSE, suppress adding the entry,
     720                 :  *                                           but preserve the side-effect of
     721                 :  *                                           setting  save_current 
     722                 :  *         Global Variables:
     723                 :  *             current_definitions       Pointer to pointer to "tail" of the
     724                 :  *                                           Vocabulary currently in effect;
     725                 :  *                                           either Device-node or Global.
     726                 :  *
     727                 :  *      Outputs:
     728                 :  *         Returned Value:               NONE
     729                 :  *         Global Variables:
     730                 :  *             *current_definitions    Updated with the new entry
     731                 :  *         Local Static Variables:
     732                 :  *             save_current            Pointer to previous entry
     733                 :  *         Memory Allocated
     734                 :  *             For the new entry's copy of the name.
     735                 :  *         When Freed?
     736                 :  *             When the Device-Node is "finish"ed or the Global Vocabulary
     737                 :  *                 is reset, or when the program exits.
     738                 :  *
     739                 :  *      Process Explanation:
     740                 :  *          Because  current_definitions  points to the Global Vocabulary
     741                 :  *              pointer during "global" scope, this routine is extremely
     742                 :  *              straightforward.
     743                 :  *          All user-defined words have the same action, i.e., emitting
     744                 :  *              the assigned FCode-number.  The new entry's "parameter
     745                 :  *              field" size is, of course, zero; the "ignore-function"
     746                 :  *              is NULL.
     747                 :  *
     748                 :  *      Extraneous Remarks:
     749                 :  *          The  define_token  parameter is a late addition, necessitated
     750                 :  *              by the decision to continue processing after an erroneous
     751                 :  *              attempt to create a definition inside a control-structure,
     752                 :  *              in order to catch other errors. 
     753                 :  *            
     754                 :  *
     755                 :  **************************************************************************** */
     756                 : 
     757                 : void add_to_current( char *name,
     758                 :                            TIC_P_DEFLT_TYPE fc_token,
     759                 :                                fwtoken definer,
     760                 :                                    bool define_token)
     761            9978 : {
     762            9978 :     save_current = *current_definitions;
     763            9978 :     if ( define_token )
     764                 : {
     765            9961 :         char *nu_name = strdup( name);
     766            9961 :         add_tic_entry( nu_name, FC_TOKEN_FUNC, fc_token,
     767                 :                            definer, 0 , NULL, current_definitions );
     768                 :     }
     769            9978 : }
     770                 : 
     771                 : 
     772                 : void hide_last_colon ( void )
     773             717 : {
     774                 :     tic_hdr_t *temp_vocab;
     775                 : 
     776                 :     /*  The  add_to_current()  function will have been called before this
     777                 :      *      one when a new colon-definition is created, so  save_current
     778                 :      *      will have been set to point to the entry that had been made
     779                 :      *      just before the newest one, which we are hiding here.
     780                 :      */
     781                 : 
     782             717 :     temp_vocab = save_current ;
     783             717 :     save_current = *current_definitions;
     784             717 :     *current_definitions = temp_vocab;
     785                 : 
     786             717 : }
     787                 : 
     788                 : void reveal_last_colon ( void )
     789             719 : {
     790                 :     /*  We call this function either when the colon-definition is
     791                 :      *      completed, or when "recursive"-ness is intentional.
     792                 :      */
     793             719 :     *current_definitions = save_current ;
     794             719 : }
     795                 : 
     796                 : 
     797                 : /* **************************************************************************
     798                 :  *
     799                 :  *      Function name:  create_current_alias
     800                 :  *      Synopsis:       Create an alias for OLD_NAME, called NEW_NAME, in
     801                 :  *                          the "current" scope of definitions, which may
     802                 :  *                          be either the Global ("core") Vocabulary or the
     803                 :  *                          current Device-Node Vocabulary.  Indicate if
     804                 :  *                          successful (i.e., OLD_NAME was valid).
     805                 :  *                      This is actually a little trickier than it may at
     806                 :  *                          first appear; read the Rules in the Process
     807                 :  *                          Explanation for full details...
     808                 :  *
     809                 :  *      Inputs:
     810                 :  *         Parameters:
     811                 :  *             new_name          The name for the new alias to be created
     812                 :  *             old_name          The name of the old function to be duplicated
     813                 :  *         Global Variables:
     814                 :  *             current_definitions        Device-node vocabulary currently
     815                 :  *                                            in effect.
     816                 :  *             scope_is_global            TRUE if "global" scope is in effect
     817                 :  *         Local Static Variables:
     818                 :  *             global_voc_dict_ptr        "Tail" of Global Vocabulary
     819                 :  *
     820                 :  *      Outputs:
     821                 :  *         Returned Value:                TRUE if OLD_NAME was found.
     822                 :  *         Global Variables:
     823                 :  *             *current_definitions      Updated with the new entry 
     824                 :  *         Memory Allocated
     825                 :  *             By support routine.
     826                 :  *         When Freed?
     827                 :  *             When RESET-SYMBOLS is issued (if "global" scope is in effect)
     828                 :  *                 or when the device-node is "finish"ed.
     829                 :  *         Printout:
     830                 :  *             Advisory message if Rule 3 (see below) is invoked.
     831                 :  *
     832                 :  *      Process Explanation:
     833                 :  *          Both the "old" and "new" names are presumed to already point to
     834                 :  *              stable, freshly allocated memory-spaces.
     835                 :  *          Rules:
     836                 :  *          (1)
     837                 :  *          If "global" scope is in effect, and the "old" name is found in
     838                 :  *              the Global Vocabulary, then the "new" name will be created
     839                 :  *              in the Global Vocabulary.
     840                 :  *          (2)
     841                 :  *          Similarly, if "device" scope is in effect, and the "old" name is
     842                 :  *              found in the current device-node's vocabulary, the "new" name
     843                 :  *              will be created in the current device-node's vocabulary.
     844                 :  *          (3)
     845                 :  *          BUT!:  If "device" scope is in effect, and the "old" name is found
     846                 :  *              in the Global Vocabulary, then the "new" name will be created
     847                 :  *              in the current device-node's vocabulary.  It will only be
     848                 :  *              recognized in the scope of that device-node, and will be
     849                 :  *              removed from memory when the device-node is "finish"ed.
     850                 :  *          And, yes, it *is* supposed to work that way...   ;-)
     851                 :  *
     852                 :  *          Again, because  current_definitions  points to the Global Vocab
     853                 :  *              pointer during "global" scope, the first two rules of this
     854                 :  *              routine are extremely straightforward; it's Rule 3 that you
     855                 :  *              have to watch out for...  ;-)
     856                 :  *
     857                 :  *          And one other thing:
     858                 :  *              We will always make the alias's  pfld_size  zero.  See the
     859                 :  *              prolog for  create_tic_alias()  in  ticvocab.c  for details...
     860                 :  *
     861                 :  *      Extraneous Remarks:
     862                 :  *          I will stretch the rules of well-structured code here, too.
     863                 :  *
     864                 :  **************************************************************************** */
     865                 : 
     866                 : bool create_current_alias( char *new_name, char *old_name )
     867             122 : {
     868             122 :     bool retval = FALSE;
     869                 : 
     870             122 :     if ( create_tic_alias( new_name, old_name, current_definitions) )
     871                 :     {
     872              60 :          return ( TRUE );
     873                 :     }
     874                 :     
     875              62 :     if ( INVERSE(scope_is_global) )
     876                 :     {
     877              58 :         tic_hdr_t *found = lookup_core_word( old_name );
     878              58 :         if ( found != NULL )
     879                 :         {
     880              50 :             add_tic_entry( new_name, found->funct,
     881                 :                                found->pfield.deflt_elem,
     882                 :                                    found->fword_defr,
     883                 :                                        0, found->ign_func,
     884                 :                                            current_definitions );
     885              50 :             retval = TRUE;
     886                 :             {
     887              50 :                 tokenization_error( INFO,
     888                 :                    "%s is a Global definition, but its alias, %s, "
     889                 :                        "will only be defined %s",
     890                 :                            strupr( old_name), new_name,
     891                 :                                in_what_node( current_device_node) );
     892              50 :                 show_node_start();
     893                 :             }
     894                 :         }
     895                 :     }
     896                 : 
     897              62 :     return ( retval );
     898                 : }
     899                 : 
     900                 : /* **************************************************************************
     901                 :  *
     902                 :  *      Support functions specific to the lists will be defined
     903                 :  *          after the lists are created.
     904                 :  *
     905                 :  **************************************************************************** */
     906                 : 
     907                 : /* **************************************************************************
     908                 :  *
     909                 :  *     Create the initial list (or "Table") of FCode-Tokens.
     910                 :  *
     911                 :  *     Most Standard FCode tokens are not specified as to their definition
     912                 :  *         type, but a few have a definer specified as either a VALUE, a
     913                 :  *         VARIABLE or a DEFER; we will enter them with the appropriate macro.
     914                 :  *
     915                 :  **************************************************************************** */
     916                 : 
     917                 : static tic_hdr_t tokens_table[] =
     918                 : {
     919                 :         BUILTIN_FCODE( 0x000, "end0" ) ,
     920                 :         BUILTIN_FCODE( 0x010, "b(lit)" ) ,
     921                 :         BUILTIN_FCODE( 0x011, "b(')" ) ,
     922                 :         BUILTIN_FCODE( 0x012, "b(\")" ) ,
     923                 :         BUILTIN_FCODE( 0x013, "bbranch" ) ,
     924                 :         BUILTIN_FCODE( 0x014, "b?branch" ) ,
     925                 :         BUILTIN_FCODE( 0x015, "b(loop)" ) ,
     926                 :         BUILTIN_FCODE( 0x016, "b(+loop)" ) ,
     927                 :         BUILTIN_FCODE( 0x017, "b(do)" ) ,
     928                 :         BUILTIN_FCODE( 0x018, "b(?do)" ) ,
     929                 :         BUILTIN_FCODE( 0x019, "i" ) ,
     930                 :         BUILTIN_FCODE( 0x01a, "j" ) ,
     931                 :         BUILTIN_FCODE( 0x01b, "b(leave)" ) ,
     932                 :         BUILTIN_FCODE( 0x01c, "b(of)" ) ,
     933                 :         BUILTIN_FCODE( 0x01d, "execute" ) ,
     934                 :         BUILTIN_FCODE( 0x01e, "+" ) ,
     935                 :         BUILTIN_FCODE( 0x01f, "-" ) ,
     936                 :         BUILTIN_FCODE( 0x020, "*" ) ,
     937                 :         BUILTIN_FCODE( 0x021, "/" ) ,
     938                 :         BUILTIN_FCODE( 0x022, "mod" ) ,
     939                 :         BUILTIN_FCODE( 0x023, "and" ) ,
     940                 :         BUILTIN_FCODE( 0x024, "or" ) ,
     941                 :         BUILTIN_FCODE( 0x025, "xor" ) ,
     942                 :         BUILTIN_FCODE( 0x026, "invert" ) ,
     943                 :         BUILTIN_FCODE( 0x026, "not" ) ,           /*  Synonym for "invert" */
     944                 :         BUILTIN_FCODE( 0x027, "lshift" ) ,
     945                 :         BUILTIN_FCODE( 0x027, "<<" ) ,            /*  Synonym for "lshift" */
     946                 :         BUILTIN_FCODE( 0x028, "rshift" ) ,
     947                 :         BUILTIN_FCODE( 0x028, ">>" ) ,            /*  Synonym for "rshift" */
     948                 :         BUILTIN_FCODE( 0x029, ">>a" ) ,
     949                 :         BUILTIN_FCODE( 0x02a, "/mod" ) ,
     950                 :         BUILTIN_FCODE( 0x02b, "u/mod" ) ,
     951                 :         BUILTIN_FCODE( 0x02c, "negate" ) ,
     952                 :         BUILTIN_FCODE( 0x02d, "abs" ) ,
     953                 :         BUILTIN_FCODE( 0x02e, "min" ) ,
     954                 :         BUILTIN_FCODE( 0x02f, "max" ) ,
     955                 :         BUILTIN_FCODE( 0x030, ">r" ) ,
     956                 :         BUILTIN_FCODE( 0x031, "r>" ) ,
     957                 :         BUILTIN_FCODE( 0x032, "r@" ) ,
     958                 :         BUILTIN_FCODE( 0x033, "exit" ) ,
     959                 :         BUILTIN_FCODE( 0x034, "0=" ) ,
     960                 :         BUILTIN_FCODE( 0x035, "0<>" ) ,
     961                 :         BUILTIN_FCODE( 0x036, "0<" ) ,
     962                 :         BUILTIN_FCODE( 0x037, "0<=" ) ,
     963                 :         BUILTIN_FCODE( 0x038, "0>" ) ,
     964                 :         BUILTIN_FCODE( 0x039, "0>=" ) ,
     965                 :         BUILTIN_FCODE( 0x03a, "<" ) ,
     966                 :         BUILTIN_FCODE( 0x03b, ">" ) ,
     967                 :         BUILTIN_FCODE( 0x03c, "=" ) ,
     968                 :         BUILTIN_FCODE( 0x03d, "<>" ) ,
     969                 :         BUILTIN_FCODE( 0x03e, "u>" ) ,
     970                 :         BUILTIN_FCODE( 0x03f, "u<=" ) ,
     971                 :         BUILTIN_FCODE( 0x040, "u<" ) ,
     972                 :         BUILTIN_FCODE( 0x041, "u>=" ) ,
     973                 :         BUILTIN_FCODE( 0x042, ">=" ) ,
     974                 :         BUILTIN_FCODE( 0x043, "<=" ) ,
     975                 :         BUILTIN_FCODE( 0x044, "between" ) ,
     976                 :         BUILTIN_FCODE( 0x045, "within" ) ,
     977                 :         BUILTIN_FCODE( 0x046, "drop" ) ,
     978                 :         BUILTIN_FCODE( 0x047, "dup" ) ,
     979                 :         BUILTIN_FCODE( 0x048, "over" ) ,
     980                 :         BUILTIN_FCODE( 0x049, "swap" ) ,
     981                 :         BUILTIN_FCODE( 0x04A, "rot" ) ,
     982                 :         BUILTIN_FCODE( 0x04b, "-rot" ) ,
     983                 :         BUILTIN_FCODE( 0x04c, "tuck" ) ,
     984                 :         BUILTIN_FCODE( 0x04d, "nip" ) ,
     985                 :         BUILTIN_FCODE( 0x04e, "pick" ) ,
     986                 :         BUILTIN_FCODE( 0x04f, "roll" ) ,
     987                 :         BUILTIN_FCODE( 0x050, "?dup" ) ,
     988                 :         BUILTIN_FCODE( 0x051, "depth" ) ,
     989                 :         BUILTIN_FCODE( 0x052, "2drop" ) ,
     990                 :         BUILTIN_FCODE( 0x053, "2dup" ) ,
     991                 :         BUILTIN_FCODE( 0x054, "2over" ) ,
     992                 :         BUILTIN_FCODE( 0x055, "2swap" ) ,
     993                 :         BUILTIN_FCODE( 0x056, "2rot" ) ,
     994                 :         BUILTIN_FCODE( 0x057, "2/" ) ,
     995                 :         BUILTIN_FCODE( 0x058, "u2/" ) ,
     996                 :         BUILTIN_FCODE( 0x059, "2*" ) ,
     997                 :         BUILTIN_FCODE( 0x05a, "/c" ) ,
     998                 :         BUILTIN_FCODE( 0x05b, "/w" ) ,
     999                 :         BUILTIN_FCODE( 0x05c, "/l" ) ,
    1000                 :         BUILTIN_FCODE( 0x05d, "/n" ) ,
    1001                 :         BUILTIN_FCODE( 0x05e, "ca+" ) ,
    1002                 :         BUILTIN_FCODE( 0x05f, "wa+" ) ,
    1003                 :         BUILTIN_FCODE( 0x060, "la+" ) ,
    1004                 :         BUILTIN_FCODE( 0x061, "na+" ) ,
    1005                 :         BUILTIN_FCODE( 0x062, "char+" ) ,
    1006                 :         BUILTIN_FCODE( 0x062, "ca1+" ) ,          /*  Synonym for char+" */
    1007                 :         BUILTIN_FCODE( 0x063, "wa1+" ) ,
    1008                 :         BUILTIN_FCODE( 0x064, "la1+" ) ,
    1009                 :         BUILTIN_FCODE( 0x065, "cell+" ) ,
    1010                 :         BUILTIN_FCODE( 0x065, "na1+" ) ,          /*  Synonym for "cell+" */
    1011                 :         BUILTIN_FCODE( 0x066, "chars" ) ,
    1012                 :         BUILTIN_FCODE( 0x066, "/c*" ) ,           /*  Synonym for "chars" */
    1013                 :         BUILTIN_FCODE( 0x067, "/w*" ) ,
    1014                 :         BUILTIN_FCODE( 0x068, "/l*" ) ,
    1015                 :         BUILTIN_FCODE( 0x069, "cells" ) ,
    1016                 :         BUILTIN_FCODE( 0x069, "/n*" ) ,           /*  Synonym for "cells" */
    1017                 :         BUILTIN_FCODE( 0x06a, "on" ) ,
    1018                 :         BUILTIN_FCODE( 0x06b, "off" ) ,
    1019                 :         BUILTIN_FCODE( 0x06c, "+!" ) ,
    1020                 :         BUILTIN_FCODE( 0x06d, "@" ) ,
    1021                 :         BUILTIN_FCODE( 0x06e, "l@" ) ,
    1022                 :         BUILTIN_FCODE( 0x06f, "w@" ) ,
    1023                 :         BUILTIN_FCODE( 0x070, "<w@" ) ,
    1024                 :         BUILTIN_FCODE( 0x071, "c@" ) ,
    1025                 :         BUILTIN_FCODE( 0x072, "!" ) ,
    1026                 :         BUILTIN_FCODE( 0x073, "l!" ) ,
    1027                 :         BUILTIN_FCODE( 0x074, "w!" ) ,
    1028                 :         BUILTIN_FCODE( 0x075, "c!" ) ,
    1029                 :         BUILTIN_FCODE( 0x076, "2@" ) ,
    1030                 :         BUILTIN_FCODE( 0x077, "2!" ) ,
    1031                 :         BUILTIN_FCODE( 0x078, "move" ) ,
    1032                 :         BUILTIN_FCODE( 0x079, "fill" ) ,
    1033                 :         BUILTIN_FCODE( 0x07a, "comp" ) ,
    1034                 :         BUILTIN_FCODE( 0x07b, "noop" ) ,
    1035                 :         BUILTIN_FCODE( 0x07c, "lwsplit" ) ,
    1036                 :         BUILTIN_FCODE( 0x07d, "wljoin" ) ,
    1037                 :         BUILTIN_FCODE( 0x07e, "lbsplit" ) ,
    1038                 :         BUILTIN_FCODE( 0x07f, "bljoin" ) ,
    1039                 :         BUILTIN_FCODE( 0x080, "wbflip" ) ,
    1040                 :         BUILTIN_FCODE( 0x080, "flip" ) ,   /*  Synonym for "wbflip"  */
    1041                 :         BUILTIN_FCODE( 0x081, "upc" ) ,
    1042                 :         BUILTIN_FCODE( 0x082, "lcc" ) ,
    1043                 :         BUILTIN_FCODE( 0x083, "pack" ) ,
    1044                 :         BUILTIN_FCODE( 0x084, "count" ) ,
    1045                 :         BUILTIN_FCODE( 0x085, "body>" ) ,
    1046                 :         BUILTIN_FCODE( 0x086, ">body" ) ,
    1047                 :         BUILTIN_FCODE( 0x087, "fcode-revision" ) ,
    1048                 :         BUILTIN_FCODE( 0x087, "version" ) , /*  Synonym for "fcode-revision" */
    1049                 :         BI_FCODE_VRBLE( 0x088, "span" ) ,
    1050                 :         BUILTIN_FCODE( 0x089, "unloop" ) ,
    1051                 :         BUILTIN_FCODE( 0x08a, "expect" ) ,
    1052                 :         BUILTIN_FCODE( 0x08b, "alloc-mem" ) ,
    1053                 :         BUILTIN_FCODE( 0x08c, "free-mem" ) ,
    1054                 :         BUILTIN_FCODE( 0x08d, "key?" ) ,
    1055                 :         BUILTIN_FCODE( 0x08e, "key" ) ,
    1056                 :         BUILTIN_FCODE( 0x08f, "emit" ) ,
    1057                 :         BUILTIN_FCODE( 0x090, "type" ) ,
    1058                 :         BUILTIN_FCODE( 0x091, "(cr" ) ,
    1059                 :         BUILTIN_FCODE( 0x092, "cr" ) ,
    1060                 :         BI_FCODE_VRBLE( 0x093, "#out" ) ,
    1061                 :         BI_FCODE_VRBLE( 0x094, "#line" ) ,
    1062                 :         BUILTIN_FCODE( 0x095, "hold" ) ,
    1063                 :         BUILTIN_FCODE( 0x096, "<#" ) ,
    1064                 :         BUILTIN_FCODE( 0x097, "u#>" ) ,
    1065                 :         BUILTIN_FCODE( 0x098, "sign" ) ,
    1066                 :         BUILTIN_FCODE( 0x099, "u#" ) ,
    1067                 :         BUILTIN_FCODE( 0x09a, "u#s" ) ,
    1068                 :         BUILTIN_FCODE( 0x09b, "u." ) ,
    1069                 :         BUILTIN_FCODE( 0x09c, "u.r" ) ,
    1070                 :         BUILTIN_FCODE( 0x09d, "." ) ,
    1071                 :         BUILTIN_FCODE( 0x09e, ".r" ) ,
    1072                 :         BUILTIN_FCODE( 0x09f, ".s" ) ,
    1073                 :         BI_FCODE_VRBLE( 0x0a0, "base" ) ,
    1074                 :         OBSOLETE_FCODE( 0x0a1, "convert" ) ,
    1075                 :         BUILTIN_FCODE( 0x0a2, "$number" ) ,
    1076                 :         BUILTIN_FCODE( 0x0a3, "digit" ) ,
    1077                 :         BI_FCODE_CONST( 0x0a4, "-1" ) ,
    1078                 :         BI_FCODE_CONST( 0x0a4, "true" ) ,          /*  Synonym for "-1" */
    1079                 :         BI_FCODE_CONST( 0x0a5, "0" ) ,
    1080                 :         BI_FCODE_CONST( 0x0a5, "false" ) ,         /*  Synonym for "0" */
    1081                 :         BI_FCODE_CONST( 0x0a5, "struct" ) ,        /*  Synonym for "0" */
    1082                 :         BI_FCODE_CONST( 0x0a6, "1" ) ,
    1083                 :         BI_FCODE_CONST( 0x0a7, "2" ) ,
    1084                 :         BI_FCODE_CONST( 0x0a8, "3" ) ,
    1085                 :         BI_FCODE_CONST( 0x0a9, "bl" ) ,
    1086                 :         BI_FCODE_CONST( 0x0aa, "bs" ) ,
    1087                 :         BI_FCODE_CONST( 0x0ab, "bell" ) ,
    1088                 :         BUILTIN_FCODE( 0x0ac, "bounds" ) ,
    1089                 :         BUILTIN_FCODE( 0x0ad, "here" ) ,
    1090                 :         BUILTIN_FCODE( 0x0ae, "aligned" ) ,
    1091                 :         BUILTIN_FCODE( 0x0af, "wbsplit" ) ,
    1092                 :         BUILTIN_FCODE( 0x0b0, "bwjoin" ) ,
    1093                 :         BUILTIN_FCODE( 0x0b1, "b(<mark)" ) ,
    1094                 :         BUILTIN_FCODE( 0x0b2, "b(>resolve)" ) ,
    1095                 :         OBSOLETE_FCODE( 0x0b3, "set-token-table" ) ,
    1096                 :         OBSOLETE_FCODE( 0x0b4, "set-table" ) ,
    1097                 :         BUILTIN_FCODE( 0x0b5, "new-token" ) ,
    1098                 :         BUILTIN_FCODE( 0x0b6, "named-token" ) ,
    1099                 :         BUILTIN_FCODE( 0x0b7, "b(:)" ) ,
    1100                 :         BUILTIN_FCODE( 0x0b8, "b(value)" ) ,
    1101                 :         BUILTIN_FCODE( 0x0b9, "b(variable)" ) ,
    1102                 :         BUILTIN_FCODE( 0x0ba, "b(constant)" ) ,
    1103                 :         BUILTIN_FCODE( 0x0bb, "b(create)" ) ,
    1104                 :         BUILTIN_FCODE( 0x0bc, "b(defer)" ) ,
    1105                 :         BUILTIN_FCODE( 0x0bd, "b(buffer:)" ) ,
    1106                 :         BUILTIN_FCODE( 0x0be, "b(field)" ) ,
    1107                 :         OBSOLETE_FCODE( 0x0bf, "b(code)" ) ,
    1108                 :         BUILTIN_FCODE( 0x0c0, "instance" ) ,
    1109                 :         BUILTIN_FCODE( 0x0c2, "b(;)" ) ,
    1110                 :         BUILTIN_FCODE( 0x0c3, "b(to)" ) ,
    1111                 :         BUILTIN_FCODE( 0x0c4, "b(case)" ) ,
    1112                 :         BUILTIN_FCODE( 0x0c5, "b(endcase)" ) ,
    1113                 :         BUILTIN_FCODE( 0x0c6, "b(endof)" ) ,
    1114                 :         BUILTIN_FCODE( 0x0c7, "#" ) ,
    1115                 :         BUILTIN_FCODE( 0x0c8, "#s" ) ,
    1116                 :         BUILTIN_FCODE( 0x0c9, "#>" ) ,
    1117                 :         BUILTIN_FCODE( 0x0ca, "external-token" ) ,
    1118                 :         BUILTIN_FCODE( 0x0cb, "$find" ) ,
    1119                 :         BUILTIN_FCODE( 0x0cc, "offset16" ) ,
    1120                 :         BUILTIN_FCODE( 0x0cd, "evaluate" ) ,
    1121                 :         BUILTIN_FCODE( 0x0cd, "eval" ) ,   /*  Synonym for "evaluate"  */
    1122                 :         BUILTIN_FCODE( 0x0d0, "c," ) ,
    1123                 :         BUILTIN_FCODE( 0x0d1, "w," ) ,
    1124                 :         BUILTIN_FCODE( 0x0d2, "l," ) ,
    1125                 :         BUILTIN_FCODE( 0x0d3, "," ) ,
    1126                 :         BUILTIN_FCODE( 0x0d4, "um*" ) ,
    1127                 :         BUILTIN_FCODE( 0x0d4, "u*x" ) ,        /*  Synonym for "um*" */
    1128                 :         BUILTIN_FCODE( 0x0d5, "um/mod" ) ,
    1129                 :         BUILTIN_FCODE( 0x0d5, "xu/mod" ) ,   /*  Synonym for "um/mod"  */
    1130                 :         BUILTIN_FCODE( 0x0d8, "d+" ) ,
    1131                 :         BUILTIN_FCODE( 0x0d8, "x+" ) ,   /*  Synonym for "d+"  */
    1132                 :         BUILTIN_FCODE( 0x0d9, "d-" ) ,
    1133                 :         BUILTIN_FCODE( 0x0d9, "x-" ) ,   /*  Synonym for "d-"  */
    1134                 :         BUILTIN_FCODE( 0x0da, "get-token" ) ,
    1135                 :         BUILTIN_FCODE( 0x0db, "set-token" ) ,
    1136                 :         BI_FCODE_VRBLE( 0x0dc, "state" ) ,
    1137                 :         BUILTIN_FCODE( 0x0dd, "compile" ) ,
    1138                 :         BUILTIN_FCODE( 0x0de, "behavior" ) ,
    1139                 :         BUILTIN_FCODE( 0x0f0, "start0" ) ,
    1140                 :         BUILTIN_FCODE( 0x0f1, "start1" ) ,
    1141                 :         BUILTIN_FCODE( 0x0f2, "start2" ) ,
    1142                 :         BUILTIN_FCODE( 0x0f3, "start4" ) ,
    1143                 :         BUILTIN_FCODE( 0x0fc, "ferror" ) ,
    1144                 :         BUILTIN_FCODE( 0x0fd, "version1" ) ,
    1145                 :         OBSOLETE_FCODE( 0x0fe, "4-byte-id" ) ,
    1146                 :         BUILTIN_FCODE( 0x0ff, "end1" ) ,
    1147                 :         OBSOLETE_FCODE( 0x101, "dma-alloc" ) ,
    1148                 :         BUILTIN_FCODE( 0x102, "my-address" ) ,
    1149                 :         BUILTIN_FCODE( 0x103, "my-space" ) ,
    1150                 :         OBSOLETE_FCODE( 0x104, "memmap" ) ,
    1151                 :         BUILTIN_FCODE( 0x105, "free-virtual" ) ,
    1152                 :         OBSOLETE_FCODE( 0x106, ">physical" ) ,
    1153                 :         OBSOLETE_FCODE( 0x10f, "my-params" ) ,
    1154                 :         BUILTIN_FCODE( 0x110, "property" ) ,
    1155                 :         BUILTIN_FCODE( 0x110, "attribute" ) ,    /*  Synonym for "property"  */
    1156                 :         BUILTIN_FCODE( 0x111, "encode-int" ) ,
    1157                 :         BUILTIN_FCODE( 0x111, "xdrint" ) ,     /*  Synonym for "encode-int"  */
    1158                 :         BUILTIN_FCODE( 0x112, "encode+" ) ,
    1159                 :         BUILTIN_FCODE( 0x112, "xdr+" ) ,          /*  Synonym for "encode+"  */
    1160                 :         BUILTIN_FCODE( 0x113, "encode-phys" ) ,
    1161                 :         BUILTIN_FCODE( 0x113, "xdrphys" ) ,   /*  Synonym for "encode-phys"  */
    1162                 :         BUILTIN_FCODE( 0x114, "encode-string" ) ,
    1163                 :         BUILTIN_FCODE( 0x114, "xdrstring" ) , /* Synonym for "encode-string" */
    1164                 :         BUILTIN_FCODE( 0x115, "encode-bytes" ) ,
    1165                 :         BUILTIN_FCODE( 0x115, "xdrbytes" ) ,  /*  Synonym for "encode-bytes" */
    1166                 :         BUILTIN_FCODE( 0x116, "reg" ) ,
    1167                 :         OBSOLETE_FCODE( 0x117, "intr" ) ,
    1168                 :         OBSOLETE_FCODE( 0x118, "driver" ) ,
    1169                 :         BUILTIN_FCODE( 0x119, "model" ) ,
    1170                 :         BUILTIN_FCODE( 0x11a, "device-type" ) ,
    1171                 :         BUILTIN_FCODE( 0x11b, "parse-2int" ) ,
    1172                 :         BUILTIN_FCODE( 0x11b, "decode-2int" ) , /*  Synonym for "parse-2int" */
    1173                 :         BUILTIN_FCODE( 0x11c, "is-install" ) ,
    1174                 :         BUILTIN_FCODE( 0x11d, "is-remove" ) ,
    1175                 :         BUILTIN_FCODE( 0x11e, "is-selftest" ) ,
    1176                 :         BUILTIN_FCODE( 0x11f, "new-device" ) ,
    1177                 :         BUILTIN_FCODE( 0x120, "diagnostic-mode?" ) ,
    1178                 :         BUILTIN_FCODE( 0x121, "display-status" ) ,
    1179                 :         BUILTIN_FCODE( 0x122, "memory-test-issue" ) ,
    1180                 :         OBSOLETE_FCODE( 0x123, "group-code" ) ,
    1181                 :         BI_FCODE_VRBLE( 0x124, "mask" ) ,
    1182                 :         BUILTIN_FCODE( 0x125, "get-msecs" ) ,
    1183                 :         BUILTIN_FCODE( 0x126, "ms" ) ,
    1184                 :         BUILTIN_FCODE( 0x127, "finish-device" ) ,
    1185                 :         BUILTIN_FCODE( 0x128, "decode-phys" ) ,
    1186                 :         BUILTIN_FCODE( 0x12b, "interpose" ) ,
    1187                 :         BUILTIN_FCODE( 0x130, "map-low" ) ,
    1188                 :         BUILTIN_FCODE( 0x130, "map-sbus" ) ,   /*  Synonym for "map-low"  */
    1189                 :         BUILTIN_FCODE( 0x131, "sbus-intr>cpu" ) ,
    1190                 :         BI_FCODE_VALUE( 0x150, "#lines" ) ,
    1191                 :         BI_FCODE_VALUE( 0x151, "#columns" ) ,
    1192                 :         BI_FCODE_VALUE( 0x152, "line#" ) ,
    1193                 :         BI_FCODE_VALUE( 0x153, "column#" ) ,
    1194                 :         BI_FCODE_VALUE( 0x154, "inverse?" ) ,
    1195                 :         BI_FCODE_VALUE( 0x155, "inverse-screen?" ) ,
    1196                 :         OBSOLETE_VALUE( 0x156, "frame-buffer-busy?" ) ,
    1197                 :         BI_FCODE_DEFER( 0x157, "draw-character" ) ,
    1198                 :         BI_FCODE_DEFER( 0x158, "reset-screen" ) ,
    1199                 :         BI_FCODE_DEFER( 0x159, "toggle-cursor" ) ,
    1200                 :         BI_FCODE_DEFER( 0x15a, "erase-screen" ) ,
    1201                 :         BI_FCODE_DEFER( 0x15b, "blink-screen" ) ,
    1202                 :         BI_FCODE_DEFER( 0x15c, "invert-screen" ) ,
    1203                 :         BI_FCODE_DEFER( 0x15d, "insert-characters" ) ,
    1204                 :         BI_FCODE_DEFER( 0x15e, "delete-characters" ) ,
    1205                 :         BI_FCODE_DEFER( 0x15f, "insert-lines" ) ,
    1206                 :         BI_FCODE_DEFER( 0x160, "delete-lines" ) ,
    1207                 :         BI_FCODE_DEFER( 0x161, "draw-logo" ) ,
    1208                 :         BI_FCODE_VALUE( 0x162, "frame-buffer-adr" ) ,
    1209                 :         BI_FCODE_VALUE( 0x163, "screen-height" ) ,
    1210                 :         BI_FCODE_VALUE( 0x164, "screen-width" ) ,
    1211                 :         BI_FCODE_VALUE( 0x165, "window-top" ) ,
    1212                 :         BI_FCODE_VALUE( 0x166, "window-left" ) ,
    1213                 :         BUILTIN_FCODE( 0x16a, "default-font" ) ,
    1214                 :         BUILTIN_FCODE( 0x16b, "set-font" ) ,
    1215                 :         BI_FCODE_VALUE( 0x16c, "char-height" ) ,
    1216                 :         BI_FCODE_VALUE( 0x16d, "char-width" ) ,
    1217                 :         BUILTIN_FCODE( 0x16e, ">font" ) ,
    1218                 :         BI_FCODE_VALUE( 0x16f, "fontbytes" ) ,
    1219                 :         OBSOLETE_FCODE( 0x170, "fb1-draw-character" ) ,
    1220                 :         OBSOLETE_FCODE( 0x171, "fb1-reset-screen" ) ,
    1221                 :         OBSOLETE_FCODE( 0x172, "fb1-toggle-cursor" ) ,
    1222                 :         OBSOLETE_FCODE( 0x173, "fb1-erase-screen" ) ,
    1223                 :         OBSOLETE_FCODE( 0x174, "fb1-blink-screen" ) ,
    1224                 :         OBSOLETE_FCODE( 0x175, "fb1-invert-screen" ) ,
    1225                 :         OBSOLETE_FCODE( 0x176, "fb1-insert-characters" ) ,
    1226                 :         OBSOLETE_FCODE( 0x177, "fb1-delete-characters" ) ,
    1227                 :         OBSOLETE_FCODE( 0x178, "fb1-insert-lines" ) ,
    1228                 :         OBSOLETE_FCODE( 0x179, "fb1-delete-lines" ) ,
    1229                 :         OBSOLETE_FCODE( 0x17a, "fb1-draw-logo" ) ,
    1230                 :         OBSOLETE_FCODE( 0x17b, "fb1-install" ) ,
    1231                 :         OBSOLETE_FCODE( 0x17c, "fb1-slide-up" ) ,
    1232                 :         BUILTIN_FCODE( 0x180, "fb8-draw-character" ) ,
    1233                 :         BUILTIN_FCODE( 0x181, "fb8-reset-screen" ) ,
    1234                 :         BUILTIN_FCODE( 0x182, "fb8-toggle-cursor" ) ,
    1235                 :         BUILTIN_FCODE( 0x183, "fb8-erase-screen" ) ,
    1236                 :         BUILTIN_FCODE( 0x184, "fb8-blink-screen" ) ,
    1237                 :