Annotation of coherent/d/bin/conv/conv.y, revision 1.1.1.1

1.1       root        1: /* conv - programmer's calculator
                      2:  * conv evaluates expressions in c style syntax and reports the results
                      3:  * in hexadecimal, decimal, octal, binary, and ascii character constants.
                      4:  * If arguments are present, they are each evaluated as independent
                      5:  * expressions, otherwise each line of standard input is evaluated.
                      6:  * Input numbers follow the style of the old conv, ie
                      7:  *     #digits - hexadecimal
                      8:  *     0xdigits - hexadecimal
                      9:  *     0Xdigits - hexadecimal
                     10:  *     0digits - octal
                     11:  *     $digits - binary
                     12:  *     digits - decimal
                     13:  *     'character - ascii character constant
                     14:  * The only expressions not allowed are those involving arrays, pointers,
                     15:  * structure members, and addresses.  All of the integer arithmetic ops
                     16:  * are supported including variables, assignment ops, conditional expressions,
                     17:  * and the comma operator.
                     18:  * In addition, there is an iterative conditional expression
                     19:  *     <expr1> ?? <expr2> :: <expr3>
                     20:  * which evaluates to while (<expr1>) <expr2>; <expr3>, that is evaluating
                     21:  * <expr2> as often as <expr1> evaluates to true, then returning the value
                     22:  * of <expr3>.
                     23:  * Bug: function definition and evaluation should be permitted.
                     24:  */
                     25: %{
                     26: #include <ctype.h>
                     27: 
                     28: #define        NNODES  1000
                     29: 
                     30: char   *version = "Conv Version 2.00.\n";
                     31: 
                     32: typedef union yynode {
                     33:        struct {
                     34:                int     n_op;
                     35:                union yynode *n1_ln;
                     36:                union yynode *n1_rn;
                     37:        } yyn1;
                     38:        struct {
                     39:                int     n_op;
                     40:                long    n2_val;
                     41:        } yyn2;
                     42:        struct {
                     43:                char    n3_name[];
                     44:        } yyn3;
                     45: } NODE;
                     46: #define n_ln   yyn1.n1_ln
                     47: #define n_rn   yyn1.n1_rn
                     48: #define n_val  yyn2.n2_val
                     49: #define n_name yyn3.n3_name
                     50: 
                     51: #define NULL ((NODE *)0)
                     52: NODE *node();
                     53: NODE *vnode();
                     54: NODE *nnode();
                     55: NODE *hash();
                     56: NODE *dotp;
                     57: long getcc();
                     58: long getv();
                     59: 
                     60: %}
                     61: 
                     62: %union {
                     63:        int     yy_op;
                     64:        long    yy_val;
                     65:        NODE    *yy_nod;
                     66: }
                     67: 
                     68: %start list
                     69: 
                     70: %token NUMBER NAME CALL LINK
                     71: %token INC DEC INCBEF DECBEF INCAFT DECAFT
                     72: 
                     73: %left ','
                     74: %right '=' ADDEQ SUBEQ MULEQ DIVEQ REMEQ ANDEQ IOREQ EOREQ SHLEQ SHREQ
                     75: %left QUQU COCO
                     76: %left '?' ':'
                     77: %left OR
                     78: %left AND
                     79: %left '|'
                     80: %left '^'
                     81: %left '&'
                     82: %left EQ NE
                     83: %left '<' '>' LE GE
                     84: %left SHL SHR
                     85: %left '+' '-'
                     86: %left '*' '/' '%'
                     87: %right '~' '!' UMINUS
                     88: 
                     89: %type <yy_op> '=' ADDEQ SUBEQ MULEQ DIVEQ REMEQ ANDEQ IOREQ EOREQ SHLEQ SHREQ
                     90: %type <yy_op> '?' ':' OR AND '|' '^' '&'
                     91: %type <yy_op> EQ NE '<' '>' LE GE
                     92: %type <yy_op> SHL SHR '+' '-' '*' '/' '%'
                     93: %type <yy_op> '~' '!' UMINUS '(' ')' ','
                     94: %type <yy_op> INC DEC INCAFT INCBEF DECAFT DECBEF
                     95: %type <yy_nod> NAME
                     96: %type <yy_val> NUMBER
                     97: %type <yy_nod> expr
                     98: 
                     99: %%
                    100: 
                    101: list:  /* empty */
                    102: |      list '\n'
                    103: |      list expr '\n' {
                    104:                eval($2, dotp->n_ln);
                    105:                        switch ($2->n_op) {
                    106:                case IOREQ:
                    107:                case EOREQ:
                    108:                case ANDEQ:
                    109:                case SHLEQ:
                    110:                case SHREQ:
                    111:                case REMEQ:
                    112:                case DIVEQ:
                    113:                case MULEQ:
                    114:                case SUBEQ:
                    115:                case ADDEQ:
                    116:                case '=':
                    117:                        break;
                    118:                default:
                    119:                        putv(dotp->n_ln);
                    120:                }
                    121:                nfree($2);
                    122:        }
                    123: |      list error '\n' {
                    124:                yyerrok;
                    125:        }
                    126: ;
                    127: 
                    128: 
                    129: expr:  expr ',' expr {
                    130:                $$ = node($2, $1, $3);
                    131:        }
                    132: |      NAME '=' expr {
                    133:                $$ = node($2, $1, $3);
                    134:        }
                    135: |      NAME ADDEQ expr {
                    136:                $$ = node($2, $1, $3);
                    137:        }
                    138: |      NAME SUBEQ expr {
                    139:                $$ = node($2, $1, $3);
                    140:        }
                    141: |      NAME MULEQ expr {
                    142:                $$ = node($2, $1, $3);
                    143:        }
                    144: |      NAME DIVEQ expr {
                    145:                $$ = node($2, $1, $3);
                    146:        }
                    147: |      NAME REMEQ expr {
                    148:                $$ = node($2, $1, $3);
                    149:        }
                    150: |      NAME ANDEQ expr {
                    151:                $$ = node($2, $1, $3);
                    152:        }
                    153: |      NAME IOREQ expr {
                    154:                $$ = node($2, $1, $3);
                    155:        }
                    156: |      NAME EOREQ expr {
                    157:                $$ = node($2, $1, $3);
                    158:        }
                    159: |      NAME SHLEQ expr {
                    160:                $$ = node($2, $1, $3);
                    161:        }
                    162: |      NAME SHREQ expr {
                    163:                $$ = node($2, $1, $3);
                    164:        }
                    165: |      NAME INC {
                    166:                $$ = node(INCAFT, $1, NULL);
                    167:        }
                    168: |      NAME DEC {
                    169:                $$ = node(DECAFT, $1, NULL);
                    170:        }
                    171: |      INC NAME {
                    172:                $$ = node(INCBEF, $2, NULL);
                    173:        }
                    174: |      DEC NAME {
                    175:                $$ = node(DECBEF, $2, NULL);
                    176:        }
                    177: |      expr QUQU expr COCO expr {
                    178:                $$ = node($2, $1, node($4, $3, $5));
                    179:        }
                    180: |      expr '?' expr ':' expr {
                    181:                $$ = node($2, $1, node($4, $3, $5));
                    182:        }
                    183: |      expr OR expr {
                    184:                $$ = node($2, $1, $3);
                    185:        }
                    186: |      expr AND expr {
                    187:                $$ = node($2, $1, $3);
                    188:        }
                    189: |      expr '|' expr {
                    190:                $$ = node($2, $1, $3);
                    191:        }
                    192: |      expr '^' expr {
                    193:                $$ = node($2, $1, $3);
                    194:        }
                    195: |      expr '&' expr {
                    196:                $$ = node($2, $1, $3);
                    197:        }
                    198: |      expr EQ expr {
                    199:                $$ = node($2, $1, $3);
                    200:        }
                    201: |      expr NE expr {
                    202:                $$ = node($2, $1, $3);
                    203:        }
                    204: |      expr '<' expr {
                    205:                $$ = node($2, $1, $3);
                    206:        }
                    207: |      expr '>' expr {
                    208:                $$ = node($2, $1, $3);
                    209:        }
                    210: |      expr LE expr {
                    211:                $$ = node($2, $1, $3);
                    212:        }
                    213: |      expr GE expr {
                    214:                $$ = node($2, $1, $3);
                    215:        }
                    216: |      expr SHR expr {
                    217:                $$ = node($2, $1, $3);
                    218:        }
                    219: |      expr SHL expr {
                    220:                $$ = node($2, $1, $3);
                    221:        }
                    222: |      expr '+' expr {
                    223:                $$ = node($2, $1, $3);
                    224:        }
                    225: |      expr '-' expr {
                    226:                $$ = node($2, $1, $3);
                    227:        }
                    228: |      expr '*' expr {
                    229:                $$ = node($2, $1, $3);
                    230:        }
                    231: |      expr '/' expr {
                    232:                $$ = node($2, $1, $3);
                    233:        }
                    234: |      expr '%' expr {
                    235:                $$ = node($2, $1, $3);
                    236:        }
                    237: |      '-' expr %prec UMINUS {
                    238:                $$ = node(UMINUS, $2, NULL);
                    239:        }
                    240: |      '~' expr %prec UMINUS {
                    241:                $$ = node($1, $2, NULL);
                    242:        }
                    243: |      '!' expr %prec UMINUS {
                    244:                $$ = node($1, $2, NULL);
                    245:        }
                    246: |      NAME {
                    247:                $$ = $1;
                    248:        }
                    249: |      NUMBER {
                    250:                $$ = vnode($1);
                    251:        }
                    252: |      '(' expr ')' {
                    253:                $$ = node($1, $2, NULL);
                    254:        }
                    255: ;
                    256: 
                    257: 
                    258: %%
                    259: 
                    260: yylex()
                    261: {
                    262:        register int c;
                    263:        char *seq = "=";
                    264:        char tmpbuf[64];
                    265:        register char *p;
                    266: 
                    267: again:
                    268:        while ((c=getc()) == ' ' || c == '\t')
                    269:                ;
                    270: 
                    271:        if (isalnum(c) || c == '#' || c == '$') {
                    272:                tmpbuf[0] = c;
                    273:                c = getc();
                    274:                for (p = tmpbuf+1; p < &tmpbuf[64] && isalnum(c); c = getc())
                    275:                        *p++ = c;
                    276:                ungetc(c);
                    277:                *p++ = 0;
                    278:                c = tmpbuf[0];
                    279:                if (c == '#' || c == '$' || isdigit(c)) {
                    280:                        yylval.yy_val = getv(tmpbuf);
                    281:                        return (NUMBER);
                    282:                }
                    283:                yylval.yy_nod = hash(tmpbuf);
                    284:                return (NAME);
                    285:        }
                    286:        switch (c) {
                    287: 
                    288:        case '\'':
                    289:                yylval.yy_val = getcc();
                    290:                return NUMBER;
                    291:        case '\\': if (substr("\n", 1, 0))
                    292:                        goto again;
                    293:                return yylval.yy_op = c;
                    294:        case '+': return substr("=+", ADDEQ, INC, c);
                    295:        case '-': return substr("=-", SUBEQ, DEC, c);
                    296:        case '*': return substr(seq, MULEQ, c);
                    297:        case '/': return substr(seq, DIVEQ, c);
                    298:        case '%': return substr(seq, REMEQ, c);
                    299:        case '&': return substr("=&", ANDEQ, AND, c);
                    300:        case '|': return substr("=|", IOREQ, OR, c);
                    301:        case '^': return substr(seq, EOREQ, c);
                    302:        case '=': return substr(seq, EQ, c);
                    303:        case '!': return substr(seq, NE, c);
                    304:        case '<': if ((c = substr("<=", SHL, LE, c)) == SHL)
                    305:                        return substr(seq, SHLEQ, c);
                    306:                return yylval.yy_op = c;
                    307:        case '>': if ((c = substr(">=", SHR, GE, c)) == SHR)
                    308:                        return substr(seq, SHREQ, c);
                    309:                return yylval.yy_op = c;
                    310:        case '.':
                    311:                yylval.yy_nod = dotp;
                    312:                return NAME;
                    313:        }
                    314:        return yylval.yy_op = c;
                    315: }
                    316: 
                    317: NODE *reg[32];
                    318: 
                    319: NODE *
                    320: hash(bp)
                    321: char *bp;
                    322: {
                    323:        int hash;
                    324:        {
                    325:                register char *p;
                    326:                register c;
                    327: 
                    328:                hash = 0;
                    329:                p = bp;
                    330:                while (c = *p++)
                    331:                        hash += c;
                    332:        }
                    333:        {
                    334:                register NODE *rp, **ep;
                    335: 
                    336:                bp[sizeof(NODE)] = 0;
                    337:                for (ep = &reg[hash & 31]; rp = *ep; ep = &rp->n_rn) {
                    338:                        if (strcmp(bp, rp->n_ln->n_rn->n_name) == 0)
                    339:                                return (rp->n_ln);
                    340:                }
                    341:                rp = node(NAME, vnode((long) 0), nnode(bp));
                    342:                *ep = node(LINK, rp, NULL);
                    343:                return (rp);
                    344:        }
                    345: }
                    346: 
                    347: /*
                    348:  * Depending on the next character, return one of several tokens.
                    349:  */
                    350: substr(cp, t1)
                    351: register char *cp;
                    352: int t1;
                    353: {
                    354:        register int cn;
                    355:        register int *tp;
                    356: 
                    357:        tp = &t1;
                    358:        cn = getc();
                    359:        while (*cp)
                    360:                if (*cp++ == cn)
                    361:                        return yylval.yy_op = *tp;
                    362:                else
                    363:                        tp += 1;
                    364:        ungetc(cn);
                    365:        return yylval.yy_op = *tp;
                    366: }
                    367: 
                    368: int peekc;
                    369: char *inputs = 0;
                    370: 
                    371: getc()
                    372: {
                    373:        register int c;
                    374: 
                    375:        if (peekc) {
                    376:                c = peekc;
                    377:                peekc = 0;
                    378:        } else if (inputs != 0) {
                    379:                if (c = *inputs)
                    380:                        inputs += 1;
                    381:                else
                    382:                        c = -1;
                    383:        } else
                    384:                c = getchar();
                    385:        return c;
                    386: }
                    387: 
                    388: ungetc(c)
                    389: {
                    390:        peekc = c;
                    391: }
                    392: 
                    393: main(argc, argv)
                    394: char *argv[];
                    395: {
                    396:        dotp = node(NAME, vnode((long) 0), NULL);
                    397:        if (argc > 1) {
                    398:                while (--argc > 0) {
                    399:                        ++argv;
                    400:                        if (!strcmp(*argv, "-V")) {
                    401:                                printf(version);
                    402:                                exit(0);
                    403:                        }
                    404:                        inputs = malloc(strlen(*argv)+2);
                    405:                        strcpy(inputs, *argv);
                    406:                        strcat(inputs, "\n");
                    407:                        yyparse();
                    408:                }
                    409:        } else {
                    410:                inputs = 0;
                    411:                yyparse();
                    412:        }
                    413:        return 0;
                    414: }
                    415: yyerror() { puts("Syntax"); }
                    416: 
                    417: NODE _nodes_[NNODES];
                    418: NODE *_np_ = &_nodes_[0];
                    419: 
                    420: NODE *
                    421: alloc()
                    422: {
                    423:        register NODE *np;
                    424: 
                    425:        np = _np_;
                    426:        for (;;) {
                    427:                if (np->n_op == 0) {
                    428:                        _np_ = np;
                    429:                        return (np);
                    430:                }
                    431:                if (++np >= &_nodes_[NNODES])
                    432:                        np = &_nodes_[0];
                    433:                if (np == _np_)
                    434:                        break;
                    435:        }
                    436:        puts("No space");
                    437:        exit(1);
                    438: }
                    439: 
                    440: nfree(np)
                    441: register NODE *np;
                    442: {
                    443:        if (np->n_op != NAME && np->n_op != NUMBER) {
                    444:                if (np->n_rn != NULL)
                    445:                        nfree(np->n_rn);
                    446:                nfree(np->n_ln);
                    447:        }
                    448:        if (np->n_op != NAME) {
                    449:                np->n_op = 0;
                    450:                if (np < _np_)
                    451:                        _np_ = np;
                    452:        }
                    453: }
                    454: 
                    455: NODE *
                    456: node(op, nl, nr)
                    457: NODE *nl, *nr;
                    458: {
                    459:        register NODE *np;
                    460: 
                    461:        np = alloc();
                    462:        np->n_op = op;
                    463:        np->n_ln = nl;
                    464:        np->n_rn = nr;
                    465:        return (np);
                    466: }
                    467: 
                    468: NODE *
                    469: vnode(va)
                    470: long va;
                    471: {
                    472:        register NODE *np;
                    473: 
                    474:        np = alloc();
                    475:        np->n_op = NUMBER;
                    476:        np->n_val = va;
                    477:        return (np);
                    478: }
                    479: 
                    480: NODE *
                    481: nnode(cp)
                    482: register char *cp;
                    483: {
                    484:        register NODE *np;
                    485:        register char *p;
                    486: 
                    487:        np = alloc();
                    488:        p = np->n_name;
                    489:        while (p < np+1)
                    490:                *p++ = *cp++;
                    491:        return (np);
                    492: }
                    493: 
                    494: eval(np, dp)
                    495: register NODE *np, *dp;
                    496: {
                    497:        NODE lval, rval, *lptr;
                    498: 
                    499:        dp->n_op = NUMBER;
                    500: again:
                    501:        switch (np->n_op) {
                    502:        case '=':
                    503:        case ADDEQ:
                    504:        case SUBEQ:
                    505:        case MULEQ:
                    506:        case DIVEQ:
                    507:        case REMEQ:
                    508:        case SHREQ:
                    509:        case SHLEQ:
                    510:        case ANDEQ:
                    511:        case EOREQ:
                    512:        case IOREQ:
                    513:                eval(np->n_rn, &rval);
                    514:                /* Fall through */
                    515:        case INCBEF:
                    516:        case DECBEF:
                    517:        case INCAFT:
                    518:        case DECAFT:
                    519:                lptr = np->n_ln->n_ln;
                    520:                break;
                    521:        case NAME:
                    522:                lptr = np->n_ln;
                    523:                break;
                    524:        case ',':
                    525:        case '|':
                    526:        case '^':
                    527:        case '&':
                    528:        case EQ:
                    529:        case NE:
                    530:        case '<':
                    531:        case '>':
                    532:        case LE:
                    533:        case GE:
                    534:        case SHR:
                    535:        case SHL:
                    536:        case '+':
                    537:        case '-':
                    538:        case '*':
                    539:        case '/':
                    540:        case '%':
                    541:                eval(np->n_rn, &rval);
                    542:                /* Fall through */
                    543:        case UMINUS:
                    544:        case '~':
                    545:        case '!':
                    546:        case QUQU:
                    547:        case '?':
                    548:        case OR:
                    549:        case AND:
                    550:                eval(np->n_ln, &lval);
                    551:                break;
                    552:        case NUMBER:
                    553:                lptr = np;
                    554:                break;
                    555:        case '(':
                    556:                np = np->n_ln;
                    557:                goto again;
                    558:        default:
                    559:                printf("Bad operator: %d\n", np->n_op);
                    560:                return;
                    561:        }
                    562:        switch (np->n_op) {
                    563:        case ',':
                    564:                np = np->n_rn;
                    565:                goto again;
                    566:        case '=':
                    567:                lptr->n_val = rval.n_val;
                    568:                *dp = *lptr;
                    569:                break;
                    570:        case ADDEQ:
                    571:                lptr->n_val += rval.n_val;
                    572:                *dp = *lptr;
                    573:                break;
                    574:        case SUBEQ:
                    575:                lptr->n_val -= rval.n_val;
                    576:                *dp = *lptr;
                    577:                break;
                    578:        case MULEQ:
                    579:                lptr->n_val *= rval.n_val;
                    580:                *dp = *lptr;
                    581:                break;
                    582:        case DIVEQ:
                    583:                lptr->n_val /= rval.n_val;
                    584:                *dp = *lptr;
                    585:                break;
                    586:        case REMEQ:
                    587:                lptr->n_val %= rval.n_val;
                    588:                *dp = *lptr;
                    589:                break;
                    590:        case SHREQ:
                    591:                lptr->n_val >>= rval.n_val;
                    592:                *dp = *lptr;
                    593:                break;
                    594:        case SHLEQ:
                    595:                lptr->n_val <<= rval.n_val;
                    596:                *dp = *lptr;
                    597:                break;
                    598:        case ANDEQ:
                    599:                lptr->n_val &= rval.n_val;
                    600:                *dp = *lptr;
                    601:                break;
                    602:        case EOREQ:
                    603:                lptr->n_val ^= rval.n_val;
                    604:                *dp = *lptr;
                    605:                break;
                    606:        case IOREQ:
                    607:                lptr->n_val |= rval.n_val;
                    608:                *dp = *lptr;
                    609:                break;
                    610:        case INCBEF:
                    611:                ++lptr->n_val;
                    612:                *dp = *lptr;
                    613:                break;
                    614:        case DECBEF:
                    615:                --lptr->n_val;
                    616:                *dp = *lptr;
                    617:                break;
                    618:        case INCAFT:
                    619:                *dp = *lptr;
                    620:                lptr->n_val++;
                    621:                break;
                    622:        case DECAFT:
                    623:                *dp = *lptr;
                    624:                lptr->n_val++;
                    625:                break;
                    626:        case NAME:
                    627:                *dp = *lptr;
                    628:                break;
                    629:        case NUMBER:
                    630:                *dp = *lptr;
                    631:                break;
                    632:        case '|':
                    633:                dp->n_val = lval.n_val | rval.n_val;
                    634:                break;
                    635:        case '^':
                    636:                dp->n_val = lval.n_val ^ rval.n_val;
                    637:                break;
                    638:        case '&':
                    639:                dp->n_val = lval.n_val & rval.n_val;
                    640:                break;
                    641:        case EQ:
                    642:                dp->n_val = lval.n_val == rval.n_val;
                    643:                break;
                    644:        case NE:
                    645:                dp->n_val = lval.n_val != rval.n_val;
                    646:                break;
                    647:        case '<':
                    648:                dp->n_val = lval.n_val < rval.n_val;
                    649:                break;
                    650:        case '>':
                    651:                dp->n_val = lval.n_val > rval.n_val;
                    652:                break;
                    653:        case LE:
                    654:                dp->n_val = lval.n_val <= rval.n_val;
                    655:                break;
                    656:        case GE:
                    657:                dp->n_val = lval.n_val >= rval.n_val;
                    658:                break;
                    659:        case SHR:
                    660:                dp->n_val = lval.n_val >> rval.n_val;
                    661:                break;
                    662:        case SHL:
                    663:                dp->n_val = lval.n_val << rval.n_val;
                    664:                break;
                    665:        case '+':
                    666:                dp->n_val = lval.n_val + rval.n_val;
                    667:                break;
                    668:        case '-':
                    669:                dp->n_val = lval.n_val - rval.n_val;
                    670:                break;
                    671:        case '*':
                    672:                dp->n_val = lval.n_val * rval.n_val;
                    673:                break;
                    674:        case '/':
                    675:                dp->n_val = lval.n_val / rval.n_val;
                    676:                break;
                    677:        case '%':
                    678:                dp->n_val = lval.n_val % rval.n_val;
                    679:                break;
                    680:        case UMINUS:
                    681:                dp->n_val = - lval.n_val;
                    682:                break;
                    683:        case '~':
                    684:                dp->n_val = ~ lval.n_val;
                    685:                break;
                    686:        case '!':
                    687:                dp->n_val = ! lval.n_val;
                    688:                break;
                    689:        case QUQU:
                    690:                if (lval.n_val)
                    691:                        eval(np->n_rn->n_ln, &rval);
                    692:                else
                    693:                        np = np->n_rn->n_rn;
                    694:                goto again;
                    695:        case '?':
                    696:                if (lval.n_val)
                    697:                        np = np->n_rn->n_ln;
                    698:                else
                    699:                        np = np->n_rn->n_rn;
                    700:                goto again;
                    701:        case OR:
                    702:                if (lval.n_val != 0) {
                    703:                        *dp = lval;
                    704:                        break;
                    705:                }
                    706:                np = np->n_rn;
                    707:                goto again;
                    708:        case AND:
                    709:                if (lval.n_val == 0) {
                    710:                        *dp = lval;
                    711:                        break;
                    712:                }
                    713:                np = np->n_rn;
                    714:                goto again;
                    715:        }
                    716: }
                    717: 
                    718: long
                    719: getcc()
                    720: {
                    721:        register int c, d;
                    722:        c = getc();
                    723:        d = getc();
                    724:        if (d != '\'') ungetc(d);
                    725:        return c;
                    726: }
                    727: 
                    728: char digits[16] = "0123456789ABCDEF";
                    729: 
                    730: long
                    731: getv(dp)
                    732: register char *dp;
                    733: {
                    734:        register int d;
                    735:        register long v;
                    736:        register int b;
                    737: 
                    738:        v = 0;
                    739:        b = 10; d = *dp++;
                    740:        switch (d) {
                    741:        case '#': b = 16; d = *dp++; break;
                    742:        case '$': b = 2; d = *dp++; break;
                    743:        case '0': b = 8; d = *dp++;
                    744:                if (d == 'x' || d == 'X') {
                    745:                        b = 16; d = *dp++;
                    746:                }
                    747:                break;
                    748:        }
                    749:        while ((isdigit(d) && (d -= '0') < b)
                    750:            || (isupper(d) && (d += 10 - 'A') < b)
                    751:            || (islower(d) && (d += 10 - 'a') < b)) {
                    752:                v = v * b + d;
                    753:                d = *dp++;
                    754:                if (d == 0)
                    755:                        return v;
                    756:        }
                    757:        printf("Bad digit: 0%o\n", dp[-1]);
                    758:        return v;
                    759: }
                    760: 
                    761: putv(v) NODE *v;
                    762: {
                    763:        long    l;
                    764:        register        c;
                    765:        long            m;
                    766: 
                    767:        l = v->n_val;
                    768:        /*
                    769:         * hex, decimal, octal
                    770:         */
                    771:        printf( "#%X %D 0%O $", l, l, l);
                    772:        /*
                    773:         * binary
                    774:         */
                    775:        for (c=32, m=l; m; --c, m<<=1)
                    776:                if (m < 0)
                    777:                        break;
                    778:        do {
                    779:                printf( m<0? "1": "0");
                    780:                m <<= 1;
                    781:        } while (--c);
                    782:        /*
                    783:         * char
                    784:         */
                    785:        printf( " '");
                    786:        if ((c=(char)l) < 0) {
                    787:                printf( "~");
                    788:                c &= 0177;
                    789:        }
                    790:        if (c<' ' || c=='\177') {
                    791:                printf( "^");
                    792:                if (c == '\177')
                    793:                        c = '?';
                    794:                else
                    795:                        c += '@';
                    796:        }
                    797:        printf( "%c'\n", c);
                    798: }

unix.superglobalmegacorp.com

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