rem: s, ncall, ndef WARNING; if (ncall + ndef > NARGS) ERROR "function %s has %d arguments, limit %d", s, ncall+ndef, NARGS FATAL; for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) {	 dprintf( ("evaluate args[%d], fp=%d:\n", i, fp-frame) );
add: s, ncall, ndef WARNING; } if (ncall + ndef > NARGS) { ERROR "function %s has %d arguments, limit %d", s, ncall+ndef, NARGS FATAL; } for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) {  dprintf(("evaluate args[%d], fp=%d:\n", i, fp-frame));
context: Cell *call(a, n) Node **a;{	static Cell newcopycell = { OCELL, CCOPY, 0, (uchar *) "", 0.0, NUM|STR|DONTFREE };	int i, ncall, ndef, freed = 0;	Node *x;	Cell *args[NARGS], *oargs[NARGS], *y, *z, *fcn;	uchar *s;	fcn = execute(a[0]);	/* the function itself */	s = fcn->nval;	if (!isfunc(fcn))		ERROR "calling undefined function %s", s FATAL;	if (frame == NULL) {		fp = frame = (struct Frame *) calloc(nframe += 100, sizeof(struct Frame));		if (frame == NULL)			ERROR "out of space for stack frames calling %s", s FATAL;	}	for (ncall = 0, x = a[1]; x != NULL; x = x->nnext)	/* args in call */		ncall++;	ndef = (int) fcn->fval;			/* args in defn */	dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, fp-frame) );	if (ncall > ndef)		ERROR "function %s called with %d args, uses only %d",			s, ncall, ndef WARNING;	if (ncall + ndef > NARGS)		ERROR "function %s has %d arguments, limit %d", s, ncall+ndef, NARGS FATAL;	for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) {	/* get call args */		dprintf( ("evaluate args[%d], fp=%d:\n", i, fp-frame) );		y = execute(x);		oargs[i] = y;		dprintf( ("args[%d]: %s %f <%s>, t=%o\n",			   i, y->nval, y->fval, isarr(y) ? "(array)" : (char*) y->sval, y->tval) );		if (isfunc(y))			ERROR "can't use function %s as argument in %s", y->nval, s FATAL;		if (isarr(y))			args[i] = y;	/* arrays by ref */		else			args[i] = copycell(y);		tempfree(y, "callargs");	}	for ( ; i < ndef; i++) {	/* add null args for ones not provided */		args[i] = gettemp("nullargs");		*args[i] = newcopycell;	}	fp++;	/* now ok to up frame */	if (fp >= frame + nframe) {		int dfp = fp - frame;	/* old index */		frame = (struct Frame *)			realloc(frame, (nframe += 100) * sizeof(struct Frame));		if (frame == NULL)			ERROR "out of space for stack frames in %s", s FATAL;		fp = frame + dfp;	}	fp->fcncell = fcn;	fp->args = args;	fp->nargs = ndef;	/* number defined with (excess are locals) */	fp->retval = gettemp("retval");	dprintf( ("start exec of %s, fp=%d\n", s, fp-frame) );	y = execute((Node *)(fcn->sval));	/* execute body */	dprintf( ("finished exec of %s, fp=%d\n", s, fp-frame) );	for (i = 0; i < ndef; i++) {		Cell *t = fp->args[i];		if (isarr(t)) {			if (t->csub == CCOPY) {				if (i >= ncall) {					freesymtab(t);					t->csub = CTEMP;				} else {					oargs[i]->tval = t->tval;					oargs[i]->tval &= ~(STR|NUM|DONTFREE);					oargs[i]->sval = t->sval;					tempfree(t, "oargsarr");				}			}		} else {			t->csub = CTEMP;			tempfree(t, "fp->args");			if (t == y) freed = 1;		}	}	tempfree(fcn, "call.fcn");	if (isexit(y) || isnext(y))		return y;	if (!freed) tempfree(y, "fcn ret");	/* should not free twice! */	z = fp->retval;			/* return value */	dprintf( ("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval) );	fp--;	return(z);}