1: 
   2: #ifndef lint
   3: static char *rcsid =
   4:    "$Header: fex2.c,v 1.3 83/09/07 17:55:38 sklower Exp $";
   5: #endif
   6: 
   7: /*					-[Mon Jan 31 21:54:52 1983 by layer]-
   8:  * 	fex2.c				$Locker:  $
   9:  * nlambda functions
  10:  *
  11:  * (c) copyright 1982, Regents of the University of California
  12:  */
  13: 
  14: #include "global.h"
  15: #define NDOVARS 30
  16: #include "frame.h"
  17: 
  18: /*
  19:  * Ndo  maclisp do function.
  20:  */
  21: lispval
  22: Ndo()
  23: {
  24:     register lispval current, where, handy;
  25:     register struct nament *mybnp;
  26:     lispval temp, atom;
  27:     lispval body, endtest, endform, varstuff, renewals[NDOVARS] ;
  28:     struct argent *getem, *startnp;
  29:     struct nament *savedbnp = bnp;
  30:     int count, repeatdo, index;
  31:     extern struct frame *errp;
  32:     pbuf pb;
  33:     Savestack(3);
  34: 
  35:     current = lbot->val;
  36:     varstuff = current->d.car;
  37: 
  38:     switch( TYPE(varstuff) ) {
  39: 
  40:     case ATOM:          /* This is old style maclisp do;
  41: 					   atom is var, cadr(current) = init;
  42: 					   caddr(current) = repeat etc. */
  43:         if(varstuff==nil) goto newstyle;
  44:         current = current->d.cdr;   /* car(current) is now init */
  45:         PUSHDOWN(varstuff,eval(current->d.car));
  46:                     /* Init var.	    */
  47:         *renewals = (current = current->d.cdr)->d.car;
  48:                     /* get repeat form  */
  49:         endtest = (current = current->d.cdr)->d.car;
  50:         body = current->d.cdr;
  51: 
  52:         errp = Pushframe(F_PROG,nil,nil);
  53: 
  54:         switch (retval) {
  55:             case C_RET: /*
  56: 				 * returning from this prog, value to return
  57: 				 * is in lispretval
  58: 				 */
  59:                 errp = Popframe();
  60:                 popnames(savedbnp);
  61:                 return(lispretval);
  62: 
  63:             case C_GO:  /*
  64: 				 * going to a certain label, label to go to in
  65: 				 * in lispretval
  66: 				 */
  67:                 where = body;
  68:                 while ((TYPE(where) == DTPR)
  69:                     & (where->d.car != lispretval))
  70:                 where = where->d.cdr;
  71:                 if (where->d.car == lispretval) {
  72:                     popnames(errp->svbnp);
  73:                     where = where->d.cdr;
  74:                     goto singbody;
  75:                 }
  76:                 /* label not found in this prog, must
  77: 				 * go up to higher prog
  78: 				 */
  79:                 Inonlocalgo(C_GO,lispretval,nil);
  80: 
  81:                 /* NOT REACHED */
  82: 
  83:             case C_INITIAL: break;      /* fall through */
  84: 
  85:         }
  86: 
  87:         singtop:
  88:             if(eval(endtest)!=nil) {
  89:             errp = Popframe();
  90:             popnames(savedbnp);
  91:             return(nil);
  92:             }
  93:             where = body;
  94: 
  95:         singbody:
  96:             while (TYPE(where) == DTPR)
  97:             {
  98:             temp = where->d.car;
  99:             if((TYPE(temp))!=ATOM) eval(temp);
 100:             where = where->d.cdr;
 101:             }
 102:             varstuff->a.clb = eval(*renewals);
 103:             goto singtop;
 104: 
 105: 
 106:     newstyle:
 107:     case DTPR:          /* New style maclisp do; atom is
 108: 					   list of things of the form
 109: 					   (var init repeat)		*/
 110:         count = 0;
 111:         startnp = np;
 112:         for(where = varstuff; where != nil; where = where->d.cdr) {
 113:                     /* do inits and count do vars. */
 114:                     /* requires "simultaneous" eval
 115: 					   of all inits			*/
 116:                 while (TYPE(where->d.car) != DTPR)
 117:               where->d.car =
 118:                  errorh1(Vermisc,"do: variable forms must be lists ",
 119:                  nil,TRUE,0,where->d.car);
 120:             handy = where->d.car->d.cdr;
 121:             temp = nil;
 122:             if(handy !=nil)
 123:                 temp = eval(handy->d.car);
 124:             protect(temp);
 125:             count++;
 126:         }
 127:         if(count > NDOVARS)
 128:             error("More than 15 do vars",FALSE);
 129:         where = varstuff;
 130:         getem = startnp;    /* base of stack of init forms */
 131:         for(index = 0; index < count; index++) {
 132: 
 133:             handy = where->d.car;
 134:                     /* get var name from group	*/
 135: 
 136:             atom = handy->d.car;
 137:             while((TYPE(atom) != ATOM) || (atom == nil))
 138:               atom = errorh1(Vermisc,"do variable must be a non nil symbol ",
 139:                             nil,TRUE,0,atom);
 140:             PUSHDOWN(atom,getem->val);
 141:             getem++;
 142:             handy = handy->d.cdr->d.cdr;
 143:             if(handy==nil)
 144:                 handy = CNIL;  /* be sure not to rebind later */
 145:             else
 146:                 handy = handy->d.car;
 147:             renewals[index] = handy;
 148: 
 149:                     /* more loop "increments" */
 150:             where = where->d.cdr;
 151:         }
 152:         np = startnp;       /* pop off all init forms */
 153:                     /* Examine End test and End form */
 154:         current = current->d.cdr;
 155:         handy = current->d.car;
 156:         body = current->d.cdr;
 157: 
 158:         /*
 159: 		 * a do form with a test of nil just does the body once
 160: 		 * and returns nil
 161: 		 */
 162:         if (handy == nil) repeatdo = 1; /* just do it once */
 163:         else repeatdo = -1;     /* do it forever   */
 164: 
 165:         endtest = handy->d.car;
 166:         endform = handy->d.cdr;
 167: 
 168:         where = body;
 169: 
 170:         errp = Pushframe(F_PROG,nil,nil);
 171:         while(TRUE) {
 172: 
 173:             switch (retval) {
 174:             case C_RET: /*
 175: 				 * returning from this prog, value to return
 176: 				 * is in lispretval
 177: 				 */
 178:                 errp = Popframe();
 179:                 popnames(savedbnp);
 180:                 Restorestack();
 181:                 return(lispretval);
 182: 
 183:             case C_GO:  /*
 184: 				 * going to a certain label, label to go to in
 185: 				 * in lispretval
 186: 				 */
 187:                 where = body;
 188:                 while ((TYPE(where) == DTPR)
 189:                     & (where->d.car != lispretval))
 190:                 where = where->d.cdr;
 191:                 if (where->d.car == lispretval) {
 192:                     popnames(errp->svbnp);
 193:                     where = where->d.cdr;
 194:                     goto bodystart;
 195:                 }
 196:                 /* label not found in this prog, must
 197: 				 * go up to higher prog
 198: 				 */
 199:                 Inonlocalgo(C_GO,lispretval,nil);
 200: 
 201:                 /* NOT REACHED */
 202: 
 203:             case C_INITIAL: break;      /* fall through */
 204: 
 205:             }
 206: 
 207:         loop:
 208:                 np = startnp;   /* is bumped when doing repeat forms */
 209: 
 210:             if((repeatdo-- == 0) || (eval(endtest) !=nil)) {
 211:             for(handy = nil; endform!=nil; endform = endform->d.cdr)
 212:             {
 213:                 handy = eval(endform->d.car);
 214:             }
 215:             errp = Popframe();
 216:             popnames(savedbnp);
 217:             Restorestack();
 218:             return(handy);
 219:             }
 220: 
 221:         bodystart:
 222:             while (TYPE(where) == DTPR)
 223:             {
 224:             temp = where->d.car;
 225:             if((TYPE(temp))!=ATOM) eval(temp);
 226:             where = where->d.cdr;
 227:             }
 228:             where = body;
 229:             getem = np = startnp;
 230:                     /* Simultaneously eval repeat forms */
 231:             for(index = 0; index < count; index++) {
 232:             temp = renewals[index];
 233:             if (temp == nil || temp == CNIL)
 234:                 protect(temp);
 235:             else
 236:                 protect(eval(temp));
 237:             }
 238:                     /* now simult. rebind all the atoms */
 239:             mybnp = savedbnp;
 240:             for(index = 0; index < count; index++)
 241:             {
 242:                if( getem->val != CNIL )  /* if this atom has a repeat */
 243:             mybnp->atm->a.clb = (getem)->val;  /* rebind */
 244:             mybnp++;
 245:             getem++;
 246:             }
 247:             goto loop;
 248:         }
 249:         default:
 250:         error("do: neither list nor atom follows do", FALSE);
 251:         }
 252:         /* NOTREACHED */
 253: }
 254: 
 255: lispval
 256: Nprogv()
 257: {
 258:     register lispval where, handy;
 259:     register struct nament *namptr;
 260:     register struct argent *vars;
 261:     struct nament *oldbnp = bnp;
 262:     Savestack(4);
 263: 
 264:     where = lbot->val;
 265:     protect(eval(where->d.car));        /* list of vars = lbot[1].val */
 266:     protect(eval((where = where->d.cdr)->d.car));
 267:                         /* list of vals */
 268:     handy = lbot[2].val;
 269:     namptr = oldbnp;
 270:                         /* simultaneous eval of all
 271: 						   args */
 272:     for(;handy!=nil; handy = handy->d.cdr) {
 273:         (np++)->val = (handy->d.car);
 274:         /*  Note, each element should not be reevaluated like it
 275: 		 *  was  before.  - dhl */
 276:         /* Before: (np++)->val = eval(handy->d.car);*/
 277:         TNP;
 278:     }
 279:     /*asm("# Here is where rebinding is done");	 /* very cute */
 280:     for(handy=lbot[1].val,vars=lbot+3; handy!=nil; handy=handy->d.cdr) {
 281:         namptr->atm = handy->d.car;
 282:         ++namptr;               /* protect against interrupts
 283: 						   while re-lambda binding */
 284:         bnp = namptr;
 285:         namptr[-1].atm = handy->d.car;
 286:         namptr[-1].val = handy->d.car->a.clb;
 287:         if(vars < np)
 288:         handy->d.car->a.clb = vars++->val;
 289:         else
 290:         handy->d.car->a.clb = nil;
 291:     }
 292: 
 293:     handy = nil;
 294:     for(where = where->d.cdr; where != nil; where = where->d.cdr)
 295:         handy = eval(where->d.car);
 296:     popnames(oldbnp);
 297:     Restorestack();
 298:     return(handy);
 299: }
 300: 
 301: lispval
 302: Nprogn()
 303: {
 304:     register lispval result, where;
 305: 
 306:     result = nil;
 307:     for(where = lbot->val; where != nil; where = where->d.cdr)
 308:         result = eval(where->d.car);
 309:     return(result);
 310: 
 311: 
 312: }
 313: lispval
 314: Nprog2()
 315: {
 316:     register lispval result, where;
 317: 
 318:     where = lbot->val;
 319:     eval(where->d.car);
 320:     result = eval((where = where->d.cdr)->d.car);
 321:     protect(result);
 322:     for(where = where->d.cdr; where != nil; where = where->d.cdr)
 323:         eval(where->d.car);
 324:     np--;
 325:     return(result);
 326: }
 327: lispval
 328: typred(typ,ptr)
 329: int     typ;
 330: lispval ptr;
 331: 
 332: {   int tx;
 333:     if ((tx = TYPE(ptr)) == typ) return(tatom);
 334:     if ((tx == INT) && (typ == ATOM)) return(tatom);
 335:     return(nil);
 336: }
 337: 
 338: /*
 339:  * function
 340:  * In the interpreter, function is the same as quote
 341:  */
 342: lispval
 343: Nfunction()
 344: {
 345:     if((lbot->val == nil) || (lbot->val->d.cdr != nil))
 346:         argerr("function");
 347:     return(lbot->val->d.car);
 348: }

Defined functions

Ndo defined in line 21; never used
Nfunction defined in line 342; never used
Nprog2 defined in line 313; never used
Nprogn defined in line 301; used 1 times
Nprogv defined in line 255; never used
typred defined in line 327; used 4 times

Defined variables

rcsid defined in line 3; never used

Defined macros

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