Home | History | Annotate | Line # | Download | only in fgen
fgen.l revision 1.35.8.1
      1       1.1       eeh %{
      2  1.35.8.1       tls /*	$NetBSD: fgen.l,v 1.35.8.1 2014/08/20 00:04:58 tls Exp $	*/
      3       1.1       eeh /* FLEX input for FORTH input file scanner */
      4       1.2       eeh /*
      5       1.2       eeh  * Copyright (c) 1998 Eduardo Horvath.
      6       1.2       eeh  * All rights reserved.
      7       1.2       eeh  *
      8       1.2       eeh  * Redistribution and use in source and binary forms, with or without
      9       1.2       eeh  * modification, are permitted provided that the following conditions
     10       1.2       eeh  * are met:
     11       1.2       eeh  * 1. Redistributions of source code must retain the above copyright
     12       1.2       eeh  *    notice, this list of conditions and the following disclaimer.
     13       1.2       eeh  * 2. Redistributions in binary form must reproduce the above copyright
     14       1.2       eeh  *    notice, this list of conditions and the following disclaimer in the
     15       1.2       eeh  *    documentation and/or other materials provided with the distribution.
     16       1.2       eeh  *
     17       1.2       eeh  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18       1.2       eeh  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19       1.2       eeh  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20       1.2       eeh  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21       1.2       eeh  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22       1.2       eeh  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23       1.2       eeh  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24       1.2       eeh  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25       1.2       eeh  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26       1.2       eeh  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27       1.2       eeh  */
     28       1.2       eeh /*
     29       1.1       eeh 	Specifications are as follows:
     30       1.1       eeh 
     31       1.1       eeh 	The function "yylex()" always returns a pointer to a structure:
     32       1.1       eeh 
     33       1.1       eeh 	    struct tok {
     34       1.1       eeh 		int type;
     35       1.1       eeh 		char *text;
     36       1.1       eeh 	    }
     37       1.1       eeh 	    #define TOKEN struct tok
     38       1.1       eeh */
     39      1.21       agc #include <sys/cdefs.h>
     40      1.25  dmcmahil #ifdef HAVE_NBTOOL_CONFIG_H
     41      1.25  dmcmahil #include "nbtool_config.h"
     42      1.25  dmcmahil #endif
     43      1.21       agc 
     44      1.22     lukem #if defined(__RCSID) && !defined(lint)
     45  1.35.8.1       tls __RCSID("$NetBSD: fgen.l,v 1.35.8.1 2014/08/20 00:04:58 tls Exp $");
     46      1.21       agc #endif
     47      1.21       agc 
     48       1.1       eeh %}
     49       1.8      tron 
     50      1.34       eeh %option yylineno
     51       1.1       eeh 
     52      1.34       eeh hex	[0-9A-Fa-f]
     53      1.34       eeh hexdot	[0-9A-Fa-f.]
     54       1.1       eeh white	[ \t\n\r\f]
     55       1.1       eeh tail	{white}
     56       1.1       eeh 
     57       1.1       eeh %{
     58       1.3       mrg #include <sys/types.h>
     59      1.24  dmcmahil #include <arpa/inet.h>
     60       1.3       mrg 
     61       1.3       mrg #include <assert.h>
     62       1.7      tron #include <err.h>
     63       1.1       eeh #include <errno.h>
     64       1.3       mrg #include <fcntl.h>
     65       1.6       mrg #include <stdarg.h>
     66       1.1       eeh #include <stdio.h>
     67       1.1       eeh #include <string.h>
     68       1.2       eeh #include <unistd.h>
     69       1.3       mrg 
     70       1.1       eeh #include "fgen.h"
     71      1.35     joerg static TOKEN ltoken;
     72       1.1       eeh 
     73       1.1       eeh /*
     74       1.1       eeh  * Global variables that control the parse state.
     75       1.1       eeh  */
     76       1.1       eeh 
     77      1.35     joerg static struct fcode *dictionary = NULL;
     78      1.35     joerg static struct macro *aliases = NULL;
     79      1.35     joerg static int outf = 1; /* stdout */
     80      1.35     joerg static int state = 0;
     81      1.35     joerg static int nextfcode = 0x800;
     82      1.35     joerg static int numbase = TOK_HEX;
     83      1.35     joerg static long outpos;
     84      1.35     joerg static char *outbuf = NULL;
     85      1.35     joerg static char *outfile, *infile;
     86       1.1       eeh #define BUFCLICK	(1024*1024)
     87      1.35     joerg static size_t outbufsiz = 0;
     88      1.35     joerg static char *myname = NULL;
     89      1.35     joerg static int offsetsize = 8;
     90      1.35     joerg static int defining = 0;
     91      1.35     joerg static int tokenizer = 0;
     92      1.35     joerg static int need_end0 = 1;
     93       1.1       eeh 
     94       1.1       eeh #define PSTKSIZ		1024
     95      1.35     joerg static Cell parse_stack[PSTKSIZ];
     96      1.35     joerg static int parse_stack_ptr = 0;
     97       1.1       eeh 
     98      1.35     joerg static void	token_err(int, const char *, const char *, const char *, ...)
     99      1.35     joerg     __printflike(4, 5) __dead;
    100      1.35     joerg static YY_DECL;
    101       1.2       eeh 
    102      1.35     joerg static int debug = 0;
    103       1.1       eeh #define ASSERT if (debug) assert
    104      1.34       eeh #define STATE(y, x)	do { if (debug) printf( "%lx State %s: token `%s'\n", outpos, x, y); } while (0)
    105      1.35     joerg static int mark_fload = 0;
    106       1.3       mrg 
    107       1.1       eeh %}
    108       1.1       eeh 
    109      1.33  christos %option nounput
    110      1.33  christos 
    111       1.1       eeh %%
    112       1.1       eeh 
    113      1.30     lukem 0		{ ltoken.type = TOK_OTHER; ltoken.text = yytext; return &ltoken; }
    114       1.1       eeh 
    115      1.30     lukem 1		{ ltoken.type = TOK_OTHER; ltoken.text = yytext; return &ltoken; }
    116       1.1       eeh 
    117      1.30     lukem 2		{ ltoken.type = TOK_OTHER; ltoken.text = yytext; return &ltoken; }
    118       1.1       eeh 
    119      1.30     lukem 3		{ ltoken.type = TOK_OTHER; ltoken.text = yytext; return &ltoken; }
    120       1.1       eeh 
    121      1.30     lukem -1		{ ltoken.type = TOK_OTHER; ltoken.text = yytext; return &ltoken; }
    122      1.19       eeh 
    123      1.30     lukem \.		{ ltoken.type = TOK_OTHER; ltoken.text = yytext; return &ltoken; }
    124       1.1       eeh 
    125       1.1       eeh {white}*		/* whitespace -- keep looping */ ;
    126       1.1       eeh 
    127       1.1       eeh \\[^\n]*\n		/* end of line comment -- keep looping */ { STATE(yytext, "EOL comment"); }
    128       1.1       eeh 
    129      1.34       eeh -?{hex}{hexdot}*	{ ltoken.type = TOK_NUMBER; ltoken.text = yytext;
    130      1.30     lukem 					return &ltoken; }
    131       1.1       eeh 
    132      1.30     lukem \'.\'		{ ltoken.type = TOK_C_LIT; ltoken.text = yytext; return &ltoken; }
    133       1.1       eeh 
    134      1.30     lukem \"{white}*(\\\"|[^"])*\"	{ ltoken.type = TOK_STRING_LIT; ltoken.text = yytext;
    135      1.30     lukem 				return &ltoken; } /* String started by `"' or `."' */
    136       1.1       eeh 
    137      1.30     lukem \.\({white}*(\\\"|[^)])*\)	{ ltoken.type = TOK_PSTRING; ltoken.text = yytext;
    138      1.30     lukem 				return &ltoken; } /* String of type `.(.....)' */
    139       1.1       eeh 
    140      1.30     lukem \.\"{white}*(\\\"|[^"])*\"	{ ltoken.type = TOK_PSTRING; ltoken.text = yytext;
    141      1.30     lukem 				return &ltoken; }
    142       1.1       eeh 
    143      1.34       eeh [aA][bB][oO][rR][tT]\"{white}*(\\\"|[^"])*\" { ltoken.type = TOK_ABORT_S;
    144      1.34       eeh 				ltoken.text = yytext;  return &ltoken; }
    145      1.34       eeh 
    146      1.30     lukem "("		{ ltoken.type = TOK_COMMENT; ltoken.text = yytext;
    147      1.30     lukem 				return &ltoken; }
    148       1.1       eeh 
    149      1.30     lukem ":"		{ ltoken.type = TOK_COLON; ltoken.text = yytext;
    150      1.30     lukem 				return &ltoken; }
    151       1.1       eeh 
    152      1.30     lukem ";"		{ ltoken.type = TOK_SEMICOLON; ltoken.text = yytext;
    153      1.30     lukem 				return &ltoken; }
    154       1.1       eeh 
    155      1.30     lukem \'		{ ltoken.type = TOK_TOKENIZE; ltoken.text = yytext;
    156      1.30     lukem 				return &ltoken; }
    157       1.1       eeh 
    158      1.30     lukem [aA][gG][aA][iI][nN]	{ ltoken.type = TOK_AGAIN; ltoken.text = yytext;
    159      1.30     lukem 				return &ltoken; }
    160       1.1       eeh 
    161      1.30     lukem [aA][lL][iI][aA][sS]	{ ltoken.type = TOK_ALIAS; ltoken.text = yytext;
    162      1.30     lukem 				return &ltoken; }
    163       1.1       eeh 
    164      1.30     lukem \[\'\]			{ ltoken.type = TOK_GETTOKEN; ltoken.text = yytext;
    165      1.30     lukem 				return &ltoken; }
    166       1.1       eeh 
    167      1.30     lukem [aA][sS][cC][iI][iI]	{ ltoken.type = TOK_ASCII; ltoken.text = yytext;
    168      1.30     lukem 				return &ltoken; }
    169       1.1       eeh 
    170      1.30     lukem [bB][eE][gG][iI][nN]	{ ltoken.type = TOK_BEGIN; ltoken.text = yytext;
    171      1.30     lukem 				return &ltoken; }
    172       1.1       eeh 
    173      1.30     lukem [bB][uU][fF][fF][eE][rR]:	{ ltoken.type = TOK_BUFFER; ltoken.text = yytext;
    174      1.30     lukem 				return &ltoken; }
    175       1.1       eeh 
    176      1.30     lukem [cC][aA][sS][eE]	{ ltoken.type = TOK_CASE; ltoken.text = yytext;
    177      1.30     lukem 				return &ltoken; }
    178       1.1       eeh 
    179      1.30     lukem [cC][oO][nN][sS][tT][aA][nN][tT]	{ ltoken.type = TOK_CONSTANT; ltoken.text = yytext;
    180      1.30     lukem 				return &ltoken; }
    181       1.1       eeh 
    182      1.30     lukem [cC][oO][nN][tT][rR][oO][lL]	{ ltoken.type = TOK_CONTROL; ltoken.text = yytext;
    183      1.30     lukem 				return &ltoken; }
    184       1.1       eeh 
    185      1.30     lukem [cC][rR][eE][aA][tT][eE]	{ ltoken.type = TOK_CREATE; ltoken.text = yytext;
    186      1.30     lukem 				return &ltoken; }
    187       1.1       eeh 
    188      1.30     lukem [dD]#		{ ltoken.type = TOK_DECIMAL; ltoken.text = yytext;
    189      1.30     lukem 				return &ltoken; }
    190       1.1       eeh 
    191      1.30     lukem [dD][eE][cC][iI][mM][aA][lL]	{ ltoken.type = TOK_DECIMAL; ltoken.text = yytext;
    192      1.30     lukem 				return &ltoken; }
    193       1.1       eeh 
    194      1.30     lukem [dD][eE][fF][eE][rR]	{ ltoken.type = TOK_DEFER; ltoken.text = yytext;
    195      1.30     lukem 				return &ltoken; }
    196       1.1       eeh 
    197      1.30     lukem \??[dD][oO]	{ ltoken.type = TOK_DO; ltoken.text = yytext;
    198      1.30     lukem 				return &ltoken; }
    199       1.1       eeh 
    200      1.30     lukem [eE][lL][sS][eE]	{ ltoken.type = TOK_ELSE; ltoken.text = yytext;
    201      1.30     lukem 				return &ltoken; }
    202       1.1       eeh 
    203      1.34       eeh [eE][nN][dD]0	{ ltoken.type = TOK_END0; ltoken.text = yytext;
    204      1.34       eeh 				return &ltoken; }
    205      1.34       eeh 
    206      1.30     lukem [eE][nN][dD][cC][aA][sS][eE]	{ ltoken.type = TOK_ENDCASE; ltoken.text = yytext;
    207      1.30     lukem 				return &ltoken; }
    208       1.1       eeh 
    209      1.30     lukem [eE][nN][dD][oO][fF]	{ ltoken.type = TOK_ENDOF; ltoken.text = yytext;
    210      1.30     lukem 				return &ltoken; }
    211       1.1       eeh 
    212      1.30     lukem [eE][xX][tT][eE][rR][nN][aA][lL]	{ ltoken.type = TOK_EXTERNAL; ltoken.text = yytext;
    213      1.30     lukem 				return &ltoken; }
    214       1.1       eeh 
    215      1.34       eeh [fF][cC][oO][dD][eE]-[vV][eE][rR][sS][iI][oO][nN]2	{
    216      1.34       eeh 			ltoken.type = TOK_FCODE_VERSION2; ltoken.text = yytext;
    217      1.34       eeh 				return &ltoken; }
    218      1.34       eeh 
    219      1.34       eeh [fF][cC][oO][dD][eE]-[eE][nN][dD]	{ ltoken.type = TOK_FCODE_END; ltoken.text = yytext;
    220      1.34       eeh 				return &ltoken; }
    221      1.34       eeh 
    222      1.30     lukem [fF][iI][eE][lL][dD]	{ ltoken.type = TOK_FIELD; ltoken.text = yytext;
    223      1.30     lukem 				return &ltoken; }
    224       1.1       eeh 
    225      1.30     lukem [hH]#		{ ltoken.type = TOK_HEX; ltoken.text = yytext;
    226      1.30     lukem 				return &ltoken; }
    227       1.1       eeh 
    228      1.30     lukem [hH][eE][aA][dD][eE][rR][lL][eE][sS][sS]	{ ltoken.type = TOK_HEADERLESS; ltoken.text = yytext;
    229      1.30     lukem 				return &ltoken; }
    230       1.1       eeh 
    231      1.30     lukem [hH][eE][aA][dD][eE][rR][sS]	{ ltoken.type = TOK_HEADERS; ltoken.text = yytext;
    232      1.30     lukem 				return &ltoken; }
    233       1.1       eeh 
    234      1.30     lukem [hH][eE][xX]	{ ltoken.type = TOK_HEX; ltoken.text = yytext;
    235      1.30     lukem 				return &ltoken; }
    236       1.1       eeh 
    237      1.30     lukem [iI][fF]		{ ltoken.type = TOK_IF; ltoken.text = yytext;
    238      1.30     lukem 				return &ltoken; }
    239       1.1       eeh 
    240      1.30     lukem \??[lL][eE][aA][vV][eE]	{ ltoken.type = TOK_LEAVE; ltoken.text = yytext;
    241      1.30     lukem 				return &ltoken; }
    242       1.1       eeh 
    243      1.30     lukem \+?[lL][oO][oO][pP]	{ ltoken.type = TOK_LOOP; ltoken.text = yytext;
    244      1.30     lukem 				return &ltoken; }
    245       1.1       eeh 
    246      1.30     lukem [oO]#		{ ltoken.type = TOK_OCTAL; ltoken.text = yytext;
    247      1.30     lukem 				return &ltoken; }
    248       1.1       eeh 
    249      1.30     lukem [oO][cC][tT][aA][lL]	{ ltoken.type = TOK_OCTAL; ltoken.text = yytext;
    250      1.30     lukem 				return &ltoken; }
    251       1.1       eeh 
    252      1.30     lukem [oO][fF]		{ ltoken.type = TOK_OF; ltoken.text = yytext;
    253      1.30     lukem 				return &ltoken; }
    254       1.1       eeh 
    255      1.34       eeh [oO][fF][fF][sS][eE][tT]16	{ ltoken.type = TOK_OFFSET16; ltoken.text = yytext;
    256      1.34       eeh 				return &ltoken; }
    257      1.34       eeh 
    258      1.30     lukem [rR][eE][pP][eE][aA][tT]	{ ltoken.type = TOK_REPEAT; ltoken.text = yytext;
    259      1.30     lukem 				return &ltoken; }
    260       1.1       eeh 
    261      1.34       eeh [sS][tT][aA][rR][tT][0124]	{ ltoken.type = TOK_STARTX; ltoken.text = yytext;
    262      1.34       eeh 				return &ltoken; }
    263      1.34       eeh 
    264      1.30     lukem [tT][hH][eE][nN]	{ ltoken.type = TOK_THEN; ltoken.text = yytext;
    265      1.30     lukem 				return &ltoken; }
    266       1.1       eeh 
    267      1.30     lukem [tT][oO]		{ ltoken.type = TOK_TO; ltoken.text = yytext;
    268      1.30     lukem 				return &ltoken; }
    269       1.1       eeh 
    270      1.30     lukem [uU][nN][tT][iI][lL]	{ ltoken.type = TOK_UNTIL; ltoken.text = yytext;
    271      1.30     lukem 				return &ltoken; }
    272       1.1       eeh 
    273      1.30     lukem [vV][aA][lL][uU][eE]	{ ltoken.type = TOK_VALUE; ltoken.text = yytext;
    274      1.30     lukem 				return &ltoken; }
    275       1.1       eeh 
    276      1.30     lukem [vV][aA][rR][iI][aA][bB][lL][eE]	{ ltoken.type = TOK_VARIABLE; ltoken.text = yytext;
    277      1.30     lukem 				return &ltoken; }
    278       1.1       eeh 
    279      1.34       eeh [vV][eE][rR][sS][iI][oO][nN]1	{ ltoken.type = TOK_VERSION1; ltoken.text = yytext;
    280      1.30     lukem 				return &ltoken; }
    281       1.1       eeh 
    282      1.34       eeh [wW][hH][iI][lL][eE]	{ ltoken.type = TOK_WHILE; ltoken.text = yytext;
    283      1.30     lukem 				return &ltoken; }
    284       1.1       eeh 
    285      1.30     lukem tokenizer\[	{ ltoken.type = TOK_BEGTOK; ltoken.text = yytext;
    286      1.30     lukem 				return &ltoken; }
    287       1.1       eeh 
    288      1.30     lukem emit-byte		{ ltoken.type = TOK_EMIT_BYTE; ltoken.text = yytext;
    289      1.30     lukem 				return &ltoken; }
    290       1.1       eeh 
    291      1.30     lukem \]tokenizer	{ ltoken.type = TOK_ENDTOK; ltoken.text = yytext;
    292      1.30     lukem 				return &ltoken; }
    293       1.1       eeh 
    294      1.34       eeh [fF][lL][oO][aA][dD]	{ ltoken.type = TOK_FLOAD; ltoken.text = yytext;
    295      1.30     lukem 				return &ltoken; }
    296       1.1       eeh 
    297       1.1       eeh 
    298      1.30     lukem [^ \n\t\r\f]+	{ ltoken.type = TOK_OTHER; ltoken.text = yytext;
    299      1.30     lukem 				return &ltoken; }
    300       1.1       eeh 
    301       1.1       eeh <<EOF>>			{ return NULL; }
    302       1.1       eeh %%
    303       1.1       eeh 
    304       1.1       eeh /* Function definitions */
    305      1.35     joerg static void push(Cell);
    306      1.35     joerg static Cell pop(void);
    307      1.35     joerg static int depth(void);
    308      1.35     joerg static int fadd(struct fcode *, struct fcode *);
    309      1.35     joerg static struct fcode *flookup(struct fcode *, const char *);
    310      1.35     joerg static int aadd(struct macro *, struct macro *);
    311      1.35     joerg static struct macro *alookup(struct macro *, const char *);
    312      1.35     joerg static void initdic(void);
    313      1.35     joerg __dead static void usage(const char *);
    314      1.35     joerg static void tokenize(YY_BUFFER_STATE);
    315      1.35     joerg static int emit(const char *);
    316      1.35     joerg static int spit(long);
    317      1.35     joerg static int offspit(long);
    318      1.35     joerg static void sspit(const char *);
    319      1.35     joerg static int apply_macros(YY_BUFFER_STATE, const char *);
    320      1.35     joerg static Cell cvt(const char *, char **, int base);
    321       1.1       eeh 
    322       1.1       eeh /*
    323       1.1       eeh  * Standard FCode names and numbers.  Includes standard
    324       1.1       eeh  * tokenizer aliases.
    325       1.1       eeh  */
    326      1.35     joerg static struct fcode fcodes[] = {
    327      1.30     lukem 		{ "end0",			0x0000, 0, NULL, NULL },
    328      1.30     lukem 		{ "b(lit)",			0x0010, 0, NULL, NULL },
    329      1.30     lukem 		{ "b(')",			0x0011, 0, NULL, NULL },
    330      1.30     lukem 		{ "b(\")",			0x0012, 0, NULL, NULL },
    331      1.30     lukem 		{ "bbranch",			0x0013, 0, NULL, NULL },
    332      1.30     lukem 		{ "b?branch",			0x0014, 0, NULL, NULL },
    333      1.30     lukem 		{ "b(loop)",			0x0015, 0, NULL, NULL },
    334      1.30     lukem 		{ "b(+loop)",			0x0016, 0, NULL, NULL },
    335      1.30     lukem 		{ "b(do)",			0x0017, 0, NULL, NULL },
    336      1.30     lukem 		{ "b(?do)",			0x0018, 0, NULL, NULL },
    337      1.30     lukem 		{ "i",				0x0019, 0, NULL, NULL },
    338      1.30     lukem 		{ "j",				0x001a, 0, NULL, NULL },
    339      1.30     lukem 		{ "b(leave)",			0x001b, 0, NULL, NULL },
    340      1.30     lukem 		{ "b(of)",			0x001c, 0, NULL, NULL },
    341      1.30     lukem 		{ "execute",			0x001d, 0, NULL, NULL },
    342      1.30     lukem 		{ "+",				0x001e, 0, NULL, NULL },
    343      1.30     lukem 		{ "-",				0x001f, 0, NULL, NULL },
    344      1.30     lukem 		{ "*",				0x0020, 0, NULL, NULL },
    345      1.30     lukem 		{ "/",				0x0021, 0, NULL, NULL },
    346      1.30     lukem 		{ "mod",			0x0022, 0, NULL, NULL },
    347      1.30     lukem 		{ "and",			0x0023, 0, NULL, NULL },
    348      1.30     lukem 		{ "or",				0x0024, 0, NULL, NULL },
    349      1.30     lukem 		{ "xor",			0x0025, 0, NULL, NULL },
    350      1.30     lukem 		{ "invert",			0x0026, 0, NULL, NULL },
    351      1.30     lukem 		{ "lshift",			0x0027, 0, NULL, NULL },
    352      1.30     lukem 		{ "rshift",			0x0028, 0, NULL, NULL },
    353      1.30     lukem 		{ ">>a",			0x0029, 0, NULL, NULL },
    354      1.30     lukem 		{ "/mod",			0x002a, 0, NULL, NULL },
    355      1.30     lukem 		{ "u/mod",			0x002b, 0, NULL, NULL },
    356      1.30     lukem 		{ "negate",			0x002c, 0, NULL, NULL },
    357      1.30     lukem 		{ "abs",			0x002d, 0, NULL, NULL },
    358      1.30     lukem 		{ "min",			0x002e, 0, NULL, NULL },
    359      1.30     lukem 		{ "max",			0x002f, 0, NULL, NULL },
    360      1.30     lukem 		{ ">r",				0x0030, 0, NULL, NULL },
    361      1.30     lukem 		{ "r>",				0x0031, 0, NULL, NULL },
    362      1.30     lukem 		{ "r@",				0x0032, 0, NULL, NULL },
    363      1.30     lukem 		{ "exit",			0x0033, 0, NULL, NULL },
    364      1.30     lukem 		{ "0=",				0x0034, 0, NULL, NULL },
    365      1.30     lukem 		{ "0<>",			0x0035, 0, NULL, NULL },
    366      1.30     lukem 		{ "0<",				0x0036, 0, NULL, NULL },
    367      1.30     lukem 		{ "0<=",			0x0037, 0, NULL, NULL },
    368      1.30     lukem 		{ "0>",				0x0038, 0, NULL, NULL },
    369      1.30     lukem 		{ "0>=",			0x0039, 0, NULL, NULL },
    370      1.30     lukem 		{ "<",				0x003a, 0, NULL, NULL },
    371      1.30     lukem 		{ ">",				0x003b, 0, NULL, NULL },
    372      1.30     lukem 		{ "=",				0x003c, 0, NULL, NULL },
    373      1.30     lukem 		{ "<>",				0x003d, 0, NULL, NULL },
    374      1.30     lukem 		{ "u>",				0x003e, 0, NULL, NULL },
    375      1.30     lukem 		{ "u<=",			0x003f, 0, NULL, NULL },
    376      1.30     lukem 		{ "u<",				0x0040, 0, NULL, NULL },
    377      1.30     lukem 		{ "u>=",			0x0041, 0, NULL, NULL },
    378      1.30     lukem 		{ ">=",				0x0042, 0, NULL, NULL },
    379      1.30     lukem 		{ "<=",				0x0043, 0, NULL, NULL },
    380      1.30     lukem 		{ "between",			0x0044, 0, NULL, NULL },
    381      1.30     lukem 		{ "within",			0x0045, 0, NULL, NULL },
    382      1.30     lukem 		{ "drop",			0x0046, 0, NULL, NULL },
    383      1.30     lukem 		{ "dup",			0x0047, 0, NULL, NULL },
    384      1.30     lukem 		{ "over",			0x0048, 0, NULL, NULL },
    385      1.30     lukem 		{ "swap",			0x0049, 0, NULL, NULL },
    386      1.30     lukem 		{ "rot",			0x004a, 0, NULL, NULL },
    387      1.30     lukem 		{ "-rot",			0x004b, 0, NULL, NULL },
    388      1.30     lukem 		{ "tuck",			0x004c, 0, NULL, NULL },
    389      1.30     lukem 		{ "nip",			0x004d, 0, NULL, NULL },
    390      1.30     lukem 		{ "pick",			0x004e, 0, NULL, NULL },
    391      1.30     lukem 		{ "roll",			0x004f, 0, NULL, NULL },
    392      1.30     lukem 		{ "?dup",			0x0050, 0, NULL, NULL },
    393      1.30     lukem 		{ "depth",			0x0051, 0, NULL, NULL },
    394      1.30     lukem 		{ "2drop",			0x0052, 0, NULL, NULL },
    395      1.30     lukem 		{ "2dup",			0x0053, 0, NULL, NULL },
    396      1.30     lukem 		{ "2over",			0x0054, 0, NULL, NULL },
    397      1.30     lukem 		{ "2swap",			0x0055, 0, NULL, NULL },
    398      1.30     lukem 		{ "2rot",			0x0056, 0, NULL, NULL },
    399      1.30     lukem 		{ "2/",				0x0057, 0, NULL, NULL },
    400      1.30     lukem 		{ "u2/",			0x0058, 0, NULL, NULL },
    401      1.30     lukem 		{ "2*",				0x0059, 0, NULL, NULL },
    402      1.30     lukem 		{ "/c",				0x005a, 0, NULL, NULL },
    403      1.30     lukem 		{ "/w",				0x005b, 0, NULL, NULL },
    404      1.30     lukem 		{ "/l",				0x005c, 0, NULL, NULL },
    405      1.30     lukem 		{ "/n",				0x005d, 0, NULL, NULL },
    406      1.30     lukem 		{ "ca+",			0x005e, 0, NULL, NULL },
    407      1.30     lukem 		{ "wa+",			0x005f, 0, NULL, NULL },
    408      1.30     lukem 		{ "la+",			0x0060, 0, NULL, NULL },
    409      1.30     lukem 		{ "na+",			0x0061, 0, NULL, NULL },
    410      1.30     lukem 		{ "char+",			0x0062, 0, NULL, NULL },
    411      1.30     lukem 		{ "wa1+",			0x0063, 0, NULL, NULL },
    412      1.30     lukem 		{ "la1+",			0x0064, 0, NULL, NULL },
    413      1.30     lukem 		{ "cell+",			0x0065, 0, NULL, NULL },
    414      1.30     lukem 		{ "chars",			0x0066, 0, NULL, NULL },
    415      1.30     lukem 		{ "/w*",			0x0067, 0, NULL, NULL },
    416      1.30     lukem 		{ "/l*",			0x0068, 0, NULL, NULL },
    417      1.30     lukem 		{ "cells",			0x0069, 0, NULL, NULL },
    418      1.30     lukem 		{ "on",				0x006a, 0, NULL, NULL },
    419      1.30     lukem 		{ "off",			0x006b, 0, NULL, NULL },
    420      1.30     lukem 		{ "+!",				0x006c, 0, NULL, NULL },
    421      1.30     lukem 		{ "@",				0x006d, 0, NULL, NULL },
    422      1.30     lukem 		{ "l@",				0x006e, 0, NULL, NULL },
    423      1.30     lukem 		{ "w@",				0x006f, 0, NULL, NULL },
    424      1.30     lukem 		{ "<w@",			0x0070, 0, NULL, NULL },
    425      1.30     lukem 		{ "c@",				0x0071, 0, NULL, NULL },
    426      1.30     lukem 		{ "!",				0x0072, 0, NULL, NULL },
    427      1.30     lukem 		{ "l!",				0x0073, 0, NULL, NULL },
    428      1.30     lukem 		{ "w!",				0x0074, 0, NULL, NULL },
    429      1.30     lukem 		{ "c!",				0x0075, 0, NULL, NULL },
    430      1.30     lukem 		{ "2@",				0x0076, 0, NULL, NULL },
    431      1.30     lukem 		{ "2!",				0x0077, 0, NULL, NULL },
    432      1.30     lukem 		{ "move",			0x0078, 0, NULL, NULL },
    433      1.30     lukem 		{ "fill",			0x0079, 0, NULL, NULL },
    434      1.30     lukem 		{ "comp",			0x007a, 0, NULL, NULL },
    435      1.30     lukem 		{ "noop",			0x007b, 0, NULL, NULL },
    436      1.30     lukem 		{ "lwsplit",			0x007c, 0, NULL, NULL },
    437      1.30     lukem 		{ "wjoin",			0x007d, 0, NULL, NULL },
    438      1.30     lukem 		{ "lbsplit",			0x007e, 0, NULL, NULL },
    439      1.30     lukem 		{ "bljoin",			0x007f, 0, NULL, NULL },
    440      1.30     lukem 		{ "wbflip",			0x0080, 0, NULL, NULL },
    441      1.30     lukem 		{ "upc",			0x0081, 0, NULL, NULL },
    442      1.30     lukem 		{ "lcc",			0x0082, 0, NULL, NULL },
    443      1.30     lukem 		{ "pack",			0x0083, 0, NULL, NULL },
    444      1.30     lukem 		{ "count",			0x0084, 0, NULL, NULL },
    445      1.30     lukem 		{ "body>",			0x0085, 0, NULL, NULL },
    446      1.30     lukem 		{ ">body",			0x0086, 0, NULL, NULL },
    447      1.30     lukem 		{ "fcode-revision",		0x0087, 0, NULL, NULL },
    448      1.30     lukem 		{ "span",			0x0088, 0, NULL, NULL },
    449      1.30     lukem 		{ "unloop",			0x0089, 0, NULL, NULL },
    450      1.30     lukem 		{ "expect",			0x008a, 0, NULL, NULL },
    451      1.30     lukem 		{ "alloc-mem",			0x008b, 0, NULL, NULL },
    452      1.30     lukem 		{ "free-mem",			0x008c, 0, NULL, NULL },
    453      1.30     lukem 		{ "key?",			0x008d, 0, NULL, NULL },
    454      1.30     lukem 		{ "key",			0x008e, 0, NULL, NULL },
    455      1.30     lukem 		{ "emit",			0x008f, 0, NULL, NULL },
    456      1.30     lukem 		{ "type",			0x0090, 0, NULL, NULL },
    457      1.30     lukem 		{ "(cr",			0x0091, 0, NULL, NULL },
    458      1.30     lukem 		{ "cr",				0x0092, 0, NULL, NULL },
    459      1.30     lukem 		{ "#out",			0x0093, 0, NULL, NULL },
    460      1.30     lukem 		{ "#line",			0x0094, 0, NULL, NULL },
    461      1.30     lukem 		{ "hold",			0x0095, 0, NULL, NULL },
    462      1.30     lukem 		{ "<#",				0x0096, 0, NULL, NULL },
    463      1.30     lukem 		{ "u#>",			0x0097, 0, NULL, NULL },
    464      1.30     lukem 		{ "sign",			0x0098, 0, NULL, NULL },
    465      1.30     lukem 		{ "u#",				0x0099, 0, NULL, NULL },
    466      1.30     lukem 		{ "u#s",			0x009a, 0, NULL, NULL },
    467      1.30     lukem 		{ "u.",				0x009b, 0, NULL, NULL },
    468      1.30     lukem 		{ "u.r",			0x009c, 0, NULL, NULL },
    469      1.30     lukem 		{ ".",				0x009d, 0, NULL, NULL },
    470      1.30     lukem 		{ ".r",				0x009e, 0, NULL, NULL },
    471      1.30     lukem 		{ ".s",				0x009f, 0, NULL, NULL },
    472      1.30     lukem 		{ "base",			0x00a0, 0, NULL, NULL },
    473      1.30     lukem 		{ "convert",			0x00a1, 0, NULL, NULL },
    474      1.30     lukem 		{ "$number",			0x00a2, 0, NULL, NULL },
    475      1.30     lukem 		{ "digit",			0x00a3, 0, NULL, NULL },
    476      1.30     lukem 		{ "-1",				0x00a4, 0, NULL, NULL },
    477      1.30     lukem 		{ "true",			0x00a4, 0, NULL, NULL },
    478      1.30     lukem 		{ "0",				0x00a5, 0, NULL, NULL },
    479      1.30     lukem 		{ "1",				0x00a6, 0, NULL, NULL },
    480      1.30     lukem 		{ "2",				0x00a7, 0, NULL, NULL },
    481      1.30     lukem 		{ "3",				0x00a8, 0, NULL, NULL },
    482      1.30     lukem 		{ "bl",				0x00a9, 0, NULL, NULL },
    483      1.30     lukem 		{ "bs",				0x00aa, 0, NULL, NULL },
    484      1.30     lukem 		{ "bell",			0x00ab, 0, NULL, NULL },
    485      1.30     lukem 		{ "bounds",			0x00ac, 0, NULL, NULL },
    486      1.30     lukem 		{ "here",			0x00ad, 0, NULL, NULL },
    487      1.30     lukem 		{ "aligned",			0x00ae, 0, NULL, NULL },
    488      1.30     lukem 		{ "wbsplit",			0x00af, 0, NULL, NULL },
    489      1.30     lukem 		{ "bwjoin",			0x00b0, 0, NULL, NULL },
    490      1.30     lukem 		{ "b(<mark)",			0x00b1, 0, NULL, NULL },
    491      1.30     lukem 		{ "b(>resolve)",		0x00b2, 0, NULL, NULL },
    492      1.30     lukem 		{ "set-token-table",		0x00b3, 0, NULL, NULL },
    493      1.30     lukem 		{ "set-table",			0x00b4, 0, NULL, NULL },
    494      1.30     lukem 		{ "new-token",			0x00b5, 0, NULL, NULL },
    495      1.30     lukem 		{ "named-token",		0x00b6, 0, NULL, NULL },
    496      1.30     lukem 		{ "b(:)",			0x00b7, 0, NULL, NULL },
    497      1.30     lukem 		{ "b(value)",			0x00b8, 0, NULL, NULL },
    498      1.30     lukem 		{ "b(variable)",		0x00b9, 0, NULL, NULL },
    499      1.30     lukem 		{ "b(constant)",		0x00ba, 0, NULL, NULL },
    500      1.30     lukem 		{ "b(create)",			0x00bb, 0, NULL, NULL },
    501      1.30     lukem 		{ "b(defer)",			0x00bc, 0, NULL, NULL },
    502      1.30     lukem 		{ "b(buffer:)",			0x00bd, 0, NULL, NULL },
    503      1.30     lukem 		{ "b(field)",			0x00be, 0, NULL, NULL },
    504      1.30     lukem 		{ "b(code)",			0x00bf, 0, NULL, NULL },
    505      1.30     lukem 		{ "instance",			0x00c0, 0, NULL, NULL },
    506      1.30     lukem 		{ "b(;)",			0x00c2, 0, NULL, NULL },
    507      1.30     lukem 		{ "b(to)",			0x00c3, 0, NULL, NULL },
    508      1.30     lukem 		{ "b(case)",			0x00c4, 0, NULL, NULL },
    509      1.30     lukem 		{ "b(endcase)",			0x00c5, 0, NULL, NULL },
    510      1.30     lukem 		{ "b(endof)",			0x00c6, 0, NULL, NULL },
    511      1.30     lukem 		{ "#",				0x00c7, 0, NULL, NULL },
    512      1.30     lukem 		{ "#s",				0x00c8, 0, NULL, NULL },
    513      1.30     lukem 		{ "#>",				0x00c9, 0, NULL, NULL },
    514      1.30     lukem 		{ "external-token",		0x00ca, 0, NULL, NULL },
    515      1.30     lukem 		{ "$find",			0x00cb, 0, NULL, NULL },
    516      1.30     lukem 		{ "offset16",			0x00cc, 0, NULL, NULL },
    517      1.30     lukem 		{ "evaluate",			0x00cd, 0, NULL, NULL },
    518      1.30     lukem 		{ "c,",				0x00d0, 0, NULL, NULL },
    519      1.30     lukem 		{ "w,",				0x00d1, 0, NULL, NULL },
    520      1.30     lukem 		{ "l,",				0x00d2, 0, NULL, NULL },
    521      1.34       eeh 		{ ",",				0x00d3, 0, NULL, NULL },
    522      1.30     lukem 		{ "um*",			0x00d4, 0, NULL, NULL },
    523      1.30     lukem 		{ "um/mod",			0x00d5, 0, NULL, NULL },
    524      1.30     lukem 		{ "d+",				0x00d8, 0, NULL, NULL },
    525      1.30     lukem 		{ "d-",				0x00d9, 0, NULL, NULL },
    526      1.30     lukem 		{ "get-token",			0x00da, 0, NULL, NULL },
    527      1.30     lukem 		{ "set-token",			0x00db, 0, NULL, NULL },
    528      1.30     lukem 		{ "state",			0x00dc, 0, NULL, NULL },
    529      1.30     lukem 		{ "compile,",			0x00dd, 0, NULL, NULL },
    530      1.30     lukem 		{ "behavior",			0x00de, 0, NULL, NULL },
    531      1.30     lukem 		{ "start0",			0x00f0, 0, NULL, NULL },
    532      1.30     lukem 		{ "start1",			0x00f1, 0, NULL, NULL },
    533      1.30     lukem 		{ "start2",			0x00f2, 0, NULL, NULL },
    534      1.30     lukem 		{ "start4",			0x00f3, 0, NULL, NULL },
    535      1.30     lukem 		{ "ferror",			0x00fc, 0, NULL, NULL },
    536      1.30     lukem 		{ "version1",			0x00fd, 0, NULL, NULL },
    537      1.30     lukem 		{ "4-byte-id",			0x00fe, 0, NULL, NULL },
    538      1.30     lukem 		{ "end1",			0x00ff, 0, NULL, NULL },
    539      1.30     lukem 		{ "dma-alloc",			0x0101, 0, NULL, NULL },
    540      1.30     lukem 		{ "my-address",			0x0102, 0, NULL, NULL },
    541      1.30     lukem 		{ "my-space",			0x0103, 0, NULL, NULL },
    542      1.30     lukem 		{ "memmap",			0x0104, 0, NULL, NULL },
    543      1.30     lukem 		{ "free-virtual",		0x0105, 0, NULL, NULL },
    544      1.30     lukem 		{ ">physical",			0x0106, 0, NULL, NULL },
    545      1.30     lukem 		{ "my-params",			0x010f, 0, NULL, NULL },
    546      1.30     lukem 		{ "property",			0x0110, 0, NULL, NULL },
    547      1.30     lukem 		{ "encode-int",			0x0111, 0, NULL, NULL },
    548      1.30     lukem 		{ "encode+",			0x0112, 0, NULL, NULL },
    549      1.30     lukem 		{ "encode-phys",		0x0113, 0, NULL, NULL },
    550      1.30     lukem 		{ "encode-string",		0x0114, 0, NULL, NULL },
    551      1.30     lukem 		{ "encode-bytes",		0x0115, 0, NULL, NULL },
    552      1.30     lukem 		{ "reg",			0x0116, 0, NULL, NULL },
    553      1.30     lukem 		{ "intr",			0x0117, 0, NULL, NULL },
    554      1.30     lukem 		{ "driver",			0x0118, 0, NULL, NULL },
    555      1.30     lukem 		{ "model",			0x0119, 0, NULL, NULL },
    556      1.30     lukem 		{ "device-type",		0x011a, 0, NULL, NULL },
    557      1.30     lukem 		{ "parse-2int",			0x011b, 0, NULL, NULL },
    558      1.30     lukem 		{ "is-install",			0x011c, 0, NULL, NULL },
    559      1.30     lukem 		{ "is-remove",			0x011d, 0, NULL, NULL },
    560      1.30     lukem 		{ "is-selftest",		0x011e, 0, NULL, NULL },
    561      1.30     lukem 		{ "new-device",			0x011f, 0, NULL, NULL },
    562      1.30     lukem 		{ "diagnostic-mode?",		0x0120, 0, NULL, NULL },
    563      1.30     lukem 		{ "display-status",		0x0121, 0, NULL, NULL },
    564      1.30     lukem 		{ "memory-test-suite",		0x0122, 0, NULL, NULL },
    565      1.30     lukem 		{ "group-code",			0x0123, 0, NULL, NULL },
    566      1.30     lukem 		{ "mask",			0x0124, 0, NULL, NULL },
    567      1.30     lukem 		{ "get-msecs",			0x0125, 0, NULL, NULL },
    568      1.30     lukem 		{ "ms",				0x0126, 0, NULL, NULL },
    569      1.34       eeh 		{ "finish-device",		0x0127, 0, NULL, NULL },
    570      1.30     lukem 		{ "decode-phys",		0x0128, 0, NULL, NULL },
    571      1.30     lukem 		{ "map-low",			0x0130, 0, NULL, NULL },
    572      1.30     lukem 		{ "sbus-intr>cpu",		0x0131, 0, NULL, NULL },
    573      1.30     lukem 		{ "#lines",			0x0150, 0, NULL, NULL },
    574      1.30     lukem 		{ "#columns",			0x0151, 0, NULL, NULL },
    575      1.30     lukem 		{ "line#",			0x0152, 0, NULL, NULL },
    576      1.30     lukem 		{ "column#",			0x0153, 0, NULL, NULL },
    577      1.30     lukem 		{ "inverse?",			0x0154, 0, NULL, NULL },
    578      1.30     lukem 		{ "inverse-screen?",		0x0155, 0, NULL, NULL },
    579      1.30     lukem 		{ "frame-buffer-busy?",		0x0156, 0, NULL, NULL },
    580      1.30     lukem 		{ "draw-character",		0x0157, 0, NULL, NULL },
    581      1.30     lukem 		{ "reset-screen",		0x0158, 0, NULL, NULL },
    582      1.30     lukem 		{ "toggle-cursor",		0x0159, 0, NULL, NULL },
    583      1.30     lukem 		{ "erase-screen",		0x015a, 0, NULL, NULL },
    584      1.30     lukem 		{ "blink-screen",		0x015b, 0, NULL, NULL },
    585      1.30     lukem 		{ "invert-screen",		0x015c, 0, NULL, NULL },
    586      1.30     lukem 		{ "insert-characters",		0x015d, 0, NULL, NULL },
    587      1.30     lukem 		{ "delete-characters",		0x015e, 0, NULL, NULL },
    588      1.30     lukem 		{ "insert-lines",		0x015f, 0, NULL, NULL },
    589      1.30     lukem 		{ "delete-lines",		0x0160, 0, NULL, NULL },
    590      1.30     lukem 		{ "draw-logo",			0x0161, 0, NULL, NULL },
    591      1.30     lukem 		{ "frame-buffer-addr",		0x0162, 0, NULL, NULL },
    592      1.30     lukem 		{ "screen-height",		0x0163, 0, NULL, NULL },
    593      1.30     lukem 		{ "screen-width",		0x0164, 0, NULL, NULL },
    594      1.30     lukem 		{ "window-top",			0x0165, 0, NULL, NULL },
    595      1.30     lukem 		{ "window-left",		0x0166, 0, NULL, NULL },
    596      1.30     lukem 		{ "default-font",		0x016a, 0, NULL, NULL },
    597      1.30     lukem 		{ "set-font",			0x016b, 0, NULL, NULL },
    598      1.30     lukem 		{ "char-height",		0x016c, 0, NULL, NULL },
    599      1.30     lukem 		{ "char-width",			0x016d, 0, NULL, NULL },
    600      1.30     lukem 		{ ">font",			0x016e, 0, NULL, NULL },
    601      1.30     lukem 		{ "fontbytes",			0x016f, 0, NULL, NULL },
    602      1.30     lukem 		{ "fb8-draw-character",		0x0180, 0, NULL, NULL },
    603      1.30     lukem 		{ "fb8-reset-screen",		0x0181, 0, NULL, NULL },
    604      1.30     lukem 		{ "fb8-toggle-cursor",		0x0182, 0, NULL, NULL },
    605      1.30     lukem 		{ "fb8-erase-screen",		0x0183, 0, NULL, NULL },
    606      1.30     lukem 		{ "fb8-blink-screen",		0x0184, 0, NULL, NULL },
    607      1.30     lukem 		{ "fb8-invert-screen",		0x0185, 0, NULL, NULL },
    608      1.30     lukem 		{ "fb8-insert-characters",	0x0186, 0, NULL, NULL },
    609      1.30     lukem 		{ "fb8-delete-characters",	0x0187, 0, NULL, NULL },
    610      1.30     lukem 		{ "fb8-inisert-lines",		0x0188, 0, NULL, NULL },
    611      1.30     lukem 		{ "fb8-delete-lines",		0x0189, 0, NULL, NULL },
    612      1.30     lukem 		{ "fb8-draw-logo",		0x018a, 0, NULL, NULL },
    613      1.30     lukem 		{ "fb8-install",		0x018b, 0, NULL, NULL },
    614      1.30     lukem 		{ "return-buffer",		0x01a0, 0, NULL, NULL },
    615      1.30     lukem 		{ "xmit-packet",		0x01a1, 0, NULL, NULL },
    616      1.30     lukem 		{ "poll-packet",		0x01a2, 0, NULL, NULL },
    617      1.30     lukem 		{ "mac-address",		0x01a4, 0, NULL, NULL },
    618      1.30     lukem 		{ "device-name",		0x0201, 0, NULL, NULL },
    619      1.30     lukem 		{ "my-args",			0x0202, 0, NULL, NULL },
    620      1.30     lukem 		{ "my-self",			0x0203, 0, NULL, NULL },
    621      1.30     lukem 		{ "find-package",		0x0204, 0, NULL, NULL },
    622      1.30     lukem 		{ "open-package",		0x0205, 0, NULL, NULL },
    623      1.30     lukem 		{ "close-package",		0x0206, 0, NULL, NULL },
    624      1.30     lukem 		{ "find-method",		0x0207, 0, NULL, NULL },
    625      1.30     lukem 		{ "call-package",		0x0208, 0, NULL, NULL },
    626      1.30     lukem 		{ "$call-parent",		0x0209, 0, NULL, NULL },
    627      1.30     lukem 		{ "my-parent",			0x020a, 0, NULL, NULL },
    628      1.30     lukem 		{ "ihandle>phandle",		0x020b, 0, NULL, NULL },
    629      1.30     lukem 		{ "my-unit",			0x020d, 0, NULL, NULL },
    630      1.30     lukem 		{ "$call-method",		0x020e, 0, NULL, NULL },
    631      1.30     lukem 		{ "$open-package",		0x020f, 0, NULL, NULL },
    632      1.30     lukem 		{ "processor-type",		0x0210, 0, NULL, NULL },
    633      1.30     lukem 		{ "firmware-version",		0x0211, 0, NULL, NULL },
    634      1.30     lukem 		{ "fcode-version",		0x0212, 0, NULL, NULL },
    635      1.30     lukem 		{ "alarm",			0x0213, 0, NULL, NULL },
    636      1.30     lukem 		{ "(is-user-word)",		0x0214, 0, NULL, NULL },
    637      1.30     lukem 		{ "suspend-fcode",		0x0215, 0, NULL, NULL },
    638      1.30     lukem 		{ "abort",			0x0216, 0, NULL, NULL },
    639      1.30     lukem 		{ "catch",			0x0217, 0, NULL, NULL },
    640      1.30     lukem 		{ "throw",			0x0218, 0, NULL, NULL },
    641      1.30     lukem 		{ "user-abort",			0x0219, 0, NULL, NULL },
    642      1.30     lukem 		{ "get-my-property",		0x021a, 0, NULL, NULL },
    643      1.30     lukem 		{ "decode-int",			0x021b, 0, NULL, NULL },
    644      1.30     lukem 		{ "decode-string",		0x021c, 0, NULL, NULL },
    645      1.30     lukem 		{ "get-inherited-property",	0x021d, 0, NULL, NULL },
    646      1.30     lukem 		{ "delete-property",		0x021e, 0, NULL, NULL },
    647      1.30     lukem 		{ "get-package-property",	0x021f, 0, NULL, NULL },
    648      1.30     lukem 		{ "cpeek",			0x0220, 0, NULL, NULL },
    649      1.30     lukem 		{ "wpeek",			0x0221, 0, NULL, NULL },
    650      1.30     lukem 		{ "lpeek",			0x0222, 0, NULL, NULL },
    651      1.30     lukem 		{ "cpoke",			0x0223, 0, NULL, NULL },
    652      1.30     lukem 		{ "wpoke",			0x0224, 0, NULL, NULL },
    653      1.30     lukem 		{ "lpoke",			0x0225, 0, NULL, NULL },
    654      1.30     lukem 		{ "lwflip",			0x0226, 0, NULL, NULL },
    655      1.30     lukem 		{ "lbflip",			0x0227, 0, NULL, NULL },
    656      1.30     lukem 		{ "lbflips",			0x0228, 0, NULL, NULL },
    657      1.30     lukem 		{ "adr-mask",			0x0229, 0, NULL, NULL },
    658      1.30     lukem 		{ "rb@",			0x0230, 0, NULL, NULL },
    659      1.30     lukem 		{ "rb!",			0x0231, 0, NULL, NULL },
    660      1.30     lukem 		{ "rw@",			0x0232, 0, NULL, NULL },
    661      1.30     lukem 		{ "rw!",			0x0233, 0, NULL, NULL },
    662      1.30     lukem 		{ "rl@",			0x0234, 0, NULL, NULL },
    663      1.30     lukem 		{ "rl!",			0x0235, 0, NULL, NULL },
    664      1.30     lukem 		{ "wbflips",			0x0236, 0, NULL, NULL },
    665      1.30     lukem 		{ "lwflips",			0x0237, 0, NULL, NULL },
    666      1.30     lukem 		{ "probe",			0x0238, 0, NULL, NULL },
    667      1.30     lukem 		{ "probe-virtual",		0x0239, 0, NULL, NULL },
    668      1.30     lukem 		{ "child",			0x023b, 0, NULL, NULL },
    669      1.30     lukem 		{ "peer",			0x023c, 0, NULL, NULL },
    670      1.30     lukem 		{ "next-property",		0x023d, 0, NULL, NULL },
    671      1.30     lukem 		{ "byte-load",			0x023e, 0, NULL, NULL },
    672      1.30     lukem 		{ "set-args",			0x023f, 0, NULL, NULL },
    673      1.30     lukem 		{ "left-parse-string",		0x0240, 0, NULL, NULL },
    674       1.1       eeh 			/* 64-bit FCode extensions */
    675      1.30     lukem 		{ "bxjoin",			0x0241, 0, NULL, NULL },
    676      1.30     lukem 		{ "<l@",			0x0242, 0, NULL, NULL },
    677      1.30     lukem 		{ "lxjoin",			0x0243, 0, NULL, NULL },
    678      1.30     lukem 		{ "rx@",			0x022e, 0, NULL, NULL },
    679      1.30     lukem 		{ "rx!",			0x022f, 0, NULL, NULL },
    680      1.30     lukem 		{ "wxjoin",			0x0244, 0, NULL, NULL },
    681      1.30     lukem 		{ "x,",				0x0245, 0, NULL, NULL },
    682      1.30     lukem 		{ "x@",				0x0246, 0, NULL, NULL },
    683      1.30     lukem 		{ "x!",				0x0247, 0, NULL, NULL },
    684      1.30     lukem 		{ "/x",				0x0248, 0, NULL, NULL },
    685      1.30     lukem 		{ "/x*",			0x0249, 0, NULL, NULL },
    686      1.30     lukem 		{ "xa+",			0x024a, 0, NULL, NULL },
    687      1.30     lukem 		{ "xa1+",			0x024b, 0, NULL, NULL },
    688      1.30     lukem 		{ "xbflip",			0x024c, 0, NULL, NULL },
    689      1.30     lukem 		{ "xbflips",			0x024d, 0, NULL, NULL },
    690      1.30     lukem 		{ "xbsplit",			0x024e, 0, NULL, NULL },
    691      1.30     lukem 		{ "xlflip",			0x024f, 0, NULL, NULL },
    692      1.30     lukem 		{ "xlflips",			0x0250, 0, NULL, NULL },
    693      1.30     lukem 		{ "xlsplit",			0x0251, 0, NULL, NULL },
    694      1.30     lukem 		{ "xwflip",			0x0252, 0, NULL, NULL },
    695      1.30     lukem 		{ "xwflips",			0x0253, 0, NULL, NULL },
    696      1.30     lukem 		{ "xwsplit",			0x0254, 0, NULL, NULL },
    697      1.30     lukem 		{ NULL,				0, 0, NULL, NULL }
    698       1.1       eeh };
    699       1.1       eeh 
    700       1.1       eeh /*
    701       1.1       eeh  * Default macros -- can be overridden by colon definitions.
    702       1.1       eeh  */
    703      1.35     joerg static struct macro macros[] = {
    704      1.30     lukem 	{ "eval",	"evaluate", 0, NULL, NULL }, /* Build a more balanced tree */
    705      1.30     lukem 	{ "(.)",	"dup abs <# u#s swap sign u#>", 0, NULL, NULL },
    706      1.30     lukem 	{ "<<",		"lshift", 0, NULL, NULL },
    707      1.30     lukem 	{ ">>",		"rshift", 0, NULL, NULL },
    708      1.30     lukem 	{ "?",		"@ .", 0, NULL, NULL },
    709      1.30     lukem 	{ "1+",		"1 +", 0, NULL, NULL },
    710      1.30     lukem 	{ "1-",		"1 -", 0, NULL, NULL },
    711      1.30     lukem 	{ "2+",		"2 +", 0, NULL, NULL },
    712      1.30     lukem 	{ "2-",		"2 -", 0, NULL, NULL },
    713      1.30     lukem 	{ "abort\"",	"-2 throw", 0, NULL, NULL },
    714      1.30     lukem 	{ "accept",	"span @ -rot expect span @ swap span !", 0, NULL, NULL },
    715      1.30     lukem 	{ "allot",	"0 max 0 ?do 0 c, loop", 0, NULL, NULL },
    716      1.30     lukem 	{ "blank",	"bl fill", 0, NULL, NULL },
    717      1.30     lukem 	{ "/c*",	"chars", 0, NULL, NULL },
    718      1.30     lukem 	{ "ca1+",	"char+", 0, NULL, NULL },
    719      1.34       eeh 	{ "carret",	"b(lit) 00 00 00 h# 0d", 0, NULL, NULL },
    720      1.34       eeh 	{ ".d",		"base @ swap d# 0a base ! . base !", 0, NULL, NULL },
    721      1.30     lukem 	{ "decode-bytes", ">r over r@ + swap r@ - rot r>", 0, NULL, NULL },
    722      1.30     lukem 	{ "3drop",	"drop 2drop", 0, NULL, NULL },
    723      1.30     lukem 	{ "3dup",	"2 pick 2 pick 2 pick", 0, NULL, NULL },
    724      1.30     lukem 	{ "erase",	"0 fill", 0, NULL, NULL },
    725      1.30     lukem 	{ "false",	"0", 0, NULL, NULL },
    726      1.34       eeh 	{ ".h",		"base @ swap d# 10 base ! . base !", 0, NULL, NULL },
    727      1.34       eeh 	{ "linefeed",	"b(lit) 00 00 00 d# 0a", 0, NULL, NULL },
    728      1.30     lukem 	{ "/n*",	"cells", 0, NULL, NULL },
    729      1.30     lukem 	{ "na1+",	"cell+", 0, NULL, NULL },
    730      1.30     lukem 	{ "not",	"invert", 0, NULL, NULL },
    731      1.30     lukem 	{ "s.",		"(.) type space", 0, NULL, NULL },
    732      1.30     lukem 	{ "space",	"bl emit", 0, NULL, NULL },
    733      1.30     lukem 	{ "spaces",	"0 max 0 ?do space loop", 0, NULL, NULL },
    734      1.30     lukem 	{ "struct",	"0", 0, NULL, NULL },
    735      1.30     lukem 	{ "true",	"-1", 0, NULL, NULL },
    736      1.30     lukem 	{ "(u,)",	"<# u#s u#>", 0, NULL, NULL },
    737      1.30     lukem 	{ NULL, NULL, 0, NULL, NULL }
    738       1.1       eeh };
    739       1.1       eeh 
    740       1.1       eeh /*
    741      1.13       eeh  * Utility functions.
    742      1.13       eeh  */
    743      1.13       eeh 
    744      1.13       eeh /*
    745      1.13       eeh  * ASCII -> long int converter, eats `.'s
    746      1.13       eeh  */
    747      1.13       eeh #define strtol(x, y, z)		cvt(x, y, z)
    748      1.35     joerg static Cell
    749      1.30     lukem cvt(const char *s, char **e, int base)
    750      1.13       eeh {
    751      1.14       eeh 	Cell v = 0;
    752      1.13       eeh 	int c, n = 0;
    753      1.13       eeh 
    754      1.13       eeh 	c = *s;
    755      1.13       eeh 	if (c == '-') { n = 1; s++; }
    756      1.13       eeh 
    757      1.13       eeh 	for (c = *s; (c = *s); s++) {
    758      1.13       eeh 
    759      1.13       eeh 		/* Ignore `.' */
    760      1.13       eeh 		if (c == '.')
    761      1.13       eeh 			continue;
    762      1.13       eeh 		if (c >= '0' && c <= '9')
    763      1.13       eeh 			c -= '0';
    764      1.13       eeh 		else if (c >= 'a' && c <= 'f')
    765      1.13       eeh 			c += 10 - 'a';
    766      1.13       eeh 		else if (c >= 'A' && c <= 'F')
    767      1.13       eeh 			c += 10 - 'A';
    768      1.13       eeh 		if (c >= base)
    769      1.13       eeh 			break;
    770      1.13       eeh 		v *= base;
    771      1.13       eeh 		v += c;
    772      1.13       eeh 	}
    773      1.13       eeh 	if (e)
    774      1.30     lukem 		*e = __UNCONST(s);
    775      1.13       eeh 	if (n)
    776      1.13       eeh 		return (-v);
    777      1.13       eeh 	return (v);
    778      1.13       eeh }
    779      1.13       eeh 
    780      1.13       eeh /*
    781       1.1       eeh  * Parser stack control functions.
    782       1.1       eeh  */
    783       1.1       eeh 
    784      1.35     joerg static void
    785      1.28     lukem push(Cell val)
    786       1.1       eeh {
    787      1.34       eeh 	if (debug > 1)
    788      1.34       eeh 		printf("push %lx\n", (long)val);
    789       1.1       eeh 	parse_stack[parse_stack_ptr++] = val;
    790       1.1       eeh 	if (parse_stack_ptr >= PSTKSIZ) {
    791       1.1       eeh 		(void)printf( "Parse stack overflow\n");
    792       1.1       eeh 		exit(1);
    793       1.1       eeh 	}
    794       1.1       eeh }
    795       1.1       eeh 
    796      1.35     joerg static Cell
    797      1.28     lukem pop(void)
    798       1.1       eeh {
    799       1.1       eeh 	ASSERT(parse_stack_ptr);
    800      1.34       eeh 	if (debug > 1)
    801      1.34       eeh 		printf("pop %lx\n", (long)parse_stack[parse_stack_ptr-1]);
    802       1.1       eeh 	return parse_stack[--parse_stack_ptr];
    803       1.1       eeh }
    804       1.1       eeh 
    805      1.35     joerg static int
    806      1.28     lukem depth(void)
    807       1.4       eeh {
    808       1.4       eeh 	return (parse_stack_ptr);
    809       1.4       eeh }
    810       1.4       eeh 
    811       1.1       eeh /*
    812       1.1       eeh  * Insert fcode into dictionary.
    813       1.1       eeh  */
    814      1.35     joerg static int
    815      1.28     lukem fadd(struct fcode *dict, struct fcode *new)
    816       1.1       eeh {
    817       1.1       eeh 	int res = strcmp(dict->name, new->name);
    818       1.1       eeh 
    819       1.1       eeh 	new->type = FCODE;
    820       1.1       eeh 	ASSERT(dict->type == FCODE);
    821      1.34       eeh 	if (!res) {
    822      1.34       eeh 		/*
    823      1.34       eeh 		 * Duplicate entry.  Give the old name the new FCode
    824      1.34       eeh 		 * number.
    825      1.34       eeh 		 */
    826      1.34       eeh 		dict->num = new->num;
    827      1.34       eeh 		return (0);
    828      1.34       eeh 	}
    829       1.1       eeh 	if (res < 0) {
    830       1.1       eeh 		if (dict->l)
    831       1.2       eeh 			return fadd(dict->l, new);
    832       1.1       eeh 		else {
    833      1.34       eeh 			if (debug > 5)
    834       1.2       eeh 				(void)printf( "fadd: new FCode `%s' is %lx\n",
    835       1.1       eeh 					      new->name, new->num);
    836       1.1       eeh 			new->l = new->r = NULL;
    837       1.1       eeh 			dict->l = new;
    838       1.1       eeh 		}
    839       1.1       eeh 	} else {
    840       1.1       eeh 		if (dict->r)
    841       1.2       eeh 			return fadd(dict->r, new);
    842       1.1       eeh 		else {
    843      1.34       eeh 			if (debug > 5)
    844       1.2       eeh 				(void)printf( "fadd: new FCode `%s' is %lx\n",
    845       1.1       eeh 					      new->name, new->num);
    846       1.1       eeh 			new->l = new->r = NULL;
    847       1.1       eeh 			dict->r = new;
    848       1.1       eeh 		}
    849       1.1       eeh 	}
    850       1.1       eeh 	return (1);
    851       1.1       eeh }
    852       1.1       eeh 
    853       1.1       eeh /*
    854       1.1       eeh  * Look for a code in the dictionary.
    855       1.1       eeh  */
    856      1.35     joerg static struct fcode *
    857      1.30     lukem flookup(struct fcode *dict, const char *str)
    858       1.1       eeh {
    859       1.1       eeh 	int res;
    860       1.1       eeh 	if (!dict) return (dict);
    861       1.1       eeh 
    862       1.1       eeh 	res = strcmp(dict->name, str);
    863       1.1       eeh 	ASSERT(dict->type == FCODE);
    864      1.34       eeh 	if (debug > 5)
    865       1.1       eeh 		(void)printf( "flookup: `%s' and `%s' %s match\n",
    866       1.1       eeh 			      str, dict->name, res?"don't":"do");
    867       1.1       eeh 	if (!res) return (dict);
    868       1.1       eeh 	if (res < 0)
    869       1.1       eeh 		return (flookup(dict->l, str));
    870       1.1       eeh 	else
    871       1.1       eeh 		return (flookup(dict->r, str));
    872       1.1       eeh 
    873       1.1       eeh }
    874       1.1       eeh 
    875       1.1       eeh /*
    876       1.1       eeh  * Insert alias into macros.
    877       1.1       eeh  */
    878      1.35     joerg static int
    879      1.28     lukem aadd(struct macro *dict, struct macro *new)
    880       1.1       eeh {
    881       1.1       eeh 	int res = strcmp(dict->name, new->name);
    882       1.1       eeh 
    883       1.1       eeh 	new->type = MACRO;
    884       1.1       eeh 	ASSERT(dict->type == MACRO);
    885      1.34       eeh 	if (!res) {
    886      1.34       eeh 		/* Duplicate name.  Replace the old macro */
    887      1.34       eeh 		dict->equiv = new->equiv;
    888      1.34       eeh 		/* We can't free the old equiv since it may be static data. */
    889      1.34       eeh 		return (0);
    890      1.34       eeh 	}
    891       1.1       eeh 	if (res < 0) {
    892       1.1       eeh 		if (dict->l)
    893       1.2       eeh 			return aadd(dict->l, new);
    894       1.1       eeh 		else {
    895       1.1       eeh 			new->l = new->r = NULL;
    896       1.1       eeh 			dict->l = new;
    897      1.34       eeh 			if (debug > 5)
    898       1.1       eeh 				(void)printf( "aadd: new alias `%s' to `%s'\n",
    899       1.1       eeh 					      new->name, new->equiv);
    900       1.1       eeh 		}
    901       1.1       eeh 	} else {
    902       1.1       eeh 		if (dict->r)
    903       1.2       eeh 			return aadd(dict->r, new);
    904       1.1       eeh 		else {
    905       1.1       eeh 			new->l = new->r = NULL;
    906       1.1       eeh 			dict->r = new;
    907      1.34       eeh 			if (debug > 5)
    908       1.1       eeh 				(void)printf( "aadd: new alias `%s' to `%s'\n",
    909       1.1       eeh 					      new->name, new->equiv);
    910       1.1       eeh 		}
    911       1.1       eeh 	}
    912       1.1       eeh 	return (1);
    913       1.1       eeh }
    914       1.1       eeh 
    915       1.1       eeh /*
    916       1.1       eeh  * Look for a macro in the aliases.
    917       1.1       eeh  */
    918      1.35     joerg static struct macro *
    919      1.30     lukem alookup(struct macro *dict, const char *str)
    920       1.1       eeh {
    921       1.1       eeh 	int res;
    922       1.1       eeh 	if (!dict) return (dict);
    923       1.1       eeh 
    924       1.1       eeh 	ASSERT(dict->type == MACRO);
    925       1.1       eeh 	res = strcmp(dict->name, str);
    926       1.1       eeh 	if (!res) return (dict);
    927       1.1       eeh 	if (res < 0)
    928       1.1       eeh 		return (alookup(dict->l, str));
    929       1.1       eeh 	else
    930       1.1       eeh 		return (alookup(dict->r, str));
    931       1.1       eeh 
    932       1.1       eeh }
    933       1.1       eeh 
    934       1.1       eeh /*
    935       1.1       eeh  * Bootstrap the dictionary and then install
    936       1.1       eeh  * all the standard FCodes.
    937       1.1       eeh  */
    938      1.35     joerg static void
    939      1.28     lukem initdic(void)
    940       1.1       eeh {
    941       1.1       eeh 	struct fcode *code = fcodes;
    942       1.1       eeh 	struct macro *alias = macros;
    943       1.1       eeh 
    944       1.1       eeh 	ASSERT(dictionary == NULL);
    945       1.1       eeh 	code->l = code->r = NULL;
    946       1.1       eeh 	dictionary = code;
    947       1.1       eeh 	code->type = FCODE;
    948       1.1       eeh 
    949       1.1       eeh 	while ((++code)->name) {
    950       1.1       eeh 		if(!fadd(dictionary, code)) {
    951       1.1       eeh 			printf("init: duplicate dictionary entry %s\n",
    952       1.1       eeh 			       code->name);
    953       1.1       eeh 		}
    954       1.1       eeh 	}
    955       1.1       eeh 
    956       1.1       eeh 	ASSERT(aliases == NULL);
    957       1.1       eeh 	aliases = alias;
    958       1.1       eeh 	alias->l = alias->r = NULL;
    959       1.1       eeh 	alias->type = MACRO;
    960       1.1       eeh 	while ((++alias)->name) {
    961       1.1       eeh 		if(!aadd(aliases, alias)) {
    962       1.1       eeh 			printf("init: duplicate macro entry %s\n",
    963       1.1       eeh 			       alias->name);
    964       1.1       eeh 		}
    965       1.1       eeh 	}
    966       1.1       eeh 
    967       1.1       eeh }
    968       1.1       eeh 
    969      1.35     joerg static int
    970      1.30     lukem apply_macros(YY_BUFFER_STATE yinput, const char *str)
    971       1.1       eeh {
    972       1.1       eeh 	struct macro *xform = alookup(aliases, str);
    973       1.1       eeh 
    974       1.1       eeh 	if (xform) {
    975       1.1       eeh 		YY_BUFFER_STATE newbuf;
    976       1.1       eeh 
    977      1.34       eeh 		if (debug > 1)
    978      1.34       eeh 			printf("Expanding %s to %s\n", str, xform->equiv);
    979      1.34       eeh 
    980       1.1       eeh 		newbuf = yy_scan_string(xform->equiv);
    981       1.1       eeh 		yy_switch_to_buffer(newbuf);
    982       1.1       eeh 		tokenize(newbuf);
    983      1.30     lukem 		yy_switch_to_buffer(yinput);
    984       1.1       eeh 		yy_delete_buffer(newbuf);
    985       1.1       eeh 	}
    986       1.1       eeh 	return (xform != NULL);
    987       1.1       eeh }
    988       1.1       eeh 
    989      1.35     joerg static void
    990      1.30     lukem usage(const char *me)
    991       1.1       eeh {
    992      1.34       eeh 	(void)fprintf(stderr, "%s: [-d level] [-o outfile] <infile>\n", me);
    993       1.1       eeh 	exit(1);
    994       1.1       eeh }
    995       1.1       eeh 
    996       1.1       eeh int
    997      1.28     lukem main(int argc, char *argv[])
    998       1.1       eeh {
    999  1.35.8.1       tls 	int ch;
   1000       1.1       eeh 	FILE *inf;
   1001       1.1       eeh 	struct fcode_header *fheader;
   1002       1.1       eeh 	YY_BUFFER_STATE inbuf;
   1003      1.30     lukem 	const char *hdrtype = "version1";
   1004       1.1       eeh 	int i;
   1005       1.1       eeh 
   1006       1.1       eeh 	outf = 1; /* stdout */
   1007       1.1       eeh 	myname = argv[0];
   1008       1.1       eeh 
   1009       1.1       eeh 	while ((ch = getopt(argc, argv, "d:o:")) != -1)
   1010       1.1       eeh 		switch(ch) {
   1011       1.1       eeh 		case 'd':
   1012      1.34       eeh 			mark_fload = 1;
   1013       1.1       eeh 			debug = atol(optarg);
   1014       1.1       eeh 			break;
   1015       1.1       eeh 		case 'o':
   1016       1.6       mrg 			outfile = optarg;
   1017       1.1       eeh 			break;
   1018       1.1       eeh 		default:
   1019       1.1       eeh 			usage(myname);
   1020       1.1       eeh 		}
   1021       1.1       eeh 	argc -= optind;
   1022       1.1       eeh 	argv += optind;
   1023       1.1       eeh 
   1024       1.6       mrg 	if (argc != 1)
   1025       1.6       mrg 		usage(myname);
   1026       1.1       eeh 
   1027       1.6       mrg 	infile = argv[0];
   1028       1.6       mrg 
   1029       1.1       eeh 	/*
   1030       1.1       eeh 	 * Initialization stuff.
   1031       1.1       eeh 	 */
   1032       1.1       eeh 	initdic();
   1033       1.1       eeh 	outbufsiz = BUFCLICK;
   1034       1.1       eeh 	outbuf = malloc(outbufsiz);
   1035       1.1       eeh 	fheader = (struct fcode_header *)outbuf;
   1036       1.1       eeh 	outpos = 0;
   1037       1.1       eeh 	emit(hdrtype);
   1038       1.1       eeh 	outpos = sizeof(*fheader);
   1039       1.1       eeh 
   1040       1.1       eeh 	/*
   1041       1.1       eeh 	 * Do it.
   1042       1.1       eeh 	 */
   1043       1.6       mrg 	if ((inf = fopen(infile, "r")) == NULL)
   1044       1.6       mrg 		(void)err(1, "can not open %s for reading", infile);
   1045       1.1       eeh 
   1046       1.1       eeh 	inbuf = yy_create_buffer( inf, YY_BUF_SIZE );
   1047       1.1       eeh 	yy_switch_to_buffer(inbuf);
   1048       1.3       mrg 	tokenize(inbuf);
   1049       1.1       eeh 	yy_delete_buffer(inbuf);
   1050       1.1       eeh 	fclose(inf);
   1051      1.34       eeh 	if (need_end0) emit("end0");
   1052       1.1       eeh 
   1053       1.1       eeh 	/* Now calculate length and checksum and stick them in the header */
   1054       1.1       eeh 	fheader->format = 0x08;
   1055       1.2       eeh 	fheader->length = htonl(outpos);
   1056       1.1       eeh 	fheader->checksum = 0;
   1057       1.1       eeh 	for (i = sizeof(*fheader); i<outpos; i++)
   1058      1.34       eeh 		fheader->checksum += (unsigned char)outbuf[i];
   1059       1.2       eeh 	fheader->checksum = htons(fheader->checksum);
   1060       1.1       eeh 
   1061      1.17     bjh21 	if ((outf = open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1)
   1062       1.6       mrg 		err(1, "can out open %s for writing", outfile);
   1063       1.6       mrg 
   1064       1.1       eeh 	if (write(outf, outbuf, outpos) != outpos) {
   1065       1.1       eeh 		close(outf);
   1066       1.6       mrg 		unlink(outfile);
   1067       1.6       mrg 		err(1, "write error");
   1068       1.1       eeh 	}
   1069       1.1       eeh 	close(outf);
   1070       1.1       eeh 	return (0);
   1071       1.1       eeh };
   1072       1.1       eeh 
   1073       1.1       eeh /*
   1074       1.1       eeh  * Tokenize one file.  This is a separate function so it can
   1075       1.1       eeh  * be called recursively to parse mutiple levels of include files.
   1076       1.1       eeh  */
   1077       1.1       eeh 
   1078      1.35     joerg static void
   1079      1.30     lukem tokenize(YY_BUFFER_STATE yinput)
   1080       1.1       eeh {
   1081       1.1       eeh 	FILE *inf;
   1082       1.1       eeh 	YY_BUFFER_STATE inbuf;
   1083       1.1       eeh 	TOKEN *token;
   1084      1.30     lukem 	const char *last_token = "";
   1085       1.1       eeh 	struct fcode *fcode;
   1086       1.1       eeh 	int pos, off;
   1087       1.1       eeh 
   1088       1.1       eeh 	while ((token = yylex()) != NULL) {
   1089       1.1       eeh 		switch (token->type) {
   1090       1.1       eeh 		case TOK_NUMBER:
   1091       1.1       eeh 			STATE(token->text, "TOK_NUMBER");
   1092       1.1       eeh 		{
   1093       1.1       eeh 			char *end;
   1094       1.1       eeh 			Cell value;
   1095       1.1       eeh 
   1096       1.1       eeh 			if (tokenizer) {
   1097       1.1       eeh 				push(strtol(token->text, &end, 16));
   1098       1.1       eeh 				break;
   1099       1.1       eeh 			}
   1100      1.30     lukem 			value = strtol(token->text, &end, numbase);
   1101       1.6       mrg 			if (*end != 0)
   1102       1.6       mrg 				token_err(yylineno, infile, yytext,
   1103       1.6       mrg 				    "illegal number conversion");
   1104       1.6       mrg 
   1105       1.1       eeh 			/*
   1106       1.1       eeh 			 * If this is a 64-bit value we need to store two literals
   1107       1.1       eeh 			 * and issue a `lxjoin' to combine them.  But that's a future
   1108       1.1       eeh 			 * project.
   1109       1.1       eeh 			 */
   1110       1.1       eeh 			emit("b(lit)");
   1111      1.13       eeh 			spit((value>>24)&0x0ff);
   1112       1.1       eeh 			spit((value>>16)&0x0ff);
   1113       1.1       eeh 			spit((value>>8)&0x0ff);
   1114       1.1       eeh 			spit(value&0x0ff);
   1115      1.13       eeh 			if ((value>>32) != value && (value>>32) != 0 &&
   1116      1.13       eeh 				(value>>32) != -1) {
   1117      1.13       eeh 				emit("b(lit)");
   1118      1.13       eeh 				spit((value>>56)&0x0ff);
   1119      1.13       eeh 				spit((value>>48)&0x0ff);
   1120      1.13       eeh 				spit((value>>40)&0x0ff);
   1121      1.13       eeh 				spit((value>>32)&0x0ff);
   1122      1.13       eeh 				emit("lxjoin");
   1123      1.13       eeh 			}
   1124       1.1       eeh 		}
   1125       1.1       eeh 		break;
   1126       1.1       eeh 		case TOK_C_LIT:
   1127       1.1       eeh 			STATE(token->text, "TOK_C_LIT");
   1128       1.1       eeh 			emit("b(lit)");
   1129       1.1       eeh 			spit(0);
   1130       1.1       eeh 			spit(0);
   1131       1.1       eeh 			spit(0);
   1132       1.1       eeh 			spit(token->text[1]);
   1133       1.3       mrg 		break;
   1134       1.1       eeh 		case TOK_STRING_LIT:
   1135       1.1       eeh 			STATE(token->text, "TOK_STRING_LIT:");
   1136       1.1       eeh 		{
   1137       1.1       eeh 			int len;
   1138       1.1       eeh 			char *p = token->text;
   1139       1.1       eeh 
   1140       1.1       eeh 			++p;			/* Skip the quote */
   1141       1.1       eeh 			len = strlen(++p);	/* Skip the 1st space */
   1142       1.6       mrg 
   1143       1.6       mrg #define ERR_TOOLONG	\
   1144       1.6       mrg 	token_err(yylineno, infile, yytext, "string length %d too long", len)
   1145       1.6       mrg 
   1146       1.6       mrg 			if (len > 255)
   1147       1.6       mrg 				ERR_TOOLONG;
   1148       1.6       mrg 
   1149       1.1       eeh 			if (p[len-1] == ')' ||
   1150       1.1       eeh 			    p[len-1] == '"') {
   1151       1.1       eeh 				p[len-1] = 0;
   1152       1.1       eeh 			}
   1153       1.1       eeh 			emit("b(\")");
   1154       1.1       eeh 			sspit(p);
   1155       1.1       eeh 		}
   1156       1.1       eeh 		break;
   1157       1.1       eeh 		case TOK_PSTRING:
   1158       1.1       eeh 			STATE(token->text, "TOK_PSTRING:");
   1159       1.1       eeh 		{
   1160       1.1       eeh 			int len;
   1161       1.1       eeh 			char *p = token->text;
   1162       1.1       eeh 
   1163       1.1       eeh 			if (*p++ == '.') p++; /* Skip over delimiter */
   1164       1.1       eeh 			p++; /* Skip over space/tab */
   1165       1.1       eeh 
   1166       1.1       eeh 			len = strlen(p);
   1167       1.6       mrg 			if (len > 255)
   1168       1.6       mrg 				ERR_TOOLONG;
   1169       1.6       mrg 
   1170       1.1       eeh 			if (p[len-1] == ')' ||
   1171       1.1       eeh 			    p[len-1] == '"') {
   1172       1.1       eeh 				p[len-1] = 0;
   1173       1.1       eeh 			}
   1174       1.1       eeh 			emit("b(\")");
   1175       1.1       eeh 			sspit(p);
   1176       1.1       eeh 			emit("type");
   1177       1.1       eeh 		}
   1178       1.1       eeh 		break;
   1179      1.34       eeh 		case TOK_ABORT_S:
   1180      1.34       eeh 			STATE(token->text, "TOK_PSTRING:");
   1181      1.34       eeh 		{
   1182      1.34       eeh 			int len;
   1183      1.34       eeh 			Cell value = -2;
   1184      1.34       eeh 			char *p = token->text;
   1185      1.34       eeh 
   1186      1.34       eeh 			while (*p++ != ' '); /* Skip to the string */
   1187      1.34       eeh 
   1188      1.34       eeh 			len = strlen(p);
   1189      1.34       eeh 			if (len > 255)
   1190      1.34       eeh 				ERR_TOOLONG;
   1191      1.34       eeh 
   1192      1.34       eeh 			if (p[len-1] == '"') {
   1193      1.34       eeh 				p[len-1] = 0;
   1194      1.34       eeh 			}
   1195      1.34       eeh 			emit("b?branch");
   1196      1.34       eeh 			push(outpos);
   1197      1.34       eeh 			offspit(0);
   1198      1.34       eeh 			emit("b(\")");
   1199      1.34       eeh 			sspit(p);
   1200      1.34       eeh 			emit("type");
   1201      1.34       eeh 			emit("cr");
   1202      1.34       eeh 			emit("b(lit)");
   1203      1.34       eeh 			spit((value>>24)&0x0ff);
   1204      1.34       eeh 			spit((value>>16)&0x0ff);
   1205      1.34       eeh 			spit((value>>8)&0x0ff);
   1206      1.34       eeh 			spit(value&0x0ff);
   1207      1.34       eeh 			emit("throw");
   1208      1.34       eeh 			emit("b(>resolve)");
   1209      1.34       eeh 			pos = outpos;
   1210      1.34       eeh 			outpos = pop();
   1211      1.34       eeh 			off = pos - outpos;
   1212      1.34       eeh 			offspit(off);
   1213      1.34       eeh 			outpos = pos;
   1214      1.34       eeh 		}
   1215      1.34       eeh 		break;
   1216      1.34       eeh 
   1217       1.1       eeh 		case TOK_TOKENIZE:
   1218       1.1       eeh 			STATE(token->text, "TOK_TOKENIZE");
   1219       1.1       eeh 			/* The next pass should tokenize the FCODE number */
   1220       1.1       eeh 			emit("b(')");
   1221       1.1       eeh 			break;
   1222       1.1       eeh 		case TOK_COMMENT:
   1223       1.1       eeh 			STATE(token->text, "TOK_COMMENT:");
   1224      1.34       eeh 			do {
   1225      1.34       eeh 				off = input();
   1226      1.34       eeh 			} while ((off != ')') && (off != '\n') &&
   1227      1.34       eeh 				(off != EOF));
   1228       1.1       eeh 			break;
   1229       1.1       eeh 		case TOK_COLON:
   1230       1.1       eeh 			STATE(token->text, "TOK_COLON:");
   1231       1.1       eeh 
   1232       1.1       eeh 			token = yylex();
   1233       1.6       mrg 			if (token == NULL)
   1234       1.6       mrg 				token_err(yylineno, infile, yytext,
   1235       1.6       mrg 				    "EOF in colon definition");
   1236       1.1       eeh 
   1237       1.1       eeh 			/* Add new code to dictionary */
   1238       1.1       eeh 			fcode = malloc(sizeof(*fcode));
   1239       1.1       eeh 			fcode->num = nextfcode++;
   1240       1.1       eeh 			fcode->name = strdup(token->text);
   1241      1.34       eeh 			if (!fadd(dictionary, fcode)) {
   1242      1.34       eeh 				/* Duplicate definition.  Free the memory. */
   1243      1.34       eeh 				if (debug)
   1244      1.34       eeh 					(void)printf("%s: duplicate FCode\n",
   1245      1.34       eeh 						token->text);
   1246      1.34       eeh 				free(__UNCONST(fcode->name));
   1247      1.34       eeh 				free(fcode);
   1248      1.34       eeh 			}
   1249       1.6       mrg 			if (debug)
   1250       1.6       mrg 				(void)printf("Adding %s to dictionary\n", token->text);
   1251       1.1       eeh 			if (state == 0)
   1252       1.1       eeh 				emit("new-token");
   1253       1.1       eeh 			else {
   1254       1.1       eeh 				if (state == TOK_EXTERNAL)
   1255       1.1       eeh 					emit("external-token");
   1256       1.1       eeh 				else
   1257       1.1       eeh 				/* Here we have a choice of new-token or named-token */
   1258       1.1       eeh 					emit("named-token");
   1259       1.1       eeh 				sspit(token->text);
   1260       1.1       eeh 			}
   1261       1.1       eeh 			spit(fcode->num);
   1262       1.1       eeh 			emit("b(:)");
   1263       1.4       eeh 			last_token = fcode->name;
   1264       1.1       eeh 			defining = 1;
   1265       1.1       eeh  			break;
   1266       1.1       eeh 		case TOK_SEMICOLON:
   1267       1.1       eeh 			STATE(token->text, "TOK_SEMICOLON:");
   1268       1.1       eeh 			emit("b(;)");
   1269       1.1       eeh 			defining = 0;
   1270       1.4       eeh 			if (depth()) {
   1271       1.6       mrg 				token_err(yylineno, infile, NULL,
   1272       1.6       mrg 				    "Warning: stack depth %d at end of %s\n",
   1273       1.6       mrg 				    depth(), last_token);
   1274       1.4       eeh 			}
   1275       1.4       eeh 			last_token = "";
   1276       1.1       eeh 			break;
   1277       1.1       eeh 
   1278       1.1       eeh 			/* These are special */
   1279       1.1       eeh 		case TOK_AGAIN:
   1280       1.1       eeh 			STATE(token->text, "TOK_AGAIN");
   1281       1.1       eeh 			emit("bbranch");
   1282       1.1       eeh 			pos = pop();
   1283      1.34       eeh 			pos = pos - outpos;
   1284      1.34       eeh 			offspit(pos);
   1285       1.1       eeh 			break;
   1286       1.1       eeh 		case TOK_ALIAS:
   1287       1.1       eeh 			STATE(token->text, "TOK_ALIAS");
   1288       1.1       eeh 		{
   1289       1.1       eeh 			struct macro *alias;
   1290       1.1       eeh 
   1291       1.1       eeh 			token = yylex();
   1292       1.1       eeh 			if (token == NULL) {
   1293       1.1       eeh 				(void)printf( "EOF in alias definition\n");
   1294       1.3       mrg 				return;
   1295       1.1       eeh 			}
   1296       1.1       eeh 			if (token->type != TOK_OTHER) {
   1297       1.1       eeh 				(void)printf( "ENDCOMMENT aliasing weird token type %d\n",
   1298       1.1       eeh 					      token->type);
   1299       1.1       eeh 			}
   1300       1.1       eeh 			alias = malloc(sizeof(*alias));
   1301       1.1       eeh 			alias->name = strdup(token->text);
   1302       1.1       eeh 			token = yylex();
   1303       1.1       eeh 			if (token == NULL) {
   1304       1.1       eeh 				(void)printf( "EOF in alias definition\n");
   1305       1.3       mrg 				return;
   1306       1.1       eeh 			}
   1307       1.1       eeh 			alias->equiv = strdup(token->text);
   1308       1.1       eeh 			if (!aadd(aliases, alias)) {
   1309      1.34       eeh 				free(__UNCONST(alias->name));
   1310      1.34       eeh 				free(alias);
   1311       1.1       eeh 			}
   1312       1.1       eeh 		}
   1313       1.1       eeh 		break;
   1314       1.1       eeh 		case TOK_GETTOKEN:
   1315       1.1       eeh 			STATE(token->text, "TOK_GETTOKEN");
   1316       1.1       eeh 			/* This is caused by ['] */
   1317       1.1       eeh 			emit("b(')");
   1318       1.1       eeh 			token = yylex();
   1319       1.1       eeh 			if (token == NULL) {
   1320       1.1       eeh 				(void)printf( "EOF in [']\n");
   1321       1.3       mrg 				return;
   1322       1.1       eeh 			}
   1323       1.1       eeh 			if ((fcode = flookup(dictionary, token->text)) == NULL) {
   1324       1.1       eeh 				(void)printf( "[']: %s not found\n", token->text);
   1325       1.1       eeh 				exit(1);
   1326       1.1       eeh 			}
   1327       1.1       eeh 			spit(fcode->num);
   1328       1.1       eeh 			break;
   1329       1.1       eeh 		case TOK_ASCII:
   1330       1.1       eeh 			STATE(token->text, "TOK_ASCII");
   1331       1.1       eeh 			token = yylex();
   1332       1.1       eeh 			if (token == NULL) {
   1333       1.1       eeh 				(void)printf( "EOF after \"ascii\"\n");
   1334       1.1       eeh 				exit(1);
   1335       1.1       eeh 			}
   1336       1.1       eeh 			emit("b(lit)");
   1337       1.1       eeh 			spit(0);
   1338       1.1       eeh 			spit(0);
   1339       1.1       eeh 			spit(0);
   1340       1.1       eeh 			spit(token->text[0]);
   1341       1.1       eeh 			break;
   1342       1.1       eeh 		case TOK_BEGIN:
   1343       1.1       eeh 			STATE(token->text, "TOK_BEGIN");
   1344       1.1       eeh 			emit("b(<mark)");
   1345       1.1       eeh 			push(outpos);
   1346       1.1       eeh 			break;
   1347       1.1       eeh 		case TOK_BUFFER:
   1348       1.1       eeh 			STATE(token->text, "TOK_BUFFER");
   1349       1.1       eeh 
   1350       1.1       eeh 			token = yylex();
   1351       1.1       eeh 			if (token == NULL) {
   1352       1.1       eeh 				(void)printf( "EOF in colon definition\n");
   1353       1.3       mrg 				return;
   1354       1.1       eeh 			}
   1355       1.1       eeh 
   1356       1.1       eeh 			/* Add new code to dictionary */
   1357       1.1       eeh 			fcode = malloc(sizeof(*fcode));
   1358       1.1       eeh 			fcode->num = nextfcode++;
   1359       1.1       eeh 			fcode->name = strdup(token->text);
   1360       1.1       eeh 			fadd(dictionary, fcode);
   1361       1.1       eeh 
   1362       1.1       eeh 			if (state == 0)
   1363       1.1       eeh 				emit("new-token");
   1364       1.1       eeh 			else {
   1365       1.1       eeh 				if (state == TOK_EXTERNAL)
   1366       1.1       eeh 					emit("external-token");
   1367       1.1       eeh 				else
   1368       1.1       eeh 				/* Here we have a choice of new-token or named-token */
   1369       1.1       eeh 					emit("named-token");
   1370       1.1       eeh 				sspit(token->text);
   1371       1.1       eeh 			}
   1372       1.1       eeh 			spit(fcode->num);
   1373       1.1       eeh 			emit("b(buffer:)");
   1374       1.1       eeh 			break;
   1375       1.1       eeh 		case TOK_CASE:
   1376       1.1       eeh 			STATE(token->text, "TOK_CASE");
   1377       1.1       eeh 			emit("b(case)");
   1378       1.1       eeh 			push(0);
   1379       1.1       eeh 			break;
   1380       1.1       eeh 		case TOK_CONSTANT:
   1381       1.1       eeh 			STATE(token->text, "TOK_CONSTANT");
   1382       1.1       eeh 
   1383       1.1       eeh 			token = yylex();
   1384       1.1       eeh 			if (token == NULL) {
   1385       1.1       eeh 				(void)printf( "EOF in constant definition\n");
   1386       1.3       mrg 				return;
   1387       1.1       eeh 			}
   1388       1.1       eeh 
   1389       1.1       eeh 			/* Add new code to dictionary */
   1390       1.1       eeh 			fcode = malloc(sizeof(*fcode));
   1391       1.1       eeh 			fcode->num = nextfcode++;
   1392       1.1       eeh 			fcode->name = strdup(token->text);
   1393       1.1       eeh 			fadd(dictionary, fcode);
   1394       1.1       eeh 
   1395       1.1       eeh 			if (state == 0)
   1396       1.1       eeh 				emit("new-token");
   1397       1.1       eeh 			else {
   1398       1.1       eeh 				if (state == TOK_EXTERNAL)
   1399       1.1       eeh 					emit("external-token");
   1400       1.1       eeh 				else
   1401       1.1       eeh 				/* Here we have a choice of new-token or named-token */
   1402       1.1       eeh 					emit("named-token");
   1403       1.1       eeh 				sspit(token->text);
   1404       1.1       eeh 			}
   1405       1.1       eeh 			spit(fcode->num);
   1406       1.1       eeh 			emit("b(constant)");
   1407       1.1       eeh 			break;
   1408       1.1       eeh 		case TOK_CONTROL:
   1409       1.1       eeh 			STATE(token->text, "TOK_CONTROL");
   1410       1.1       eeh 			token = yylex();
   1411       1.1       eeh 			if (token == NULL) {
   1412       1.1       eeh 				(void)printf( "EOF after \"ascii\"\n");
   1413       1.1       eeh 				exit(1);
   1414       1.1       eeh 			}
   1415       1.1       eeh 			emit("b(lit)");
   1416       1.1       eeh 			spit(0);
   1417       1.1       eeh 			spit(0);
   1418       1.1       eeh 			spit(0);
   1419       1.1       eeh 			spit(token->text[0]&0x1f);
   1420       1.1       eeh 			break;
   1421       1.1       eeh 		case TOK_CREATE:
   1422       1.1       eeh 			STATE(token->text, "TOK_CREATE");
   1423       1.1       eeh 			/* Don't know what this does or if it's right */
   1424       1.1       eeh 			token = yylex();
   1425       1.1       eeh 			if (token == NULL) {
   1426       1.1       eeh 				(void)printf( "EOF in create definition\n");
   1427       1.3       mrg 				return;
   1428       1.1       eeh 			}
   1429       1.1       eeh 
   1430       1.1       eeh 			/* Add new code to dictionary */
   1431       1.1       eeh 			fcode = malloc(sizeof(*fcode));
   1432       1.1       eeh 			fcode->num = nextfcode++;
   1433       1.1       eeh 			fcode->name = strdup(token->text);
   1434       1.1       eeh 			fadd(dictionary, fcode);
   1435       1.1       eeh 
   1436       1.1       eeh 			if (state == 0)
   1437       1.1       eeh 				emit("new-token");
   1438       1.1       eeh 			else {
   1439       1.1       eeh 				if (state == TOK_EXTERNAL)
   1440       1.1       eeh 					emit("external-token");
   1441       1.1       eeh 				else
   1442       1.1       eeh 				/* Here we have a choice of new-token or named-token */
   1443       1.1       eeh 					emit("named-token");
   1444       1.1       eeh 				sspit(token->text);
   1445       1.1       eeh 			}
   1446       1.1       eeh 			spit(fcode->num);
   1447       1.1       eeh 			emit("b(create)");
   1448       1.1       eeh 			break;
   1449       1.1       eeh 		case TOK_DECIMAL:
   1450       1.1       eeh 			STATE(token->text, "TOK_DECIMAL");
   1451       1.1       eeh 			if (token->text[1] != '#') {
   1452       1.1       eeh 				if (defining) {
   1453      1.34       eeh 					emit("b(lit)");
   1454      1.34       eeh 					spit(0);
   1455      1.34       eeh 					spit(0);
   1456      1.34       eeh 					spit(0);
   1457       1.1       eeh 					spit(10);
   1458       1.1       eeh 					emit("base");
   1459       1.1       eeh 					emit("!");
   1460       1.1       eeh 				} else
   1461      1.30     lukem 					numbase = TOK_DECIMAL;
   1462       1.1       eeh 			} else {
   1463       1.1       eeh 				char *end;
   1464       1.1       eeh 				Cell value;
   1465       1.1       eeh 
   1466       1.1       eeh 				token = yylex();
   1467       1.1       eeh 				if (token == NULL) {
   1468       1.1       eeh 					(void)printf( "EOF after d#\n");
   1469       1.3       mrg 					return;
   1470       1.1       eeh 				}
   1471       1.1       eeh 				if (token->type == TOK_OTHER) {
   1472       1.1       eeh 					if (strcmp("-1", token->text) == 0) {
   1473       1.1       eeh 						emit(token->text);
   1474       1.1       eeh 						break;
   1475       1.1       eeh 					}
   1476       1.1       eeh 				}
   1477       1.1       eeh 				value = strtol(token->text, &end, 10);
   1478       1.6       mrg 				if (*end != 0)
   1479       1.6       mrg 					token_err(yylineno, infile, NULL,
   1480       1.6       mrg 					    "Illegal number conversion: %s", token->text);
   1481       1.6       mrg 
   1482       1.1       eeh 				/*
   1483       1.1       eeh 				 * If this is a 64-bit value we need to store two literals
   1484       1.1       eeh 				 * and issue a `lxjoin' to combine them.  But that's a future
   1485       1.1       eeh 				 * project.
   1486       1.1       eeh 				 */
   1487       1.1       eeh 				emit("b(lit)");
   1488      1.13       eeh 				spit((value>>24)&0x0ff);
   1489       1.1       eeh 				spit((value>>16)&0x0ff);
   1490       1.1       eeh 				spit((value>>8)&0x0ff);
   1491       1.1       eeh 				spit(value&0x0ff);
   1492      1.15       eeh 				if ((value>>32) != value && (value>>32) != 0) {
   1493      1.13       eeh 					emit("b(lit)");
   1494      1.13       eeh 					spit((value>>56)&0x0ff);
   1495      1.13       eeh 					spit((value>>48)&0x0ff);
   1496      1.13       eeh 					spit((value>>40)&0x0ff);
   1497      1.13       eeh 					spit((value>>32)&0x0ff);
   1498      1.13       eeh 					emit("lxjoin");
   1499      1.13       eeh 				}
   1500       1.1       eeh 			}
   1501       1.1       eeh 			break;
   1502       1.1       eeh 		case TOK_DEFER:
   1503       1.1       eeh 			STATE(token->text, "TOK_DEFER");
   1504       1.1       eeh 			/* Don't know what this does or if it's right */
   1505       1.1       eeh 			token = yylex();
   1506       1.1       eeh 			if (token == NULL) {
   1507       1.1       eeh 				(void)printf( "EOF in colon definition\n");
   1508       1.3       mrg 				return;
   1509       1.1       eeh 			}
   1510       1.1       eeh 
   1511       1.1       eeh 			/* Add new code to dictionary */
   1512       1.1       eeh 			fcode = malloc(sizeof(*fcode));
   1513       1.1       eeh 			fcode->num = nextfcode++;
   1514       1.1       eeh 			fcode->name = strdup(token->text);
   1515       1.1       eeh 			fadd(dictionary, fcode);
   1516       1.1       eeh 
   1517       1.1       eeh 			if (state == 0)
   1518       1.1       eeh 				emit("new-token");
   1519       1.1       eeh 			else {
   1520       1.1       eeh 				if (state == TOK_EXTERNAL)
   1521       1.1       eeh 					emit("external-token");
   1522       1.1       eeh 				else
   1523       1.1       eeh 				/* Here we have a choice of new-token or named-token */
   1524       1.1       eeh 					emit("named-token");
   1525       1.1       eeh 				sspit(token->text);
   1526       1.1       eeh 			}
   1527       1.1       eeh 			spit(fcode->num);
   1528       1.1       eeh 			emit("b(defer)");
   1529       1.1       eeh 			break;
   1530       1.1       eeh 		case TOK_DO:
   1531       1.1       eeh 			STATE(token->text, "TOK_DO");
   1532       1.1       eeh 			/*
   1533       1.1       eeh 			 * From the 1275 spec.  B is branch location, T is branch target.
   1534       1.1       eeh 			 *
   1535       1.1       eeh 			 *	b(do)  offset1 ... b(loop)  offset2 ...
   1536       1.1       eeh 			 *	b(do)  offset1 ... b(+loop) offset2 ...
   1537       1.1       eeh 			 *	b(?do) offset1 ... b(loop)  offset2 ...
   1538       1.1       eeh 			 *	b(?do) offset1 ... b(+loop) offset2 ...
   1539       1.1       eeh 			 *            ^                            ^
   1540       1.1       eeh 			 *           B1       ^            ^       T1
   1541       1.1       eeh 			 *                    T2           B2
   1542       1.1       eeh 			 *
   1543       1.1       eeh 			 * How we do this is we generate the b(do) or b(?do), spit out a
   1544       1.1       eeh 			 * zero offset while remembering b1 and t2.  Then we call tokenize()
   1545       1.1       eeh 			 * to generate the body.  When tokenize() finds a b(loop) or b(+loop),
   1546       1.1       eeh 			 * it generates the FCode and returns, with outpos at b2.  We then
   1547       1.1       eeh 			 * calculate the offsets, put them in the right slots and finishup.
   1548       1.1       eeh 			 */
   1549       1.1       eeh 
   1550       1.1       eeh 			if (token->text[0] == '?')
   1551       1.1       eeh 				emit("b(?do)");
   1552       1.1       eeh 			else
   1553       1.1       eeh 				emit("b(do)");
   1554       1.1       eeh 			push(outpos);
   1555      1.34       eeh 			offspit(0);	/* Place holder for later */
   1556       1.1       eeh 			push(outpos);
   1557       1.1       eeh 			break;
   1558      1.34       eeh 		case TOK_END0:
   1559      1.34       eeh 			STATE(token->text, "TOK_END0");
   1560      1.34       eeh 			emit("end0");
   1561      1.34       eeh 			/* Remember we already generated end0 */
   1562      1.34       eeh 			need_end0 = 0;
   1563      1.34       eeh 			break;
   1564       1.1       eeh 		case TOK_ELSE:
   1565       1.1       eeh 			STATE(token->text, "TOK_ELSE");
   1566       1.1       eeh 			/* Get where we need to patch */
   1567       1.1       eeh 			off = pop();
   1568       1.1       eeh 			emit("bbranch");
   1569       1.1       eeh 			/* Save where we are now. */
   1570       1.1       eeh 			push(outpos);
   1571      1.34       eeh 			offspit(0);	/* Place holder for later */
   1572       1.1       eeh 			emit("b(>resolve)");
   1573       1.1       eeh 			/* Rewind and patch the if branch */
   1574       1.1       eeh 			pos = outpos;
   1575       1.1       eeh 			outpos = off;
   1576       1.1       eeh 			off = pos - off;
   1577      1.34       eeh 			offspit(off);	/* Place holder for later */
   1578       1.1       eeh 			/* revert to the end */
   1579       1.1       eeh 			outpos = pos;
   1580       1.1       eeh 			break;
   1581       1.1       eeh 		case TOK_ENDCASE:
   1582       1.1       eeh 			STATE(token->text, "TOK_ENDCASE:");
   1583      1.34       eeh 			emit("b(endcase)");
   1584       1.1       eeh 			pos = outpos; /* Remember where we need to branch to */
   1585       1.1       eeh 
   1586       1.1       eeh 			/* Thread our way backwards and install proper offsets */
   1587       1.1       eeh 			off = pop();
   1588       1.1       eeh 			while (off) {
   1589      1.34       eeh 				int disp;
   1590      1.34       eeh 				int next;
   1591       1.1       eeh 
   1592       1.1       eeh 				/* Move to this offset */
   1593       1.1       eeh 				outpos = off;
   1594       1.1       eeh 				/* Load next offset to process */
   1595      1.34       eeh 				disp = (signed char)(outbuf[outpos]);
   1596      1.34       eeh 				if (offsetsize == 16) {
   1597      1.34       eeh 					disp = (disp << 8) |
   1598      1.34       eeh 						(unsigned char)outbuf[outpos+1];
   1599      1.34       eeh 				}
   1600      1.34       eeh 				next = outpos + disp;
   1601      1.34       eeh 				if (debug > 3)
   1602      1.34       eeh 					printf("Next endof: %x at %x\n",
   1603      1.34       eeh 						disp, next);
   1604       1.1       eeh 
   1605       1.1       eeh 				/* process this offset */
   1606       1.1       eeh 				off = pos - outpos;
   1607      1.34       eeh 				offspit(off);
   1608      1.34       eeh 				if ((off = disp))
   1609      1.34       eeh 					off = next;
   1610       1.1       eeh 			}
   1611       1.1       eeh 			outpos = pos;
   1612       1.1       eeh 			break;
   1613       1.1       eeh 		case TOK_ENDOF:
   1614       1.1       eeh 			STATE(token->text, "TOK_ENDOF");
   1615       1.1       eeh 			off = pop();
   1616       1.1       eeh 			emit("b(endof)");
   1617       1.1       eeh 			/*
   1618       1.1       eeh 			 * Save back pointer in the offset field so we can traverse
   1619       1.1       eeh 			 * the linked list and patch it in the endcase.
   1620       1.1       eeh 			 */
   1621       1.1       eeh 			pos = pop();	/* get position of prev link. */
   1622       1.1       eeh 			push(outpos);	/* save position of this link. */
   1623      1.34       eeh 			if (pos)
   1624      1.34       eeh 				/* save potision of prev link. */
   1625      1.34       eeh 				offspit(pos - outpos);
   1626      1.34       eeh 			else
   1627      1.34       eeh 				/* This is the first statement */
   1628      1.34       eeh 				offspit(0);
   1629       1.1       eeh 			pos = outpos;
   1630       1.1       eeh 			/* Now point the offset from b(of) here. */
   1631       1.1       eeh 			outpos = off;
   1632      1.34       eeh 			off = pos - off;
   1633      1.34       eeh 			offspit(off);
   1634       1.1       eeh 			/* Restore position */
   1635       1.1       eeh 			outpos = pos;
   1636       1.1       eeh 			break;
   1637       1.1       eeh 		case TOK_EXTERNAL:
   1638       1.1       eeh 			STATE(token->text, "TOK_EXTERNAL");
   1639       1.1       eeh 			state = TOK_EXTERNAL;
   1640       1.1       eeh 			break;
   1641      1.34       eeh 		case TOK_FCODE_VERSION2:
   1642      1.34       eeh 			/* This is actually a tokenizer directive. */
   1643      1.34       eeh 			STATE(token->text, "TOK_FCODE_VERSION2");
   1644      1.34       eeh 			offsetsize = 16;
   1645      1.34       eeh 			pos = outpos;
   1646      1.34       eeh 			outpos = 0;
   1647      1.34       eeh 			emit("start1");
   1648      1.34       eeh 			outpos = pos;
   1649      1.34       eeh 			break;
   1650      1.34       eeh 		case TOK_FCODE_END:
   1651      1.34       eeh 			/*
   1652      1.34       eeh 			 * Another tokenizer directive.
   1653      1.34       eeh 			 *
   1654      1.34       eeh 			 * This should generate end0 and finish filling in
   1655      1.34       eeh 			 * the FCode header.  But that's all done in main().
   1656      1.34       eeh 			 */
   1657      1.34       eeh 			STATE(token->text, "TOK_FCODE_END");
   1658      1.34       eeh 			return;
   1659       1.1       eeh 		case TOK_FIELD:
   1660       1.1       eeh 			STATE(token->text, "TOK_FIELD");
   1661       1.1       eeh 
   1662       1.1       eeh 			token = yylex();
   1663       1.1       eeh 			if (token == NULL) {
   1664       1.1       eeh 				(void)printf( "EOF in field definition\n");
   1665       1.3       mrg 				return;
   1666       1.1       eeh 			}
   1667       1.1       eeh 
   1668       1.1       eeh 			/* Add new code to dictionary */
   1669       1.1       eeh 			fcode = malloc(sizeof(*fcode));
   1670       1.1       eeh 			fcode->num = nextfcode++;
   1671       1.1       eeh 			fcode->name = strdup(token->text);
   1672       1.1       eeh 			fadd(dictionary, fcode);
   1673       1.1       eeh 
   1674       1.1       eeh 			if (state == 0)
   1675       1.1       eeh 				emit("new-token");
   1676       1.1       eeh 			else {
   1677       1.1       eeh 				if (state == TOK_EXTERNAL)
   1678       1.1       eeh 					emit("external-token");
   1679       1.1       eeh 				else
   1680       1.1       eeh 				/* Here we have a choice of new-token or named-token */
   1681       1.1       eeh 					emit("named-token");
   1682       1.1       eeh 				sspit(token->text);
   1683       1.1       eeh 			}
   1684       1.1       eeh 			spit(fcode->num);
   1685       1.1       eeh 			emit("b(field)");
   1686       1.1       eeh 			break;
   1687       1.1       eeh 
   1688       1.1       eeh 		case TOK_HEX:
   1689       1.1       eeh 			STATE(token->text, "TOK_HEX");
   1690       1.1       eeh 			if (token->text[1] != '#') {
   1691       1.1       eeh 				if (defining) {
   1692      1.34       eeh 					emit("b(lit)");
   1693      1.34       eeh 					spit(0);
   1694      1.34       eeh 					spit(0);
   1695      1.34       eeh 					spit(0);
   1696       1.1       eeh 					spit(16);
   1697       1.1       eeh 					emit("base");
   1698       1.1       eeh 					emit("!");
   1699       1.1       eeh 				} else
   1700      1.30     lukem 					numbase = TOK_HEX;
   1701       1.1       eeh 			} else {
   1702       1.1       eeh 				char *end;
   1703       1.1       eeh 				Cell value;
   1704       1.1       eeh 
   1705       1.1       eeh 				token = yylex();
   1706       1.1       eeh 				if (token == NULL) {
   1707       1.1       eeh 					(void)printf( "EOF after h#\n");
   1708       1.3       mrg 					return;
   1709       1.1       eeh 				}
   1710       1.1       eeh 				value = strtol(token->text, &end, 16);
   1711       1.1       eeh 				if (*end != 0) {
   1712       1.6       mrg 					(void)printf("Illegal number conversion:%s:%d: %s\n",
   1713       1.6       mrg 					    infile, yylineno, yytext);
   1714       1.1       eeh 					exit(1);
   1715       1.1       eeh 				}
   1716       1.1       eeh 				/*
   1717       1.1       eeh 				 * If this is a 64-bit value we need to store two literals
   1718       1.1       eeh 				 * and issue a `lxjoin' to combine them.  But that's a future
   1719       1.1       eeh 				 * project.
   1720       1.1       eeh 				 */
   1721       1.1       eeh 				emit("b(lit)");
   1722      1.13       eeh 				spit((value>>24)&0x0ff);
   1723       1.1       eeh 				spit((value>>16)&0x0ff);
   1724       1.1       eeh 				spit((value>>8)&0x0ff);
   1725       1.1       eeh 				spit(value&0x0ff);
   1726      1.15       eeh 				if ((value>>32) != value && (value>>32) != 0) {
   1727      1.13       eeh 					emit("b(lit)");
   1728      1.13       eeh 					spit((value>>56)&0x0ff);
   1729      1.13       eeh 					spit((value>>48)&0x0ff);
   1730      1.13       eeh 					spit((value>>40)&0x0ff);
   1731      1.13       eeh 					spit((value>>32)&0x0ff);
   1732      1.13       eeh 					emit("lxjoin");
   1733      1.13       eeh 				}
   1734       1.1       eeh 			}
   1735       1.1       eeh 			break;
   1736       1.1       eeh 		case TOK_HEADERLESS:
   1737       1.1       eeh 			STATE(token->text, "TOK_HEADERLESS");
   1738       1.1       eeh 			state = 0;
   1739       1.1       eeh 			break;
   1740       1.1       eeh 		case TOK_HEADERS:
   1741       1.1       eeh 			STATE(token->text, "TOK_HEADERS");
   1742       1.1       eeh 			state = TOK_HEADERS;
   1743       1.1       eeh 			break;
   1744       1.1       eeh 		case TOK_IF:
   1745       1.1       eeh 			STATE(token->text, "TOK_IF");
   1746       1.1       eeh 			/*
   1747       1.1       eeh 			 * Similar to do but simpler since we only deal w/one branch.
   1748       1.1       eeh 			 */
   1749       1.1       eeh 			emit("b?branch");
   1750       1.1       eeh 			push(outpos);
   1751      1.34       eeh 			offspit(0);	/* Place holder for later */
   1752       1.1       eeh 			break;
   1753       1.1       eeh 		case TOK_LEAVE:
   1754       1.1       eeh 			STATE(token->text, "TOK_LEAVE");
   1755       1.1       eeh 			emit("b(leave)");
   1756       1.1       eeh 			break;
   1757       1.1       eeh 		case TOK_LOOP:
   1758       1.1       eeh 			STATE(token->text, "TOK_LOOP");
   1759       1.1       eeh 
   1760       1.1       eeh 			if (token->text[0] == '+')
   1761       1.1       eeh 				emit("b(+loop)");
   1762       1.1       eeh 			else
   1763       1.1       eeh 				emit("b(loop)");
   1764       1.1       eeh 			/* First do backwards branch of loop */
   1765       1.1       eeh 			pos = pop();
   1766       1.1       eeh 			off = pos - outpos;
   1767      1.34       eeh 			offspit(off);
   1768       1.1       eeh 			/* Now do forward branch of do */
   1769       1.1       eeh 			pos = outpos;
   1770       1.1       eeh 			outpos = pop();
   1771       1.1       eeh 			off = pos - outpos;
   1772      1.34       eeh 			spit(off);
   1773       1.1       eeh 			/* Restore output position */
   1774       1.1       eeh 			outpos = pos;
   1775       1.1       eeh 			break;
   1776       1.1       eeh 		case TOK_OCTAL:
   1777       1.1       eeh 			STATE(token->text, "TOK_OCTAL");
   1778       1.1       eeh 			if (token->text[1] != '#') {
   1779       1.1       eeh 				if (defining) {
   1780       1.1       eeh 					spit(16);
   1781       1.1       eeh 					emit("base");
   1782       1.1       eeh 					emit("!");
   1783       1.1       eeh 				} else
   1784      1.30     lukem 					numbase = TOK_OCTAL;
   1785       1.1       eeh 			} else {
   1786       1.1       eeh 				char *end;
   1787       1.1       eeh 				Cell value;
   1788       1.1       eeh 
   1789       1.1       eeh 				token = yylex();
   1790       1.1       eeh 				if (token == NULL) {
   1791       1.1       eeh 					(void)printf( "EOF after o#\n");
   1792       1.3       mrg 					return;
   1793       1.1       eeh 				}
   1794       1.1       eeh 				value = strtol(token->text, &end, 8);
   1795       1.1       eeh 				if (*end != 0) {
   1796       1.6       mrg 					(void)printf("Illegal number conversion:%s:%d: %s\n",
   1797       1.6       mrg 					    infile, yylineno, yytext);
   1798       1.1       eeh 					exit(1);
   1799       1.1       eeh 				}
   1800       1.1       eeh 				/*
   1801       1.1       eeh 				 * If this is a 64-bit value we need to store two literals
   1802       1.1       eeh 				 * and issue a `lxjoin' to combine them.  But that's a future
   1803       1.1       eeh 				 * project.
   1804       1.1       eeh 				 */
   1805       1.1       eeh 				emit("b(lit)");
   1806      1.13       eeh 				spit((value>>24)&0x0ff);
   1807       1.1       eeh 				spit((value>>16)&0x0ff);
   1808       1.1       eeh 				spit((value>>8)&0x0ff);
   1809       1.1       eeh 				spit(value&0x0ff);
   1810      1.15       eeh 				if ((value>>32) != value && (value>>32) != 0) {
   1811      1.13       eeh 					emit("b(lit)");
   1812      1.13       eeh 					spit((value>>56)&0x0ff);
   1813      1.13       eeh 					spit((value>>48)&0x0ff);
   1814      1.13       eeh 					spit((value>>40)&0x0ff);
   1815      1.13       eeh 					spit((value>>32)&0x0ff);
   1816      1.13       eeh 					emit("lxjoin");
   1817      1.13       eeh 				}
   1818       1.1       eeh 			}
   1819       1.1       eeh 			break;
   1820       1.1       eeh 		case TOK_OF:
   1821       1.1       eeh 			STATE(token->text, "TOK_OF");
   1822       1.1       eeh 			/*
   1823       1.1       eeh 			 * Let's hope I get the semantics right.
   1824       1.1       eeh 			 *
   1825       1.1       eeh 			 * The `of' behaves almost the same as an
   1826       1.1       eeh 			 * `if'.  The difference is that `endof'
   1827       1.1       eeh 			 * takes a branch offset to the associated
   1828       1.1       eeh 			 * `endcase'.  Here we will generate a temporary
   1829       1.1       eeh 			 * offset of the `of' associated with the `endof'.
   1830       1.1       eeh 			 * Then in `endcase' we should be pointing just
   1831       1.1       eeh 			 * after the offset of the last `endof' so we
   1832       1.1       eeh 			 * calculate the offset and thread our way backwards
   1833       1.1       eeh 			 * searching for the previous `b(case)' or `b(endof)'.
   1834       1.1       eeh 			 */
   1835       1.1       eeh 			emit("b(of)");
   1836       1.1       eeh 			push(outpos);
   1837      1.34       eeh 			offspit(0);	/* Place holder for later */
   1838      1.34       eeh 			break;
   1839      1.34       eeh 		case TOK_OFFSET16:
   1840      1.34       eeh 			STATE(token->text, "TOK_OFFSET16");
   1841      1.34       eeh 			offsetsize = 16;
   1842      1.34       eeh 			emit("offset16");
   1843       1.1       eeh 			break;
   1844       1.1       eeh 		case TOK_REPEAT:
   1845       1.1       eeh 			STATE(token->text, "TOK_REPEAT");
   1846       1.1       eeh 			emit("bbranch");
   1847       1.1       eeh 			pos = pop();
   1848       1.1       eeh 			off = pop();
   1849       1.1       eeh 			/* First the offset for the branch back to the begin */
   1850       1.1       eeh 			off -= outpos;
   1851      1.34       eeh 			offspit(off);
   1852       1.1       eeh 			emit("b(>resolve)");
   1853       1.1       eeh 			/* Now point the offset of the while here. */
   1854       1.1       eeh 			off = outpos;
   1855       1.1       eeh 			outpos = pos;
   1856       1.1       eeh 			pos = off - pos;
   1857      1.34       eeh 			offspit(pos);
   1858       1.1       eeh 			/* Return to the end of the output */
   1859       1.1       eeh 			outpos = off;
   1860       1.1       eeh 			break;
   1861      1.34       eeh 		case TOK_STARTX:
   1862      1.34       eeh 			/* Put a "startX" at addr 0. */
   1863      1.34       eeh 			STATE(token->text, "TOK_FCODE_VERSION2");
   1864      1.34       eeh 			offsetsize = 16;
   1865      1.34       eeh 			pos = outpos;
   1866      1.34       eeh 			outpos = 0;
   1867      1.34       eeh 			emit(token->text);
   1868      1.34       eeh 			outpos = pos;
   1869      1.34       eeh 			break;
   1870       1.1       eeh 		case TOK_THEN:
   1871       1.1       eeh 			STATE(token->text, "TOK_THEN");
   1872       1.1       eeh 			emit("b(>resolve)");
   1873       1.1       eeh 			pos = outpos;
   1874       1.1       eeh 			outpos = pop();
   1875       1.1       eeh 			off = pos - outpos;
   1876      1.34       eeh 			offspit(off);
   1877       1.1       eeh 			outpos = pos;
   1878       1.1       eeh 			break;
   1879       1.1       eeh 		case TOK_TO:
   1880       1.1       eeh 			STATE(token->text, "TOK_TO");
   1881       1.1       eeh 			/* The next pass should tokenize the FCODE number */
   1882       1.1       eeh 			emit("b(to)");
   1883       1.1       eeh 			break;
   1884       1.1       eeh 		case TOK_UNTIL:
   1885       1.1       eeh 			STATE(token->text, "TOK_UNTIL");
   1886       1.1       eeh 			emit("b?branch");
   1887       1.1       eeh 			pos = pop();
   1888       1.1       eeh 			pos -= outpos;
   1889      1.34       eeh 			offspit(pos);
   1890      1.30     lukem 			break;
   1891       1.1       eeh 		case TOK_VALUE:
   1892       1.1       eeh 			STATE(token->text, "TOK_VALUE");
   1893       1.1       eeh 
   1894       1.1       eeh 			token = yylex();
   1895       1.1       eeh 			if (token == NULL) {
   1896       1.1       eeh 				(void)printf( "EOF in value definition\n");
   1897       1.3       mrg 				return;
   1898       1.1       eeh 			}
   1899       1.1       eeh 
   1900       1.1       eeh 			/* Add new code to dictionary */
   1901       1.1       eeh 			fcode = malloc(sizeof(*fcode));
   1902       1.1       eeh 			fcode->num = nextfcode++;
   1903       1.1       eeh 			fcode->name = strdup(token->text);
   1904       1.1       eeh 			fadd(dictionary, fcode);
   1905       1.1       eeh 
   1906       1.1       eeh 			if (state == 0)
   1907       1.1       eeh 				emit("new-token");
   1908       1.1       eeh 			else {
   1909       1.1       eeh 				if (state == TOK_EXTERNAL)
   1910       1.1       eeh 					emit("external-token");
   1911       1.1       eeh 				else
   1912       1.1       eeh 				/* Here we have a choice of new-token or named-token */
   1913       1.1       eeh 					emit("named-token");
   1914       1.1       eeh 				sspit(token->text);
   1915       1.1       eeh 			}
   1916       1.1       eeh 			spit(fcode->num);
   1917       1.1       eeh 			emit("b(value)");
   1918       1.1       eeh 			break;
   1919       1.1       eeh 		case TOK_VARIABLE:
   1920       1.1       eeh 			STATE(token->text, "TOK_VARIABLE");
   1921       1.1       eeh 
   1922       1.1       eeh 			token = yylex();
   1923       1.1       eeh 			if (token == NULL) {
   1924       1.1       eeh 				(void)printf( "EOF in variable definition\n");
   1925       1.3       mrg 				return;
   1926       1.1       eeh 			}
   1927       1.1       eeh 
   1928       1.1       eeh 			/* Add new code to dictionary */
   1929       1.1       eeh 			fcode = malloc(sizeof(*fcode));
   1930       1.1       eeh 			fcode->num = nextfcode++;
   1931       1.1       eeh 			fcode->name = strdup(token->text);
   1932       1.1       eeh 			fadd(dictionary, fcode);
   1933       1.1       eeh 
   1934       1.1       eeh 			if (state == 0)
   1935       1.1       eeh 				emit("new-token");
   1936       1.1       eeh 			else {
   1937       1.1       eeh 				if (state == TOK_EXTERNAL)
   1938       1.1       eeh 					emit("external-token");
   1939       1.1       eeh 				else
   1940       1.1       eeh 				/* Here we have a choice of new-token or named-token */
   1941       1.1       eeh 					emit("named-token");
   1942       1.1       eeh 				sspit(token->text);
   1943       1.1       eeh 			}
   1944       1.1       eeh 			spit(fcode->num);
   1945       1.1       eeh 			emit("b(variable)");
   1946       1.1       eeh 			break;
   1947      1.34       eeh 		case TOK_VERSION1:
   1948      1.34       eeh 			/* This is actually a tokenizer directive. */
   1949      1.34       eeh 			STATE(token->text, "TOK_FCODE_VERSION1");
   1950      1.34       eeh 			offsetsize = 8;
   1951      1.34       eeh 			pos = outpos;
   1952      1.34       eeh 			outpos = 0;
   1953      1.34       eeh 			emit("version1");
   1954      1.34       eeh 			outpos = pos;
   1955      1.34       eeh 			break;
   1956       1.1       eeh 		case TOK_WHILE:
   1957       1.1       eeh 			STATE(token->text, "TOK_WHILE");
   1958       1.1       eeh 			emit("b?branch");
   1959       1.1       eeh 			push(outpos);
   1960      1.34       eeh 			offspit(0);
   1961       1.1       eeh 			break;
   1962       1.1       eeh 
   1963       1.1       eeh 			/* Tokenizer directives */
   1964       1.1       eeh 		case TOK_BEGTOK:
   1965       1.1       eeh 			STATE(token->text, "TOK_BEGTOK");
   1966       1.1       eeh 			tokenizer = 1;
   1967       1.1       eeh 			break;
   1968       1.1       eeh 		case TOK_EMIT_BYTE:
   1969       1.1       eeh 			STATE(token->text, "TOK_EMIT_BYTE");
   1970       1.1       eeh 			spit(pop());
   1971       1.1       eeh 			break;
   1972       1.1       eeh 		case TOK_ENDTOK:
   1973       1.1       eeh 			STATE(token->text, "TOK_ENDTOK");
   1974       1.1       eeh 			tokenizer = 0;
   1975       1.1       eeh 			break;
   1976       1.1       eeh 		case TOK_FLOAD:
   1977       1.6       mrg 			{
   1978       1.6       mrg 				char *oldinfile = infile;
   1979       1.6       mrg 
   1980      1.34       eeh 				STATE(token->text, "TOK_FLOAD");
   1981      1.34       eeh 				/* Parse a different file for a while */
   1982      1.34       eeh 				token = yylex();
   1983      1.34       eeh 				if ((inf = fopen(token->text, "r")) == NULL) {
   1984      1.34       eeh 					(void)printf("%s: Could not "
   1985      1.34       eeh 						"open %s: %s\n",
   1986      1.34       eeh 						myname, token->text,
   1987      1.34       eeh 						strerror(errno));
   1988      1.34       eeh 					break;
   1989      1.34       eeh 				}
   1990      1.34       eeh 				infile = strdup(token->text);
   1991      1.34       eeh 				if (mark_fload) {
   1992      1.34       eeh 					/*
   1993      1.34       eeh 					 * Insert commands to print out the
   1994      1.34       eeh 					 * filename into the instruction
   1995      1.34       eeh 					 * stream
   1996      1.34       eeh 					 */
   1997      1.34       eeh 					emit("b(\")");
   1998      1.34       eeh 					sspit("fload-ing ");
   1999      1.34       eeh 					emit("type");
   2000      1.34       eeh 					emit("b(\")");
   2001      1.34       eeh 					sspit(infile);
   2002      1.34       eeh 					emit("type");
   2003      1.34       eeh 					emit("cr");
   2004      1.34       eeh 					emit(".s");
   2005      1.34       eeh 				}
   2006      1.34       eeh 				inbuf = yy_create_buffer(inf, YY_BUF_SIZE);
   2007      1.34       eeh 				yy_switch_to_buffer(inbuf);
   2008      1.34       eeh 
   2009      1.34       eeh 				printf("======= fload file %s\n", infile);
   2010       1.6       mrg 				tokenize(inbuf);
   2011      1.34       eeh 				printf("======= done file %s\n", infile);
   2012      1.34       eeh 				yy_switch_to_buffer(yinput);
   2013      1.34       eeh 				yy_delete_buffer(inbuf);
   2014      1.34       eeh 				fclose(inf);
   2015      1.34       eeh 				if (mark_fload) {
   2016      1.34       eeh 					/*
   2017      1.34       eeh 					 * Insert commands to print out the
   2018      1.34       eeh 					 * filename into the instruction
   2019      1.34       eeh 					 * stream
   2020      1.34       eeh 					 */
   2021      1.34       eeh 					emit("b(\")");
   2022      1.34       eeh 					sspit("fload-ed ");
   2023      1.34       eeh 					emit("type");
   2024      1.34       eeh 					emit("b(\")");
   2025      1.34       eeh 					sspit(infile);
   2026      1.34       eeh 					emit("type");
   2027      1.34       eeh 					emit("cr");
   2028      1.34       eeh 					emit(".s");
   2029      1.34       eeh 					emit("cr");
   2030      1.34       eeh 				}
   2031      1.34       eeh 				free(infile);
   2032       1.6       mrg 				infile = oldinfile;
   2033       1.6       mrg 			}
   2034       1.1       eeh 			break;
   2035       1.1       eeh 		case TOK_OTHER:
   2036       1.1       eeh 			STATE(token->text, "TOK_OTHER");
   2037      1.30     lukem 			if (apply_macros(yinput, token->text))
   2038       1.1       eeh 				break;
   2039       1.1       eeh 			if (emit(token->text)) {
   2040       1.1       eeh #if 0
   2041       1.1       eeh 				/*
   2042       1.1       eeh 				 * Call an external command
   2043       1.1       eeh 				 *
   2044       1.1       eeh 				 * XXXXX assumes it will always find the command
   2045       1.1       eeh 				 */
   2046       1.1       eeh 				sspit(token->text);
   2047       1.1       eeh 				emit("$find");
   2048       1.1       eeh 				emit("drop");
   2049       1.1       eeh 				emit("execute");
   2050       1.1       eeh #else
   2051      1.34       eeh 				printf("%s:%d: undefined token %s\n",
   2052      1.34       eeh 					infile, yylineno, yytext);
   2053      1.34       eeh 				exit(1);
   2054      1.34       eeh 				token_err(yylineno, infile, yytext,
   2055      1.34       eeh 					"%s: undefined token `%s'\n",
   2056      1.34       eeh 					myname, token->text);
   2057       1.1       eeh 				fflush(stderr);
   2058       1.1       eeh 				exit(1);
   2059       1.1       eeh #endif
   2060       1.1       eeh 			}
   2061       1.1       eeh 			break;
   2062       1.1       eeh 		default:
   2063      1.16   thorpej 			/* Nothing */ ;
   2064       1.1       eeh 		}
   2065       1.1       eeh 	}
   2066       1.3       mrg 	return;
   2067       1.6       mrg }
   2068       1.6       mrg 
   2069       1.6       mrg /*
   2070       1.6       mrg  * print a tokenizer error message
   2071       1.6       mrg  */
   2072      1.35     joerg static void
   2073      1.30     lukem token_err(int lineno, const char *file, const char *text, const char *fmt, ...)
   2074       1.6       mrg {
   2075       1.6       mrg 	va_list ap;
   2076       1.6       mrg 
   2077       1.6       mrg 	va_start(ap, fmt);
   2078      1.30     lukem 	if (file)
   2079      1.30     lukem 		(void)fprintf(stderr, "%s:%d: ", file, lineno);
   2080       1.6       mrg 	if (fmt)
   2081       1.6       mrg 		(void)vfprintf(stderr, fmt, ap);
   2082       1.6       mrg 	fputc('\n', stderr);
   2083       1.6       mrg 	if (text)
   2084       1.6       mrg 		fprintf(stderr, "\t%s", text);
   2085       1.6       mrg 	va_end(ap);
   2086       1.6       mrg 	exit(1);
   2087       1.1       eeh }
   2088       1.1       eeh 
   2089       1.1       eeh /*
   2090       1.1       eeh  * Lookup fcode string in dictionary and spit it out.
   2091       1.1       eeh  *
   2092       1.1       eeh  * Fcode must be in dictionary.  No alias conversion done.
   2093       1.1       eeh  */
   2094      1.35     joerg static int
   2095      1.30     lukem emit(const char *str)
   2096       1.1       eeh {
   2097       1.1       eeh 	struct fcode *code;
   2098       1.2       eeh 	if ((code = flookup( dictionary, str)))
   2099       1.1       eeh 		spit(code->num);
   2100       1.1       eeh 	if (debug > 1) {
   2101       1.1       eeh 		if (code)
   2102       1.1       eeh 			(void)printf( "emitting `%s'\n", code->name);
   2103       1.1       eeh 		else
   2104       1.1       eeh 			(void)printf( "emit: not found `%s'\n", str);
   2105       1.1       eeh 	}
   2106       1.1       eeh 	return (code == NULL);
   2107       1.1       eeh }
   2108       1.1       eeh 
   2109       1.1       eeh /*
   2110       1.1       eeh  * Spit out an integral value as a series of FCodes.
   2111       1.1       eeh  *
   2112       1.1       eeh  * It will spit out one zero byte or as many bytes as are
   2113       1.1       eeh  * non-zero.
   2114       1.1       eeh  */
   2115      1.35     joerg static int
   2116      1.28     lukem spit(long n)
   2117       1.1       eeh {
   2118       1.2       eeh 	int count = 1;
   2119       1.1       eeh 
   2120       1.1       eeh 	if (n >> 8)
   2121       1.2       eeh 		count += spit(n >> 8);
   2122      1.30     lukem 	if ((size_t)outpos >= outbufsiz) {
   2123      1.30     lukem 		while ((size_t)outpos >= outbufsiz) outbufsiz += BUFCLICK;
   2124       1.1       eeh 		if (!(outbuf = realloc(outbuf, outbufsiz))) {
   2125       1.2       eeh 			(void)printf( "realloc of %ld bytes failed -- out of memory\n",
   2126       1.3       mrg 				      (long)outbufsiz);
   2127       1.1       eeh 			exit(1);
   2128       1.1       eeh 		}
   2129       1.1       eeh 	}
   2130      1.34       eeh 	if (debug > 3) printf("%lx: spitting %2.2x\n", outpos, (unsigned char)n);
   2131       1.1       eeh 	outbuf[outpos++] = n;
   2132       1.2       eeh 	return (count);
   2133       1.1       eeh }
   2134       1.1       eeh 
   2135       1.1       eeh /*
   2136       1.1       eeh  * Spit out an FCode string.
   2137       1.1       eeh  */
   2138      1.35     joerg static void
   2139      1.30     lukem sspit(const char *s)
   2140       1.1       eeh {
   2141       1.1       eeh 	int len = strlen(s);
   2142       1.1       eeh 
   2143       1.1       eeh 	if (len > 255) {
   2144       1.1       eeh 		(void)printf( "string length %d too long\n", len);
   2145       1.3       mrg 		return;
   2146       1.1       eeh 	}
   2147      1.34       eeh 	if (debug > 2)
   2148       1.1       eeh 		(void)printf( "sspit: len %d str `%s'\n", len, s);
   2149       1.1       eeh 	spit(len);
   2150      1.34       eeh 	while (len--)
   2151       1.3       mrg 		spit(*s++);
   2152       1.1       eeh }
   2153       1.1       eeh 
   2154      1.34       eeh /*
   2155      1.34       eeh  * Spit out an offset.  Offsets can be 8 or 16 bits.
   2156      1.34       eeh  * Bail if the value overflows.  This is a little complicated since
   2157      1.34       eeh  * offsets can be negative numbers.
   2158      1.34       eeh  */
   2159      1.35     joerg static int
   2160      1.34       eeh offspit(long n)
   2161      1.34       eeh {
   2162      1.34       eeh 
   2163      1.34       eeh 	if (offsetsize == 16) {
   2164      1.34       eeh 		volatile int16_t off16 = n;
   2165      1.34       eeh 
   2166      1.34       eeh 		if (n != off16)
   2167      1.34       eeh 			token_err(yylineno, infile, NULL,
   2168      1.34       eeh 				"Offset16 offset overflow: %lx != %x\n",
   2169      1.34       eeh 				n, off16);
   2170      1.34       eeh 		spit((n>>8) & 0xff);
   2171      1.34       eeh 		return spit(n & 0xff);
   2172      1.34       eeh 	} else {
   2173      1.34       eeh 		volatile int8_t off8 = n;
   2174      1.34       eeh 
   2175      1.34       eeh 		if (n != off8)
   2176      1.34       eeh 			token_err(yylineno, infile, NULL,
   2177      1.34       eeh 				"Offset8 offset overflow: %lx != %x\n",
   2178      1.34       eeh 				n, off8);
   2179      1.34       eeh 		return spit(n & 0x0ffL);
   2180      1.34       eeh 	}
   2181      1.34       eeh }
   2182      1.34       eeh 
   2183       1.1       eeh int
   2184      1.28     lukem yywrap(void)
   2185       1.3       mrg {
   2186       1.1       eeh 	/* Always generate EOF */
   2187       1.1       eeh 	return (1);
   2188       1.1       eeh }
   2189