|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.