Annotation of coherent/d/bin/dc/dc.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * DC - Reverse Polish desk calculator (multi-precision)
                      3:  * Depends on mint value being defined as a `char *'
                      4:  * so mint may also be char string
                      5:  */
                      6: #include <stdio.h>
                      7: #include "bc.h"
                      8: 
                      9: char   *version = "DC Version 1.00.\n";
                     10: 
                     11: #define        NREG    256
                     12: #define        NSTACK  256
                     13: 
                     14: struct reg_t   {
                     15:        struct  reg_t   *next;
                     16:        rvalue  regval;
                     17: }      *reg[NREG];
                     18: 
                     19: rvalue stack[NSTACK],
                     20:        *sp = &stack[0];
                     21: 
                     22: static char    *soflmsg = "Out of pushdown",
                     23:                *suflmsg = "stack empty",
                     24:                *oospmsg = "Out of space",
                     25:                *nregmsg = "Missing reg name";
                     26: 
                     27: #define        skiperr(m) {fprintf(stderr,"%s\n",m);return(-1);}
                     28: 
                     29: #define        push(x) {if(sp==&stack[NSTACK]){skiperr(soflmsg);}else{x=sp++;}}
                     30: 
                     31: #define        pop(x)  {if(sp==&stack[0]){skiperr(suflmsg);}else{x=--sp;}}
                     32: 
                     33: #define        new(x)  {push(x);minit(&(x)->mantissa);}
                     34: 
                     35: #define        temp(x) {push(x);pop(x);}
                     36: 
                     37: #define        tos(x)  {pop(x);push(x);}
                     38: 
                     39: #define        getreg(c,r){if((c=getc(infile))==EOF){skiperr(nregmsg);}else{r=reg[c];}}
                     40: 
                     41: #define        newreg(c, r) {\
                     42:                struct reg_t *nr=(struct reg_t *)malloc(sizeof(struct reg_t));\
                     43:                if (nr == NULL) {\
                     44:                        skiperr(oospmsg);\
                     45:                } else {\
                     46:                        nr->next = r;\
                     47:                        r = reg[c] = nr;\
                     48:                }\
                     49:        }
                     50: 
                     51: #define        execute(x, y) if((x)->scale<0){\
                     52:        FILE f;char *s=(x)->mantissa.val;if(y)minit(&(x)->mantissa);\
                     53:        _stropen(s,strlen(s),&f);c=interp(&f);infile=fp;if(y)mpfree(s);\
                     54:        if(c)return(c-1);}
                     55: 
                     56: main(argc, argv)
                     57: int    argc;
                     58: char   *argv[];
                     59: {
                     60:        FILE    *fp;
                     61: 
                     62:        init();
                     63:        if (argc > 1)
                     64:                if (!strcmp(argv[1], "-V")) {
                     65:                        fprintf(stderr, version);
                     66:                        exit(0);
                     67:                } else if ((fp=fopen(argv[1], "r"))==NULL) {
                     68:                        fprintf(stderr, "Dc: can't open %s\n", argv[1]);
                     69:                        return (1);
                     70:                } else if (interp(fp) > 0)
                     71:                        return (0);
                     72:                else
                     73:                        fclose(fp);
                     74:        while (interp(stdin) < 0)
                     75:                ;
                     76:        return (0);
                     77: }
                     78: 
                     79: interp(fp)
                     80: FILE   *fp;
                     81: {
                     82:        register int    c;
                     83:        register rvalue *a, *b;
                     84:        struct  reg_t   *r;
                     85:        int     (*f)();
                     86:        int     d;
                     87:        extern int iseq(), isne(), islt(), isle(), isge(), isgt();
                     88:        extern int dcsub(), bcadd(), bcmul(), bcdiv(), bcrem(), bcexp();
                     89:        extern int sibase(), sobase(), output();
                     90: 
                     91:        infile = fp;
                     92:        for (f=NULL;;f=NULL) switch (c = getc(infile)) {
                     93:        case EOF:
                     94:                return (0);
                     95:        case ' ':
                     96:        case '\t':
                     97:        case '\n':
                     98:                continue;
                     99:        case '_':
                    100:                c = getc(infile);
                    101:                f = mneg;
                    102:                /* Fall through */
                    103:        case '0': case '1': case '2': case '3':
                    104:        case '4': case '5': case '6': case '7':
                    105:        case '8': case '9': case 'A': case 'B':
                    106:        case 'C': case 'D': case 'E': case 'F':
                    107:        case '.':
                    108:                push(a);
                    109:                b = getnum(c);
                    110:                *a = *b;
                    111:                mpfree((char *)b);
                    112:                if (f!=NULL)
                    113:                        (*f)(&a->mantissa, &a->mantissa);
                    114:                continue;
                    115:        case '-':
                    116:                f = dcsub;
                    117:                goto binary;
                    118:        case '+':
                    119:                f = bcadd;
                    120:                goto binary;
                    121:        case '*':
                    122:                f = bcmul;
                    123:                goto binary;
                    124:        case '/':
                    125:                f = bcdiv;
                    126:                goto binary;
                    127:        case '%':
                    128:                f = bcrem;
                    129:                goto binary;
                    130:        case '^':
                    131:                f = bcexp;
                    132:                /* Fall through */
                    133:        binary:
                    134:                pop(b);
                    135:                pop(a);
                    136:                (*f)(b, a);
                    137:                push(a);
                    138:                continue;
                    139:        case '[':
                    140:                push(a);
                    141:                if (c = rdstring(a))
                    142:                        return (c);
                    143:                continue;
                    144:        case '<':
                    145:                f = islt;
                    146:                goto compare;
                    147:        case '=':
                    148:                f = iseq;
                    149:                goto compare;
                    150:        case '>':
                    151:                f = isgt;
                    152:                goto compare;
                    153:        case '!':
                    154:                switch (c=getc(infile)) {
                    155:                case '<':
                    156:                        f = isge;
                    157:                        goto compare;
                    158:                case '=':
                    159:                        f = isne;
                    160:                        goto compare;
                    161:                case '>':
                    162:                        f = isle;
                    163:                        goto compare;
                    164:                default:
                    165:                        ungetc(c, infile);
                    166:                        temp(a);
                    167:                        rdline(a, infile);
                    168:                        system(a->mantissa.val);
                    169:                        printf("!\n");
                    170:                        mvfree(&a->mantissa);
                    171:                        continue;
                    172:                }
                    173:        compare:
                    174:                pop(b);
                    175:                pop(a);
                    176:                d = (*f)(bccmp(b, a));
                    177:                getreg(c, r);
                    178:                if (d && r != NULL)
                    179:                        execute(&r->regval, 0);
                    180:                continue;
                    181:        case '?':
                    182:                temp(a);
                    183:                rdline(a, stdin);
                    184:                execute(a, 1);
                    185:                continue;
                    186:        case 'c':
                    187:                while (sp != &stack[0]) {
                    188:                        pop(a);
                    189:                        mvfree(&a->mantissa);
                    190:                }
                    191:                continue;
                    192:        case 'd':
                    193:                tos(a);
                    194:                new(b);
                    195:                mcopy(&a->mantissa, &b->mantissa);
                    196:                b->scale = a->scale;
                    197:                continue;
                    198:        case 'f':
                    199:                for (c = 0;  c != NREG; c++)
                    200:                        if ((r=reg[c]) != NULL) {
                    201:                                printf("`%c': ", c);
                    202:                                output(&r->regval);
                    203:                        }
                    204:                printf("stack:\n");
                    205:                for (a = &stack[0];  a < sp;  a++)
                    206:                        output(a);
                    207:                continue;
                    208:        case 'i':
                    209:                f = sibase;
                    210:                goto unary;
                    211:        case 'I':
                    212:        case 'K':
                    213:                new(a);
                    214:                mitom((c=='I' ? ibase : scale), &a->mantissa);
                    215:                a->scale = 0;
                    216:                continue;
                    217:        case 'k':
                    218:                pop(a);
                    219:                scale = rtoint(a);
                    220:                mvfree(&a->mantissa);
                    221:                if (scale < 0) {
                    222:                        scale = 0;
                    223:                        skiperr("Scale < 0");
                    224:                }
                    225:                continue;
                    226:        case 'l':
                    227:        case 'L':
                    228:                getreg(c, r);
                    229:                new(a);
                    230:                if (r == NULL) {
                    231:                        newscalar(a);
                    232:                } else if (c == 'l') {
                    233:                        mcopy(&r->regval.mantissa, &a->mantissa);
                    234:                        a->scale = r->regval.scale;
                    235:                } else {
                    236:                        reg[c] = r->next;
                    237:                        *a = r->regval;
                    238:                        free((char *)r);
                    239:                }
                    240:                continue;
                    241:        case 'o':
                    242:                f = sobase;
                    243:                goto unary;
                    244:        case 'O':
                    245:                new(a);
                    246:                mcopy(&outbase, &a->mantissa);
                    247:                a->scale = 0;
                    248:                continue;
                    249:        case 'p':
                    250:                tos(a);
                    251:                output(a);
                    252:                continue;
                    253:        case 'P':
                    254:                f = output;
                    255:                /* Fall through */
                    256:        unary:
                    257:                pop(a);
                    258:                (*f)(a);
                    259:                mvfree(&a->mantissa);
                    260:                continue;
                    261:        case 'q':
                    262:                return (1);
                    263:                continue;
                    264:        case 'Q':
                    265:                pop(a);
                    266:                c = rtoint(a);
                    267:                mvfree(&a->mantissa);
                    268:                return (--c > 0 ? c : 0);
                    269:                continue;
                    270:        case 's':
                    271:                getreg(c, r);
                    272:                pop(a);
                    273:                if (r != NULL) {
                    274:                        mvfree(&r->regval.mantissa);
                    275:                } else
                    276:                        newreg(c, r);
                    277:                r->regval = *a;
                    278:                continue;
                    279:        case 'S':
                    280:                getreg(c, r);
                    281:                pop(a);
                    282:                newreg(c, r);
                    283:                r->regval = *a;
                    284:                continue;
                    285:        case 'v':
                    286:                tos(a);
                    287:                bcsqrt(a);
                    288:                continue;
                    289:        case 'x':
                    290:                pop(a);
                    291:                execute(a, 1);
                    292:                continue;
                    293:        case 'X':
                    294:                tos(a);
                    295:                mitom(a->scale, &a->mantissa);
                    296:                a->scale = 0;
                    297:                continue;
                    298:        case 'z':
                    299:                new(a);
                    300:                mitom(sp - &stack[0], &a->mantissa);
                    301:                a->scale = 0;
                    302:                continue;
                    303:        case 'Z':
                    304:        {
                    305:                char    *s;
                    306: 
                    307:                tos(a);
                    308:                s = mtos(&a->mantissa);
                    309:                mitom(strlen(s), &a->mantissa);
                    310:                a->scale = 0;
                    311:                mpfree(s);
                    312:        }
                    313:                continue;
                    314:        default:
                    315:                fprintf(stderr, "`%c'", c);
                    316:                skiperr("?");
                    317:        }
                    318: }
                    319: 
                    320: iseq(x)
                    321: {
                    322:        return (x==0);
                    323: }
                    324: 
                    325: isne(x)
                    326: {
                    327:        return (x!=0);
                    328: }
                    329: 
                    330: islt(x)
                    331: {
                    332:        return (x<0);
                    333: }
                    334: 
                    335: isle(x)
                    336: {
                    337:        return (x<=0);
                    338: }
                    339: 
                    340: isge(x)
                    341: {
                    342:        return (x>=0);
                    343: }
                    344: 
                    345: isgt(x)
                    346: {
                    347:        return (x>0);
                    348: }
                    349: 
                    350: rdstring(v)
                    351: rvalue *v;
                    352: {
                    353:        register int    c;
                    354:        register char   *s,
                    355:                        *str;
                    356:        unsigned int    len,
                    357:                        d = 0;          /* nesting depth */
                    358: 
                    359:        s = str = malloc(len=16);
                    360:        while ((c=getc(infile)) != EOF) {
                    361:                if (c == '[')
                    362:                        ++d;
                    363:                else if (c == ']' && d-- == 0)
                    364:                        break;
                    365:                if (str != NULL)
                    366:                        *s++ = c;
                    367:                if (s == &str[len]) {
                    368:                        str = realloc(str, len*=2);
                    369:                        s = &str[len/2];
                    370:                }
                    371:        }
                    372:        if (str == NULL) {
                    373:                skiperr(oospmsg);
                    374:        } else if (c == EOF) {
                    375:                skiperr("Missing ']'");
                    376:        } else {
                    377:                *s = '\0';
                    378:                v->mantissa.val = str;
                    379:                v->mantissa.len = len;
                    380:                v->scale = -1;
                    381:                return (0);
                    382:        }
                    383: }
                    384: rdline(v, fp)
                    385: rvalue *v;
                    386: FILE   *fp;
                    387: {
                    388:        register int    c;
                    389:        register char   *s,
                    390:                        *str;
                    391:        unsigned int    len;
                    392: 
                    393:        s = str = malloc(len=16);
                    394:        while ((c=getc(fp))!= EOF && c != '\n') {
                    395:                if (str != NULL)
                    396:                        *s++ = c;
                    397:                if (s == &str[len]) {
                    398:                        str = realloc(str, len*=2);
                    399:                        s = &str[len/2];
                    400:                }
                    401:        }
                    402:        if (str == NULL) {
                    403:                skiperr(oospmsg);
                    404:        } else {
                    405:                *s = '\0';
                    406:                v->mantissa.val = str;
                    407:                v->mantissa.len = len;
                    408:                v->scale = -1;
                    409:                return (0);
                    410:        }
                    411: }
                    412: 
                    413: output(v)
                    414: rvalue *v;
                    415: {
                    416:        if (v->scale < 0)
                    417:                printf("%s\n", v->mantissa.val);
                    418:        else {
                    419:                putnum(v);
                    420:                pnewln();
                    421:        }
                    422: }

unix.superglobalmegacorp.com

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