|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid = ! 3: "$Header: lam1.c,v 1.7 85/03/24 11:04:00 sklower Exp $"; ! 4: #endif ! 5: ! 6: /* -[Fri Feb 17 16:44:24 1984 by layer]- ! 7: * lam1.c $Locker: $ ! 8: * lambda functions ! 9: * ! 10: * (c) copyright 1982, Regents of the University of California ! 11: */ ! 12: ! 13: # include "global.h" ! 14: # include <sgtty.h> ! 15: # include "chkrtab.h" ! 16: # include "frame.h" ! 17: ! 18: lispval ! 19: Leval() ! 20: { ! 21: register lispval temp; ! 22: ! 23: chkarg(1,"eval"); ! 24: temp = lbot->val; ! 25: return(eval(temp)); ! 26: } ! 27: ! 28: lispval ! 29: Lxcar() ! 30: { register int typ; ! 31: register lispval temp, result; ! 32: ! 33: chkarg(1,"xcar"); ! 34: temp = lbot->val; ! 35: if (((typ = TYPE(temp)) == DTPR) || (typ == ATOM) || HUNKP(temp)) ! 36: return(temp->d.car); ! 37: else if(typ == SDOT) { ! 38: result = inewint(temp->i); ! 39: return(result); ! 40: } else if(Schainp!=nil && typ==ATOM) ! 41: return(nil); ! 42: else ! 43: return(error("Bad arg to car",FALSE)); ! 44: ! 45: } ! 46: ! 47: lispval ! 48: Lxcdr() ! 49: { register int typ; ! 50: register lispval temp; ! 51: ! 52: chkarg(1,"xcdr"); ! 53: temp = lbot->val; ! 54: if(temp==nil) return (nil); ! 55: ! 56: if (((typ = TYPE(temp)) == DTPR) || HUNKP(temp)) ! 57: return(temp->d.cdr); ! 58: else if(typ==SDOT) { ! 59: if(temp->s.CDR==0) return(nil); ! 60: temp = temp->s.CDR; ! 61: if(TYPE(temp)==DTPR) ! 62: errorh1(Vermisc,"Fell off the end of a bignum",nil,FALSE,5,lbot->val); ! 63: return(temp); ! 64: } else if(Schainp!=nil && typ==ATOM) ! 65: return(nil); ! 66: else ! 67: return(error("Bad arg to cdr", FALSE)); ! 68: } ! 69: ! 70: lispval ! 71: cxxr(as,ds) ! 72: register int as,ds; ! 73: { ! 74: ! 75: register lispval temp, temp2; ! 76: int i, typ; ! 77: lispval errorh(); ! 78: ! 79: chkarg(1,"c{ad}+r"); ! 80: temp = lbot->val; ! 81: ! 82: for( i=0 ; i<ds ; i++) ! 83: { ! 84: if( temp != nil) ! 85: { ! 86: typ = TYPE(temp); ! 87: if ((typ == DTPR) || HUNKP(temp)) ! 88: temp = temp->d.cdr; ! 89: else ! 90: if(typ==SDOT) ! 91: { ! 92: if(temp->s.CDR==0) ! 93: temp = nil; ! 94: else ! 95: temp = temp->s.CDR; ! 96: if(TYPE(temp)==DTPR) ! 97: errorh1(Vermisc,"Fell off the end of a bignum",nil,FALSE,5,lbot->val); ! 98: } ! 99: else ! 100: if(Schainp!=nil && typ==ATOM) ! 101: return(nil); ! 102: else ! 103: return(errorh1(Vermisc,"Bad arg to cdr",nil,FALSE,5,temp)); ! 104: } ! 105: } ! 106: ! 107: for( i=0 ; i<as ; i++) ! 108: { ! 109: if( temp != nil ) ! 110: { ! 111: typ = TYPE(temp); ! 112: if ((typ == DTPR) || HUNKP(temp)) ! 113: temp = temp->d.car; ! 114: else if(typ == SDOT) ! 115: temp2 = inewint(temp->i), temp = temp2; ! 116: else if(Schainp!=nil && typ==ATOM) ! 117: return(nil); ! 118: else ! 119: return(errorh1(Vermisc,"Bad arg to car",nil,FALSE,5,temp)); ! 120: } ! 121: } ! 122: ! 123: return(temp); ! 124: } ! 125: ! 126: lispval ! 127: Lcar() ! 128: { return(cxxr(1,0)); } ! 129: ! 130: lispval ! 131: Lcdr() ! 132: { return(cxxr(0,1)); } ! 133: ! 134: lispval ! 135: Lcadr() ! 136: { return(cxxr(1,1)); } ! 137: ! 138: lispval ! 139: Lcaar() ! 140: { return(cxxr(2,0)); } ! 141: ! 142: lispval ! 143: Lc02r() ! 144: { return(cxxr(0,2)); } /* cddr */ ! 145: ! 146: lispval ! 147: Lc12r() ! 148: { return(cxxr(1,2)); } /* caddr */ ! 149: ! 150: lispval ! 151: Lc03r() ! 152: { return(cxxr(0,3)); } /* cdddr */ ! 153: ! 154: lispval ! 155: Lc13r() ! 156: { return(cxxr(1,3)); } /* cadddr */ ! 157: ! 158: lispval ! 159: Lc04r() ! 160: { return(cxxr(0,4)); } /* cddddr */ ! 161: ! 162: lispval ! 163: Lc14r() ! 164: { return(cxxr(1,4)); } /* caddddr */ ! 165: ! 166: /* ! 167: * ! 168: * (nthelem num list) ! 169: * ! 170: * Returns the num'th element of the list, by doing a caddddd...ddr ! 171: * where there are num-1 d's. If num<=0 or greater than the length of ! 172: * the list, we return nil. ! 173: * ! 174: */ ! 175: ! 176: lispval ! 177: Lnthelem() ! 178: { ! 179: register lispval temp; ! 180: register int i; ! 181: ! 182: chkarg(2,"nthelem"); ! 183: ! 184: if( TYPE(temp = lbot->val) != INT) ! 185: return (error ("First arg to nthelem must be a fixnum",FALSE)); ! 186: ! 187: i = temp->i; /* pick up the first arg */ ! 188: ! 189: if( i <= 0) return(nil); ! 190: ! 191: ++lbot; /* fix lbot for call to cxxr() 'cadddd..r' */ ! 192: temp = cxxr(1,i-1); ! 193: --lbot; ! 194: ! 195: return(temp); ! 196: } ! 197: ! 198: lispval ! 199: Lscons() ! 200: { ! 201: register struct argent *argp = lbot; ! 202: register lispval retp, handy; ! 203: ! 204: chkarg(2,"scons"); ! 205: retp = newsdot(); ! 206: handy = (argp) -> val; ! 207: if(TYPE(handy)!=INT) ! 208: error("First arg to scons must be an int.",FALSE); ! 209: retp->s.I = handy->i; ! 210: handy = (argp+1)->val; ! 211: if(handy==nil) ! 212: retp->s.CDR = (lispval) 0; ! 213: else { ! 214: if(TYPE(handy)!=SDOT) ! 215: error("Currently you may only link sdots to sdots.",FALSE); ! 216: retp->s.CDR = handy; ! 217: } ! 218: return(retp); ! 219: } ! 220: ! 221: lispval ! 222: Lbigtol(){ ! 223: register lispval handy,newp; ! 224: ! 225: chkarg(1,"Bignum-to-list"); ! 226: handy = lbot->val; ! 227: while(TYPE(handy)!=SDOT) ! 228: handy = errorh1(Vermisc, ! 229: "Non bignum argument to Bignum-to-list", ! 230: nil,TRUE,5755,handy); ! 231: protect(newp = newdot()); ! 232: while(handy) { ! 233: newp->d.car = inewint((long)handy->s.I); ! 234: if(handy->s.CDR==(lispval) 0) break; ! 235: newp->d.cdr = newdot(); ! 236: newp = newp->d.cdr; ! 237: handy = handy->s.CDR; ! 238: } ! 239: handy = (--np)->val; ! 240: return(handy); ! 241: } ! 242: ! 243: lispval ! 244: Lcons() ! 245: { ! 246: register lispval retp; ! 247: register struct argent *argp; ! 248: ! 249: chkarg(2,"cons"); ! 250: retp = newdot(); ! 251: retp->d.car = ((argp = lbot) -> val); ! 252: retp->d.cdr = argp[1].val; ! 253: return(retp); ! 254: } ! 255: #define CA 0 ! 256: #define CD 1 ! 257: ! 258: lispval ! 259: rpla(what) ! 260: int what; ! 261: { register struct argent *argp; ! 262: register int typ; register lispval first, second; ! 263: ! 264: chkarg(2,"rplac[ad]"); ! 265: argp = np-1; ! 266: first = (argp-1)->val; ! 267: while(first==nil) ! 268: first = error("Attempt to rplac[ad] nil.",TRUE); ! 269: second = argp->val; ! 270: if (((typ = TYPE(first)) == DTPR) || (typ == ATOM) || HUNKP(first)) { ! 271: if (what == CA) ! 272: first->d.car = second; ! 273: else ! 274: first->d.cdr = second; ! 275: return(first); ! 276: } ! 277: if (typ==SDOT) { ! 278: if(what == CA) { ! 279: typ = TYPE(second); ! 280: if(typ!=INT) error("Rplacca of a bignum will only replace INTS",FALSE); ! 281: first->s.I = second->i; ! 282: } else { ! 283: if(second==nil) ! 284: first->s.CDR = (lispval) 0; ! 285: else ! 286: first->s.CDR = second; ! 287: } ! 288: return(first); ! 289: } ! 290: return(error("Bad arg to rpla",FALSE)); ! 291: } ! 292: lispval ! 293: Lrplca() ! 294: { return(rpla(CA)); } ! 295: ! 296: lispval ! 297: Lrplcd() ! 298: { return(rpla(CD)); } ! 299: ! 300: ! 301: lispval ! 302: Leq() ! 303: { ! 304: register struct argent *mynp = lbot + AD; ! 305: ! 306: chkarg(2,"eq"); ! 307: if(mynp->val==(mynp+1)->val) return(tatom); ! 308: return(nil); ! 309: } ! 310: ! 311: ! 312: ! 313: lispval ! 314: Lnull() ! 315: { chkarg(1,"null"); ! 316: return ((lbot->val == nil) ? tatom : nil); ! 317: } ! 318: ! 319: ! 320: ! 321: /* Lreturn **************************************************************/ ! 322: /* Returns the first argument - which is nill if not specified. */ ! 323: ! 324: lispval ! 325: Lreturn() ! 326: { ! 327: if(lbot==np) protect (nil); ! 328: Inonlocalgo(C_RET,lbot->val,nil); ! 329: /* NOT REACHED */ ! 330: } ! 331: ! 332: ! 333: lispval ! 334: Linfile() ! 335: { ! 336: FILE *port; ! 337: register lispval name; ! 338: ! 339: chkarg(1,"infile"); ! 340: name = lbot->val; ! 341: loop: ! 342: name = verify(name,"infile: file name must be atom or string"); ! 343: /* return nil if file couldnt be opened ! 344: if ((port = fopen((char *)name,"r")) == NULL) return(nil); */ ! 345: ! 346: if ((port = fopen((char *)name,"r")) == NULL) { ! 347: name = errorh1(Vermisc,"Unable to open file for reading.",nil,TRUE,31,name); ! 348: goto loop; ! 349: } ! 350: ioname[PN(port)] = (lispval) inewstr((char *)name); /* remember name */ ! 351: return(P(port)); ! 352: } ! 353: ! 354: /* outfile - open a file for writing. ! 355: * 27feb81 [jkf] - modifed to accept two arguments, the second one being a ! 356: * string or atom, which if it begins with an `a' tells outfile to open the ! 357: * file in append mode ! 358: */ ! 359: lispval ! 360: Loutfile() ! 361: { ! 362: FILE *port; register lispval name; ! 363: char *mode ="w"; /* mode is w for create new file, a for append */ ! 364: char *given; ! 365: ! 366: if(lbot+1== np) protect(nil); ! 367: chkarg(2,"outfile"); ! 368: name = lbot->val; ! 369: given = (char *)verify((lbot+1)->val,"Illegal file open mode."); ! 370: if(*given == 'a') mode = "a"; ! 371: loop: ! 372: name = verify(name,"Please supply atom or string name for port."); ! 373: #ifdef os_vms ! 374: /* ! 375: * If "w" mode, open it as a "txt" file for convenience in VMS ! 376: */ ! 377: if (strcmp(mode,"w") == 0) { ! 378: int fd; ! 379: ! 380: if ((fd = creat(name,0777,"txt")) < 0) { ! 381: name = errorh1(Vermisc,"Unable to open file for writing.",nil,TRUE,31,name); ! 382: goto loop; ! 383: } ! 384: port = fdopen(fd,mode); ! 385: } else ! 386: #endif ! 387: if ((port = fopen((char *)name,mode)) == NULL) { ! 388: name = errorh1(Vermisc,"Unable to open file for writing.",nil,TRUE,31,name); ! 389: goto loop; ! 390: } ! 391: ioname[PN(port)] = (lispval) inewstr((char *)name); ! 392: return(P(port)); ! 393: } ! 394: ! 395: lispval ! 396: Lterpr() ! 397: { ! 398: register lispval handy; ! 399: FILE *port; ! 400: ! 401: if(lbot==np) handy = nil; ! 402: else ! 403: { ! 404: chkarg(1,"terpr"); ! 405: handy = lbot->val; ! 406: } ! 407: ! 408: port = okport(handy,okport(Vpoport->a.clb,stdout)); ! 409: putc('\n',port); ! 410: fflush(port); ! 411: return(nil); ! 412: } ! 413: ! 414: lispval ! 415: Lclose() ! 416: { ! 417: lispval port; ! 418: ! 419: chkarg(1,"close"); ! 420: port = lbot->val; ! 421: if((TYPE(port))==PORT) { ! 422: fclose(port->p); ! 423: ioname[PN(port->p)] = nil; ! 424: return(tatom); ! 425: } ! 426: errorh1(Vermisc,"close:Non-port",nil,FALSE,987,port); ! 427: /* not reached */ ! 428: } ! 429: ! 430: lispval ! 431: Ltruename() ! 432: { ! 433: chkarg(1,"truename"); ! 434: if(TYPE(lbot->val) != PORT) ! 435: errorh1(Vermisc,"truename: non port argument",nil,FALSE,0,lbot->val); ! 436: ! 437: return(ioname[PN(lbot->val->p)]); ! 438: } ! 439: ! 440: lispval ! 441: Lnwritn() ! 442: { ! 443: register FILE *port; ! 444: register value; ! 445: register lispval handy; ! 446: ! 447: if(lbot==np) handy = nil; ! 448: else ! 449: { ! 450: chkarg(1,"nwritn"); ! 451: handy = lbot->val; ! 452: } ! 453: ! 454: port = okport(handy,okport(Vpoport->a.clb,stdout)); ! 455: value = port->_ptr - port->_base; ! 456: return(inewint(value)); ! 457: } ! 458: ! 459: lispval ! 460: Ldrain() ! 461: { ! 462: register FILE *port; ! 463: register int iodes; ! 464: register lispval handy; ! 465: struct sgttyb arg; ! 466: ! 467: if(lbot==np) handy = nil; ! 468: else ! 469: { ! 470: chkarg(1,"nwritn"); ! 471: handy = lbot->val; ! 472: } ! 473: port = okport(handy, okport(Vpoport->a.clb,stdout)); ! 474: if(port->_flag & _IOWRT) { ! 475: fflush(port); ! 476: return(nil); ! 477: } ! 478: if(! port->_flag & _IOREAD) return(nil); ! 479: port->_cnt = 0; ! 480: port->_ptr = port->_base; ! 481: iodes = fileno(port); ! 482: if(gtty(iodes,&arg) != -1) stty(iodes,&arg); ! 483: return(P(port)); ! 484: } ! 485: ! 486: lispval ! 487: Llist() ! 488: { ! 489: /* added for the benefit of mapping functions. */ ! 490: register struct argent *ulim, *namptr; ! 491: register lispval temp, result; ! 492: Savestack(4); ! 493: ! 494: ulim = np; ! 495: namptr = lbot + AD; ! 496: temp = result = (lispval) np; ! 497: protect(nil); ! 498: for(; namptr < ulim;) { ! 499: temp = temp->l = newdot(); ! 500: temp->d.car = (namptr++)->val; ! 501: } ! 502: temp->l = nil; ! 503: Restorestack(); ! 504: return(result->l); ! 505: } ! 506: ! 507: lispval ! 508: Lnumberp() ! 509: { ! 510: chkarg(1,"numberp"); ! 511: switch(TYPE(lbot->val)) { ! 512: case INT: case DOUB: case SDOT: ! 513: return(tatom); ! 514: } ! 515: return(nil); ! 516: } ! 517: ! 518: lispval ! 519: Latom() ! 520: { ! 521: register struct argent *lb = lbot; ! 522: chkarg(1,"atom"); ! 523: if(TYPE(lb->val)==DTPR || (HUNKP(lb->val))) ! 524: return(nil); ! 525: else ! 526: return(tatom); ! 527: } ! 528: ! 529: lispval ! 530: Ltype() ! 531: { ! 532: chkarg(1,"type"); ! 533: switch(TYPE(lbot->val)) { ! 534: case INT: ! 535: return(int_name); ! 536: case ATOM: ! 537: return(atom_name); ! 538: case SDOT: ! 539: return(sdot_name); ! 540: case DOUB: ! 541: return(doub_name); ! 542: case DTPR: ! 543: return(dtpr_name); ! 544: case STRNG: ! 545: return(str_name); ! 546: case ARRAY: ! 547: return(array_name); ! 548: case BCD: ! 549: return(funct_name); ! 550: case OTHER: ! 551: return(other_name); ! 552: ! 553: case HUNK2: ! 554: return(hunk_name[0]); ! 555: case HUNK4: ! 556: return(hunk_name[1]); ! 557: case HUNK8: ! 558: return(hunk_name[2]); ! 559: case HUNK16: ! 560: return(hunk_name[3]); ! 561: case HUNK32: ! 562: return(hunk_name[4]); ! 563: case HUNK64: ! 564: return(hunk_name[5]); ! 565: case HUNK128: ! 566: return(hunk_name[6]); ! 567: ! 568: case VECTOR: ! 569: return(vect_name); ! 570: case VECTORI: ! 571: return(vecti_name); ! 572: ! 573: case VALUE: ! 574: return(val_name); ! 575: case PORT: ! 576: return(port_name); ! 577: } ! 578: return(nil); ! 579: } ! 580: ! 581: lispval ! 582: Ldtpr() ! 583: { ! 584: chkarg(1,"dtpr"); ! 585: return(typred(DTPR, lbot->val)); ! 586: } ! 587: ! 588: lispval ! 589: Lbcdp() ! 590: { ! 591: chkarg(1,"bcdp"); ! 592: return(typred(BCD, lbot->val)); ! 593: } ! 594: ! 595: lispval ! 596: Lportp() ! 597: { ! 598: chkarg(1,"portp"); ! 599: return(typred(PORT, lbot->val)); ! 600: } ! 601: ! 602: lispval ! 603: Larrayp() ! 604: { ! 605: chkarg(1,"arrayp"); ! 606: return(typred(ARRAY, lbot->val)); ! 607: } ! 608: ! 609: /* ! 610: * (hunkp 'g_arg1) ! 611: * Returns t if g_arg1 is a hunk, otherwise returns nil. ! 612: */ ! 613: ! 614: lispval ! 615: Lhunkp() ! 616: { ! 617: chkarg(1,"hunkp"); ! 618: if (HUNKP(lbot->val)) ! 619: return(tatom); /* If a hunk, return t */ ! 620: else ! 621: return(nil); /* else nil */ ! 622: } ! 623: ! 624: lispval ! 625: Lset() ! 626: { ! 627: lispval varble; ! 628: ! 629: chkarg(2,"set"); ! 630: varble = lbot->val; ! 631: switch(TYPE(varble)) ! 632: { ! 633: case ATOM: return(varble->a.clb = lbot[1].val); ! 634: ! 635: case VALUE: return(varble->l = lbot[1].val); ! 636: } ! 637: ! 638: error("IMPROPER USE OF SET",FALSE); ! 639: /* NOTREACHED */ ! 640: } ! 641: ! 642: lispval ! 643: Lequal() ! 644: { ! 645: register lispval first, second; ! 646: register type1, type2; ! 647: lispval Lsub(),Lzerop(); ! 648: long *oldsp; ! 649: Keepxs(); ! 650: chkarg(2,"equal"); ! 651: ! 652: ! 653: if(lbot->val==lbot[1].val) return(tatom); ! 654: ! 655: oldsp=sp(); stack((long)lbot->val);stack((long)lbot[1].val); ! 656: for(;oldsp > sp();) { ! 657: ! 658: first = (lispval) unstack(); second = (lispval) unstack(); ! 659: again: ! 660: if(first==second) continue; ! 661: ! 662: type1=TYPE(first); type2=TYPE(second); ! 663: if(type1!=type2) { ! 664: if((type1==SDOT&&type2==INT)||(type1==INT&&type2==SDOT)) ! 665: goto dosub; ! 666: {Freexs(); return(nil);} ! 667: } ! 668: switch(type1) { ! 669: case DTPR: ! 670: stack((long)first->d.cdr); stack((long)second->d.cdr); ! 671: first = first->d.car; second = second->d.car; ! 672: goto again; ! 673: case DOUB: ! 674: if(first->r!=second->r) ! 675: {Freexs(); return(nil);} ! 676: continue; ! 677: case INT: ! 678: if(first->i!=second->i) ! 679: {Freexs(); return(nil);} ! 680: continue; ! 681: case VECTOR: ! 682: if(!vecequal(first,second)) {Freexs(); return(nil);} ! 683: continue; ! 684: case VECTORI: ! 685: if(!veciequal(first,second)) {Freexs(); return(nil);} ! 686: continue; ! 687: dosub: ! 688: case SDOT: { ! 689: lispval temp; ! 690: struct argent *OLDlbot = lbot; ! 691: lbot = np; ! 692: np++->val = first; ! 693: np++->val = second; ! 694: temp = Lsub(); ! 695: np = lbot; ! 696: lbot = OLDlbot; ! 697: if(TYPE(temp)!=INT || temp->i!=0) ! 698: {Freexs(); return(nil);} ! 699: } ! 700: continue; ! 701: case VALUE: ! 702: if(first->l!=second->l) ! 703: {Freexs(); return(nil);} ! 704: continue; ! 705: case STRNG: ! 706: if(strcmp((char *)first,(char *)second)!=0) ! 707: {Freexs(); return(nil);} ! 708: continue; ! 709: ! 710: default: ! 711: {Freexs(); return(nil);} ! 712: } ! 713: } ! 714: {Freexs(); return(tatom);} ! 715: } ! 716: lispval ! 717: oLequal() ! 718: { ! 719: chkarg(2,"equal"); ! 720: ! 721: if( lbot[1].val == lbot->val ) return(tatom); ! 722: if(Iequal(lbot[1].val,lbot->val)) return(tatom); else return(nil); ! 723: } ! 724: ! 725: Iequal(first,second) ! 726: register lispval first, second; ! 727: { ! 728: register type1, type2; ! 729: lispval Lsub(),Lzerop(); ! 730: ! 731: if(first==second) ! 732: return(1); ! 733: type1=TYPE(first); ! 734: type2=TYPE(second); ! 735: if(type1!=type2) { ! 736: if((type1==SDOT&&type2==INT)||(type1==INT&&type2==SDOT)) ! 737: goto dosub; ! 738: return(0); ! 739: } ! 740: switch(type1) { ! 741: case DTPR: ! 742: return( ! 743: Iequal(first->d.car,second->d.car) && ! 744: Iequal(first->d.cdr,second->d.cdr) ); ! 745: case DOUB: ! 746: return(first->r==second->r); ! 747: case INT: ! 748: return( (first->i==second->i)); ! 749: dosub: ! 750: case SDOT: ! 751: { ! 752: lispval temp; ! 753: struct argent *OLDlbot = lbot; ! 754: lbot = np; ! 755: np++->val = first; ! 756: np++->val = second; ! 757: temp = Lsub(); ! 758: np = lbot; ! 759: lbot = OLDlbot; ! 760: return(TYPE(temp)==INT&& temp->i==0); ! 761: } ! 762: case VALUE: ! 763: return( first->l==second->l ); ! 764: case STRNG: ! 765: return(strcmp((char *)first,(char *)second)==0); ! 766: } ! 767: return(0); ! 768: } ! 769: lispval ! 770: Zequal() ! 771: { ! 772: register lispval first, second; ! 773: register type1, type2; ! 774: lispval Lsub(),Lzerop(); ! 775: long *oldsp; ! 776: Keepxs(); ! 777: chkarg(2,"equal"); ! 778: ! 779: ! 780: if(lbot->val==lbot[1].val) return(tatom); ! 781: ! 782: oldsp=sp(); stack((long)lbot->val);stack((long)lbot[1].val); ! 783: ! 784: for(;oldsp > sp();) { ! 785: ! 786: first = (lispval) unstack(); second = (lispval) unstack(); ! 787: again: ! 788: if(first==second) continue; ! 789: ! 790: type1=TYPE(first); type2=TYPE(second); ! 791: if(type1!=type2) { ! 792: if((type1==SDOT&&type2==INT)||(type1==INT&&type2==SDOT)) ! 793: goto dosub; ! 794: {Freexs(); return(nil);} ! 795: } ! 796: switch(type1) { ! 797: case DTPR: ! 798: stack((long)first->d.cdr); stack((long)second->d.cdr); ! 799: first = first->d.car; second = second->d.car; ! 800: goto again; ! 801: case DOUB: ! 802: if(first->r!=second->r) ! 803: {Freexs(); return(nil);} ! 804: continue; ! 805: case INT: ! 806: if(first->i!=second->i) ! 807: {Freexs(); return(nil);} ! 808: continue; ! 809: dosub: ! 810: case SDOT: ! 811: { ! 812: lispval temp; ! 813: struct argent *OLDlbot = lbot; ! 814: lbot = np; ! 815: np++->val = first; ! 816: np++->val = second; ! 817: temp = Lsub(); ! 818: np = lbot; ! 819: lbot = OLDlbot; ! 820: if(TYPE(temp)!=INT || temp->i!=0) ! 821: {Freexs(); return(nil);} ! 822: } ! 823: continue; ! 824: case VALUE: ! 825: if(first->l!=second->l) ! 826: {Freexs(); return(nil);} ! 827: continue; ! 828: case STRNG: ! 829: if(strcmp((char *)first,(char *)second)!=0) ! 830: {Freexs(); return(nil);} ! 831: continue; ! 832: } ! 833: } ! 834: {Freexs(); return(tatom);} ! 835: } ! 836: ! 837: /* ! 838: * (print 'expression ['port]) prints the given expression to the given ! 839: * port or poport if no port is given. The amount of structure ! 840: * printed is a function of global lisp variables plevel and ! 841: * plength. ! 842: */ ! 843: lispval ! 844: Lprint() ! 845: { ! 846: register lispval handy; ! 847: extern int plevel,plength; ! 848: ! 849: ! 850: handy = nil; /* port is optional, default nil */ ! 851: switch(np-lbot) ! 852: { ! 853: case 2: handy = lbot[1].val; ! 854: case 1: break; ! 855: default: argerr("print"); ! 856: } ! 857: ! 858: chkrtab(Vreadtable->a.clb); ! 859: if(TYPE(Vprinlevel->a.clb) == INT) ! 860: { ! 861: plevel = Vprinlevel->a.clb->i; ! 862: } ! 863: else plevel = -1; ! 864: if(TYPE(Vprinlength->a.clb) == INT) ! 865: { ! 866: plength = Vprinlength->a.clb->i; ! 867: } ! 868: else plength = -1; ! 869: printr(lbot->val,okport(handy,okport(Vpoport->a.clb,poport))); ! 870: return(nil); ! 871: } ! 872: ! 873: /* patom does not use plevel or plength ! 874: * ! 875: * form is (patom 'value ['port]) ! 876: */ ! 877: lispval ! 878: Lpatom() ! 879: { ! 880: register lispval temp; ! 881: register lispval handy; ! 882: register int typ; ! 883: FILE *port; ! 884: ! 885: handy = nil; /* port is optional, default nil */ ! 886: switch(np-lbot) ! 887: { ! 888: case 2: handy = lbot[1].val; ! 889: case 1: break; ! 890: default: argerr("patom"); ! 891: } ! 892: ! 893: temp = Vreadtable->a.clb; ! 894: chkrtab(temp); ! 895: port = okport(handy, okport(Vpoport->a.clb,stdout)); ! 896: if ((typ= TYPE((temp = (lbot)->val))) == ATOM) ! 897: fputs(temp->a.pname, port); ! 898: else if(typ == STRNG) ! 899: fputs((char *)temp,port); ! 900: else ! 901: { ! 902: if(TYPE(Vprinlevel->a.clb) == INT) ! 903: { ! 904: plevel = Vprinlevel->a.clb->i; ! 905: } ! 906: else plevel = -1; ! 907: if(TYPE(Vprinlength->a.clb) == INT) ! 908: { ! 909: plength = Vprinlength->a.clb->i; ! 910: } ! 911: else plength = -1; ! 912: ! 913: printr(temp, port); ! 914: } ! 915: return(temp); ! 916: } ! 917: ! 918: /* ! 919: * (pntlen thing) returns the length it takes to print out ! 920: * an atom or number. ! 921: */ ! 922: ! 923: lispval ! 924: Lpntlen() ! 925: { ! 926: return(inewint((long)Ipntlen())); ! 927: } ! 928: Ipntlen() ! 929: { ! 930: register lispval temp; ! 931: register char *handy; ! 932: char *sprintf(); ! 933: ! 934: temp = np[-1].val; ! 935: loop: switch(TYPE(temp)) { ! 936: ! 937: case ATOM: ! 938: handy = temp->a.pname; ! 939: break; ! 940: ! 941: case STRNG: ! 942: handy = (char *) temp; ! 943: break; ! 944: ! 945: case INT: ! 946: sprintf(strbuf,"%d",temp->i); ! 947: handy =strbuf; ! 948: break; ! 949: ! 950: case DOUB: ! 951: sprintf(strbuf,"%g",temp->r); ! 952: handy =strbuf; ! 953: break; ! 954: ! 955: default: ! 956: temp = error("Non atom or number to pntlen\n",TRUE); ! 957: goto loop; ! 958: } ! 959: ! 960: return( strlen(handy)); ! 961: } ! 962: #undef okport ! 963: FILE * ! 964: okport(arg,proper) ! 965: lispval arg; ! 966: FILE *proper; ! 967: { ! 968: if(TYPE(arg)!=PORT) ! 969: return(proper); ! 970: else ! 971: return(arg->p); ! 972: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.