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