|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.