26 |
|
#include <math.h> |
27 |
|
#include <stdlib.h> |
28 |
|
|
29 |
+ |
#include "rtmisc.h" |
30 |
+ |
#include "rtio.h" |
31 |
|
#include "rterror.h" |
32 |
|
#include "calcomp.h" |
33 |
|
|
47 |
|
unsigned int esupport = /* what to support */ |
48 |
|
E_VARIABLE | E_FUNCTION ; |
49 |
|
|
50 |
+ |
int eofc = 0; /* optional end-of-file character */ |
51 |
|
int nextc; /* lookahead character */ |
52 |
|
|
53 |
< |
double (*eoper[])() = { /* expression operations */ |
53 |
> |
double (*eoper[])(EPNODE *) = { /* expression operations */ |
54 |
|
ebotch, |
55 |
|
evariable, |
56 |
|
enumber, |
85 |
|
|
86 |
|
|
87 |
|
EPNODE * |
88 |
< |
eparse(expr) /* parse an expression string */ |
89 |
< |
char *expr; |
88 |
> |
eparse( /* parse an expression string */ |
89 |
> |
char *expr |
90 |
> |
) |
91 |
|
{ |
92 |
|
EPNODE *ep; |
93 |
|
|
101 |
|
|
102 |
|
|
103 |
|
double |
104 |
< |
eval(expr) /* evaluate an expression string */ |
105 |
< |
char *expr; |
104 |
> |
eval( /* evaluate an expression string */ |
105 |
> |
char *expr |
106 |
> |
) |
107 |
|
{ |
108 |
|
register EPNODE *ep; |
109 |
|
double rval; |
116 |
|
|
117 |
|
|
118 |
|
int |
119 |
< |
epcmp(ep1, ep2) /* compare two expressions for equivalence */ |
120 |
< |
register EPNODE *ep1, *ep2; |
119 |
> |
epcmp( /* compare two expressions for equivalence */ |
120 |
> |
register EPNODE *ep1, |
121 |
> |
register EPNODE *ep2 |
122 |
> |
) |
123 |
|
{ |
124 |
|
double d; |
125 |
|
|
135 |
|
if (ep2->v.num == 0) |
136 |
|
return(ep1->v.num != 0); |
137 |
|
d = ep1->v.num / ep2->v.num; |
138 |
< |
return(d > 1.000000000001 | d < 0.999999999999); |
138 |
> |
return((d > 1.000000000001) | (d < 0.999999999999)); |
139 |
|
|
140 |
|
case CHAN: |
141 |
|
case ARG: |
166 |
|
|
167 |
|
|
168 |
|
void |
169 |
< |
epfree(epar) /* free a parse tree */ |
170 |
< |
register EPNODE *epar; |
169 |
> |
epfree( /* free a parse tree */ |
170 |
> |
register EPNODE *epar |
171 |
> |
) |
172 |
|
{ |
173 |
|
register EPNODE *ep; |
174 |
|
|
202 |
|
|
203 |
|
/* the following used to be a switch */ |
204 |
|
static double |
205 |
< |
eargument(ep) |
206 |
< |
EPNODE *ep; |
205 |
> |
eargument( |
206 |
> |
EPNODE *ep |
207 |
> |
) |
208 |
|
{ |
209 |
|
return(argument(ep->v.chan)); |
210 |
|
} |
211 |
|
|
212 |
|
static double |
213 |
< |
enumber(ep) |
214 |
< |
EPNODE *ep; |
213 |
> |
enumber( |
214 |
> |
EPNODE *ep |
215 |
> |
) |
216 |
|
{ |
217 |
|
return(ep->v.num); |
218 |
|
} |
219 |
|
|
220 |
|
static double |
221 |
< |
euminus(ep) |
222 |
< |
EPNODE *ep; |
221 |
> |
euminus( |
222 |
> |
EPNODE *ep |
223 |
> |
) |
224 |
|
{ |
225 |
|
register EPNODE *ep1 = ep->v.kid; |
226 |
|
|
228 |
|
} |
229 |
|
|
230 |
|
static double |
231 |
< |
echannel(ep) |
232 |
< |
EPNODE *ep; |
231 |
> |
echannel( |
232 |
> |
EPNODE *ep |
233 |
> |
) |
234 |
|
{ |
235 |
|
return(chanvalue(ep->v.chan)); |
236 |
|
} |
237 |
|
|
238 |
|
static double |
239 |
< |
eadd(ep) |
240 |
< |
EPNODE *ep; |
239 |
> |
eadd( |
240 |
> |
EPNODE *ep |
241 |
> |
) |
242 |
|
{ |
243 |
|
register EPNODE *ep1 = ep->v.kid; |
244 |
|
|
246 |
|
} |
247 |
|
|
248 |
|
static double |
249 |
< |
esubtr(ep) |
250 |
< |
EPNODE *ep; |
249 |
> |
esubtr( |
250 |
> |
EPNODE *ep |
251 |
> |
) |
252 |
|
{ |
253 |
|
register EPNODE *ep1 = ep->v.kid; |
254 |
|
|
256 |
|
} |
257 |
|
|
258 |
|
static double |
259 |
< |
emult(ep) |
260 |
< |
EPNODE *ep; |
259 |
> |
emult( |
260 |
> |
EPNODE *ep |
261 |
> |
) |
262 |
|
{ |
263 |
|
register EPNODE *ep1 = ep->v.kid; |
264 |
|
|
266 |
|
} |
267 |
|
|
268 |
|
static double |
269 |
< |
edivi(ep) |
270 |
< |
EPNODE *ep; |
269 |
> |
edivi( |
270 |
> |
EPNODE *ep |
271 |
> |
) |
272 |
|
{ |
273 |
|
register EPNODE *ep1 = ep->v.kid; |
274 |
|
double d; |
283 |
|
} |
284 |
|
|
285 |
|
static double |
286 |
< |
epow(ep) |
287 |
< |
EPNODE *ep; |
286 |
> |
epow( |
287 |
> |
EPNODE *ep |
288 |
> |
) |
289 |
|
{ |
290 |
|
register EPNODE *ep1 = ep->v.kid; |
291 |
|
double d; |
307 |
|
} |
308 |
|
|
309 |
|
static double |
310 |
< |
ebotch(ep) |
311 |
< |
EPNODE *ep; |
310 |
> |
ebotch( |
311 |
> |
EPNODE *ep |
312 |
> |
) |
313 |
|
{ |
314 |
|
eputs("Bad expression!\n"); |
315 |
|
quit(1); |
318 |
|
|
319 |
|
|
320 |
|
EPNODE * |
321 |
< |
ekid(ep, n) /* return pointer to a node's nth kid */ |
322 |
< |
register EPNODE *ep; |
323 |
< |
register int n; |
321 |
> |
ekid( /* return pointer to a node's nth kid */ |
322 |
> |
register EPNODE *ep, |
323 |
> |
register int n |
324 |
> |
) |
325 |
|
{ |
326 |
|
|
327 |
|
for (ep = ep->v.kid; ep != NULL; ep = ep->sibling) |
333 |
|
|
334 |
|
|
335 |
|
int |
336 |
< |
nekids(ep) /* return # of kids for node ep */ |
337 |
< |
register EPNODE *ep; |
336 |
> |
nekids( /* return # of kids for node ep */ |
337 |
> |
register EPNODE *ep |
338 |
> |
) |
339 |
|
{ |
340 |
|
register int n = 0; |
341 |
|
|
347 |
|
|
348 |
|
|
349 |
|
void |
350 |
< |
initfile(fp, fn, ln) /* prepare input file */ |
351 |
< |
FILE *fp; |
352 |
< |
char *fn; |
353 |
< |
int ln; |
350 |
> |
initfile( /* prepare input file */ |
351 |
> |
FILE *fp, |
352 |
> |
char *fn, |
353 |
> |
int ln |
354 |
> |
) |
355 |
|
{ |
356 |
|
static char inpbuf[MAXLINE]; |
357 |
|
|
366 |
|
|
367 |
|
|
368 |
|
void |
369 |
< |
initstr(s, fn, ln) /* prepare input string */ |
370 |
< |
char *s; |
371 |
< |
char *fn; |
372 |
< |
int ln; |
369 |
> |
initstr( /* prepare input string */ |
370 |
> |
char *s, |
371 |
> |
char *fn, |
372 |
> |
int ln |
373 |
> |
) |
374 |
|
{ |
375 |
|
infp = NULL; |
376 |
|
infile = fn; |
382 |
|
|
383 |
|
|
384 |
|
void |
385 |
< |
getscanpos(fnp, lnp, spp, fpp) /* return current scan position */ |
386 |
< |
char **fnp; |
387 |
< |
int *lnp; |
388 |
< |
char **spp; |
389 |
< |
FILE **fpp; |
385 |
> |
getscanpos( /* return current scan position */ |
386 |
> |
char **fnp, |
387 |
> |
int *lnp, |
388 |
> |
char **spp, |
389 |
> |
FILE **fpp |
390 |
> |
) |
391 |
|
{ |
392 |
|
if (fnp != NULL) *fnp = infile; |
393 |
|
if (lnp != NULL) *lnp = lineno; |
397 |
|
|
398 |
|
|
399 |
|
int |
400 |
< |
scan() /* scan next character, return literal next */ |
400 |
> |
scan(void) /* scan next character, return literal next */ |
401 |
|
{ |
402 |
|
register int lnext = 0; |
403 |
|
|
414 |
|
nextc = linbuf[linepos++]; |
415 |
|
if (!lnext) |
416 |
|
lnext = nextc; |
417 |
+ |
if (nextc == eofc) { |
418 |
+ |
nextc = EOF; |
419 |
+ |
break; |
420 |
+ |
} |
421 |
|
if (nextc == '{') { |
422 |
|
scan(); |
423 |
|
while (nextc != '}') |
433 |
|
|
434 |
|
|
435 |
|
char * |
436 |
< |
long2ascii(l) /* convert long to ascii */ |
437 |
< |
long l; |
436 |
> |
long2ascii( /* convert long to ascii */ |
437 |
> |
long l |
438 |
> |
) |
439 |
|
{ |
440 |
|
static char buf[16]; |
441 |
|
register char *cp; |
460 |
|
|
461 |
|
|
462 |
|
void |
463 |
< |
syntax(err) /* report syntax error and quit */ |
464 |
< |
char *err; |
463 |
> |
syntax( /* report syntax error and quit */ |
464 |
> |
char *err |
465 |
> |
) |
466 |
|
{ |
467 |
|
register int i; |
468 |
|
|
487 |
|
|
488 |
|
|
489 |
|
void |
490 |
< |
addekid(ep, ekid) /* add a child to ep */ |
491 |
< |
register EPNODE *ep; |
492 |
< |
EPNODE *ekid; |
490 |
> |
addekid( /* add a child to ep */ |
491 |
> |
register EPNODE *ep, |
492 |
> |
EPNODE *ekid |
493 |
> |
) |
494 |
|
{ |
495 |
|
if (ep->v.kid == NULL) |
496 |
|
ep->v.kid = ekid; |
504 |
|
|
505 |
|
|
506 |
|
char * |
507 |
< |
getname() /* scan an identifier */ |
507 |
> |
getname(void) /* scan an identifier */ |
508 |
|
{ |
509 |
|
static char str[RMAXWORD+1]; |
510 |
|
register int i, lnext; |
521 |
|
|
522 |
|
|
523 |
|
int |
524 |
< |
getinum() /* scan a positive integer */ |
524 |
> |
getinum(void) /* scan a positive integer */ |
525 |
|
{ |
526 |
|
register int n, lnext; |
527 |
|
|
536 |
|
|
537 |
|
|
538 |
|
double |
539 |
< |
getnum() /* scan a positive float */ |
539 |
> |
getnum(void) /* scan a positive float */ |
540 |
|
{ |
541 |
|
register int i, lnext; |
542 |
|
char str[RMAXWORD+1]; |
557 |
|
lnext = scan(); |
558 |
|
} |
559 |
|
} |
560 |
< |
if ((lnext == 'e' | lnext == 'E') && i < RMAXWORD) { |
560 |
> |
if ((lnext == 'e') | (lnext == 'E') && i < RMAXWORD) { |
561 |
|
str[i++] = lnext; |
562 |
|
lnext = scan(); |
563 |
< |
if ((lnext == '-' | lnext == '+') && i < RMAXWORD) { |
563 |
> |
if ((lnext == '-') | (lnext == '+') && i < RMAXWORD) { |
564 |
|
str[i++] = lnext; |
565 |
|
lnext = scan(); |
566 |
|
} |
578 |
|
|
579 |
|
|
580 |
|
EPNODE * |
581 |
< |
getE1() /* E1 -> E1 ADDOP E2 */ |
581 |
> |
getE1(void) /* E1 -> E1 ADDOP E2 */ |
582 |
|
/* E2 */ |
583 |
|
{ |
584 |
|
register EPNODE *ep1, *ep2; |
600 |
|
|
601 |
|
|
602 |
|
EPNODE * |
603 |
< |
getE2() /* E2 -> E2 MULOP E3 */ |
603 |
> |
getE2(void) /* E2 -> E2 MULOP E3 */ |
604 |
|
/* E3 */ |
605 |
|
{ |
606 |
|
register EPNODE *ep1, *ep2; |
622 |
|
|
623 |
|
|
624 |
|
EPNODE * |
625 |
< |
getE3() /* E3 -> E4 ^ E3 */ |
625 |
> |
getE3(void) /* E3 -> E4 ^ E3 */ |
626 |
|
/* E4 */ |
627 |
|
{ |
628 |
|
register EPNODE *ep1, *ep2; |
644 |
|
|
645 |
|
|
646 |
|
EPNODE * |
647 |
< |
getE4() /* E4 -> ADDOP E5 */ |
647 |
> |
getE4(void) /* E4 -> ADDOP E5 */ |
648 |
|
/* E5 */ |
649 |
|
{ |
650 |
|
register EPNODE *ep1, *ep2; |
672 |
|
|
673 |
|
|
674 |
|
EPNODE * |
675 |
< |
getE5() /* E5 -> (E1) */ |
675 |
> |
getE5(void) /* E5 -> (E1) */ |
676 |
|
/* VAR */ |
677 |
|
/* NUM */ |
678 |
|
/* $N */ |
750 |
|
|
751 |
|
|
752 |
|
EPNODE * |
753 |
< |
rconst(epar) /* reduce a constant expression */ |
754 |
< |
register EPNODE *epar; |
753 |
> |
rconst( /* reduce a constant expression */ |
754 |
> |
register EPNODE *epar |
755 |
> |
) |
756 |
|
{ |
757 |
|
register EPNODE *ep; |
758 |
|
|
769 |
|
|
770 |
|
|
771 |
|
int |
772 |
< |
isconstvar(ep) /* is ep linked to a constant expression? */ |
773 |
< |
register EPNODE *ep; |
772 |
> |
isconstvar( /* is ep linked to a constant expression? */ |
773 |
> |
register EPNODE *ep |
774 |
> |
) |
775 |
|
{ |
776 |
|
register EPNODE *ep1; |
777 |
|
|
795 |
|
|
796 |
|
|
797 |
|
int |
798 |
< |
isconstfun(ep) /* is ep linked to a constant function? */ |
799 |
< |
register EPNODE *ep; |
798 |
> |
isconstfun( /* is ep linked to a constant function? */ |
799 |
> |
register EPNODE *ep |
800 |
> |
) |
801 |
|
{ |
802 |
|
register EPNODE *dp; |
803 |
|
register LIBR *lp; |
804 |
|
|
805 |
|
if (ep->type != VAR) |
806 |
|
return(0); |
807 |
< |
if ((dp = ep->v.ln->def) != NULL) |
807 |
> |
if ((dp = ep->v.ln->def) != NULL) { |
808 |
|
if (dp->v.kid->type == FUNC) |
809 |
|
return(dp->type == ':'); |
810 |
|
else |
811 |
|
return(0); /* don't identify masked library functions */ |
812 |
+ |
} |
813 |
|
if ((lp = ep->v.ln->lib) != NULL) |
814 |
|
return(lp->atyp == ':'); |
815 |
|
return(0); |