|
|
1.1 root 1: #include "global.h"
2: /************************************************************************/
3: /* */
4: /* file: eval.i */
5: /* contents: evaluator and namestack maintenance routines */
6: /* */
7: /************************************************************************/
8:
9:
10: /* eval *****************************************************************/
11: /* returns the value of the pointer passed as the argument. */
12:
13: lispval
14: eval(actarg)
15: lispval actarg;
16: {
17: #define argptr handy
18: register lispval a = actarg;
19: register lispval handy;
20: register struct nament *namptr;
21: register struct argent *workp;
22: register struct argent *lbot;
23: register struct argent *np;
24: struct argent *poplbot;
25: struct nament *oldbnp = bnp;
26: lispval Ifcall(), Iarray();
27:
28: /*debugging
29: printf("Eval:");
30: printr(a,stdout);
31: fflush(stdout); */
32: switch (TYPE(a))
33: {
34: case ATOM:
35: handy = a->clb;
36: if(handy==CNIL) {
37: handy = errorh(Vermisc,"Unbound Variable:",nil,TRUE,0,a);
38: }
39: return(handy);
40:
41: case VALUE:
42: return(a->l);
43:
44: case DTPR:
45: (np++)->val = a; /* push form on namestack */
46: lbot = np; /* define beginning of argstack */
47: oldbnp = bnp; /* remember start of bind stack */
48: a = a->car; /* function name or lambda-expr */
49: for(EVER)
50: {
51: switch(TYPE(a))
52: {
53: case ATOM:
54: /* get function binding */
55: if(a->fnbnd==nil && a->clb!=nil) {
56: a=a->clb;
57: if(TYPE(a)==ATOM)
58: a=a->fnbnd;
59: } else
60: a = a->fnbnd;
61: break;
62: case VALUE:
63: a = a->l; /* get value */
64: break;
65: }
66:
67: vtemp = (CNIL-1); /* sentinel value for error test */
68:
69: funcal: switch (TYPE(a))
70: {
71: case BCD: /* function */
72: argptr = actarg->cdr;
73:
74: /* decide whether lambda, nlambda or
75: macro and push args onto argstack
76: accordingly. */
77:
78: if(a->discipline==nlambda) {
79: (np++)->val = argptr;
80: TNP;
81: }else if(a->discipline==macro) {
82: (np++)->val = actarg;
83: TNP;
84: } else for(;argptr!=nil; argptr = argptr->cdr) {
85: (np++)->val = eval(argptr->car);
86: TNP;
87: }
88: /* go for it */
89:
90: if(TYPE(a->discipline)==INT)
91: vtemp = Ifcall(a);
92: else
93: vtemp = (*(lispval (*)())(a->entry))();
94: break;
95:
96: case ARRAY:
97: vtemp = Iarray(a,actarg->cdr);
98: break;
99:
100:
101: case DTPR:
102: /* push args on argstack according to
103: type */
104:
105: argptr = a->car;
106: if (argptr==lambda) {
107: for(argptr = actarg->cdr;
108: argptr!=nil; argptr=argptr->cdr) {
109:
110: (np++)->val = eval(argptr->car);
111: TNP;
112: }
113: } else if (argptr==nlambda) {
114: (np++)->val = actarg->cdr;
115: TNP;
116: } else if(argptr==macro) {
117: (np++)->val = actarg;
118: TNP;
119: } else if(argptr==lexpr) {
120: for(argptr = actarg->cdr;
121: argptr!=nil; argptr=argptr->cdr) {
122:
123: (np++)->val = eval(argptr->car);
124: TNP;
125: }
126: handy = newdot();
127: handy->car = (lispval)lbot;
128: handy->cdr = (lispval)np;
129: PUSHDOWN(lexpr_atom,handy);
130: lbot = np;
131: (np++)->val = inewint(((lispval *)handy->cdr) - (lispval *)handy->car);
132:
133: } else break; /* something is wrong - this isn't a proper function */
134:
135: argptr = (a->cdr)->car;
136: namptr = bnp;
137: workp = lbot;
138: if(bnp + (np - lbot)> bnplim)
139: binderr();
140: for(;argptr != (lispval)nil;
141: workp++,argptr = argptr->cdr) /* rebind formal names (shallow) */
142: {
143: if(argptr->car==nil)
144: continue;
145: /*if(((namptr)->atm = argptr->car)==nil)
146: error("Attempt to lambda bind nil",FALSE);*/
147: namptr->atm = argptr->car;
148: if (workp < np) {
149: namptr->val = namptr->atm->clb;
150: namptr->atm->clb = workp->val;
151: } else
152: bnp = namptr,
153: error("Too few actual parameters",FALSE);
154: namptr++;
155: }
156: bnp = namptr;
157: if (workp < np)
158: error("Too many actual parameters",FALSE);
159:
160: /* execute body, implied prog allowed */
161:
162: for (handy = a->cdr->cdr;
163: handy != nil;
164: handy = handy->cdr) {
165: vtemp = eval(handy->car);
166: }
167: }
168: if (vtemp != (CNIL-1))
169: /* if we get here with a believable value, */
170: /* we must have executed a function. */
171: {
172: popnames(oldbnp);
173:
174: /* in case some clown trashed t */
175:
176: tatom->clb = (lispval) tatom;
177: if(a->car==macro) return(eval(vtemp));
178: /* It is of the most wonderful
179: coincidence that the offset
180: for car is the same as for
181: discipline so we get bcd macros
182: for free here ! */
183: else return(vtemp);
184: }
185: popnames(oldbnp);
186: a = (lispval) errorh(Vermisc,"BAD FUNCTION",nil,TRUE,0,actarg);
187: }
188:
189: }
190: return(a); /* other data types are considered constants */
191: }
192:
193:
194:
195:
196: /* popnames *************************************************************/
197: /* removes from the name stack all entries above the first argument. */
198: /* routine should usually be used to clean up the name stack as it */
199: /* knows about the special cases. np is returned pointing to the */
200: /* same place as the argument passed. */
201: lispval
202: popnames(llimit)
203: register struct nament *llimit;
204: {
205: register struct nament *rnp;
206:
207: for(rnp = bnp - 1; rnp >= llimit; rnp--)
208: rnp->atm->clb = rnp->val;
209: bnp = llimit;
210: }
211:
212:
213: /************************************************************************/
214: /* */
215: /* file: apply.c */
216: /* Caveat -- Work in Progress -- not guaranteed! not tested!
217: /* */
218: /* apply ***************************************************************/
219: lispval
220: Lapply()
221: {
222: register lispval a;
223: register lispval handy;
224: register struct argent *workp;
225: register struct nament *namptr;
226: register struct argent *lbot;
227: register struct argent *np;
228: lispval vtemp;
229: struct nament *oldbnp = bnp;
230: struct argent *oldlbot = lbot; /* Bottom of my frame! */
231:
232: a = lbot->val;
233: argptr = lbot[1].val;
234: if(np-lbot!=2)
235: errorh(Vermisc,"Apply: Wrong number of args.",nil,FALSE,
236: 999,a,argptr);
237: if(TYPE(argptr)!=DTPR && argptr!=nil)
238: argptr = errorh(Vermisc,"Apply: non-list of args",nil,TRUE,
239: 998,argptr);
240: (np++)->val = a; /* push form on namestack */
241: TNP;
242: lbot = np; /* bottom of current frame */
243: for(EVER)
244: {
245: if (TYPE(a) == ATOM) a = a->fnbnd;
246: /* get function defn (unless calling form */
247: /* is itself a lambda-expr) */
248: vtemp = CNIL; /* sentinel value for error test */
249: switch (TYPE(a))
250: {
251: case BCD: /* printf("BCD\n");*/
252: /* push arguments - value of a */
253: if(a->discipline==nlambda || a->discipline==macro) {
254: (np++)->val=argptr;
255: TNP;
256: } else for (; argptr!=nil; argptr = argptr->cdr) {
257: (np++)->val=argptr->car;
258: TNP;
259: }
260:
261: vtemp = (*(lispval (*)())(a->entry))(); /* go for it */
262: break;
263:
264: case ARRAY:
265: vtemp = Iarray(a,argptr);
266: break;
267:
268:
269: case DTPR:
270: if (a->car==nlambda || a->car==macro) {
271: (np++)->val = argptr;
272: TNP;
273: } else if (a->car==lambda)
274: for (; argptr!=nil; argptr = argptr->cdr) {
275: (np++)->val = argptr->car;
276: TNP;
277: }
278: else if(a->car==lexpr) {
279: for (; argptr!=nil; argptr = argptr->cdr) {
280:
281: (np++)->val = argptr->car;
282: TNP;
283: }
284: handy = newdot();
285: handy->car = (lispval)lbot;
286: handy->cdr = (lispval)np;
287: PUSHDOWN(lexpr_atom,handy);
288: lbot = np;
289: (np++)->val = inewint(((lispval *)handy->cdr) - (lispval *)handy->car);
290:
291: } else break; /* something is wrong - this isn't a proper function */
292: rebind(a->cdr->car,lbot);
293: np = lbot;
294: for (handy = a->cdr->cdr;
295: handy != nil;
296: handy = handy->cdr) {
297: vtemp = eval(handy->car); /* go for it */
298: }
299: }
300: if (vtemp != CNIL)
301: /* if we get here with a believable value, */
302: /* we must have executed a function. */
303: {
304: popnames(oldbnp);
305:
306: /* in case some clown trashed t */
307:
308: tatom->clb = (lispval) tatom;
309: return(vtemp);
310: }
311: popnames(oldbnp);
312: printr(oldlbot->val,stdout);
313: a = (lispval) error("BAD FUNCTION",TRUE);
314: }
315: /*NOT REACHED*/
316: }
317:
318:
319: /*
320: * Rebind -- rebind formal names
321: */
322: rebind(argptr,workp)
323: register lispval argptr; /* argptr points to list of atoms */
324: register struct argent * workp; /* workp points to position on stack
325: where evaluated args begin */
326: {
327: register lispval vtemp;
328: register struct nament *namptr = bnp;
329: register struct argent *lbot;
330: register struct argent *np;
331:
332: for(;argptr != (lispval)nil;
333: workp++,argptr = argptr->cdr) /* rebind formal names (shallow) */
334: {
335: if(argptr->car==nil)
336: continue;
337: namptr->atm = argptr->car;
338: if (workp < np) {
339: namptr->val = namptr->atm->clb;
340: namptr->atm->clb = workp->val;
341: } else
342: bnp = namptr,
343: error("Too few actual parameters",FALSE);
344: namptr++;
345: if(namptr > bnplim)
346: binderr();
347: }
348: bnp = namptr;
349: if (workp < np)
350: error("Too many actual parameters",FALSE);
351: }
352:
353: lispval
354: Lfuncal()
355: {
356: register lispval a;
357: register lispval handy;
358: register struct argent *oldlbot;
359: register struct nament **namptr;
360: register struct argent *lbot;
361: register struct argent *np;
362:
363: lispval Ifcall(),Llist(),Iarray();
364: lispval vtemp;
365: struct nament *oldbnp = bnp;
366: int typ;
367: extern lispval end[];
368:
369: /*debugging stufff
370: printf("In funcal: ");
371: printr(lbot->val,stdout);
372: fflush(stdout);
373: printf("\n"); */
374:
375: oldlbot = lbot; /* bottom of my namestack frame */
376: a = lbot->val; /* function I am evaling. */
377: lbot++;
378:
379: for(EVER)
380: {
381: typ = TYPE(a);
382: if (typ == ATOM) a = a->fnbnd, typ = TYPE(a);
383:
384: /* get function defn (unless calling form */
385: /* is itself a lambda-expr) */
386: vtemp = CNIL; /* sentinel value for error test */
387: switch (typ) {
388: case ARRAY:
389: vtemp = Iarray(a,Llist());
390: break;
391: case BCD:
392: if(a->discipline==nlambda)
393: { if(np==lbot) protect(nil); /* default is nil */
394: while(np-lbot!=1 || (lbot->val != nil &&
395: TYPE(lbot->val)!=DTPR)) {
396: lbot->val = error("Bad funcall arg(s) to fexpr.",TRUE);
397: np = lbot+1;
398: }
399: }
400: /* go for it */
401:
402: if(TYPE(a->discipline)==INT)
403: vtemp = Ifcall(a);
404: else
405: vtemp = (*(lispval (*)())(a->entry))();
406: if(a->discipline==macro)
407: vtemp = eval(vtemp);
408: break;
409:
410:
411: case DTPR:
412: if (a->car == lambda) {
413: ;/* VOID */
414: } else if (a->car == nlambda || a->car==macro) {
415: if( np==lbot ) protect(nil); /* default */
416: while(np-lbot!=1 || (lbot->val != nil &&
417: TYPE(lbot->val)!=DTPR)) {
418: lbot->val = error("Bad funcall arg(s) to fexpr.",TRUE);
419: np = lbot+1;
420: }
421: } else if (a->car == lexpr) {
422: handy = newdot();
423: handy->car = (lispval) lbot;
424: handy->cdr = (lispval) np;
425: PUSHDOWN(lexpr_atom,handy);
426: lbot = np;
427: (np++)->val = inewint(((lispval *)handy->cdr) - (lispval *)handy->car);
428: } else break; /* something is wrong - this isn't a proper function */
429: rebind(a->cdr->car,lbot);
430: np = lbot;
431: for (handy = a->cdr->cdr;
432: handy != nil;
433: handy = handy->cdr) {
434: vtemp = eval(handy->car); /* go for it */
435: }
436: if(a->car==macro)
437: vtemp = eval(vtemp);
438: }
439: if (vtemp != CNIL)
440: /* if we get here with a believable value, */
441: /* we must have executed a function. */
442: {
443: popnames(oldbnp);
444:
445: /* in case some clown trashed t */
446:
447: tatom->clb = (lispval) tatom;
448: /*debugging
449: if(a>(lispval) end){printf(" leaving:");
450: printr(a,stdout);
451: fflush(stdout);} */
452: return(vtemp);
453: }
454: popnames(oldbnp);
455: printr(oldlbot->val,stdout);
456: a = (lispval) error("BAD FUNCTION",TRUE);
457:
458: }
459: /*NOT REACHED*/
460: }
461:
462: /* protect **************************************************************/
463: /* pushes the first argument onto namestack, thereby protecting from gc */
464: lispval
465: protect(a)
466: lispval a;
467: {
468: /* (np++)->val = a;
469: if (np >= nplim)
470: namerr();
471: */
472: asm(" movl 4(ap),(r6)+");
473: asm(" cmpl r6,_nplim");
474: asm(" jlss out1");
475: asm(" calls $0,_namerr");
476: asm("out1: ret");
477: }
478:
479:
480: /* unprot ****************************************************************/
481: /* returns the top thing on the name stack. Underflow had better not */
482: /* occur. */
483: lispval
484: unprot()
485: {
486: asm(" movl -(r6),r0");
487: }
488:
489: lispval
490: linterp()
491: {
492: error("BYTE INTERPRETER CALLED ERRONEOUSLY",FALSE);
493: }
494:
495: /* Undeff - called from qfuncl when it detects a call to a undefined
496: function from compiled code, we print out a message and
497: dont allow continuation
498: */
499: lispval
500: Undeff(atmn)
501: lispval atmn;
502: {
503: printf("\n%s - ",atmn->pname);
504: error("Undefined function called from compiled code",FALSE);
505: }
506: bindfix(firstarg)
507: lispval firstarg;
508: {
509: register lispval *argp = &firstarg;
510: register struct nament *mybnp = bnp;
511: while(*argp != nil) {
512: mybnp->atm = *argp++;
513: mybnp->val = mybnp->atm->clb;
514: mybnp->atm->clb = *argp++;
515: bnp = mybnp++;
516: }
517: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.