Annotation of coherent/d/bin/bc/grmact.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include <assert.h>
        !             3: #include "bc.h"
        !             4: 
        !             5: 
        !             6: /*
        !             7:  *     Gerror is used by the various grammar actions when a
        !             8:  *     semantic error is discoverd.  It simply prints out a
        !             9:  *     message and sets allok to FALSE.
        !            10:  *     It is also called by yyerror to report syntax errors.
        !            11:  *     It is also called by lexerror to report lexical errors.
        !            12:  *     Allok, errors, and any partially defined function or statement
        !            13:  *     will be cleared at the end of the line, except for the
        !            14:  *     too much code error which clears at the end of the function
        !            15:  *     or statement which has grown too large.
        !            16:  */
        !            17: 
        !            18: gerror(str)
        !            19: char   *str;
        !            20: {
        !            21:        if (allok == TRUE) {
        !            22:                if (infnam != NULL)
        !            23:                        fprintf(stderr, "%s: ", infnam);
        !            24:                if (inline != 0)
        !            25:                        fprintf(stderr, "%d: ", inline);
        !            26:                fprintf(stderr, "%r\n", &str);
        !            27:                allok = FALSE;
        !            28:        }
        !            29: }
        !            30: 
        !            31: /*
        !            32:  * Chktype verifies that the type of `var' will work in sload, aeload,
        !            33:  * or arload.  Otherwise it emits an error and returns zero so the
        !            34:  * grammar action can abort the parse.
        !            35:  */
        !            36: chktype(var, type)
        !            37: register dicent *var;
        !            38: register int type;
        !            39: {
        !            40:        if (var->localt == type)
        !            41:                return 1;
        !            42:        else if (var->localt == UNDEFINED)
        !            43:                if (var->globalt == type || var->globalt == UNDEFINED)
        !            44:                        return 1;
        !            45:                else
        !            46:                        gerror("'%s' is wrong global type", var->word);
        !            47:        else
        !            48:                gerror("'%s' is wrong local type", var->word);
        !            49:        return 0;
        !            50: }
        !            51: 
        !            52: /*
        !            53:  *     Sload emits the code to load the scalar with dictionary entry
        !            54:  *     var.
        !            55:  */
        !            56: 
        !            57: sload(var)
        !            58: register dicent        *var;
        !            59: {
        !            60:        switch (var->localt) {
        !            61:        case SCALAR:
        !            62:                emitop(PLOSC);
        !            63:                emitcnt(var->localv);
        !            64:                break;
        !            65:        case UNDEFINED:
        !            66:                switch (var->globalt) {
        !            67:                case UNDEFINED:
        !            68:                        var->globalt = SCALAR;
        !            69:                        newscalar(&var->globalv.rvalue);
        !            70:                        /* fall thru */
        !            71:                case SCALAR:
        !            72:                        emitop(PGLSC);
        !            73:                        emitnum(&var->globalv.rvalue);
        !            74:                        break;
        !            75:                }
        !            76:        }
        !            77: }
        !            78: 
        !            79: 
        !            80: /*
        !            81:  *     Aeload emits the code to load the array element with dictionary
        !            82:  *     entry var.
        !            83:  */
        !            84: 
        !            85: aeload(var)
        !            86: register dicent        *var;
        !            87: {
        !            88:        switch (var->localt) {
        !            89:        case ARRAY:
        !            90:                emitop(PLOAE);
        !            91:                emitcnt(var->localv);
        !            92:                break;
        !            93:        case UNDEFINED:
        !            94:                switch (var->globalt) {
        !            95:                case UNDEFINED:
        !            96:                        var->globalt = ARRAY;
        !            97:                        newarray(&var->globalv.arvalue);
        !            98:                        /* fall thru */
        !            99:                case ARRAY:
        !           100:                        emitop(PGLAE);
        !           101:                        emitarry(&var->globalv.arvalue);
        !           102:                        break;
        !           103:                }
        !           104:        }
        !           105: }
        !           106: 
        !           107: 
        !           108: /*
        !           109:  *     Arload emits the code to load the whole array with dictionary
        !           110:  *     entry var.
        !           111:  */
        !           112: 
        !           113: arload(var)
        !           114: register dicent        *var;
        !           115: {
        !           116:        switch (var->localt) {
        !           117:        case ARRAY:
        !           118:                emitop(PLOAR);
        !           119:                emitcnt(var->localv);
        !           120:                break;
        !           121:        case UNDEFINED:
        !           122:                switch (var->globalt) {
        !           123:                case UNDEFINED:
        !           124:                        var->globalt = ARRAY;
        !           125:                        newarray(&var->globalv.arvalue);
        !           126:                        /* fall thru */
        !           127:                case ARRAY:
        !           128:                        emitop(PGLAR);
        !           129:                        emitarry(&var->globalv.arvalue);
        !           130:                        break;
        !           131:                }
        !           132:        }
        !           133: }
        !           134: 
        !           135: 
        !           136: /*
        !           137:  *     If there is room for another code item, incloc advances loc
        !           138:  *     and returns the old loc.  If not then incloc calls gerror.
        !           139:  *     Note that both the value returned by incloc and loc itself
        !           140:  *     always point to a location in cstream.
        !           141:  */
        !           142: 
        !           143: code   *
        !           144: incloc()
        !           145: {
        !           146:        register code   *res;
        !           147: 
        !           148:        res = loc++;
        !           149:        if (res >= &cstream[MAXCODE - 1]) {
        !           150:                loc = res;
        !           151:                gerror("Too much code");
        !           152:        }
        !           153:        return (res);
        !           154: }
        !           155: 
        !           156: 
        !           157: /*
        !           158:  *     Negate returns the opcode which branches on the opposite
        !           159:  *     condition of when `op' branches.
        !           160:  */
        !           161: 
        !           162: opcode
        !           163: negate(op)
        !           164: opcode op;
        !           165: {
        !           166:        switch (op) {
        !           167:        case BRALW:
        !           168:                return (BRNEV);
        !           169:        case BRNEV:
        !           170:                return (BRALW);
        !           171:        case BRLT:
        !           172:                return (BRGE);
        !           173:        case BRLE:
        !           174:                return (BRGT);
        !           175:        case BREQ:
        !           176:                return (BRNE);
        !           177:        case BRGE:
        !           178:                return (BRLT);
        !           179:        case BRGT:
        !           180:                return (BRLE);
        !           181:        case BRNE:
        !           182:                return (BREQ);
        !           183:        }
        !           184:        assert(FALSE);
        !           185: }
        !           186: 
        !           187: 
        !           188: /*
        !           189:  *     Locaddr sets the local addresses (ie frame pointer offsets) for
        !           190:  *     all local variables and parameters.  `vec' is an array of `len'
        !           191:  *     pointers to dictionary entries and `base' is the frame offset
        !           192:  *     of the first entry.
        !           193:  *     Note that locaddr assumes that it is never called with len zero.
        !           194:  */
        !           195: 
        !           196: locaddr(vec, len, base)
        !           197: register dicent        *vec[];
        !           198: register int   len,
        !           199:                base;
        !           200: {
        !           201:        do {
        !           202:                (*vec++)->localv = base++;
        !           203:        } while (--len > 0);
        !           204: }
        !           205: 
        !           206: 
        !           207: /*
        !           208:  *     Chkfunc checks to make sure that the identifier with dictionary
        !           209:  *     entry pointed to by `dicp' can be used as a function.  If it
        !           210:  *     is not already a function, then the body and types fields of the
        !           211:  *     func value are set to NULL.
        !           212:  */
        !           213: 
        !           214: chkfunc(dicp)
        !           215: register dicent        *dicp;
        !           216: {
        !           217:        if (dicp->globalt == FUNCTION)
        !           218:                return 1;
        !           219:        if (dicp->globalt == UNDEFINED) {
        !           220:                dicp->globalt = FUNCTION;
        !           221:                dicp->globalv.fvalue.fcsize = 0;
        !           222:                dicp->globalv.fvalue.body = dicp->globalv.fvalue.types = NULL;
        !           223:                return 1;
        !           224:        }
        !           225:        gerror("'%s' is not a function", dicp->word);
        !           226:        return 0;
        !           227: }
        !           228: 
        !           229: /*
        !           230:  *     Install installs the definition of the function `fnc'.
        !           231:  *     `pvec' and `lpvec' (`avec' and `lavec') are the vector
        !           232:  *     of formal parameters (respectively automatic variables)
        !           233:  *     and its length.
        !           234:  */
        !           235: 
        !           236: install(fnc, pvec, lpvec, avec, lavec)
        !           237: register func  *fnc;
        !           238: dicent **pvec,
        !           239:        **avec;
        !           240: int    lpvec,
        !           241:        lavec;
        !           242: {
        !           243:        int     csize;
        !           244: 
        !           245:        litfree(fnc->body, fnc->body+fnc->fcsize);
        !           246:        mpfree(fnc->body);
        !           247:        mpfree(fnc->types);
        !           248:        fnc->nparams = lpvec;
        !           249:        fnc->nautos = lavec;
        !           250:        if (lpvec + lavec == 0)
        !           251:                fnc->types = NULL;
        !           252:        else {
        !           253:                fnc->types = (type *)mpalc((lpvec + lavec) * sizeof (type));
        !           254:                copylty(pvec, fnc->types, lpvec);
        !           255:                copylty(avec, &fnc->types[lpvec], lavec);
        !           256:        }
        !           257:        fnc->fcsize = loc - cstream;
        !           258:        csize = fnc->fcsize * sizeof (code);
        !           259:        fnc->body = (code *)mpalc(csize);
        !           260:        copy((char *)cstream, (char *)fnc->body, csize);
        !           261:        remloc(pvec, lpvec);
        !           262:        remloc(avec, lavec);
        !           263: }
        !           264: 
        !           265: /*
        !           266:  *     Copylty copyies the local types from the dictionary vector
        !           267:  *     `dvec' to the type vector `tvec'.  `len' is the number of
        !           268:  *     entries to copy.
        !           269:  */
        !           270: 
        !           271: copylty(dvec, tvec, len)
        !           272: register dicent        *dvec[];
        !           273: register type  tvec[];
        !           274: register int   len;
        !           275: {
        !           276:        while (--len >= 0)
        !           277:                *tvec++ = (*dvec++)->localt;
        !           278: }
        !           279: 
        !           280: 
        !           281: /*
        !           282:  *     Copy copyies the block of bytes at `from' to that at `to'.
        !           283:  *     `len' is the number of bytes to copy.  Note that these
        !           284:  *     blocks should not overlap.
        !           285:  */
        !           286: 
        !           287: copy(from, to, len)
        !           288: register char  *from,
        !           289:                *to;
        !           290: register int   len;
        !           291: {
        !           292:        while (--len >= 0)
        !           293:                *to++ = *from++;
        !           294: }
        !           295: 
        !           296: /*
        !           297:  *     Remloc is used to remove the local types from the dictionary
        !           298:  *     vector `dvec'.  `len' is the length of the vector.
        !           299:  */
        !           300: 
        !           301: remloc(dvec, len)
        !           302: register dicent        **dvec;
        !           303: register int   len;
        !           304: {
        !           305:        while (--len >= 0)
        !           306:                (*dvec++)->localt = UNDEFINED;
        !           307: }
        !           308: 
        !           309: /*
        !           310:  * Litfree recovers literal and string storage from bp to ep.
        !           311:  * Called after interp() on cstream to loc,
        !           312:  * after function definition abort on cstream to loc,
        !           313:  * during function redefinition on the old body.
        !           314:  */
        !           315: litfree(pc, end) register code *pc, *end;
        !           316: {
        !           317:        register int op;
        !           318:        while (pc < end) {
        !           319:                op = pc++->opcode;
        !           320:                if (pc >= end)
        !           321:                        break;
        !           322:                switch (op) {
        !           323:                case BRNEV:     /* Why by two? */
        !           324:                        printf("BRNEV in litfree\n");
        !           325:                case CALL:
        !           326:                        ++pc;
        !           327:                case PGLSC:
        !           328:                case PLOSC:
        !           329:                case PGLAE:
        !           330:                case PLOAE:
        !           331:                case PGLAR:
        !           332:                case PLOAR:
        !           333:                case RETURN:
        !           334:                case BRALW:
        !           335:                case BRLT:
        !           336:                case BRLE:
        !           337:                case BREQ:
        !           338:                case BRGE:
        !           339:                case BRGT:
        !           340:                case BRNE:
        !           341:                        ++pc;
        !           342:                case LOAD:
        !           343:                case LIBASE:
        !           344:                case LOBASE:
        !           345:                case LSCALE:
        !           346:                case STORE:
        !           347:                case SIBASE:
        !           348:                case SOBASE:
        !           349:                case SSCALE:
        !           350:                case POP:
        !           351:                case PRVAL:
        !           352:                case STOP:
        !           353:                case INC:
        !           354:                case DEC:
        !           355:                case PRNUM:
        !           356:                case PRNL:
        !           357:                case LENGTH:
        !           358:                case SCALE:
        !           359:                case SQRT:
        !           360:                case ADD:
        !           361:                case SUB:
        !           362:                case MUL:
        !           363:                case DIV:
        !           364:                case REM:
        !           365:                case EXP:
        !           366:                case NEG:
        !           367:                case EXIT:
        !           368:                        break;
        !           369:                case PLISC:
        !           370:                        mvfree(&pc->lvalue->mantissa);
        !           371:                        mpfree(pc++->lvalue);
        !           372:                        break;
        !           373:                case PRSTR:
        !           374:                        mpfree(pc++->svalue);
        !           375:                        break;
        !           376:                default:
        !           377:                        fprintf(stderr, "Mixup in litfree\n");
        !           378:                        exit(1);
        !           379:                }
        !           380:        }
        !           381: }

unix.superglobalmegacorp.com

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