4 * (C) Copyright 1989-1995
19 * The module lkeval.c contains the routines to evaluate
20 * arithmetic/numerical expressions. The functions in
21 * lkeval.c perform a recursive evaluation of the arithmetic
22 * expression read from the input text line.
23 * The expression may include binary/unary operators, brackets,
24 * symbols, labels, and constants in hexadecimal, decimal, octal
25 * and binary. Arithmetic operations are prioritized and
26 * evaluated by normal arithmetic conventions.
28 * lkeval.c contains the following functions:
35 * lkeval.c contains no local/static variables
38 /*)Function addr_t eval()
40 * The function eval() evaluates a character string to a
44 * int c character from input string
45 * int v value of character in current radix
46 * addr_t n evaluation value
49 * int radix current number conversion radix
52 * int digit() lkeval.c
54 * char getnb() lklex.c
55 * VOID unget() lklex.c
58 * Input test is scanned and evaluated to a
70 while ((v = digit(c, radix)) >= 0) {
78 /*)Function addr_t expr(n)
80 * int n a firewall priority; all top
81 * level calls (from the user)
82 * should be made with n set to 0.
84 * The function expr() evaluates an expression and
88 * int c current input text character
89 * int p current operator priority
90 * addr_t v value returned by term()
91 * addr_t ve value returned by a
92 * recursive call to expr()
95 * char ctype[] array of character types, one per
97 * int lkerr error flag
98 * FILE * stderr c_library
101 * VOID expr() lkeval.c
102 * int fprintf() c_library
103 * int getnb() lklex.c
104 * int oprio() lkeval.c
105 * VOID term() lkeval.c
106 * VOID unget() lklex.c
110 * An expression is evaluated by scanning the input
118 register addr_t v, ve;
121 while (ctype[c = getnb()] & BINOP) {
122 if ((p = oprio(c)) <= n)
124 if ((c == '>' || c == '<') && c != get()) {
125 fprintf(stderr, "Invalid expression");
176 /*)Function addr_t term()
178 * The function term() evaluates a single constant
179 * or symbol value prefaced by any unary operator
180 * ( +, -, ~, ', ", >, or < ).
183 * int c current character
184 * char id[] symbol name
185 * int n value of digit in current radix
186 * int r current evaluation radix
187 * sym * sp pointer to a sym structure
188 * addr_t v evaluation value
191 * char ctype[] array of character types, one per
193 * int lkerr error flag
196 * int digit() lkeval.c
197 * VOID expr() lkeval.c
198 * int fprintf() c_library
200 * VOID getid() lklex.c
201 * int getmap() lklex.c
202 * int getnb() lklex.c
203 * sym * lkpsym() lksym.c
204 * addr_t symval() lksym.c
205 * VOID unget() lklex.c
208 * An arithmetic term is evaluated by scanning input text.
220 if (c == '#') { c = getnb(); }
223 if (getnb() != ')') {
224 fprintf(stderr, "Missing delimiter");
236 return(getmap(-1)&0377);
240 v = (getmap(-1)&0377)<<8;
241 v |= getmap(-1)&0377;
244 v |= (getmap(-1)&0377)<<8;
248 if (c == '>' || c == '<') {
254 if (ctype[c] & DIGIT) {
289 while ((n = digit(c, r)) >= 0) {
296 if (ctype[c] & LETTER) {
298 if ((sp = lkpsym(id, 0)) == NULL) {
299 fprintf(stderr, "Undefined symbol %8s\n", id);
308 /*)Function int digit(c, r)
310 * int c digit character
311 * int r current radix
313 * The function digit() returns the value of c
314 * in the current radix r. If the c value is not
315 * a number of the current radix then a -1 is returned.
321 * char ctype[] array of character types, one per
336 if (ctype[c] & RAD16) {
337 if (c >= 'A' && c <= 'F')
338 return (c - 'A' + 10);
339 if (c >= 'a' && c <= 'f')
340 return (c - 'a' + 10);
345 if (ctype[c] & RAD10)
359 /*)Function int oprio(c)
361 * int c operator character
363 * The function oprio() returns a relative priority
364 * for all valid unary and binary operators.
383 if (c == '*' || c == '/' || c == '%')
385 if (c == '+' || c == '-')
387 if (c == '<' || c == '>')