|
|
1.1 ! root 1: static char *sccsid = "@(#)lam1.c 34.3 10/24/80"; ! 2: ! 3: # include "global.h" ! 4: # include <sgtty.h> ! 5: # include "chkrtab.h" ! 6: /**************************************************************************/ ! 7: /* */ ! 8: /* file: ccdfns.i */ ! 9: /* contents: LISP functions coded in C */ ! 10: /* */ ! 11: /* These include LISP primitives, numeric and boolean functions and */ ! 12: /* predicates, some list-processing functions, i/o support functions */ ! 13: /* and control flow functions (e.g. cont, break). */ ! 14: /* There are two types of functions: lambda (prefixed "L") and nlambda */ ! 15: /* (prefixed "N"). */ ! 16: /* Lambda's all call chkarg to insure that at least the minimum number */ ! 17: /* of necessary arguments are on the namestack. */ ! 18: /* All functions take their arguments from the namestack in a read- */ ! 19: /* only manner, and return their results via the normal C value */ ! 20: /* return mechanism. */ ! 21: /* */ ! 22: ! 23: lispval ! 24: Leval() ! 25: { ! 26: register lispval temp; ! 27: ! 28: chkarg(1,"eval"); ! 29: temp = lbot->val; ! 30: return(eval(temp)); ! 31: } ! 32: ! 33: lispval ! 34: Lxcar() ! 35: { register int typ; ! 36: register lispval temp, result; ! 37: ! 38: chkarg(1,"xcar"); ! 39: temp = lbot->val; ! 40: if (((typ = TYPE(temp)) == DTPR) || (typ == ATOM) || HUNKP(temp)) ! 41: return(temp->d.car); ! 42: else if(typ == SDOT) { ! 43: result = inewint(temp->i); ! 44: return(result); ! 45: } else if(Schainp!=nil && typ==ATOM) ! 46: return(nil); ! 47: else ! 48: return(error("Bad arg to car",FALSE)); ! 49: ! 50: } ! 51: ! 52: lispval ! 53: Lxcdr() ! 54: { register int typ; ! 55: register lispval temp, result; ! 56: ! 57: chkarg(1,"xcdr"); ! 58: temp = lbot->val; ! 59: if(temp==nil) return (nil); ! 60: ! 61: if (((typ = TYPE(temp)) == DTPR) || HUNKP(temp)) ! 62: return(temp->d.cdr); ! 63: else if(typ==SDOT) { ! 64: if(temp->s.CDR==0) return(nil); ! 65: return(temp->s.CDR); ! 66: } else if(Schainp!=nil && typ==ATOM) ! 67: return(nil); ! 68: else ! 69: return(error("Bad arg to cdr", FALSE)); ! 70: } ! 71: ! 72: lispval ! 73: cxxr(as,ds) ! 74: register int as,ds; ! 75: { ! 76: ! 77: register lispval temp, temp2; ! 78: int i, typ; ! 79: lispval errorh(); ! 80: ! 81: chkarg(1,"c{ad}+r"); ! 82: temp = lbot->val; ! 83: ! 84: for( i=0 ; i<ds ; i++) ! 85: { ! 86: if( temp != nil) ! 87: { ! 88: typ = TYPE(temp); ! 89: if ((typ == DTPR) || HUNKP(temp)) ! 90: temp = temp->d.cdr; ! 91: else ! 92: if(typ==SDOT) ! 93: { ! 94: if(temp->s.CDR==0) ! 95: temp = nil; ! 96: else ! 97: temp = temp->s.CDR; ! 98: } ! 99: else ! 100: if(Schainp!=nil && typ==ATOM) ! 101: return(nil); ! 102: else ! 103: return(errorh(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(errorh(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: register int typ; ! 204: ! 205: chkarg(2,"scons"); ! 206: retp = newsdot(); ! 207: handy = (argp) -> val; ! 208: if(TYPE(handy)!=INT) ! 209: error("First arg to scons must be an int.",FALSE); ! 210: retp->s.I = handy->i; ! 211: handy = (argp+1)->val; ! 212: if(handy==nil) ! 213: retp->s.CDR = (lispval) 0; ! 214: else { ! 215: if(TYPE(handy)!=SDOT) ! 216: error("Currently you may only link sdots to sdots.",FALSE); ! 217: retp->s.CDR = handy; ! 218: } ! 219: return(retp); ! 220: } ! 221: ! 222: lispval ! 223: Lcons() ! 224: { ! 225: register lispval retp; ! 226: register struct argent *argp; ! 227: ! 228: chkarg(2,"cons"); ! 229: retp = newdot(); ! 230: retp->d.car = ((argp = lbot) -> val); ! 231: retp->d.cdr = argp[1].val; ! 232: return(retp); ! 233: } ! 234: #define CA 0 ! 235: #define CD 1 ! 236: ! 237: lispval ! 238: rpla(what) ! 239: int what; ! 240: { register struct argent *argp; ! 241: register int typ; register lispval first, second; ! 242: ! 243: chkarg(2,"rplac[ad]"); ! 244: argp = np-1; ! 245: first = (argp-1)->val; ! 246: while(first==nil) ! 247: first = error("Attempt to rplac[ad] nil.",TRUE); ! 248: second = argp->val; ! 249: if (((typ = TYPE(first)) == DTPR) || (typ == ATOM) || HUNKP(first)) { ! 250: if (what == CA) ! 251: first->d.car = second; ! 252: else ! 253: first->d.cdr = second; ! 254: return(first); ! 255: } ! 256: if (typ==SDOT) { ! 257: if(what == CA) { ! 258: typ = TYPE(second); ! 259: if(typ!=INT) error("Rplacca of a bignum will only replace INTS",FALSE); ! 260: first->s.I = second->i; ! 261: } else { ! 262: if(second==nil) ! 263: first->s.CDR = (lispval) 0; ! 264: else ! 265: first->s.CDR = second; ! 266: } ! 267: return(first); ! 268: } ! 269: return(error("Bad arg to rpla",FALSE)); ! 270: } ! 271: lispval ! 272: Lrplaca() ! 273: { return(rpla(CA)); } ! 274: ! 275: lispval ! 276: Lrplacd() ! 277: { return(rpla(CD)); } ! 278: ! 279: ! 280: lispval ! 281: Leq() ! 282: { ! 283: register struct argent *mynp = lbot + AD; ! 284: int itemp, flag; ! 285: ! 286: chkarg(2,"eq"); ! 287: if(mynp->val==(mynp+1)->val) return(tatom); ! 288: return(nil); ! 289: } ! 290: ! 291: ! 292: ! 293: lispval ! 294: Lnull() ! 295: { chkarg(1,"null"); ! 296: return ((lbot->val == nil) ? tatom : nil); ! 297: } ! 298: ! 299: ! 300: ! 301: /* Lreturn **************************************************************/ ! 302: /* Returns the first argument - which is nill if not specified. */ ! 303: ! 304: Lreturn() ! 305: { ! 306: snpand(0); ! 307: if(lbot==np) protect (nil); ! 308: contval = lbot->val; ! 309: reset(BRRETN); ! 310: } ! 311: ! 312: ! 313: /* Lretbrk **************************************************************/ ! 314: /* The first argument must be an integer and must be in the range */ ! 315: /* -1 .. -depth. */ ! 316: lispval ! 317: Lretbrk() ! 318: { ! 319: lispval number; ! 320: register level; ! 321: ! 322: snpand(1); ! 323: if(lbot==np) protect (nil); ! 324: number = lbot->val; ! 325: if (TYPE(number) != INT) ! 326: level = -1; ! 327: else ! 328: level = number->i; ! 329: if(level < 0) ! 330: level += depth; ! 331: contval = (lispval) level; ! 332: if (level < depth) ! 333: reset(BRRETB); ! 334: return(nil); ! 335: } ! 336: ! 337: ! 338: ! 339: lispval ! 340: Linfile() ! 341: { ! 342: FILE *port; ! 343: register lispval name; ! 344: int typ; ! 345: snpand(1); ! 346: ! 347: chkarg(1,"infile"); ! 348: name = lbot->val; ! 349: loop: ! 350: name = verify(name,"infile: file name must be atom or string"); ! 351: /* return nil if file couldnt be opened ! 352: if ((port = fopen((char *)name,"r")) == NULL) return(nil); */ ! 353: ! 354: if ((port = fopen((char *)name,"r")) == NULL) { ! 355: name = errorh(Vermisc,"Unable to open file for reading.",nil,TRUE,31,name); ! 356: goto loop; ! 357: } ! 358: ioname[PN(port)] = (lispval) inewstr(name); /* remember name */ ! 359: return(P(port)); ! 360: } ! 361: ! 362: lispval ! 363: Loutfile() ! 364: { ! 365: FILE *port; register lispval name; ! 366: ! 367: chkarg(1,"outfile"); ! 368: name = lbot->val; ! 369: loop: ! 370: name = verify(name,"Please supply atom or string name for port."); ! 371: if ((port = fopen(name,"w")) == NULL) { ! 372: name = errorh(Vermisc,"Unable to open file for writing.",nil,TRUE,31,name); ! 373: goto loop; ! 374: } ! 375: ioname[PN(port)] = (lispval) inewstr(name); ! 376: return(P(port)); ! 377: } ! 378: ! 379: lispval ! 380: Lterpr() ! 381: { ! 382: FILE *port; ! 383: ! 384: snpand(0); ! 385: if(lbot==np) protect (nil); ! 386: port = okport(lbot->val,okport(Vpoport->a.clb,stdout)); ! 387: putc('\n',port); ! 388: fflush(port); ! 389: return(nil); ! 390: } ! 391: ! 392: lispval ! 393: Lclose() ! 394: { ! 395: lispval port; ! 396: ! 397: if(lbot==np) ! 398: port = error("Close requires one argument of type port",TRUE); ! 399: port = lbot->val; ! 400: if((TYPE(port))==PORT) fclose(port->p); ! 401: ioname[PN(port->p)] = nil; ! 402: return(tatom); ! 403: } ! 404: ! 405: lispval ! 406: Lnwritn() ! 407: { ! 408: register FILE *port; ! 409: register value; ! 410: ! 411: snpand(2); ! 412: if(lbot==np) protect (nil); ! 413: port = okport(lbot->val,okport(Vpoport->a.clb,stdout)); ! 414: value = port->_ptr - port->_base; ! 415: return(inewint(value)); ! 416: } ! 417: ! 418: lispval ! 419: Ldrain() ! 420: { ! 421: register FILE *port; ! 422: register int iodes; ! 423: struct sgttyb arg; ! 424: ! 425: snpand(2); ! 426: if(lbot==np) protect (nil); ! 427: port = okport(lbot->val, okport(Vpoport->a.clb,stdout)); ! 428: if(port->_flag & _IOWRT) { ! 429: fflush(port); ! 430: return(nil); ! 431: } ! 432: if(! port->_flag & _IOREAD) return(nil); ! 433: port->_cnt = 0; ! 434: port->_ptr = port->_base; ! 435: iodes = fileno(port); ! 436: if(gtty(iodes,&arg) != -1) stty(iodes,&arg); ! 437: return((lispval)(xports + (port - _iob))); ! 438: } ! 439: ! 440: lispval ! 441: Llist() ! 442: { ! 443: /* added for the benefit of mapping functions. */ ! 444: register struct argent *ulim, *namptr; ! 445: register lispval temp, result; ! 446: register struct argent *lbot, *np; ! 447: ! 448: ulim = np; ! 449: namptr = lbot + AD; ! 450: temp = result = (lispval) np; ! 451: protect(nil); ! 452: for(; namptr < ulim;) { ! 453: temp = temp->l = newdot(); ! 454: temp->d.car = (namptr++)->val; ! 455: } ! 456: temp->l = nil; ! 457: return(result->l); ! 458: } ! 459: ! 460: lispval ! 461: Lnumberp() ! 462: { ! 463: chkarg(1,"numberp"); ! 464: switch(TYPE(lbot->val)) { ! 465: case INT: case DOUB: case SDOT: ! 466: return(tatom); ! 467: } ! 468: return(nil); ! 469: } ! 470: ! 471: lispval ! 472: Latom() ! 473: { ! 474: register struct argent *lb = lbot; ! 475: chkarg(1,"atom"); ! 476: if(TYPE(lb->val)==DTPR || (HUNKP(lb->val))) ! 477: return(nil); ! 478: else ! 479: return(tatom); ! 480: } ! 481: ! 482: lispval ! 483: Ltype() ! 484: { ! 485: chkarg(1,"type"); ! 486: switch(TYPE(lbot->val)) { ! 487: case INT: ! 488: return(int_name); ! 489: case ATOM: ! 490: return(atom_name); ! 491: case SDOT: ! 492: return(sdot_name); ! 493: case DOUB: ! 494: return(doub_name); ! 495: case DTPR: ! 496: return(dtpr_name); ! 497: case STRNG: ! 498: return(str_name); ! 499: case ARRAY: ! 500: return(array_name); ! 501: case BCD: ! 502: return(funct_name); ! 503: ! 504: case HUNK2: ! 505: return(hunk_name[0]); ! 506: case HUNK4: ! 507: return(hunk_name[1]); ! 508: case HUNK8: ! 509: return(hunk_name[2]); ! 510: case HUNK16: ! 511: return(hunk_name[3]); ! 512: case HUNK32: ! 513: return(hunk_name[4]); ! 514: case HUNK64: ! 515: return(hunk_name[5]); ! 516: case HUNK128: ! 517: return(hunk_name[6]); ! 518: ! 519: case VALUE: ! 520: return(val_name); ! 521: case PORT: ! 522: return(port_name); ! 523: } ! 524: return(nil); ! 525: } ! 526: ! 527: lispval ! 528: Ldtpr() ! 529: { ! 530: chkarg(1,"dtpr"); ! 531: return(typred(DTPR, lbot->val)); ! 532: } ! 533: ! 534: lispval ! 535: Lbcdp() ! 536: { ! 537: chkarg(1,"bcdp"); ! 538: return(typred(BCD, lbot->val)); ! 539: } ! 540: ! 541: lispval ! 542: Lportp() ! 543: { ! 544: chkarg(1,"portp"); ! 545: return(typred(PORT, lbot->val)); ! 546: } ! 547: ! 548: lispval ! 549: Larrayp() ! 550: { ! 551: chkarg(1,"arrayp"); ! 552: return(typred(ARRAY, lbot->val)); ! 553: } ! 554: ! 555: /* ! 556: * (hunkp 'g_arg1) ! 557: * Returns t if g_arg1 is a hunk, otherwise returns nil. ! 558: */ ! 559: ! 560: lispval ! 561: Lhunkp() ! 562: { ! 563: chkarg(1,"hunkp"); ! 564: if (HUNKP(lbot->val)) ! 565: return(tatom); /* If a hunk, return t */ ! 566: else ! 567: return(nil); /* else nil */ ! 568: } ! 569: ! 570: lispval ! 571: Lset() ! 572: { ! 573: lispval varble; ! 574: snpand(0); ! 575: ! 576: chkarg(2,"set"); ! 577: varble = lbot->val; ! 578: switch(TYPE(varble)) ! 579: { ! 580: case ATOM: return(varble->a.clb = lbot[1].val); ! 581: ! 582: case VALUE: return(varble->l = lbot[1].val); ! 583: } ! 584: ! 585: error("IMPROPER USE OF SET",FALSE); ! 586: } ! 587: ! 588: lispval ! 589: Lequal() ! 590: { ! 591: register lispval first, second; ! 592: register type1, type2; ! 593: register struct argent *lbot, *np; ! 594: lispval Lsub(),Lzerop(), *stack(), unstack(), *sp(); ! 595: lispval *oldsp; int mustloop = FALSE, result; ! 596: chkarg(2,"equal"); ! 597: ! 598: ! 599: if(lbot->val==lbot[1].val) return(tatom); ! 600: ! 601: for((oldsp=sp(), stack(lbot->val,lbot[1].val)); ! 602: oldsp > sp();) { ! 603: ! 604: first = unstack(); second = unstack(); ! 605: again: ! 606: if(first==second) continue; ! 607: ! 608: type1=TYPE(first); type2=TYPE(second); ! 609: if(type1!=type2) { ! 610: if((type1==SDOT&&type2==INT)||(type1==INT&&type2==SDOT)) ! 611: goto dosub; ! 612: return(nil); ! 613: } ! 614: switch(type1) { ! 615: case DTPR: ! 616: stack(first->d.cdr,second->d.cdr); ! 617: first = first->d.car; second = second->d.car; ! 618: goto again; ! 619: case DOUB: ! 620: if(first->r!=second->r) ! 621: return(nil); ! 622: continue; ! 623: case INT: ! 624: if(first->i!=second->i) ! 625: return(nil); ! 626: continue; ! 627: dosub: ! 628: case SDOT: ! 629: lbot = np; ! 630: np++->val = first; ! 631: np++->val = second; ! 632: lbot->val = Lsub(); ! 633: if(TYPE(lbot->val)!=INT || lbot->val->i!=0) ! 634: return(nil); ! 635: np = lbot; ! 636: continue; ! 637: case VALUE: ! 638: if(first->l!=second->l) ! 639: return(nil); ! 640: continue; ! 641: case STRNG: ! 642: if(strcmp(first,second)!=0) ! 643: return(nil); ! 644: continue; ! 645: ! 646: default: ! 647: return(nil); ! 648: } ! 649: } ! 650: return(tatom); ! 651: } ! 652: lispval ! 653: oLequal() ! 654: { ! 655: chkarg(2,"equal"); ! 656: ! 657: if( lbot[1].val == lbot->val ) return(tatom); ! 658: if(Iequal(lbot[1].val,lbot->val)) return(tatom); else return(nil); ! 659: } ! 660: ! 661: Iequal(first,second) ! 662: register lispval first, second; ! 663: { ! 664: register type1, type2; ! 665: register struct argent *lbot, *np; ! 666: lispval Lsub(),Lzerop(); ! 667: ! 668: if(first==second) ! 669: return(1); ! 670: type1=TYPE(first); ! 671: type2=TYPE(second); ! 672: if(type1!=type2) { ! 673: if((type1==SDOT&&type2==INT)||(type1==INT&&type2==SDOT)) ! 674: goto dosub; ! 675: return(0); ! 676: } ! 677: switch(type1) { ! 678: case DTPR: ! 679: return( ! 680: Iequal(first->d.car,second->d.car) && ! 681: Iequal(first->d.cdr,second->d.cdr) ); ! 682: case DOUB: ! 683: return(first->r==second->r); ! 684: case INT: ! 685: return( (first->i==second->i)); ! 686: dosub: ! 687: case SDOT: ! 688: lbot = np; ! 689: np++->val = first; ! 690: np++->val = second; ! 691: lbot->val = Lsub(); ! 692: np = lbot + 1; ! 693: return(TYPE(lbot->val)==INT&& lbot->val->i==0); ! 694: case VALUE: ! 695: return( first->l==second->l ); ! 696: case STRNG: ! 697: return(strcmp(first,second)==0); ! 698: } ! 699: return(0); ! 700: } ! 701: lispval ! 702: Zequal() ! 703: { ! 704: register lispval first, second; ! 705: register type1, type2; ! 706: register struct argent *lbot, *np; ! 707: lispval Lsub(),Lzerop(), *stack(), unstack(), *sp(); ! 708: lispval *oldsp; int mustloop = FALSE, result; ! 709: chkarg(2,"equal"); ! 710: ! 711: ! 712: if(lbot->val==lbot[1].val) return(tatom); ! 713: ! 714: for((oldsp=sp(), stack(lbot->val,lbot[1].val)); ! 715: oldsp > sp();) { ! 716: ! 717: first = unstack(); second = unstack(); ! 718: again: ! 719: if(first==second) continue; ! 720: ! 721: type1=TYPE(first); type2=TYPE(second); ! 722: if(type1!=type2) { ! 723: if((type1==SDOT&&type2==INT)||(type1==INT&&type2==SDOT)) ! 724: goto dosub; ! 725: return(nil); ! 726: } ! 727: switch(type1) { ! 728: case DTPR: ! 729: stack(first->d.cdr,second->d.cdr); ! 730: first = first->d.car; second = second->d.car; ! 731: goto again; ! 732: case DOUB: ! 733: if(first->r!=second->r) ! 734: return(nil); ! 735: continue; ! 736: case INT: ! 737: if(first->i!=second->i) ! 738: return(nil); ! 739: continue; ! 740: dosub: ! 741: case SDOT: ! 742: lbot = np; ! 743: np++->val = first; ! 744: np++->val = second; ! 745: lbot->val = Lsub(); ! 746: if(TYPE(lbot->val)!=INT || lbot->val->i!=0) ! 747: return(nil); ! 748: np = lbot; ! 749: continue; ! 750: case VALUE: ! 751: if(first->l!=second->l) ! 752: return(nil); ! 753: continue; ! 754: case STRNG: ! 755: if(strcmp(first,second)!=0) ! 756: return(nil); ! 757: continue; ! 758: } ! 759: } ! 760: return(tatom); ! 761: } ! 762: ! 763: lispval ! 764: Lprint() ! 765: { ! 766: extern int prinlevel,prinlength; ! 767: ! 768: snpand(0); ! 769: if(np-lbot==1) protect(nil); ! 770: chkarg(2,"print"); ! 771: chkrtab(Vreadtable->a.clb); ! 772: if(TYPE(Vprinlevel->a.clb) == INT) ! 773: { ! 774: prinlevel = Vprinlevel->a.clb->i; ! 775: } ! 776: else prinlevel = -1; ! 777: if(TYPE(Vprinlength->a.clb) == INT) ! 778: { ! 779: prinlength = Vprinlength->a.clb->i; ! 780: } ! 781: else prinlength = -1; ! 782: printr(lbot->val,okport(lbot[1].val,okport(Vpoport->a.clb,poport))); ! 783: return(nil); ! 784: } ! 785: ! 786: /* patom does not use prinlevel or prinlength */ ! 787: lispval ! 788: Lpatom() ! 789: { ! 790: register lispval temp; ! 791: register int typ; ! 792: FILE *port; ! 793: extern int prinlevel,prinlength; ! 794: ! 795: snpand(2); ! 796: if(np-lbot==1) protect(nil); ! 797: chkarg(2,"patom"); ! 798: temp = Vreadtable->a.clb; ! 799: chkrtab(temp); ! 800: port = okport(lbot[1].val, okport(Vpoport->a.clb,stdout)); ! 801: if ((typ= TYPE((temp = (lbot)->val))) == ATOM) ! 802: fputs(temp->a.pname, port); ! 803: else if(typ == STRNG) ! 804: fputs(temp,port); ! 805: else ! 806: { ! 807: printr(temp, port); ! 808: } ! 809: return(temp); ! 810: } ! 811: ! 812: /* ! 813: * (pntlen thing) returns the length it takes to print out ! 814: * an atom or number. ! 815: */ ! 816: ! 817: lispval ! 818: Lpntlen() ! 819: { ! 820: register lispval temp; ! 821: return(inewint(Ipntlen())); ! 822: } ! 823: Ipntlen() ! 824: { ! 825: register lispval temp; ! 826: register char *handy; ! 827: ! 828: temp = np[-1].val; ! 829: loop: switch(TYPE(temp)) { ! 830: ! 831: case ATOM: ! 832: handy = temp->a.pname; ! 833: break; ! 834: ! 835: case STRNG: ! 836: handy = (char *) temp; ! 837: break; ! 838: ! 839: case INT: ! 840: sprintf(strbuf,"%d",temp->i); ! 841: handy =strbuf; ! 842: break; ! 843: ! 844: case DOUB: ! 845: sprintf(strbuf,"%g",temp->r); ! 846: handy =strbuf; ! 847: break; ! 848: ! 849: default: ! 850: temp = error("Non atom or number to pntlen\n",TRUE); ! 851: goto loop; ! 852: } ! 853: ! 854: return( strlen(handy)); ! 855: } ! 856: #undef okport ! 857: FILE * ! 858: okport(arg,proper) ! 859: lispval arg; ! 860: FILE *proper; ! 861: { ! 862: if(TYPE(arg)!=PORT) ! 863: return(proper); ! 864: else ! 865: return(arg->p); ! 866: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.