diff options
Diffstat (limited to 'usr.bin/fgen')
-rw-r--r-- | usr.bin/fgen/fgen.h | 30 | ||||
-rw-r--r-- | usr.bin/fgen/fgen.l | 2015 |
2 files changed, 1087 insertions, 958 deletions
diff --git a/usr.bin/fgen/fgen.h b/usr.bin/fgen/fgen.h index 6a96850d171..c6eb46b1d53 100644 --- a/usr.bin/fgen/fgen.h +++ b/usr.bin/fgen/fgen.h @@ -1,5 +1,5 @@ -/* $OpenBSD: fgen.h,v 1.2 2002/02/16 21:27:45 millert Exp $ */ -/* $NetBSD: fgen.h,v 1.4 2001/06/13 10:46:05 wiz Exp $ */ +/* $OpenBSD: fgen.h,v 1.3 2020/03/24 07:00:40 otto Exp $ */ +/* $NetBSD: fgen.h,v 1.9 2010/02/08 20:14:55 eeh Exp $ */ /* * fgen.h -- stuff for the fcode tokenizer. * @@ -14,11 +14,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Eduardo Horvath. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -33,7 +28,7 @@ */ /* Type of a Cell */ -typedef long Cell; +typedef int64_t Cell; /* Token from the scanner. */ struct tok { @@ -44,12 +39,12 @@ struct tok { #define TOKEN struct tok #define YY_DECL TOKEN* yylex(void) -#define FCODE 0xF00DBABE -#define MACRO 0xFEEDBABE +#define FCODE 0x000FC0DE +#define MACRO 0x0000F00D /* Defined fcode and string. */ struct fcode { - char *name; + const char *name; long num; int type; struct fcode *l; @@ -58,8 +53,8 @@ struct fcode { /* macro instruction as separate words */ struct macro { - char *name; - char *equiv; + const char *name; + const char *equiv; int type; struct macro *l; struct macro *r; @@ -88,12 +83,12 @@ enum toktypes { TOK_PSTRING, TOK_TOKENIZE, TOK_COMMENT, - TOK_ENDCOMMENT, TOK_COLON, TOK_SEMICOLON, TOK_TOSTRING, /* These are special */ + TOK_ABORT_S, TOK_AGAIN, TOK_ALIAS, TOK_GETTOKEN, @@ -107,9 +102,12 @@ enum toktypes { TOK_DEFER, TOK_DO, TOK_ELSE, + TOK_END0, TOK_ENDCASE, TOK_ENDOF, TOK_EXTERNAL, + TOK_FCODE_VERSION2, + TOK_FCODE_END, TOK_FIELD, TOK_HEADERLESS, TOK_HEADERS, @@ -117,14 +115,16 @@ enum toktypes { TOK_LEAVE, TOK_LOOP, TOK_OF, + TOK_OFFSET16, TOK_REPEAT, + TOK_STARTX, TOK_THEN, TOK_TO, TOK_UNTIL, TOK_VALUE, TOK_VARIABLE, + TOK_VERSION1, TOK_WHILE, - TOK_OFFSET16, /* Tokenizer directives */ TOK_BEGTOK, diff --git a/usr.bin/fgen/fgen.l b/usr.bin/fgen/fgen.l index 7248ac6aad6..3d72e4de5a6 100644 --- a/usr.bin/fgen/fgen.l +++ b/usr.bin/fgen/fgen.l @@ -1,6 +1,6 @@ %{ -/* $OpenBSD: fgen.l,v 1.12 2015/10/09 01:37:07 deraadt Exp $ */ -/* $NetBSD: fgen.l,v 1.12 2001/06/13 10:46:05 wiz Exp $ */ +/* $OpenBSD: fgen.l,v 1.13 2020/03/24 07:00:40 otto Exp $ */ +/* $NetBSD: fgen.l,v 1.37 2016/03/08 20:13:44 christos Exp $ */ /* FLEX input for FORTH input file scanner */ /* * Copyright (c) 1998 Eduardo Horvath. @@ -14,11 +14,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Eduardo Horvath. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -42,18 +37,20 @@ } #define TOKEN struct tok */ +#include <sys/cdefs.h> + %} %option yylineno -decimal [0-9] hex [0-9A-Fa-f] -octal [0-7] +hexdot [0-9A-Fa-f.] white [ \t\n\r\f] tail {white} %{ #include <sys/types.h> +#include <arpa/inet.h> #include <assert.h> #include <err.h> @@ -63,684 +60,770 @@ tail {white} #include <stdio.h> #include <string.h> #include <unistd.h> +#include <util.h> #include "fgen.h" -TOKEN token; +static TOKEN ltoken; /* * Global variables that control the parse state. */ -struct fcode *dictionary = NULL; -struct macro *aliases = NULL; -int outf = 1; /* stdout */ -int state = 0; -int nextfcode = 0x800; -int base = TOK_HEX; -long outpos; -char *outbuf = NULL; -char *outfile, *infile; +static struct fcode *dictionary = NULL; +static struct macro *aliases = NULL; +static int outf = 1; /* stdout */ +static int state = 0; +static int nextfcode = 0x800; +static int numbase = TOK_HEX; +static long outpos; +static char *outbuf = NULL; +static char *outfile, *infile; #define BUFCLICK (1024*1024) -size_t outbufsiz = 0; -char *myname = NULL; -int offsetsize = 8; -int defining = 0; -int tokenizer = 0; +static size_t outbufsiz = 0; +static char *myname = NULL; +static int offsetsize = 8; +static int defining = 0; +static int tokenizer = 0; +static int need_end0 = 1; #define PSTKSIZ 1024 -Cell parse_stack[PSTKSIZ]; -int parse_stack_ptr = 0; +static Cell parse_stack[PSTKSIZ]; +static int parse_stack_ptr = 0; -void token_err(int, char *, char *, char *, ...) - __attribute__((__format__(__printf__, 4, 5))); -YY_DECL; +static void token_err(int, const char *, const char *, const char *, ...) + __attribute__((__format__ (printf, 4, 5))) __dead; +static YY_DECL; -int debug = 0; +static int debug = 0; #define ASSERT if (debug) assert -#define STATE(y, x) do { if (debug) printf( "%ld State %s: token `%s'\n", outpos, x, y); } while (0) +#define STATE(y, x) do { if (debug) printf("%lx State %s: token `%s'\n", outpos, x, y); } while (0) +static int mark_fload = 0; + +void * +emalloc(size_t sz) +{ + void *p = malloc(sz); + if (p == NULL) + err(1, NULL); + return p; +} + +char * +estrdup(const char *s) +{ + char *p = strdup(s); + if (p == NULL) + err(1, NULL); + return p; +} + +void * +erealloc(void *p, size_t sz) +{ + void *q = realloc(p, sz); + if (q == NULL) + err(1, NULL); + return q; +} -#define YY_NO_UNPUT %} +%option nounput + %% -0 { token.type = TOK_OTHER; token.text = yytext; - return &token; } +0 { ltoken.type = TOK_OTHER; ltoken.text = yytext; return <oken; } + +1 { ltoken.type = TOK_OTHER; ltoken.text = yytext; return <oken; } -1 { token.type = TOK_OTHER; token.text = yytext; - return &token; } +2 { ltoken.type = TOK_OTHER; ltoken.text = yytext; return <oken; } -2 { token.type = TOK_OTHER; token.text = yytext; - return &token; } +3 { ltoken.type = TOK_OTHER; ltoken.text = yytext; return <oken; } -3 { token.type = TOK_OTHER; token.text = yytext; - return &token; } +-1 { ltoken.type = TOK_OTHER; ltoken.text = yytext; return <oken; } --1 { token.type = TOK_OTHER; token.text = yytext; - return &token; } +\. { ltoken.type = TOK_OTHER; ltoken.text = yytext; return <oken; } {white}* /* whitespace -- keep looping */ ; \\[^\n]*\n /* end of line comment -- keep looping */ { STATE(yytext, "EOL comment"); } --?{hex}+ { token.type = TOK_NUMBER; token.text = yytext; - return &token; } +-?{hex}{hexdot}* { ltoken.type = TOK_NUMBER; ltoken.text = yytext; + return <oken; } + +\'.\' { ltoken.type = TOK_C_LIT; ltoken.text = yytext; return <oken; } -\'.\' { token.type = TOK_C_LIT; token.text = yytext; return &token; } +\"{white}*(\\\"|[^"])*\" { ltoken.type = TOK_STRING_LIT; ltoken.text = yytext; + return <oken; } /* String started by `"' or `."' */ -\"{white}*(\\\"|[^"])*\" { token.type = TOK_STRING_LIT; token.text = yytext; - return &token; } /* String started by `"' or `."' */ +\.\({white}*(\\\"|[^)])*\) { ltoken.type = TOK_PSTRING; ltoken.text = yytext; + return <oken; } /* String of type `.(.....)' */ -\.\({white}*(\\\"|[^)])*\) { token.type = TOK_PSTRING; token.text = yytext; - return &token; } /* String of type `.(.....)' */ +\.\"{white}*(\\\"|[^"])*\" { ltoken.type = TOK_PSTRING; ltoken.text = yytext; + return <oken; } -\.\"{white}*(\\\"|[^"])*\" { token.type = TOK_PSTRING; token.text = yytext; - return &token; } +[aA][bB][oO][rR][tT]\"{white}*(\\\"|[^"])*\" { ltoken.type = TOK_ABORT_S; + ltoken.text = yytext; return <oken; } -"(" { token.type = TOK_COMMENT; token.text = yytext; - return &token; } +"(" { ltoken.type = TOK_COMMENT; ltoken.text = yytext; + return <oken; } -")" { token.type = TOK_ENDCOMMENT; token.text = yytext; - return &token; } +":" { ltoken.type = TOK_COLON; ltoken.text = yytext; + return <oken; } -":" { token.type = TOK_COLON; token.text = yytext; - return &token; } +";" { ltoken.type = TOK_SEMICOLON; ltoken.text = yytext; + return <oken; } -";" { token.type = TOK_SEMICOLON; token.text = yytext; - return &token; } +\' { ltoken.type = TOK_TOKENIZE; ltoken.text = yytext; + return <oken; } -\' { token.type = TOK_TOKENIZE; token.text = yytext; - return &token; } +[aA][gG][aA][iI][nN] { ltoken.type = TOK_AGAIN; ltoken.text = yytext; + return <oken; } -[aA][gG][aA][iI][nN] { token.type = TOK_AGAIN; token.text = yytext; - return &token; } +[aA][lL][iI][aA][sS] { ltoken.type = TOK_ALIAS; ltoken.text = yytext; + return <oken; } -[aA][lL][iI][aA][sS] { token.type = TOK_ALIAS; token.text = yytext; - return &token; } +\[\'\] { ltoken.type = TOK_GETTOKEN; ltoken.text = yytext; + return <oken; } -\[\'\] { token.type = TOK_GETTOKEN; token.text = yytext; - return &token; } +[aA][sS][cC][iI][iI] { ltoken.type = TOK_ASCII; ltoken.text = yytext; + return <oken; } -[aA][sS][cC][iI][iI] { token.type = TOK_ASCII; token.text = yytext; - return &token; } +[bB][eE][gG][iI][nN] { ltoken.type = TOK_BEGIN; ltoken.text = yytext; + return <oken; } -[bB][eE][gG][iI][nN] { token.type = TOK_BEGIN; token.text = yytext; - return &token; } +[bB][uU][fF][fF][eE][rR]: { ltoken.type = TOK_BUFFER; ltoken.text = yytext; + return <oken; } -[bB][uU][fF][fF][eE][rR]: { token.type = TOK_BUFFER; token.text = yytext; - return &token; } +[cC][aA][sS][eE] { ltoken.type = TOK_CASE; ltoken.text = yytext; + return <oken; } -[cC][aA][sS][eE] { token.type = TOK_CASE; token.text = yytext; - return &token; } +[cC][oO][nN][sS][tT][aA][nN][tT] { ltoken.type = TOK_CONSTANT; ltoken.text = yytext; + return <oken; } -[cC][oO][nN][sS][tT][aA][nN][tT] { token.type = TOK_CONSTANT; token.text = yytext; - return &token; } +[cC][oO][nN][tT][rR][oO][lL] { ltoken.type = TOK_CONTROL; ltoken.text = yytext; + return <oken; } -[cC][oO][nN][tT][rR][oO][lL] { token.type = TOK_CONTROL; token.text = yytext; - return &token; } +[cC][rR][eE][aA][tT][eE] { ltoken.type = TOK_CREATE; ltoken.text = yytext; + return <oken; } -[cC][rR][eE][aA][tT][eE] { token.type = TOK_CREATE; token.text = yytext; - return &token; } +[dD]# { ltoken.type = TOK_DECIMAL; ltoken.text = yytext; + return <oken; } -[dD]# { token.type = TOK_DECIMAL; token.text = yytext; - return &token; } +[dD][eE][cC][iI][mM][aA][lL] { ltoken.type = TOK_DECIMAL; ltoken.text = yytext; + return <oken; } -[dD][eE][cC][iI][mM][aA][lL] { token.type = TOK_DECIMAL; token.text = yytext; - return &token; } +[dD][eE][fF][eE][rR] { ltoken.type = TOK_DEFER; ltoken.text = yytext; + return <oken; } -[dD][eE][fF][eE][rR] { token.type = TOK_DEFER; token.text = yytext; - return &token; } +\??[dD][oO] { ltoken.type = TOK_DO; ltoken.text = yytext; + return <oken; } -\??[dD][oO] { token.type = TOK_DO; token.text = yytext; - return &token; } +[eE][lL][sS][eE] { ltoken.type = TOK_ELSE; ltoken.text = yytext; + return <oken; } -[eE][lL][sS][eE] { token.type = TOK_ELSE; token.text = yytext; - return &token; } +[eE][nN][dD]0 { ltoken.type = TOK_END0; ltoken.text = yytext; + return <oken; } -[eE][nN][dD][cC][aA][sS][eE] { token.type = TOK_ENDCASE; token.text = yytext; - return &token; } +[eE][nN][dD][cC][aA][sS][eE] { ltoken.type = TOK_ENDCASE; ltoken.text = yytext; + return <oken; } -[eE][nN][dD][oO][fF] { token.type = TOK_ENDOF; token.text = yytext; - return &token; } +[eE][nN][dD][oO][fF] { ltoken.type = TOK_ENDOF; ltoken.text = yytext; + return <oken; } -[eE][xX][tT][eE][rR][nN][aA][lL] { token.type = TOK_EXTERNAL; token.text = yytext; - return &token; } +[eE][xX][tT][eE][rR][nN][aA][lL] { ltoken.type = TOK_EXTERNAL; ltoken.text = yytext; + return <oken; } -[fF][iI][eE][lL][dD] { token.type = TOK_FIELD; token.text = yytext; - return &token; } +[fF][cC][oO][dD][eE]-[vV][eE][rR][sS][iI][oO][nN]2 { + ltoken.type = TOK_FCODE_VERSION2; ltoken.text = yytext; + return <oken; } -[hH]# { token.type = TOK_HEX; token.text = yytext; - return &token; } +[fF][cC][oO][dD][eE]-[eE][nN][dD] { ltoken.type = TOK_FCODE_END; ltoken.text = yytext; + return <oken; } -[hH][eE][aA][dD][eE][rR][lL][eE][sS][sS] { token.type = TOK_HEADERLESS; token.text = yytext; - return &token; } +[fF][iI][eE][lL][dD] { ltoken.type = TOK_FIELD; ltoken.text = yytext; + return <oken; } -[hH][eE][aA][dD][eE][rR][sS] { token.type = TOK_HEADERS; token.text = yytext; - return &token; } +[hH]# { ltoken.type = TOK_HEX; ltoken.text = yytext; + return <oken; } -[hH][eE][xX] { token.type = TOK_HEX; token.text = yytext; - return &token; } +[hH][eE][aA][dD][eE][rR][lL][eE][sS][sS] { ltoken.type = TOK_HEADERLESS; ltoken.text = yytext; + return <oken; } -[iI][fF] { token.type = TOK_IF; token.text = yytext; - return &token; } +[hH][eE][aA][dD][eE][rR][sS] { ltoken.type = TOK_HEADERS; ltoken.text = yytext; + return <oken; } -\??[lL][eE][aA][vV][eE] { token.type = TOK_LEAVE; token.text = yytext; - return &token; } +[hH][eE][xX] { ltoken.type = TOK_HEX; ltoken.text = yytext; + return <oken; } -\+?[lL][oO][oO][pP] { token.type = TOK_LOOP; token.text = yytext; - return &token; } +[iI][fF] { ltoken.type = TOK_IF; ltoken.text = yytext; + return <oken; } -[oO]# { token.type = TOK_OCTAL; token.text = yytext; - return &token; } +\??[lL][eE][aA][vV][eE] { ltoken.type = TOK_LEAVE; ltoken.text = yytext; + return <oken; } -[oO][cC][tT][aA][lL] { token.type = TOK_OCTAL; token.text = yytext; - return &token; } +\+?[lL][oO][oO][pP] { ltoken.type = TOK_LOOP; ltoken.text = yytext; + return <oken; } -[oO][fF] { token.type = TOK_OF; token.text = yytext; - return &token; } +[oO]# { ltoken.type = TOK_OCTAL; ltoken.text = yytext; + return <oken; } -[rR][eE][pP][eE][aA][tT] { token.type = TOK_REPEAT; token.text = yytext; - return &token; } +[oO][cC][tT][aA][lL] { ltoken.type = TOK_OCTAL; ltoken.text = yytext; + return <oken; } -[tT][hH][eE][nN] { token.type = TOK_THEN; token.text = yytext; - return &token; } +[oO][fF] { ltoken.type = TOK_OF; ltoken.text = yytext; + return <oken; } -[tT][oO] { token.type = TOK_TO; token.text = yytext; - return &token; } +[oO][fF][fF][sS][eE][tT]16 { ltoken.type = TOK_OFFSET16; ltoken.text = yytext; + return <oken; } -[uU][nN][tT][iI][lL] { token.type = TOK_UNTIL; token.text = yytext; - return &token; } +[rR][eE][pP][eE][aA][tT] { ltoken.type = TOK_REPEAT; ltoken.text = yytext; + return <oken; } -[vV][aA][lL][uU][eE] { token.type = TOK_VALUE; token.text = yytext; - return &token; } +[sS][tT][aA][rR][tT][0124] { ltoken.type = TOK_STARTX; ltoken.text = yytext; + return <oken; } + +[tT][hH][eE][nN] { ltoken.type = TOK_THEN; ltoken.text = yytext; + return <oken; } -[vV][aA][rR][iI][aA][bB][lL][eE] { token.type = TOK_VARIABLE; token.text = yytext; - return &token; } +[tT][oO] { ltoken.type = TOK_TO; ltoken.text = yytext; + return <oken; } -[wW][hH][iI][lL][eE] { token.type = TOK_WHILE; token.text = yytext; - return &token; } +[uU][nN][tT][iI][lL] { ltoken.type = TOK_UNTIL; ltoken.text = yytext; + return <oken; } -offset16 { token.type = TOK_OFFSET16; token.text = yytext; - return &token; } +[vV][aA][lL][uU][eE] { ltoken.type = TOK_VALUE; ltoken.text = yytext; + return <oken; } -tokenizer\[ { token.type = TOK_BEGTOK; token.text = yytext; - return &token; } +[vV][aA][rR][iI][aA][bB][lL][eE] { ltoken.type = TOK_VARIABLE; ltoken.text = yytext; + return <oken; } -emit-byte { token.type = TOK_EMIT_BYTE; token.text = yytext; - return &token; } +[vV][eE][rR][sS][iI][oO][nN]1 { ltoken.type = TOK_VERSION1; ltoken.text = yytext; + return <oken; } -\]tokenizer { token.type = TOK_ENDTOK; token.text = yytext; - return &token; } +[wW][hH][iI][lL][eE] { ltoken.type = TOK_WHILE; ltoken.text = yytext; + return <oken; } -fload { token.type = TOK_FLOAD; token.text = yytext; - return &token; } +tokenizer\[ { ltoken.type = TOK_BEGTOK; ltoken.text = yytext; + return <oken; } +emit-byte { ltoken.type = TOK_EMIT_BYTE; ltoken.text = yytext; + return <oken; } -[^ \n\t\r\f]+ { token.type = TOK_OTHER; token.text = yytext; - return &token; } +\]tokenizer { ltoken.type = TOK_ENDTOK; ltoken.text = yytext; + return <oken; } + +[fF][lL][oO][aA][dD] { ltoken.type = TOK_FLOAD; ltoken.text = yytext; + return <oken; } + + +[^ \n\t\r\f]+ { ltoken.type = TOK_OTHER; ltoken.text = yytext; + return <oken; } <<EOF>> { return NULL; } %% /* Function definitions */ -void push(Cell); -Cell pop(void); -int depth(void); -int fadd(struct fcode *, struct fcode *); -struct fcode *flookup(struct fcode *, char *); -int aadd(struct macro *, struct macro *); -struct macro *alookup(struct macro *, char *); -void initdic(void); -void usage(char *); -void tokenize(YY_BUFFER_STATE); -int emit(char *); -int spit(long); -void sspit(char *); -int apply_macros(YY_BUFFER_STATE, char *); -int main(int argc, char *argv[]); +static void push(Cell); +static Cell pop(void); +static int depth(void); +static int fadd(struct fcode *, struct fcode *); +static struct fcode *flookup(struct fcode *, const char *); +static int aadd(struct macro *, struct macro *); +static struct macro *alookup(struct macro *, const char *); +static void initdic(void); +__dead static void usage(void); +static void tokenize(YY_BUFFER_STATE); +static int emit(const char *); +static int spit(long); +static int offspit(long); +static void sspit(const char *); +static int apply_macros(YY_BUFFER_STATE, const char *); +static Cell cvt(const char *, char **, int base); /* * Standard FCode names and numbers. Includes standard * tokenizer aliases. */ -struct fcode fcodes[] = { - { "end0", 0x0000 }, - { "b(lit)", 0x0010 }, - { "b(')", 0x0011 }, - { "b(\")", 0x0012 }, - { "bbranch", 0x0013 }, - { "b?branch", 0x0014 }, - { "b(loop)", 0x0015 }, - { "b(+loop)", 0x0016 }, - { "b(do)", 0x0017 }, - { "b(?do)", 0x0018 }, - { "i", 0x0019 }, - { "j", 0x001a }, - { "b(leave)", 0x001b }, - { "b(of)", 0x001c }, - { "execute", 0x001d }, - { "+", 0x001e }, - { "-", 0x001f }, - { "*", 0x0020 }, - { "/", 0x0021 }, - { "mod", 0x0022 }, - { "and", 0x0023 }, - { "or", 0x0024 }, - { "xor", 0x0025 }, - { "invert", 0x0026 }, - { "lshift", 0x0027 }, - { "rshift", 0x0028 }, - { ">>a", 0x0029 }, - { "/mod", 0x002a }, - { "u/mod", 0x002b }, - { "negate", 0x002c }, - { "abs", 0x002d }, - { "min", 0x002e }, - { "max", 0x002f }, - { ">r", 0x0030 }, - { "r>", 0x0031 }, - { "r@", 0x0032 }, - { "exit", 0x0033 }, - { "0=", 0x0034 }, - { "0<>", 0x0035 }, - { "0<", 0x0036 }, - { "0<=", 0x0037 }, - { "0>", 0x0038 }, - { "0>=", 0x0039 }, - { "<", 0x003a }, - { ">", 0x003b }, - { "=", 0x003c }, - { "<>", 0x003d }, - { "u>", 0x003e }, - { "u<=", 0x003f }, - { "u<", 0x0040 }, - { "u>=", 0x0041 }, - { ">=", 0x0042 }, - { "<=", 0x0043 }, - { "between", 0x0044 }, - { "within", 0x0045 }, - { "drop", 0x0046 }, - { "dup", 0x0047 }, - { "over", 0x0048 }, - { "swap", 0x0049 }, - { "rot", 0x004a }, - { "-rot", 0x004b }, - { "tuck", 0x004c }, - { "nip", 0x004d }, - { "pick", 0x004e }, - { "roll", 0x004f }, - { "?dup", 0x0050 }, - { "depth", 0x0051 }, - { "2drop", 0x0052 }, - { "2dup", 0x0053 }, - { "2over", 0x0054 }, - { "2swap", 0x0055 }, - { "2rot", 0x0056 }, - { "2/", 0x0057 }, - { "u2/", 0x0058 }, - { "2*", 0x0059 }, - { "/c", 0x005a }, - { "/w", 0x005b }, - { "/l", 0x005c }, - { "/n", 0x005d }, - { "ca+", 0x005e }, - { "wa+", 0x005f }, - { "la+", 0x0060 }, - { "na+", 0x0061 }, - { "char+", 0x0062 }, - { "wa1+", 0x0063 }, - { "la1+", 0x0064 }, - { "cell+", 0x0065 }, - { "chars", 0x0066 }, - { "/w*", 0x0067 }, - { "/l*", 0x0068 }, - { "cells", 0x0069 }, - { "on", 0x006a }, - { "off", 0x006b }, - { "+!", 0x006c }, - { "@", 0x006d }, - { "l@", 0x006e }, - { "w@", 0x006f }, - { "<w@", 0x0070 }, - { "c@", 0x0071 }, - { "!", 0x0072 }, - { "l!", 0x0073 }, - { "w!", 0x0074 }, - { "c!", 0x0075 }, - { "2@", 0x0076 }, - { "2!", 0x0077 }, - { "move", 0x0078 }, - { "fill", 0x0079 }, - { "comp", 0x007a }, - { "noop", 0x007b }, - { "lwsplit", 0x007c }, - { "wjoin", 0x007d }, - { "lbsplit", 0x007e }, - { "bljoin", 0x007f }, - { "wbflip", 0x0080 }, - { "upc", 0x0081 }, - { "lcc", 0x0082 }, - { "pack", 0x0083 }, - { "count", 0x0084 }, - { "body>", 0x0085 }, - { ">body", 0x0086 }, - { "fcode-revision", 0x0087 }, - { "span", 0x0088 }, - { "unloop", 0x0089 }, - { "expect", 0x008a }, - { "alloc-mem", 0x008b }, - { "free-mem", 0x008c }, - { "key?", 0x008d }, - { "key", 0x008e }, - { "emit", 0x008f }, - { "type", 0x0090 }, - { "(cr", 0x0091 }, - { "cr", 0x0092 }, - { "#out", 0x0093 }, - { "#line", 0x0094 }, - { "hold", 0x0095 }, - { "<#", 0x0096 }, - { "u#>", 0x0097 }, - { "sign", 0x0098 }, - { "u#", 0x0099 }, - { "u#s", 0x009a }, - { "u.", 0x009b }, - { "u.r", 0x009c }, - { ".", 0x009d }, - { ".r", 0x009e }, - { ".s", 0x009f }, - { "base", 0x00a0 }, - { "convert", 0x00a1 }, - { "$number", 0x00a2 }, - { "digit", 0x00a3 }, - { "-1", 0x00a4 }, - { "true", 0x00a4 }, - { "0", 0x00a5 }, - { "1", 0x00a6 }, - { "2", 0x00a7 }, - { "3", 0x00a8 }, - { "bl", 0x00a9 }, - { "bs", 0x00aa }, - { "bell", 0x00ab }, - { "bounds", 0x00ac }, - { "here", 0x00ad }, - { "aligned", 0x00ae }, - { "wbsplit", 0x00af }, - { "bwjoin", 0x00b0 }, - { "b(<mark)", 0x00b1 }, - { "b(>resolve)", 0x00b2 }, - { "set-token-table", 0x00b3 }, - { "set-table", 0x00b4 }, - { "new-token", 0x00b5 }, - { "named-token", 0x00b6 }, - { "b(:)", 0x00b7 }, - { "b(value)", 0x00b8 }, - { "b(variable)", 0x00b9 }, - { "b(constant)", 0x00ba }, - { "b(create)", 0x00bb }, - { "b(defer)", 0x00bc }, - { "b(buffer:)", 0x00bd }, - { "b(field)", 0x00be }, - { "b(code)", 0x00bf }, - { "instance", 0x00c0 }, - { "b(;)", 0x00c2 }, - { "b(to)", 0x00c3 }, - { "b(case)", 0x00c4 }, - { "b(endcase)", 0x00c5 }, - { "b(endof)", 0x00c6 }, - { "#", 0x00c7 }, - { "#s", 0x00c8 }, - { "#>", 0x00c9 }, - { "external-token", 0x00ca }, - { "$find", 0x00cb }, - { "offset16", 0x00cc }, - { "evaluate", 0x00cd }, - { "c,", 0x00d0 }, - { "w,", 0x00d1 }, - { "l,", 0x00d2 }, - { "'", 0x00d3 }, - { "um*", 0x00d4 }, - { "um/mod", 0x00d5 }, - { "d+", 0x00d8 }, - { "d-", 0x00d9 }, - { "get-token", 0x00da }, - { "set-token", 0x00db }, - { "state", 0x00dc }, - { "compile,", 0x00dd }, - { "behavior", 0x00de }, - { "start0", 0x00f0 }, - { "start1", 0x00f1 }, - { "start2", 0x00f2 }, - { "start4", 0x00f3 }, - { "ferror", 0x00fc }, - { "version1", 0x00fd }, - { "4-byte-id", 0x00fe }, - { "end1", 0x00ff }, - { "dma-alloc", 0x0101 }, - { "my-address", 0x0102 }, - { "my-space", 0x0103 }, - { "memmap", 0x0104 }, - { "free-virtual", 0x0105 }, - { ">physical", 0x0106 }, - { "my-params", 0x010f }, - { "property", 0x0110 }, - { "encode-int", 0x0111 }, - { "encode+", 0x0112 }, - { "encode-phys", 0x0113 }, - { "encode-string", 0x0114 }, - { "encode-bytes", 0x0115 }, - { "reg", 0x0116 }, - { "intr", 0x0117 }, - { "driver", 0x0118 }, - { "model", 0x0119 }, - { "device-type", 0x011a }, - { "parse-2int", 0x011b }, - { "is-install", 0x011c }, - { "is-remove", 0x011d }, - { "is-selftest", 0x011e }, - { "new-device", 0x011f }, - { "diagnostic-mode?", 0x0120 }, - { "display-status", 0x0121 }, - { "memory-test-suite", 0x0122 }, - { "group-code", 0x0123 }, - { "mask", 0x0124 }, - { "get-msecs", 0x0125 }, - { "ms", 0x0126 }, - { "find-device", 0x0127 }, - { "decode-phys", 0x0128 }, - { "map-low", 0x0130 }, - { "sbus-intr>cpu", 0x0131 }, - { "#lines", 0x0150 }, - { "#columns", 0x0151 }, - { "line#", 0x0152 }, - { "column#", 0x0153 }, - { "inverse?", 0x0154 }, - { "inverse-screen?", 0x0155 }, - { "frame-buffer-busy?", 0x0156 }, - { "draw-character", 0x0157 }, - { "reset-screen", 0x0158 }, - { "toggle-cursor", 0x0159 }, - { "erase-screen", 0x015a }, - { "blink-screen", 0x015b }, - { "invert-screen", 0x015c }, - { "insert-characters", 0x015d }, - { "delete-characters", 0x015e }, - { "insert-lines", 0x015f }, - { "delete-lines", 0x0160 }, - { "draw-logo", 0x0161 }, - { "frame-buffer-addr", 0x0162 }, - { "screen-height", 0x0163 }, - { "screen-width", 0x0164 }, - { "window-top", 0x0165 }, - { "window-left", 0x0166 }, - { "default-font", 0x016a }, - { "set-font", 0x016b }, - { "char-height", 0x016c }, - { "char-width", 0x016d }, - { ">font", 0x016e }, - { "fontbytes", 0x016f }, - { "fb8-draw-character", 0x0180 }, - { "fb8-reset-screen", 0x0181 }, - { "fb8-toggle-cursor", 0x0182 }, - { "fb8-erase-screen", 0x0183 }, - { "fb8-blink-screen", 0x0184 }, - { "fb8-invert-screen", 0x0185 }, - { "fb8-insert-characters", 0x0186 }, - { "fb8-delete-characters", 0x0187 }, - { "fb8-inisert-lines", 0x0188 }, - { "fb8-delete-lines", 0x0189 }, - { "fb8-draw-logo", 0x018a }, - { "fb8-install", 0x018b }, - { "return-buffer", 0x01a0 }, - { "xmit-packet", 0x01a1 }, - { "poll-packet", 0x01a2 }, - { "mac-address", 0x01a4 }, - { "device-name", 0x0201 }, - { "my-args", 0x0202 }, - { "my-self", 0x0203 }, - { "find-package", 0x0204 }, - { "open-package", 0x0205 }, - { "close-package", 0x0206 }, - { "find-method", 0x0207 }, - { "call-package", 0x0208 }, - { "$call-parent", 0x0209 }, - { "my-parent", 0x020a }, - { "ihandle>phandle", 0x020b }, - { "my-unit", 0x020d }, - { "$call-method", 0x020e }, - { "$open-package", 0x020f }, - { "processor-type", 0x0210 }, - { "firmware-version", 0x0211 }, - { "fcode-version", 0x0212 }, - { "alarm", 0x0213 }, - { "(is-user-word)", 0x0214 }, - { "suspend-fcode", 0x0215 }, - { "abort", 0x0216 }, - { "catch", 0x0217 }, - { "throw", 0x0218 }, - { "user-abort", 0x0219 }, - { "get-my-property", 0x021a }, - { "decode-int", 0x021b }, - { "decode-string", 0x021c }, - { "get-inherited-property", 0x021d }, - { "delete-property", 0x021e }, - { "get-package-property", 0x021f }, - { "cpeek", 0x0220 }, - { "wpeek", 0x0221 }, - { "lpeek", 0x0222 }, - { "cpoke", 0x0223 }, - { "wpoke", 0x0224 }, - { "lpoke", 0x0225 }, - { "lwflip", 0x0226 }, - { "lbflip", 0x0227 }, - { "lbflips", 0x0228 }, - { "adr-mask", 0x0229 }, - { "rb@", 0x0230 }, - { "rb!", 0x0231 }, - { "rw@", 0x0232 }, - { "rw!", 0x0233 }, - { "rl@", 0x0234 }, - { "rl!", 0x0235 }, - { "wbflips", 0x0236 }, - { "lwflips", 0x0237 }, - { "probe", 0x0238 }, - { "probe-virtual", 0x0239 }, - { "child", 0x023b }, - { "peer", 0x023c }, - { "next-property", 0x023d }, - { "byte-load", 0x023e }, - { "set-args", 0x023f }, - { "left-parse-string", 0x0240 }, +static struct fcode fcodes[] = { + { "end0", 0x0000, 0, NULL, NULL }, + { "b(lit)", 0x0010, 0, NULL, NULL }, + { "b(')", 0x0011, 0, NULL, NULL }, + { "b(\")", 0x0012, 0, NULL, NULL }, + { "bbranch", 0x0013, 0, NULL, NULL }, + { "b?branch", 0x0014, 0, NULL, NULL }, + { "b(loop)", 0x0015, 0, NULL, NULL }, + { "b(+loop)", 0x0016, 0, NULL, NULL }, + { "b(do)", 0x0017, 0, NULL, NULL }, + { "b(?do)", 0x0018, 0, NULL, NULL }, + { "i", 0x0019, 0, NULL, NULL }, + { "j", 0x001a, 0, NULL, NULL }, + { "b(leave)", 0x001b, 0, NULL, NULL }, + { "b(of)", 0x001c, 0, NULL, NULL }, + { "execute", 0x001d, 0, NULL, NULL }, + { "+", 0x001e, 0, NULL, NULL }, + { "-", 0x001f, 0, NULL, NULL }, + { "*", 0x0020, 0, NULL, NULL }, + { "/", 0x0021, 0, NULL, NULL }, + { "mod", 0x0022, 0, NULL, NULL }, + { "and", 0x0023, 0, NULL, NULL }, + { "or", 0x0024, 0, NULL, NULL }, + { "xor", 0x0025, 0, NULL, NULL }, + { "invert", 0x0026, 0, NULL, NULL }, + { "lshift", 0x0027, 0, NULL, NULL }, + { "rshift", 0x0028, 0, NULL, NULL }, + { ">>a", 0x0029, 0, NULL, NULL }, + { "/mod", 0x002a, 0, NULL, NULL }, + { "u/mod", 0x002b, 0, NULL, NULL }, + { "negate", 0x002c, 0, NULL, NULL }, + { "abs", 0x002d, 0, NULL, NULL }, + { "min", 0x002e, 0, NULL, NULL }, + { "max", 0x002f, 0, NULL, NULL }, + { ">r", 0x0030, 0, NULL, NULL }, + { "r>", 0x0031, 0, NULL, NULL }, + { "r@", 0x0032, 0, NULL, NULL }, + { "exit", 0x0033, 0, NULL, NULL }, + { "0=", 0x0034, 0, NULL, NULL }, + { "0<>", 0x0035, 0, NULL, NULL }, + { "0<", 0x0036, 0, NULL, NULL }, + { "0<=", 0x0037, 0, NULL, NULL }, + { "0>", 0x0038, 0, NULL, NULL }, + { "0>=", 0x0039, 0, NULL, NULL }, + { "<", 0x003a, 0, NULL, NULL }, + { ">", 0x003b, 0, NULL, NULL }, + { "=", 0x003c, 0, NULL, NULL }, + { "<>", 0x003d, 0, NULL, NULL }, + { "u>", 0x003e, 0, NULL, NULL }, + { "u<=", 0x003f, 0, NULL, NULL }, + { "u<", 0x0040, 0, NULL, NULL }, + { "u>=", 0x0041, 0, NULL, NULL }, + { ">=", 0x0042, 0, NULL, NULL }, + { "<=", 0x0043, 0, NULL, NULL }, + { "between", 0x0044, 0, NULL, NULL }, + { "within", 0x0045, 0, NULL, NULL }, + { "drop", 0x0046, 0, NULL, NULL }, + { "dup", 0x0047, 0, NULL, NULL }, + { "over", 0x0048, 0, NULL, NULL }, + { "swap", 0x0049, 0, NULL, NULL }, + { "rot", 0x004a, 0, NULL, NULL }, + { "-rot", 0x004b, 0, NULL, NULL }, + { "tuck", 0x004c, 0, NULL, NULL }, + { "nip", 0x004d, 0, NULL, NULL }, + { "pick", 0x004e, 0, NULL, NULL }, + { "roll", 0x004f, 0, NULL, NULL }, + { "?dup", 0x0050, 0, NULL, NULL }, + { "depth", 0x0051, 0, NULL, NULL }, + { "2drop", 0x0052, 0, NULL, NULL }, + { "2dup", 0x0053, 0, NULL, NULL }, + { "2over", 0x0054, 0, NULL, NULL }, + { "2swap", 0x0055, 0, NULL, NULL }, + { "2rot", 0x0056, 0, NULL, NULL }, + { "2/", 0x0057, 0, NULL, NULL }, + { "u2/", 0x0058, 0, NULL, NULL }, + { "2*", 0x0059, 0, NULL, NULL }, + { "/c", 0x005a, 0, NULL, NULL }, + { "/w", 0x005b, 0, NULL, NULL }, + { "/l", 0x005c, 0, NULL, NULL }, + { "/n", 0x005d, 0, NULL, NULL }, + { "ca+", 0x005e, 0, NULL, NULL }, + { "wa+", 0x005f, 0, NULL, NULL }, + { "la+", 0x0060, 0, NULL, NULL }, + { "na+", 0x0061, 0, NULL, NULL }, + { "char+", 0x0062, 0, NULL, NULL }, + { "wa1+", 0x0063, 0, NULL, NULL }, + { "la1+", 0x0064, 0, NULL, NULL }, + { "cell+", 0x0065, 0, NULL, NULL }, + { "chars", 0x0066, 0, NULL, NULL }, + { "/w*", 0x0067, 0, NULL, NULL }, + { "/l*", 0x0068, 0, NULL, NULL }, + { "cells", 0x0069, 0, NULL, NULL }, + { "on", 0x006a, 0, NULL, NULL }, + { "off", 0x006b, 0, NULL, NULL }, + { "+!", 0x006c, 0, NULL, NULL }, + { "@", 0x006d, 0, NULL, NULL }, + { "l@", 0x006e, 0, NULL, NULL }, + { "w@", 0x006f, 0, NULL, NULL }, + { "<w@", 0x0070, 0, NULL, NULL }, + { "c@", 0x0071, 0, NULL, NULL }, + { "!", 0x0072, 0, NULL, NULL }, + { "l!", 0x0073, 0, NULL, NULL }, + { "w!", 0x0074, 0, NULL, NULL }, + { "c!", 0x0075, 0, NULL, NULL }, + { "2@", 0x0076, 0, NULL, NULL }, + { "2!", 0x0077, 0, NULL, NULL }, + { "move", 0x0078, 0, NULL, NULL }, + { "fill", 0x0079, 0, NULL, NULL }, + { "comp", 0x007a, 0, NULL, NULL }, + { "noop", 0x007b, 0, NULL, NULL }, + { "lwsplit", 0x007c, 0, NULL, NULL }, + { "wjoin", 0x007d, 0, NULL, NULL }, + { "lbsplit", 0x007e, 0, NULL, NULL }, + { "bljoin", 0x007f, 0, NULL, NULL }, + { "wbflip", 0x0080, 0, NULL, NULL }, + { "upc", 0x0081, 0, NULL, NULL }, + { "lcc", 0x0082, 0, NULL, NULL }, + { "pack", 0x0083, 0, NULL, NULL }, + { "count", 0x0084, 0, NULL, NULL }, + { "body>", 0x0085, 0, NULL, NULL }, + { ">body", 0x0086, 0, NULL, NULL }, + { "fcode-revision", 0x0087, 0, NULL, NULL }, + { "span", 0x0088, 0, NULL, NULL }, + { "unloop", 0x0089, 0, NULL, NULL }, + { "expect", 0x008a, 0, NULL, NULL }, + { "alloc-mem", 0x008b, 0, NULL, NULL }, + { "free-mem", 0x008c, 0, NULL, NULL }, + { "key?", 0x008d, 0, NULL, NULL }, + { "key", 0x008e, 0, NULL, NULL }, + { "emit", 0x008f, 0, NULL, NULL }, + { "type", 0x0090, 0, NULL, NULL }, + { "(cr", 0x0091, 0, NULL, NULL }, + { "cr", 0x0092, 0, NULL, NULL }, + { "#out", 0x0093, 0, NULL, NULL }, + { "#line", 0x0094, 0, NULL, NULL }, + { "hold", 0x0095, 0, NULL, NULL }, + { "<#", 0x0096, 0, NULL, NULL }, + { "u#>", 0x0097, 0, NULL, NULL }, + { "sign", 0x0098, 0, NULL, NULL }, + { "u#", 0x0099, 0, NULL, NULL }, + { "u#s", 0x009a, 0, NULL, NULL }, + { "u.", 0x009b, 0, NULL, NULL }, + { "u.r", 0x009c, 0, NULL, NULL }, + { ".", 0x009d, 0, NULL, NULL }, + { ".r", 0x009e, 0, NULL, NULL }, + { ".s", 0x009f, 0, NULL, NULL }, + { "base", 0x00a0, 0, NULL, NULL }, + { "convert", 0x00a1, 0, NULL, NULL }, + { "$number", 0x00a2, 0, NULL, NULL }, + { "digit", 0x00a3, 0, NULL, NULL }, + { "-1", 0x00a4, 0, NULL, NULL }, + { "true", 0x00a4, 0, NULL, NULL }, + { "0", 0x00a5, 0, NULL, NULL }, + { "1", 0x00a6, 0, NULL, NULL }, + { "2", 0x00a7, 0, NULL, NULL }, + { "3", 0x00a8, 0, NULL, NULL }, + { "bl", 0x00a9, 0, NULL, NULL }, + { "bs", 0x00aa, 0, NULL, NULL }, + { "bell", 0x00ab, 0, NULL, NULL }, + { "bounds", 0x00ac, 0, NULL, NULL }, + { "here", 0x00ad, 0, NULL, NULL }, + { "aligned", 0x00ae, 0, NULL, NULL }, + { "wbsplit", 0x00af, 0, NULL, NULL }, + { "bwjoin", 0x00b0, 0, NULL, NULL }, + { "b(<mark)", 0x00b1, 0, NULL, NULL }, + { "b(>resolve)", 0x00b2, 0, NULL, NULL }, + { "set-token-table", 0x00b3, 0, NULL, NULL }, + { "set-table", 0x00b4, 0, NULL, NULL }, + { "new-token", 0x00b5, 0, NULL, NULL }, + { "named-token", 0x00b6, 0, NULL, NULL }, + { "b(:)", 0x00b7, 0, NULL, NULL }, + { "b(value)", 0x00b8, 0, NULL, NULL }, + { "b(variable)", 0x00b9, 0, NULL, NULL }, + { "b(constant)", 0x00ba, 0, NULL, NULL }, + { "b(create)", 0x00bb, 0, NULL, NULL }, + { "b(defer)", 0x00bc, 0, NULL, NULL }, + { "b(buffer:)", 0x00bd, 0, NULL, NULL }, + { "b(field)", 0x00be, 0, NULL, NULL }, + { "b(code)", 0x00bf, 0, NULL, NULL }, + { "instance", 0x00c0, 0, NULL, NULL }, + { "b(;)", 0x00c2, 0, NULL, NULL }, + { "b(to)", 0x00c3, 0, NULL, NULL }, + { "b(case)", 0x00c4, 0, NULL, NULL }, + { "b(endcase)", 0x00c5, 0, NULL, NULL }, + { "b(endof)", 0x00c6, 0, NULL, NULL }, + { "#", 0x00c7, 0, NULL, NULL }, + { "#s", 0x00c8, 0, NULL, NULL }, + { "#>", 0x00c9, 0, NULL, NULL }, + { "external-token", 0x00ca, 0, NULL, NULL }, + { "$find", 0x00cb, 0, NULL, NULL }, + { "offset16", 0x00cc, 0, NULL, NULL }, + { "evaluate", 0x00cd, 0, NULL, NULL }, + { "c,", 0x00d0, 0, NULL, NULL }, + { "w,", 0x00d1, 0, NULL, NULL }, + { "l,", 0x00d2, 0, NULL, NULL }, + { ",", 0x00d3, 0, NULL, NULL }, + { "um*", 0x00d4, 0, NULL, NULL }, + { "um/mod", 0x00d5, 0, NULL, NULL }, + { "d+", 0x00d8, 0, NULL, NULL }, + { "d-", 0x00d9, 0, NULL, NULL }, + { "get-token", 0x00da, 0, NULL, NULL }, + { "set-token", 0x00db, 0, NULL, NULL }, + { "state", 0x00dc, 0, NULL, NULL }, + { "compile,", 0x00dd, 0, NULL, NULL }, + { "behavior", 0x00de, 0, NULL, NULL }, + { "start0", 0x00f0, 0, NULL, NULL }, + { "start1", 0x00f1, 0, NULL, NULL }, + { "start2", 0x00f2, 0, NULL, NULL }, + { "start4", 0x00f3, 0, NULL, NULL }, + { "ferror", 0x00fc, 0, NULL, NULL }, + { "version1", 0x00fd, 0, NULL, NULL }, + { "4-byte-id", 0x00fe, 0, NULL, NULL }, + { "end1", 0x00ff, 0, NULL, NULL }, + { "dma-alloc", 0x0101, 0, NULL, NULL }, + { "my-address", 0x0102, 0, NULL, NULL }, + { "my-space", 0x0103, 0, NULL, NULL }, + { "memmap", 0x0104, 0, NULL, NULL }, + { "free-virtual", 0x0105, 0, NULL, NULL }, + { ">physical", 0x0106, 0, NULL, NULL }, + { "my-params", 0x010f, 0, NULL, NULL }, + { "property", 0x0110, 0, NULL, NULL }, + { "encode-int", 0x0111, 0, NULL, NULL }, + { "encode+", 0x0112, 0, NULL, NULL }, + { "encode-phys", 0x0113, 0, NULL, NULL }, + { "encode-string", 0x0114, 0, NULL, NULL }, + { "encode-bytes", 0x0115, 0, NULL, NULL }, + { "reg", 0x0116, 0, NULL, NULL }, + { "intr", 0x0117, 0, NULL, NULL }, + { "driver", 0x0118, 0, NULL, NULL }, + { "model", 0x0119, 0, NULL, NULL }, + { "device-type", 0x011a, 0, NULL, NULL }, + { "parse-2int", 0x011b, 0, NULL, NULL }, + { "is-install", 0x011c, 0, NULL, NULL }, + { "is-remove", 0x011d, 0, NULL, NULL }, + { "is-selftest", 0x011e, 0, NULL, NULL }, + { "new-device", 0x011f, 0, NULL, NULL }, + { "diagnostic-mode?", 0x0120, 0, NULL, NULL }, + { "display-status", 0x0121, 0, NULL, NULL }, + { "memory-test-suite", 0x0122, 0, NULL, NULL }, + { "group-code", 0x0123, 0, NULL, NULL }, + { "mask", 0x0124, 0, NULL, NULL }, + { "get-msecs", 0x0125, 0, NULL, NULL }, + { "ms", 0x0126, 0, NULL, NULL }, + { "finish-device", 0x0127, 0, NULL, NULL }, + { "decode-phys", 0x0128, 0, NULL, NULL }, + { "map-low", 0x0130, 0, NULL, NULL }, + { "sbus-intr>cpu", 0x0131, 0, NULL, NULL }, + { "#lines", 0x0150, 0, NULL, NULL }, + { "#columns", 0x0151, 0, NULL, NULL }, + { "line#", 0x0152, 0, NULL, NULL }, + { "column#", 0x0153, 0, NULL, NULL }, + { "inverse?", 0x0154, 0, NULL, NULL }, + { "inverse-screen?", 0x0155, 0, NULL, NULL }, + { "frame-buffer-busy?", 0x0156, 0, NULL, NULL }, + { "draw-character", 0x0157, 0, NULL, NULL }, + { "reset-screen", 0x0158, 0, NULL, NULL }, + { "toggle-cursor", 0x0159, 0, NULL, NULL }, + { "erase-screen", 0x015a, 0, NULL, NULL }, + { "blink-screen", 0x015b, 0, NULL, NULL }, + { "invert-screen", 0x015c, 0, NULL, NULL }, + { "insert-characters", 0x015d, 0, NULL, NULL }, + { "delete-characters", 0x015e, 0, NULL, NULL }, + { "insert-lines", 0x015f, 0, NULL, NULL }, + { "delete-lines", 0x0160, 0, NULL, NULL }, + { "draw-logo", 0x0161, 0, NULL, NULL }, + { "frame-buffer-addr", 0x0162, 0, NULL, NULL }, + { "screen-height", 0x0163, 0, NULL, NULL }, + { "screen-width", 0x0164, 0, NULL, NULL }, + { "window-top", 0x0165, 0, NULL, NULL }, + { "window-left", 0x0166, 0, NULL, NULL }, + { "default-font", 0x016a, 0, NULL, NULL }, + { "set-font", 0x016b, 0, NULL, NULL }, + { "char-height", 0x016c, 0, NULL, NULL }, + { "char-width", 0x016d, 0, NULL, NULL }, + { ">font", 0x016e, 0, NULL, NULL }, + { "fontbytes", 0x016f, 0, NULL, NULL }, + { "fb8-draw-character", 0x0180, 0, NULL, NULL }, + { "fb8-reset-screen", 0x0181, 0, NULL, NULL }, + { "fb8-toggle-cursor", 0x0182, 0, NULL, NULL }, + { "fb8-erase-screen", 0x0183, 0, NULL, NULL }, + { "fb8-blink-screen", 0x0184, 0, NULL, NULL }, + { "fb8-invert-screen", 0x0185, 0, NULL, NULL }, + { "fb8-insert-characters", 0x0186, 0, NULL, NULL }, + { "fb8-delete-characters", 0x0187, 0, NULL, NULL }, + { "fb8-inisert-lines", 0x0188, 0, NULL, NULL }, + { "fb8-delete-lines", 0x0189, 0, NULL, NULL }, + { "fb8-draw-logo", 0x018a, 0, NULL, NULL }, + { "fb8-install", 0x018b, 0, NULL, NULL }, + { "return-buffer", 0x01a0, 0, NULL, NULL }, + { "xmit-packet", 0x01a1, 0, NULL, NULL }, + { "poll-packet", 0x01a2, 0, NULL, NULL }, + { "mac-address", 0x01a4, 0, NULL, NULL }, + { "device-name", 0x0201, 0, NULL, NULL }, + { "my-args", 0x0202, 0, NULL, NULL }, + { "my-self", 0x0203, 0, NULL, NULL }, + { "find-package", 0x0204, 0, NULL, NULL }, + { "open-package", 0x0205, 0, NULL, NULL }, + { "close-package", 0x0206, 0, NULL, NULL }, + { "find-method", 0x0207, 0, NULL, NULL }, + { "call-package", 0x0208, 0, NULL, NULL }, + { "$call-parent", 0x0209, 0, NULL, NULL }, + { "my-parent", 0x020a, 0, NULL, NULL }, + { "ihandle>phandle", 0x020b, 0, NULL, NULL }, + { "my-unit", 0x020d, 0, NULL, NULL }, + { "$call-method", 0x020e, 0, NULL, NULL }, + { "$open-package", 0x020f, 0, NULL, NULL }, + { "processor-type", 0x0210, 0, NULL, NULL }, + { "firmware-version", 0x0211, 0, NULL, NULL }, + { "fcode-version", 0x0212, 0, NULL, NULL }, + { "alarm", 0x0213, 0, NULL, NULL }, + { "(is-user-word)", 0x0214, 0, NULL, NULL }, + { "suspend-fcode", 0x0215, 0, NULL, NULL }, + { "abort", 0x0216, 0, NULL, NULL }, + { "catch", 0x0217, 0, NULL, NULL }, + { "throw", 0x0218, 0, NULL, NULL }, + { "user-abort", 0x0219, 0, NULL, NULL }, + { "get-my-property", 0x021a, 0, NULL, NULL }, + { "decode-int", 0x021b, 0, NULL, NULL }, + { "decode-string", 0x021c, 0, NULL, NULL }, + { "get-inherited-property", 0x021d, 0, NULL, NULL }, + { "delete-property", 0x021e, 0, NULL, NULL }, + { "get-package-property", 0x021f, 0, NULL, NULL }, + { "cpeek", 0x0220, 0, NULL, NULL }, + { "wpeek", 0x0221, 0, NULL, NULL }, + { "lpeek", 0x0222, 0, NULL, NULL }, + { "cpoke", 0x0223, 0, NULL, NULL }, + { "wpoke", 0x0224, 0, NULL, NULL }, + { "lpoke", 0x0225, 0, NULL, NULL }, + { "lwflip", 0x0226, 0, NULL, NULL }, + { "lbflip", 0x0227, 0, NULL, NULL }, + { "lbflips", 0x0228, 0, NULL, NULL }, + { "adr-mask", 0x0229, 0, NULL, NULL }, + { "rb@", 0x0230, 0, NULL, NULL }, + { "rb!", 0x0231, 0, NULL, NULL }, + { "rw@", 0x0232, 0, NULL, NULL }, + { "rw!", 0x0233, 0, NULL, NULL }, + { "rl@", 0x0234, 0, NULL, NULL }, + { "rl!", 0x0235, 0, NULL, NULL }, + { "wbflips", 0x0236, 0, NULL, NULL }, + { "lwflips", 0x0237, 0, NULL, NULL }, + { "probe", 0x0238, 0, NULL, NULL }, + { "probe-virtual", 0x0239, 0, NULL, NULL }, + { "child", 0x023b, 0, NULL, NULL }, + { "peer", 0x023c, 0, NULL, NULL }, + { "next-property", 0x023d, 0, NULL, NULL }, + { "byte-load", 0x023e, 0, NULL, NULL }, + { "set-args", 0x023f, 0, NULL, NULL }, + { "left-parse-string", 0x0240, 0, NULL, NULL }, /* 64-bit FCode extensions */ - { "bxjoin", 0x0241 }, - { "<l@", 0x0242 }, - { "lxjoin", 0x0243 }, - { "rx@", 0x022e }, - { "rx!", 0x022f }, - { "wxjoin", 0x0244 }, - { "x,", 0x0245 }, - { "x@", 0x0246 }, - { "x!", 0x0247 }, - { "/x", 0x0248 }, - { "/x*", 0x0249 }, - { "xa+", 0x024a }, - { "xa1+", 0x024b }, - { "xbflip", 0x024c }, - { "xbflips", 0x024d }, - { "xbsplit", 0x024e }, - { "xlflip", 0x024f }, - { "xlflips", 0x0250 }, - { "xlsplit", 0x0251 }, - { "xwflip", 0x0252 }, - { "xwflips", 0x0253 }, - { "xwsplit", 0x0254 }, - { NULL, 0 } + { "bxjoin", 0x0241, 0, NULL, NULL }, + { "<l@", 0x0242, 0, NULL, NULL }, + { "lxjoin", 0x0243, 0, NULL, NULL }, + { "rx@", 0x022e, 0, NULL, NULL }, + { "rx!", 0x022f, 0, NULL, NULL }, + { "wxjoin", 0x0244, 0, NULL, NULL }, + { "x,", 0x0245, 0, NULL, NULL }, + { "x@", 0x0246, 0, NULL, NULL }, + { "x!", 0x0247, 0, NULL, NULL }, + { "/x", 0x0248, 0, NULL, NULL }, + { "/x*", 0x0249, 0, NULL, NULL }, + { "xa+", 0x024a, 0, NULL, NULL }, + { "xa1+", 0x024b, 0, NULL, NULL }, + { "xbflip", 0x024c, 0, NULL, NULL }, + { "xbflips", 0x024d, 0, NULL, NULL }, + { "xbsplit", 0x024e, 0, NULL, NULL }, + { "xlflip", 0x024f, 0, NULL, NULL }, + { "xlflips", 0x0250, 0, NULL, NULL }, + { "xlsplit", 0x0251, 0, NULL, NULL }, + { "xwflip", 0x0252, 0, NULL, NULL }, + { "xwflips", 0x0253, 0, NULL, NULL }, + { "xwsplit", 0x0254, 0, NULL, NULL }, + { NULL, 0, 0, NULL, NULL } }; /* * Default macros -- can be overridden by colon definitions. */ -struct macro macros[] = { - { "eval", "evaluate" }, /* Build a more balanced tree */ - { "(.)", "dup abs <# u#s swap sign u#>" }, - { "<<", "lshift" }, - { ">>", "rshift" }, - { "?", "@ ." }, - { "1+", "1 +" }, - { "1-", "1 -" }, - { "2+", "2 +" }, - { "2-", "2 -" }, - { "abort\"", "-2 throw" }, - { "accept", "span @ -rot expect span @ swap span !" }, - { "allot", "0 max 0 ?do 0 c, loop" }, - { "blank", "bl fill" }, - { "/c*", "chars" }, - { "ca1+", "char+" }, - { "carret", "b(lit) 00 00 00 0x0d" }, - { ".d" "base @ swap 0x0a base ! . base !" }, - { "decode-bytes", ">r over r@ + swap r@ - rot r>" }, - { "3drop", "drop 2drop" }, - { "3dup", "2 pick 2 pick 2 pick" }, - { "erase", "0 fill" }, - { "false", "0" }, - { ".h" "base @ swap 0x10 base ! . base !" }, - { "linefeed", "b(lit) 00 00 00 0x0a" }, - { "/n*", "cells" }, - { "na1+", "cell+", }, - { "not", "invert", }, - { "s.", "(.) type space" }, - { "space", "bl emit" }, - { "spaces", "0 max 0 ?do space loop" }, - { "struct", "0" }, - { "true", "-1" }, - { "(u,)", "<# u#s u#>" }, - { NULL, NULL } +static struct macro macros[] = { + { "eval", "evaluate", 0, NULL, NULL }, /* Build a more balanced tree */ + { "(.)", "dup abs <# u#s swap sign u#>", 0, NULL, NULL }, + { "<<", "lshift", 0, NULL, NULL }, + { ">>", "rshift", 0, NULL, NULL }, + { "?", "@ .", 0, NULL, NULL }, + { "1+", "1 +", 0, NULL, NULL }, + { "1-", "1 -", 0, NULL, NULL }, + { "2+", "2 +", 0, NULL, NULL }, + { "2-", "2 -", 0, NULL, NULL }, + { "abort\"", "-2 throw", 0, NULL, NULL }, + { "accept", "span @ -rot expect span @ swap span !", 0, NULL, NULL }, + { "allot", "0 max 0 ?do 0 c, loop", 0, NULL, NULL }, + { "blank", "bl fill", 0, NULL, NULL }, + { "/c*", "chars", 0, NULL, NULL }, + { "ca1+", "char+", 0, NULL, NULL }, + { "carret", "b(lit) 00 00 00 h# 0d", 0, NULL, NULL }, + { ".d", "base @ swap d# 0a base ! . base !", 0, NULL, NULL }, + { "decode-bytes", ">r over r@ + swap r@ - rot r>", 0, NULL, NULL }, + { "3drop", "drop 2drop", 0, NULL, NULL }, + { "3dup", "2 pick 2 pick 2 pick", 0, NULL, NULL }, + { "erase", "0 fill", 0, NULL, NULL }, + { "false", "0", 0, NULL, NULL }, + { ".h", "base @ swap d# 10 base ! . base !", 0, NULL, NULL }, + { "linefeed", "b(lit) 00 00 00 d# 0a", 0, NULL, NULL }, + { "/n*", "cells", 0, NULL, NULL }, + { "na1+", "cell+", 0, NULL, NULL }, + { "not", "invert", 0, NULL, NULL }, + { "s.", "(.) type space", 0, NULL, NULL }, + { "space", "bl emit", 0, NULL, NULL }, + { "spaces", "0 max 0 ?do space loop", 0, NULL, NULL }, + { "struct", "0", 0, NULL, NULL }, + { "true", "-1", 0, NULL, NULL }, + { "(u,)", "<# u#s u#>", 0, NULL, NULL }, + { NULL, NULL, 0, NULL, NULL } }; /* + * Utility functions. + */ + +/* + * ASCII -> long int converter, eats `.'s + */ +#define strtol(x, y, z) cvt(x, y, z) +static Cell +cvt(const char *s, char **e, int base) +{ + Cell v = 0; + int c, n = 0; + + c = *s; + if (c == '-') { n = 1; s++; } + + for (c = *s; (c = *s); s++) { + + /* Ignore `.' */ + if (c == '.') + continue; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'a' && c <= 'f') + c += 10 - 'a'; + else if (c >= 'A' && c <= 'F') + c += 10 - 'A'; + if (c >= base) + break; + v *= base; + v += c; + } + if (e) + *e = (char *)s; + if (n) + return (-v); + return (v); +} + +/* * Parser stack control functions. */ -void -push(val) -Cell val; +static void +push(Cell val) { + if (debug > 1) + printf("push %lx\n", (long)val); parse_stack[parse_stack_ptr++] = val; - if (parse_stack_ptr >= PSTKSIZ) { - (void)printf( "Parse stack overflow\n"); - exit(1); - } + if (parse_stack_ptr >= PSTKSIZ) + errx(EXIT_FAILURE, "Parse stack overflow"); } -Cell -pop() +static Cell +pop(void) { ASSERT(parse_stack_ptr); + if (debug > 1) + printf("pop %lx\n", (long)parse_stack[parse_stack_ptr-1]); return parse_stack[--parse_stack_ptr]; } -int -depth() +static int +depth(void) { return (parse_stack_ptr); } @@ -748,27 +831,28 @@ depth() /* * Insert fcode into dictionary. */ -int -fadd(dict, new) -struct fcode *dict, *new; +static int +fadd(struct fcode *dict, struct fcode *new) { int res = strcmp(dict->name, new->name); -#ifdef DEBUG new->type = FCODE; ASSERT(dict->type == FCODE); -#endif - /* Don't allow duplicate entries. */ - if (!res) return (0); + if (!res) { + /* + * Duplicate entry. Give the old name the new FCode + * number. + */ + dict->num = new->num; + return (0); + } if (res < 0) { if (dict->l) return fadd(dict->l, new); else { -#ifdef DEBUG - if (debug > 1) - (void)printf( "fadd: new FCode `%s' is %lx\n", + if (debug > 5) + printf("fadd: new FCode `%s' is %lx\n", new->name, new->num); -#endif new->l = new->r = NULL; dict->l = new; } @@ -776,11 +860,9 @@ struct fcode *dict, *new; if (dict->r) return fadd(dict->r, new); else { -#ifdef DEBUG - if (debug > 1) - (void)printf( "fadd: new FCode `%s' is %lx\n", + if (debug > 5) + printf("fadd: new FCode `%s' is %lx\n", new->name, new->num); -#endif new->l = new->r = NULL; dict->r = new; } @@ -791,21 +873,17 @@ struct fcode *dict, *new; /* * Look for a code in the dictionary. */ -struct fcode * -flookup(dict, str) -struct fcode *dict; -char *str; +static struct fcode * +flookup(struct fcode *dict, const char *str) { int res; if (!dict) return (dict); res = strcmp(dict->name, str); -#ifdef DEBUG ASSERT(dict->type == FCODE); - if (debug > 2) - (void)printf( "flookup: `%s' and `%s' %s match\n", + if (debug > 5) + printf("flookup: `%s' and `%s' %s match\n", str, dict->name, res?"don't":"do"); -#endif if (!res) return (dict); if (res < 0) return (flookup(dict->l, str)); @@ -817,29 +895,28 @@ char *str; /* * Insert alias into macros. */ -int -aadd(dict, new) - struct macro *dict, *new; +static int +aadd(struct macro *dict, struct macro *new) { int res = strcmp(dict->name, new->name); -#ifdef DEBUG new->type = MACRO; ASSERT(dict->type == MACRO); -#endif - /* Don't allow duplicate entries. */ - if (!res) return (0); + if (!res) { + /* Duplicate name. Replace the old macro */ + dict->equiv = new->equiv; + /* We can't free the old equiv since it may be static data. */ + return (0); + } if (res < 0) { if (dict->l) return aadd(dict->l, new); else { new->l = new->r = NULL; dict->l = new; -#ifdef DEBUG - if (debug > 1) - (void)printf( "aadd: new alias `%s' to `%s'\n", + if (debug > 5) + printf("aadd: new alias `%s' to `%s'\n", new->name, new->equiv); -#endif } } else { if (dict->r) @@ -847,11 +924,9 @@ aadd(dict, new) else { new->l = new->r = NULL; dict->r = new; -#ifdef DEBUG - if (debug > 1) - (void)printf( "aadd: new alias `%s' to `%s'\n", + if (debug > 5) + printf("aadd: new alias `%s' to `%s'\n", new->name, new->equiv); -#endif } } return (1); @@ -860,17 +935,13 @@ aadd(dict, new) /* * Look for a macro in the aliases. */ -struct macro * -alookup(dict, str) -struct macro *dict; -char *str; +static struct macro * +alookup(struct macro *dict, const char *str) { int res; if (!dict) return (dict); -#ifdef DEBUG ASSERT(dict->type == MACRO); -#endif res = strcmp(dict->name, str); if (!res) return (dict); if (res < 0) @@ -884,8 +955,8 @@ char *str; * Bootstrap the dictionary and then install * all the standard FCodes. */ -void -initdic() +static void +initdic(void) { struct fcode *code = fcodes; struct macro *alias = macros; @@ -893,98 +964,85 @@ initdic() ASSERT(dictionary == NULL); code->l = code->r = NULL; dictionary = code; -#ifdef DEBUG code->type = FCODE; -#endif while ((++code)->name) { if(!fadd(dictionary, code)) { - printf("init: duplicate dictionary entry %s\n", - code->name); - abort(); + warnx("%s: duplicate dictionary entry `%s'", __func__, + code->name); } } ASSERT(aliases == NULL); aliases = alias; alias->l = alias->r = NULL; -#ifdef DEBUG alias->type = MACRO; -#endif while ((++alias)->name) { if(!aadd(aliases, alias)) { - printf("init: duplicate macro entry %s\n", - alias->name); - abort(); + warnx("%s: duplicate macro entry `%s'", __func__, + alias->name); } } } -int -apply_macros(input, str) - YY_BUFFER_STATE input; - char *str; +static int +apply_macros(YY_BUFFER_STATE yinput, const char *str) { struct macro *xform = alookup(aliases, str); if (xform) { YY_BUFFER_STATE newbuf; + if (debug > 1) + printf("Expanding %s to %s\n", str, xform->equiv); + newbuf = yy_scan_string(xform->equiv); yy_switch_to_buffer(newbuf); tokenize(newbuf); - yy_switch_to_buffer(input); + yy_switch_to_buffer(yinput); yy_delete_buffer(newbuf); } return (xform != NULL); } -void -usage(me) - char *me; +static void +usage(void) { - (void)fprintf(stderr, "usage: %s [-d level] [-o outfile] infile\n", me); - exit(1); + (void)fprintf(stderr, "%s: [-d level] [-o outfile] <infile>\n", + getprogname()); + exit(EXIT_FAILURE); } int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { - int bflag, ch; + int ch; FILE *inf; struct fcode_header *fheader; YY_BUFFER_STATE inbuf; - char *hdrtype = "version1"; + const char *hdrtype = "version1"; int i; - if (pledge("stdio rpath wpath cpath", NULL) == -1) - err(1, "pledge"); - outf = 1; /* stdout */ - myname = argv[0]; - bflag = 0; while ((ch = getopt(argc, argv, "d:o:")) != -1) switch(ch) { case 'd': + mark_fload = 1; debug = atol(optarg); break; case 'o': outfile = optarg; break; - case '?': default: - warnx("Illegal argument: %c", ch); - usage(myname); + usage(); } argc -= optind; argv += optind; if (argc != 1) - usage(myname); + usage(); infile = argv[0]; @@ -993,11 +1051,8 @@ main(argc, argv) */ initdic(); outbufsiz = BUFCLICK; - outbuf = malloc(outbufsiz); - if (outbuf == NULL) - (void)err(1, "out of memory"); - - fheader = (struct fcode_header *)outbuf; + fheader = emalloc(outbufsiz); + outbuf = (void *)fheader; outpos = 0; emit(hdrtype); outpos = sizeof(*fheader); @@ -1006,48 +1061,48 @@ main(argc, argv) * Do it. */ if ((inf = fopen(infile, "r")) == NULL) - (void)err(1, "can not open %s for reading", infile); + err(EXIT_FAILURE, "Cannot open `%s'", infile); - inbuf = yy_create_buffer( inf, YY_BUF_SIZE ); + inbuf = yy_create_buffer(inf, YY_BUF_SIZE); yy_switch_to_buffer(inbuf); tokenize(inbuf); yy_delete_buffer(inbuf); fclose(inf); - emit("end0"); + if (need_end0) emit("end0"); /* Now calculate length and checksum and stick them in the header */ fheader->format = 0x08; fheader->length = htonl(outpos); fheader->checksum = 0; for (i = sizeof(*fheader); i<outpos; i++) - fheader->checksum += outbuf[i]; + fheader->checksum += (unsigned char)outbuf[i]; fheader->checksum = htons(fheader->checksum); if ((outf = open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) - err(1, "can out open %s for writing", outfile); + err(EXIT_FAILURE, "Cannot open `%s'", outfile); if (write(outf, outbuf, outpos) != outpos) { + int serrno = errno; close(outf); unlink(outfile); - err(1, "write error"); + errc(EXIT_FAILURE, serrno, "write error"); } close(outf); - return (0); + return EXIT_SUCCESS; }; /* * Tokenize one file. This is a separate function so it can - * be called recursively to parse multiple levels of include files. + * be called recursively to parse mutiple levels of include files. */ -void -tokenize(input) - YY_BUFFER_STATE input; +static void +tokenize(YY_BUFFER_STATE yinput) { FILE *inf; YY_BUFFER_STATE inbuf; TOKEN *token; - char *last_token = ""; + const char *last_token = ""; struct fcode *fcode; int pos, off; @@ -1063,7 +1118,7 @@ tokenize(input) push(strtol(token->text, &end, 16)); break; } - value = strtol(token->text, &end, base); + value = strtol(token->text, &end, numbase); if (*end != 0) token_err(yylineno, infile, yytext, "illegal number conversion"); @@ -1074,10 +1129,19 @@ tokenize(input) * project. */ emit("b(lit)"); - spit(value>>24); + spit((value>>24)&0x0ff); spit((value>>16)&0x0ff); spit((value>>8)&0x0ff); spit(value&0x0ff); + if ((value>>32) != value && (value>>32) != 0 && + (value>>32) != -1) { + emit("b(lit)"); + spit((value>>56)&0x0ff); + spit((value>>48)&0x0ff); + spit((value>>40)&0x0ff); + spit((value>>32)&0x0ff); + emit("lxjoin"); + } } break; case TOK_C_LIT: @@ -1091,14 +1155,14 @@ tokenize(input) case TOK_STRING_LIT: STATE(token->text, "TOK_STRING_LIT:"); { - int len; + size_t len; char *p = token->text; ++p; /* Skip the quote */ len = strlen(++p); /* Skip the 1st space */ #define ERR_TOOLONG \ - token_err(yylineno, infile, yytext, "string length %d too long", len) + token_err(yylineno, infile, yytext, "string length %zu too long", len) if (len > 255) ERR_TOOLONG; @@ -1114,7 +1178,7 @@ tokenize(input) case TOK_PSTRING: STATE(token->text, "TOK_PSTRING:"); { - int len; + size_t len; char *p = token->text; if (*p++ == '.') p++; /* Skip over delimiter */ @@ -1133,6 +1197,44 @@ tokenize(input) emit("type"); } break; + case TOK_ABORT_S: + STATE(token->text, "TOK_PSTRING:"); + { + size_t len; + Cell value = -2; + char *p = token->text; + + while (*p++ != ' '); /* Skip to the string */ + + len = strlen(p); + if (len > 255) + ERR_TOOLONG; + + if (p[len-1] == '"') { + p[len-1] = 0; + } + emit("b?branch"); + push(outpos); + offspit(0); + emit("b(\")"); + sspit(p); + emit("type"); + emit("cr"); + emit("b(lit)"); + spit((value>>24)&0x0ff); + spit((value>>16)&0x0ff); + spit((value>>8)&0x0ff); + spit(value&0x0ff); + emit("throw"); + emit("b(>resolve)"); + pos = outpos; + outpos = pop(); + off = pos - outpos; + offspit(off); + outpos = pos; + } + break; + case TOK_TOKENIZE: STATE(token->text, "TOK_TOKENIZE"); /* The next pass should tokenize the FCODE number */ @@ -1140,13 +1242,10 @@ tokenize(input) break; case TOK_COMMENT: STATE(token->text, "TOK_COMMENT:"); - while (((token = yylex()) != NULL) && token->type != TOK_ENDCOMMENT) - ; - break; - case TOK_ENDCOMMENT: - STATE(token->text, "TOK_ENDCOMMENT"); - token_err(yylineno, infile, NULL, - "ENDCOMMENT encountered outside comment"); + do { + off = input(); + } while ((off != ')') && (off != '\n') && + (off != EOF)); break; case TOK_COLON: STATE(token->text, "TOK_COLON:"); @@ -1157,22 +1256,19 @@ tokenize(input) "EOF in colon definition"); /* Add new code to dictionary */ - fcode = malloc(sizeof(*fcode)); - if (fcode == NULL) - (void)err(1, "out of memory"); - + fcode = emalloc(sizeof(*fcode)); fcode->num = nextfcode++; - fcode->name = strdup(token->text); - if (fcode->name == NULL) - (void)err(1, "out of memory"); - - if (!fadd(dictionary, fcode)) - token_err(yylineno, infile, NULL, - "Duplicate definition: `%s'\n", fcode->name); -#ifdef DEBUG + fcode->name = estrdup(token->text); + if (!fadd(dictionary, fcode)) { + /* Duplicate definition. Free the memory. */ + if (debug) + printf("%s: duplicate FCode\n", + token->text); + free((void *)fcode->name); + free(fcode); + } if (debug) - (void)printf("Adding %s to dictionary\n", token->text); -#endif + printf("Adding %s to dictionary\n", token->text); if (state == 0) emit("new-token"); else { @@ -1205,11 +1301,8 @@ tokenize(input) STATE(token->text, "TOK_AGAIN"); emit("bbranch"); pos = pop(); - pos -= outpos; - if (offsetsize == 16) { - spit((pos>>8)&0xff); - } - spit(pos&0xff); + pos = pos - outpos; + offspit(pos); break; case TOK_ALIAS: STATE(token->text, "TOK_ALIAS"); @@ -1218,36 +1311,26 @@ tokenize(input) token = yylex(); if (token == NULL) { - (void)printf( "EOF in alias definition\n"); + warnx("EOF in alias definition"); return; } if (token->type != TOK_OTHER) { - (void)printf( "ENDCOMMENT aliasing weird token type %d\n", - token->type); + warnx("ENDCOMMENT aliasing weird token type %d", + token->type); } - alias = malloc(sizeof(*alias)); - if (alias == NULL) - (void)err(1, "out of memory"); - - alias->name = strdup(token->text); - if (alias->name == NULL) - (void)err(1, "out of memory"); - + alias = emalloc(sizeof(*alias)); + alias->name = estrdup(token->text); token = yylex(); if (token == NULL) { - free(alias->name); + warnx("EOF in alias definition"); + free((void *)alias->name); free(alias); - (void)printf( "EOF in alias definition\n"); return; } - alias->equiv = strdup(token->text); - if (alias->equiv == NULL) - (void)err(1, "out of memory"); - + alias->equiv = estrdup(token->text); if (!aadd(aliases, alias)) { - (void)printf( "ERROR: Duplicate alias %s\n", - alias->name); - exit(1); + free((void *)alias->name); + free(alias); } } break; @@ -1257,22 +1340,19 @@ tokenize(input) emit("b(')"); token = yylex(); if (token == NULL) { - (void)printf( "EOF in [']\n"); + warnx("EOF in [']"); return; } - if ((fcode = flookup(dictionary, token->text)) == NULL) { - (void)printf( "[']: %s not found\n", token->text); - exit(1); - } + if ((fcode = flookup(dictionary, token->text)) == NULL) + errx(EXIT_FAILURE, "[']: %s not found", + token->text); spit(fcode->num); break; case TOK_ASCII: STATE(token->text, "TOK_ASCII"); token = yylex(); - if (token == NULL) { - (void)printf( "EOF after \"ascii\"\n"); - exit(1); - } + if (token == NULL) + errx(EXIT_FAILURE, "EOF after \"ascii\""); emit("b(lit)"); spit(0); spit(0); @@ -1289,20 +1369,14 @@ tokenize(input) token = yylex(); if (token == NULL) { - (void)printf( "EOF in colon definition\n"); + warnx("EOF in colon definition"); return; } /* Add new code to dictionary */ - fcode = malloc(sizeof(*fcode)); - if (fcode == NULL) - (void)err(1, "out of memory"); - + fcode = emalloc(sizeof(*fcode)); fcode->num = nextfcode++; - fcode->name = strdup(token->text); - if (fcode->name == NULL) - (void)err(1, "out of memory"); - + fcode->name = estrdup(token->text); fadd(dictionary, fcode); if (state == 0) @@ -1328,19 +1402,14 @@ tokenize(input) token = yylex(); if (token == NULL) { - (void)printf( "EOF in constant definition\n"); + warnx("EOF in constant definition"); return; } /* Add new code to dictionary */ - fcode = malloc(sizeof(*fcode)); - if (fcode == NULL) - (void)err(1, "out of memory"); + fcode = emalloc(sizeof(*fcode)); fcode->num = nextfcode++; - fcode->name = strdup(token->text); - if (fcode->name == NULL) - (void)err(1, "out of memory"); - + fcode->name = estrdup(token->text); fadd(dictionary, fcode); if (state == 0) @@ -1359,10 +1428,8 @@ tokenize(input) case TOK_CONTROL: STATE(token->text, "TOK_CONTROL"); token = yylex(); - if (token == NULL) { - (void)printf( "EOF after \"ascii\"\n"); - exit(1); - } + if (token == NULL) + errx(EXIT_FAILURE, "EOF after \"ascii\""); emit("b(lit)"); spit(0); spit(0); @@ -1374,20 +1441,14 @@ tokenize(input) /* Don't know what this does or if it's right */ token = yylex(); if (token == NULL) { - (void)printf( "EOF in create definition\n"); + warnx("EOF in create definition"); return; } /* Add new code to dictionary */ - fcode = malloc(sizeof(*fcode)); - if (fcode == NULL) - err(1, "out of memory"); - + fcode = emalloc(sizeof(*fcode)); fcode->num = nextfcode++; - fcode->name = strdup(token->text); - if (fcode->name == NULL) - (void)err(1, "out of memory"); - + fcode->name = estrdup(token->text); fadd(dictionary, fcode); if (state == 0) @@ -1407,18 +1468,22 @@ tokenize(input) STATE(token->text, "TOK_DECIMAL"); if (token->text[1] != '#') { if (defining) { + emit("b(lit)"); + spit(0); + spit(0); + spit(0); spit(10); emit("base"); emit("!"); } else - base = TOK_DECIMAL; + numbase = TOK_DECIMAL; } else { char *end; Cell value; token = yylex(); if (token == NULL) { - (void)printf( "EOF after d#\n"); + warnx("EOF after d#"); return; } if (token->type == TOK_OTHER) { @@ -1438,10 +1503,18 @@ tokenize(input) * project. */ emit("b(lit)"); - spit(value>>24); + spit((value>>24)&0x0ff); spit((value>>16)&0x0ff); spit((value>>8)&0x0ff); spit(value&0x0ff); + if ((value>>32) != value && (value>>32) != 0) { + emit("b(lit)"); + spit((value>>56)&0x0ff); + spit((value>>48)&0x0ff); + spit((value>>40)&0x0ff); + spit((value>>32)&0x0ff); + emit("lxjoin"); + } } break; case TOK_DEFER: @@ -1449,20 +1522,14 @@ tokenize(input) /* Don't know what this does or if it's right */ token = yylex(); if (token == NULL) { - (void)printf( "EOF in colon definition\n"); + warnx("EOF in colon definition"); return; } /* Add new code to dictionary */ - fcode = malloc(sizeof(*fcode)); - if (fcode == NULL) - (void)err(1, "out of memory"); - + fcode = emalloc(sizeof(*fcode)); fcode->num = nextfcode++; - fcode->name = strdup(token->text); - if (fcode->name == NULL) - (void)err(1, "out of memory"); - + fcode->name = estrdup(token->text); fadd(dictionary, fcode); if (state == 0) @@ -1503,12 +1570,15 @@ tokenize(input) else emit("b(do)"); push(outpos); - if (offsetsize == 16) { - spit(0); - } - spit(0); /* Place holder for later */ + offspit(0); /* Place holder for later */ push(outpos); break; + case TOK_END0: + STATE(token->text, "TOK_END0"); + emit("end0"); + /* Remember we already generated end0 */ + need_end0 = 0; + break; case TOK_ELSE: STATE(token->text, "TOK_ELSE"); /* Get where we need to patch */ @@ -1516,46 +1586,47 @@ tokenize(input) emit("bbranch"); /* Save where we are now. */ push(outpos); - if (offsetsize == 16) { - spit(0); /* Place holder for later */ - } - spit(0); /* Place holder for later */ + offspit(0); /* Place holder for later */ emit("b(>resolve)"); /* Rewind and patch the if branch */ pos = outpos; outpos = off; off = pos - off; - if (offsetsize == 16) { - spit(0); /* Place holder for later */ - } - spit(0); /* Place holder for later */ + offspit(off); /* Place holder for later */ /* revert to the end */ outpos = pos; break; case TOK_ENDCASE: STATE(token->text, "TOK_ENDCASE:"); + emit("b(endcase)"); pos = outpos; /* Remember where we need to branch to */ /* Thread our way backwards and install proper offsets */ off = pop(); while (off) { - int tmp; + int disp; + int next; /* Move to this offset */ outpos = off; /* Load next offset to process */ - tmp = outbuf[outpos]; + disp = (signed char)(outbuf[outpos]); + if (offsetsize == 16) { + disp = (disp << 8) | + (unsigned char)outbuf[outpos+1]; + } + next = outpos + disp; + if (debug > -3) + printf("Next endof: %x at %x\n", + disp, next); /* process this offset */ off = pos - outpos; - if (offsetsize == 16) { - spit((off>>8)&0xff); - } - spit(off&0xff); - off = tmp; + offspit(off); + if ((off = disp)) + off = next; } outpos = pos; - emit("b(endcase)"); break; case TOK_ENDOF: STATE(token->text, "TOK_ENDOF"); @@ -1567,18 +1638,17 @@ tokenize(input) */ pos = pop(); /* get position of prev link. */ push(outpos); /* save position of this link. */ - spit(pos); /* save position of prev link. */ - if (offsetsize == 16) { - spit(0); - } + if (pos) + /* save potision of prev link. */ + offspit(pos - outpos); + else + /* This is the first statement */ + offspit(0); pos = outpos; /* Now point the offset from b(of) here. */ outpos = off; - off = outpos - off; - if (offsetsize == 16) { - spit((off>>8)&0xff); - } - spit(off&0xff); + off = pos - off; + offspit(off); /* Restore position */ outpos = pos; break; @@ -1586,25 +1656,37 @@ tokenize(input) STATE(token->text, "TOK_EXTERNAL"); state = TOK_EXTERNAL; break; + case TOK_FCODE_VERSION2: + /* This is actually a tokenizer directive. */ + STATE(token->text, "TOK_FCODE_VERSION2"); + offsetsize = 16; + pos = outpos; + outpos = 0; + emit("start1"); + outpos = pos; + break; + case TOK_FCODE_END: + /* + * Another tokenizer directive. + * + * This should generate end0 and finish filling in + * the FCode header. But that's all done in main(). + */ + STATE(token->text, "TOK_FCODE_END"); + return; case TOK_FIELD: STATE(token->text, "TOK_FIELD"); token = yylex(); if (token == NULL) { - (void)printf( "EOF in field definition\n"); + warnx("EOF in field definition"); return; } /* Add new code to dictionary */ - fcode = malloc(sizeof(*fcode)); - if (fcode == NULL) - (void)err(1, "out of memory"); - + fcode = emalloc(sizeof(*fcode)); fcode->num = nextfcode++; - fcode->name = strdup(token->text); - if (fcode->name == NULL) - (void)err(1, "out of memory"); - + fcode->name = estrdup(token->text); fadd(dictionary, fcode); if (state == 0) @@ -1625,36 +1707,47 @@ tokenize(input) STATE(token->text, "TOK_HEX"); if (token->text[1] != '#') { if (defining) { + emit("b(lit)"); + spit(0); + spit(0); + spit(0); spit(16); emit("base"); emit("!"); } else - base = TOK_HEX; + numbase = TOK_HEX; } else { char *end; Cell value; token = yylex(); if (token == NULL) { - (void)printf( "EOF after h#\n"); + warnx("EOF after h#"); return; } value = strtol(token->text, &end, 16); - if (*end != 0) { - (void)printf("Illegal number conversion:%s:%d: %s\n", + if (*end != 0) + errx(EXIT_FAILURE, "Illegal number" + " conversion:%s:%d: %s\n", infile, yylineno, yytext); - exit(1); - } /* * If this is a 64-bit value we need to store two literals * and issue a `lxjoin' to combine them. But that's a future * project. */ emit("b(lit)"); - spit(value>>24); + spit((value>>24)&0x0ff); spit((value>>16)&0x0ff); spit((value>>8)&0x0ff); spit(value&0x0ff); + if ((value>>32) != value && (value>>32) != 0) { + emit("b(lit)"); + spit((value>>56)&0x0ff); + spit((value>>48)&0x0ff); + spit((value>>40)&0x0ff); + spit((value>>32)&0x0ff); + emit("lxjoin"); + } } break; case TOK_HEADERLESS: @@ -1665,11 +1758,6 @@ tokenize(input) STATE(token->text, "TOK_HEADERS"); state = TOK_HEADERS; break; - case TOK_OFFSET16: - STATE(token->text, "TOK_OFFSET16"); - offsetsize = 16; - emit("offset16"); - break; case TOK_IF: STATE(token->text, "TOK_IF"); /* @@ -1677,10 +1765,7 @@ tokenize(input) */ emit("b?branch"); push(outpos); - if (offsetsize == 16) { - spit(0); /* Place holder for later */ - } - spit(0); /* Place holder for later */ + offspit(0); /* Place holder for later */ break; case TOK_LEAVE: STATE(token->text, "TOK_LEAVE"); @@ -1696,18 +1781,12 @@ tokenize(input) /* First do backwards branch of loop */ pos = pop(); off = pos - outpos; - if (offsetsize == 16) { - spit((off>>8)&0xff); - } - spit(off&0xff); + offspit(off); /* Now do forward branch of do */ pos = outpos; outpos = pop(); off = pos - outpos; - if (offsetsize == 16) { - spit((off>>8)&0xff); - } - spit(off&0xff); + spit(off); /* Restore output position */ outpos = pos; break; @@ -1719,21 +1798,21 @@ tokenize(input) emit("base"); emit("!"); } else - base = TOK_OCTAL; + numbase = TOK_OCTAL; } else { char *end; Cell value; token = yylex(); if (token == NULL) { - (void)printf( "EOF after o#\n"); + warnx("EOF after o#"); return; } value = strtol(token->text, &end, 8); if (*end != 0) { - (void)printf("Illegal number conversion:%s:%d: %s\n", + errx(EXIT_FAILURE, "Illegal number" + " conversion:%s:%d: %s\n", infile, yylineno, yytext); - exit(1); } /* * If this is a 64-bit value we need to store two literals @@ -1741,10 +1820,18 @@ tokenize(input) * project. */ emit("b(lit)"); - spit(value>>24); + spit((value>>24)&0x0ff); spit((value>>16)&0x0ff); spit((value>>8)&0x0ff); spit(value&0x0ff); + if ((value>>32) != value && (value>>32) != 0) { + emit("b(lit)"); + spit((value>>56)&0x0ff); + spit((value>>48)&0x0ff); + spit((value>>40)&0x0ff); + spit((value>>32)&0x0ff); + emit("lxjoin"); + } } break; case TOK_OF: @@ -1764,10 +1851,12 @@ tokenize(input) */ emit("b(of)"); push(outpos); - if (offsetsize == 16) { - spit(0); - } - spit(0); /* Place holder for later */ + offspit(0); /* Place holder for later */ + break; + case TOK_OFFSET16: + STATE(token->text, "TOK_OFFSET16"); + offsetsize = 16; + emit("offset16"); break; case TOK_REPEAT: STATE(token->text, "TOK_REPEAT"); @@ -1776,32 +1865,32 @@ tokenize(input) off = pop(); /* First the offset for the branch back to the begin */ off -= outpos; - if (offsetsize == 16) { - spit((off>>8)&0xff); - } - spit(off&0xff); + offspit(off); emit("b(>resolve)"); /* Now point the offset of the while here. */ off = outpos; outpos = pos; pos = off - pos; - if (offsetsize == 16) { - spit((pos>>8)&0xff); - } - spit(pos&0xff); + offspit(pos); /* Return to the end of the output */ outpos = off; break; + case TOK_STARTX: + /* Put a "startX" at addr 0. */ + STATE(token->text, "TOK_FCODE_VERSION2"); + offsetsize = 16; + pos = outpos; + outpos = 0; + emit(token->text); + outpos = pos; + break; case TOK_THEN: STATE(token->text, "TOK_THEN"); emit("b(>resolve)"); pos = outpos; outpos = pop(); off = pos - outpos; - if (offsetsize == 16) { - spit((off>>8)&0xff); - } - spit(off&0xff); + offspit(off); outpos = pos; break; case TOK_TO: @@ -1811,37 +1900,24 @@ tokenize(input) break; case TOK_UNTIL: STATE(token->text, "TOK_UNTIL"); - { - int pos; - emit("b?branch"); pos = pop(); pos -= outpos; - if (offsetsize == 16) { - spit((pos>>8)&0xff); - } - spit(pos&0xff); - } - break; + offspit(pos); + break; case TOK_VALUE: STATE(token->text, "TOK_VALUE"); token = yylex(); if (token == NULL) { - (void)printf( "EOF in value definition\n"); + warnx("EOF in value definition"); return; } /* Add new code to dictionary */ - fcode = malloc(sizeof(*fcode)); - if (fcode == NULL) - (void)err(1, "out of memory"); - + fcode = emalloc(sizeof(*fcode)); fcode->num = nextfcode++; - fcode->name = strdup(token->text); - if (fcode->name == NULL) - (void)err(1, "out of memory"); - + fcode->name = estrdup(token->text); fadd(dictionary, fcode); if (state == 0) @@ -1862,20 +1938,14 @@ tokenize(input) token = yylex(); if (token == NULL) { - (void)printf( "EOF in variable definition\n"); + warnx("EOF in variable definition"); return; } /* Add new code to dictionary */ - fcode = malloc(sizeof(*fcode)); - if (fcode == NULL) - (void)err(1, "out of memory"); - + fcode = emalloc(sizeof(*fcode)); fcode->num = nextfcode++; - fcode->name = strdup(token->text); - if (fcode->name == NULL) - (void)err(1, "out of memory"); - + fcode->name = estrdup(token->text); fadd(dictionary, fcode); if (state == 0) @@ -1891,14 +1961,20 @@ tokenize(input) spit(fcode->num); emit("b(variable)"); break; + case TOK_VERSION1: + /* This is actually a tokenizer directive. */ + STATE(token->text, "TOK_FCODE_VERSION1"); + offsetsize = 8; + pos = outpos; + outpos = 0; + emit("version1"); + outpos = pos; + break; case TOK_WHILE: STATE(token->text, "TOK_WHILE"); emit("b?branch"); push(outpos); - if (offsetsize == 16) { - spit(0); - } - spit(0); + offspit(0); break; /* Tokenizer directives */ @@ -1915,30 +1991,64 @@ tokenize(input) tokenizer = 0; break; case TOK_FLOAD: - STATE(token->text, "TOK_FLOAD"); - /* Parse a different file for a while */ - token = yylex(); - if ((inf = fopen(token->text, "r")) == NULL) { - (void)printf("%s: Could not open %s: %s\n", - myname, token->text, strerror(errno)); - break; - } - inbuf = yy_create_buffer(inf, YY_BUF_SIZE); - yy_switch_to_buffer(inbuf); { char *oldinfile = infile; - infile = token->text; + STATE(token->text, "TOK_FLOAD"); + /* Parse a different file for a while */ + token = yylex(); + if ((inf = fopen(token->text, "r")) == NULL) { + warn("Cannot open `%s'", token->text); + break; + } + infile = estrdup(token->text); + if (mark_fload) { + /* + * Insert commands to print out the + * filename into the instruction + * stream + */ + emit("b(\")"); + sspit("fload-ing "); + emit("type"); + emit("b(\")"); + sspit(infile); + emit("type"); + emit("cr"); + emit(".s"); + } + inbuf = yy_create_buffer(inf, YY_BUF_SIZE); + yy_switch_to_buffer(inbuf); + + printf("======= fload file %s\n", infile); tokenize(inbuf); + printf("======= done file %s\n", infile); + yy_switch_to_buffer(yinput); + yy_delete_buffer(inbuf); + fclose(inf); + if (mark_fload) { + /* + * Insert commands to print out the + * filename into the instruction + * stream + */ + emit("b(\")"); + sspit("fload-ed "); + emit("type"); + emit("b(\")"); + sspit(infile); + emit("type"); + emit("cr"); + emit(".s"); + emit("cr"); + } + free(infile); infile = oldinfile; } - yy_switch_to_buffer(input); - yy_delete_buffer(inbuf); - fclose(inf); break; case TOK_OTHER: STATE(token->text, "TOK_OTHER"); - if (apply_macros(input, token->text)) + if (apply_macros(yinput, token->text)) break; if (emit(token->text)) { #if 0 @@ -1952,15 +2062,14 @@ tokenize(input) emit("drop"); emit("execute"); #else - (void)printf( "%s: undefined token `%s'\n", - myname, token->text); - fflush(stderr); - exit(1); + token_err(yylineno, infile, yytext, + "%s: undefined token `%s'\n", + myname, token->text); #endif } break; default: - break; + /* Nothing */ ; } } return; @@ -1969,21 +2078,22 @@ tokenize(input) /* * print a tokenizer error message */ -void -token_err(int lineno, char *infile, char *text, char *fmt, ...) +static void +token_err(int lineno, const char *file, const char *text, const char *fmt, ...) { va_list ap; va_start(ap, fmt); - if (infile) - (void)fprintf(stderr, "%s:%d: ", infile, lineno); + fprintf(stderr, "%s: ", getprogname()); + if (file) + (void)fprintf(stderr, "%s,%d: ", file, lineno); if (fmt) (void)vfprintf(stderr, fmt, ap); fputc('\n', stderr); if (text) fprintf(stderr, "\t%s", text); va_end(ap); - exit(1); + exit(EXIT_FAILURE); } /* @@ -1991,21 +2101,18 @@ token_err(int lineno, char *infile, char *text, char *fmt, ...) * * Fcode must be in dictionary. No alias conversion done. */ -int -emit(str) - char *str; +static int +emit(const char *str) { struct fcode *code; - if ((code = flookup( dictionary, str))) + if ((code = flookup(dictionary, str))) spit(code->num); -#ifdef DEBUG if (debug > 1) { if (code) - (void)printf( "emitting `%s'\n", code->name); + printf("emitting `%s'\n", code->name); else - (void)printf( "emit: not found `%s'\n", str); + printf("emit: not found `%s'\n", str); } -#endif return (code == NULL); } @@ -2015,22 +2122,18 @@ emit(str) * It will spit out one zero byte or as many bytes as are * non-zero. */ -int -spit(n) - long n; +static int +spit(long n) { int count = 1; if (n >> 8) count += spit(n >> 8); - if (outpos >= outbufsiz) { - while (outpos >= outbufsiz) outbufsiz += BUFCLICK; - if (!(outbuf = realloc(outbuf, outbufsiz))) { - (void)printf( "realloc of %ld bytes failed -- out of memory\n", - (long)outbufsiz); - exit(1); - } + if ((size_t)outpos >= outbufsiz) { + while ((size_t)outpos >= outbufsiz) outbufsiz += BUFCLICK; + outbuf = erealloc(outbuf, outbufsiz); } + if (debug > 3) printf("%lx: spitting %2.2x\n", outpos, (unsigned char)n); outbuf[outpos++] = n; return (count); } @@ -2038,27 +2141,53 @@ spit(n) /* * Spit out an FCode string. */ -void -sspit(s) - char *s; +static void +sspit(const char *s) { int len = strlen(s); if (len > 255) { - (void)printf( "string length %d too long\n", len); + warnx("string length %d too long", len); return; } -#ifdef DEBUG - if (debug > 1) - (void)printf( "sspit: len %d str `%s'\n", len, s); -#endif + if (debug > 2) + printf("sspit: len %d str `%s'\n", len, s); spit(len); - while (*s) + while (len--) spit(*s++); } +/* + * Spit out an offset. Offsets can be 8 or 16 bits. + * Bail if the value overflows. This is a little complicated since + * offsets can be negative numbers. + */ +static int +offspit(long n) +{ + + if (offsetsize == 16) { + volatile int16_t off16 = n; + + if (n != off16) + token_err(yylineno, infile, NULL, + "Offset16 offset overflow: %lx != %x\n", + n, off16); + spit((n>>8) & 0xff); + return spit(n & 0xff); + } else { + volatile int8_t off8 = n; + + if (n != off8) + token_err(yylineno, infile, NULL, + "Offset8 offset overflow: %lx != %x\n", + n, off8); + return spit(n & 0x0ffL); + } +} + int -yywrap() +yywrap(void) { /* Always generate EOF */ return (1); |