Annotation of 42BSD/ucb/lisp/franz/io.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *rcsid =
                      3:    "$Header: /na/franz/franz/RCS/io.c,v 1.8 83/08/06 08:38:42 jkf Exp $";
                      4: #endif
                      5: 
                      6: /*                                     -[Fri Aug  5 12:45:22 1983 by jkf]-
                      7:  *     io.c                            $Locker:  $
                      8:  * input output functions
                      9:  *
                     10:  * (c) copyright 1982, Regents of the University of California
                     11:  */
                     12: 
                     13: #include "global.h"
                     14: #include <ctype.h>
                     15: #include "chars.h"
                     16: #include "chkrtab.h"
                     17: 
                     18: struct readtable {
                     19: unsigned char  ctable[132];
                     20: } initread = {
                     21: /*     ^@ nul  ^A soh  ^B stx  ^C etx  ^D eot  ^E eng  ^F ack  ^G bel  */
                     22:        VERR,   VERR,   VERR,   VERR,   VERR,   VERR,   VERR,   VERR,
                     23: /*     ^H bs   ^I ht   ^J nl   ^K vt   ^L np   ^M cr   ^N so   ^O si   */
                     24:        VCHAR,  VSEP,   VSEP,   VSEP,   VSEP,   VSEP,   VERR,   VERR,
                     25: /*     ^P dle  ^Q dc1  ^R dc2  ^S dc3  ^T dc4  ^U nak  ^V syn  ^W etb  */
                     26:        VERR,   VERR,   VERR,   VERR,   VERR,   VERR,   VERR,   VERR,
                     27: /*     ^X can  ^Y em   ^Z sub  ^[ esc  ^\ fs   ^] gs   ^^ rs   ^_ us   */
                     28:        VERR,   VERR,   VERR,   VSEP,   VERR,   VERR,   VERR,   VERR,
                     29: /*     sp      !       "       #       $       %       &       '       */
                     30:        VSEP,   VCHAR,  VSD,    VCHAR,  VCHAR,  VCHAR,  VCHAR,  VSQ,
                     31: /*     (       )       *       +       ,       -       .       /       */
                     32:        VLPARA, VRPARA, VCHAR,  VSIGN,  VCHAR,  VSIGN,  VPERD,  VCHAR,
                     33: /*     0       1       2       3       4       5       6       7       */
                     34:        VNUM,   VNUM,   VNUM,   VNUM,   VNUM,   VNUM,   VNUM,   VNUM,
                     35: /*     8       9       :       ;       <       =       >       ?       */
                     36:        VNUM,   VNUM,   VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     37: /*     @       A       B       C       D       E       F       G       */
                     38:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     39: /*     H       I       J       K       L       M       N       O       */
                     40:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     41: /*     P       Q       R       S       T       U       V       W       */
                     42:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     43: /*     X       Y       Z       [       \       ]       ^       _       */
                     44:        VCHAR,  VCHAR,  VCHAR,  VLBRCK, VESC,   VRBRCK, VCHAR,  VCHAR,
                     45: /*     `       a       b       c       d       e       f       g       */
                     46:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     47: /*     h       i       j       k       l       m       n       o       */
                     48:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     49: /*     p       q       r       s       t       u       v       w       */
                     50:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     51: /*     x       y       z       {       |       }       ~       del     */
                     52:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VDQ,    VCHAR,  VCHAR,  VERR,
                     53: /*     unused  Xsdc    Xesc    Xdqc                                    */
                     54:        0,      '"',    '\\',   '|'
                     55: };
                     56: 
                     57: extern unsigned char *ctable;
                     58: lispval atomval;       /* external varaible containing atom returned
                     59:                           from internal atom reading routine */
                     60: lispval readrx(); lispval readr(); lispval readry();
                     61: char *atomtoolong();
                     62: int keywait;
                     63: int plevel = -1;       /* contains maximum list recursion count        */
                     64: int plength = -1;   /* maximum number of list elements printed */
                     65: static int dbqflag;
                     66: static int mantisfl = 0;
                     67: extern int uctolc;
                     68: extern lispval lastrtab;       /* external variable designating current reader
                     69:                           table */
                     70: static char baddot1[]=
                     71: "Bad reader construction: (. <something>)\nShould be (nil . <something>)\n";
                     72: static char baddot2[]=
                     73: "Bad reader construction: (<something> .)\n\
                     74: Should be (<something> . <something>), assumed to be (<something>)";
                     75: static char baddot3[]=
                     76: "Bad reader construction: (<something> . <something> not followed by )";
                     77: 
                     78: /* readr ****************************************************************/
                     79: /* returns a s-expression read in from the port specified as the first */
                     80: /* argument.  Handles superbrackets, reader macros.                    */
                     81: lispval
                     82: readr(useport)
                     83: FILE *useport;
                     84: {
                     85:        register lispval handy = Vreadtable->a.clb;
                     86: 
                     87:        chkrtab(handy);
                     88:        rbktf = FALSE;
                     89:        rdrport = (FILE *) useport;
                     90:        if(useport==stdin)
                     91:                keywait = TRUE; 
                     92:        handy = readrx(Iratom());
                     93:        if(useport==stdin)
                     94:                keywait = FALSE;
                     95:        return(handy);
                     96: 
                     97: }
                     98: 
                     99: 
                    100: /* readrx **************************************************************/
                    101: /* returns a s-expression beginning with the syntax code of an atom    */
                    102: /* passed in the first */
                    103: /* argument.  Does the actual work for readr, including list, dotted   */
                    104: /* pair, and quoted atom detection                                     */
                    105: lispval
                    106: readrx(code)
                    107: register int code;
                    108: {
                    109:        register lispval work;
                    110:        register lispval *current;
                    111:        register struct argent *result;
                    112:        int inlbkt = FALSE;
                    113:        lispval errorh();
                    114:        Savestack(4); /* ???not necessary because np explicitly restored if
                    115:          changed */
                    116: 
                    117: top:
                    118:        switch(code)
                    119:        {
                    120:        case TLBKT:
                    121:                inlbkt = TRUE;
                    122:        case TLPARA:
                    123:                result = np;
                    124:                current = (lispval *)np;
                    125:                np++->val = nil; /*protect(nil);*/
                    126:                for(EVER) {
                    127:                        switch(code = Iratom())
                    128:                        {
                    129:                        case TRPARA:
                    130:                                if(rbktf && inlbkt)
                    131:                                        rbktf = FALSE;
                    132:                                goto out;
                    133:                        default:
                    134:                                atomval = readrx(code);
                    135:                        case TSCA:
                    136:                                np++->val=atomval;
                    137:                                *current = work = newdot();
                    138:                                work->d.car = atomval;
                    139:                                np--;
                    140:                                current = (lispval *) &(work->d.cdr);
                    141:                                break;
                    142:                        case TINF:
                    143:                                imacrox(result->val,TRUE);
                    144:                                work = atomval;
                    145:                                result->val = work->d.car;
                    146:                                current = (lispval *) & (result->val);
                    147:                                goto mcom;
                    148:                        case TSPL:
                    149:                                macrox(); /* input and output in atomval */
                    150:                                *current = atomval;
                    151:                        mcom:
                    152:                                while(*current!=nil) {
                    153:                                        if(TYPE(*current)!=DTPR)
                    154:                                                errorh1(Vermisc,"Non-list returned from splicing macro",nil,FALSE,7,*current);
                    155:                                        current=(lispval *)&((*current)->d.cdr);
                    156:                                }
                    157:                                break;
                    158:                        case TPERD:
                    159:                                if(result->val==nil) {
                    160:                                        work = result->val=newdot();
                    161:                                        current = (lispval *) &(work->d.cdr);
                    162:                                        fprintf(stderr,baddot1);
                    163:                                }
                    164:                                code = Iratom();
                    165:                                if(code==TRPARA) {
                    166:                                        result->val = errorh1(Vermisc,baddot2,nil,TRUE,58,result->val);
                    167:                                        goto out;
                    168:                                }
                    169:                                *current = readrx(code);
                    170:                                /* there is the possibility that the expression
                    171:                                   following the dot is terminated with a "]"
                    172:                                   and thus needs no closing lparens to follow
                    173:                                */
                    174:                                if(!rbktf && ((code = Iratom()))!=TRPARA) {
                    175:                                        errorh2(Vermisc,baddot3,nil,TRUE,59,result->val,atomval);
                    176:                                }
                    177:                                if(rbktf && inlbkt)
                    178:                                        rbktf = FALSE;
                    179:                                goto out;
                    180:                        case TEOF:
                    181:                                errorh1(Vermisc,"Premature end of file after ", 
                    182:                                                          nil,FALSE,0,result->val);
                    183:                        }
                    184:                        if(rbktf) {
                    185:                                if(inlbkt)
                    186:                                        rbktf = FALSE;
                    187:                                goto out;
                    188:                        }
                    189:                }
                    190:        case TSCA:
                    191:                Restorestack();
                    192:                return(atomval);
                    193:        case TEOF:
                    194:                Restorestack();
                    195:                return(eofa);
                    196:        case TMAC:
                    197:                macrox();
                    198:                Restorestack();
                    199:                return(atomval);
                    200:        case TINF:
                    201:                imacrox(nil,FALSE);
                    202:                work = atomval;
                    203:                if(work==nil) { code = Iratom(); goto top;}
                    204:                work = work->d.car;
                    205:                Restorestack();
                    206:                if(work->d.cdr==nil)
                    207:                    return(work->d.car);
                    208:                else
                    209:                    return(work);
                    210:        case TSPL:
                    211:                macrox();
                    212:                if((work = atomval)!=nil) {
                    213:                        if(TYPE(work)==DTPR && work->d.cdr==nil) {
                    214:                                Restorestack();
                    215:                                return(work->d.car);
                    216:                        } else {
                    217:                                errorh1(Vermisc,
                    218: "Improper value returned from splicing macro at top-level",nil,FALSE,9,work);
                    219:                        }
                    220:                }
                    221:                code = Iratom();
                    222:                goto top;
                    223:                /* return(readrx(Iratom())); */
                    224:        case TSQ:
                    225:                result = np;
                    226:                protect(newdot());
                    227:                (work = result->val)->d.car = quota;
                    228:                work = work->d.cdr = newdot();
                    229:                work->d.car = readrx(Iratom());
                    230:                goto out;
                    231: 
                    232:        case TRPARA:
                    233:                Restorestack();
                    234:                return(errorh(Vermisc,
                    235:                    "read: read a right paren when expecting an s-expression",
                    236:                    nil,FALSE,0));
                    237:        case TPERD:
                    238:                Restorestack();
                    239:                return(errorh(Vermisc,
                    240:                    "read: read a period when expecting an s-expression",
                    241:                    nil,FALSE,0));
                    242:                    
                    243:        /* should never get here, we should have covered all cases above */
                    244:        default:
                    245:                Restorestack();
                    246:                return(errorh1(Vermisc,"Readlist error,  code ",nil,FALSE,0,inewint((long)code)));
                    247:        }
                    248: out:
                    249:        work = result->val;
                    250:        np = result;
                    251:        Restorestack();
                    252:        return(work);
                    253: }
                    254: macrox()
                    255: {
                    256:        FILE *svport;
                    257:        lispval handy, Lapply();
                    258: 
                    259:        Savestack(0);
                    260:        svport = rdrport;       /* save from possible changing */
                    261:        lbot = np;
                    262:        protect(handy=Iget(atomval,lastrtab));
                    263:        if (handy == nil)
                    264:        {
                    265:            errorh1(Vermisc,"read: can't find the character macro for ",nil,
                    266:                        FALSE,0,atomval);
                    267:        }
                    268:        protect(nil);
                    269:        atomval = Lapply();
                    270:        chkrtab(Vreadtable->a.clb);     /* the macro could have changed
                    271:                                           the readtable
                    272:                                         */
                    273:        rdrport = svport;       /* restore old value */
                    274:        Restorestack();
                    275:        return;
                    276: }
                    277: imacrox(current,inlist)
                    278: register lispval current;
                    279: {
                    280:        FILE *svport;
                    281:        register lispval work;
                    282:        lispval Lapply(), handy;
                    283: 
                    284:        Savestack(2);
                    285:        svport = rdrport;       /* save from possible changing */
                    286:        if(inlist)
                    287:        {
                    288:            protect(handy = newdot());
                    289:            handy->d.car = current;
                    290:            for(work = handy->d.car; (TYPE(work->d.cdr))==DTPR; )
                    291:                work = work->d.cdr;
                    292:             handy->d.cdr = work;
                    293:        }
                    294:        else handy = current;
                    295:        
                    296:        lbot = np;
                    297:        protect(Iget(atomval,lastrtab));
                    298:        protect(handy);
                    299:        atomval = Lfuncal();
                    300:        chkrtab(Vreadtable->a.clb);     /* the macro could have changed
                    301:                                           the readtable
                    302:                                         */
                    303:        rdrport = svport;       /* restore old value */
                    304:        Restorestack();
                    305:        return;
                    306: }
                    307: 
                    308: 
                    309: 
                    310: /* ratomr ***************************************************************/
                    311: /* this routine returns a pointer to an atom read in from the port given*/
                    312: /* by the first argument                                               */
                    313: lispval
                    314: ratomr(useport)
                    315: register FILE  *useport;
                    316: {
                    317:        rdrport = useport;
                    318:        switch(Iratom())
                    319:        {
                    320:        case TEOF:
                    321:                return(eofa);
                    322:        case TSQ:
                    323:        case TRPARA:
                    324:        case TLPARA:
                    325:        case TLBKT:
                    326:        case TPERD:
                    327:                strbuf[1]=0;
                    328:                return(getatom(TRUE));
                    329:        default:
                    330:                return(atomval);
                    331:        }
                    332: }
                    333: 
                    334: #define push(); *name++ = c; if(name>=endstrb) name = atomtoolong(name);
                    335: #define next() (((cc=getc(useport))!=EOF)?(stats = ctable[c = cc &0177]):\
                    336:                                        ((c=0),(saweof = 1),(stats = SEPMASK)))
                    337: Iratom()
                    338: {
                    339:        register FILE   *useport = rdrport;
                    340:        register char   c, marker, *name;
                    341:        extern lispval finatom(), calcnum(), getnum();
                    342:        int code, cc;
                    343:        int strflag = FALSE;
                    344: 
                    345:        name = strbuf;
                    346: 
                    347: again: cc = getc(useport);
                    348:        if(cc==EOF)
                    349:        {
                    350:            clearerr(useport);
                    351:            return(TEOF);
                    352:        }
                    353:        c = cc & 0177;
                    354:        *name = c;
                    355: 
                    356:        switch(synclass(ctable[c])) {
                    357: 
                    358:        default:        goto again;
                    359: 
                    360:        case synclass(VNUM):
                    361: 
                    362:        case synclass(VSIGN):   *name++ = c;
                    363:                        atomval = (getnum(name));
                    364:                        return(TSCA);
                    365: 
                    366:        case synclass(VESC):
                    367:                        dbqflag = TRUE;
                    368:                        *name++ = getc(useport) & 0177;
                    369:                        atomval = (finatom(name));
                    370:                        return(TSCA);
                    371:                        
                    372:        case synclass(VCHAR):
                    373:                        if(uctolc && isupper(c)) c = tolower(c);
                    374:                        *name++ = c;
                    375:                        atomval = (finatom(name));
                    376:                        return(TSCA);
                    377: 
                    378:        case synclass(VLPARA):  return(TLPARA);
                    379: 
                    380:        case synclass(VRPARA):  return(TRPARA);
                    381: 
                    382:        case synclass(VPERD):   marker = peekc(useport) & 0177;
                    383:                        if(synclass(VNUM)!=synclass(ctable[marker]))
                    384:                        {  if(SEPMASK & ctable[marker])
                    385:                                return(TPERD);
                    386:                           else { *name++ = c;  /* this period begins an atm */
                    387:                                  atomval = finatom(name);
                    388:                                  return(TSCA);
                    389:                           }
                    390:                        }
                    391:                        *name++ = '.';
                    392:                        mantisfl = 1;
                    393:                        atomval = (getnum(name));
                    394:                        return(TSCA);
                    395: 
                    396:        case synclass(VLBRCK):  return(TLBKT);
                    397: 
                    398:        case synclass(VRBRCK):  rbktf = TRUE;
                    399:                        return(TRPARA);
                    400: 
                    401:        case synclass(VSQ):     return(TSQ);
                    402: 
                    403:        case synclass(VSD):     strflag = TRUE;
                    404:        case synclass(VDQ):     name = strbuf;
                    405:                        marker = c;
                    406:                        while ((c = getc(useport)) != marker) {
                    407: 
                    408:                                if(synclass(VESC)==synclass(ctable[c]))
                    409:                                        c = getc(useport) & 0177;
                    410:                                push();
                    411:                                if (feof(useport)) {
                    412:                                        clearerr(useport);
                    413:                                        error("EOF encountered while reading atom", FALSE);
                    414:                                }
                    415:                        }
                    416:                        *name = NULL_CHAR;
                    417:                        if(strflag)
                    418:                                atomval = (lispval) pinewstr(strbuf);
                    419:                        else
                    420:                                atomval = (getatom(TRUE));
                    421:                        return(TSCA);
                    422: 
                    423:        case synclass(VERR):    if (c == '\0') 
                    424:                        {
                    425:                          fprintf(stderr,"[read: null read and ignored]\n");
                    426:                          goto again;   /* null pname */
                    427:                        }
                    428:                        fprintf(stderr,"%c (%o): ",c,(int) c);
                    429:                        error("ILLEGAL CHARACTER IN ATOM",TRUE);
                    430: 
                    431:        case synclass(VSINF):
                    432:                code = TINF;
                    433:                goto same;
                    434:        case synclass(VSSPL):
                    435:                code = TSPL;
                    436:                goto same;
                    437:        case synclass(VSMAC):
                    438:                code = TMAC;
                    439:        same:
                    440:                marker = peekc(rdrport);
                    441:                if(! (SEPMASK & ctable[marker]) ) {
                    442:                    *name++ = c;  /* this is not a macro */
                    443:                    atomval = (finatom(name));
                    444:                    return(TSCA);
                    445:                }
                    446:                goto simple;
                    447:        case synclass(VINF):
                    448:                code = TINF;
                    449:                goto simple;
                    450:        case synclass(VSCA):
                    451:                code = TSCA;
                    452:                goto simple;
                    453:        case synclass(VSPL):
                    454:                code = TSPL;
                    455:                goto simple;
                    456:        case synclass(VMAC):
                    457:                code = TMAC;
                    458:        simple:
                    459:                strbuf[0] = c;
                    460:                strbuf[1] = 0;
                    461:                atomval = (getatom(TRUE));
                    462:                return(code);
                    463:        }
                    464: }
                    465: 
                    466: lispval
                    467: getnum(name)
                    468: register char *name;
                    469: {
                    470:        unsigned char c;
                    471:        register lispval result;
                    472:        register FILE *useport=rdrport;
                    473:        unsigned char  stats;
                    474:        int sawdigit = 0, saweof = 0,cc;
                    475:        char *exploc = (char *) 0;
                    476:        double realno;
                    477:        extern lispval finatom(), calcnum(), newdoub(), dopow();
                    478: 
                    479:        if(mantisfl) {
                    480:                mantisfl = 0;
                    481:                next();
                    482:                goto mantissa;
                    483:        }
                    484:        if(VNUM==ctable[*(unsigned char*)(name-1)]) sawdigit = 1;
                    485:        while(VNUM==next()) {
                    486:                push();         /* recognize [0-9]*, in "ex" parlance */
                    487:                sawdigit = 1;
                    488:        }
                    489:        if(c=='.') {
                    490:                push();         /* continue */ 
                    491:        } else if(stats & SEPMASK) {
                    492:                if(!saweof)ungetc((int)c,useport);
                    493:                return(calcnum(strbuf,name,(int)ibase->a.clb->i));
                    494:        } else if(c=='^') {
                    495:                push();
                    496:                return(dopow(name,(int)ibase->a.clb->i));
                    497:        } else if(c=='_') {
                    498:                if(sawdigit)    /* _ must be preceeded by a digit */
                    499:                {
                    500:                    push();
                    501:                    return(dopow(name,2));
                    502:                }
                    503:                else goto backout;
                    504:        } else if(c=='e' || c=='E' || c=='d' ||c=='D') {
                    505:                if(sawdigit) goto expt;
                    506:                else goto backout;
                    507:        } else {
                    508:        backout:
                    509:                ungetc((int)c,useport);
                    510:                return(finatom(name));
                    511:        }
                    512:                                /* at this point we have [0-9]*\. , which might
                    513:                                   be a decimal int or the leading part of a
                    514:                                   float                                */
                    515:        if(next()!=VNUM) {
                    516:                if(c=='e' || c=='E' || c=='d' ||c=='D')
                    517:                        goto expt;
                    518:                else if(c=='^') {
                    519:                        push();
                    520:                        return(dopow(name,(int)ibase->a.clb->i));
                    521:                } else if(c=='_') {
                    522:                        push();
                    523:                        return(dopow(name,2));
                    524:                } else if( stats & SEPMASK) {
                    525:                                /* Here we have 1.x where x is not number
                    526:                                 * but is a separator 
                    527:                                 * Here we have decimal int. NOT FORTRAN!
                    528:                                 */
                    529:                        if(!saweof)ungetc((int)c,useport);
                    530:                        return(calcnum(strbuf,name-1,10));
                    531:                }
                    532:                else goto last;  /* return a symbol */
                    533:        }
                    534: mantissa:
                    535:        do {
                    536:                push();
                    537:        } while (VNUM==next());
                    538:        
                    539:        /* Here we have [0-9]*\.[0-9]*
                    540:         * three possibilities:
                    541:         *   next character is e,E,d or D in which case we examine
                    542:         *      the exponent [then we are faced with a similar
                    543:         *      situation to this one: is the character after the
                    544:         *      exponent a separator or not]
                    545:         *   next character is a separator, in which case we have a
                    546:         *      number (without an exponent)
                    547:         *   next character is not a separator in which case we have
                    548:         *      an atom (whose prefix just happens to look like a
                    549:         *      number)
                    550:         */
                    551:        if( (c == 'e') || (c == 'E') || (c == 'd') || (c == 'D')) goto expt;
                    552:        
                    553:        if(stats & SEPMASK) goto verylast;      /* a real number */
                    554:        else goto last; /* prefix makes it look like a number, but it isn't */
                    555:        
                    556: expt:
                    557:        exploc = name;  /* remember location of exponent character */
                    558:        push();
                    559:        next();
                    560:        if(c=='+' || c =='-') {
                    561:                push();
                    562:                next();
                    563:        }
                    564:        while (VNUM==stats) {
                    565:                push();
                    566:                next();
                    567:        }
                    568: 
                    569:        /* if a separator follows then we have a number, else just
                    570:         * an atom
                    571:         */
                    572:        if (stats & SEPMASK) goto verylast;
                    573:        
                    574: last:  /* get here when what looks like a number turns out to be an atom */
                    575:        if(!saweof) ungetc((int)c,useport);
                    576:        return(finatom(name));
                    577: 
                    578: verylast:
                    579:        if(!saweof) ungetc((int)c,useport);
                    580:        /* scanf requires that the exponent be 'e' */
                    581:        if(exploc != (char *) 0 ) *exploc = 'e';
                    582:        *name=0;
                    583:        sscanf(strbuf,"%F",&realno);
                    584:        (result = newdoub())->r = realno;
                    585:        return(result);
                    586: }
                    587: 
                    588: lispval
                    589: dopow(part2,base)
                    590: register char *part2;
                    591: {
                    592:        register char *name = part2;
                    593:        register FILE *useport = rdrport;
                    594:        register int power;
                    595:        lispval work;
                    596:        unsigned char stats,c;
                    597:        int cc, saweof = 0;
                    598:        char *end1 = part2 - 1; lispval Ltimes();
                    599:        Savestack(4);
                    600: 
                    601:        while(VNUM==next()) {
                    602:                push();
                    603:        }
                    604:        if(c!='.') {
                    605:                if(!saweof)ungetc((int)c,useport);
                    606:        }
                    607:        if(c!='.' && !(stats & SEPMASK)) {
                    608:                return(finatom(name));
                    609:        }
                    610:        lbot = np;
                    611:        np++->val = inewint(base);
                    612:        /* calculate "mantissa"*/
                    613:        if(*end1=='.')
                    614:                np++->val = calcnum(strbuf,end1-1,10);
                    615:        else
                    616:                np++->val = calcnum(strbuf,end1,(int)ibase->a.clb->i);
                    617: 
                    618:        /* calculate exponent */
                    619:        if(c=='.')
                    620:                power = calcnum(part2,name,10)->i;
                    621:        else
                    622:                power = calcnum(part2,name,(int)ibase->a.clb->i)->i;
                    623:        while(power-- > 0)
                    624:                lbot[1].val = Ltimes();
                    625:        work = lbot[1].val;
                    626:        Restorestack();
                    627:        return(work);
                    628: }
                    629:        
                    630: 
                    631: lispval
                    632: calcnum(strbuf,name,base)
                    633: register char *name;
                    634: char *strbuf;
                    635: {
                    636:        register char *p;
                    637:        register lispval result, temp;
                    638:        int negflag = 0;
                    639: 
                    640:        result = temp = newsdot();              /* initialize sdot cell */
                    641:        protect(temp);
                    642:        p = strbuf;
                    643:        if(*p=='+') p++;
                    644:        else if(*p=='-') {negflag = 1; p++;}
                    645:        *name = 0;
                    646:        if(p>=name) return(getatom(TRUE));
                    647: 
                    648:        for(;p < name; p++)
                    649:                dmlad(temp,(long)base,(long)*p-'0');
                    650:        if(negflag)
                    651:                dmlad(temp,-1L,0L);
                    652: 
                    653:        if(temp->s.CDR==0) {
                    654:                result = inewint(temp->i);
                    655:                pruneb(np[-1].val);
                    656:        }
                    657:        np--;
                    658:        return(result);
                    659: }
                    660: lispval
                    661: finatom(name)
                    662: register char *name;
                    663: {
                    664:        register FILE *useport = rdrport;
                    665:        unsigned char c, stats;
                    666:        int cc, saweof = 0;
                    667: 
                    668:        while(!(next()&SEPMASK)) {
                    669: 
                    670:                if(synclass(stats) == synclass(VESC)) {
                    671:                        c = getc(useport) & 0177;
                    672:                } else {
                    673:                        if(uctolc && isupper(c)) c = tolower(c);
                    674:                }
                    675:                push();
                    676:        }
                    677:        *name = NULL_CHAR;
                    678:        if(!saweof)ungetc((int)c,useport);
                    679:        return(getatom(TRUE));
                    680: }
                    681: 
                    682: char *
                    683: atomtoolong(copyto)
                    684: char *copyto;
                    685: {
                    686:     int size;
                    687:     register char *oldp = strbuf;
                    688:     register char *newp;
                    689:     lispval nveci();
                    690:     /*
                    691:      * the string buffer contains an string which is too long 
                    692:      * so we get a bigger buffer.
                    693:      */
                    694: 
                    695:     size =  (endstrb - strbuf)*4 + 28 ;
                    696:     newp = (char *) nveci(size);
                    697:     atom_buffer = (lispval) newp;
                    698:     strbuf = newp;
                    699:     endstrb = newp + size - 1;
                    700:     while(oldp < copyto) *newp++ = *oldp++;
                    701:        return(newp);
                    702: }
                    703:     
                    704: /* printr ***************************************************************/
                    705: /* prints the first argument onto the port specified by the second     */
                    706: 
                    707: /*
                    708:  * Last modified Mar 21, 1980 for hunks
                    709:  */
                    710: 
                    711: printr(a,useport)
                    712: register lispval a;
                    713: register FILE *useport;
                    714: {
                    715:        register hsize, i;
                    716:        char strflag = 0;
                    717:        char Idqc = 0;
                    718:        char *chstr;
                    719:        int curplength = plength;
                    720:        int quot;
                    721:        lispval Istsrch();
                    722:        lispval debugmode;
                    723: 
                    724: val_loop:
                    725:        if(! VALID(a)) {
                    726:            debugmode = Istsrch(matom("debugging"))->d.cdr->d.cdr->d.cdr;
                    727:            if(debugmode != nil) {
                    728:                printf("<printr:bad lisp data: 0x%x>\n",a);
                    729:                error("Bad lisp data encountered by printr", FALSE); 
                    730:            } else {
                    731:                a = badst;
                    732:                printf("<printr:bad lisp data: 0x%x>",a);
                    733:                return;
                    734:            }
                    735:        }
                    736: 
                    737:        switch (TYPE(a))
                    738:        {
                    739: 
                    740: 
                    741:        case UNBO:      fputs("<UNBOUND>",useport);
                    742:                        break;
                    743: 
                    744:        case VALUE:     fputs("(ptr to)",useport);
                    745:                        a = a->l;
                    746:                        goto val_loop;
                    747: 
                    748:        case INT:       fprintf(useport,"%d",a->i);
                    749:                        break;
                    750: 
                    751:        case DOUB:      {  char buf[64];
                    752:                           lfltpr(buf,a->r);
                    753:                           fputs(buf,useport);
                    754:                        }
                    755:                        break;
                    756: 
                    757:        case PORT:      { lispval  cp;
                    758:                          if((cp = ioname[PN(a->p)]) == nil)
                    759:                             fputs("%$unopenedport",useport);
                    760:                          else fprintf(useport,"%%%s",cp);
                    761:                        }
                    762:                        break;
                    763: 
                    764:        case HUNK2:
                    765:        case HUNK4:
                    766:        case HUNK8:
                    767:        case HUNK16:
                    768:        case HUNK32:
                    769:        case HUNK64:
                    770:        case HUNK128:
                    771:                        if(plevel == 0) 
                    772:                        {   
                    773:                             fputs("%",useport);
                    774:                             break;
                    775:                        }
                    776:                        hsize = 2 << HUNKSIZE(a);
                    777:                        fputs("{", useport);
                    778:                        plevel--;
                    779:                        printr(a->h.hunk[0], useport);
                    780:                        curplength--;
                    781:                        for (i=1; i < hsize; i++)
                    782:                        {
                    783:                            if (a->h.hunk[i] == hunkfree)
                    784:                                break;
                    785:                            if (curplength-- == 0)
                    786:                            {
                    787:                                fputs(" ...",useport); 
                    788:                                break;
                    789:                            }
                    790:                            else
                    791:                            {
                    792:                                fputs(" ", useport);
                    793:                                printr(a->h.hunk[i], useport);
                    794:                            }
                    795:                        }
                    796:                        fputs("}", useport);
                    797:                        plevel++;
                    798:                        break;
                    799:                        
                    800:        case VECTOR:
                    801:                        chstr = "vector";
                    802:                        quot = 4;       /* print out # of longwords */
                    803:                        goto veccommon;
                    804: 
                    805:        case VECTORI:
                    806:                        chstr = "vectori";
                    807:                        quot = 1;
                    808:           veccommon:
                    809:                        /* print out 'vector' or 'vectori' except in
                    810:                         * these circumstances:
                    811:                         * property is a symbol, in which case print
                    812:                         *  the symbol's pname
                    813:                         * property is a list with a 'print' property,
                    814:                         *  in which case it is funcalled to print the
                    815:                         *  vector
                    816:                         */
                    817:                        if(a->v.vector[VPropOff] != nil)
                    818:                        {
                    819:                            if ((i=TYPE(a->v.vector[VPropOff])) == ATOM)
                    820:                            {
                    821:                                chstr = a->v.vector[VPropOff]->a.pname;
                    822:                            }
                    823:                            else if ((i == DTPR) && vectorpr(a,useport))
                    824:                            {
                    825:                                break;  /* printed by vectorpr */
                    826:                            }
                    827:                            else if ((i == DTPR)
                    828:                                     && (a->v.vector[VPropOff]->d.car != nil)
                    829:                                     && TYPE(a->v.vector[VPropOff]->d.car)
                    830:                                         == ATOM)
                    831:                            {
                    832:                                chstr = a->v.vector[VPropOff]->d.car->a.pname;
                    833:                            }
                    834:                        }
                    835:                        fprintf(useport,"%s[%d]",
                    836:                                    chstr, a->vl.vectorl[VSizeOff]/quot);
                    837:                        break;
                    838: 
                    839:        case ARRAY:     fputs("array[",useport);
                    840:                        printr(a->ar.length,useport);
                    841:                        fputs("]",useport);
                    842:                        break;
                    843: 
                    844:        case BCD:       fprintf(useport,"#%X-",a->bcd.start);
                    845:                        printr(a->bcd.discipline,useport);
                    846:                        break;
                    847: 
                    848:        case OTHER:     fprintf(useport,"#Other-%X",a);
                    849:                        break;
                    850: 
                    851:        case SDOT:      pbignum(a,useport);
                    852:                        break;
                    853: 
                    854:        case DTPR:      if(plevel==0)
                    855:                        {
                    856:                             fputs("&",useport);
                    857:                             break;
                    858:                        }
                    859:                        plevel--;
                    860:                        if(a->d.car==quota && a->d.cdr!=nil 
                    861:                            && a->d.cdr->d.cdr==nil) {
                    862:                                putc('\'',useport);
                    863:                                printr(a->d.cdr->d.car,useport);
                    864:                                plevel++;
                    865:                                break;
                    866:                        }
                    867:                        putc('(',useport);
                    868:                        curplength--;
                    869:        morelist:       printr(a->d.car,useport);
                    870:                        if ((a = a->d.cdr) != nil)
                    871:                                {
                    872:                                if(curplength-- == 0)
                    873:                                {
                    874:                                    fputs(" ...",useport);
                    875:                                    goto out;
                    876:                                }
                    877:                                putc(' ',useport);
                    878:                                if (TYPE(a) == DTPR) goto morelist;
                    879:                                fputs(". ",useport);
                    880:                                printr(a,useport);
                    881:                                }
                    882:                out:
                    883:                        fputc(')',useport);
                    884:                        plevel++;
                    885:                        break;
                    886: 
                    887:        case STRNG:     strflag = TRUE;
                    888:                        Idqc = Xsdc;
                    889: 
                    890:        case ATOM:      {
                    891:                        char    *front, *temp, first; int clean;
                    892:                        temp = front = (strflag ? ((char *) a) : a->a.pname);
                    893:                        if(Idqc==0) Idqc = Xdqc;
                    894: 
                    895:                        if(Idqc) {
                    896:                                clean = first = *temp;
                    897:                                first &= 0177;
                    898:                                switch(QUTMASK & ctable[first]) {
                    899:                                case QWNFRST:
                    900:                                case QALWAYS:
                    901:                                        clean = 0; break;
                    902:                                case QWNUNIQ:
                    903:                                        if(temp[1]==0) clean = 0;
                    904:                                }
                    905:                                if (first=='-'||first=='+') temp++;
                    906:                                if(synclass(ctable[*temp])==VNUM) clean = 0;
                    907:                                while (clean && *temp) {
                    908:                                        if((ctable[*temp]&QUTMASK)==QALWAYS)
                    909:                                                clean = 0;
                    910:                                        else if(uctolc && (isupper(*temp)))
                    911:                                                clean = 0;
                    912:                                        temp++;
                    913:                                }
                    914:                                if (clean && !strflag)
                    915:                                        fputs(front,useport);
                    916:                                else     {
                    917:                                        putc(Idqc,useport);
                    918:                                        for(temp=front;*temp;temp++) {
                    919:                                                if(  *temp==Idqc
                    920:                                                  || (synclass(ctable[*temp])) == CESC)
                    921:                                                        putc(Xesc,useport);
                    922:                                                putc(*temp,useport);
                    923:                                        }
                    924:                                        putc(Idqc,useport);
                    925:                                }
                    926: 
                    927:                        }  else {
                    928:                                register char *cp = front;
                    929:                                int handy = ctable[*cp & 0177];
                    930: 
                    931:                                if(synclass(handy)==CNUM)
                    932:                                        putc(Xesc,useport);
                    933:                                else switch(handy & QUTMASK) {
                    934:                                case QWNUNIQ:
                    935:                                        if(cp[1]==0) putc(Xesc,useport);
                    936:                                        break;
                    937:                                case QWNFRST:
                    938:                                case QALWAYS:
                    939:                                        putc(Xesc,useport);
                    940:                                }
                    941:                                for(; *cp; cp++) {
                    942:                                        if((ctable[*cp]& QUTMASK)==QALWAYS)
                    943:                                                putc(Xesc,useport);
                    944:                                        putc(*cp,useport);
                    945:                                }
                    946:                        }
                    947:                }
                    948:        }
                    949: }
                    950: 
                    951: /* -- vectorpr
                    952:  * (perhaps) print out vector specially
                    953:  * this is called with a vector whose property list begins with
                    954:  * a list.  We search for the 'print' property and if it exists,
                    955:  * funcall the print function with two args: the vector and the port.
                    956:  * We return TRUE iff we funcalled the function, else we return FALSE
                    957:  * to have the standard printing done
                    958:  */
                    959: 
                    960: vectorpr(vec,port)
                    961: register lispval vec;
                    962: FILE *port;
                    963: {
                    964:     register lispval handy;
                    965:     Savestack(2);
                    966: 
                    967: 
                    968:     for ( handy = vec->v.vector[VPropOff]->d.cdr
                    969:           ; handy != nil; handy = handy->d.cdr->d.cdr)
                    970:     {
                    971:        if (handy->d.car == Vprintsym)
                    972:        {
                    973:            lbot = np;
                    974:            protect(handy->d.cdr->d.car);       /* function to call */
                    975:            protect(vec);
                    976:            protect(P(port));
                    977:            Lfuncal();
                    978:            Restorestack();
                    979:            return(TRUE);       /* did the call */
                    980:        }
                    981:     }
                    982:     Restorestack();
                    983:     return(FALSE);     /* nothing printed */
                    984: }
                    985:            
                    986:     
                    987:     
                    988: 
                    989: 
                    990: 
                    991: lfltpr(buf,val)                /* lisp floating point printer */
                    992: char *buf;
                    993: double val;
                    994: {
                    995:        register char *cp1; char *sprintf();
                    996: 
                    997:        sprintf(buf,(char *)Vfloatformat->a.clb,val);
                    998:        for(cp1 = buf; *cp1; cp1++)
                    999:                if(*cp1=='.'|| *cp1=='E' || *cp1 == 'e') return;
                   1000: 
                   1001:        /* if we are here, there was no dot, so the number was
                   1002:           an integer.  Furthermore, cp1 already points to the 
                   1003:           end of the string. */
                   1004: 
                   1005:        *cp1++ = '.';
                   1006:        *cp1++ = '0';
                   1007:        *cp1++ = 0;
                   1008: }
                   1009:        
                   1010: 
                   1011: /* dmpport ****************************************************************/
                   1012: /* outputs buffer indicated by first argument whether full or not      */
                   1013: 
                   1014: dmpport(useport)
                   1015: FILE *useport;
                   1016: {
                   1017:        fflush(useport);
                   1018: }
                   1019: 
                   1020: /*  protect and unprot moved to eval.c  (whr)  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.