📄 smal32.c
字号:
WITH->use |= (1L << ((long)lab)) | (1L << ((long)setyet)); /* with */ /* symbol previously unused */}static void externl(){ /* parse and process external symbol declarations */ symptr symbol; /* externl */ if (lex.typ == id) { /* read over external symbol name */ symbol = lookup(lex.pos, lex.lim); if (symbol > 0) makeext(symbol); } else errmsg(idexp, lex.pos, lex.lim); nextlex();}static void comdef(){ /* parse and process common declarations */ symptr symbol; if (lex.typ != id) { errmsg(idexp, lex.pos, lex.lim); return; } symbol = lookup(lex.pos, lex.lim); if (symbol > 0) { association *WITH = &symtab[symbol - 1]; makeext(symbol); /* read over common name */ nextlex(); getcomma(); /* get common size or maximum location */ expresbal(); if (expr.base != abssym && expr.base != WITH->id) { errmsg(badrel, exprpos, exprlim); return; } expr.offset += expr.offset & 1; /* halfword align size */ expr.offset += expr.offset & 2; /* word align size */ if (!allowlist) return; fputs("IF\\DEF(S", obj); writesym(obj, WITH->id); fputs(")\n S", obj); writesym(obj, WITH->id); fputs("=#", obj); writehex(obj, expr.offset, 4L); fputs("\nENDIF\nIF\\DEF(R", obj); writesym(obj, WITH->id); fputs(")\n R", obj); writesym(obj, WITH->id); fputs("=C\n C=C+S", obj); writesym(obj, WITH->id); fputs("\n CT=.\n .=C\n .=CT\nENDIF\n",obj); return; } nextlex(); getcomma(); /* skip over size */ expresbal(); /* symbol table full */ /* skip over name */ /* common name missing */}/* inside smal32.onepass, processing of text insertions */static void insert_(){ /* process use directive (push one input file on stack) */ int i; inbufptr pos; int startpos; if (lex.typ != quote) { errmsg(quoexp, lex.pos, lex.lim); nextlex(); return; } if (getlevel >= maxgetl) { errmsg(maxuse, lex.pos, lex.lim); nextlex(); return; } /* put together the file name */ pos = lex.pos + 1; startpos = 1; if (line[pos - 1] != pathbrk) { /* relative path */ memcpy(infile[getlevel], infile[getlevel - 1], sizeof(filename)); for (i = 1; i < filelen; i++) { if (infile[getlevel][i - 1] == pathbrk) startpos = i + 1; } } for (i = startpos - 1; i < filelen; i++) { if (pos < lex.lim - 1) { infile[getlevel][i] = line[pos - 1]; pos++; } else infile[getlevel][i] = 0; } /* try to open the file */ if (inp[getlevel] != NULL) { inp[getlevel] = freopen(infile[getlevel], "r", inp[getlevel]); } else { inp[getlevel] = fopen(infile[getlevel], "r"); } if (inp[getlevel] == NULL) { /* see if it worked */ errmsg(baduse, lex.pos, lex.lim); } else { /* if it worked, save current source */ pushget(); getlevel++; gettext = 0; /* set source to file, not macro */ actcnt = 0; /* set to no macro parameters */ } nextlex();}/* static variables for macdef: */static poolref parmtab[parmlim];static int parms;static poolref _oldsp;static void getpar(){ /* getpar */ /* parse one formal parameter of form: <param> := <id> ! ( <id> ) ! = <id> corresponding to by name, by list of names, and by value */ /* the parameter identifier */ lexeme _parm; /* the position of the begin paren */ lexeme par; /* the type of the formal parameter */ char typ = ' '; if (parms < parmlim) { /* read over parameter */ if (lex.typ == id) { /* name parameter */ _parm = lex; typ = 'a'; } else if (lex.typ == eq) { nextlex(); if (lex.typ == id) { typ = '='; _parm = lex; } else { _parm.typ = eol; errmsg(idexp, lex.pos, lex.lim); } } else if (lex.typ == bpar) { par = lex; /* hold onto position for errors */ /* skip over paren */ nextlex(); if (lex.typ == id) { typ = '('; _parm = lex; nextlex(); /* skip over identifier */ if (lex.typ != epar) errmsg(unbal, par.pos, par.lim); } else { _parm.typ = eol; errmsg(idexp, lex.pos, lex.lim); } } else { _parm.typ = eol; errmsg(idexp, lex.pos, lex.lim); } if (_parm.typ == id) { /* have a good param */ parms++; if (firstpass) { parmtab[parms-1] = pushtext(_parm.pos, _parm.lim); putch(typ); } } } else { errmsg(parovf, lex.pos, lex.lim); } nextlex();}static parm lookup_(pos, lim)inbufptr pos, lim;{ /* lookup candidate formal parameter name */ parm Result, i; /* lookup */ Result = 0; i = 0; while (i < parms) { i++; if (poolcmp(parmtab[i - 1], pos, lim)) { Result = i; i = parms; } } return Result;}static void getbody(){ /* parse macro body of form: <body> ::= <linesequence> endmac */ /* counter to find right endmac when nested */ long nest; inbufptr pos; /* progress pointers for parameter scan */ inbufptr lim; /* identity of current parameter */ parm parmnum; /* getbody */ nest = 1; do { if (listing) listline(); getop(); if (optype == opmac) nest++; else if (optype == opendm) nest--; else if (optype == opend) nest = 0; if (nest > 0 && firstpass) { /* save text */ pos = 1; while (pos <= length) { while (!(charclass[line[pos - 1]] & isalpha) && (pos <= length) ) { /* copy non identifier text */ if (line[pos - 1] == '\'') { /* squeeze out quote marks */ pos++; /* assert line[length+1]=';' */ while (line[pos - 1] == '\'') { putch('\''); pos++; } } else { /* pass through simple text */ putch(line[pos - 1]); pos++; } } if (pos > length) break; /* found an identifier */ lim = pos; while (charclass[line[lim - 1]] & isalphanum) lim++; /* length of identifier known */ parmnum = lookup_(pos, lim); if (parmnum > 0) { /* identifier is a macro formal parm */ putch(pooldel); putch(parmnum + '0'); } else { /* identifier is just text */ for (pos--; pos <= lim - 2; pos++) putch(line[pos]); } pos = lim; } putch(pooldel); putch(','); } } while (nest >= 1); poolsp = _oldsp; /* pop formal parameter table from stack */ if (optype == opend) { /* found end of file, not endm */ errmsg(misemc, 0, 0); popget(); } if (firstpass) { putch(pooldel); /* two pooldel's in a row end a macro */ putch(pooldel); }}static void macdef(){ /* process macro definitions of the form: macro <name> [ <param> [ , <param> ]* ] <body> */ opptr m; parms = 0; _oldsp = poolsp; /* mark stack top, allowing temporary use */ if (lex.typ == id) { /* have macro name */ m = oplookup(lex.pos, lex.lim); if (m <= 0) /* skip over macro name */ { /* no room in table */ opfull = true; } else if (firstpass) { if (optab[m - 1].id == 0) { /* first definition */ if (poolfit(lex.pos, lex.lim)) { optab[m - 1].id = putpool_(lex.pos, lex.lim); optab[m - 1].typ = opmcall; optab[m - 1].val = poolpos + 1; } } else { /* redefinition */ optab[m - 1].typ = opmcall; optab[m - 1].val = poolpos + 1; } } nextlex(); if (lex.typ != eol) { getpar(); while (lex.typ != eol) { getcomma(); getpar(); } } if (firstpass) /* mark end of parmtypes */ putch(pooldel); } else { /* missing macro name */ errmsg(idexp, lex.pos, lex.lim); /* skip over junk */ nextlex(); } if (lex.typ != eol && erset == 0) errmsg(unproc, lex.pos, lex.lim); getbody();}/* static variables for maccall: */static poolref _poolpos;static void getpar_(){ /* parse a parameter of the form: <param> ::= [ <lexeme> ]* ! <expression> ! ( [ <lexeme> ]* ) [ : <expr> [ : <expr> ] ] */ char typ; /* indicates expected parameter type */ inbufptr pos; /* location of parameter */ inbufptr lim; /* position info for begin paren */ lexeme par; typ = strpool[_poolpos - relsym]; _poolpos++; actcnt++; if (((1L << ((long)lex.typ)) & ((1L << ((long)comma)) | (1L << ((long)eol)))) != 0) { /* parameter missing */ actparm[actcnt - 1] = 0; return; } if (typ == 'a') { pos = lex.pos; lim = lex.lim; while (((1L << ((long)lex.typ)) & ((1L << ((long)eol)) | (1L << ((long)comma)))) == 0) { if (lex.typ == bpar) skipbal(); else if (lex.typ == epar) errmsg(unbal, lex.pos, lex.lim); lim = lex.lim; nextlex(); } actparm[actcnt - 1] = pushtext(pos, lim); return; } if (typ == '=') { expresbal(); /* recall that text is pushed backwards */ pushitxt(expr.offset); /* end with decimal offset */ if (expr.base != abssym) { /* add in correction for relocatable symbols */ pushchar('+'); if (expr.base == relsym) { /* actual param is REL(0)+offset */ pushchar(')'); pushchar('0'); pushchar('('); pushchar('L'); pushchar('E'); pushchar('R'); actparm[actcnt - 1] = poolsp + 1; } else { /* actual param is external+offset */ short int i = expr.base - relsym; short int j; for (j = i; strpool[j] != pooldel; j++); for (j--; j >= i; j--) { pushchar(strpool[j]); } } } actparm[actcnt - 1] = poolsp + 1; return; } if (typ != '(') return; if (lex.typ != bpar) { errmsg(parexp, lex.pos, lex.lim); nextlex(); return; } par = lex; /* skip paren at list head */ nextlex(); pos = lex.pos; lim = pos; /* default for empty string */ while (((1L << ((long)lex.typ)) & ((1L << ((long)eol)) | (1L << ((long)epar)))) == 0) { if (lex.typ == bpar) skipbal(); lim = lex.lim; nextlex(); } if (lex.typ == eol) errmsg(unbal, par.pos, par.lim); else nextlex(); if (lex.typ == colon) { /* substring */ nextlex(); if (lex.typ != colon) { /* get start */ expresbal(); if (expr.base != abssym) errmsg(badrel, exprpos, exprlim); if (expr.offset > 1) { if (expr.offset > lim - pos) pos = lim; else pos += expr.offset - 1; } } if (lex.typ == colon) { nextlex(); /* get length */ expresbal(); if (expr.base != abssym) errmsg(badrel, exprpos, exprlim); if (expr.offset < lim - pos) { if (expr.offset < 1) lim = pos; else lim = pos + expr.offset; } } } if (pos >= lim) actparm[actcnt - 1] = 0; else actparm[actcnt - 1] = pushtext(pos, lim);}static void maccall(poolpos_)poolref poolpos_;{ /* call macro who's text is stored at poolpos in string pool; form of call is: <name> [ <param> [ , <param> ]* ] */ /* save previous macro expansion status block */ _poolpos = poolpos_; if (poolfull) { /* stop bad calls */ } else { pushget(); actcnt = 0; while (strpool[_poolpos-relsym] != pooldel && lex.typ != eol) { getpar_(); if (lex.typ != eol) getcomma(); } if (lex.typ != eol) errmsg(parovf, lex.pos, lex.lim); while (strpool[_poolpos - relsym] != pooldel) _poolpos++; gettext = _poolpos + 1; /* set to read macro text from pool */ }}/* inside smal32.onepass, processing of conditional directives */static void findend(){ /* skip over lines until a line with endif or end opcode found */ long nest; nest = 0; do { /* read and check following lines */ /* first list previous line */ if (listing) listline(); getop(); if (optype == opif) nest++; else if (optype == opendif) nest--; } while (optype != opend && nest >= 0); if (optype == opend) { errmsg(miseif, 0, 0); popget(); }}static void findelse(){ /* skip lines until one with an else, elseif <true>, or end found */ do { /* read over then parts (allowing multiple elseif's) */ if (lex.typ != eol && erset == 0) errmsg(unproc, lex.pos, lex.lim); do { /* list line to be skipped */ if (listing) listline(); getop(); while (optype == opif) { findend(); /* list end */ if (listing) listline(); if (optype == opend) optype = opendif; /* don't complain twice */ else getop(); } } while (((1L << ((long)optype)) & ((1L << ((long)opend)) | (1L << ((long)opendif)) | (1L << ((long)opelse)) | (1L << ((long)opelseif)))) == 0); if (optype == opelseif) { if (predicate()) optype = opelse; } } while (((1L << ((long)optype)) & ((1L << ((long)opend)) | (1L << ((long)opendif)) | (1L << ((long)opelse)))) == 0); if (optype == opend) { errmsg(miseif, 0, 0); popget(); }}/* inside smal32, main assembly procedure for one pass through source */static void onepass(){ /* perform one assembly pass. produce output if listing=true */ /* max val of loc.offset when loc.base = relsym */ long maxrel; /* starting address, if specified */ value startloc; /* detects multiple start dirs */ boolean seenstart; poolsp = poolsize; gettext = 0; getle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -