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

1.1     ! root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
        !             2: /* $Header: B1tlt.c,v 1.1 84/06/28 00:49:00 timo Exp $ */
        !             3: 
        !             4: #include "b.h"
        !             5: #include "b1obj.h"
        !             6: #include "B1tlt.h"
        !             7: 
        !             8: Visible value mk_elt() { return grab_elt(); }
        !             9: 
        !            10: Visible value size(x) value x; { /* monadic # operator */
        !            11:        if (!Is_tlt(x)) error("in #t, t is not a text, list or table");
        !            12:        return mk_integer((int) Length(x));
        !            13: }
        !            14: 
        !            15: #define Lisent(tp,k) (*(tp+(k)))
        !            16: 
        !            17: Visible value size2(v, t) value v, t; { /* Dyadic # operator */
        !            18:        intlet len= Length(t), n= 0, k; value *tp= Ats(t);
        !            19:        if (!Is_tlt(t)) error("in e#t, t is not a text, list or table");
        !            20:        switch (t->type) {
        !            21:        case Tex:
        !            22:                {string cp= (string)tp; char c;
        !            23:                        if (v->type != Tex)
        !            24:                                error("in e#t, t is a text but e is not");
        !            25:                        if (Length(v) != 1) error(
        !            26:                                "in e#t, e is a text but not a character");
        !            27:                        c= *Str(v);
        !            28:                        Overall if (*cp++ == c) n++;
        !            29:                } break;
        !            30:        case ELT:
        !            31:                break;
        !            32:        case Lis:
        !            33:                {intlet lo= -1, mi, xx, mm, hi= len; relation c;
        !            34:                bins:   if (hi-lo < 2) break;
        !            35:                        mi= (lo+hi)/2;
        !            36:                        if ((c= compare(v, Lisent(tp,mi))) == 0) goto some;
        !            37:                        if (c < 0) hi= mi; else lo= mi;
        !            38:                        goto bins;
        !            39:                some:   xx= mi;
        !            40:                        while (xx-lo > 1) {
        !            41:                                mm= (lo+xx)/2;
        !            42:                                if (compare(v, Lisent(tp,mm)) == 0) xx= mm;
        !            43:                                else lo= mm;
        !            44:                        }
        !            45:                        xx= mi;
        !            46:                        while (hi-xx > 1) {
        !            47:                                mm= (xx+hi)/2;
        !            48:                                if (compare(v, Lisent(tp,mm)) == 0) xx= mm;
        !            49:                                else hi= mm;
        !            50:                        }
        !            51:                        n= hi-lo-1;
        !            52:                } break;
        !            53:        case Tab:
        !            54:                Overall if (compare(v, Dts(*tp++)) == 0) n++;
        !            55:                break;
        !            56:        default:
        !            57:                syserr("e#t with non text, list or table");
        !            58:                break;
        !            59:        }
        !            60:        return mk_integer((int) n);
        !            61: }
        !            62: 
        !            63: Hidden bool less(r) relation r;    { return r<0; }
        !            64: Hidden bool greater(r) relation r; { return r>0; }
        !            65: 
        !            66: Hidden value mm1(t, rel) value t; bool (*rel)(); {
        !            67:        intlet len= Length(t), k; value m, *tp= Ats(t);
        !            68:        switch (t->type) {
        !            69:        case Tex:
        !            70:                {string cp= (string) tp; char mc= '\0', mm[2];
        !            71:                        Overall {
        !            72:                                if (mc == '\0' || ((*rel)(*cp < mc ? -1 : (*cp > mc ? 1 : 0))))
        !            73:                                        mc= *cp;
        !            74:                                cp++;
        !            75:                        }
        !            76:                        mm[0]= mc; mm[1]= '\0';
        !            77:                        m= mk_text(mm);
        !            78:                } break;
        !            79:        case Lis:
        !            80:                if ((*rel)(-1)) /*min*/ m= copy(*Ats(t));
        !            81:                else m= copy(*(Ats(t)+len-1));
        !            82:                break;
        !            83:        case Tab:
        !            84:                {value dm= Vnil;
        !            85:                        Overall {
        !            86:                                if (dm == Vnil || (*rel)(compare(Dts(*tp), dm)))
        !            87:                                        dm= Dts(*tp);
        !            88:                                tp++;
        !            89:                        }
        !            90:                        m= copy(dm);
        !            91:                } break;
        !            92:        default:
        !            93:                syserr("min or max t, with non text, list or table");
        !            94:        }
        !            95:        return m;
        !            96: }
        !            97: 
        !            98: Hidden value mm2(v, t, rel) value v, t; bool (*rel)(); {
        !            99:        intlet len= Length(t), k; value m= Vnil, *tp= Ats(t);
        !           100:        switch (t->type) {
        !           101:        case Tex:
        !           102:                {string cp= (string) tp; char c, mc= '\0', mm[2];
        !           103:                        c= *Str(v);
        !           104:                        Overall {
        !           105:                                if ((*rel)(c < *cp ? -1 : c > *cp ? 1 : 0)) {
        !           106:                                        if (mc == '\0' || (*rel)(*cp < mc ? -1 : *cp>mc ? 1 : 0))
        !           107:                                                mc= *cp;
        !           108:                                }
        !           109:                                cp++;
        !           110:                        }
        !           111:                        if (mc != '\0') {
        !           112:                                mm[0]= mc; mm[1]= '\0';
        !           113:                                m= mk_text(mm);
        !           114:                        }
        !           115:                } break;
        !           116:        case Lis:
        !           117:                {intlet lim1, mid, lim2;
        !           118:                        if ((*rel)(-1)) { /*min*/
        !           119:                                lim1= 1; lim2= len-1;
        !           120:                        } else {
        !           121:                                lim2= 1; lim1= len-1;
        !           122:                        }
        !           123:                        if (!(*rel)(compare(v, Lisent(tp,lim2)))) break;
        !           124:                        if (len == 1 || (*rel)(compare(v, Lisent(tp,lim1)))) {
        !           125:                                m= copy(Lisent(tp,lim1));
        !           126:                                break;
        !           127:                        }
        !           128:                        /* v rel tp[lim2] && !(v rel tp[lim1]) */
        !           129:                        while (abs(lim2-lim1) > 1) {
        !           130:                                mid= (lim1+lim2)/2;
        !           131:                                if ((*rel)(compare(v, Lisent(tp,mid)))) lim2= mid;
        !           132:                                else lim1= mid;
        !           133:                        }
        !           134:                        m= copy(Lisent(tp,lim2));
        !           135:                } break;
        !           136:        case Tab:
        !           137:                {value dm= Vnil;
        !           138:                        Overall {
        !           139:                                if ((*rel)(compare(v, Dts(*tp)))) {
        !           140:                                        if (dm == Vnil ||
        !           141:                                                (*rel)(compare(Dts(*tp), dm)))
        !           142:                                                dm= Dts(*tp);
        !           143:                                }
        !           144:                                tp++;
        !           145:                        }
        !           146:                        if (dm != Vnil) m= copy(dm);
        !           147:                } break;
        !           148:        default:
        !           149:                syserr("min2 or max2 with non text, list or table");
        !           150:                break;
        !           151:        }
        !           152:        return m;
        !           153: }
        !           154: 
        !           155: Visible value min1(t) value t; { /* Monadic min */
        !           156:        if (!Is_tlt(t)) error("in min t, t is not a text, list or table");
        !           157:        if (Length(t) == 0) error("in min t, t is empty");
        !           158:        return mm1(t, less);
        !           159: }
        !           160: 
        !           161: Visible value min2(v, t) value v, t; {
        !           162:        value m;
        !           163:        if (!Is_tlt(t)) error("in e min t, t is not a text, list or table");
        !           164:        if (Length(t) == 0) error("in e min t, t is empty");
        !           165:        if (Is_text(t)) {
        !           166:                if (!Is_text(v)) error("in e min t, t is a text but e is not");
        !           167:                if (Length(v) != 1) error("in e min t, e is a text but not a character");
        !           168:        }
        !           169:        m= mm2(v, t, less);
        !           170:        if (m == Vnil) error("in e min t, no element of t exceeds e");
        !           171:        return m;
        !           172: }
        !           173: 
        !           174: Visible value max1(t) value t; {
        !           175:        if (!Is_tlt(t)) error("in max t, t is not a text, list or table");
        !           176:        if (Length(t) == 0) error("in max t, t is empty");
        !           177:        return mm1(t, greater);
        !           178: }
        !           179: 
        !           180: Visible value max2(v, t) value v, t; {
        !           181:        value m;
        !           182:        if (!Is_tlt(t)) error("in e max t, t is not a text, list or table");
        !           183:        if (Length(t) == 0) error("in e max t, t is empty");
        !           184:        if (Is_text(t)) {
        !           185:                if (!Is_text(v)) error("in e max t, t is a text but e is not");
        !           186:                if (Length(v) != 1) error("in e max t, e is a text but not a character");
        !           187:        }
        !           188:        m= mm2(v, t, greater);
        !           189:        if (m == Vnil) error("in e max t, no element of t is less than e");
        !           190:        return m;
        !           191: }
        !           192: 
        !           193: Visible value th_of(n, t) value n, t; {
        !           194:        return thof(intval(n), t);
        !           195: }
        !           196: 
        !           197: Visible value thof(n, t) int n; value t; {
        !           198:        intlet len= Length(t); value w;
        !           199:        if (!Is_tlt(t)) error("in n th'of t, t is not a text, list or table");
        !           200:        if (n <= 0 || n > len) error("in n th'of t, n is out of bounds");
        !           201:        switch (t->type) {
        !           202:        case Tex:
        !           203:                {char ww[2];
        !           204:                        ww[0]= *(Str(t)+n-1); ww[1]= '\0';
        !           205:                        w= mk_text(ww);
        !           206:                } break;
        !           207:        case Lis:
        !           208:                w= copy(*(Ats(t)+n-1));
        !           209:                break;
        !           210:        case Tab:
        !           211:                w= copy(Dts(*(Ats(t)+n-1)));
        !           212:                break;
        !           213:        default:
        !           214:                syserr("th'of with non text, list or table");
        !           215:        }
        !           216:        return w;
        !           217: }
        !           218: 
        !           219: Visible bool found(elem, v, probe, where)
        !           220:        value (*elem)(), v, probe; intlet *where;
        !           221:        /* think of elem(v,lo-1) as -Infinity and elem(v,hi+1) as +Infinity.
        !           222:           found and where at the end satisfy:
        !           223:           SELECT:
        !           224:               SOME k IN {lo..hi} HAS probe = elem(v,k):
        !           225:                   found = Yes AND where = k
        !           226:               ELSE: found = No AND elem(v,where-1) < probe < elem(v,where).
        !           227:        */
        !           228: {relation c; intlet lo=0, hi= Length(v)-1;
        !           229:        if (lo > hi) { *where= lo; return No; }
        !           230:        if ((c= compare(probe, (*elem)(v, lo))) == 0) {*where= lo; return Yes; }
        !           231:        if (c < 0) { *where=lo; return No; }
        !           232:        if (lo == hi) { *where=hi+1; return No; }
        !           233:        if ((c= compare(probe, (*elem)(v, hi))) == 0) { *where=hi; return Yes; }
        !           234:        if (c > 0) { *where=hi+1; return No; }
        !           235:        /* elem(lo) < probe < elem(hi) */
        !           236:        while (hi-lo > 1) {
        !           237:                if ((c= compare(probe, (*elem)(v, (lo+hi)/2))) == 0) {
        !           238:                        *where= (lo+hi)/2; return Yes;
        !           239:                }
        !           240:                if (c < 0) hi= (lo+hi)/2; else lo= (lo+hi)/2;
        !           241:        }
        !           242:        *where= hi; return No;
        !           243: }
        !           244: 
        !           245: Visible bool in(v, t) value v, t; {
        !           246:        intlet where, k, len= Length(t); value *tp= Ats(t);
        !           247:        if (!Is_tlt(t)) error("in the test e in t, t is not a text, list or table");
        !           248:        switch (t->type) {
        !           249:        case Tex:
        !           250:                if (v->type != Tex)
        !           251:                        error("in the test e in t, t is a text but e is not");
        !           252:                if (Length(v) != 1)
        !           253:                        error("in the test e in t, e is a text but not a character");
        !           254:                return index((string) tp, *Str(v)) != 0;
        !           255:        case ELT:
        !           256:                return No;
        !           257:        case Lis:
        !           258:                return found(list_elem, t, v, &where);
        !           259:        case Tab:
        !           260:                Overall if (compare(v, Dts(*tp++)) == 0) return Yes;
        !           261:                return No;
        !           262:        default:
        !           263:                syserr("e in t with non text, list or table");
        !           264:                return No;
        !           265:        }
        !           266: }

unix.superglobalmegacorp.com

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