removed extra tt_col += n in gen_write
[unix-history] / usr / src / usr.bin / window / parser4.c
CommitLineData
8318d219 1#ifndef lint
60de5df9 2static char sccsid[] = "@(#)parser4.c 3.4 %G%";
8318d219
EW
3#endif
4
60de5df9
EW
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
8318d219
EW
11#include "parser.h"
12
13/*
14 * | 3
15 * ^ 4
16 * & 5
17 * == != 6
18 * < <= > >= 7
19 * << >> 8
20 * + - 9
21 * * / % 10
22 */
23p_expr3_10(level, v, flag)
24register struct value *v;
25char flag;
26{
0180c2d9 27 struct value l, r;
8318d219
EW
28 int op;
29 char *opname;
30
0180c2d9
EW
31 if ((level == 10 ? p_expr11(v, flag)
32 : p_expr3_10(level + 1, v, flag)) < 0)
33 return -1;
8318d219
EW
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 }
0180c2d9
EW
109 l = *v;
110 if (l.v_type == V_ERR)
8318d219
EW
111 flag = 0;
112
113 op = token;
114 (void) s_gettok();
0180c2d9
EW
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;
8318d219
EW
120 }
121
0180c2d9 122 if (r.v_type == V_ERR)
8318d219 123 flag = 0;
0180c2d9 124 else switch (op) {
8318d219
EW
125 case T_EQ:
126 case T_NE:
127 case T_LT:
128 case T_LE:
129 case T_GT:
130 case T_GE:
0180c2d9
EW
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);
8318d219
EW
148 }
149 break;
0180c2d9
EW
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:
8318d219 157 default:
0180c2d9
EW
158 if (l.v_type == V_STR || r.v_type == V_STR) {
159 p_error("%s: Numeric operands required.",
8318d219
EW
160 opname);
161 flag = 0;
162 }
163 }
8318d219 164 if (!flag) {
0180c2d9
EW
165 val_free(l);
166 val_free(r);
8318d219 167 v->v_type = V_ERR;
0180c2d9
EW
168 if (p_abort())
169 return -1;
8318d219
EW
170 continue;
171 }
172
0180c2d9
EW
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 }
8318d219
EW
192 switch (op) {
193 case T_OR:
0180c2d9 194 v->v_num = l.v_num | r.v_num;
8318d219
EW
195 break;
196 case T_XOR:
0180c2d9 197 v->v_num = l.v_num ^ r.v_num;
8318d219
EW
198 break;
199 case T_AND:
0180c2d9 200 v->v_num = l.v_num & r.v_num;
8318d219
EW
201 break;
202 case T_EQ:
0180c2d9 203 v->v_num = l.v_num == r.v_num;
8318d219
EW
204 break;
205 case T_NE:
0180c2d9 206 v->v_num = l.v_num != r.v_num;
8318d219
EW
207 break;
208 case T_LT:
0180c2d9 209 v->v_num = l.v_num < r.v_num;
8318d219
EW
210 break;
211 case T_LE:
0180c2d9 212 v->v_num = l.v_num <= r.v_num;
8318d219
EW
213 break;
214 case T_GT:
0180c2d9 215 v->v_num = l.v_num > r.v_num;
8318d219
EW
216 break;
217 case T_GE:
0180c2d9 218 v->v_num = l.v_num >= r.v_num;
8318d219
EW
219 break;
220 case T_LS:
0180c2d9
EW
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;
8318d219
EW
229 break;
230 case T_RS:
0180c2d9
EW
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;
8318d219
EW
241 break;
242 case T_PLUS:
0180c2d9
EW
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;
8318d219
EW
248 break;
249 case T_MINUS:
0180c2d9 250 v->v_num = l.v_num - r.v_num;
8318d219
EW
251 break;
252 case T_MUL:
0180c2d9 253 v->v_num = l.v_num * r.v_num;
8318d219
EW
254 break;
255 case T_DIV:
0180c2d9 256 v->v_num = l.v_num / r.v_num;
8318d219
EW
257 break;
258 case T_MOD:
0180c2d9 259 v->v_num = l.v_num % r.v_num;
8318d219
EW
260 break;
261 }
0180c2d9
EW
262 val_free(l);
263 val_free(r);
8318d219
EW
264 }
265 /*NOTREACHED*/
266}