|
|
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.