📄 smal32.c
字号:
/* assert lex.typ = bpar */ nest = 1; par = lex; do { nextlex(); if (lex.typ == bpar) nest++; else if (lex.typ == epar) nest--; } while (nest >= 1 && lex.typ != eol); if (lex.typ == eol) errmsg(unbal, par.pos, par.lim);}static void expression();static void value_(){ /* parse values of an expression of the form <value> ::= <ident> ! <num> ! . ! ( <expression> ) ! <string> ! <identifier> ( <argument> ) return the value of the value in expr */ symptr symbol; lexeme op, par; long i; association *WITH; exprpos = lex.pos; exprlim = lex.lim; exprundef = false; if (lex.typ == num) { /* got a + 1number */ expr.offset = lex.UU.val; expr.base = abssym; exprdef = true; /* read over number */ nextlex(); } else if (lex.typ == quote) { expr.base = 0; expr.offset = 0; exprdef = true; i = lex.lim - lex.pos; if (i > 6) errmsg(bounds, lex.pos, lex.lim); else if (i > 2) { long FORLIM = lex.lim - lex.pos - 3; for (i = 0; i <= FORLIM; i++) expr.offset = expr.offset * 256 + line[lex.pos + i]; } nextlex(); } else if ((lex.typ == id) && (next.typ == bpar)) { /* do a named (unary) function */ op = lex; nextlex(); /* skip operator name */ par = lex; nextlex(); /* skip opening paren */ expr.base = abssym; expr.offset = 1; /* default to ambiguous */ exprdef = true; /* default to defined */ if (poolcmp(funcdf, op.pos, op.lim)) { if (lex.typ == id) /* skip operand */ symbol = lookup(lex.pos, lex.lim); else { symbol = 0; errmsg(idexp, lex.pos, lex.lim); } nextlex(); if (symbol != 0) expr.offset = -(((1L<<((long)setyet)) & symtab[symbol - 1].use) != 0); } else if (poolcmp(funcfw, op.pos, op.lim)) { if (lex.typ == id) /* skip operand */ symbol = lookup(lex.pos, lex.lim); else { symbol = 0; errmsg(idexp, lex.pos, lex.lim); } nextlex(); if (symbol != 0) expr.offset = -(((1L<<((long)usedyet)) & symtab[symbol - 1].use)!=0 && ((1L<<((long)setyet)) & symtab[symbol - 1].use)==0); } else if (poolcmp(functy, op.pos, op.lim)) { expression(); expr.offset = expr.base; expr.base = abssym; } else if (poolcmp(funcab, op.pos, op.lim)) { expression(); expr.base = abssym; } else if (poolcmp(funcrl, op.pos, op.lim)) { expression(); if (expr.base == abssym) { expr.base = relsym; } else { errmsg(badrel, exprpos, exprlim); } } else if (poolcmp(funcle, op.pos, op.lim)) { if (lex.typ == epar) expr.offset = 0; else { expr.offset = lex.pos; if (lex.typ == bpar) skipbal(); while ((next.typ != eol)&&(next.typ != epar)) { nextlex(); if (lex.typ == bpar) skipbal(); } expr.offset = lex.lim - expr.offset; nextlex(); } } else { errmsg(unfunc, op.pos, op.lim); while ((lex.typ != epar) && (lex.typ != eol)) nextlex(); } if (lex.typ == epar) { exprpos = op.pos; exprlim = lex.lim; /* skip end paren */ nextlex(); } else { errmsg(unbal, par.pos, par.lim); } } else if (lex.typ == id) { /* ah, just an ordinary identifier.. */ symbol = lookup(lex.pos, lex.lim); if (symbol > 0) { /* read over identifier */ WITH = &symtab[symbol - 1]; WITH->use |= 1L << ((long)usedyet); if (((1L << ((long)def)) & WITH->use) != 0 || ((1L << ((long)lab)) & WITH->use) != 0) { expr = WITH->val; exprdef = true; exprundef = (((1L << ((long)setyet)) & WITH->use) == 0); } else { errmsg(undef, lex.pos, lex.lim); expr.offset = 0; expr.base = abssym; exprdef = false; } } else { /* if */ expr.offset = 0; /* no err on full table */ expr.base = abssym; exprdef = true; /* pretend it's defined */ } nextlex(); } else if (lex.typ == dot) { expr = loc; exprdef = true; /* read over dot */ nextlex(); } else if (lex.typ == bpar) { par = lex; nextlex(); expression(); if (lex.typ == epar) { exprpos = par.pos; exprlim = lex.lim; nextlex(); } else errmsg(unbal, par.pos, par.lim); } else { /* got something else */ errmsg(notval, lex.pos, lex.lim); expr.offset = 0; expr.base = abssym; exprdef = false; if (((1L << ((long)lex.typ)) & ((1L << ((long)epar)) | (1L << ((long)eol)) | (1L << ((long)comma)))) == 0) /* read over whatever it is */ nextlex(); } exprundef = (!exprdef || exprundef);}static void term(){ /* parse terms of an expression of the form <term> ::= [ <unary> ] <value> return the value of the term in expr */ /* unary operator */ lexeme op; if (((1L << ((long)lex.typ)) & ((1L << ((long)plus)) | (1L << ((long)minus)) | (1L << ((long)notsym)))) == 0) { /* unary */ value_(); return; } op = lex; /* read over unary operator */ nextlex(); /* get value to be modified */ value_(); exprpos = op.pos; switch (op.typ) { /* case */ case plus: /* blank case */ break; case minus: if (expr.base == abssym) expr.offset = neg(expr.offset); else errmsg(badrel, op.pos, op.lim); break; case notsym: if (expr.base == abssym) expr.offset = inot(expr.offset); else errmsg(badrel, op.pos, op.lim); break; } /* no unary operator */}/* inside smal32.onepass, procedures to parse expressions */static void expression(){ /* parse expressions of the form <expression> ::= <term> ! <expression> <binop> <term> return the value of the expression in expr */ value acc; /* the accumulator */ boolean accdef; /* is the accumulator defined */ boolean accundef; /* does acc. have fwd ref(s)? */ lexeme op; /* what operator was found */ inbufptr expos; /* position of start of expression */ /* get leading term */ term(); acc = expr; accdef = exprdef; accundef = exprundef; expos = exprpos; /* save pos for error handlers */ while ( (lex.typ == plus) || (lex.typ == minus) || (lex.typ == gt) || (lex.typ == lt) || (lex.typ == eq) || (lex.typ == andsym) || (lex.typ == orsym) ) { /* while loop processing terms */ op = lex; /* skip over operator */ nextlex(); if ( (op.typ == lex.typ) && ( (op.typ == gt) || (op.typ == lt) ) ) { /* skip over remainder of operator */ /* it is a shift operator: >> or << */ nextlex(); if (op.typ == gt) op.typ = epar; else op.typ = bpar; } /* get following term */ term(); if (!exprdef) { accdef = false; continue; } switch (op.typ) { /* case */ case plus: /* plus */ acc.offset = add(acc.offset, expr.offset); if (acc.base == abssym) acc.base = expr.base; else if (expr.base != abssym) { errmsg(badrel, op.pos, op.lim); acc.base = abssym; } break; case minus: /* minus */ acc.offset = sub(acc.offset, expr.offset); if (acc.base == expr.base) acc.base = abssym; else if (expr.base != abssym) { errmsg(badrel, op.pos, op.lim); acc.base = abssym; } break; case gt: case lt: case eq: if (acc.base == expr.base) { switch (op.typ) { /* case */ case gt: acc.offset =-(acc.offset > expr.offset); break; case lt: acc.offset =-(acc.offset < expr.offset); break; case eq: acc.offset =-(acc.offset ==expr.offset); break; } acc.base = abssym; } else { /* gt,lt,eq */ errmsg(badrel, op.pos, op.lim); acc.base = abssym; acc.offset = 1; /* neither true nor false */ } break; case andsym: case orsym: if (acc.base == abssym && expr.base == abssym) { switch (op.typ) { /* case */ case andsym: acc.offset=iand(acc.offset,expr.offset); break; case orsym: acc.offset =ior(acc.offset,expr.offset); break; } } else /* andsym,orsym */ errmsg(badrel, op.pos, op.lim); break; case bpar: case epar: if (acc.base == abssym && expr.base == abssym) { if (expr.offset > 32) expr.offset = 32; while (expr.offset > 0) { switch (op.typ) { case bpar: acc.offset =add(acc.offset, acc.offset); break; case epar: acc.offset = rightshift(acc.offset); break; } expr.offset--; } } else { errmsg(badrel, op.pos, op.lim); } /* shift operators */ break; } } expr = acc; exprdef = accdef; exprundef = (exprundef || accundef || !exprdef); exprpos = expos;}static void expresbal(){ /* evaluate expressions, assuring balanced parens */ /* expresbal */ expression(); while (lex.typ == epar) { errmsg(unbal, lex.pos, lex.lim); nextlex(); }}static boundval( v, min, max )long *v;long min, max;{ /* check to see v is between min and max */ if ((*v < min) || (*v > max)) { errmsg( bounds, exprpos, exprlim ); *v = min; }}static boolean predicate(){ /* evaluate expression */ /* evaluate predicates for if and elseif directives */ boolean Result; expresbal(); Result = false; /* default */ if (expr.base == abssym) { if (expr.offset == -1) return true; } else errmsg(badrel, exprpos, exprlim); return Result;}/* inside smal32.onepass, processing of key syntactic elements */static void labeldef(){ /* parse label definition; define label and handle multiples */ symptr symbol; /* labeldef */ /* assume that (lex.typ = id) and (next.typ = colon) */ symbol = lookup(lex.pos, lex.lim); if (symbol > 0) { /* the symbol is in the table */ association *WITH = &symtab[symbol - 1]; if (((1L << ((long)setyet)) & WITH->use) != 0) { errmsg(muldef, lex.pos, lex.lim); } else if (((1L << ((long)lab)) & WITH->use) != 0) { if (WITH->val.offset != loc.offset || WITH->val.base != loc.base) { errmsg(phase, lex.pos, lex.lim); } } else { WITH->val = loc; } WITH->use |= (1L << ((long)lab)) | (1L << ((long)setyet)); } nextlex(); /* read over id */ nextlex(); /* read over colon */}static void definition(){ /* parse and process definition of form <id> = <expression> */ symptr symbol; association *WITH; /* definition */ symbol = lookup(lex.pos, lex.lim); if (((1L << ((long)lab)) & symtab[symbol - 1].use) != 0) /* read over id */ errmsg(muldef, lex.pos, lex.lim); nextlex(); /* read over eq */ nextlex(); expresbal(); if (symbol <= 0) return; WITH = &symtab[symbol - 1]; WITH->use |= 1L << ((long)setyet); if (exprdef) { WITH->use |= 1L << ((long)def); WITH->val = expr; }}static void origin(){ /* skip dot */ /* parse and process definitions of the form . = <expression> */ /* origin */ nextlex(); /* skip eq */ nextlex(); expresbal(); loc = expr;}static void opcode(){ /* parse opcode field, including detection of data width specifying suffices. Resultant info is returned via globals optype, opval, opsubt, opsufi, opsufi2, opsuff and opsufcc. */ opptr i; oppos = lex.pos; oplim = lex.lim; optype = operr; i = oplookup(oppos, oplim); if (i != 0) { if (optab[i - 1].id != 0) { _REC_optab *WITH = &optab[i - 1]; optype = WITH->typ; opval = WITH->val; opsubt = WITH->subtyp; } } nextlex();}static void getop(){ /* skip and ignore labels on a line, return the opcode globally suppress any error messages encountered in parsing the line */ startup(); while (lex.typ == id && next.typ == colon) { /* skip id */ nextlex(); /* skip colon */ nextlex(); } if (lex.typ == id) { if (next.typ == eq) optype = operr; else opcode(); } else optype = operr; erset = 0;}/* inside smal32.onepass, processing of external symbol linkages */static void internl(){ /* parse and process internal symbol definitions */ symptr symbol; if (lex.typ == id) { /* read over internal symbol name */ symbol = lookup(lex.pos, lex.lim); if (symbol > 0) { association *WITH = &symtab[symbol - 1]; WITH->use |= 1L << ((long)intdef); if ((WITH->use & ((1L << ((long)def)) | (1L << ((long)lab)))) == 0) /* if with */ errmsg(undef, lex.pos, lex.lim); } } else errmsg(idexp, lex.pos, lex.lim); nextlex();}static void makeext(symbol)symptr symbol;{ /* make or verify that the current symbol is external */ /* used only from externl and comdef */ association *WITH = &symtab[symbol - 1]; if (((1L << ((long)setyet)) & WITH->use) != 0) errmsg(muldef, lex.pos, lex.lim); else if (((1L << ((long)usedyet)) & WITH->use) != 0) errmsg(fwdref, lex.pos, lex.lim); else if (((1L << ((long)lab)) & WITH->use) != 0) { if (WITH->val.base != WITH->id || WITH->val.offset != 0) errmsg(muldef, lex.pos, lex.lim); } else { WITH->val.base = WITH->id; WITH->val.offset = 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -