📄 smal32.c
字号:
}static poolref putpool(s)char *s;{ poolref Result; int i; /* putpool */ poolpos++; Result = poolpos; for (i = 0; i <= 7; i++) { if (s[i] != ' ') { strpool[poolpos - relsym] = s[i]; poolpos++; } } strpool[poolpos - relsym] = pooldel; return Result;}static long hash(s, modulus)char *s;long modulus;{ /* it is critical that this hash function match that inside onepass */ int i; long acc; /* hash */ acc = 1; for (i = 0; i <= 7; i++) { if (s[i] != ' ') { acc = (acc * 5 + s[i]) % modulus + 1; } } return acc;}static void op(s, t, v, i)char *s;optypes t;long *i;{ *i = hash(s, (long)opcodes); while (optab[(*i) - 1].id != 0) { *i = ((*i) % opcodes) + 1; } optab[*i - 1].id = putpool(s); optab[*i - 1].typ = t; optab[*i - 1].val = v; optab[*i - 1].subtyp = 0;}static void opinit(){ /* opinit */ /* initialize the opcode table and string pool (done only once) */ long i; for (i = 1; i <= opcodes; i++) optab[i - 1].id = 0; poolfull = false; opfull = false; poolpos = relsym; strpool[poolpos - relsym] = pooldel; /* null symbol at start of pool is default relocation base */ op("B ", opb, 0L, &i); op("H ", oph, 0L, &i); op("W ", opw, 0L, &i); op("ASCII ", opascii, 0L, &i); op("IF ", opif, 0L, &i); op("ELSEIF ", opelseif, 0L, &i); op("ELSE ", opelse, 0L, &i); op("ENDIF ", opendif, 0L, &i); op("INT ", opint, 0L, &i); op("EXT ", opext, 0L, &i); op("COMMON ", opcomon, 0L, &i); op("MACRO ", opmac, 0L, &i); op("ENDMAC ", opendm, 0L, &i); op("USE ", opuse, 0L, &i); op("LIST ", oplist, 0L, &i); op("ERROR ", operror, 0L, &i); op("TITLE ", opttl, 0L, &i); op("SUBTITLE", opsbttl, 0L, &i); op("PAGE ", opeject, 0L, &i); op("S ", opstart, 0L, &i); op("END ", opend, 0L, &i); /* note: when adding to this list, be sure to adjust the constant 'opcodes' to reflect the additions; the local procedure 'op' used above assumes that the opcode table will always have some free space. */ /* following establish unary function names.. */ funcdf = putpool("DEF "); funcfw = putpool("FWD "); functy = putpool("TYP "); funcab = putpool("ABS "); funcrl = putpool("REL "); funcle = putpool("LEN ");}/* all kinds of error messages (no more than 31 of them!) */typedef enum { minermsg, baddig, /* bad digit in number */ baddir, /* bad assembly directive */ badrad, /* bad radix */ badrel, /* misuse of relocation in expression */ bounds, /* value out of bounds */ comexp, /* comma expected */ fwdref, /* definition must precede use */ idexp, /* identifier expected */ maxuse, /* too many source files */ baduse, /* cannot open use file */ miseif, /* missing endif */ misemc, /* missing endmac */ misquo, /* missing end quote */ muldef, /* multiple symbol definition */ mulstt, /* multiple start directives */ notfit, /* text too long for line */ notlab, /* expected label or directive */ notval, /* expected a value, got something else */ parexp, /* not a parenthesized list */ parovf, /* too many macro parameters */ phase, /* phase error in label value between passes */ quoexp, /* quoted string expected */ unbal, /* unbalanced parens */ undef, /* undefined symbol */ unfunc, /* bad function */ erropr, /* error operation */ unproc, /* unprocessed data at end of line */ maxermsg} ermsg;static char * errormsgs[] = { "---",/* 12345678901234567890123456 all error messages are 26 chars long */ "bad digit in number ", "invalid directive ", "bad radix ", "misuse of relocation ", "value out of bounds ", "comma expected ", "name used before defined ", "symbolic name expected ", "too many use levels ", "cannot open use file ", "missing endif ", "missing endmac ", "missing end quote ", "multiple label definition ", "multiple start directives ", "text too long for line ", "not a label or directive ", "bad value or expression ", "not a parenthesized list ", "too many macro parameters ", "label differed in pass 1 ", "quoted string expected ", "unbalanced parentheses ", "undefined symbol ", "invalid function ", "error message ", "comment or eol expected ", "+++"};/* types having to do with lexical analysis */typedef enum { id, /* identifier */ num, /* number (hex or decimal) */ quote, /* quoted string */ colon, /* : */ dot, /* . */ comma, /* , */ eq, /* = */ gt, /* > */ lt, /* < */ plus, /* + */ minus, /* - */ notsym, /* \ */ andsym, /* & */ orsym, /* ! */ bpar, /* ( */ epar, /* ) */ eol, /* end of line and start of comment */ junk /* string of unclassified characters */} lextypes;typedef struct lexeme { /* start, end of lexeme in line */ inbufptr pos; inbufptr lim; lextypes typ; union { /* value of number */ long val; } UU;} lexeme;typedef int parm;/* static variables used within onepass and affiliated code: */static boolean firstpass; /* true on the first pass only */static boolean allowlist; /* true on the final pass only */static boolean permitlisting; /* is a listing file to be opened */static boolean symtabdump; /* is a symboltable dump to be created */char charclass[256]; /* used to classify characters *//* bits set in charclass to classify characters */#define isvalid 1#define ispunc 2#define isquote 4#define isdigit 8#define isupper 16#define islower 32#define isalpha (isupper | islower)#define isalphanum (isalpha | isdigit)static void classchar( s, c )char* s;char c;{ /* in charclass, classify all chars in s as c */ char ch; while ((ch = *s) != 0) { charclass[ch] |= c; s++; }}static value loc; /* current assembly location counter */static value objloc; /* current object code generation location counter */static long lineno; /* current line in assembly source */static lexeme lex; /* current lexeme */static lexeme next; /* next lexeme for lookahead use *//* variables associated with stack on transient end of stringpool */static poolref poolsp; /* pool stack pointer */static poolref oldsp; /* pointer to previous frame in stack */static int actcnt; /* count of actual params in current frame */static poolref actparm[parmlim]; /* pointers to ap's in frame *//* variables controlling source of input */static poolref gettext; /* loc in pool from which macro text comes */static int getlevel; /* file from which non-macro text comes */static linebuf line; /* line buffers and lexical analysis */static int pos; /* current input line position */static int ch; /* line[pos] */static inbufptr length; /* current input line length *//* record of errors on the current line */static linebuf erbuf; /* markup under error */static inbufptr ermax; /* max used position in erbuf */static long erset; /* set of messages to generate *//* record of code generated by current line */typedef struct _REC_codebuf { value val; int form;} _REC_codebuf;static _REC_codebuf codebuf[listcodes];static int codelen; /* the number of object code chunks not yet listed */static value codeloc; /* the location counter of the first object output *//* listing control variables */static boolean listing; /* set to (listlevel > 0) and (allowlist) */static long listlevel; /* dec on macro call, inc on return *//* info about last expression */static value expr; /* value of expression */static boolean exprdef; /* is the value of the expression defined */static boolean exprundef; /* does expr. contain fwd ref(s)? */static inbufptr exprpos, exprlim; /* position of expression on line *//* info about opcode decoded on current line */static optypes optype;static long opval, opsubt;static inbufptr oppos, oplim;/* routines to manage stack in stringpool, these routines assume that ord(maxch)>=32; if ord(maxch)>32, they may be recoded for greater efficiency without any effect on their users */static void pushchar(ch)char ch;{ /* push one char onto stack in stringpool */ if (poolsp > poolpos) { strpool[poolsp - relsym] = ch; poolsp--; } else poolfull = true;}static poolref pushtext(pos, lim)inbufptr pos, lim;{ /* push the indicated text onto the stack from the line, as a terminated string, return a reference to the first char */ inbufptr i; /* pushtext */ pushchar(pooldel); for (i = lim - 2; i >= pos - 1; i--) pushchar(line[i]); return (poolsp + 1);}static poolref pushitxt(i)long i;{ /* push the indicated integer as a decimal text string, terminated with a pooldel, and return a reference to the first char */ pushchar(pooldel); if (i == 0) { pushchar('0'); return (poolsp + 1); } while (i != 0) { pushchar((char)(mod10(i) + '0')); i = div10(i); }}static char popchar(){ /* pop one char from stack in stringpool */ poolsp++; return (strpool[poolsp - relsym]);}static void pushint(i)long i;{ /* push an integer onto stack as a sequence of chars */ pushchar((char)(i & 31)); pushchar((char)((i / 32) & 31)); pushchar((char)(i / 1024));}static long popint(){ /* pop an integer from the stack as a sequence of chars */ long i; i = popchar() * 1024; i += popchar() * 32; return (i + popchar());}static void pushget(){ /* push a macro expansion control block on the stack */ int i; listlevel--; for (i = 0; i < actcnt; i++) pushint((long)actparm[i]); pushchar(actcnt); pushint((long)oldsp); pushint((long)gettext); pushchar(getlevel); oldsp = poolsp;}static void popget(){ /* pop a macro expansion control block from the stack */ int i; if (poolfull) { /* can't pop safely, so go all the way */ listlevel = 1; gettext = 0; getlevel = 0; return; } /* can pop one level safely */ listlevel++; poolsp = oldsp; getlevel = popchar(); gettext = popint(); oldsp = popint(); actcnt = popchar(); for (i = actcnt - 1; i >= 0; i--) actparm[i] = popint();}/* inside smal32.onepass, input/output routines */static void errmsg(msg, pos, lim)ermsg msg;inbufptr pos, lim;{ /* record error and position of error in line for later listing */ inbufptr i; erset |= 1L << ((long)msg); if (allowlist) { errorcount++; /* for posterity's sake */ listing = allowlist; /* force error line to be listed */ for (i = ermax; i <= pos - 2; i++) erbuf[i] = ' '; for (i = pos - 1; i <= lim - 2; i++) erbuf[i] = '='; if (lim > ermax + 1) ermax = lim - 1; }}/* routines used by getline */static void makeend(){ /* put an end directive on the line as result of end file */ /* makeend */ line[0] = 'E'; line[1] = 'N'; line[2] = 'D'; length = 3; line[3] = ';'; /* char beyond end must be initialized */}static void getmac(){ /* get one line of text from the string pool copy of macro body */ long parmnum; poolref _parm; int i; char ch; i = 0; do { /* copy literal text from pool to line */ ch = strpool[gettext - relsym]; gettext++; while (ch != pooldel && i < linelen - 1) { i++; line[i - 1] = ch; ch = strpool[gettext - relsym]; gettext++; } if (ch != pooldel) { /* isn't space in the line */ errmsg(notfit, 0, 0); while (strpool[gettext - relsym] != pooldel) gettext++; gettext++; } ch = strpool[gettext - relsym]; /* char after pooldel */ gettext++; if (charclass[ch] & isdigit) { /* macro param */ parmnum = ch - '0'; if (parmnum <= actcnt) { /* param exists */ _parm = actparm[parmnum - 1]; if (_parm > 0) { /* param is nonblank */ ch = strpool[_parm - relsym]; while (ch != pooldel && i < linelen - 1) { /* loop copying text of parameter */ i++; line[i - 1] = ch; _parm++; ch = strpool[_parm - relsym]; } if (ch != pooldel) errmsg(notfit, 0, 0); } } ch = ' '; /* force loop to continue */ } } while ((ch != pooldel) && (ch != ',')); if (ch == pooldel) { makeend(); } else { length = i; line[i] = ';'; /* this char must be initialized */ }}static void get(f)FILE *f;{ /* read one line from appropriate input file */ int i; int ch; i = 0; for (;;) { ch = getc(f); if ((ch == EOF) || (ch == '\n')) break; if (i >= (linelen - 1)) break; if (ch == pooldel) ch = pdelrep; if (ch == '\t') { do { line[i] = ' '; i++; } while (((i & 7) != 0) && (i < (linelen - 1))); } else { line[i] = ch; i++; } } if (i >= (linelen - 1)) errmsg(notfit, 0, 0); if ((ch == EOF) & (i == 0)) { makeend(); } else { length = i; line[i] = ';'; /* this char must be initialized */ }}static void getline(){ /* read one line from the input file, initialize the lexical analysis and listing control variables */ erset = 0; ermax = 0; if (gettext > 0) { getmac(); } else { /* lines are only counted at the bottom level! */ if (getlevel == 1) lineno++; get(inp[getlevel - 1]); } pos = 1; lex.typ = eol; lex.pos = 1; lex.lim = 1; next.typ = eol; next.pos = 1; next.lim = 1;}static void settitle(buf, len, pos, lim)char *buf;inbufptr *len, pos, lim;{ /* fill the indicated title buffer with the indicated part of the input line */ inbufptr i; *len = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -