Annotation of researchv10dc/cmd/icon/src/iconx/oref.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * File: oref.c
        !             3:  *  Contents: bang, sect, subsc
        !             4:  */
        !             5: 
        !             6: #include "../h/rt.h"
        !             7: 
        !             8: /*
        !             9:  * !x - generate successive values from object x.
        !            10:  */
        !            11: 
        !            12: OpDclV(bang,1,"!")
        !            13:    {
        !            14:    register word i, j, slen;
        !            15:    register union block *bp, *ep;
        !            16:    register struct descrip *dp;
        !            17:    int typ1;
        !            18:    char sbuf[MaxCvtLen];
        !            19:    FILE *fd;
        !            20:    extern char *alcstr();
        !            21: 
        !            22:    Arg2 = Arg1;
        !            23: 
        !            24:    DeRef(Arg1);
        !            25:    if ((typ1 = cvstr(&Arg1, sbuf)) != NULL) {
        !            26:       /*
        !            27:        * A string is being banged.
        !            28:        */
        !            29:       i = 1;
        !            30:       while (i <= StrLen(Arg1)) {
        !            31:          /*
        !            32:           * Loop through the string using i as an index.
        !            33:           */
        !            34:          if (typ1 == Cvt) {
        !            35:             /*
        !            36:              * x was converted to a string, thus, the resulting string
        !            37:              * can't be modified and a trapped variable isn't needed.
        !            38:              * Make a one-character string out of the next character
        !            39:              * in x and suspend it.
        !            40:              */
        !            41:             strreq((word)1);
        !            42:             StrLen(Arg0) = 1;
        !            43:             StrLoc(Arg0) = alcstr(StrLoc(Arg1)+i-1, (word)1);
        !            44:             Suspend;
        !            45:             }
        !            46:          else {
        !            47:             /*
        !            48:              * x a string and thus a trapped variable must be made
        !            49:              * for the one character string being suspended.
        !            50:              */
        !            51:             blkreq((word)sizeof(struct b_tvsubs));
        !            52:             mksubs(&Arg2, &Arg1, i, (word)1, &Arg0);
        !            53:             Suspend;
        !            54:             Arg1 = Arg2;
        !            55:             DeRef(Arg1);
        !            56:             if (!Qual(Arg1))
        !            57:                runerr(103, &Arg1);
        !            58:             }
        !            59:          i++;
        !            60:          }
        !            61:       }
        !            62:    else {
        !            63:       /*
        !            64:        * x isn't a string.
        !            65:        */
        !            66:       switch (Type(Arg1)) {
        !            67:          case T_List:
        !            68:             /*
        !            69:              * x is a list.  Chain through each list element block and for
        !            70:              * each one, suspend with a variable pointing to each
        !            71:              * element contained in the block.
        !            72:              */
        !            73:             bp = BlkLoc(Arg1);
        !            74:             for (Arg1 = bp->list.listhead; Arg1.dword == D_Lelem;
        !            75:                Arg1 = BlkLoc(Arg1)->lelem.listnext) {
        !            76:                bp = BlkLoc(Arg1);
        !            77:                for (i = 0; i < bp->lelem.nused; i++) {
        !            78:                  j = bp->lelem.first + i;
        !            79:                  if (j >= bp->lelem.nelem)
        !            80:                     j -= bp->lelem.nelem;
        !            81:                  dp = &bp->lelem.lslots[j];
        !            82:                  Arg0.dword = D_Var + ((word *)dp - (word *)bp);
        !            83:                  VarLoc(Arg0) = dp;
        !            84:                  Suspend;
        !            85:                  bp = BlkLoc(Arg1);   /* bp is untended, must reset */
        !            86:                  }
        !            87:                }
        !            88:             break;
        !            89: 
        !            90: 
        !            91:          case T_File:
        !            92:             /*
        !            93:              * x is a file.  Read the next line into the string space
        !            94:              * and suspend the newly allocated string.
        !            95:              */
        !            96:             fd = BlkLoc(Arg1)->file.fd;
        !            97:             if ((BlkLoc(Arg1)->file.status & Fs_Read) == 0)
        !            98:                runerr(212, &Arg1);
        !            99:             while ((slen = getstr(sbuf,MaxCvtLen,fd)) >= 0) {
        !           100:                strreq(slen);
        !           101:                StrLen(Arg0) = slen;
        !           102:                StrLoc(Arg0) = alcstr(sbuf,slen);
        !           103:                Suspend;
        !           104:                }
        !           105:             break;
        !           106: 
        !           107:          case T_Table:
        !           108:             /*
        !           109:              * x is a table.  Chain down the element list in each bucket
        !           110:              * and suspend a variable pointing to each element in turn.
        !           111:              */
        !           112:             for (i = 0; i < TSlots; i++) {
        !           113:                bp = BlkLoc(Arg1);
        !           114:                for (Arg2 = bp->table.buckets[i]; Arg2.dword == D_Telem;
        !           115:                    Arg2 = BlkLoc(Arg2)->telem.clink) {
        !           116:                  ep = BlkLoc(Arg2);
        !           117:                  dp = &ep->telem.tval;
        !           118:                  Arg0.dword = D_Var + ((word *)dp - (word *)ep);
        !           119:                  VarLoc(Arg0) = dp;
        !           120:                  Suspend;
        !           121:                  bp = BlkLoc(Arg1);   /* bp is untended, must reset */
        !           122:                  }
        !           123:                }
        !           124:             break;
        !           125: 
        !           126:          case T_Set:
        !           127:            /*
        !           128:             *  This is similar to the method for tables except that a
        !           129:             *  value is returned instead of a variable.
        !           130:             */
        !           131:                for(i = 0; i < SSlots; i++) {
        !           132:                  bp = BlkLoc(Arg1);
        !           133:                  for(Arg2 = bp->set.sbucks[i]; Arg2.dword == D_Selem;
        !           134:                     Arg2 = BlkLoc(Arg2)->selem.clink) {
        !           135:                     Arg0 = BlkLoc(Arg2)->selem.setmem;
        !           136:                     Suspend;
        !           137:                  bp = BlkLoc(Arg1);    /* bp untended, must be reset */
        !           138:                    }
        !           139:                }
        !           140:                break;
        !           141: 
        !           142:          case T_Record:
        !           143:             /*
        !           144:              * x is a record.  Loop through the fields and suspend
        !           145:              * a variable pointing to each one.
        !           146:              */
        !           147:             bp = BlkLoc(Arg1);
        !           148:             j = BlkLoc(bp->record.recdesc)->proc.nfields;
        !           149:             for (i = 0; i < j; i++) {
        !           150:                dp = &bp->record.fields[i];
        !           151:                Arg0.dword = D_Var + ((word *)dp - (word *)bp);
        !           152:                VarLoc(Arg0) = dp;
        !           153:                Suspend;
        !           154:                bp = BlkLoc(Arg1);   /* bp is untended, must reset */
        !           155:                }
        !           156:             break;
        !           157: 
        !           158:          default: /* This object can not be compromised. */
        !           159:             runerr(116, &Arg1);
        !           160:          }
        !           161:       }
        !           162: 
        !           163:    /*
        !           164:     * Eventually fail.
        !           165:     */
        !           166:    Fail;
        !           167:    }
        !           168: 
        !           169: 
        !           170: /*
        !           171:  * x[i:j] - form a substring or list section of x.
        !           172:  */
        !           173: 
        !           174: OpDclV(sect,3,":")
        !           175:    {
        !           176:    register word i, j, t;
        !           177:    int typ1;
        !           178:    char sbuf[MaxCvtLen];
        !           179:    long l1, l2;
        !           180:    extern char *alcstr();
        !           181: 
        !           182:    blkreq((word)sizeof(struct b_tvsubs));       /* request space */
        !           183: 
        !           184:    if (cvint(&Arg2, &l1) == NULL)
        !           185:       runerr(101, &Arg2);
        !           186:    if (cvint(&Arg3, &l2) == NULL)
        !           187:       runerr(101, &Arg3);
        !           188: 
        !           189:    Arg4 = Arg1;
        !           190:    DeRef(Arg1);
        !           191: 
        !           192:    if (!Qual(Arg1) && Arg1.dword == D_List) {
        !           193:       i = cvpos(l1, BlkLoc(Arg1)->list.size);
        !           194:       if (i == 0)
        !           195:          Fail;
        !           196:       j = cvpos(l2, BlkLoc(Arg1)->list.size);
        !           197:       if (j == 0)
        !           198:          Fail;
        !           199:       if (i > j) {
        !           200:          t = i;
        !           201:          i = j;
        !           202:          j = t;
        !           203:          }
        !           204:       cplist(&Arg1, &Arg0, i, j);
        !           205:       Return;
        !           206:       }
        !           207: 
        !           208:    if ((typ1 = cvstr(&Arg1, sbuf)) == NULL)
        !           209:       runerr(110, &Arg1);
        !           210: 
        !           211:    i = cvpos(l1, StrLen(Arg1));
        !           212:    if (i == 0)
        !           213:       Fail;
        !           214:    j = cvpos(l2, StrLen(Arg1));
        !           215:    if (j == 0)
        !           216:       Fail;
        !           217:    if (i > j) {                        /* convert section to substring */
        !           218:       t = i;
        !           219:       i = j;
        !           220:       j = t - j;
        !           221:       }
        !           222:    else
        !           223:       j = j - i;
        !           224: 
        !           225:    if (typ1 == Cvt) {                  /* if string was created, */
        !           226:       strreq(j);                               /*   just return a string */
        !           227:       StrLen(Arg0) = j;
        !           228:       StrLoc(Arg0) = alcstr(StrLoc(Arg1)+i-1, j);
        !           229:       }
        !           230:    else                                /* else make a substring tv */
        !           231:       mksubs(&Arg4, &Arg1, i, j, &Arg0);
        !           232:    Return;
        !           233:    }
        !           234: 
        !           235: 
        !           236: /*
        !           237:  * x[y] - access yth character or element of x.
        !           238:  */
        !           239: 
        !           240: OpDclV(subsc,2,"[]")
        !           241:    {
        !           242:    register word i, j;
        !           243:    register union block *bp;
        !           244:    int typ1;
        !           245:    long l1;
        !           246:    struct descrip *dp;
        !           247:    char sbuf[MaxCvtLen];
        !           248:    extern char *alcstr();
        !           249:    extern struct b_tvtbl *alctvtbl();
        !           250: 
        !           251:    /*
        !           252:     * Make a copy of x.
        !           253:     */
        !           254:    Arg3 = Arg1;
        !           255: 
        !           256:    DeRef(Arg1);
        !           257:    if ((typ1 = cvstr(&Arg1, sbuf)) != NULL) {
        !           258:       /*
        !           259:        * x is a string, make sure that y is an integer.
        !           260:        */
        !           261:       if (cvint(&Arg2, &l1) == NULL)
        !           262:          runerr(101, &Arg2);
        !           263:       /*
        !           264:        * Convert y to a position in x and fail if the position is out
        !           265:        *  of bounds.
        !           266:        */
        !           267:       i = cvpos(l1, StrLen(Arg1));
        !           268:       if (i == 0 || i > StrLen(Arg1))
        !           269:          Fail;
        !           270:       if (typ1 == Cvt) {
        !           271:          /*
        !           272:           * x was converted to a string, so it can't be assigned back into.
        !           273:           *  Just return a string containing the selected character.
        !           274:           */
        !           275:          strreq((word)1);
        !           276:          StrLen(Arg0) = 1;
        !           277:          StrLoc(Arg0) = alcstr(StrLoc(Arg1)+i-1, (word)1);
        !           278:          }
        !           279:       else {
        !           280:          /*
        !           281:           * x is a string, make a substring trapped variable for the one
        !           282:           *  character substring selected and return it.
        !           283:           */
        !           284:          blkreq((word)sizeof(struct b_tvsubs));
        !           285:          mksubs(&Arg3, &Arg1, i, (word)1, &Arg0);
        !           286:          }
        !           287:       Return;
        !           288:       }
        !           289: 
        !           290:    /*
        !           291:     * x isn't a string or convertible to one, see if it's an aggregate.
        !           292:     */
        !           293:    DeRef(Arg1);
        !           294: /* >listref */
        !           295:    switch (Type(Arg1)) {
        !           296:       case T_List:
        !           297:          /*
        !           298:           * Make sure that Arg2 is an integer and that the
        !           299:           *  subscript is in range.
        !           300:           */
        !           301:          if (cvint(&Arg2, &l1) == NULL)
        !           302:             runerr(101, &Arg2);
        !           303:          i = cvpos(l1, BlkLoc(Arg1)->list.size);
        !           304:          if (i == 0 || i > BlkLoc(Arg1)->list.size)
        !           305:             Fail;
        !           306: 
        !           307:          /*
        !           308:           * Locate the list block containing the desired element.
        !           309:           */
        !           310:          bp = BlkLoc(BlkLoc(Arg1)->list.listhead);
        !           311:          j = 1;
        !           312:          while (i >= j + bp->lelem.nused) {
        !           313:             j += bp->lelem.nused;
        !           314:             if ((bp->lelem.listnext).dword != D_Lelem)
        !           315:                syserr("list reference out of bounds in subsc");
        !           316:             bp = BlkLoc(bp->lelem.listnext);
        !           317:             }
        !           318: 
        !           319:          /*
        !           320:           * Locate the desired element in the block that contains it
        !           321:           *  and return a pointer to it.
        !           322:           */
        !           323:          i += bp->lelem.first - j;
        !           324:          if (i >= bp->lelem.nelem)
        !           325:             i -= bp->lelem.nelem;
        !           326:          dp = &bp->lelem.lslots[i];
        !           327:          Arg0.dword = D_Var + ((int *)dp - (int *)bp);
        !           328:          VarLoc(Arg0) = dp;
        !           329:          Return;
        !           330: /* <listref */
        !           331: 
        !           332:       case T_Table:
        !           333:          /*
        !           334:           * x is a table.  Locate the appropriate bucket
        !           335:           *  based on the hash value.
        !           336:           */
        !           337:          blkreq((word)sizeof(struct b_tvtbl));
        !           338:          i = hash(&Arg2);              /* get hash number of subscript  */
        !           339:          bp = BlkLoc(BlkLoc(Arg1)->table.buckets[SlotNum(i,TSlots)]);
        !           340:          /*
        !           341:           * Work down the chain of elements for the bucket and if an
        !           342:           *  element with the desired subscript value is found, return
        !           343:           *  a pointer to it.
        !           344:           * Elements are ordered in the chain by hash number value
        !           345:           * from smallest to largest.
        !           346:           */
        !           347:          while (bp != NULL) {
        !           348:            if (bp->telem.hashnum > i)          /* past it - not there */
        !           349:                break;
        !           350:             if ((bp->telem.hashnum == i)  &&  (equiv(&bp->telem.tref, &Arg2))) {
        !           351:                dp = &bp->telem.tval;
        !           352:                Arg0.dword = D_Var + ((word *)dp - (word *)bp);
        !           353:                VarLoc(Arg0) = dp;
        !           354:                Return;
        !           355:                }
        !           356:             /* We haven't reached the right hash number yet or
        !           357:              * the element is not the right one.
        !           358:              */
        !           359:             bp = BlkLoc(bp->telem.clink);
        !           360:             }
        !           361:            /*
        !           362:             * x[y] is not in the table, make a table element trapped variable
        !           363:             *  and return it as the result.
        !           364:             */
        !           365:          Arg0.dword = D_Tvtbl;
        !           366:          BlkLoc(Arg0) = (union block *) alctvtbl(&Arg1, &Arg2, i);
        !           367:          Return;
        !           368: 
        !           369:       case T_Record:
        !           370:          /*
        !           371:           * x is a record.  Convert y to an integer and be sure that it
        !           372:           *  it is in range as a field number.
        !           373:           */
        !           374:          if (cvint(&Arg2, &l1) == NULL)
        !           375:             runerr(101, &Arg2);
        !           376:          bp = BlkLoc(Arg1);
        !           377:          i = cvpos(l1, (word)(BlkLoc(bp->record.recdesc)->proc.nfields));
        !           378:          if (i == 0 || i > BlkLoc(bp->record.recdesc)->proc.nfields)
        !           379:             Fail;
        !           380:          /*
        !           381:           * Locate the appropriate field and return a pointer to it.
        !           382:           */
        !           383:          dp = &bp->record.fields[i-1];
        !           384:            Arg0.dword = D_Var + ((word *)dp - (word *)bp);
        !           385:          VarLoc(Arg0) = dp;
        !           386:          Return;
        !           387: 
        !           388:       default:
        !           389:          /*
        !           390:           * x is of a type that can't be subscripted.
        !           391:           */
        !           392:          runerr(114, &Arg1);
        !           393:       }
        !           394:    Return;
        !           395:    }

unix.superglobalmegacorp.com

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