Annotation of researchv10dc/cmd/icon/src/iconx/fconv.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * File: fconv.c
                      3:  *  Contents: abs, cset, integer, list, numeric, proc, real, set, string, table
                      4:  */
                      5: 
                      6: #include "../h/rt.h"
                      7: 
                      8: /*
                      9:  * abs(x) - absolute value of x.
                     10:  */
                     11: FncDcl(abs,1)
                     12:    {
                     13:    union numeric result;
                     14: 
                     15:    switch (cvnum(&Arg1, &result)) {
                     16:       /*
                     17:        * If x is convertible to a numeric, turn Arg0 into
                     18:        *  a descriptor for the appropriate type and value.  If the
                     19:        *  conversion fails, produce an error.  This code assumes that
                     20:        *  x = -x is always valid, but this assumption does not always
                     21:        *  hold.
                     22:        */
                     23:       case T_Integer:
                     24:       case T_Longint:
                     25:          if (result.integer < 0L)
                     26:             result.integer = -result.integer;
                     27:          Mkint(result.integer, &Arg0);
                     28:          break;
                     29: 
                     30:       case T_Real:
                     31:          if (result.real < 0.0)
                     32:             result.real = -result.real;
                     33:          mkreal(result.real, &Arg0);
                     34:          break;
                     35: 
                     36:       default:
                     37:          runerr(102, &Arg1);
                     38:       }
                     39:    Return;
                     40:    }
                     41: 
                     42: 
                     43: /*
                     44:  * cset(x) - convert x to cset.
                     45:  */
                     46: 
                     47: FncDcl(cset,1)
                     48:    {
                     49:    register int i, j;
                     50:    register struct b_cset *bp;
                     51:    int *cs, csbuf[CsetSize];
                     52:    extern struct b_cset *alccset();
                     53: 
                     54:    blkreq((word)sizeof(struct b_cset));
                     55: 
                     56:    if (Arg1.dword == D_Cset)
                     57:       /*
                     58:        * x is already a cset, just return it.
                     59:        */
                     60:       Arg0 = Arg1;
                     61:    else if (cvcset(&Arg1, &cs, csbuf) != NULL) {
                     62:       /*
                     63:        * x was convertible to cset and the result resides in csbuf.  Allocate
                     64:        *  a cset, make Arg0 a descriptor for it and copy the bits from csbuf
                     65:        *  into it.
                     66:        */
                     67:       Arg0.dword = D_Cset;
                     68:       bp = alccset(0);
                     69:       BlkLoc(Arg0) =  (union block *) bp;
                     70:       for (i = 0; i < CsetSize; i++)
                     71:          bp->bits[i] = cs[i];
                     72:       j = 0;
                     73:       for (i = 0; i < CsetSize*CIntSize; i++) {
                     74:          if (Testb(i,cs))
                     75:             j++;
                     76:          }
                     77:       bp->size = j;
                     78:       }
                     79:    else                        /* Not a cset nor convertible to one. */
                     80:       Fail;
                     81:    Return;
                     82:    }
                     83: 
                     84: 
                     85: /*
                     86:  * integer(x) - convert x to integer.
                     87:  */
                     88: 
                     89: FncDcl(integer,1)
                     90:    {
                     91:    long l;
                     92: 
                     93:    switch (cvint(&Arg1, &l)) {
                     94: 
                     95:       case T_Integer:
                     96:       case T_Longint:
                     97:          Mkint(l, &Arg0);
                     98:          break;
                     99: 
                    100:       default:
                    101:          Fail;
                    102:       }
                    103:    Return;
                    104:    }
                    105: 
                    106: 
                    107: /*
                    108:  * list(n,x) - create a list of size n, with initial value x.
                    109:  */
                    110: 
                    111: /* >list */
                    112: FncDcl(list,2)
                    113:    {
                    114:    register word i, size;
                    115:    word nelem;
                    116:    register struct b_lelem *bp;
                    117:    register struct b_list *hp;
                    118:    extern struct b_list *alclist();
                    119:    extern struct b_lelem *alclstb();
                    120: 
                    121:    defshort(&Arg1, 0);                 /* Size defaults to 0 */
                    122: 
                    123:    nelem = size = IntVal(Arg1);
                    124: 
                    125: 
                    126:    /*
                    127:     * Ensure that the size is positive and that the list element block 
                    128:     *  has at least MinListSlots element slots.
                    129:     */
                    130:    if (size < 0)
                    131:       runerr(205, &Arg1);
                    132:    if (nelem < MinListSlots)
                    133:       nelem = MinListSlots;
                    134: 
                    135:    /*
                    136:     * Ensure space for a list header block, and a list element block
                    137:     * with nelem element slots.
                    138:     */
                    139:    blkreq(sizeof(struct b_list) + sizeof(struct b_lelem) +
                    140:          nelem * sizeof(struct descrip));
                    141: 
                    142:    /*
                    143:     * Allocate the list header block and a list element block.
                    144:     *  Note that nelem is the number of elements in the list element
                    145:     *  block while size is the number of elements in the
                    146:     *  list.
                    147:     */
                    148:    hp = alclist(size);
                    149:    bp = alclstb(nelem, (word)0, size);
                    150:    hp->listhead.dword = hp->listtail.dword = D_Lelem;
                    151:    BlkLoc(hp->listhead) = BlkLoc(hp->listtail) = (union block *) bp;
                    152: 
                    153:    /*
                    154:     * Initialize each list element.
                    155:     */
                    156:    for (i = 0; i < size; i++)
                    157:       bp->lslots[i] = Arg2;
                    158: 
                    159:    /*
                    160:     * Return the new list.
                    161:     */
                    162:    Arg0.dword = D_List;
                    163:    BlkLoc(Arg0) = (union block *) hp;
                    164:    Return;
                    165:    }
                    166: /* <list */
                    167: 
                    168: 
                    169: /*
                    170:  * numeric(x) - convert x to numeric type.
                    171:  */
                    172: FncDcl(numeric,1)
                    173:    {
                    174:    union numeric n1;
                    175: 
                    176:    switch (cvnum(&Arg1, &n1)) {
                    177: 
                    178:       case T_Integer:
                    179:       case T_Longint:
                    180:          Mkint(n1.integer, &Arg0);
                    181:          break;
                    182: 
                    183:       case T_Real:
                    184:          mkreal(n1.real, &Arg0);
                    185:          break;
                    186: 
                    187:       default:
                    188:          Fail;
                    189:       }
                    190:    Return;
                    191:    }
                    192: 
                    193: 
                    194: /*
                    195:  * proc(x,args) - convert x to a procedure if possible; use args to
                    196:  *  resolve ambiguous string names.
                    197:  */
                    198: FncDcl(proc,2)
                    199:    {
                    200:    char sbuf[MaxCvtLen];
                    201:    
                    202:    /*
                    203:     * If x is already a proc, just return it in Arg0.
                    204:     */
                    205:    Arg0 = Arg1;
                    206:    if (Arg0.dword == D_Proc) {
                    207:       Return;
                    208:       }
                    209:    if (cvstr(&Arg0, sbuf) == NULL)
                    210:       Fail;
                    211:    /*
                    212:     * args defaults to 1.
                    213:     */
                    214:    defshort(&Arg2, 1);
                    215:    /*
                    216:     * Attempt to convert Arg0 to a procedure descriptor using args to
                    217:     *  discriminate between procedures with the same names.  Fail if
                    218:     *  the conversion isn't successful.
                    219:     */
                    220:    if (strprc(&Arg0,IntVal(Arg2))) {
                    221:       Return;
                    222:       }
                    223:    else
                    224:       Fail;
                    225:    }
                    226: 
                    227: 
                    228: /*
                    229:  * real(x) - convert x to real.
                    230:  */
                    231: 
                    232: FncDcl(real,1)
                    233:    {
                    234:    double r;
                    235: 
                    236:    /*
                    237:     * If x is already a real, just return it.  Otherwise convert it and
                    238:     *  return it, failing if the conversion is unsuccessful.
                    239:     */
                    240:    if (Arg1.dword == D_Real)
                    241:       Arg0 = Arg1;
                    242:    else if (cvreal(&Arg1, &r) == T_Real)
                    243:       mkreal(r, &Arg0);
                    244:    else
                    245:       Fail;
                    246:    Return;
                    247:    }
                    248: 
                    249: 
                    250: /*
                    251:  * set(list) - create a set with members in list.
                    252:  *  The members are linked into hash chains which are
                    253:  *  arranged in increasing order by hash number.
                    254:  */
                    255: FncDcl(set,1)
                    256:    {
                    257:    register word hn;
                    258:    register struct descrip *pd;
                    259:    register struct b_set *ps;
                    260:    union block *pb;
                    261:    struct b_selem *ne;
                    262:    struct descrip *pe;
                    263:    int res;
                    264:    word i, j;
                    265:    extern struct descrip *memb();
                    266:    extern struct b_set *alcset();
                    267:    extern struct b_selem *alcselem();
                    268: 
                    269:    if (Arg1.dword != D_List)
                    270:       runerr(108,&Arg1);
                    271: 
                    272:    blkreq(sizeof(struct b_set) + (BlkLoc(Arg1)->list.size *
                    273:       sizeof(struct b_selem)));
                    274: 
                    275:    pb = BlkLoc(Arg1);
                    276:    Arg0.dword = D_Set;
                    277:    ps = alcset();
                    278:    BlkLoc(Arg0) = (union block *) ps;
                    279:    /*
                    280:     * Chain through each list block and for
                    281:     *  each element contained in the block
                    282:     *  insert the element into the set if not there.
                    283:     */
                    284:    for (Arg1 = pb->list.listhead; Arg1.dword == D_Lelem;
                    285:       Arg1 = BlkLoc(Arg1)->lelem.listnext) {
                    286:          pb = BlkLoc(Arg1);
                    287:          for (i = 0; i < pb->lelem.nused; i++) {
                    288:             j = pb->lelem.first + i;
                    289:             if (j >= pb->lelem.nelem)
                    290:                j -= pb->lelem.nelem;
                    291:             pd = &pb->lelem.lslots[j];
                    292:             pe = memb(ps, pd, hn = hash(pd), &res);
                    293:             if (res == 0) {
                    294:                ne = alcselem(pd,hn);
                    295:                 addmem(ps,ne,pe);
                    296:                 }
                    297:             }
                    298:       }
                    299:    Return;
                    300:    }
                    301: 
                    302: 
                    303: /*
                    304:  * string(x) - convert x to string.
                    305:  */
                    306: 
                    307: /* >string */
                    308: FncDcl(string,1)
                    309:    {
                    310:    char sbuf[MaxCvtLen];
                    311:    extern char *alcstr();
                    312: 
                    313:    Arg0 = Arg1;
                    314:    switch (cvstr(&Arg0, sbuf)) {
                    315: 
                    316:       /*
                    317:        * If Arg1 is not a string, allocate it and return it; if it is a
                    318:        *  string, just return it; fail otherwise.
                    319:        */
                    320:       case Cvt:
                    321:          strreq(StrLen(Arg0));         /* allocate converted string */
                    322:          StrLoc(Arg0) = alcstr(StrLoc(Arg0), StrLen(Arg0));
                    323: 
                    324:       case NoCvt:
                    325:          Return;
                    326: 
                    327:       default:
                    328:          Fail;
                    329:       }
                    330:    }
                    331: /* <string */
                    332: 
                    333: /*
                    334:  * table(x) - create a table with default value x.
                    335:  */
                    336: FncDcl(table,1)
                    337:    {
                    338:    extern struct b_table *alctable();
                    339: 
                    340:    blkreq((word)sizeof(struct b_table));
                    341:    Arg0.dword = D_Table;
                    342:    BlkLoc(Arg0) = (union block *) alctable(&Arg1);
                    343:    Return;
                    344:    }

unix.superglobalmegacorp.com

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