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