4 * (C) Copyright 1989-1995
18 * The module lkeval.c contains the routines to evaluate
19 * arithmetic/numerical expressions. The functions in
20 * lkeval.c perform a recursive evaluation of the arithmetic
21 * expression read from the input text line.
22 * The expression may include binary/unary operators, brackets,
23 * symbols, labels, and constants in hexadecimal, decimal, octal
24 * and binary. Arithmetic operations are prioritized and
25 * evaluated by normal arithmetic conventions.
27 * lkeval.c contains the following functions:
34 * lkeval.c contains no local/static variables
37 /*)Function Addr_T eval()
39 * The function eval() evaluates a character string to a
43 * int c character from input string
44 * int v value of character in current radix
45 * Addr_T n evaluation value
48 * int radix current number conversion radix
51 * int digit() lkeval.c
53 * char getnb() lklex.c
54 * VOID unget() lklex.c
57 * Input test is scanned and evaluated to a
69 while ((v = digit(c, radix)) >= 0) {
77 /*)Function Addr_T expr(n)
79 * int n a firewall priority; all top
80 * level calls (from the user)
81 * should be made with n set to 0.
83 * The function expr() evaluates an expression and
87 * int c current input text character
88 * int p current operator priority
89 * Addr_T v value returned by term()
90 * Addr_T ve value returned by a
91 * recursive call to expr()
94 * char ctype[] array of character types, one per
96 * int lkerr error flag
97 * FILE * stderr c_library
100 * VOID expr() lkeval.c
101 * int fprintf() c_library
102 * int getnb() lklex.c
103 * int oprio() lkeval.c
104 * VOID term() lkeval.c
105 * VOID unget() lklex.c
109 * An expression is evaluated by scanning the input
117 register Addr_T v, ve;
120 while (ctype[c = getnb()] & BINOP) {
121 if ((p = oprio(c)) <= n)
123 if ((c == '>' || c == '<') && c != get()) {
124 fprintf(stderr, "Invalid expression");
175 /*)Function Addr_T term()
177 * The function term() evaluates a single constant
178 * or symbol value prefaced by any unary operator
179 * ( +, -, ~, ', ", >, or < ).
182 * int c current character
183 * char id[] symbol name
184 * int n value of digit in current radix
185 * int r current evaluation radix
186 * sym * sp pointer to a sym structure
187 * Addr_T v evaluation value
190 * char ctype[] array of character types, one per
192 * int lkerr error flag
195 * int digit() lkeval.c
196 * VOID expr() lkeval.c
197 * int fprintf() c_library
199 * VOID getid() lklex.c
200 * int getmap() lklex.c
201 * int getnb() lklex.c
202 * sym * lkpsym() lksym.c
203 * Addr_T symval() lksym.c
204 * VOID unget() lklex.c
207 * An arithmetic term is evaluated by scanning input text.
213 register int c, r, n;
219 if (c == '#') { c = getnb(); }
222 if (getnb() != ')') {
223 fprintf(stderr, "Missing delimiter");
235 return(getmap(-1)&0377);
239 v = (getmap(-1)&0377)<<8;
240 v |= getmap(-1)&0377;
243 v |= (getmap(-1)&0377)<<8;
247 if (c == '>' || c == '<') {
253 if (ctype[c] & DIGIT) {
288 while ((n = digit(c, r)) >= 0) {
295 if (ctype[c] & LETTER) {
297 if ((sp = lkpsym(id, 0)) == NULL) {
298 fprintf(stderr, "Undefined symbol %8s\n", id);
305 /* Shouldn't get here. */
309 /*)Function int digit(c, r)
311 * int c digit character
312 * int r current radix
314 * The function digit() returns the value of c
315 * in the current radix r. If the c value is not
316 * a number of the current radix then a -1 is returned.
322 * char ctype[] array of character types, one per
337 if (ctype[c] & RAD16) {
338 if (c >= 'A' && c <= 'F')
339 return (c - 'A' + 10);
340 if (c >= 'a' && c <= 'f')
341 return (c - 'a' + 10);
346 if (ctype[c] & RAD10)
360 /*)Function int oprio(c)
362 * int c operator character
364 * The function oprio() returns a relative priority
365 * for all valid unary and binary operators.
384 if (c == '*' || c == '/' || c == '%')
386 if (c == '+' || c == '-')
388 if (c == '<' || c == '>')