1: #ifndef lint
   2: static char sccsid[] = "@(#)parser4.c	3.4 4/24/85";
   3: #endif
   4: 
   5: /*
   6:  * Copyright (c) 1983 Regents of the University of California,
   7:  * All rights reserved.  Redistribution permitted subject to
   8:  * the terms of the Berkeley Software License Agreement.
   9:  */
  10: 
  11: #include "parser.h"
  12: 
  13: /*
  14:  * |		3
  15:  * ^		4
  16:  * &		5
  17:  * == !=	6
  18:  * < <= > >=	7
  19:  * << >>	8
  20:  * + -		9
  21:  * * / %	10
  22:  */
  23: p_expr3_10(level, v, flag)
  24: register struct value *v;
  25: char flag;
  26: {
  27:     struct value l, r;
  28:     int op;
  29:     char *opname;
  30: 
  31:     if ((level == 10 ? p_expr11(v, flag)
  32:          : p_expr3_10(level + 1, v, flag)) < 0)
  33:         return -1;
  34:     for (;;) {
  35:         switch (level) {
  36:         case 3:
  37:             if (token != T_OR)
  38:                 return 0;
  39:             opname = "|";
  40:             break;
  41:         case 4:
  42:             if (token != T_XOR)
  43:                 return 0;
  44:             opname = "^";
  45:             break;
  46:         case 5:
  47:             if (token != T_AND)
  48:                 return 0;
  49:             opname = "&";
  50:             break;
  51:         case 6:
  52:             if (token == T_EQ)
  53:                 opname = "==";
  54:             else if (token == T_NE)
  55:                 opname = "!=";
  56:             else
  57:                 return 0;
  58:             break;
  59:         case 7:
  60:             switch (token) {
  61:             case T_LT:
  62:                 opname = "<";
  63:                 break;
  64:             case T_LE:
  65:                 opname = "<=";
  66:                 break;
  67:             case T_GT:
  68:                 opname = ">";
  69:                 break;
  70:             case T_GE:
  71:                 opname = ">=";
  72:                 break;
  73:             default:
  74:                 return 0;
  75:             }
  76:             break;
  77:         case 8:
  78:             if (token == T_LS)
  79:                 opname = "<<";
  80:             else if (token == T_RS)
  81:                 opname = ">>";
  82:             else
  83:                 return 0;
  84:             break;
  85:         case 9:
  86:             if (token == T_PLUS)
  87:                 opname = "+";
  88:             else if (token == T_MINUS)
  89:                 opname = "-";
  90:             else
  91:                 return 0;
  92:             break;
  93:         case 10:
  94:             switch (token) {
  95:             case T_MUL:
  96:                 opname = "*";
  97:                 break;
  98:             case T_DIV:
  99:                 opname = "/";
 100:                 break;
 101:             case T_MOD:
 102:                 opname = "%";
 103:                 break;
 104:             default:
 105:                 return 0;
 106:             }
 107:             break;
 108:         }
 109:         l = *v;
 110:         if (l.v_type == V_ERR)
 111:             flag = 0;
 112: 
 113:         op = token;
 114:         (void) s_gettok();
 115:         if ((level == 10 ? p_expr11(&r, flag)
 116:              : p_expr3_10(level + 1, &r, flag)) < 0) {
 117:             p_synerror();
 118:             val_free(l);
 119:             return -1;
 120:         }
 121: 
 122:         if (r.v_type == V_ERR)
 123:             flag = 0;
 124:         else switch (op) {
 125:         case T_EQ:
 126:         case T_NE:
 127:         case T_LT:
 128:         case T_LE:
 129:         case T_GT:
 130:         case T_GE:
 131:         case T_PLUS:
 132:             if (l.v_type == V_STR) {
 133:                 if (r.v_type == V_NUM)
 134:                     if (p_convstr(&r) < 0)
 135:                         flag = 0;
 136:             } else
 137:                 if (r.v_type == V_STR)
 138:                     if (p_convstr(&l) < 0)
 139:                         flag = 0;
 140:             break;
 141:         case T_LS:
 142:         case T_RS:
 143:             if (r.v_type == V_STR) {
 144:                 char *p = r.v_str;
 145:                 r.v_type = V_NUM;
 146:                 r.v_num = strlen(p);
 147:                 str_free(p);
 148:             }
 149:             break;
 150:         case T_OR:
 151:         case T_XOR:
 152:         case T_AND:
 153:         case T_MINUS:
 154:         case T_MUL:
 155:         case T_DIV:
 156:         case T_MOD:
 157:         default:
 158:             if (l.v_type == V_STR || r.v_type == V_STR) {
 159:                 p_error("%s: Numeric operands required.",
 160:                     opname);
 161:                 flag = 0;
 162:             }
 163:         }
 164:         if (!flag) {
 165:             val_free(l);
 166:             val_free(r);
 167:             v->v_type = V_ERR;
 168:             if (p_abort())
 169:                 return -1;
 170:             continue;
 171:         }
 172: 
 173:         v->v_type = V_NUM;
 174:         switch (op) {
 175:         case T_EQ:
 176:         case T_NE:
 177:         case T_LT:
 178:         case T_LE:
 179:         case T_GT:
 180:         case T_GE:
 181:             if (l.v_type == V_STR) {
 182:                 int tmp = strcmp(l.v_str, r.v_str);
 183:                 str_free(l.v_str);
 184:                 str_free(r.v_str);
 185:                 l.v_type = V_NUM;
 186:                 l.v_num = tmp;
 187:                 r.v_type = V_NUM;
 188:                 r.v_num = 0;
 189:             }
 190:             break;
 191:         }
 192:         switch (op) {
 193:         case T_OR:
 194:             v->v_num = l.v_num | r.v_num;
 195:             break;
 196:         case T_XOR:
 197:             v->v_num = l.v_num ^ r.v_num;
 198:             break;
 199:         case T_AND:
 200:             v->v_num = l.v_num & r.v_num;
 201:             break;
 202:         case T_EQ:
 203:             v->v_num = l.v_num == r.v_num;
 204:             break;
 205:         case T_NE:
 206:             v->v_num = l.v_num != r.v_num;
 207:             break;
 208:         case T_LT:
 209:             v->v_num = l.v_num < r.v_num;
 210:             break;
 211:         case T_LE:
 212:             v->v_num = l.v_num <= r.v_num;
 213:             break;
 214:         case T_GT:
 215:             v->v_num = l.v_num > r.v_num;
 216:             break;
 217:         case T_GE:
 218:             v->v_num = l.v_num >= r.v_num;
 219:             break;
 220:         case T_LS:
 221:             if (l.v_type == V_STR) {
 222:                 int i;
 223:                 if ((i = strlen(l.v_str)) > r.v_num)
 224:                     i = r.v_num;
 225:                 v->v_str = str_ncpy(l.v_str, i);
 226:                 v->v_type = V_STR;
 227:             } else
 228:                 v->v_num = l.v_num << r.v_num;
 229:             break;
 230:         case T_RS:
 231:             if (l.v_type == V_STR) {
 232:                 int i;
 233:                 if ((i = strlen(l.v_str)) > r.v_num)
 234:                     i -= r.v_num;
 235:                 else
 236:                     i = 0;
 237:                 v->v_str = str_cpy(l.v_str + i);
 238:                 v->v_type = V_STR;
 239:             } else
 240:                 v->v_num = l.v_num >> r.v_num;
 241:             break;
 242:         case T_PLUS:
 243:             if (l.v_type == V_STR) {
 244:                 v->v_str = str_cat(l.v_str, r.v_str);
 245:                 v->v_type = V_STR;
 246:             } else
 247:                 v->v_num = l.v_num + r.v_num;
 248:             break;
 249:         case T_MINUS:
 250:             v->v_num = l.v_num - r.v_num;
 251:             break;
 252:         case T_MUL:
 253:             v->v_num = l.v_num * r.v_num;
 254:             break;
 255:         case T_DIV:
 256:             v->v_num = l.v_num / r.v_num;
 257:             break;
 258:         case T_MOD:
 259:             v->v_num = l.v_num % r.v_num;
 260:             break;
 261:         }
 262:         val_free(l);
 263:         val_free(r);
 264:     }
 265:     /*NOTREACHED*/
 266: }

Defined functions

p_expr3_10 defined in line 23; used 4 times

Defined variables

sccsid defined in line 2; never used
Last modified: 1987-02-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 678
Valid CSS Valid XHTML 1.0 Strict