Annotation of 43BSDTahoe/new/B/src/bsmall/b2exp.c, revision 1.1

1.1     ! root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
        !             2: /* $Header: b2exp.c,v 1.1 84/06/28 00:49:08 timo Exp $ */
        !             3: 
        !             4: /* B expression evaluation */
        !             5: #include "b.h"
        !             6: #include "b0con.h"
        !             7: #include "b1obj.h"
        !             8: #include "b1mem.h" /* for ptr */
        !             9: #include "b2env.h"
        !            10: #include "b2syn.h"
        !            11: #include "b2sem.h"
        !            12: #include "b2sou.h"
        !            13: 
        !            14: /*************************************************************/
        !            15: /*                                                           */
        !            16: /* The operand and operator stacks are modelled as compounds */
        !            17: /* whose first field is the top and whose second field is    */
        !            18: /* the remainder of the stack (i.e., linked lists).          */
        !            19: /* A cleaner and more efficient implementation of            */
        !            20: /* these heavily used stacks would be in order.              */
        !            21: /*                                                           */
        !            22: /*************************************************************/
        !            23: 
        !            24: /* nd = operand, tor = operator (function) */
        !            25: 
        !            26: value ndstack, torstack;
        !            27: #define Bot Vnil
        !            28: fun Bra, Ket;
        !            29: 
        !            30: Visible Procedure inittors() {
        !            31:        ndstack= torstack= Vnil;
        !            32:        Bra= mk_fun(-1, -1, Mon, (literal)Dummy, (txptr)Dummy, (txptr)Dummy, (value)Dummy, (bool)Dummy);
        !            33:        Ket= mk_fun( 0,  0, Dya, (literal)Dummy, (txptr)Dummy, (txptr)Dummy, (value)Dummy, (bool)Dummy);
        !            34: }
        !            35: 
        !            36: Hidden Procedure pop_stack(stack) value *stack; {
        !            37:        value oldstack= *stack;
        !            38:        *stack= *field(*stack, 1);
        !            39:        put_in_field(Vnil, &oldstack, 0); put_in_field(Vnil, &oldstack, 1);
        !            40:        release(oldstack);
        !            41: }
        !            42: 
        !            43: Hidden value popnd() {
        !            44:        value r;
        !            45:        if (ndstack == Vnil) syserr("operand stack underflow");
        !            46:        r= *field(ndstack, 0);
        !            47:        pop_stack(&ndstack);
        !            48:        return r;
        !            49: }
        !            50: 
        !            51: Hidden Procedure pushnd(nd) value nd; {
        !            52:        value s= ndstack;
        !            53:        ndstack= mk_compound(2);
        !            54:        put_in_field(nd, &ndstack, 0); put_in_field(s, &ndstack, 1);
        !            55: }
        !            56: 
        !            57: Hidden Procedure pushmontor(tor) value tor; {
        !            58:        value s= torstack;
        !            59:        torstack= mk_compound(2);
        !            60:        put_in_field(tor, &torstack, 0); put_in_field(s, &torstack, 1);
        !            61: }
        !            62: 
        !            63: Hidden Procedure pushdyator(tor2) value tor2; {
        !            64:        value tor1; funprd *t1, *t2= Funprd(tor2);
        !            65:        intlet L1, H1, L2= t2->L, H2= t2->H;
        !            66:  prio: if (torstack == Vnil) syserr("operator stack underflow");
        !            67:        tor1= *field(torstack, 0); t1= Funprd(tor1),
        !            68:        L1= t1->L; H1= t1->H;
        !            69:        if (L2 > H1)
        !            70:                if (tor2 == Ket) {
        !            71:                        if (tor1 != Bra)
        !            72:                                syserr("local operator stack underflow");
        !            73:                        pop_stack(&torstack);
        !            74:                }
        !            75:                else pushmontor(tor2);
        !            76:        else if (L1 >= H2) {
        !            77:                value nd1= Vnil, nd2= popnd();
        !            78:                if (t1->adic == Dya) nd1= popnd();
        !            79:                pushnd(formula(nd1, tor1, nd2));
        !            80:                if (xeq) {
        !            81:                        release(nd2);
        !            82:                        release(nd1);
        !            83:                }
        !            84:                pop_stack(&torstack);
        !            85:                goto prio;
        !            86:        } else pprerr("priorities? use ( and ) to resolve", "");
        !            87: }
        !            88: 
        !            89: Forward value basexpr();
        !            90: Forward value text_dis();
        !            91: Forward value tl_dis();
        !            92: 
        !            93: Hidden value statabsel(t, k) value t, k; {
        !            94:        /* temporary, while no static type check */
        !            95:        return mk_elt();
        !            96: }
        !            97: 
        !            98: Visible value expr(q) txptr q; {
        !            99:        value c, v; txptr i, j; intlet len, k;
        !           100:        if ((len= 1+count(",", q)) == 1) return basexpr(q);
        !           101:        c= mk_compound(len);
        !           102:        k_Overfields {
        !           103:                if (Lastfield(k)) i= q;
        !           104:                else req(",", q, &i, &j);
        !           105:                v= basexpr(i);
        !           106:                put_in_field(v, &c, k);
        !           107:                if (!Lastfield(k)) tx= j;
        !           108:        }
        !           109:        return c;
        !           110: }
        !           111: 
        !           112: Hidden value basexpr(q) txptr q; {
        !           113:        value v= obasexpr(q);
        !           114:        Skipsp(tx);
        !           115:        if (tx < q && Char(tx) == ',')
        !           116:                parerr("no commas allowed in this context", "");
        !           117:        upto(q, "expression");
        !           118:        return v;
        !           119: }
        !           120: 
        !           121: Forward bool primary(), clocondis();
        !           122: 
        !           123: #define Pbot {pushnd(Bot); pushmontor(Bra);}
        !           124: #define Ipush if (!pushing) {Pbot; pushing= Yes;}
        !           125: #define Fpush if (pushing) {                                    \
        !           126:                      pushnd(v); pushdyator(Ket); v= popnd();   \
        !           127:                      if (popnd() != Bot) syserr(               \
        !           128:                              xeq ? "formula evaluation awry" : \
        !           129:                                      "formula parsing awry");  \
        !           130:              }
        !           131: 
        !           132: Visible value obasexpr(q) txptr q; {
        !           133:        value v, t; bool pushing= No;
        !           134:  nxtnd:        Skipsp(tx);
        !           135:        nothing(q, "expression");
        !           136:        t= tag();
        !           137:        if (primary(q, t, &v, Yes)) /* then t is released */;
        !           138:        else if (t != Vnil) {
        !           139:                value f;
        !           140:                if (is_monfun(t, &f)) {
        !           141:                        release(t);
        !           142:                        Ipush;
        !           143:                        pushmontor(f);
        !           144:                        goto nxtnd;
        !           145:                } else {
        !           146:                        release(t);
        !           147:                        error("target has not yet received a value");
        !           148:                }
        !           149:        } else if (Montormark(Char(tx))) {
        !           150:                Ipush;
        !           151:                pushmontor(montor());
        !           152:                goto nxtnd;
        !           153:        } else parerr("no expression where expected", "");
        !           154:        /* We are past an operand and look for an operator */
        !           155:        Skipsp(tx);
        !           156:        if (tx < q) {
        !           157:                txptr tx0= tx; bool lt, eq, gt;
        !           158:                if (Letter(Char(tx))) {
        !           159:                        fun f;
        !           160:                        t= tag();
        !           161:                        if (is_dyafun(t, &f)) {
        !           162:                                release(t);
        !           163:                                Ipush;
        !           164:                                pushnd(v);
        !           165:                                pushdyator(f);
        !           166:                                goto nxtnd;
        !           167:                        }
        !           168:                        release(t);
        !           169:                } else if (relop(&lt, &eq, &gt));
        !           170:                else if (Dyatormark(Char(tx))) {
        !           171:                        Ipush;
        !           172:                        pushnd(v);
        !           173:                        pushdyator(dyator());
        !           174:                        goto nxtnd;
        !           175:                }
        !           176:                tx= tx0;
        !           177:        }
        !           178:        Fpush;
        !           179:        return v;
        !           180: }
        !           181: 
        !           182: Hidden bool clocondis(q, p) txptr q; value *p; {
        !           183:        txptr i, j;
        !           184:        Skipsp(tx);
        !           185:        nothing(q, "expression");
        !           186:        if (Char(tx) == '(') {
        !           187:                tx++; req(")", q, &i, &j);
        !           188:                *p= expr(i); tx= j;
        !           189:                return Yes;
        !           190:        }
        !           191:        if (Dig(Char(tx)) || Char(tx) == '.' || Char(tx) == 'E' &&
        !           192:           (Dig(Char(tx+1)) || Char(tx+1)=='+' || Char(tx+1)=='-')) {
        !           193:                *p= constant(q);
        !           194:                return Yes;
        !           195:        }
        !           196:        if (Char(tx) == '\'' || Char(tx) == '"') {
        !           197:                *p= text_dis(q);
        !           198:                return Yes;
        !           199:        }
        !           200:        if (Char(tx) == '{') {
        !           201:                *p= tl_dis(q);
        !           202:                return Yes;
        !           203:        }
        !           204:        return No;
        !           205: }
        !           206: 
        !           207: Hidden bool primary(q, t, p, tri) txptr q; value t, *p; bool tri; {
        !           208: /* If a tag has been seen, it is held in t.
        !           209:    Releasing t is a task of primary, but only if the call succeeds. */
        !           210:        fun f; value tt, relt= Vnil; value *aa= &t;
        !           211:        if (t != Vnil) /* tag */ {
        !           212:                if (xeq) {
        !           213:                        tt= t;
        !           214:                        aa= lookup(t);
        !           215:                        if (aa == Pnil) {
        !           216:                                if (is_zerfun(t, &f)) {
        !           217:                                        t= formula(Vnil, f, Vnil);        
        !           218:                                        aa= &t;
        !           219:                                } else return No;
        !           220:                        } else if (Is_refinement(*aa)) {
        !           221:                                ref_et(*aa, Ret); t= resval; resval= Vnil;
        !           222:                                aa= &t;
        !           223:                        } else if (Is_formal(*aa)) {
        !           224:                                t= eva_formal(*aa);
        !           225:                                aa= &t;
        !           226:                        } else if (Is_shared(*aa)) {
        !           227:                                if (!in_env(prmnv->tab, t, &aa)) return No;
        !           228:                                if (Is_filed(*aa))
        !           229:                                        if (!is_tloaded(t, &aa)) return No;
        !           230:                                t= Vnil;
        !           231:                        } else if (Is_filed(*aa)) {
        !           232:                                if (!is_tloaded(t, &aa)) return No;
        !           233:                                t= Vnil;
        !           234:                        } else t= Vnil;
        !           235:                        release(tt);
        !           236:                }
        !           237:        } else if (clocondis(q, &t)) aa= &t;
        !           238:        else return No;
        !           239:        Skipsp(tx);
        !           240:        while (tx < q && Char(tx) == '[') {
        !           241:                txptr i, j; value s;
        !           242:                tx++; req("]", q, &i, &j);
        !           243:                s= expr(i); tx= j;
        !           244:                /* don't copy table for selection */
        !           245:                if (xeq) {
        !           246:                        aa= adrassoc(*aa, s);
        !           247:                        release(s);
        !           248:                        relt= t;
        !           249:                        if (aa == Pnil) error("key not in table");
        !           250:                } else {
        !           251:                        t= statabsel(tt= t, s);
        !           252:                        release(tt); release(s);
        !           253:                }
        !           254:                Skipsp(tx);
        !           255:        }
        !           256:        if (tri && tx < q && (Char(tx) == '@' || Char(tx) == '|')) {
        !           257:                intlet B, C;
        !           258:                if (xeq && !Is_text(*aa))
        !           259:                        parerr("in t@p or t|p, t is not a text", "");
        !           260:                trimbc(q, xeq ? length(*aa) : 0, &B, &C);
        !           261:                if (xeq) {
        !           262:                        relt= t;
        !           263:                        t= trim(*aa, B, C);
        !           264:                        aa= &t;
        !           265:                }
        !           266:        }
        !           267:        *p= t == Vnil || relt != Vnil ? copy(*aa) : t;
        !           268:        release(relt);
        !           269:        return Yes;
        !           270: }
        !           271: 
        !           272: Forward intlet trimi();
        !           273: 
        !           274: Visible Procedure trimbc(q, len, B, C) txptr q; intlet len, *B, *C; {
        !           275:        char bc; intlet N;
        !           276:        *B= *C= 0;
        !           277:        while (tx < q && (Char(tx) == '@' || Char(tx) == '|')) {
        !           278:                bc= Char(tx++);
        !           279:                N= trimi(q);
        !           280:                if (bc == '@') *B+= N-1;
        !           281:                else *C+= (len-*B-*C)-N;
        !           282:                if (*B < 0 || *C < 0 || *B+*C > len)
        !           283:                        error("in t@p or t|p, p is out of bounds");
        !           284:                Skipsp(tx);
        !           285:        }
        !           286: }
        !           287: 
        !           288: Hidden intlet trimi(q) txptr q; {
        !           289:        value v, t; bool pushing= No;
        !           290:  nxtnd:        Skipsp(tx);
        !           291:        nothing(q, "expression");
        !           292:        t= tag();
        !           293:        if (primary(q, t, &v, No)); /* then t is released */
        !           294:        else if (t != Vnil) {
        !           295:                value f;
        !           296:                if (is_monfun(t, &f)) {
        !           297:                        release(t);
        !           298:                        Ipush;
        !           299:                        pushmontor(f);
        !           300:                        goto nxtnd;
        !           301:                } else {
        !           302:                        release(t);
        !           303:                        error("target has not yet received a value");
        !           304:                }
        !           305:        } else if (Montormark(Char(tx))) {
        !           306:                Ipush;
        !           307:                pushmontor(montor());
        !           308:                goto nxtnd;
        !           309:        } else parerr("no expression where expected", "");
        !           310:        Fpush;
        !           311:        {int ii; intlet i= 0;
        !           312:                if (xeq) {
        !           313:                        ii= intval(v);
        !           314:                        if (ii < 0) error("in t@p or t|p, p is negative");
        !           315:                        if (ii > Maxintlet)
        !           316:                                error("in t@p or t|p, p is excessive");
        !           317:                        i= ii;
        !           318:                }
        !           319:                release(v);
        !           320:                return i;
        !           321:        }
        !           322: }
        !           323: 
        !           324: Visible value constant(q) txptr q; {
        !           325:        bool dig= No; txptr first= tx;
        !           326:        while (tx < q && Dig(Char(tx))) {
        !           327:                ++tx;
        !           328:                dig= Yes;
        !           329:        }
        !           330:        if (tx < q && Char(tx) == '.') {
        !           331:                tx++;
        !           332:                while (tx < q && Dig(Char(tx))) {
        !           333:                        dig= Yes;
        !           334:                        ++tx;
        !           335:                }
        !           336:                if (!dig) pprerr("point without digits", "");
        !           337:        }
        !           338:        if (tx < q && Char(tx) == 'E') {
        !           339:                tx++;
        !           340:                if (!(Dig(Char(tx))) && Keymark(Char(tx))) {
        !           341:                        tx--;
        !           342:                        goto done;
        !           343:                }
        !           344:                if (tx < q && (Char(tx) == '+' || Char(tx) == '-')) ++tx;
        !           345:                dig= No;
        !           346:                while (tx < q && Dig(Char(tx))) {
        !           347:                        dig= Yes;
        !           348:                        ++tx;
        !           349:                }
        !           350:                if (!dig) parerr("E not followed by exponent", "");
        !           351:        }
        !           352:  done: return numconst(first, tx);
        !           353: }
        !           354: 
        !           355: char txdbuf[TXDBUFSIZE];
        !           356: txptr txdbufend= &txdbuf[TXDBUFSIZE];
        !           357: 
        !           358: Visible Procedure concat_to(v, s) value* v; string s; { /*TEMPORARY*/
        !           359:        value v1, v2;
        !           360:        if (*v == Vnil) *v= mk_text(s);
        !           361:        else {
        !           362:                *v= concat(v1= *v, v2= mk_text(s));
        !           363:                release(v1); release(v2);
        !           364:        }
        !           365: }
        !           366: 
        !           367: Hidden value text_dis(q) txptr q; {
        !           368:        char aq[2]; txptr tp= txdbuf; value t= Vnil, t1, t2;
        !           369:        aq[1]= '\0'; *aq= Char(tx++);
        !           370:  fbuf: while (tx < q && Char(tx) != *aq) {
        !           371:                if (Char(tx) == '`') {
        !           372:                        if (Char(tx+1) == '`') tx++;
        !           373:                        else {
        !           374:                                *tp= '\0';
        !           375:                                concat_to(&t, txdbuf);
        !           376:                                t= concat(t1= t, t2= conversion(q));
        !           377:                                release(t1); release(t2);
        !           378:                                tp= txdbuf; goto fbuf;
        !           379:                        }
        !           380:                }
        !           381:                *tp++= Char(tx++);
        !           382:                if (tp+1 >= txdbufend) {
        !           383:                        *(txdbufend-1)= '\0';
        !           384:                        concat_to(&t, txdbuf);
        !           385:                        tp= txdbuf;
        !           386:                }
        !           387:        }
        !           388:        if (tx >= q) parerr("cannot find matching ", aq);
        !           389:        if (++tx < q && Char(tx) == *aq) {
        !           390:                *tp++= Char(tx++);
        !           391:                goto fbuf;
        !           392:        }
        !           393:        *tp= '\0';
        !           394:        concat_to(&t, txdbuf);
        !           395:        return t;
        !           396: }
        !           397: 
        !           398: Visible value conversion(q) txptr q; {
        !           399:        txptr f, t; value v, c;
        !           400:        thought('`');
        !           401:        req("`", q, &f, &t);
        !           402:        v= expr(f); c= Ifxeq(convert(v, Yes, Yes));
        !           403:        if (xeq) release(v);
        !           404:        tx= t; return c;
        !           405: }
        !           406: 
        !           407: Hidden value tl_dis(q) txptr q; {
        !           408:        txptr f, t, ff, tt;
        !           409:        intlet len, k;
        !           410:        thought('{');
        !           411:        Skipsp(tx);
        !           412:        if (Char(tx) == '}') {
        !           413:                tx++;
        !           414:                return Ifxeq(mk_elt());
        !           415:        }
        !           416:        req("}", q, &f, &t);
        !           417:        if (find("..", f, &ff, &tt)) {
        !           418:                value enu, lo, hi;
        !           419:                lo= basexpr(ff);
        !           420:                if (!xeq || Is_number(lo)) {
        !           421:                        tx= tt; while (Char(tx) == '.') tx++;
        !           422:                        hi= basexpr(f);
        !           423:                        if (xeq) {
        !           424:                                value entries;
        !           425:                                if (!integral(lo))
        !           426:                                  error("in {p..q}, p is a number but not an integer");
        !           427:                                if (!Is_number(hi))
        !           428:                                  error("in {p..q}, p is a number but q is not");
        !           429:                                if (!integral(hi))
        !           430:                                  error("in {p..q}, q is a number but not an integer");
        !           431:                                entries= diff(lo, hi);
        !           432:                                if (compare(entries, one)>0)
        !           433:                                        error("in {p..q}, integer q < x < p");
        !           434:                                enu= mk_numrange(lo, hi);
        !           435:                                release(entries);
        !           436:                        } else enu= mk_elt();
        !           437:                        release(hi); release(lo);
        !           438:                } else if (Is_text(lo)) {
        !           439:                        char a, z;
        !           440:                        if (!character(lo))
        !           441:                          error("in {p..q}, p is a text but not a character");
        !           442:                        tx= tt; hi= basexpr(f);
        !           443:                        if (!Is_text(hi))
        !           444:                          error("in {p..q}, p is a text but q is not");
        !           445:                        if (!character(hi))
        !           446:                          error("in {p..q}, q is a text but not a character");
        !           447:                        a= charval(lo); z= charval(hi);
        !           448:                        if (z < a-1) error("in {p..q}, character q < x < p");
        !           449:                        enu= mk_charrange(lo, hi);
        !           450:                        release(lo); release(hi);
        !           451:                } else error("in {p..q}, p is neither a number nor a text");
        !           452:                tx= t; return enu;
        !           453:        }
        !           454:        len= 1+count(";", f);
        !           455:        Skipsp(tx);
        !           456:        if (Char(tx) == '[') {
        !           457:                value ta, ke, a;
        !           458:                ta= mk_elt();
        !           459:                k_Over_len {
        !           460:                        Skipsp(tx);
        !           461:                        need("[");
        !           462:                        req("]", f, &ff, &tt);
        !           463:                        ke= expr(ff); tx= tt;
        !           464:                        need(":");
        !           465:                        if (Last(k)) {ff= f; tt= t;}
        !           466:                        else req(";", f, &ff, &tt);
        !           467:                        a= basexpr(ff); tx= tt;
        !           468:                        replace(a, &ta, ke);
        !           469:                        release(ke); release(a);
        !           470:                }
        !           471:                return ta;
        !           472:        }
        !           473:        {value l, v;
        !           474:                l= mk_elt();
        !           475:                k_Over_len {
        !           476:                        if (Last(k)) {ff= f; tt= t;}
        !           477:                        else req(";", f, &ff, &tt);
        !           478:                        v= basexpr(ff); tx= tt;
        !           479:                        insert(v, &l);
        !           480:                        release(v);
        !           481:                }
        !           482:                return l;
        !           483:        }
        !           484: }

unix.superglobalmegacorp.com

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