1: # include   <ingres.h>
   2: # include   <aux.h>
   3: # include   <symbol.h>
   4: # include   <tree.h>
   5: # include   <access.h>
   6: # include   "../decomp/globs.h"
   7: # include   <sccs.h>
   8: # include   <errors.h>
   9: 
  10: SCCSID(@(#)interp.c	8.4	2/8/85)
  11: 
  12: 
  13: 
  14: /*
  15: **
  16: ** INTERPRET
  17: **
  18: **	 Processes the retrieved tuple from the De.ov_source relation
  19: **	 according to the symbols in the list.  Recognition
  20: **	 of characteristic delimiters and separators initiates
  21: **	 action appropriate to a target list or qualification list
  22: **	 as the case may be.
  23: **
  24: **	 Between delimiters, the symbol list is expected to be in
  25: **	 Polish postfix form.  A qualification list is further
  26: **	 expected to be in conjunctive normal form, with Boolean
  27: **	 operators infixed.
  28: **
  29: */
  30: 
  31: 
  32: double  pow();
  33: double  sqrt();
  34: double  log();
  35: double  exp();
  36: double  sin();
  37: double  cos();
  38: double  atan();
  39: 
  40: # define SPUSH(v)   (++((struct stacksym *) v))
  41: # define SPOP(v)    (((struct stacksym *) v)--)
  42: 
  43: SYMBOL *
  44: interpret(istlist,list)
  45: int     istlist; /* signals a target list: used for string substitution */
  46: SYMBOL  **list; /* ptr to list of sym pointers */
  47: {
  48:     register SYMBOL     *tos;
  49:     SYMBOL          *op1,*op2;  /*operands popped off stack*/
  50:     register ANYTYPE    *val1,*val2;    /*ptrs to values of operands*/
  51:     int         opval, optype, l1;
  52:     char            *s1;
  53:     int         byflag;
  54:     long            hitid;
  55:     extern char     *Usercode;
  56:     extern          ov_err();
  57:     int         cb_mark;
  58:     extern char     *ov_ovqpbuf;
  59:     extern char     *locv();
  60:     int         i;
  61: 
  62: #	ifdef xOTR1
  63:     if (tTf(72, 0))
  64:     {
  65:         printf("INTERP:  list=%x\n",list);
  66:         printf("         istlist = %d\n", istlist);
  67:     }
  68: #	endif
  69: 
  70: 
  71:     byflag = (list == De.ov_bylist);    /* set byflag if aggregate function */
  72:     tos = (SYMBOL *)(De.ov_stack-1);
  73:     /* reset the concat and ascii operator buffer */
  74:     seterr(De.ov_ovqpbuf, CBUFULL, ov_err);
  75:     cb_mark = markbuf(De.ov_ovqpbuf);
  76: 
  77: loop:
  78: #	ifdef xOTR1
  79:     if (tTf(72, 1) && tos >= (SYMBOL *) De.ov_stack)
  80:     {
  81:         printf("\ttops of stack=");
  82:         prstack(tos);   /* print top of stack element */
  83:     }
  84: #	endif
  85:     /* check for stack overflow */
  86:     l1 = getsymbol(SPUSH(tos), &list);  /* getsymbol changes the value of list */
  87: 
  88:     if (l1)
  89:     {
  90: 
  91:         freebuf(De.ov_ovqpbuf, cb_mark);
  92:         return (tos);
  93:     }
  94:     optype = tos->type;
  95:     opval = tos->value.sym_data.i2type;
  96:     op1 = tos;
  97:     SPOP(tos);      /* assume that stack will be popped */
  98: 
  99:     switch(optype)
 100:     {
 101:       case CHAR:
 102:                     /* do any chars have to be inserted? */
 103:         if (istlist && (Patnum || Globnum))
 104:         {
 105:             insert_chars(op1);
 106:         }
 107:       case INT:
 108:       case FLOAT:
 109:         SPUSH(tos);     /* just leave symbol on stack */
 110:         goto loop;
 111: 
 112:       case COP:
 113:         SPUSH(tos);     /* new symbol goes on stack */
 114:         tos->type = CHAR;
 115:         switch (opval)
 116:         {
 117: 
 118:           case opDBA:
 119:             tos->value.sym_data.cptype = Admin.adhdr.adowner;
 120:             tos->len = 2;
 121:             goto loop;
 122: 
 123:           case opUSERCODE:
 124:             tos->value.sym_data.cptype = Usercode;
 125:             tos->len = 2;
 126:             goto loop;
 127:         }
 128: 
 129:       case AND:     /* if top value false return immediately */
 130:         if (!tos->value.sym_data.i2type)
 131:         {
 132:             freebuf(De.ov_ovqpbuf, cb_mark);
 133:             return(tos);
 134:         }
 135:         else
 136:             SPOP(tos);
 137:         freebuf(De.ov_ovqpbuf, cb_mark);
 138:         goto loop;
 139: 
 140:       case OR:      /* if top value is true then skip to
 141: 				** end of disjunction. */
 142:         if (tos->value.sym_data.i2type)
 143:         {
 144:             SPUSH(tos);
 145:             do
 146:             {
 147:                 getsymbol(tos, &list);  /* getsymbol changes the value of list */
 148:             } while (tos->type != AND);
 149:             optype = AND;
 150:             SPOP(tos);
 151:         }
 152:         SPOP(tos);
 153:         goto loop;
 154: 
 155:       case RESDOM:
 156:         freebuf(De.ov_ovqpbuf, cb_mark); /* init the concat and ascii buffer */
 157:         if (De.ov_result)
 158:         {
 159:             if (opval)  /* if gt zero then opval represents a real domain */
 160:             {
 161:                 if (byflag)
 162:                     opval++;    /* skip over count field for ag functs */
 163:                 rcvt(tos, De.ov_result->relfrmt[opval], De.ov_result->relfrml[opval]);
 164:                 tout(tos, De.ov_outtup+De.ov_result->reloff[opval], De.ov_result->relfrml[opval]);
 165:             }
 166:             else    /* opval refers to the tid and this is an update */
 167:             {
 168:                 De.ov_uptid = tos->value.sym_data.i4type;   /* copy tid */
 169:                 if (De.de_qmode == mdREPL || (De.ov_diffrel && De.de_qmode == mdDEL && De.ov_result->reldum.relindxd > 0 ))
 170:                 {
 171:                     /* De.ov_origtup must be left with the orig
 172: 					** unaltered tuple, and De.ov_outtup must
 173: 					** be initialized with the orig tuple.
 174: 					**
 175: 					** De.ov_outtup only matters with REPL.
 176: 					** Scan() sets up De.ov_origtup so when
 177: 					** De.ov_source == De.ov_result, origtup is already
 178: 					** correct.
 179: 					*/
 180: 
 181:                     if (De.ov_diffrel)
 182:                     {
 183:                         if (l1 = get(De.ov_result, &De.ov_uptid, &hitid, De.ov_origtup, CURTUP))
 184:                             syserr("interp:get on resdom %s, %d", locv(De.ov_uptid), l1);
 185:                         bmove(De.ov_origtup, De.ov_outtup, De.ov_result->reldum.relwid);
 186:                     }
 187:                     else
 188:                     {
 189:                         bmove(De.ov_intup, De.ov_outtup, De.ov_result->reldum.relwid);
 190:                     }
 191:                 }
 192:             }
 193:         }
 194:         else
 195:         {
 196:             /*
 197: 			** This is really here for the 68k machines,
 198: 			** this works on the VAX, but nowhere else...
 199: 			*/
 200:             if ( tos->type == INT && tos->len == 1)
 201:                 tos->value.sym_data.i1type = tos->value.sym_data.i2type;
 202:             if (Equel)
 203:                 equelatt(tos);  /* send attribute to equel */
 204:             else
 205:             {
 206:                 if (tos->type == CHAR)
 207:                     s1 = tos->value.sym_data.cptype;
 208:                 else
 209:                     s1 = tos->value.sym_data.c0type;
 210:                 printatt(tos->type, tos->len & I1MASK, s1); /* print attribute */
 211:             }
 212:         }
 213:         SPOP(tos);
 214:         goto loop;
 215: 
 216: 
 217:       case BOP:
 218:         op2 = (SYMBOL *)SPOP(tos);
 219:         op1 = (SYMBOL *)tos;
 220:         typecheck(op1, op2, opval);
 221:         val1 = &op1->value.sym_data;
 222:         val2 = &op2->value.sym_data;
 223: 
 224:         switch (tos->type)
 225:         {
 226:           case INT:
 227:             switch (tos->len)
 228:             {
 229:               case 1:
 230:               case 2:
 231:                 switch (opval)
 232:                 {
 233:                   case opADD:
 234:                     val1->i2type += val2->i2type;
 235:                     goto loop;
 236: 
 237:                   case opSUB:
 238:                     val1->i2type -= val2->i2type;
 239:                     goto loop;
 240: 
 241:                   case opMUL:
 242:                     val1->i2type *= val2->i2type;
 243:                     goto loop;
 244: 
 245:                   case opDIV:
 246:                     val1->i2type /= val2->i2type;
 247:                     goto loop;
 248: 
 249:                   case opMOD:
 250:                     val1->i2type %= val2->i2type;
 251:                     goto loop;
 252: 
 253:                   case opPOW:
 254:                     itof(op1);
 255:                     itof(op2);
 256:                     val1->f8type = pow(val1->f8type, val2->f8type);
 257:                     goto loop;
 258: 
 259:                   /* relational operator */
 260:                   default:
 261:                     l1 = val1->i2type - val2->i2type;
 262:                     val1->i2type = relop_interp(opval, l1);
 263:                     goto loop;
 264:                 }
 265: 
 266:               case 4:
 267:                 switch(opval)
 268:                 {
 269:                   case opADD:
 270:                     val1->i4type += val2->i4type;
 271:                     goto loop;
 272: 
 273:                   case opSUB:
 274:                     val1->i4type -= val2->i4type;
 275:                     goto loop;
 276: 
 277:                   case opMUL:
 278:                     val1->i4type *= val2->i4type;
 279:                     goto loop;
 280: 
 281:                   case opDIV:
 282:                     val1->i4type /= val2->i4type;
 283:                     goto loop;
 284: 
 285:                   case opMOD:
 286:                     val1->i4type %= val2->i4type;
 287:                     goto loop;
 288: 
 289:                   case opPOW:
 290:                     itof(op1);
 291:                     itof(op2);
 292:                     val1->f8type = pow(val1->f8type, val2->f8type);
 293:                     goto loop;
 294: 
 295:                   /* relational operator */
 296:                   default:
 297:                     tos->len = 2;
 298:                     if (val1->i4type > val2->i4type)
 299:                         l1 = 1;
 300:                     else
 301:                         if (val1->i4type == val2->i4type)
 302:                             l1 = 0;
 303:                         else
 304:                             l1 = -1;
 305: 
 306:                     val1->i2type = relop_interp(opval, l1);
 307:                     goto loop;
 308: 
 309:                 }
 310:             }
 311: 
 312:           case FLOAT:
 313:             switch (opval)
 314:             {
 315:               case opADD:
 316:                 val1->f8type += val2->f8type;
 317:                 goto loop;
 318: 
 319:               case opSUB:
 320:                 val1->f8type -= val2->f8type;
 321:                 goto loop;
 322: 
 323:               case opMUL:
 324:                 val1->f8type *= val2->f8type;
 325:                 goto loop;
 326: 
 327:               case opDIV:
 328:                 val1->f8type /= val2->f8type;
 329:                 goto loop;
 330: 
 331:               case opPOW:
 332:                 val1->f8type = pow(val1->f8type, val2->f8type);
 333:                 goto loop;
 334: 
 335:               default:
 336:                 tos->type = INT;
 337:                 tos->len = 2;
 338:                 if (val1->f8type > val2->f8type)
 339:                     l1 = 1;
 340:                 else
 341:                     if (val1->f8type == val2->f8type)
 342:                         l1 = 0;
 343:                     else
 344:                         l1 = -1;
 345:                 val1->i2type = relop_interp(opval, l1);
 346:                 goto loop;
 347:             }
 348: 
 349:         case CHAR:
 350:             switch (opval)
 351:             {
 352:                 case opSUB:
 353:                     newstring(op1, op2);
 354:                     goto loop;
 355:                 case opADD:
 356:                 case opCONCAT:
 357:                     concatsym(op1, op2);    /* concatenate the two symbols */
 358:                     goto loop;
 359:                 default:
 360:                     l1 = lexcomp(val1->cptype, size(op1), val2->cptype, op2->len & I1MASK,0);
 361:                     tos->type = INT;
 362:                     tos->len = 2;
 363:                     val1->i2type = relop_interp(opval, l1);
 364:                     goto loop;
 365:             }
 366:         }   /* end of BOP */
 367: 
 368:        case UOP:
 369:         val1 = &tos->value.sym_data;
 370:         switch (opval)
 371:         {
 372:            case opMINUS:
 373:            case opABS:
 374:             if (tos->type == CHAR)
 375:                 ov_err(BADUOPC);
 376:             l1 = opval == opMINUS;
 377:             switch (tos->type)
 378:             {
 379:                case INT:
 380:                 switch (tos->len)
 381:                 {
 382:                   case 1:
 383:                   case 2:
 384:                     if (l1 || val1->i2type < 0)
 385:                         val1->i2type = -val1->i2type;
 386:                     goto loop;
 387: 
 388:                   case 4:
 389:                     if (l1 || val1->i4type < 0)
 390:                         val1->i4type = -val1->i4type;
 391:                     goto loop;
 392:                 }
 393: 
 394:               case FLOAT:
 395:                 if (l1 || val1->f8type < 0.0)
 396:                     val1->f8type = -val1->f8type;
 397:                 goto loop;
 398:             }
 399: 
 400:           case opNOT:
 401:             val1->i2type = !val1->i2type;
 402:           case opPLUS:
 403:             if (tos->type == CHAR)
 404:                 ov_err(BADUOPC);
 405:             goto loop;
 406: 
 407:           case opASCII:
 408:             ascii(tos);
 409:             goto loop;
 410: 
 411:           case opINT1:
 412:             typecoerce(tos, INT, 1);
 413:             goto loop;
 414: 
 415:           case opINT2:
 416:             typecoerce(tos, INT, 2);
 417:             goto loop;
 418: 
 419:           case opINT4:
 420:             typecoerce(tos, INT, 4);
 421:             goto loop;
 422: 
 423:           case opFLOAT4:
 424:             typecoerce(tos, FLOAT, 4);
 425:             goto loop;
 426: 
 427:           case opFLOAT8:
 428:             typecoerce(tos, FLOAT, 8);
 429:             goto loop;
 430: 
 431:           default:
 432:             if (tos->type == CHAR)
 433:                 ov_err(BADUOPC);
 434:             if (tos->type == INT)
 435:                 itof(tos);
 436:             switch (opval)
 437:             {
 438:               case opATAN:
 439:                 val1->f8type = atan(val1->f8type);
 440:                 goto loop;
 441: 
 442:               case opLOG:
 443:                 val1->f8type = log(val1->f8type);
 444:                 goto loop;
 445: 
 446:               case opSIN:
 447:                 val1->f8type = sin(val1->f8type);
 448:                 goto loop;
 449: 
 450:               case opCOS:
 451:                 val1->f8type = cos(val1->f8type);
 452:                 goto loop;
 453: 
 454:               case opSQRT:
 455:                 val1->f8type = sqrt(val1->f8type);
 456:                 goto loop;
 457: 
 458:               case opEXP:
 459:                 val1->f8type = exp(val1->f8type);
 460:                 goto loop;
 461: 
 462:               default:
 463:                 syserr("interp:bad uop %d",opval);
 464:             }
 465:         }
 466: 
 467: 
 468:        case AOP:
 469:         aop_interp(opval, tos);
 470:         SPOP(tos);      /* pop this symbol */
 471:         goto loop;
 472: 
 473:     }
 474:     syserr("interp: fell out");
 475:     /*NOTREACHED*/
 476: }
 477: /*
 478: **	relop_interp interprets the relational operators
 479: **	(ie. EQ, NE etc.) and returns true or false
 480: **	by evaluating l1.
 481: **
 482: **	l1 should be greater than, equal or less than zero.
 483: */
 484: 
 485: relop_interp(opval, l1)
 486: int opval;
 487: int l1;
 488: {
 489:     register int    i;
 490: 
 491:     i = l1;
 492: 
 493:     switch (opval)
 494:     {
 495: 
 496:       case opEQ:
 497:         return (i == 0);
 498: 
 499:       case opNE:
 500:         return (i != 0);
 501: 
 502:       case opLT:
 503:         return (i < 0);
 504: 
 505:       case opLE:
 506:         return (i <= 0);
 507: 
 508:       case opGT:
 509:         return (i > 0);
 510: 
 511:       case opGE:
 512:         return (i >= 0);
 513: 
 514:       default:
 515:         syserr("relop:bad relop or bop %d", opval);
 516:     }
 517:     /*NOTREACHED*/
 518: }
 519: /*
 520: **	Aggregate values are stored in De.ov_outtup. De.ov_tend points
 521: **	to the spot for the next aggregate. Aop_interp()
 522: **	computes the value for the aggregate and leaves
 523: **	the result in the position pointed to by De.ov_tend.
 524: */
 525: 
 526: aop_interp(opval, tos)
 527: int     opval;
 528: register SYMBOL *tos;
 529: {
 530:     register int    i;
 531:     int     l1;
 532:     ANYTYPE     numb;   /* used for type conversion */
 533: 
 534:     bmove(De.ov_tend, (char *) &numb, 8);   /* note: this assumes that there are always 8 bytes which can be moved.
 535: 				** if it moves beyond De.ov_tend, it's ok */
 536:     switch (opval)
 537:     {
 538: 
 539:       case opSUMU:
 540:       case opSUM:
 541:         if (*De.ov_counter <= 1)
 542:             goto puta;
 543:         switch (tos->type)
 544:         {
 545:           case INT:
 546:             switch(tos->len)
 547:             {
 548:               case 1:
 549:                 tos->value.sym_data.i2type += numb.i1type;
 550:                 goto puta;
 551: 
 552:               case 2:
 553:                 tos->value.sym_data.i2type += numb.i2type;
 554:                 goto puta;
 555: 
 556:               case 4:
 557:                 tos->value.sym_data.i4type += numb.i4type;
 558:                 goto puta;
 559:             }
 560: 
 561:           case FLOAT:
 562:             if (tos->len == 4)
 563:                 numb.f8type = numb.f4type;
 564:             tos->value.sym_data.f8type += numb.f8type;
 565:             goto puta;
 566: 
 567:           default:
 568:             ov_err(BADSUMC);    /* cant sum char fields */
 569:         }
 570: 
 571:       case opCOUNTU:
 572:       case opCOUNT:
 573:         tos->type = CNTTYPE;
 574:         tos->len = CNTLEN;
 575:         tos->value.sym_data.i4type = *De.ov_counter;
 576:         goto puta;
 577: 
 578:       case opANY:
 579:         tos->type = OANYTYPE;
 580:         tos->len = OANYLEN;
 581:         if (*De.ov_counter)
 582:         {
 583:             tos->value.sym_data.i2type = 1;
 584:             if (!De.ov_bylist && (De.ov_agcount == 1))
 585:                 De.ov_targvc = 0;   /* if simple agg. stop scan */
 586:         }
 587:         else
 588:             tos->value.sym_data.i2type = 0;
 589:         goto puta;
 590: 
 591:       case opMIN:
 592:       case opMAX:
 593:         if (*De.ov_counter<=1)
 594:             goto puta;
 595:         switch (tos->type)
 596:         {
 597:           case INT:
 598:             switch (tos->len)
 599:             {
 600:               case 1:
 601:                 i = (tos->value.sym_data.i1type < numb.i1type);
 602:                 break;
 603: 
 604:               case 2:
 605:                 i = (tos->value.sym_data.i2type < numb.i2type);
 606:                 break;
 607: 
 608:               case 4:
 609:                 i = (tos->value.sym_data.i4type < numb.i4type);
 610:                 break;
 611:             }
 612:             break;
 613: 
 614:           case FLOAT:
 615:             if (tos->len == 4)
 616:                 numb.f8type = numb.f4type;
 617:             i = (tos->value.sym_data.f8type < numb.f8type);
 618:             break;
 619: 
 620:           case CHAR:
 621:             l1 = size(tos);
 622:             i = (lexcomp(tos->value.sym_data.cptype, l1, De.ov_tend, l1,0) < 0);
 623:             break;
 624: 
 625:           default:
 626:             syserr("interp:bad op type for opMIN/MAX %d", tos->type);
 627:         }
 628: 
 629:         /* check result of comparison */
 630:         if (opval == opMAX)
 631:             i = !i; /* complement test for opMAX */
 632:         if (i)
 633:             goto puta;  /* condition true. new value */
 634: 
 635:         /* condition false. Keep old value */
 636:         goto done;
 637: 
 638: 
 639:       case opAVGU:
 640:       case opAVG:
 641:         if (tos->type == INT)
 642:             itof(tos);
 643:         else
 644:             if (tos->type == CHAR)
 645:                 ov_err(BADAVG);
 646:         if (*De.ov_counter > 1)
 647:         {
 648:             tos->value.sym_data.f8type = numb.f8type + (tos->value.sym_data.f8type - numb.f8type) / *De.ov_counter;
 649:         }
 650:         tos->len = 8;
 651:         goto puta;
 652: 
 653:       default:
 654:         syserr("interp:bad agg op %d", tos->type);
 655:     }
 656: 
 657: puta:
 658:     tout(tos, De.ov_tend, tos->len);
 659: done:
 660:     De.ov_tend += tos->len & I1MASK;
 661: }

Defined functions

aop_interp defined in line 526; used 1 times
interpret defined in line 43; used 7 times
relop_interp defined in line 485; used 4 times

Defined macros

SPOP defined in line 41; used 7 times
SPUSH defined in line 40; used 4 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1488
Valid CSS Valid XHTML 1.0 Strict