88 |
|
|
89 |
|
extern char *savestr(), *emalloc(); |
90 |
|
|
91 |
– |
extern LIBR *liblookup(); |
92 |
– |
|
91 |
|
extern VARDEF *argf(); |
92 |
|
|
93 |
|
#ifdef VARIABLE |
155 |
|
{ |
156 |
|
register LIBR *lp; |
157 |
|
|
158 |
< |
if ((lp = liblookup(fname)) == NULL) { |
158 |
> |
if ((lp = liblookup(fname)) == NULL) { /* insert */ |
159 |
|
if (libsize >= MAXLIB) { |
160 |
|
eputs("Too many library functons!\n"); |
161 |
|
quit(1); |
170 |
|
break; |
171 |
|
libsize++; |
172 |
|
} |
173 |
< |
lp[0].fname = fname; /* must be static! */ |
174 |
< |
lp[0].nargs = nargs; |
175 |
< |
lp[0].atyp = assign; |
176 |
< |
lp[0].f = fptr; |
173 |
> |
if (fptr == NULL) { /* delete */ |
174 |
> |
while (lp < &library[libsize-1]) { |
175 |
> |
lp[0].fname = lp[1].fname; |
176 |
> |
lp[0].nargs = lp[1].nargs; |
177 |
> |
lp[0].atyp = lp[1].atyp; |
178 |
> |
lp[0].f = lp[1].f; |
179 |
> |
lp++; |
180 |
> |
} |
181 |
> |
libsize--; |
182 |
> |
} else { /* or assign */ |
183 |
> |
lp[0].fname = fname; /* string must be static! */ |
184 |
> |
lp[0].nargs = nargs; |
185 |
> |
lp[0].atyp = assign; |
186 |
> |
lp[0].f = fptr; |
187 |
> |
} |
188 |
> |
libupdate(fname); /* relink library */ |
189 |
|
} |
190 |
|
|
191 |
|
|
210 |
|
register int n; |
211 |
|
{ |
212 |
|
register ACTIVATION *actp = curact; |
213 |
< |
EPNODE *ep; |
213 |
> |
register EPNODE *ep; |
214 |
|
double aval; |
215 |
|
|
216 |
|
if (actp == NULL || --n < 0) { |
337 |
|
|
338 |
|
|
339 |
|
#ifndef VARIABLE |
340 |
+ |
static VARDEF *varlist = NULL; /* our list of dummy variables */ |
341 |
+ |
|
342 |
+ |
|
343 |
|
VARDEF * |
344 |
|
varinsert(vname) /* dummy variable insert */ |
345 |
|
char *vname; |
350 |
|
vp->name = savestr(vname); |
351 |
|
vp->nlinks = 1; |
352 |
|
vp->def = NULL; |
353 |
< |
vp->lib = NULL; |
354 |
< |
vp->next = NULL; |
353 |
> |
vp->lib = liblookup(vname); |
354 |
> |
vp->next = varlist; |
355 |
> |
varlist = vp; |
356 |
|
return(vp); |
357 |
|
} |
358 |
|
|
360 |
|
varfree(vp) /* free dummy variable */ |
361 |
|
register VARDEF *vp; |
362 |
|
{ |
363 |
+ |
register VARDEF *vp2; |
364 |
+ |
|
365 |
+ |
if (vp == varlist) |
366 |
+ |
varlist = vp->next; |
367 |
+ |
else { |
368 |
+ |
for (vp2 = varlist; vp2->next != vp; vp2 = vp2->next) |
369 |
+ |
; |
370 |
+ |
vp2->next = vp->next; |
371 |
+ |
} |
372 |
|
freestr(vp->name); |
373 |
|
efree((char *)vp); |
374 |
|
} |
375 |
+ |
|
376 |
+ |
|
377 |
+ |
libupdate(nm) /* update library */ |
378 |
+ |
char *nm; |
379 |
+ |
{ |
380 |
+ |
register VARDEF *vp; |
381 |
+ |
|
382 |
+ |
for (vp = varlist; vp != NULL; vp = vp->next) |
383 |
+ |
vp->lib = liblookup(vp->name); |
384 |
+ |
} |
385 |
|
#endif |
386 |
|
|
387 |
|
|
394 |
|
static double |
395 |
|
libfunc(fname, vp) /* execute library function */ |
396 |
|
char *fname; |
397 |
< |
register VARDEF *vp; |
397 |
> |
VARDEF *vp; |
398 |
|
{ |
399 |
< |
VARDEF dumdef; |
399 |
> |
register LIBR *lp; |
400 |
|
double d; |
401 |
|
int lasterrno; |
402 |
|
|
403 |
< |
if (vp == NULL) { |
404 |
< |
vp = &dumdef; |
405 |
< |
vp->lib = NULL; |
406 |
< |
} |
407 |
< |
if (((vp->lib == NULL || strcmp(fname, vp->lib->fname)) && |
375 |
< |
(vp->lib = liblookup(fname)) == NULL) || |
376 |
< |
vp->lib->f == NULL) { |
403 |
> |
if (vp != NULL) |
404 |
> |
lp = vp->lib; |
405 |
> |
else |
406 |
> |
lp = liblookup(fname); |
407 |
> |
if (lp == NULL) { |
408 |
|
eputs(fname); |
409 |
|
eputs(": undefined function\n"); |
410 |
|
quit(1); |
411 |
|
} |
412 |
|
lasterrno = errno; |
413 |
|
errno = 0; |
414 |
< |
d = (*vp->lib->f)(vp->lib->fname); |
414 |
> |
d = (*lp->f)(lp->fname); |
415 |
|
#ifdef IEEE |
416 |
< |
if (!finite(d)) |
417 |
< |
errno = EDOM; |
416 |
> |
if (errno == 0) |
417 |
> |
if (isnan(d)) |
418 |
> |
errno = EDOM; |
419 |
> |
else if (isinf(d)) |
420 |
> |
errno = ERANGE; |
421 |
|
#endif |
422 |
|
if (errno) { |
423 |
|
wputs(fname); |
424 |
< |
wputs(": bad call\n"); |
424 |
> |
if (errno == EDOM) |
425 |
> |
wputs(": domain error\n"); |
426 |
> |
else if (errno == ERANGE) |
427 |
> |
wputs(": range error\n"); |
428 |
> |
else |
429 |
> |
wputs(": error in call\n"); |
430 |
|
return(0.0); |
431 |
|
} |
432 |
|
errno = lasterrno; |