1: #ifndef lint
   2: static char *rcsid =
   3:    "$Header: fex1.c,v 1.5 85/03/24 11:03:51 sklower Exp $";
   4: #endif
   5: 
   6: /*					-[Sat Mar  5 19:50:28 1983 by layer]-
   7:  * 	fex1.c				$Locker:  $
   8:  * nlambda functions
   9:  *
  10:  * (c) copyright 1982, Regents of the University of California
  11:  */
  12: 
  13: 
  14: #include "global.h"
  15: #include "frame.h"
  16: 
  17: /* Nprog ****************************************************************/
  18: /* This first sets the local variables to nil while saving their old	*/
  19: /* values on the name stack.  Then, pointers to various things are	*/
  20: /* saved as this function may be returned to by an "Ngo" or by a	*/
  21: /* "Lreturn".  At the end is the loop that cycles through the contents	*/
  22: /* of the prog.								*/
  23: 
  24: lispval
  25: Nprog() {
  26:     register lispval where, temp;
  27:     struct nament *savedbnp = bnp;
  28:     extern struct frame *errp;
  29:     pbuf pb;
  30:     extern int retval;
  31:     extern lispval lispretval;
  32: 
  33:     if((np-lbot) < 1) chkarg(1,"prog");
  34: 
  35:     /* shallow bind the local variables to nil */
  36:     if(lbot->val->d.car != nil)
  37:     {
  38:         for( where = lbot->val->d.car ; where != nil; where = where->d.cdr )
  39:         {
  40:             if(TYPE(where) != DTPR || TYPE(temp=where->d.car) != ATOM)
  41:             errorh1(Vermisc,
  42:                "Illegal local variable list in prog ",nil,FALSE,
  43:                1,where);
  44:                 PUSHDOWN(temp,nil);
  45:         }
  46:     }
  47: 
  48:     /* put a frame on the stack which can be 'return'ed to or 'go'ed to */
  49:     errp = Pushframe(F_PROG,nil,nil);
  50: 
  51:     where = lbot->val->d.cdr;   /* first thing in the prog body */
  52: 
  53:     switch (retval) {
  54:     case C_RET: /*
  55: 			 * returning from this prog, value to return
  56: 			 * is in lispretval
  57: 			 */
  58:             errp = Popframe();
  59:             popnames(savedbnp);
  60:             return(lispretval);
  61: 
  62:     case C_GO:  /*
  63: 			 * going to a certain label, label to go to in
  64: 			 * in lispretval
  65: 			 */
  66:             where = (lbot->val)->d.cdr;
  67:             while ((TYPE(where) == DTPR)
  68:                    && (where->d.car != lispretval))
  69:                 where = where->d.cdr;
  70:             if (where->d.car == lispretval) {
  71:                 popnames(errp->svbnp);
  72:                 break;
  73:             }
  74:             /* label not found in this prog, must
  75: 			 * go up to higher prog
  76: 			 */
  77:             errp = Popframe();  /* go to next frame */
  78:             Inonlocalgo(C_GO,lispretval,nil);
  79: 
  80:             /* NOT REACHED */
  81: 
  82:     case C_INITIAL: break;
  83: 
  84:     }
  85: 
  86:     while (TYPE(where) == DTPR)
  87:         {
  88:         temp = where->d.car;
  89:         if((TYPE(temp))!=ATOM) eval(temp);
  90:         where = where->d.cdr;
  91:         }
  92:     if((where != nil) && (TYPE(where) != DTPR))
  93:         errorh1(Vermisc,"Illegal form in prog body ", nil,FALSE,0,where);
  94:     errp = Popframe();
  95:     popnames(savedbnp); /* pop off locals */
  96:     return(nil);
  97: }
  98: 
  99: lispval globtag;
 100: /*
 101:    Ncatch is now linked to the lisp symbol *catch , which has the form
 102:      (*catch tag form)
 103:     tag is evaluated and then the catch entry is set up.
 104:       then form is evaluated
 105:     finally the catch entry is removed.
 106: 
 107:   *catch is still an nlambda since its arguments should not be evaluated
 108:    before this routine is called.
 109: 
 110:    (catch form [tag]) is translated to (*catch 'tag form) by a macro.
 111:  */
 112: lispval
 113: Ncatch()
 114: {
 115:     register lispval tag;
 116:     pbuf pb;
 117:     Savestack(3);       /* save stack pointers */
 118: 
 119:     if((TYPE(lbot->val))!=DTPR) return(nil);
 120:     protect(tag = eval(lbot->val->d.car));  /* protect tag from gc */
 121: 
 122:     errp = Pushframe(F_CATCH,tag,nil);
 123: 
 124:     switch(retval) {
 125: 
 126:     case C_THROW:   /*
 127: 		       	 * value thrown is in lispretval
 128: 		       	 */
 129:             break;
 130: 
 131:     case C_INITIAL: /*
 132: 			 * calculate value of expression
 133: 			 */
 134:              lispretval = eval(lbot->val->d.cdr->d.car);
 135:     }
 136: 
 137: 
 138:     errp = Popframe();
 139:     Restorestack();
 140:     return(lispretval);
 141: }
 142: /* (errset form [flag])
 143:    if present, flag determines if the error message will be printed
 144:    if an error reaches the errset.
 145:    if no error occurs, errset returns a list of one element, the
 146:     value returned from form.
 147:    if an error occurs, nil is usually returned although it could
 148:     be non nil if err threw a non nil value
 149:  */
 150: 
 151: lispval Nerrset()
 152: {
 153:     lispval temp,flag;
 154:     pbuf pb;
 155:     Savestack(0);
 156: 
 157:     if(TYPE(lbot->val) != DTPR) return(nil);    /* no form */
 158: 
 159:     /* evaluate and save flag first */
 160:     flag = lbot->val->d.cdr;
 161:     if(TYPE(flag) == DTPR) flag = eval(flag->d.car);
 162:     else flag = tatom;  /* if not present , assume t */
 163:     protect(flag);
 164: 
 165:     errp = Pushframe(F_CATCH,Verall,flag);
 166: 
 167:     switch(retval) {
 168: 
 169:     case C_THROW:   /*
 170: 			 * error thrown to this routine, value thrown is
 171: 			 * in lispretval
 172: 			 */
 173:             break;
 174: 
 175:     case C_INITIAL: /*
 176: 			 * normally just evaluate expression and listify it.
 177: 			 */
 178:             temp = eval(lbot->val->d.car);
 179:             protect(temp);
 180:             (lispretval = newdot())->d.car = temp;
 181:             break;
 182:     }
 183: 
 184:     errp = Popframe();
 185:     Restorestack();
 186:     return(lispretval);
 187: }
 188: 
 189: /* this was changed from throw to *throw 21nov79
 190:    it is now a lambda and really should be called Lthrow
 191: */
 192: lispval
 193: Nthrow()
 194: {
 195:     switch(np-lbot) {
 196:     case 0:
 197:         protect(nil);
 198:     case 1:
 199:         protect(nil);
 200:     case 2: break;
 201:     default:
 202:         argerr("throw");
 203:     }
 204:     Inonlocalgo(C_THROW,lbot->val,(lbot+1)->val);
 205:     /* NOT REACHED */
 206: }
 207: 
 208: 
 209: 
 210: /* Ngo ******************************************************************/
 211: /* First argument only is checked - and must be an atom or evaluate	*/
 212: /* to one.								*/
 213: lispval
 214: Ngo()
 215: {
 216:     register lispval temp;
 217:     chkarg(1,"go");
 218: 
 219:     temp = (lbot->val)->d.car;
 220:     if (TYPE(temp) != ATOM)
 221:     {
 222:     temp = eval(temp);
 223:     while(TYPE(temp) != ATOM)
 224:       temp = errorh1(Vermisc,"Illegal tag to go to",nil,TRUE, 0,lbot->val);
 225:     }
 226:     Inonlocalgo(C_GO,temp,nil);
 227:     /* NOT REACHED */
 228: }
 229: 
 230: 
 231: /* Nreset ***************************************************************/
 232: /* All arguments are ignored.  This just returns-from-break to depth 0.	*/
 233: lispval
 234: Nreset()
 235: {
 236:     Inonlocalgo(C_RESET,inewint(0),nil);
 237: }
 238: 
 239: 
 240: 
 241: /* Nbreak ***************************************************************/
 242: /* If first argument is not nil, this is evaluated and printed.  Then	*/
 243: /* error is called with the "breaking" message.				*/
 244: 
 245: lispval
 246: Nbreak()
 247: {
 248:     register lispval hold; register FILE *port;
 249:     port = okport(Vpoport->a.clb,stdout);
 250:     fprintf(port,"Breaking:");
 251: 
 252:     if ((hold = lbot->val) != nil && ((hold = hold->d.car) != nil))
 253:     {
 254:         printr(hold,port);
 255:     }
 256:     putc('\n',port);
 257:     dmpport(port);
 258:     return(errorh(Verbrk,"",nil,TRUE,0));
 259: }
 260: 
 261: 
 262: /* Nexit ****************************************************************/
 263: /* Just calls lispend with no message.					*/
 264: Nexit()
 265:     {
 266:     lispend("");
 267:     }
 268: 
 269: 
 270: /* Nsys *****************************************************************/
 271: /* Just calls lispend with no message.					*/
 272: 
 273: lispval
 274: Nsys()
 275:     {
 276:     lispend("");
 277:     }
 278: 
 279: 
 280: 
 281: 
 282: lispval
 283: Ndef() {
 284:     register lispval arglist, body, name, form;
 285: 
 286:     form = lbot->val;
 287:     name = form->d.car;
 288:     body = form->d.cdr->d.car;
 289:     arglist = body->d.cdr->d.car;
 290:     if((TYPE(arglist))!=DTPR && arglist != nil)
 291:         error("Warning: defining function with nonlist of args",
 292:             TRUE);
 293:     name->a.fnbnd = body;
 294:     return(name);
 295: }
 296: 
 297: 
 298: lispval
 299: Nquote()
 300: {
 301:     return((lbot->val)->d.car);
 302: }
 303: 
 304: 
 305: lispval
 306: Nsetq()
 307: {   register lispval handy, where, value;
 308:     register int lefttype;
 309: 
 310:     value = nil;
 311: 
 312:     for(where = lbot->val; where != nil; where = handy->d.cdr) {
 313:         handy = where->d.cdr;
 314:         if((TYPE(handy))!=DTPR)
 315:             error("odd number of args to setq",FALSE);
 316:         if((lefttype=TYPE(where->d.car))==ATOM) {
 317:             if(where->d.car==nil)
 318:                 error("Attempt to set nil",FALSE);
 319:             where->d.car->a.clb = value = eval(handy->d.car);
 320:          }else if(lefttype==VALUE)
 321:             where->d.car->l = value = eval(handy->d.car);
 322:         else errorh1(Vermisc,
 323:                 "Can only setq atoms or values",nil,FALSE,0,
 324:                         where->d.car);
 325:     }
 326:     return(value);
 327: }
 328: 
 329: 
 330: lispval
 331: Ncond()
 332: {
 333:     register lispval  where, last;
 334: 
 335:     where = lbot->val;
 336:     last = nil;
 337:     for(;;) {
 338:         if ((TYPE(where))!=DTPR)
 339:             break;
 340:         if ((TYPE(where->d.car))!=DTPR)
 341:             break;
 342:         if ((last=eval((where->d.car)->d.car)) != nil)
 343:             break;
 344:         where = where->d.cdr;
 345:     }
 346: 
 347:     if ((TYPE(where)) != DTPR)
 348:             return(nil);
 349:     where = (where->d.car)->d.cdr;
 350:     while ((TYPE(where))==DTPR) {
 351:             last = eval(where->d.car);
 352:             where = where->d.cdr;
 353:     }
 354:     return(last);
 355: }
 356: 
 357: lispval
 358: Nand()
 359: {
 360:     register lispval current, temp;
 361: 
 362:     current = lbot->val;
 363:     temp = tatom;
 364:     while (current != nil)
 365:         if ( (temp = current->d.car)!=nil && (temp = eval(temp))!=nil)
 366:             current = current->d.cdr;
 367:         else {
 368:             current = nil;
 369:             temp = nil;
 370:         }
 371:     return(temp);
 372: }
 373: 
 374: 
 375: lispval
 376: Nor()
 377: {
 378:     register lispval current, temp;
 379: 
 380:     current = lbot->val;
 381:     temp = nil;
 382:     while (current != nil)
 383:         if ( (temp = eval(current->d.car)) == nil)
 384:             current = current->d.cdr;
 385:         else
 386:             break;
 387:     return(temp);
 388: }

Defined functions

Nand defined in line 357; never used
Nbreak defined in line 245; never used
Ncatch defined in line 112; never used
Ncond defined in line 330; never used
Ndef defined in line 282; never used
Nerrset defined in line 151; never used
Nexit defined in line 264; never used
Ngo defined in line 213; never used
Nor defined in line 375; never used
Nprog defined in line 24; never used
Nquote defined in line 298; never used
Nreset defined in line 233; never used
Nsetq defined in line 305; never used
Nsys defined in line 273; never used
Nthrow defined in line 192; never used

Defined variables

rcsid defined in line 2; never used
Last modified: 1985-08-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1335
Valid CSS Valid XHTML 1.0 Strict