3 Copyright (C) 1989-1995 Alan R. Baldwin
4 721 Berkeley St., Kent, Ohio 44240
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
25 * The module lkeval.c contains the routines to evaluate
26 * arithmetic/numerical expressions. The functions in
27 * lkeval.c perform a recursive evaluation of the arithmetic
28 * expression read from the input text line.
29 * The expression may include binary/unary operators, brackets,
30 * symbols, labels, and constants in hexadecimal, decimal, octal
31 * and binary. Arithmetic operations are prioritized and
32 * evaluated by normal arithmetic conventions.
34 * lkeval.c contains the following functions:
41 * lkeval.c contains no local/static variables
44 /*)Function Addr_T eval()
46 * The function eval() evaluates a character string to a
50 * int c character from input string
51 * int v value of character in current radix
52 * Addr_T n evaluation value
55 * int radix current number conversion radix
58 * int digit() lkeval.c
60 * char getnb() lklex.c
61 * VOID unget() lklex.c
64 * Input test is scanned and evaluated to a
76 while ((v = digit(c, radix)) >= 0) {
84 /*)Function Addr_T expr(n)
86 * int n a firewall priority; all top
87 * level calls (from the user)
88 * should be made with n set to 0.
90 * The function expr() evaluates an expression and
94 * int c current input text character
95 * int p current operator priority
96 * Addr_T v value returned by term()
97 * Addr_T ve value returned by a
98 * recursive call to expr()
101 * char ctype[] array of character types, one per
103 * int lkerr error flag
104 * FILE * stderr c_library
107 * VOID expr() lkeval.c
108 * int fprintf() c_library
109 * int getnb() lklex.c
110 * int oprio() lkeval.c
111 * VOID term() lkeval.c
112 * VOID unget() lklex.c
116 * An expression is evaluated by scanning the input
124 register Addr_T v, ve;
127 while (ctype[c = getnb()] & BINOP) {
128 if ((p = oprio(c)) <= n)
130 if ((c == '>' || c == '<') && c != get()) {
131 fprintf(stderr, "Invalid expression");
182 /*)Function Addr_T term()
184 * The function term() evaluates a single constant
185 * or symbol value prefaced by any unary operator
186 * ( +, -, ~, ', ", >, or < ).
189 * int c current character
190 * char id[] symbol name
191 * int n value of digit in current radix
192 * int r current evaluation radix
193 * sym * sp pointer to a sym structure
194 * Addr_T v evaluation value
197 * char ctype[] array of character types, one per
199 * int lkerr error flag
202 * int digit() lkeval.c
203 * VOID expr() lkeval.c
204 * int fprintf() c_library
206 * VOID getid() lklex.c
207 * int getmap() lklex.c
208 * int getnb() lklex.c
209 * sym * lkpsym() lksym.c
210 * Addr_T symval() lksym.c
211 * VOID unget() lklex.c
214 * An arithmetic term is evaluated by scanning input text.
220 register int c, r, n;
226 if (c == '#') { c = getnb(); }
229 if (getnb() != ')') {
230 fprintf(stderr, "Missing delimiter");
242 return(getmap(-1)&0377);
246 v = (getmap(-1)&0377)<<8;
247 v |= getmap(-1)&0377;
250 v |= (getmap(-1)&0377)<<8;
254 if (c == '>' || c == '<') {
260 if (ctype[c] & DIGIT) {
295 while ((n = digit(c, r)) >= 0) {
302 if (ctype[c] & LETTER) {
304 if ((sp = lkpsym(id, 0)) == NULL) {
305 fprintf(stderr, "Undefined symbol %8s\n", id);
312 /* Shouldn't get here. */
316 /*)Function int digit(c, r)
318 * int c digit character
319 * int r current radix
321 * The function digit() returns the value of c
322 * in the current radix r. If the c value is not
323 * a number of the current radix then a -1 is returned.
329 * char ctype[] array of character types, one per
344 if (ctype[c] & RAD16) {
345 if (c >= 'A' && c <= 'F')
346 return (c - 'A' + 10);
347 if (c >= 'a' && c <= 'f')
348 return (c - 'a' + 10);
353 if (ctype[c] & RAD10)
367 /*)Function int oprio(c)
369 * int c operator character
371 * The function oprio() returns a relative priority
372 * for all valid unary and binary operators.
391 if (c == '*' || c == '/' || c == '%')
393 if (c == '+' || c == '-')
395 if (c == '<' || c == '>')