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

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