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