Annotation of coherent/d/bin/db/trace5.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * A debugger.
                      3:  * Expression evaluator.
                      4:  */
                      5: #include <stdio.h>
                      6: #include <ctype.h>
                      7: #include "trace.h"
                      8: 
                      9: #define        VALUE   (-2)            /* must be distinct from chars */
                     10: #define        VILLEGAL (-3)           /* ditto */
                     11: #define        PRCFULL (0<<8)          /* precedence wall for full expression */
                     12: #define        PRECADD (1<<8)          /* precedence of addops */
                     13: #define        PRECMUL (2<<8)          /* precedence of mulops */
                     14: #define        PRIMARY (4<<8)          /* precedence of primary expression */
                     15: #define        tk_preced(op)   ((op)&(~0<<8))
                     16: #define        tk_char(op)     ((op)&0377)
                     17: 
                     18: /*
                     19:  * Evaluate an expression list.
                     20:  */
                     21: int
                     22: explist(vlist)
                     23: VAL vlist[VALSIZE];
                     24: {
                     25:        register VAL *vp;
                     26:        register int c, n;
                     27: 
                     28:        vp = vlist;
                     29:        n = VALSIZE;
                     30:        do {
                     31:                if (expressn(vp, PRCFULL)<0)
                     32:                        return (0);
                     33:                vp++;
                     34:                --n;
                     35:        } while ((c=getn()) == ',');
                     36:        ungetn(c);
                     37:        while (n--)
                     38:                vp++->v_flag = VNULL;
                     39:        return (1);
                     40: }
                     41: 
                     42: /*
                     43:  * Recursive expression reader;
                     44:  * returns -1 for error, 0 for null expr, 1 for good expr.
                     45:  */
                     46: int
                     47: expressn(left, wall)
                     48: register VAL   *left;
                     49: int    wall;
                     50: {
                     51:        VAL     v;
                     52:        register VAL    *right = &v;
                     53:        int     token, result;
                     54: 
                     55:        token = lextoken(left);
                     56:        if (token==VALUE)
                     57:                ;
                     58:        else if (token==VILLEGAL)
                     59:                return (-1);
                     60:        else switch (tk_char(token)) {
                     61:        case '~':
                     62:                if (expressn(left, PRIMARY)<=0)
                     63:                        return (-1);
                     64:                left->v_nval = ~left->v_nval;
                     65:                break;
                     66:        case '-':
                     67:                if (expressn(left, PRIMARY)<=0)
                     68:                        return (-1);
                     69:                left->v_nval = -left->v_nval;
                     70:                break;
                     71:        case '*':
                     72:                if (expressn(left, PRIMARY)<=0)
                     73:                        return (-1);
                     74:                add = left->v_nval;
                     75:                getb(left->v_flag&VLVAL ? left->v_segn : 0,
                     76:                        &result, sizeof result);
                     77:                left->v_nval = (long)(unsigned int)result;
                     78:                left->v_flag = VLVAL;
                     79:                left->v_segn = 0;
                     80:                break;
                     81:        case '(':
                     82:                if (expressn(left, PRCFULL)<=0)
                     83:                        return (-1);
                     84:                if ((token=lextoken(NULL))==')')
                     85:                        break;
                     86:                else {
                     87:                        unlex(token);
                     88:                        printe("Missing ')'");
                     89:                        return (-1);
                     90:                }
                     91:        default:
                     92:                unlex(token);
                     93:                left->v_flag = VNULL;
                     94:                return (0);
                     95:        }
                     96:        for (;;) {
                     97:                token = lextoken(NULL);
                     98:                if (tk_preced(token) <= wall) {
                     99:                        unlex(token);
                    100:                        return (1);
                    101:                } else switch (tk_char(token)) {
                    102:                case '*':
                    103:                        if ((result=expressn(right, PRECMUL))<=0)
                    104:                                break;
                    105:                        left->v_nval *= right->v_nval;
                    106:                        continue;
                    107:                case '/':
                    108:                        if ((result=expressn(right, PRECMUL))<=0)
                    109:                                break;
                    110:                        left->v_nval /= right->v_nval;
                    111:                        continue;
                    112:                case '+':
                    113:                        if ((result=expressn(right, PRECADD))<=0)
                    114:                                break;
                    115:                        left->v_nval += right->v_nval;
                    116:                        continue;
                    117:                case '-':
                    118:                        if ((result=expressn(right, PRECADD))<=0)
                    119:                                break;
                    120:                        left->v_nval -= right->v_nval;
                    121:                        continue;
                    122:                default:
                    123:                        unlex(token);
                    124:                        printe("Unimplemented operator");
                    125:                        return (-1);
                    126:                }
                    127:                if (result==0)
                    128:                        printe("Missing operand");
                    129:                return (-1);
                    130:        }
                    131: }
                    132: 
                    133: /*
                    134:  * Lex a token. If value, store in given val ptr.
                    135:  */
                    136: int
                    137: lextoken(vp)
                    138: VAL    *vp;
                    139: {
                    140:        register int    c;
                    141: 
                    142:        for (;;) switch (c=getn()) {
                    143:        case ' ':
                    144:        case '\t':
                    145:                continue;
                    146:        case '.':
                    147:                if (vp==NULL) {
                    148:                        printe("Missing opr before '.'");
                    149:                        ungetn(c);
                    150:                        return (VILLEGAL);
                    151:                }
                    152:                vp->v_flag = VLVAL;
                    153:                vp->v_segn = cseg;
                    154:                vp->v_nval = dot;
                    155:                return (VALUE);
                    156:                /*
                    157:                 * only binary ops need be mentioned explicitly
                    158:                 * so precedences can be added
                    159:                 */
                    160:        case '*':
                    161:        case '/':
                    162:                return (c|PRECMUL);
                    163:        case '+':
                    164:        case '-':
                    165:                return (c|PRECADD);
                    166:        default:
                    167:                if ('0'<=c && c<='9' || c == '#')
                    168:                        return (readval(vp, c));
                    169:                else if ('a'<=c && c<='z' || 'A'<=c && c<='Z' || c=='_')
                    170:                        return (readvar(vp, c));
                    171:                else
                    172:                        return (c);
                    173:        }
                    174: }
                    175: /*
                    176:  * Push token back on input stream
                    177:  */
                    178: unlex(c)
                    179: int    c;
                    180: {
                    181:        if (c!=VILLEGAL && c!=VALUE)
                    182:                ungetn(tk_char(c));
                    183: }
                    184: 
                    185: /*
                    186:  * Read a number.
                    187:  */
                    188: readval(vp, c)
                    189: VAL    *vp;
                    190: register int   c;
                    191: {
                    192:        register unsigned long  l = 0;
                    193:        register int    i, base = dbase;
                    194: 
                    195:        if (vp==NULL) {
                    196:                printe("Missing opr before number");
                    197:                ungetn(c);
                    198:                return (VILLEGAL);
                    199:        }
                    200:        if (c=='0') {
                    201:                if ((c=getn())=='x') {
                    202:                        base = 16;
                    203:                } else {
                    204:                        ungetn(c);
                    205:                        if( c != '|')
                    206:                                base = 8;
                    207:                }
                    208:        }
                    209:        else if( c == '#')
                    210:                base = 10;
                    211:        else
                    212:                ungetn( c);
                    213:        for (;;) {
                    214:                if ((10<=(i=(c=getn())-('a'-10))
                    215:                  || 10<=(i=c-('A'-10))
                    216:                  ||  0<=(i=c-'0') && i<=9
                    217:                 )&& i<base)
                    218:                        l = l*base + i;
                    219: #if FORZ8001
                    220:                else if( c == '|') {
                    221:                        long    seg;
                    222: 
                    223:                        seg = l & 127;
                    224:                        l = 0;
                    225:                        for( ;;) {
                    226:                                if( ( 10 <= ( i = ( c = getn()) - ('a'-10))
                    227:                                        || 10 <= ( i = c - ('A'-10))
                    228:                                        || 0 <= ( i = c - '0') && i <= 9 )
                    229:                                    && i < base)
                    230:                                        l = l*base + i;
                    231:                                else
                    232:                                        break;
                    233:                        }
                    234:                        l += seg << 24;
                    235:                        break;
                    236:                }
                    237: #endif
                    238:                else
                    239:                        break;
                    240:        }
                    241:        ungetn(c);
                    242:        vp->v_flag = 0;
                    243:        vp->v_nval = l;
                    244:        return (VALUE);
                    245: }
                    246: 
                    247: /*
                    248:  * Read symbol and place value in given val struct
                    249:  */
                    250: readvar(vp, c)
                    251: VAL    *vp;
                    252: {
                    253:        ungetn(c);
                    254:        if (vp==NULL) {
                    255:                printe("Missing opr before symbol");
                    256:                return (VILLEGAL);
                    257:        }
                    258:        return (getsval(vp) ? VALUE : VILLEGAL);
                    259: }
                    260: 
                    261: /*
                    262:  * Given a value, return it's segment.  If there is no segment associated
                    263:  * with it, return `v'.
                    264:  */
                    265: vsegno(vp, v)
                    266: register VAL *vp;
                    267: {
                    268:        if ((vp->v_flag&VLVAL) == 0)
                    269:                return (v);
                    270:        return (vp->v_segn);
                    271: }
                    272: 
                    273: /*
                    274:  * Evaluate a value as an lvalue and return it.  If the value is
                    275:  * null, return `v'.
                    276:  */
                    277: long
                    278: lvalue(vp, v)
                    279: register VAL *vp;
                    280: long v;
                    281: {
                    282:        if (vp->v_flag&VNULL)
                    283:                return (v);
                    284:        return (vp->v_nval);
                    285: }
                    286: 
                    287: /*
                    288:  * Evaluate a value as an rvalue and return it.  If the value is
                    289:  * null, return `v'.
                    290:  */
                    291: long
                    292: rvalue(vp, v)
                    293: register VAL *vp;
                    294: long v;
                    295: {
                    296:        if (vp->v_flag&VNULL)
                    297:                return (v);
                    298:        return (vp->v_nval);
                    299: }
                    300: 
                    301: /*
                    302:  * If the given value is null, return 1, else 0.
                    303:  */
                    304: nvalue(vp)
                    305: VAL *vp;
                    306: {
                    307:        return (vp->v_flag&VNULL);
                    308: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.