|
|
1.1 root 1: #ifndef lint
2: static char *sccsid = "%W% %G%";
3: #endif
4:
5: #include "global.h"
6: #include "frame.h"
7:
8: lispval
9: Levalf ()
10: {
11: register struct frame *myfp;
12: register lispval handy, result;
13: struct frame *searchforpdl();
14: int evaltype;
15: Savestack(3);
16:
17: if(lbot==np) handy = nil;
18: else if((np-lbot) == 1) handy = lbot->val;
19: else argerr("evalf");
20:
21: if (handy == nil) /* Arg of nil means start at the top */
22: {
23: myfp = searchforpdl(errp);
24: /*
25: * myfp may be nil, if *rset t wasn't done. In that case we
26: * just return nil
27: */
28: if(myfp == (struct frame *) 0) return(nil);
29: /*
30: * myfp may point to the call to evalframe, in which case we
31: * want to go to the next frame down. myfp will not point
32: * to the call to evalframe if for example the translink tables
33: * are turned on and the call came from compiled code
34: */
35: if( ((myfp->class == F_EVAL)
36: && TYPE(myfp->larg1) == DTPR
37: && myfp->larg1->d.car == Vevalframe)
38: || ((myfp->class == F_FUNCALL)
39: && (myfp->larg1 = Vevalframe)))
40:
41: myfp = searchforpdl(myfp->olderrp); /* advance to next frame */
42: }
43: else
44: {
45: if( TYPE(handy) != INT )
46: error("Arg to evalframe must be integer",TRUE);
47: /*
48: * Interesting artifact: A pdl pointer will be an INT, but if
49: * read in, the Franz reader produces a bignum, thus giving some
50: * protection from being hacked.
51: */
52:
53: myfp = (struct frame *)(handy->i);
54: verifypdlp(myfp); /* make sure we are given valid pointer */
55: myfp = searchforpdl(myfp);
56: if (myfp == (struct frame *) 0 ) return(nil); /* end of frames */
57: myfp = searchforpdl(myfp->olderrp); /* advance to next one */
58: };
59:
60:
61: if (myfp == (struct frame *) 0 ) return(nil); /* end of frames */
62:
63: if(myfp->class == F_EVAL) evaltype = TRUE; else evaltype = FALSE;
64:
65: /* return ( <eval or apply> <fp> <exp being evaled> <bnp>) */
66: protect(result = newdot());
67: /*
68: * See maclisp manual for difference between eval frames and apply
69: * frames, or else see the code below.
70: */
71: result->d.car = matom (evaltype ? "eval" : "apply");
72: result->d.cdr = (handy = newdot());
73: handy->d.car = inewint(myfp); /* The frame pointer as a lisp int */
74: handy->d.cdr = newdot();
75: handy = handy->d.cdr;
76: if (evaltype)
77: handy->d.car = myfp->larg1; /* eval type - simply the arg to eval */
78: else
79: { /*
80: * apply type ; must build argument list. The form will look like
81: *
82: * (<function> (<evaled arg1> <evaled arg2> ....))
83: * i.e. the function name followed by a list of evaluated args
84: */
85: lispval form, arglist;
86: struct argent *pntr;
87: (form = newdot())->d.car = myfp->larg1;
88: handy->d.car = form; /* link in to save from gc */
89: (form->d.cdr = newdot())->d.cdr = nil;
90: for (arglist = nil, pntr = myfp->svlbot; pntr < myfp->svnp; pntr++)
91: {
92: if(arglist == nil)
93: {
94: protect(arglist = newdot());
95: form->d.cdr->d.car = arglist; /* save from gc */
96: }
97: else arglist = (arglist->d.cdr = newdot());
98: arglist->d.car = pntr->val;
99: };
100: };
101: handy->d.cdr = newdot();
102: handy = handy->d.cdr;
103: /* Next is index into bindstack lisp pseudo-array, for maximum
104: usefulness */
105: handy->d.car = inewint( myfp->svbnp - orgbnp);
106: handy->d.cdr = newdot();
107: handy = handy->d.cdr;
108:
109: handy->d.car = inewint(myfp->svnp - orgnp); /* index of np in namestack*/
110: handy->d.cdr = newdot();
111: handy = handy->d.cdr;
112: handy->d.car = inewint(myfp->svlbot - orgnp);/* index of lbot in namestack*/
113: Restorestack();
114: return(result);
115: }
116:
117: struct frame *searchforpdl (myfp)
118: struct frame *myfp;
119: {
120: /*
121: * for safety sake, we verify that this is a real pdl pointer by
122: * tracing back all pdl pointers from the start
123: * then after we find it, we just advance to next F_EVAL or F_FUNCALL
124: */
125: verifypdlp(myfp);
126: for( ; myfp != (struct frame *)0 ; myfp= myfp->olderrp)
127: {
128: if((myfp->class == F_EVAL) || (myfp->class == F_FUNCALL))
129: return(myfp);
130: }
131: return((struct frame *)0);
132: }
133:
134: /*
135: * verifypdlp :: verify pdl pointer as existing, do not return unless
136: * it is valid
137: */
138: verifypdlp(curfp)
139: register struct frame *curfp;
140: {
141: register struct frame *myfp;
142:
143: for (myfp = errp; myfp != (struct frame *)0 ; myfp = myfp->olderrp)
144: if(myfp == curfp) return;
145: errorh1(Vermisc,"Invalid pdl pointer given: ",nil,FALSE,0,inewint(curfp));
146: }
147:
148: lispval
149: Lfretn ()
150: {
151: struct frame *myfp;
152: chkarg(2,"freturn");
153:
154: if( TYPE(lbot->val) != INT )
155: error("freturn: 1st arg not pdl pointer",FALSE);
156:
157: myfp = (struct frame *) (lbot->val->i);
158: verifypdlp(myfp); /* make sure pdlp is valid */
159:
160: retval = C_FRETURN; /* signal coming from freturn */
161: lispretval = (lbot+1)->val; /* value to return */
162: Iretfromfr(myfp);
163: /* NOT REACHED */
164: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.