Annotation of researchv8dc/cmd/hoc/code.c, revision 1.1.1.1

1.1       root        1: #include "hoc.h"
                      2: #include "y.tab.h"
                      3: #include <stdio.h>
                      4: 
                      5: #define        NSTACK  256
                      6: 
                      7: static Datum stack[NSTACK];    /* the stack */
                      8: static Datum *stackp;          /* next free spot on stack */
                      9: 
                     10: #define        NPROG   2000
                     11: Inst   prog[NPROG];    /* the machine */
                     12: Inst   *progp;         /* next free spot for code generation */
                     13: Inst   *pc;            /* program counter during execution */
                     14: Inst   *progbase = prog; /* start of current subprogram */
                     15: int    returning;      /* 1 if return stmt seen */
                     16: 
                     17: typedef struct Frame { /* proc/func call stack frame */
                     18:        Symbol  *sp;    /* symbol table entry */
                     19:        Inst    *retpc; /* where to resume after return */
                     20:        Datum   *argn;  /* n-th argument on stack */
                     21:        int     nargs;  /* number of arguments */
                     22: } Frame;
                     23: #define        NFRAME  100
                     24: Frame  frame[NFRAME];
                     25: Frame  *fp;            /* frame pointer */
                     26: 
                     27: initcode() {
                     28:        progp = progbase;
                     29:        stackp = stack;
                     30:        fp = frame;
                     31:        returning = 0;
                     32: }
                     33: 
                     34: push(d)
                     35:        Datum d;
                     36: {
                     37:        if (stackp >= &stack[NSTACK])
                     38:                execerror("stack too deep", (char *)0);
                     39:        *stackp++ = d;
                     40: }
                     41: 
                     42: Datum pop()
                     43: {
                     44:        if (stackp == stack)
                     45:                execerror("stack underflow", (char *)0);
                     46:        return *--stackp;
                     47: }
                     48: 
                     49: constpush()
                     50: {
                     51:        Datum d;
                     52:        d.val = ((Symbol *)*pc++)->u.val;
                     53:        push(d);
                     54: }
                     55: 
                     56: varpush()
                     57: {
                     58:        Datum d;
                     59:        d.sym = (Symbol *)(*pc++);
                     60:        push(d);
                     61: }
                     62: 
                     63: whilecode()
                     64: {
                     65:        Datum d;
                     66:        Inst *savepc = pc;
                     67: 
                     68:        execute(savepc+2);      /* condition */
                     69:        d = pop();
                     70:        while (d.val) {
                     71:                execute(*((Inst **)(savepc)));  /* body */
                     72:                if (returning)
                     73:                        break;
                     74:                execute(savepc+2);      /* condition */
                     75:                d = pop();
                     76:        }
                     77:        if (!returning)
                     78:                pc = *((Inst **)(savepc+1)); /* next stmt */
                     79: }
                     80: 
                     81: forcode()
                     82: {
                     83:        Datum d;
                     84:        Inst *savepc = pc;
                     85: 
                     86:        execute(savepc+4);              /* precharge */
                     87:        (void) pop();
                     88:        execute(*((Inst **)(savepc)));  /* condition */
                     89:        d = pop();
                     90:        while (d.val) {
                     91:                execute(*((Inst **)(savepc+2)));        /* body */
                     92:                if (returning)
                     93:                        break;
                     94:                execute(*((Inst **)(savepc+1)));        /* post loop */
                     95:                (void) pop();
                     96:                execute(*((Inst **)(savepc)));  /* condition */
                     97:                d = pop();
                     98:        }
                     99:        if (!returning)
                    100:                pc = *((Inst **)(savepc+3)); /* next stmt */
                    101: }
                    102: ifcode() 
                    103: {
                    104:        Datum d;
                    105:        Inst *savepc = pc;      /* then part */
                    106: 
                    107:        execute(savepc+3);      /* condition */
                    108:        d = pop();
                    109:        if (d.val)
                    110:                execute(*((Inst **)(savepc)));  
                    111:        else if (*((Inst **)(savepc+1))) /* else part? */
                    112:                execute(*((Inst **)(savepc+1)));
                    113:        if (!returning)
                    114:                pc = *((Inst **)(savepc+2)); /* next stmt */
                    115: }
                    116: 
                    117: define(sp)     /* put func/proc in symbol table */
                    118:        Symbol *sp;
                    119: {
                    120:        sp->u.defn = (Inst)progbase;    /* start of code */
                    121:        progbase = progp;       /* next code starts here */
                    122: }
                    123: 
                    124: call()                 /* call a function */
                    125: {
                    126:        Symbol *sp = (Symbol *)pc[0]; /* symbol table entry */
                    127:                                      /* for function */
                    128:        if (fp++ >= &frame[NFRAME-1])
                    129:                execerror(sp->name, "call nested too deeply");
                    130:        fp->sp = sp;
                    131:        fp->nargs = (int)pc[1];
                    132:        fp->retpc = pc + 2;
                    133:        fp->argn = stackp - 1;  /* last argument */
                    134:        execute(sp->u.defn);
                    135:        returning = 0;
                    136: }
                    137: 
                    138: ret()          /* common return from func or proc */
                    139: {
                    140:        int i;
                    141:        for (i = 0; i < fp->nargs; i++)
                    142:                pop();  /* pop arguments */
                    143:        pc = (Inst *)fp->retpc;
                    144:        --fp;
                    145:        returning = 1;
                    146: }
                    147: 
                    148: funcret()      /* return from a function */
                    149: {
                    150:        Datum d;
                    151:        if (fp->sp->type == PROCEDURE)
                    152:                execerror(fp->sp->name, "(proc) returns value");
                    153:        d = pop();      /* preserve function return value */
                    154:        ret();
                    155:        push(d);
                    156: }
                    157: 
                    158: procret()      /* return from a procedure */
                    159: {
                    160:        if (fp->sp->type == FUNCTION)
                    161:                execerror(fp->sp->name,
                    162:                        "(func) returns no value");
                    163:        ret();
                    164: }
                    165: 
                    166: double *getarg()       /* return pointer to argument */
                    167: {
                    168:        int nargs = (int) *pc++;
                    169:        if (nargs > fp->nargs)
                    170:            execerror(fp->sp->name, "not enough arguments");
                    171:        return &fp->argn[nargs - fp->nargs].val;
                    172: }
                    173: 
                    174: arg()  /* push argument onto stack */
                    175: {
                    176:        Datum d;
                    177:        d.val = *getarg();
                    178:        push(d);
                    179: }
                    180: 
                    181: argassign()    /* store top of stack in argument */
                    182: {
                    183:        Datum d;
                    184:        d = pop();
                    185:        push(d);        /* leave value on stack */
                    186:        *getarg() = d.val;
                    187: }
                    188: 
                    189: argaddeq()     /* store top of stack in argument */
                    190: {
                    191:        Datum d;
                    192:        d = pop();
                    193:        d.val = *getarg() += d.val;
                    194:        push(d);        /* leave value on stack */
                    195: }
                    196: 
                    197: argsubeq()     /* store top of stack in argument */
                    198: {
                    199:        Datum d;
                    200:        d = pop();
                    201:        d.val = *getarg() -= d.val;
                    202:        push(d);        /* leave value on stack */
                    203: }
                    204: 
                    205: argmuleq()     /* store top of stack in argument */
                    206: {
                    207:        Datum d;
                    208:        d = pop();
                    209:        d.val = *getarg() *= d.val;
                    210:        push(d);        /* leave value on stack */
                    211: }
                    212: 
                    213: argdiveq()     /* store top of stack in argument */
                    214: {
                    215:        Datum d;
                    216:        d = pop();
                    217:        d.val = *getarg() /= d.val;
                    218:        push(d);        /* leave value on stack */
                    219: }
                    220: 
                    221: argmodeq()     /* store top of stack in argument */
                    222: {
                    223:        Datum d;
                    224:        long x;
                    225:        d = pop();
                    226:        /* d.val = *getarg() %= d.val; */
                    227:        x = *getarg();
                    228:        x %= (long) d.val;
                    229:        d.val = *getarg() = x;
                    230:        push(d);        /* leave value on stack */
                    231: }
                    232: 
                    233: bltin() 
                    234: {
                    235: 
                    236:        Datum d;
                    237:        d = pop();
                    238:        d.val = (*(double (*)())*pc++)(d.val);
                    239:        push(d);
                    240: }
                    241: 
                    242: add()
                    243: {
                    244:        Datum d1, d2;
                    245:        d2 = pop();
                    246:        d1 = pop();
                    247:        d1.val += d2.val;
                    248:        push(d1);
                    249: }
                    250: 
                    251: sub()
                    252: {
                    253:        Datum d1, d2;
                    254:        d2 = pop();
                    255:        d1 = pop();
                    256:        d1.val -= d2.val;
                    257:        push(d1);
                    258: }
                    259: 
                    260: mul()
                    261: {
                    262:        Datum d1, d2;
                    263:        d2 = pop();
                    264:        d1 = pop();
                    265:        d1.val *= d2.val;
                    266:        push(d1);
                    267: }
                    268: 
                    269: div()
                    270: {
                    271:        Datum d1, d2;
                    272:        d2 = pop();
                    273:        if (d2.val == 0.0)
                    274:                execerror("division by zero", (char *)0);
                    275:        d1 = pop();
                    276:        d1.val /= d2.val;
                    277:        push(d1);
                    278: }
                    279: 
                    280: mod()
                    281: {
                    282:        Datum d1, d2;
                    283:        long x;
                    284:        d2 = pop();
                    285:        if (d2.val == 0.0)
                    286:                execerror("division by zero", (char *)0);
                    287:        d1 = pop();
                    288:        /* d1.val %= d2.val; */
                    289:        x = d1.val;
                    290:        x %= (long) d2.val;
                    291:        d1.val = d2.val = x;
                    292:        push(d1);
                    293: }
                    294: 
                    295: negate()
                    296: {
                    297:        Datum d;
                    298:        d = pop();
                    299:        d.val = -d.val;
                    300:        push(d);
                    301: }
                    302: 
                    303: verify(s)
                    304:        Symbol *s;
                    305: {
                    306:        if (s->type != VAR && s->type != UNDEF)
                    307:                execerror("attempt to evaluate non-variable", s->name);
                    308:        if (s->type == UNDEF)
                    309:                execerror("undefined variable", s->name);
                    310: }
                    311: 
                    312: eval()         /* evaluate variable on stack */
                    313: {
                    314:        Datum d;
                    315:        d = pop();
                    316:        verify(d.sym);
                    317:        d.val = d.sym->u.val;
                    318:        push(d);
                    319: }
                    320: 
                    321: preinc()
                    322: {
                    323:        Datum d;
                    324:        d.sym = (Symbol *)(*pc++);
                    325:        verify(d.sym);
                    326:        d.val = d.sym->u.val += 1.0;
                    327:        push(d);
                    328: }
                    329: 
                    330: predec()
                    331: {
                    332:        Datum d;
                    333:        d.sym = (Symbol *)(*pc++);
                    334:        verify(d.sym);
                    335:        d.val = d.sym->u.val -= 1.0;
                    336:        push(d);
                    337: }
                    338: 
                    339: postinc()
                    340: {
                    341:        Datum d;
                    342:        double v;
                    343:        d.sym = (Symbol *)(*pc++);
                    344:        verify(d.sym);
                    345:        v = d.sym->u.val;
                    346:        d.sym->u.val += 1.0;
                    347:        d.val = v;
                    348:        push(d);
                    349: }
                    350: 
                    351: postdec()
                    352: {
                    353:        Datum d;
                    354:        double v;
                    355:        d.sym = (Symbol *)(*pc++);
                    356:        verify(d.sym);
                    357:        v = d.sym->u.val;
                    358:        d.sym->u.val -= 1.0;
                    359:        d.val = v;
                    360:        push(d);
                    361: }
                    362: 
                    363: gt()
                    364: {
                    365:        Datum d1, d2;
                    366:        d2 = pop();
                    367:        d1 = pop();
                    368:        d1.val = (double)(d1.val > d2.val);
                    369:        push(d1);
                    370: }
                    371: 
                    372: lt()
                    373: {
                    374:        Datum d1, d2;
                    375:        d2 = pop();
                    376:        d1 = pop();
                    377:        d1.val = (double)(d1.val < d2.val);
                    378:        push(d1);
                    379: }
                    380: 
                    381: ge()
                    382: {
                    383:        Datum d1, d2;
                    384:        d2 = pop();
                    385:        d1 = pop();
                    386:        d1.val = (double)(d1.val >= d2.val);
                    387:        push(d1);
                    388: }
                    389: 
                    390: le()
                    391: {
                    392:        Datum d1, d2;
                    393:        d2 = pop();
                    394:        d1 = pop();
                    395:        d1.val = (double)(d1.val <= d2.val);
                    396:        push(d1);
                    397: }
                    398: 
                    399: eq()
                    400: {
                    401:        Datum d1, d2;
                    402:        d2 = pop();
                    403:        d1 = pop();
                    404:        d1.val = (double)(d1.val == d2.val);
                    405:        push(d1);
                    406: }
                    407: 
                    408: ne()
                    409: {
                    410:        Datum d1, d2;
                    411:        d2 = pop();
                    412:        d1 = pop();
                    413:        d1.val = (double)(d1.val != d2.val);
                    414:        push(d1);
                    415: }
                    416: 
                    417: and()
                    418: {
                    419:        Datum d1, d2;
                    420:        d2 = pop();
                    421:        d1 = pop();
                    422:        d1.val = (double)(d1.val != 0.0 && d2.val != 0.0);
                    423:        push(d1);
                    424: }
                    425: 
                    426: or()
                    427: {
                    428:        Datum d1, d2;
                    429:        d2 = pop();
                    430:        d1 = pop();
                    431:        d1.val = (double)(d1.val != 0.0 || d2.val != 0.0);
                    432:        push(d1);
                    433: }
                    434: 
                    435: not()
                    436: {
                    437:        Datum d;
                    438:        d = pop();
                    439:        d.val = (double)(d.val == 0.0);
                    440:        push(d);
                    441: }
                    442: 
                    443: power()
                    444: {
                    445:        Datum d1, d2;
                    446:        extern double Pow();
                    447:        d2 = pop();
                    448:        d1 = pop();
                    449:        d1.val = Pow(d1.val, d2.val);
                    450:        push(d1);
                    451: }
                    452: 
                    453: assign()
                    454: {
                    455:        Datum d1, d2;
                    456:        d1 = pop();
                    457:        d2 = pop();
                    458:        if (d1.sym->type != VAR && d1.sym->type != UNDEF)
                    459:                execerror("assignment to non-variable",
                    460:                        d1.sym->name);
                    461:        d1.sym->u.val = d2.val;
                    462:        d1.sym->type = VAR;
                    463:        push(d2);
                    464: }
                    465: 
                    466: addeq()
                    467: {
                    468:        Datum d1, d2;
                    469:        d1 = pop();
                    470:        d2 = pop();
                    471:        if (d1.sym->type != VAR && d1.sym->type != UNDEF)
                    472:                execerror("assignment to non-variable",
                    473:                        d1.sym->name);
                    474:        d2.val = d1.sym->u.val += d2.val;
                    475:        d1.sym->type = VAR;
                    476:        push(d2);
                    477: }
                    478: 
                    479: subeq()
                    480: {
                    481:        Datum d1, d2;
                    482:        d1 = pop();
                    483:        d2 = pop();
                    484:        if (d1.sym->type != VAR && d1.sym->type != UNDEF)
                    485:                execerror("assignment to non-variable",
                    486:                        d1.sym->name);
                    487:        d2.val = d1.sym->u.val -= d2.val;
                    488:        d1.sym->type = VAR;
                    489:        push(d2);
                    490: }
                    491: 
                    492: muleq()
                    493: {
                    494:        Datum d1, d2;
                    495:        d1 = pop();
                    496:        d2 = pop();
                    497:        if (d1.sym->type != VAR && d1.sym->type != UNDEF)
                    498:                execerror("assignment to non-variable",
                    499:                        d1.sym->name);
                    500:        d2.val = d1.sym->u.val *= d2.val;
                    501:        d1.sym->type = VAR;
                    502:        push(d2);
                    503: }
                    504: 
                    505: diveq()
                    506: {
                    507:        Datum d1, d2;
                    508:        d1 = pop();
                    509:        d2 = pop();
                    510:        if (d1.sym->type != VAR && d1.sym->type != UNDEF)
                    511:                execerror("assignment to non-variable",
                    512:                        d1.sym->name);
                    513:        d2.val = d1.sym->u.val /= d2.val;
                    514:        d1.sym->type = VAR;
                    515:        push(d2);
                    516: }
                    517: 
                    518: modeq()
                    519: {
                    520:        Datum d1, d2;
                    521:        long x;
                    522:        d1 = pop();
                    523:        d2 = pop();
                    524:        if (d1.sym->type != VAR && d1.sym->type != UNDEF)
                    525:                execerror("assignment to non-variable",
                    526:                        d1.sym->name);
                    527:        /* d2.val = d1.sym->u.val %= d2.val; */
                    528:        x = d1.sym->u.val;
                    529:        x %= (long) d2.val;
                    530:        d2.val = d1.sym->u.val = x;
                    531:        d1.sym->type = VAR;
                    532:        push(d2);
                    533: }
                    534: 
                    535: print()        /* pop top value from stack, print it */
                    536: {
                    537:        Datum d;
                    538:        static Symbol *s;       /* last value computed */
                    539:        if (s == NULL)
                    540:                s = install("_", VAR, 0.0);
                    541:        d = pop();
                    542:        printf("\t%.8g\n", d.val);
                    543:        s->u.val = d.val;
                    544: }
                    545: 
                    546: prexpr()       /* print numeric value */
                    547: {
                    548:        Datum d;
                    549:        d = pop();
                    550:        printf("%.8g ", d.val);
                    551: }
                    552: 
                    553: prstr()                /* print string value */ 
                    554: {
                    555:        printf("%s", (char *) *pc++);
                    556: }
                    557: 
                    558: varread()      /* read into variable */
                    559: {
                    560:        Datum d;
                    561:        extern FILE *fin;
                    562:        Symbol *var = (Symbol *) *pc++;
                    563:   Again:
                    564:        switch (fscanf(fin, "%lf", &var->u.val)) {
                    565:        case EOF:
                    566:                if (moreinput())
                    567:                        goto Again;
                    568:                d.val = var->u.val = 0.0;
                    569:                break;
                    570:        case 0:
                    571:                execerror("non-number read into", var->name);
                    572:                break;
                    573:        default:
                    574:                d.val = 1.0;
                    575:                break;
                    576:        }
                    577:        var->type = VAR;
                    578:        push(d);
                    579: }
                    580: 
                    581: Inst *code(f)  /* install one instruction or operand */
                    582:        Inst f;
                    583: {
                    584:        Inst *oprogp = progp;
                    585:        if (progp >= &prog[NPROG])
                    586:                execerror("program too big", (char *)0);
                    587:        *progp++ = f;
                    588:        return oprogp;
                    589: }
                    590: 
                    591: execute(p)
                    592:        Inst *p;
                    593: {
                    594:        for (pc = p; *pc != STOP && !returning; )
                    595:                (*(*pc++))();
                    596: }

unix.superglobalmegacorp.com

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