1: #ifndef lint
   2: static char *rcsid =
   3:    "$Header: lam6.c,v 1.7 85/03/24 11:04:21 sklower Exp $";
   4: #endif
   5: 
   6: /*					-[Sun Sep  4 08:56:19 1983 by jkf]-
   7:  * 	lam6.c				$Locker:  $
   8:  * lambda functions
   9:  *
  10:  * (c) copyright 1982, Regents of the University of California
  11:  */
  12: 
  13: #include "global.h"
  14: #include "frame.h"
  15: #include <signal.h>
  16: #include <sys/types.h>
  17: #include <sys/times.h>
  18: #include "chkrtab.h"
  19: #include "chars.h"
  20: 
  21: 
  22: lispval
  23: Lreadli()
  24: {
  25:     register lispval work, handy;
  26:     register FILE *p;
  27:     register char *string; char *alloca();
  28:     FILE *fstopen();
  29:     lispval Lread();
  30:     int count;
  31:     pbuf pb;
  32:     Savestack(4);
  33: #ifdef SPISFP
  34:     Keepxs();
  35: #endif
  36: 
  37:     if(lbot->val==nil) {        /*effectively, return(matom(""));*/
  38:         strbuf[0] = 0;
  39:         return(getatom(FALSE));
  40:     }
  41:     chkarg(1,"readlist");
  42:     count = 1;
  43: 
  44:     /* compute length of list */
  45:     for(work = lbot->val; TYPE(work)==DTPR; work=work->d.cdr)
  46:         count++;
  47:     string = alloca(count);
  48:     p = fstopen(string, count - 1, "r");
  49:     for(work = lbot->val; TYPE(work)==DTPR; work=work->d.cdr) {
  50:         handy = work->d.car;
  51:         switch(TYPE(handy)) {
  52:         case SDOT:
  53:         case INT:
  54:             *string++=handy->i;
  55:             break;
  56:         case ATOM:
  57:             *string++ = *(handy->a.pname);
  58:             break;
  59:         case STRNG:
  60:             *string++ = *(char *)handy;
  61:             break;
  62:         default:
  63:                 fclose(p);
  64:             error("Non atom or int to readlist",FALSE);
  65:         }
  66:     }
  67:     *string = 0;
  68:     errp = Pushframe(F_CATCH,Veruwpt,nil);  /* must unwind protect
  69: 						   so can deallocate p
  70: 						 */
  71:     switch(retval) { lispval Lctcherr();
  72:     case C_THROW:
  73:             /* an error has occured and we are given a chance
  74: 			   to unwind before the control goes higher
  75: 			   lispretval contains the error descriptor in
  76: 			   it's cdr
  77: 			 */
  78:               fclose(p);    /* free port */
  79:               errp = Popframe();
  80:               Freexs();
  81:               lbot = np;
  82:               protect(lispretval->d.cdr); /* error descriptor */
  83:               return(Lctcherr());   /* do a I-do-throw */
  84: 
  85:     case C_INITIAL:
  86:             lbot = np;
  87:             protect(P(p));
  88:             work = Lread();  /* error  could occur here */
  89:             Freexs();
  90:             fclose(p);  /* whew.. no errors */
  91:             errp = Popframe();  /* remove unwind-protect */
  92:             Restorestack();
  93:             return(work);
  94:     }
  95:     /* NOTREACHED */
  96: }
  97: 
  98: lispval
  99: Lgetenv()
 100: {
 101:     char *getenv(), *strcpy();
 102:     char *res;
 103:     chkarg(1,"getenv");
 104: 
 105: 
 106:     if((TYPE(lbot->val))!=ATOM)
 107:         error("argument to getenv must be atom",FALSE);
 108: 
 109:     res = getenv(lbot->val->a.pname);
 110:     if(res) strcpy(strbuf,res);
 111:     else strbuf[0] = '\0';
 112:     return(getatom(FALSE));
 113: }
 114: 
 115: lispval
 116: Lboundp()
 117: {
 118:     register lispval result, handy;
 119: 
 120:     chkarg(1,"boundp");
 121: 
 122:     if((TYPE(lbot->val))!=ATOM)
 123:         error("argument to boundp must be symbol",FALSE);
 124:     if( (handy = lbot->val)->a.clb==CNIL)
 125:         result = nil;
 126:     else
 127:         (result = newdot())->d.cdr = handy->a.clb;
 128:     return(result);
 129: }
 130: 
 131: 
 132: lispval
 133: Lplist()
 134: {
 135:     register lispval atm;
 136:     /* get property list of an atom or disembodied property list */
 137: 
 138:     chkarg(1,"plist");
 139:     atm = lbot->val;
 140:     switch(TYPE(atm)) {
 141:     case ATOM:
 142:     case DTPR:
 143:         break;
 144:     default:
 145:         error("Only Atoms and disembodied property lists allowed for plist",FALSE);
 146:     }
 147:     if(atm==nil) return(nilplist);
 148:     return(atm->a.plist);
 149: }
 150: 
 151: 
 152: lispval
 153: Lsetpli()
 154: {   /* set the property list of the given atom to the given list */
 155:     register lispval atm, vall;
 156: 
 157:     chkarg(2,"setplist");
 158:     atm = lbot->val;
 159:     if (TYPE(atm) != ATOM)
 160:        error("setplist: First argument must be an symbol",FALSE);
 161:     vall = (np-1)->val;
 162:     if (TYPE(vall)!= DTPR && vall !=nil)
 163:         error("setplist: Second argument must be a list",FALSE);
 164:     if (atm==nil)
 165:         nilplist = vall;
 166:     else
 167:         atm->a.plist = vall;
 168:     return(vall);
 169: }
 170: 
 171: lispval
 172: Lsignal()
 173: {
 174:     register lispval handy, old, routine;
 175:     int i;
 176:     int sginth();
 177: 
 178:     switch(np-lbot) {
 179: 
 180:     case 1: routine = nil;      /* second arg defaults to nil */
 181:         break;
 182: 
 183:     case 2: routine = lbot[1].val;
 184:         break;          /* both args given 		*/
 185: 
 186:     default: argerr("signal");
 187:     }
 188: 
 189:     handy = lbot->val;
 190:     if(TYPE(handy)!=INT)
 191:         error("First arg to signal must be an int",FALSE);
 192:     i = handy->i & 15;
 193: 
 194:     if(TYPE(routine)!=ATOM)
 195:         error("Second arg to signal must be an atom",FALSE);
 196:     old = sigacts[i];
 197: 
 198:     if(old==0) old = nil;
 199: 
 200:     if(routine==nil)
 201:         sigacts[i]=((lispval) 0);
 202:     else
 203:         sigacts[i]=routine;
 204:     if(routine == nil)
 205:         signal(i,SIG_IGN);  /* ignore this signals */
 206:     else if (old == nil)
 207:         signal(i,sginth);   /* look for this signal */
 208:     if(i == SIGINT) sigintcnt = 0; /* clear memory */
 209:     return(old);
 210: }
 211: 
 212: lispval
 213: Lassq()
 214: {
 215:     register lispval work, handy;
 216: 
 217:     chkarg(2,"assq");
 218: 
 219:     for(work = lbot[1].val, handy = lbot[0].val;
 220:         (work->d.car->d.car != handy) && (work != nil);
 221:         work = work->d.cdr);
 222:     return(work->d.car);
 223: }
 224: 
 225: lispval
 226: Lkilcopy()
 227: {
 228:     if(fork()==0) {
 229:         abort();
 230:     }
 231: }
 232: 
 233: lispval
 234: Larg()
 235: {
 236:     register lispval handy; register offset, count;
 237: 
 238:     handy = lexpr_atom->a.clb;
 239:     if(handy==CNIL || TYPE(handy)!=DTPR)
 240:         error("Arg: not in context of Lexpr.",FALSE);
 241:     count = ((long *)handy->d.cdr) -1 - (long *)handy->d.car;
 242:     if(np==lbot || lbot->val==nil)
 243:         return(inewint(count+1));
 244:     if(TYPE(lbot->val)!=INT || (offset = lbot->val->i - 1) > count || offset < 0 )
 245:         error("Out of bounds: arg to \"Arg\"",FALSE);
 246:     return( ((struct argent *)handy->d.car)[offset].val);
 247: }
 248: 
 249: lispval
 250: Lsetarg()
 251: {
 252:     register lispval handy, work;
 253:     register limit, index;
 254: 
 255:     chkarg(2,"setarg");
 256:     handy = lexpr_atom->a.clb;
 257:     if(handy==CNIL || TYPE(handy)!=DTPR)
 258:         error("Arg: not in context of Lexpr.",FALSE);
 259:     limit = ((long *)handy->d.cdr) - 1 -  (long *)(work = handy->d.car);
 260:     handy = lbot->val;
 261:     if(TYPE(handy)!=INT)
 262:         error("setarg: first argument not integer",FALSE);
 263:     if((index = handy->i - 1) < 0 || index > limit)
 264:         error("setarg: index out of range",FALSE);
 265:     return(((struct argent *) work)[index].val = lbot[1].val);
 266: }
 267: 
 268: lispval
 269: Lptime(){
 270:     extern int gctime;
 271:     int lgctime = gctime;
 272:     struct tms current;
 273:     register lispval result, handy;
 274:     Savestack(2);
 275: 
 276:     times(&current);
 277:     result = newdot();
 278:     handy = result;
 279:     protect(result);
 280:     result->d.cdr = newdot();
 281:     result->d.car = inewint(current.tms_utime);
 282:     handy = result->d.cdr;
 283:     handy->d.car = inewint(lgctime);
 284:     handy->d.cdr = nil;
 285:     if(gctime==0)
 286:         gctime = 1;
 287:     Restorestack();
 288:     return(result);
 289: }
 290: 
 291: /* (err-with-message message [value])
 292:    'message' is the error message to print.
 293:    'value' is the value to return from the errset (if present).
 294: 	it defaults to nil.
 295:     The message may not be printed if there is an (errset ... nil)
 296:     pending.
 297:  */
 298: 
 299: lispval Lerr()
 300: {
 301:     lispval errorh();
 302:     lispval valret = nil;
 303:     char *mesg;
 304: 
 305: 
 306:     switch(np-lbot) {
 307:      case 2: valret = lbot[1].val;  /* return non nil */
 308:      case 1: mesg = (char *)verify(lbot[0].val,
 309:                   "err-with-message: non atom or string arg");
 310:          break;
 311:      default: argerr("err-with-message");
 312:     }
 313: 
 314:     return(errorh(Vererr,mesg,valret,FALSE,1));
 315: }
 316: 
 317: /*
 318:  *  (tyi ['p_port ['g_eofval]])
 319:  * normally -1 is return on eof, but g_eofval will be returned if given.
 320:  */
 321: lispval
 322: Ltyi()
 323: {
 324:     register FILE *port;
 325:     register lispval handy;
 326:     lispval eofval;
 327:     int val;    /* really char but getc returns int on eof */
 328:     int eofvalgiven;
 329: 
 330:     handy = nil;   /* default port */
 331:     eofvalgiven = FALSE;  /* assume no eof value given */
 332:     switch(np-lbot)
 333:     {
 334:         case 2:  eofval = lbot[1].val;
 335:                  eofvalgiven = TRUE;
 336:         case 1:  handy = lbot[0].val;   /* port to read */
 337:         case 0:
 338:              break;
 339:         default: argerr("tyi");
 340:     }
 341: 
 342:     port = okport(handy,okport(Vpiport->a.clb,stdin));
 343: 
 344: 
 345:     fflush(stdout);     /* flush any pending output characters */
 346:     val = getc(port);
 347:     if(val==EOF)
 348:     {
 349:         clearerr(port);
 350:         if(sigintcnt > 0) sigcall(SIGINT);  /* eof might mean int */
 351:         if(eofvalgiven) return(eofval);
 352:         else return(inewint(-1));
 353:     }
 354:     return(inewint(val));
 355: }
 356: 
 357: /* Untyi (added by DNC Feb. '80) - (untyi number port) puts the
 358:    character with ascii code number in the front of the input buffer of
 359:    port.  Note that this buffer is limited to 1 character.  That buffer is
 360:    also written by tyipeek, so a peek followed by an untyi will result in
 361:    the loss of the peeked char.
 362:  */
 363: 
 364: lispval
 365: Luntyi()
 366: {
 367: 
 368:     lispval port,ch;
 369: 
 370:     port = nil;
 371: 
 372:     switch(np-lbot) {
 373:     case 2: port = lbot[1].val;
 374:     case 1: ch = lbot[0].val;
 375:         break;
 376:     default:
 377:         argerr("untyi");
 378:     }
 379: 
 380:     if(TYPE(ch) != INT) {
 381:        errorh1(Vermisc, "untyi: expects fixnum character ",
 382:                 nil,FALSE,0,ch);
 383:     }
 384: 
 385:     ungetc((int) ch->i,okport(port,okport(Vpiport->a.clb,stdin)));
 386:     return(ch);
 387: }
 388: 
 389: lispval
 390: Ltyipeek()
 391: {
 392:     register FILE *port;
 393:     register lispval handy;
 394:     int val;
 395: 
 396:     switch(np-lbot)
 397:     {
 398:         case 0:  handy = nil;   /* default port */
 399:              break;
 400:         case 1:  handy = lbot->val;
 401:              break;
 402:         default: argerr("tyipeek");
 403:     }
 404: 
 405:     port = okport(handy,okport(Vpiport->a.clb,stdin));
 406: 
 407:     fflush(stdout);     /* flush any pending output characters */
 408:     val = getc(port);
 409:     if(val==EOF)
 410:         clearerr(port);
 411:     ungetc(val,port);
 412:     return(inewint(val));
 413: }
 414: 
 415: lispval
 416: Ltyo()
 417: {
 418:     register FILE *port;
 419:     register lispval handy, where;
 420:     char val;
 421: 
 422:     switch(np-lbot)
 423:     {
 424:         case 1:  where = nil;   /* default port */
 425:              break;
 426:         case 2:  where = lbot[1].val;
 427:              break;
 428:         default: argerr("tyo");
 429:     }
 430: 
 431:     handy = lbot->val;
 432:     if(TYPE(handy)!=INT)
 433:         error("Tyo demands number for 1st arg",FALSE);
 434:     val = handy->i;
 435: 
 436:     port = (FILE *) okport(where,okport(Vpoport->a.clb,stdout));
 437:     putc(val,port);
 438:     return(handy);
 439: }
 440: 
 441: lispval
 442: Imkrtab(current)
 443: {
 444:     extern struct rtab {
 445:         unsigned char ctable[132];
 446:     } initread;
 447:     register lispval handy; extern lispval lastrtab;
 448: 
 449:     static int cycle = 0;
 450:     static char *nextfree;
 451:     Savestack(3);
 452: 
 453:     if((cycle++)%3==0) {
 454:         nextfree = (char *) csegment(STRNG,1,FALSE);
 455:         mrtabspace = (lispval) nextfree;
 456:         /* need to protect partially allocated read tables
 457: 		   from garbage collection. */
 458:     }
 459:     handy = newarray();
 460:     protect(handy);
 461: 
 462:     handy->ar.data = nextfree;
 463:     if(current == 0)
 464:         *(struct rtab *)nextfree = initread;
 465:     else
 466:     {
 467:         register index = 0; register char *cp = nextfree;
 468:         lispval c;
 469: 
 470:         *(struct rtab *)cp = *(struct rtab *)ctable;
 471:         for(; index < 128; index++) {
 472:             switch(synclass(cp[index])) {
 473:             case CSPL: case CSSPL: case CMAC: case CSMAC:
 474:             case CINF: case CSINF:
 475:             strbuf[0] = index;
 476:             strbuf[1] = 0;
 477:             c = (getatom(TRUE));
 478:             Iputprop(c,Iget(c,lastrtab),handy);
 479:             }
 480:         }
 481:     }
 482:     handy->ar.delta = inewint(4);
 483:     handy->ar.length = inewint(sizeof(struct rtab)/sizeof(int));
 484:     handy->ar.accfun = handy->ar.aux  = nil;
 485:     nextfree += sizeof(struct rtab);
 486:     Restorestack();
 487:     return(handy);
 488: }
 489: 
 490: /* makereadtable - arg : t or nil
 491: 	returns a readtable, t means return a copy of the initial readtable
 492: 
 493: 			     nil means return a copy of the current readtable
 494: */
 495: lispval
 496: Lmakertbl()
 497: {
 498:     lispval handy = Vreadtable->a.clb;
 499:     lispval value;
 500:     chkrtab(handy);
 501: 
 502:     if(lbot==np) value = nil;
 503:     else if(TYPE(value=(lbot->val)) != ATOM)
 504:         error("makereadtable: arg must be atom",FALSE);
 505: 
 506:     if(value == nil) return(Imkrtab(1));
 507:     else return(Imkrtab(0));
 508: }
 509: 
 510: lispval
 511: Lcpy1()
 512: {
 513:     register lispval handy = lbot->val, result = handy;
 514: 
 515: top:
 516:     switch(TYPE(handy))
 517:     {
 518:     case INT:
 519:         result = inewint(handy->i);
 520:         break;
 521:     case VALUE:
 522:         (result = newval())->l = handy->l;
 523:         break;
 524:     case DOUB:
 525:         (result = newdoub())->r = handy->r;
 526:         break;
 527:     default:
 528:         lbot->val =
 529:             errorh1(Vermisc,"Bad arg to cpy1",nil,TRUE,67,handy);
 530:         goto top;
 531:     }
 532:     return(result);
 533: }
 534: 
 535: /* copyint* . This returns a copy of its integer argument.  The copy will
 536:  *	 be a fresh integer cell, and will not point into the read only
 537:  *	 small integer table.
 538:  */
 539: lispval
 540: Lcopyint()
 541: {
 542:     register lispval handy = lbot->val;
 543:     register lispval ret;
 544: 
 545:     while (TYPE(handy) != INT)
 546:     { handy=errorh1(Vermisc,"copyint* : non integer arg",nil,TRUE,0,handy);}
 547:     (ret = newint())->i = handy->i;
 548:     return(ret);
 549: }

Defined functions

Imkrtab defined in line 441; used 4 times
Larg defined in line 233; never used
Lassq defined in line 212; never used
Lboundp defined in line 115; never used
Lcopyint defined in line 539; never used
Lcpy1 defined in line 510; never used
Lerr defined in line 299; never used
Lgetenv defined in line 98; never used
Lkilcopy defined in line 225; never used
Lmakertbl defined in line 495; never used
Lplist defined in line 132; used 1 times
Lptime defined in line 268; never used
Lreadli defined in line 22; never used
Lsetarg defined in line 249; never used
Lsetpli defined in line 152; never used
Lsignal defined in line 171; never used
Ltyi defined in line 321; never used
Ltyipeek defined in line 389; never used
Ltyo defined in line 415; never used
Luntyi defined in line 364; never used

Defined variables

rcsid defined in line 2; never used

Defined struct's

rtab defined in line 444; used 10 times
Last modified: 1985-08-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1341
Valid CSS Valid XHTML 1.0 Strict