|
|
1.1 ! root 1: /* ! 2: * Korn expression evaluation ! 3: */ ! 4: ! 5: static char *RCSid = "$Header: expr.c,v 3.1 88/11/03 09:15:55 egisin Exp $"; ! 6: ! 7: #include <stddef.h> ! 8: #include <errno.h> ! 9: #include <setjmp.h> ! 10: #include "sh.h" ! 11: #include "table.h" ! 12: ! 13: #define ef else if /* fashion statement */ ! 14: ! 15: #define VAR 0x01 ! 16: #define LIT 0x02 ! 17: #define LEQ 0x03 ! 18: #define LNE 0x04 ! 19: #define LLE 0x05 ! 20: #define LGE 0x06 ! 21: ! 22: static void token(); /* read next token */ ! 23: static Const char *expression; /* expression being evaluated */ ! 24: static Const char *tokp; /* lexical position */ ! 25: static int tok; /* token from token() */ ! 26: static struct tbl *val; /* value from token() */ ! 27: ! 28: static struct tbl *tempvar(), *intvar(); ! 29: static struct tbl *asn(), *e6(), *e5(), *e3(), *e2(), *e0(); ! 30: ! 31: /* ! 32: * parse and evalute expression ! 33: */ ! 34: void ! 35: evalerr(err) ! 36: char *err; ! 37: { ! 38: errorf("%s: %s\n", expression, err); ! 39: } ! 40: ! 41: long ! 42: evaluate(expr) ! 43: Const char *expr; ! 44: { ! 45: struct tbl *v; ! 46: ! 47: expression = tokp = expr; ! 48: token(); ! 49: v = intvar(asn()); ! 50: if (!(tok == 0)) ! 51: evalerr("bad expression"); ! 52: return v->val.i; ! 53: } ! 54: ! 55: static struct tbl * ! 56: asn() ! 57: { ! 58: register struct tbl *vl, *vr; ! 59: ! 60: vr = vl = e6(); ! 61: if ((tok == '=')) { ! 62: Area * olastarea = lastarea; ! 63: token(); ! 64: if ((vl->flag&RDONLY)) /* assign to rvalue */ ! 65: evalerr("bad assignment"); ! 66: vr = intvar(asn()); ! 67: lastarea = olastarea; ! 68: setint(vl, vr->val.i); ! 69: if ((vl->flag&INTEGER) && vl->type == 0) /* default base? */ ! 70: vl->type = vr->type; ! 71: } ! 72: return vr; ! 73: } ! 74: ! 75: static struct tbl * ! 76: e6() ! 77: { ! 78: register struct tbl *vl, *vr; ! 79: ! 80: vl = e5(); ! 81: while ((tok == LEQ) || (tok == LNE)) { ! 82: int op = tok; ! 83: token(); ! 84: vl = intvar(vl); ! 85: vr = intvar(e5()); ! 86: vl->val.i = vl->val.i == vr->val.i; ! 87: if (op == LNE) ! 88: vl->val.i = ! vl->val.i; ! 89: } ! 90: return vl; ! 91: } ! 92: ! 93: static struct tbl * ! 94: e5() ! 95: { ! 96: register struct tbl *vl, *vr; ! 97: ! 98: vl = e3(); ! 99: while ((tok == LLE) || (tok == '<') || (tok == '>') || (tok == LGE)) { ! 100: int op = tok; ! 101: token(); ! 102: vl = intvar(vl); ! 103: vr = intvar(e3()); ! 104: if (op == LLE) ! 105: vl->val.i = vl->val.i <= vr->val.i; ! 106: ef (op == '<') ! 107: vl->val.i = vl->val.i < vr->val.i; ! 108: ef (op == LGE) ! 109: vl->val.i = vl->val.i >= vr->val.i; ! 110: ef (op == '>') ! 111: vl->val.i = vl->val.i > vr->val.i; ! 112: } ! 113: return vl; ! 114: } ! 115: ! 116: static struct tbl * ! 117: e3() ! 118: { ! 119: register struct tbl *vl, *vr; ! 120: ! 121: vl = e2(); ! 122: while ((tok == '+') || (tok == '-')) { ! 123: int op = tok; ! 124: token(); ! 125: vl = intvar(vl); ! 126: vr = intvar(e2()); ! 127: if (op == '+') ! 128: vl->val.i += vr->val.i; ! 129: ef (op == '-') ! 130: vl->val.i -= vr->val.i; ! 131: } ! 132: return vl; ! 133: } ! 134: ! 135: static struct tbl * ! 136: e2() ! 137: { ! 138: register struct tbl *vl, *vr; ! 139: ! 140: vl = e0(); ! 141: while ((tok == '*') || (tok == '/') || (tok == '%')) { ! 142: int op = tok; ! 143: token(); ! 144: vl = intvar(vl); ! 145: vr = intvar(e0()); ! 146: if (op != '*' && vr->val.i == 0) ! 147: evalerr("zero divisor"); ! 148: if (op == '*') ! 149: vl->val.i *= vr->val.i; ! 150: ef (op == '/') ! 151: vl->val.i /= vr->val.i; ! 152: ef (op == '%') ! 153: vl->val.i %= vr->val.i; ! 154: } ! 155: return vl; ! 156: } ! 157: ! 158: static struct tbl * ! 159: e0() ! 160: { ! 161: register struct tbl *v; ! 162: ! 163: if ((tok == '!') || (tok == '-')) { ! 164: int op = tok; ! 165: token(); ! 166: v = intvar(e0()); ! 167: if (op == '!') ! 168: v->val.i = !v->val.i; ! 169: ef (op == '-') ! 170: v->val.i = -v->val.i; ! 171: } else ! 172: if ((tok == '(')) { ! 173: token(); ! 174: v = asn(); ! 175: if (!(tok == ')')) ! 176: evalerr("missing )"); ! 177: token(); ! 178: } else ! 179: if ((tok == VAR) || (tok == LIT)) { ! 180: v = val; ! 181: token(); ! 182: } else ! 183: evalerr("bad expression"); ! 184: return v; ! 185: } ! 186: ! 187: static void ! 188: token() ! 189: { ! 190: register char *cp = (char *) tokp; ! 191: register int c, c2; ! 192: ! 193: /* skip white space */ ! 194: do c = *cp++; while (c != '\0' && (c == ' ' || c == '\t')); ! 195: tokp = cp-1; ! 196: ! 197: if (letter(c)) { ! 198: for (; letnum(c); c = *cp++) ! 199: ; ! 200: c = *--cp; ! 201: *cp = 0; ! 202: val = global(tokp); ! 203: *cp = c; ! 204: tok = VAR; ! 205: } else ! 206: if (digit(c)) { ! 207: for (; letnum(c) || c == '#'; c = *cp++) ! 208: ; ! 209: c = *--cp; ! 210: *cp = 0; ! 211: val = tempvar(); ! 212: setstr(val, tokp); ! 213: val->flag |= RDONLY; ! 214: *cp = c; ! 215: tok = LIT; ! 216: } else { ! 217: c2 = *cp++; ! 218: if (c == '=' && c2 == '=') ! 219: c = LEQ; ! 220: ef (c == '!' && c2 == '=') ! 221: c = LNE; ! 222: ef (c == '<' && c2 == '=') ! 223: c = LLE; ! 224: ef (c == '>' && c2 == '=') ! 225: c = LGE; ! 226: else ! 227: cp--; ! 228: tok = c; ! 229: } ! 230: tokp = cp; ! 231: } ! 232: ! 233: static struct tbl * ! 234: tempvar() ! 235: { ! 236: register struct tbl *vp; ! 237: ! 238: vp = alloc(sizeof(struct tbl), ATEMP); ! 239: lastarea = ATEMP; ! 240: vp->flag = ISSET|INTEGER; ! 241: vp->type = 0; ! 242: vp->name[0] = '\0'; ! 243: return vp; ! 244: } ! 245: ! 246: /* cast (string) variable to temporary integer variable */ ! 247: static struct tbl * ! 248: intvar(vp) ! 249: register struct tbl *vp; ! 250: { ! 251: register struct tbl *vq; ! 252: ! 253: vq = tempvar(); ! 254: vq->type = 10; ! 255: return strint(vq, vp); ! 256: } ! 257:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.