home *** CD-ROM | disk | FTP | other *** search
- /* lkeval.c */
-
- /*
- * (C) Copyright 1989
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio 44240
- */
-
- #include <stdio.h>
- #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);
- }
-