[BACK]Return to fgen.l CVS log [TXT][DIR] Up to [local] / src / usr.bin / fgen

Annotation of src/usr.bin/fgen/fgen.l, Revision 1.1

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