Annotation of coherent/b/bin/db/db5.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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