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