|
|
1.1 ! root 1: /* ! 2: * This file contains the mini ! 3: * constant expression folder used by the ! 4: * parser. More of this is done in the ! 5: * code generator. This one exists only to ! 6: * allow constant expressions in case labels ! 7: * and in array bounds. ! 8: */ ! 9: #ifdef vax ! 10: #include "INC$LIB:cc0.h" ! 11: #else ! 12: #include "cc0.h" ! 13: #endif ! 14: ! 15: /* ! 16: * Try to fold. ! 17: * Return pointer to a constant tree ! 18: * node, or NULL if folding is impossible. ! 19: */ ! 20: TREE * ! 21: fold0(op, lp, rp) ! 22: TREE *lp, *rp; ! 23: { ! 24: register TREE *tp; ! 25: register lrf, zrf, sop; ! 26: lval_t c1, c2, grablval(); ! 27: ! 28: lrf = zrf = 0; ! 29: sop = lp->t_op; ! 30: if (sop == LCON) ! 31: ++lrf; ! 32: else if (sop == ZCON) ! 33: ++zrf; ! 34: else if (sop != ICON || lp->t_dp != NULL) ! 35: return NULL; ! 36: c1 = grablval(lp); ! 37: if (op == QUEST) { ! 38: if (rp->t_op != COLON) ! 39: return (NULL); ! 40: return (c1 ? rp->t_lp : rp->t_rp); ! 41: } ! 42: if (rp != NULL) { ! 43: sop = rp->t_op; ! 44: if (sop == LCON) ! 45: ++lrf; ! 46: else if (sop == ZCON) ! 47: ++zrf; ! 48: else if (sop != ICON || rp->t_dp != NULL) ! 49: return NULL; ! 50: c2 = grablval(rp); ! 51: } ! 52: switch (op) { ! 53: ! 54: case COM: ! 55: c1 = ~c1; ! 56: break; ! 57: ! 58: case NOT: ! 59: c1 = !c1; ! 60: break; ! 61: ! 62: case NEG: ! 63: c1 = -c1; ! 64: break; ! 65: ! 66: case ADD: ! 67: c1 += c2; ! 68: break; ! 69: ! 70: case SUB: ! 71: c1 -= c2; ! 72: break; ! 73: ! 74: case MUL: ! 75: c1 *= c2; ! 76: break; ! 77: ! 78: case DIV: ! 79: if (c2 == 0) { ! 80: cwarn("divide by zero"); ! 81: return (NULL); ! 82: } ! 83: c1 /= c2; ! 84: break; ! 85: ! 86: case REM: ! 87: if (c2 == 0) { ! 88: cwarn("zero modulus"); ! 89: return (NULL); ! 90: } ! 91: c1 %= c2; ! 92: break; ! 93: ! 94: case AND: ! 95: c1 &= c2; ! 96: break; ! 97: ! 98: case OR: ! 99: c1 |= c2; ! 100: break; ! 101: ! 102: case XOR: ! 103: c1 ^= c2; ! 104: break; ! 105: ! 106: case SHL: ! 107: c1 <<= c2; ! 108: break; ! 109: ! 110: case SHR: ! 111: c1 >>= c2; ! 112: break; ! 113: ! 114: case EQ: ! 115: c1 = c1==c2; ! 116: break; ! 117: ! 118: case NE: ! 119: c1 = c1!=c2; ! 120: break; ! 121: ! 122: case LT: ! 123: c1 = c1<c2; ! 124: break; ! 125: ! 126: case LE: ! 127: c1 = c1<=c2; ! 128: break; ! 129: ! 130: case GT: ! 131: c1 = c1>c2; ! 132: break; ! 133: ! 134: case GE: ! 135: c1 = c1>=c2; ! 136: break; ! 137: ! 138: case ANDAND: ! 139: c1 = (c1 && c2); ! 140: lrf = 0; ! 141: break; ! 142: ! 143: case OROR: ! 144: c1 = (c1 || c2); ! 145: lrf = 0; ! 146: break; ! 147: ! 148: default: ! 149: return (NULL); ! 150: } ! 151: tp = talloc(); ! 152: if (lrf) { ! 153: tp->t_op = LCON; ! 154: tp->t_type = T_LONG; ! 155: tp->t_lval = c1; ! 156: return (tp); ! 157: } ! 158: if (zrf) { ! 159: tp->t_op = ZCON; ! 160: tp->t_type = T_UINT; ! 161: tp->t_lval = c1; ! 162: return (tp); ! 163: } ! 164: tp->t_op = ICON; ! 165: tp->t_type = T_INT; ! 166: tp->t_ival = c1; ! 167: return (tp); ! 168: } ! 169: ! 170: /* ! 171: * Grab the value of a ! 172: * constant (ICON or LCON) node. ! 173: * Look at the type of the node if ICON ! 174: * and 0 extend if necessary. ! 175: */ ! 176: lval_t ! 177: grablval(tp) ! 178: register TREE *tp; ! 179: { ! 180: register op, t; ! 181: ! 182: if ((op=tp->t_op) == ICON) { ! 183: if (tp->t_dp != NULL ! 184: || (t=tp->t_type) == T_UCHAR ! 185: || t == T_USHORT ! 186: || t == T_UINT) ! 187: return ((unsigned) tp->t_ival); ! 188: return (tp->t_ival); ! 189: } ! 190: if (op == ZCON) ! 191: return (tp->t_zval); ! 192: if (op == LCON) ! 193: return (tp->t_lval); ! 194: cbotch("grablval"); ! 195: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.