|
|
1.1 root 1: static char *sccsid = "@(#)fex1.c 34.2 11/7/80";
2:
3: #include "global.h"
4: /* Nprog ****************************************************************/
5: /* This first sets the local variables to nil while saving their old */
6: /* values on the name stack. Then, pointers to various things are */
7: /* saved as this function may be returned to by an "Ngo" or by a */
8: /* "Lreturn". At the end is the loop that cycles through the contents */
9: /* of the prog. */
10:
11: lispval
12: Nprog() {
13: int saveme[SAVSIZE];
14: register struct nament *mybnp = bnp;
15: register struct argent *savednp;
16: register lispval where, temp;
17: register struct argent *lbot, *np;
18: struct argent *savedlbot;
19: struct nament *savedbnp;
20: struct nament *topbind;
21: long myerrp; extern long errp;
22:
23: savednp = np;
24: savedlbot = lbot;
25: savedbnp = bnp;
26: temp = where = (lbot->val)->d.car;
27: while (TYPE(temp) == DTPR)
28: {
29: temp = where->d.car;
30: if (TYPE(temp) == ATOM)
31: {
32: bnp->atm = temp;
33: bnp->val = (temp)->a.clb;
34: (temp)->a.clb = nil;
35: temp = where = where->d.cdr;
36: if(bnp++ > bnplim)
37: binderr();
38: }
39: else return(CNIL);
40: }
41: topbind = bnp;
42: myerrp = errp;
43: if (where != nil) return(CNIL);
44: temp = where = savedlbot->val->d.cdr;
45: getexit(saveme);
46: while (retval = setexit()) {
47: errp = myerrp;
48: switch (retval) {
49:
50: case BRRETN: resexit(saveme);
51: popnames(savedbnp);
52: lbot = savedlbot;
53: return(contval);
54:
55: case BRGOTO: where = (savedlbot->val)->d.cdr;
56: while ((TYPE(where) == DTPR) && (where->d.car != contval))
57: where = where->d.cdr;
58: if (where->d.car == contval) {
59: /* This seems wrong - M Marcus
60: resexit(saveme); */
61: popnames(topbind);
62: lbot = savedlbot;
63: break;
64: }
65:
66: default:
67: resexit(saveme);
68: reset(retval);
69:
70: }
71: }
72: while (TYPE(where) == DTPR)
73: {
74: temp = where->d.car;
75: if((TYPE(temp))!=ATOM) eval(temp);
76: where = where->d.cdr;
77: }
78: resexit(saveme);
79: return((where == nil) ? nil : CNIL);
80: }
81:
82: lispval globtag;
83: /*
84: Ncatch is now actually *catch , which has the form
85: (*catch tag form)
86: tag is evaluated and then the catch entry is set up.
87: then form is evaluated
88: finally the catch entry is removed.
89:
90: (catch form [tag]) is translated to (*catch 'tag form)
91: by a macro.
92: */
93: lispval
94: Ncatch()
95: {
96: struct argent *savednp,*savedlbot;
97: register lispval where, tag, todo;
98: register temp;
99: register struct argent *lbot, *np;
100: int type;
101:
102:
103: where = lbot->val;
104: if((TYPE(where))!=DTPR) return(nil);
105: todo = where->d.cdr->d.car;
106: tag = eval(where->d.car);
107: while((TYPE(tag)!=ATOM) && (TYPE(tag) != DTPR))
108: tag = error("Bad type of tag in *catch.",TRUE);
109: asm(" pushab On1");
110: asm(" pushr $0x2540");
111: asm(" subl2 $44,sp"); /* THIS IS A CROCK ....
112: saves current environment
113: for (return) z.B. */
114: asm(" movc3 $44,_setsav,(sp)");
115: asm(" pushl _bnp");
116: asm(" pushl r10");
117: asm(" pushl $1");
118: asm(" pushl _errp");
119: asm(" movl sp,_errp");
120: where = (eval(todo));
121: asm(" movl (sp),_errp");
122: return(where);
123: asm("On1:ret");
124: }
125:
126: /* (errset form [flag])
127: if present, flag determines if the error message will be printed
128: if an error reaches the errset.
129: if no error occurs, errset returns a list of one element, the
130: value returned from form.
131: if an error occurs, nil is usually returned although it could
132: be non nil if err threw a non nil value
133: */
134:
135: lispval Nerrset()
136: {
137: register lispval flag,where,todo; /* order important */
138: register lispval handy = Vlerall; /* to access this easily */
139: register struct argent *lbot, *np;
140: where = lbot->val;
141:
142: if(TYPE(where) != DTPR) return(nil); /* no form */
143:
144: todo = where->d.car; /* form to eval */
145: flag = where->d.cdr;
146: if(flag != nil) flag = eval(flag->d.car); /* tag to tell if er messg */
147: else flag = tatom; /* if not present , assume t */
148:
149: /* push on a catch frame */
150:
151: asm(" pushab On2"); /* where to jump if error */
152: asm(" pushr $0x2540");
153: asm(" subl2 $44,sp"); /* THIS IS A CROCK ....
154: saves current environment
155: for (return) z.B. */
156: asm(" movc3 $44,_setsav,(sp)");
157: asm(" pushl _bnp");
158: asm(" pushl r8"); /* tag , (ER%all) */
159: asm(" pushl r11"); /* flag */
160: asm(" pushl _errp"); /* link in */
161: asm(" movl sp,_errp"); /* " */
162:
163: /* evaluate form, and if ok, listify */
164:
165: handy = eval(todo);
166: asm(" movl (sp),_errp"); /* unlink this frame */
167: protect(handy); /* may gc on nxt call */
168: (flag = newdot()) ->d.car = handy; /* listify arg */
169:
170: return(flag);
171:
172: asm("On2: ret"); /* if error occured */
173:
174: }
175:
176: /* this was changed from throw to *throw 21nov79
177: it really should be called Lthrow
178: */
179: Nthrow()
180: {
181: register lispval todo, where;
182: lispval globtag,contval;
183: snpand(2); /* save register mask */
184: switch(np-lbot) {
185: case 0:
186: protect(nil);
187: case 1:
188: protect(nil);
189: case 2: break;
190: default:
191: argerr("throw");
192: }
193: globtag = lbot->val;
194: contval = (lbot+1)->val;
195: Idothrow(globtag,contval);
196: error("Uncaught throw",FALSE);
197: }
198: #include "catchfram.h"
199:
200: Idothrow(tag,value)
201: lispval tag,value;
202: {
203: typedef struct catchfr *cp;
204: register cp curp; /* must be first register */
205: extern long errp;
206: extern lispval globtag;
207: int pass1,founduw;
208: lispval handy,handy2;
209: snpand(1);
210:
211: globtag = tag;
212: /*
213: printf("throw,value ");printr(tag,stdout); printf(" ");
214: printr(value,stdout); fflush(stdout);
215: */
216: pass1 = TRUE;
217: ps2:
218: founduw = FALSE;
219:
220: for (curp=(cp)errp ; curp != (cp) nil ; curp =curp->link)
221: {
222: /* printf(" lbl: ");printr(curp->labl,stdout);fflush(stdout); */
223: if(curp->labl == Veruwpt)
224: { founduw = TRUE;
225: if(!pass1) goto foundit;
226: }
227: if(curp->labl == nil || curp->labl == tag) goto foundit;
228: if(TYPE(curp->labl) == DTPR)
229: {
230: for( handy = curp->labl ; handy != nil ; handy = handy->d.cdr)
231: {
232: if(handy->d.car == tag) goto foundit;
233: }
234: }
235: }
236: return;
237:
238: foundit: /* restore context at catch */
239: if(pass1 && founduw)
240: { pass1 = FALSE;
241: goto ps2;
242: }
243: if(founduw) /* remember the state */
244: { protect(handy2 = newdot());
245: handy2->d.car = Veruwpt;
246: handy = handy2->d.cdr = newdot();
247: handy->d.car = tatom; /* t for throw */
248: handy = handy->d.cdr = newdot();
249: handy->d.car = tag;
250: handy = handy->d.cdr = newdot();
251: handy->d.car = value;
252: value = handy2;
253: /* printf("Ret uwp: ");printr(value,stdout);fflush(stdout);*/
254: }
255:
256: popnames(curp->svbnp);
257: errp = (int) curp->link;
258: /*
259: * return value must go into r7 until after movc3 since
260: * a movc3 clobbers r0
261: */
262: asm(" movl 8(ap),r7"); /* return value */
263: asm(" addl3 $16,r11,sp");
264: /* account for current (return) */
265: asm(" movc3 $44,(sp),_setsav");
266: asm(" addl2 $44,sp");
267: asm(" popr $0x2540");
268: asm(" movl r7,r0");
269: asm(" rsb");
270:
271: }
272:
273:
274:
275: /* Ngo ******************************************************************/
276: /* First argument only is checked - and must be an atom or evaluate */
277: /* to one. */
278: Ngo()
279: {
280: contval = (lbot->val)->d.car;
281: while (TYPE(contval) != ATOM)
282: {
283: contval = eval(contval);
284: while (TYPE(contval) != ATOM) contval = error("GO ARG NOT ATOM",TRUE);
285: }
286: reset(BRGOTO);
287: }
288:
289:
290: /* Nreset ***************************************************************/
291: /* All arguments are ignored. This just returns-from-break to depth 0. */
292: Nreset()
293: {
294: contval = 0;
295: reset(BRRETB);
296: }
297:
298: /* Nresetio *************************************************************/
299:
300: lispval
301: Nresetio() {
302: register FILE *p;
303:
304: for(p = &_iob[3]; p < _iob + _NFILE; p++) {
305: if(p->_flag & (_IOWRT | _IOREAD)) fclose(p);
306: }
307: return(nil);
308:
309: }
310:
311:
312: /* Nbreak ***************************************************************/
313: /* If first argument is not nil, this is evaluated and printed. Then */
314: /* error is called with the "breaking" message. */
315:
316: lispval
317: Nbreak()
318: {
319: register lispval hold; register FILE *port;
320: port = okport(Vpoport->a.clb,stdout);
321: fprintf(port,"Breaking:");
322:
323: if ((hold = lbot->val) != nil && ((hold = hold->d.car) != nil))
324: {
325: printr(hold,port);
326: }
327: putc('\n',port);
328: dmpport(port);
329: return(errorh(Verbrk,"",nil,TRUE,0));
330: }
331:
332:
333: /* Nexit ****************************************************************/
334: /* Just calls lispend with no message. */
335: Nexit()
336: {
337: lispend("");
338: }
339:
340:
341: /* Nsys *****************************************************************/
342: /* Just calls lispend with no message. */
343:
344: lispval
345: Nsys()
346: {
347: lispend("");
348: }
349:
350:
351:
352:
353: lispval
354: Ndef() {
355: register lispval arglist, body, name, form;
356: snpand(4);
357:
358: form = lbot->val;
359: name = form->d.car;
360: body = form->d.cdr->d.car;
361: arglist = body->d.cdr->d.car;
362: if((TYPE(arglist))!=DTPR && arglist != nil)
363: error("Warning: defining function with nonlist of args",
364: TRUE);
365: name->a.fnbnd = body;
366: return(name);
367: }
368:
369:
370: lispval
371: Nquote()
372: {
373: snpand(0);
374: return((lbot->val)->d.car);
375: }
376:
377:
378: lispval
379: Nsetq()
380: { register lispval handy, where, value;
381: register int lefttype;
382: register struct argent *lbot, *np;
383:
384:
385: for(where = lbot->val; where != nil; where = handy->d.cdr) {
386: handy = where->d.cdr;
387: if((TYPE(handy))!=DTPR)
388: error("odd number of args to setq",FALSE);
389: if((lefttype=TYPE(where->d.car))==ATOM) {
390: if(where->d.car==nil)
391: error("Attempt to set nil",FALSE);
392: where->d.car->a.clb = value = eval(handy->d.car);
393: }else if(lefttype==VALUE)
394: where->d.car->l = value = eval(handy->d.car);
395: else error("CAN ONLY SETQ ATOMS OR VALUES",FALSE);
396: }
397: return(value);
398: }
399:
400:
401: lispval
402: Ncond()
403: {
404: register lispval where, last;
405: snpand(2);
406:
407: where = lbot->val;
408: last = nil;
409: for(;;) {
410: if ((TYPE(where))!=DTPR)
411: break;
412: if ((TYPE(where->d.car))!=DTPR)
413: break;
414: if ((last=eval((where->d.car)->d.car)) != nil)
415: break;
416: where = where->d.cdr;
417: }
418:
419: if ((TYPE(where)) != DTPR)
420: return(nil);
421: where = (where->d.car)->d.cdr;
422: while ((TYPE(where))==DTPR) {
423: last = eval(where->d.car);
424: where = where->d.cdr;
425: }
426: return(last);
427: }
428:
429: lispval
430: Nand()
431: {
432: register lispval current, temp;
433: snpand(2);
434:
435: current = lbot->val;
436: temp = tatom;
437: while (current != nil)
438: if ( (temp = current->d.car)!=nil && (temp = eval(temp))!=nil)
439: current = current->d.cdr;
440: else {
441: current = nil;
442: temp = nil;
443: }
444: return(temp);
445: }
446:
447:
448: lispval
449: Nor()
450: {
451: register lispval current, temp;
452: snpand(2);
453:
454: current = lbot->val;
455: temp = nil;
456: while (current != nil)
457: if ( (temp = eval(current->d.car)) == nil)
458: current = current->d.cdr;
459: else
460: break;
461: return(temp);
462: }
463:
464:
465: lispval
466: Nprocess() {
467: int wflag , childsi , childso , childnum, child;
468: register lispval current, temp;
469: char * sharg;
470: int handler;
471: int itemp;
472: FILE *bufs[2],*obufs[2];
473:
474: wflag = 1;
475: childsi = 0;
476: childso = 1;
477: current = lbot->val;
478: if( (TYPE(current))!=DTPR )
479: return(nil);
480: temp = current->d.car;
481: if( (TYPE(temp))!=ATOM )
482: return(nil);
483:
484: sharg = temp->a.pname;
485:
486: if( (current = current->d.cdr)!=nil && (TYPE((temp = current->d.car)))==ATOM ) {
487:
488: if (temp == tatom) {
489: wflag = 0;
490: childsi = 0;
491: } else if (temp != nil) {
492: fpipe(bufs);
493: wflag = 0;
494: temp->a.clb = P(bufs[1]);
495: childsi = fileno(bufs[0]);
496: }
497:
498: if( (current = current->d.cdr)!=nil && (TYPE((temp = current->d.car)))==ATOM ) {
499:
500: if (temp != nil) {
501: fpipe(obufs);
502: temp->a.clb = P(obufs[0]);
503: childso = fileno(obufs[1]);
504: }
505: }
506: }
507: handler = signal(2,1);
508: if((child = fork()) == 0 ) {
509: if(wflag!=0 && handler !=1)
510: signal(2,0);
511: else
512: signal(2,1);
513: if(childsi != 0) {
514: close(0);
515: dup(childsi);
516: }
517: if (childso !=1) {
518: close(1);
519: dup(childso);
520: }
521: execlp("csh", "csh", "-c",sharg,0);
522: execlp("sh", "sh", "-c",sharg,0);
523: exit(-1); /* if exec fails, signal problems*/
524: }
525:
526: if(childsi != 0) fclose(bufs[0]);
527: if(childso != 1) fclose(obufs[1]);
528:
529: if(wflag && child!= -1) {
530: int status=0;
531: wait(&status);
532: itemp = status >> 8;
533: } else
534: itemp = child;
535: signal(2,handler);
536: return(inewint(itemp));
537: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.