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