summaryrefslogtreecommitdiff
path: root/usr.bin/fgen
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2020-03-24 07:00:41 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2020-03-24 07:00:41 +0000
commitc79e869a7eb314bb7d27132a1a35e27b8e5fb64f (patch)
treed7a6e1328c96b3557e91c14d0a171dd4600e114e /usr.bin/fgen
parenta9b7376547498be814370bebd43ee314750a8a34 (diff)
Sync to latest from wiz at netbsd, needed for upcoming sparc64 bootblk changes;
ok kettenis@
Diffstat (limited to 'usr.bin/fgen')
-rw-r--r--usr.bin/fgen/fgen.h30
-rw-r--r--usr.bin/fgen/fgen.l2015
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 &ltoken; }
+
+1 { ltoken.type = TOK_OTHER; ltoken.text = yytext; return &ltoken; }
-1 { token.type = TOK_OTHER; token.text = yytext;
- return &token; }
+2 { ltoken.type = TOK_OTHER; ltoken.text = yytext; return &ltoken; }
-2 { token.type = TOK_OTHER; token.text = yytext;
- return &token; }
+3 { ltoken.type = TOK_OTHER; ltoken.text = yytext; return &ltoken; }
-3 { token.type = TOK_OTHER; token.text = yytext;
- return &token; }
+-1 { ltoken.type = TOK_OTHER; ltoken.text = yytext; return &ltoken; }
--1 { token.type = TOK_OTHER; token.text = yytext;
- return &token; }
+\. { ltoken.type = TOK_OTHER; ltoken.text = yytext; return &ltoken; }
{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 &ltoken; }
+
+\'.\' { ltoken.type = TOK_C_LIT; ltoken.text = yytext; return &ltoken; }
-\'.\' { token.type = TOK_C_LIT; token.text = yytext; return &token; }
+\"{white}*(\\\"|[^"])*\" { ltoken.type = TOK_STRING_LIT; ltoken.text = yytext;
+ return &ltoken; } /* 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 &ltoken; } /* 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 &ltoken; }
-\.\"{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 &ltoken; }
-"(" { token.type = TOK_COMMENT; token.text = yytext;
- return &token; }
+"(" { ltoken.type = TOK_COMMENT; ltoken.text = yytext;
+ return &ltoken; }
-")" { token.type = TOK_ENDCOMMENT; token.text = yytext;
- return &token; }
+":" { ltoken.type = TOK_COLON; ltoken.text = yytext;
+ return &ltoken; }
-":" { token.type = TOK_COLON; token.text = yytext;
- return &token; }
+";" { ltoken.type = TOK_SEMICOLON; ltoken.text = yytext;
+ return &ltoken; }
-";" { token.type = TOK_SEMICOLON; token.text = yytext;
- return &token; }
+\' { ltoken.type = TOK_TOKENIZE; ltoken.text = yytext;
+ return &ltoken; }
-\' { token.type = TOK_TOKENIZE; token.text = yytext;
- return &token; }
+[aA][gG][aA][iI][nN] { ltoken.type = TOK_AGAIN; ltoken.text = yytext;
+ return &ltoken; }
-[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 &ltoken; }
-[aA][lL][iI][aA][sS] { token.type = TOK_ALIAS; token.text = yytext;
- return &token; }
+\[\'\] { ltoken.type = TOK_GETTOKEN; ltoken.text = yytext;
+ return &ltoken; }
-\[\'\] { token.type = TOK_GETTOKEN; token.text = yytext;
- return &token; }
+[aA][sS][cC][iI][iI] { ltoken.type = TOK_ASCII; ltoken.text = yytext;
+ return &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[cC][rR][eE][aA][tT][eE] { token.type = TOK_CREATE; token.text = yytext;
- return &token; }
+[dD]# { ltoken.type = TOK_DECIMAL; ltoken.text = yytext;
+ return &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[dD][eE][fF][eE][rR] { token.type = TOK_DEFER; token.text = yytext;
- return &token; }
+\??[dD][oO] { ltoken.type = TOK_DO; ltoken.text = yytext;
+ return &ltoken; }
-\??[dD][oO] { token.type = TOK_DO; token.text = yytext;
- return &token; }
+[eE][lL][sS][eE] { ltoken.type = TOK_ELSE; ltoken.text = yytext;
+ return &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-\??[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 &ltoken; }
-\+?[lL][oO][oO][pP] { token.type = TOK_LOOP; token.text = yytext;
- return &token; }
+[iI][fF] { ltoken.type = TOK_IF; ltoken.text = yytext;
+ return &ltoken; }
-[oO]# { token.type = TOK_OCTAL; token.text = yytext;
- return &token; }
+\??[lL][eE][aA][vV][eE] { ltoken.type = TOK_LEAVE; ltoken.text = yytext;
+ return &ltoken; }
-[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 &ltoken; }
-[oO][fF] { token.type = TOK_OF; token.text = yytext;
- return &token; }
+[oO]# { ltoken.type = TOK_OCTAL; ltoken.text = yytext;
+ return &ltoken; }
-[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 &ltoken; }
-[tT][hH][eE][nN] { token.type = TOK_THEN; token.text = yytext;
- return &token; }
+[oO][fF] { ltoken.type = TOK_OF; ltoken.text = yytext;
+ return &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
+
+[tT][hH][eE][nN] { ltoken.type = TOK_THEN; ltoken.text = yytext;
+ return &ltoken; }
-[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 &ltoken; }
-[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 &ltoken; }
-offset16 { token.type = TOK_OFFSET16; token.text = yytext;
- return &token; }
+[vV][aA][lL][uU][eE] { ltoken.type = TOK_VALUE; ltoken.text = yytext;
+ return &ltoken; }
-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 &ltoken; }
-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 &ltoken; }
-\]tokenizer { token.type = TOK_ENDTOK; token.text = yytext;
- return &token; }
+[wW][hH][iI][lL][eE] { ltoken.type = TOK_WHILE; ltoken.text = yytext;
+ return &ltoken; }
-fload { token.type = TOK_FLOAD; token.text = yytext;
- return &token; }
+tokenizer\[ { ltoken.type = TOK_BEGTOK; ltoken.text = yytext;
+ return &ltoken; }
+emit-byte { ltoken.type = TOK_EMIT_BYTE; ltoken.text = yytext;
+ return &ltoken; }
-[^ \n\t\r\f]+ { token.type = TOK_OTHER; token.text = yytext;
- return &token; }
+\]tokenizer { ltoken.type = TOK_ENDTOK; ltoken.text = yytext;
+ return &ltoken; }
+
+[fF][lL][oO][aA][dD] { ltoken.type = TOK_FLOAD; ltoken.text = yytext;
+ return &ltoken; }
+
+
+[^ \n\t\r\f]+ { ltoken.type = TOK_OTHER; ltoken.text = yytext;
+ return &ltoken; }
<<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);