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 : |