|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: static char sccsid[] = "@(#)parser4.c 3.6 (Berkeley) 6/29/88"; ! 20: #endif /* not lint */ ! 21: ! 22: #include "parser.h" ! 23: ! 24: /* ! 25: * | 3 ! 26: * ^ 4 ! 27: * & 5 ! 28: * == != 6 ! 29: * < <= > >= 7 ! 30: * << >> 8 ! 31: * + - 9 ! 32: * * / % 10 ! 33: */ ! 34: p_expr3_10(level, v, flag) ! 35: register struct value *v; ! 36: char flag; ! 37: { ! 38: struct value l, r; ! 39: int op; ! 40: char *opname; ! 41: ! 42: if ((level == 10 ? p_expr11(v, flag) ! 43: : p_expr3_10(level + 1, v, flag)) < 0) ! 44: return -1; ! 45: for (;;) { ! 46: switch (level) { ! 47: case 3: ! 48: if (token != T_OR) ! 49: return 0; ! 50: opname = "|"; ! 51: break; ! 52: case 4: ! 53: if (token != T_XOR) ! 54: return 0; ! 55: opname = "^"; ! 56: break; ! 57: case 5: ! 58: if (token != T_AND) ! 59: return 0; ! 60: opname = "&"; ! 61: break; ! 62: case 6: ! 63: if (token == T_EQ) ! 64: opname = "=="; ! 65: else if (token == T_NE) ! 66: opname = "!="; ! 67: else ! 68: return 0; ! 69: break; ! 70: case 7: ! 71: switch (token) { ! 72: case T_LT: ! 73: opname = "<"; ! 74: break; ! 75: case T_LE: ! 76: opname = "<="; ! 77: break; ! 78: case T_GT: ! 79: opname = ">"; ! 80: break; ! 81: case T_GE: ! 82: opname = ">="; ! 83: break; ! 84: default: ! 85: return 0; ! 86: } ! 87: break; ! 88: case 8: ! 89: if (token == T_LS) ! 90: opname = "<<"; ! 91: else if (token == T_RS) ! 92: opname = ">>"; ! 93: else ! 94: return 0; ! 95: break; ! 96: case 9: ! 97: if (token == T_PLUS) ! 98: opname = "+"; ! 99: else if (token == T_MINUS) ! 100: opname = "-"; ! 101: else ! 102: return 0; ! 103: break; ! 104: case 10: ! 105: switch (token) { ! 106: case T_MUL: ! 107: opname = "*"; ! 108: break; ! 109: case T_DIV: ! 110: opname = "/"; ! 111: break; ! 112: case T_MOD: ! 113: opname = "%"; ! 114: break; ! 115: default: ! 116: return 0; ! 117: } ! 118: break; ! 119: } ! 120: l = *v; ! 121: if (l.v_type == V_ERR) ! 122: flag = 0; ! 123: ! 124: op = token; ! 125: (void) s_gettok(); ! 126: if ((level == 10 ? p_expr11(&r, flag) ! 127: : p_expr3_10(level + 1, &r, flag)) < 0) { ! 128: p_synerror(); ! 129: val_free(l); ! 130: return -1; ! 131: } ! 132: ! 133: if (r.v_type == V_ERR) ! 134: flag = 0; ! 135: else switch (op) { ! 136: case T_EQ: ! 137: case T_NE: ! 138: case T_LT: ! 139: case T_LE: ! 140: case T_GT: ! 141: case T_GE: ! 142: case T_PLUS: ! 143: if (l.v_type == V_STR) { ! 144: if (r.v_type == V_NUM) ! 145: if (p_convstr(&r) < 0) ! 146: flag = 0; ! 147: } else ! 148: if (r.v_type == V_STR) ! 149: if (p_convstr(&l) < 0) ! 150: flag = 0; ! 151: break; ! 152: case T_LS: ! 153: case T_RS: ! 154: if (r.v_type == V_STR) { ! 155: char *p = r.v_str; ! 156: r.v_type = V_NUM; ! 157: r.v_num = strlen(p); ! 158: str_free(p); ! 159: } ! 160: break; ! 161: case T_OR: ! 162: case T_XOR: ! 163: case T_AND: ! 164: case T_MINUS: ! 165: case T_MUL: ! 166: case T_DIV: ! 167: case T_MOD: ! 168: default: ! 169: if (l.v_type == V_STR || r.v_type == V_STR) { ! 170: p_error("%s: Numeric operands required.", ! 171: opname); ! 172: flag = 0; ! 173: } ! 174: } ! 175: if (!flag) { ! 176: val_free(l); ! 177: val_free(r); ! 178: v->v_type = V_ERR; ! 179: if (p_abort()) ! 180: return -1; ! 181: continue; ! 182: } ! 183: ! 184: v->v_type = V_NUM; ! 185: switch (op) { ! 186: case T_EQ: ! 187: case T_NE: ! 188: case T_LT: ! 189: case T_LE: ! 190: case T_GT: ! 191: case T_GE: ! 192: if (l.v_type == V_STR) { ! 193: int tmp = strcmp(l.v_str, r.v_str); ! 194: str_free(l.v_str); ! 195: str_free(r.v_str); ! 196: l.v_type = V_NUM; ! 197: l.v_num = tmp; ! 198: r.v_type = V_NUM; ! 199: r.v_num = 0; ! 200: } ! 201: break; ! 202: } ! 203: switch (op) { ! 204: case T_OR: ! 205: v->v_num = l.v_num | r.v_num; ! 206: break; ! 207: case T_XOR: ! 208: v->v_num = l.v_num ^ r.v_num; ! 209: break; ! 210: case T_AND: ! 211: v->v_num = l.v_num & r.v_num; ! 212: break; ! 213: case T_EQ: ! 214: v->v_num = l.v_num == r.v_num; ! 215: break; ! 216: case T_NE: ! 217: v->v_num = l.v_num != r.v_num; ! 218: break; ! 219: case T_LT: ! 220: v->v_num = l.v_num < r.v_num; ! 221: break; ! 222: case T_LE: ! 223: v->v_num = l.v_num <= r.v_num; ! 224: break; ! 225: case T_GT: ! 226: v->v_num = l.v_num > r.v_num; ! 227: break; ! 228: case T_GE: ! 229: v->v_num = l.v_num >= r.v_num; ! 230: break; ! 231: case T_LS: ! 232: if (l.v_type == V_STR) { ! 233: int i; ! 234: if ((i = strlen(l.v_str)) > r.v_num) ! 235: i = r.v_num; ! 236: v->v_str = str_ncpy(l.v_str, i); ! 237: v->v_type = V_STR; ! 238: } else ! 239: v->v_num = l.v_num << r.v_num; ! 240: break; ! 241: case T_RS: ! 242: if (l.v_type == V_STR) { ! 243: int i; ! 244: if ((i = strlen(l.v_str)) > r.v_num) ! 245: i -= r.v_num; ! 246: else ! 247: i = 0; ! 248: v->v_str = str_cpy(l.v_str + i); ! 249: v->v_type = V_STR; ! 250: } else ! 251: v->v_num = l.v_num >> r.v_num; ! 252: break; ! 253: case T_PLUS: ! 254: if (l.v_type == V_STR) { ! 255: v->v_str = str_cat(l.v_str, r.v_str); ! 256: v->v_type = V_STR; ! 257: } else ! 258: v->v_num = l.v_num + r.v_num; ! 259: break; ! 260: case T_MINUS: ! 261: v->v_num = l.v_num - r.v_num; ! 262: break; ! 263: case T_MUL: ! 264: v->v_num = l.v_num * r.v_num; ! 265: break; ! 266: case T_DIV: ! 267: v->v_num = l.v_num / r.v_num; ! 268: break; ! 269: case T_MOD: ! 270: v->v_num = l.v_num % r.v_num; ! 271: break; ! 272: } ! 273: val_free(l); ! 274: val_free(r); ! 275: } ! 276: /*NOTREACHED*/ ! 277: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.