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
Defined variables
sccsid
defined in line
2;
never used