/* lkeval.c */ /* * (C) Copyright 1989 * All Rights Reserved * * Alan R. Baldwin * 721 Berkeley St. * Kent, Ohio 44240 */ #include #include "aslink.h" /* * Evaluate input term. */ int eval() { register c, n, v; c = getnb(); n = 0; while ((v = digit(c, radix)) >= 0) { n = n*radix + v; c = get(); } unget(c); return(n); } /* * Expression evaluation. * `N' is a firewall priority; all top level calls * (from the user) should be made with `n' set to 0. */ int expr (n) { register c, p; register v, ve; v = term(); while (ctype[c = getnb()] == BINOP) { if ((p = oprio(c)) <= n) break; if ((c == '>' || c == '<') && c != get()) { fprintf(stderr, "Invalid expression"); return(v); } ve = expr(p); if (c == '+') { v += ve; } else if (c == '-') { v -= ve; } else { switch (c) { case '*': v *= ve; break; case '/': v /= ve; break; case '&': v &= ve; break; case '|': v |= ve; break; case '%': v %= ve; break; case '^': v ^= ve; break; case '<': v <<= ve; break; case '>': v >>= ve; break; } } } unget(c); return(v); } /* * Read a term. * Handles unary operators, brackets, * constants in decimal, octal or hexadecimal * and identifiers. */ int term() { register c, n; register r, v; struct sym *sp; char id[NCPS]; c = getnb(); if (c == '#') { c = getnb(); } if (c == '(') { v = expr(0); if (getnb() != ')') fprintf(stderr, "Missing delimiter"); return(v); } if (c == '-') { return(-expr(100)); } if (c == '~') { return(~expr(100)); } if (c == '\'') { return(getmap(-1)); } if (c == '\"') { if (hilo) { return((getmap(-1)&0377)<<8 | (getmap(-1)&0377)); } else { return((getmap(-1)&0377) | (getmap(-1)&0377)<<8); } } if (c == '>' || c == '<') { v = expr(100); if (c == '>') v >>= 8; return(v&0377); } if (ctype[c] == DIGIT) { r = 10; if (c == '0') { c = get(); switch (c) { case 'b': case 'B': r = 2; c = get(); break; case '@': case 'o': case 'O': case 'q': case 'Q': r = 8; c = get(); break; case 'd': case 'D': r = 10; c = get(); break; case 'h': case 'H': case 'x': case 'X': r = 16; c = get(); break; default: break; } } n = 0; while ((v = digit(c, r)) >= 0) { n = r*n + v; c = get(); } unget(c); return(n); } if (ctype[c] == LETTER) { getid(id, c); if ((sp = lkpsym(id, 0)) == NULL) { fprintf(stderr, "Undefined symbol %8s\n", id); return(0); } else { return(symval(sp)); } } } /* * If `c' is a legal radix `r' digit * return its value; otherwise return * -1. */ int digit(c, r) register c, r; { if (r == 16) { if (c >= 'A' && c <= 'F') return (c - 'A' + 10); if (c >= 'a' && c <= 'f') return (c - 'a' + 10); } if (c >= '0' && c <= '9') return (c - '0'); return (-1); } /* * Return the priority of the binary * operator `c'. */ int oprio(c) register c; { if (c == '*' || c == '/' || c == '%') return (10); if (c == '+' || c == '-') return (7); if (c == '<' || c == '>') return (5); if (c == '^') return (4); if (c == '&') return (3); if (c == '|') return (1); return (0); }