Annotation of 3BSD/cmd/lisp/eval.c, revision 1.1.1.1

1.1       root        1: #include "global.h"
                      2: /************************************************************************/
                      3: /*                                                                     */
                      4: /*   file: eval.i                                                      */
                      5: /*   contents: evaluator and namestack maintenance routines            */
                      6: /*                                                                     */
                      7: /************************************************************************/
                      8: 
                      9: 
                     10: /* eval *****************************************************************/
                     11: /* returns the value of the pointer passed as the argument.            */
                     12: 
                     13: lispval
                     14: eval(actarg)
                     15: lispval actarg;
                     16: {
                     17: #define argptr handy
                     18:        register lispval a = actarg;
                     19:        register lispval handy;
                     20:        register struct nament *namptr;
                     21:        register struct argent *workp;
                     22:        register struct argent *lbot;
                     23:        register struct argent *np;
                     24:        struct argent *poplbot;
                     25:        struct nament *oldbnp = bnp;
                     26:        lispval Ifcall(), Iarray();
                     27: 
                     28:        /*debugging 
                     29:        printf("Eval:");
                     30:        printr(a,stdout);
                     31:        fflush(stdout);  */
                     32:        switch (TYPE(a))
                     33:        {
                     34:        case ATOM:
                     35:                handy = a->clb;
                     36:                if(handy==CNIL) {
                     37:                        handy = errorh(Vermisc,"Unbound Variable:",nil,TRUE,0,a);
                     38:                }
                     39:                return(handy);
                     40: 
                     41:        case VALUE:
                     42:                return(a->l);
                     43: 
                     44:        case DTPR:
                     45:                (np++)->val = a;        /* push form on namestack */
                     46:                lbot = np;              /* define beginning of argstack */
                     47:                oldbnp = bnp;           /* remember start of bind stack */
                     48:                a = a->car;             /* function name or lambda-expr */
                     49:                for(EVER)
                     50:                        {
                     51:                        switch(TYPE(a))
                     52:                                {
                     53:                        case ATOM:
                     54:                                        /*  get function binding  */
                     55:                                if(a->fnbnd==nil && a->clb!=nil) {
                     56:                                        a=a->clb;
                     57:                                        if(TYPE(a)==ATOM)
                     58:                                                a=a->fnbnd;
                     59:                                } else
                     60:                                        a = a->fnbnd;
                     61:                                break;
                     62:                        case VALUE:
                     63:                                a = a->l;       /*  get value  */
                     64:                                break;
                     65:                                }
                     66: 
                     67:                        vtemp = (CNIL-1);       /* sentinel value for error test */
                     68: 
                     69:                funcal: switch (TYPE(a))
                     70:                                {
                     71:                        case BCD:       /* function */
                     72:                                argptr = actarg->cdr;
                     73: 
                     74:                                /* decide whether lambda, nlambda or
                     75:                                   macro and push args onto argstack
                     76:                                   accordingly.                         */
                     77: 
                     78:                                if(a->discipline==nlambda) {
                     79:                                        (np++)->val = argptr;
                     80:                                        TNP;
                     81:                                }else if(a->discipline==macro) {
                     82:                                        (np++)->val = actarg;
                     83:                                        TNP;
                     84:                                } else for(;argptr!=nil; argptr = argptr->cdr) {
                     85:                                        (np++)->val = eval(argptr->car);
                     86:                                        TNP;
                     87:                                }
                     88:                                /* go for it */
                     89: 
                     90:                                if(TYPE(a->discipline)==INT)
                     91:                                        vtemp = Ifcall(a);
                     92:                                else
                     93:                                        vtemp = (*(lispval (*)())(a->entry))();
                     94:                                break;
                     95: 
                     96:                        case ARRAY:
                     97:                                vtemp = Iarray(a,actarg->cdr);
                     98:                                break;
                     99: 
                    100: 
                    101:                        case DTPR:
                    102:                                        /* push args on argstack according to
                    103:                                           type                         */
                    104: 
                    105:                                argptr = a->car;
                    106:                                if (argptr==lambda) {
                    107:                                        for(argptr = actarg->cdr;
                    108:                                            argptr!=nil; argptr=argptr->cdr) {
                    109:                                                
                    110:                                                (np++)->val = eval(argptr->car);
                    111:                                                TNP;
                    112:                                        }
                    113:                                } else if (argptr==nlambda) {
                    114:                                        (np++)->val = actarg->cdr;
                    115:                                        TNP;
                    116:                                } else if(argptr==macro) {
                    117:                                        (np++)->val = actarg;
                    118:                                        TNP;
                    119:                                } else if(argptr==lexpr) {
                    120:                                        for(argptr = actarg->cdr;
                    121:                                            argptr!=nil; argptr=argptr->cdr) {
                    122:                                                
                    123:                                                (np++)->val = eval(argptr->car);
                    124:                                                TNP;
                    125:                                        }
                    126:                                        handy = newdot();
                    127:                                        handy->car = (lispval)lbot;
                    128:                                        handy->cdr = (lispval)np;
                    129:                                        PUSHDOWN(lexpr_atom,handy);
                    130:                                        lbot = np;
                    131:                                        (np++)->val = inewint(((lispval *)handy->cdr) - (lispval *)handy->car);
                    132: 
                    133:                                } else break;   /* something is wrong - this isn't a proper function */
                    134: 
                    135:                                argptr = (a->cdr)->car;
                    136:                                namptr =  bnp;
                    137:                                workp = lbot;
                    138:                                if(bnp + (np - lbot)> bnplim)
                    139:                                        binderr();
                    140:                                for(;argptr != (lispval)nil;
                    141:                                     workp++,argptr = argptr->cdr)      /* rebind formal names (shallow) */
                    142:                                {
                    143:                                        if(argptr->car==nil)
                    144:                                                continue;
                    145:                                        /*if(((namptr)->atm = argptr->car)==nil)
                    146:                                                error("Attempt to lambda bind nil",FALSE);*/
                    147:                                        namptr->atm = argptr->car;
                    148:                                        if (workp < np) {
                    149:                                                namptr->val = namptr->atm->clb;
                    150:                                                namptr->atm->clb = workp->val;
                    151:                                        } else
                    152:                                                bnp = namptr,
                    153:                                                error("Too few actual parameters",FALSE);
                    154:                                        namptr++;
                    155:                                }
                    156:                                bnp = namptr;
                    157:                                if (workp < np)
                    158:                                        error("Too many actual parameters",FALSE);
                    159: 
                    160:                                /* execute body, implied prog allowed */
                    161: 
                    162:                                for (handy = a->cdr->cdr;
                    163:                                        handy != nil;
                    164:                                        handy = handy->cdr) {
                    165:                                                vtemp = eval(handy->car);
                    166:                                        }
                    167:                                }
                    168:                        if (vtemp != (CNIL-1))
                    169:                                /* if we get here with a believable value, */
                    170:                                /* we must have executed a function. */
                    171:                                {
                    172:                                popnames(oldbnp);
                    173: 
                    174:                                /* in case some clown trashed t */
                    175: 
                    176:                                tatom->clb = (lispval) tatom;
                    177:                                if(a->car==macro) return(eval(vtemp));
                    178:                                        /* It is of the most wonderful 
                    179:                                           coincidence that the offset
                    180:                                           for car is the same as for
                    181:                                           discipline so we get bcd macros
                    182:                                           for free here ! */
                    183:                                else return(vtemp);
                    184:                                }
                    185:                        popnames(oldbnp);
                    186:                        a = (lispval) errorh(Vermisc,"BAD FUNCTION",nil,TRUE,0,actarg);
                    187:                        }
                    188: 
                    189:                }
                    190:        return(a);      /* other data types are considered constants */
                    191:        }
                    192: 
                    193: 
                    194: 
                    195: 
                    196: /* popnames *************************************************************/
                    197: /* removes from the name stack all entries above the first argument.   */
                    198: /* routine should usually be used to clean up the name stack as it     */
                    199: /* knows about the special cases.  np is returned pointing to the      */
                    200: /* same place as the argument passed.                                  */
                    201: lispval
                    202: popnames(llimit)
                    203: register struct nament *llimit;
                    204: {
                    205:        register struct nament *rnp;
                    206: 
                    207:        for(rnp = bnp - 1; rnp >= llimit; rnp--)
                    208:                rnp->atm->clb = rnp->val;
                    209:        bnp = llimit;
                    210: }
                    211: 
                    212: 
                    213: /************************************************************************/
                    214: /*                                                                     */
                    215: /*   file: apply.c                                                     */
                    216: /*     Caveat -- Work in Progress -- not guaranteed! not tested!
                    217: /*                                                                     */
                    218: /* apply  ***************************************************************/
                    219: lispval
                    220: Lapply()
                    221: {
                    222:        register lispval a;
                    223:        register lispval handy;
                    224:        register struct argent *workp;
                    225:        register struct nament *namptr;
                    226:        register struct argent *lbot;
                    227:        register struct argent *np;
                    228:        lispval vtemp;
                    229:        struct nament *oldbnp = bnp;
                    230:        struct argent *oldlbot = lbot; /* Bottom of my frame! */
                    231: 
                    232:        a = lbot->val;
                    233:        argptr = lbot[1].val;
                    234:        if(np-lbot!=2)
                    235:                errorh(Vermisc,"Apply: Wrong number of args.",nil,FALSE,
                    236:                       999,a,argptr);
                    237:        if(TYPE(argptr)!=DTPR && argptr!=nil)
                    238:                argptr = errorh(Vermisc,"Apply: non-list of args",nil,TRUE,
                    239:                                998,argptr);
                    240:        (np++)->val = a;        /* push form on namestack */
                    241:        TNP;
                    242:        lbot = np;              /* bottom of current frame */
                    243:        for(EVER)
                    244:                {
                    245:                if (TYPE(a) == ATOM) a = a->fnbnd;
                    246:                        /* get function defn (unless calling form */
                    247:                        /* is itself a lambda-expr) */
                    248:                vtemp = CNIL;                   /* sentinel value for error test */
                    249:                switch (TYPE(a))
                    250:                        {
                    251:                case BCD:       /* printf("BCD\n");*/
                    252:                                /* push arguments - value of a */
                    253:                        if(a->discipline==nlambda || a->discipline==macro) {
                    254:                                (np++)->val=argptr;
                    255:                                TNP;
                    256:                        } else for (; argptr!=nil; argptr = argptr->cdr) {
                    257:                                (np++)->val=argptr->car;
                    258:                                TNP;
                    259:                        }
                    260: 
                    261:                        vtemp = (*(lispval (*)())(a->entry))(); /* go for it */
                    262:                        break;
                    263: 
                    264:                case ARRAY:
                    265:                        vtemp = Iarray(a,argptr);
                    266:                        break;
                    267: 
                    268: 
                    269:                case DTPR:
                    270:                        if (a->car==nlambda || a->car==macro) {
                    271:                                (np++)->val = argptr;
                    272:                                TNP;
                    273:                        } else if (a->car==lambda)
                    274:                                for (; argptr!=nil; argptr = argptr->cdr) {
                    275:                                        (np++)->val = argptr->car;
                    276:                                        TNP;
                    277:                                }
                    278:                        else if(a->car==lexpr) {
                    279:                                for (; argptr!=nil; argptr = argptr->cdr) {
                    280:                                        
                    281:                                        (np++)->val = argptr->car;
                    282:                                        TNP;
                    283:                                }
                    284:                                handy = newdot();
                    285:                                handy->car = (lispval)lbot;
                    286:                                handy->cdr = (lispval)np;
                    287:                                PUSHDOWN(lexpr_atom,handy);
                    288:                                lbot = np;
                    289:                                (np++)->val = inewint(((lispval *)handy->cdr) - (lispval *)handy->car);
                    290: 
                    291:                        } else break;   /* something is wrong - this isn't a proper function */
                    292:                        rebind(a->cdr->car,lbot);
                    293:                        np = lbot;
                    294:                        for (handy = a->cdr->cdr;
                    295:                                handy != nil;
                    296:                                handy = handy->cdr) {
                    297:                                        vtemp = eval(handy->car);       /* go for it */
                    298:                                }
                    299:                        }
                    300:                if (vtemp != CNIL)
                    301:                        /* if we get here with a believable value, */
                    302:                        /* we must have executed a function. */
                    303:                        {
                    304:                        popnames(oldbnp);
                    305: 
                    306:                        /* in case some clown trashed t */
                    307: 
                    308:                        tatom->clb = (lispval) tatom;
                    309:                        return(vtemp);
                    310:                        }
                    311:                popnames(oldbnp);
                    312:                printr(oldlbot->val,stdout);
                    313:                a = (lispval) error("BAD FUNCTION",TRUE);
                    314:        }
                    315:        /*NOT REACHED*/
                    316: }
                    317: 
                    318: 
                    319: /*
                    320:  * Rebind -- rebind formal names
                    321:  */
                    322: rebind(argptr,workp)
                    323: register lispval argptr;               /* argptr points to list of atoms */
                    324: register struct argent * workp;                /* workp points to position on stack
                    325:                                           where evaluated args begin */
                    326: {
                    327:        register lispval vtemp;
                    328:        register struct nament *namptr = bnp;
                    329:        register struct argent *lbot;
                    330:        register struct argent *np;
                    331: 
                    332:        for(;argptr != (lispval)nil;
                    333:             workp++,argptr = argptr->cdr)  /* rebind formal names (shallow) */
                    334:        {
                    335:                if(argptr->car==nil)
                    336:                        continue;
                    337:                namptr->atm = argptr->car;
                    338:                if (workp < np) {
                    339:                        namptr->val = namptr->atm->clb;
                    340:                        namptr->atm->clb = workp->val;
                    341:                } else
                    342:                        bnp = namptr,
                    343:                        error("Too few actual parameters",FALSE);
                    344:                namptr++;
                    345:                if(namptr > bnplim)
                    346:                        binderr();
                    347:        }
                    348:        bnp = namptr;
                    349:        if (workp < np)
                    350:                error("Too many actual parameters",FALSE);
                    351: }
                    352: 
                    353: lispval
                    354: Lfuncal()
                    355: {
                    356:        register lispval a;
                    357:        register lispval handy; 
                    358:        register struct argent *oldlbot;
                    359:        register struct nament **namptr;
                    360:        register struct argent *lbot;
                    361:        register struct argent *np;
                    362: 
                    363:        lispval Ifcall(),Llist(),Iarray();
                    364:        lispval vtemp;
                    365:        struct nament *oldbnp = bnp;
                    366:        int typ;
                    367:        extern lispval end[];
                    368: 
                    369:        /*debugging stufff 
                    370:        printf("In funcal: ");
                    371:        printr(lbot->val,stdout);
                    372:        fflush(stdout); 
                    373:        printf("\n"); */
                    374: 
                    375:        oldlbot = lbot;         /* bottom of my namestack frame */
                    376:        a = lbot->val;          /* function I am evaling.       */
                    377:        lbot++;
                    378: 
                    379:        for(EVER)
                    380:        {
                    381:                typ = TYPE(a);
                    382:                if (typ == ATOM) a = a->fnbnd, typ = TYPE(a);
                    383: 
                    384:                        /* get function defn (unless calling form */
                    385:                        /* is itself a lambda-expr) */
                    386:                vtemp = CNIL;                   /* sentinel value for error test */
                    387:                switch (typ) {
                    388:                case ARRAY:
                    389:                        vtemp = Iarray(a,Llist());
                    390:                        break;
                    391:                case BCD:
                    392:                        if(a->discipline==nlambda)
                    393:                            {   if(np==lbot) protect(nil);  /* default is nil */
                    394:                                while(np-lbot!=1 || (lbot->val != nil &&
                    395:                                                  TYPE(lbot->val)!=DTPR)) {
                    396:                                        lbot->val = error("Bad funcall arg(s) to fexpr.",TRUE);
                    397:                                        np = lbot+1;
                    398:                                        }
                    399:                            }
                    400:                        /* go for it */
                    401: 
                    402:                        if(TYPE(a->discipline)==INT)
                    403:                                vtemp = Ifcall(a);
                    404:                        else
                    405:                                vtemp = (*(lispval (*)())(a->entry))();
                    406:                        if(a->discipline==macro)
                    407:                                vtemp = eval(vtemp);
                    408:                        break;
                    409: 
                    410: 
                    411:                case DTPR:
                    412:                        if (a->car == lambda) {
                    413:                                ;/* VOID */
                    414:                        } else if (a->car == nlambda || a->car==macro) {
                    415:                                if( np==lbot ) protect(nil);    /* default */
                    416:                                while(np-lbot!=1 || (lbot->val != nil &&
                    417:                                                  TYPE(lbot->val)!=DTPR)) {
                    418:                                        lbot->val = error("Bad funcall arg(s) to fexpr.",TRUE);
                    419:                                        np = lbot+1;
                    420:                                        }
                    421:                        } else if (a->car == lexpr) {
                    422:                                handy = newdot();
                    423:                                handy->car = (lispval) lbot;
                    424:                                handy->cdr = (lispval) np;
                    425:                                PUSHDOWN(lexpr_atom,handy);
                    426:                                lbot = np;
                    427:                                (np++)->val = inewint(((lispval *)handy->cdr) - (lispval *)handy->car);
                    428:                        } else break;           /* something is wrong - this isn't a proper function */
                    429:                        rebind(a->cdr->car,lbot);
                    430:                        np = lbot;
                    431:                        for (handy = a->cdr->cdr;
                    432:                                handy != nil;
                    433:                                handy = handy->cdr) {
                    434:                                        vtemp = eval(handy->car);       /* go for it */
                    435:                                }
                    436:                        if(a->car==macro)
                    437:                                vtemp = eval(vtemp);
                    438:                }
                    439:                if (vtemp != CNIL)
                    440:                        /* if we get here with a believable value, */
                    441:                        /* we must have executed a function. */
                    442:                        {
                    443:                        popnames(oldbnp);
                    444: 
                    445:                        /* in case some clown trashed t */
                    446: 
                    447:                        tatom->clb = (lispval) tatom;
                    448:                        /*debugging
                    449:                        if(a>(lispval) end){printf(" leaving:");
                    450:                        printr(a,stdout);
                    451:                        fflush(stdout);} */
                    452:                        return(vtemp);
                    453:                        }
                    454:                popnames(oldbnp);
                    455:                printr(oldlbot->val,stdout);
                    456:                a = (lispval) error("BAD FUNCTION",TRUE);
                    457: 
                    458:        }
                    459:        /*NOT REACHED*/
                    460: }
                    461: 
                    462: /* protect **************************************************************/
                    463: /* pushes the first argument onto namestack, thereby protecting from gc */
                    464: lispval
                    465: protect(a)
                    466: lispval a;
                    467: {
                    468:        /* (np++)->val = a;
                    469:           if (np >=  nplim)
                    470:                namerr();
                    471:         */
                    472:        asm("   movl    4(ap),(r6)+");
                    473:        asm("   cmpl    r6,_nplim");
                    474:        asm("   jlss    out1");
                    475:        asm("   calls   $0,_namerr");
                    476:        asm("out1:      ret");
                    477:        }
                    478: 
                    479: 
                    480: /* unprot ****************************************************************/
                    481: /* returns the top thing on the name stack.  Underflow had better not  */
                    482: /* occur.                                                              */
                    483: lispval
                    484: unprot()
                    485:        {
                    486:        asm("   movl    -(r6),r0");
                    487:        }
                    488: 
                    489: lispval
                    490: linterp()
                    491:        {
                    492:        error("BYTE INTERPRETER CALLED ERRONEOUSLY",FALSE);
                    493:        }
                    494: 
                    495: /* Undeff - called from qfuncl when it detects a call to a undefined
                    496:        function from compiled code, we print out a message and
                    497:        dont allow continuation
                    498: */
                    499: lispval
                    500: Undeff(atmn)
                    501: lispval atmn;
                    502: {
                    503:        printf("\n%s - ",atmn->pname);
                    504:        error("Undefined function called from compiled code",FALSE);
                    505: }
                    506: bindfix(firstarg)
                    507: lispval firstarg;
                    508: {
                    509:        register lispval *argp = &firstarg;
                    510:        register struct nament *mybnp = bnp;
                    511:        while(*argp != nil) {
                    512:                mybnp->atm = *argp++;
                    513:                mybnp->val = mybnp->atm->clb;
                    514:                mybnp->atm->clb = *argp++;
                    515:                bnp = mybnp++;
                    516:        }
                    517: }

unix.superglobalmegacorp.com

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