Annotation of coherent/b/bin/db/db5.c, revision 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.