]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/ddb/db_expr.c
Update llvm to release_39 branch r276489, and resolve conflicts.
[FreeBSD/FreeBSD.git] / sys / ddb / db_expr.c
1 /*-
2  * Mach Operating System
3  * Copyright (c) 1991,1990 Carnegie Mellon University
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify and distribute this software and its
7  * documentation is hereby granted, provided that both the copyright
8  * notice and this permission notice appear in all copies of the
9  * software, derivative works or modified versions, and any portions
10  * thereof, and that both notices appear in supporting documentation.
11  *
12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15  *
16  * Carnegie Mellon requests users of this software to return to
17  *
18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19  *  School of Computer Science
20  *  Carnegie Mellon University
21  *  Pittsburgh PA 15213-3890
22  *
23  * any improvements or extensions that they make and grant Carnegie the
24  * rights to redistribute these changes.
25  */
26 /*
27  *      Author: David B. Golub, Carnegie Mellon University
28  *      Date:   7/90
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include <sys/param.h>
35
36 #include <ddb/ddb.h>
37 #include <ddb/db_lex.h>
38 #include <ddb/db_access.h>
39 #include <ddb/db_command.h>
40
41 static bool     db_add_expr(db_expr_t *valuep);
42 static bool     db_mult_expr(db_expr_t *valuep);
43 static bool     db_shift_expr(db_expr_t *valuep);
44 static bool     db_term(db_expr_t *valuep);
45 static bool     db_unary(db_expr_t *valuep);
46 static bool     db_logical_or_expr(db_expr_t *valuep);
47 static bool     db_logical_and_expr(db_expr_t *valuep);
48 static bool     db_logical_relation_expr(db_expr_t *valuep);
49
50 static bool
51 db_term(db_expr_t *valuep)
52 {
53         int     t;
54
55         t = db_read_token();
56         if (t == tIDENT) {
57             if (!db_value_of_name(db_tok_string, valuep) &&
58                 !db_value_of_name_pcpu(db_tok_string, valuep) &&
59                 !db_value_of_name_vnet(db_tok_string, valuep)) {
60                 db_error("Symbol not found\n");
61                 /*NOTREACHED*/
62             }
63             return (true);
64         }
65         if (t == tNUMBER) {
66             *valuep = (db_expr_t)db_tok_number;
67             return (true);
68         }
69         if (t == tDOT) {
70             *valuep = (db_expr_t)db_dot;
71             return (true);
72         }
73         if (t == tDOTDOT) {
74             *valuep = (db_expr_t)db_prev;
75             return (true);
76         }
77         if (t == tPLUS) {
78             *valuep = (db_expr_t) db_next;
79             return (true);
80         }
81         if (t == tDITTO) {
82             *valuep = (db_expr_t)db_last_addr;
83             return (true);
84         }
85         if (t == tDOLLAR) {
86             if (!db_get_variable(valuep))
87                 return (false);
88             return (true);
89         }
90         if (t == tLPAREN) {
91             if (!db_expression(valuep)) {
92                 db_error("Syntax error\n");
93                 /*NOTREACHED*/
94             }
95             t = db_read_token();
96             if (t != tRPAREN) {
97                 db_error("Syntax error\n");
98                 /*NOTREACHED*/
99             }
100             return (true);
101         }
102         db_unread_token(t);
103         return (false);
104 }
105
106 static bool
107 db_unary(db_expr_t *valuep)
108 {
109         int     t;
110
111         t = db_read_token();
112         if (t == tMINUS) {
113             if (!db_unary(valuep)) {
114                 db_printf("Expression syntax error after '%c'\n", '-');
115                 db_error(NULL);
116                 /*NOTREACHED*/
117             }
118             *valuep = -*valuep;
119             return (true);
120         }
121         if (t == tEXCL) {
122             if(!db_unary(valuep)) {
123                 db_printf("Expression syntax error after '%c'\n", '!');
124                 db_error(NULL);
125                 /* NOTREACHED  */
126             }
127             *valuep = (!(*valuep));
128             return (true);
129         }
130         if (t == tBIT_NOT) {
131             if(!db_unary(valuep)) {
132                 db_printf("Expression syntax error after '%c'\n", '~');
133                 db_error(NULL);
134                 /* NOTREACHED */
135             }
136             *valuep = (~(*valuep));
137             return (true);
138         }
139         if (t == tSTAR) {
140             /* indirection */
141             if (!db_unary(valuep)) {
142                 db_printf("Expression syntax error after '%c'\n", '*');
143                 db_error(NULL);
144                 /*NOTREACHED*/
145             }
146             *valuep = db_get_value((db_addr_t)*valuep, sizeof(void *),
147                 false);
148             return (true);
149         }
150         db_unread_token(t);
151         return (db_term(valuep));
152 }
153
154 static bool
155 db_mult_expr(db_expr_t *valuep)
156 {
157         db_expr_t       lhs, rhs;
158         int             t;
159
160         if (!db_unary(&lhs))
161             return (false);
162
163         t = db_read_token();
164         while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH ||
165             t == tBIT_AND ) {
166             if (!db_term(&rhs)) {
167                 db_printf("Expression syntax error after '%c'\n", '!');
168                 db_error(NULL);
169                 /*NOTREACHED*/
170             }
171             switch(t)  {
172                 case tSTAR:
173                     lhs *= rhs;
174                     break;
175                 case tBIT_AND:
176                     lhs &= rhs;
177                     break;
178                 default:
179                     if (rhs == 0) {
180                         db_error("Divide by 0\n");
181                         /*NOTREACHED*/
182                     }
183                     if (t == tSLASH)
184                         lhs /= rhs;
185                     else if (t == tPCT)
186                         lhs %= rhs;
187                     else
188                         lhs = roundup(lhs, rhs);
189             }
190             t = db_read_token();
191         }
192         db_unread_token(t);
193         *valuep = lhs;
194         return (true);
195 }
196
197 static bool
198 db_add_expr(db_expr_t *valuep)
199 {
200         db_expr_t       lhs, rhs;
201         int             t;
202         char            c;
203
204         if (!db_mult_expr(&lhs))
205             return (false);
206
207         t = db_read_token();
208         while (t == tPLUS || t == tMINUS || t == tBIT_OR) {
209             if (!db_mult_expr(&rhs)) {
210                 c = db_tok_string[0];
211                 db_printf("Expression syntax error after '%c'\n", c);
212                 db_error(NULL);
213                 /*NOTREACHED*/
214             }
215             switch (t) {
216             case tPLUS:
217                 lhs += rhs;
218                 break;
219             case tMINUS:
220                 lhs -= rhs;
221                 break;
222             case tBIT_OR:
223                 lhs |= rhs;
224                 break;
225             default:
226                 __unreachable();
227             }
228             t = db_read_token();
229         }
230         db_unread_token(t);
231         *valuep = lhs;
232         return (true);
233 }
234
235 static bool
236 db_shift_expr(db_expr_t *valuep)
237 {
238         db_expr_t       lhs, rhs;
239         int             t;
240
241         if (!db_add_expr(&lhs))
242                 return (false);
243         t = db_read_token();
244         while (t == tSHIFT_L || t == tSHIFT_R) {
245             if (!db_add_expr(&rhs)) {
246                 db_error("Syntax error\n");
247                 /*NOTREACHED*/
248             }
249             if (rhs < 0) {
250                 db_error("Negative shift amount\n");
251                 /*NOTREACHED*/
252             }
253             if (t == tSHIFT_L)
254                 lhs <<= rhs;
255             else {
256                 /* Shift right is unsigned */
257                 lhs = (unsigned) lhs >> rhs;
258             }
259             t = db_read_token();
260         }
261         db_unread_token(t);
262         *valuep = lhs;
263         return (true);
264 }
265
266 static bool
267 db_logical_relation_expr(
268         db_expr_t *valuep)
269 {
270         db_expr_t       lhs, rhs;
271         int             t;
272         char            op[3];
273
274         if (!db_shift_expr(&lhs))
275             return (false);
276
277         t = db_read_token();
278         while (t == tLOG_EQ || t == tLOG_NOT_EQ || t == tGREATER ||
279             t == tGREATER_EQ || t == tLESS || t == tLESS_EQ) {
280             op[0] = db_tok_string[0];
281             op[1] = db_tok_string[1];
282             op[2] = 0;
283             if (!db_shift_expr(&rhs)) {
284                 db_printf("Expression syntax error after \"%s\"\n", op);
285                 db_error(NULL);
286                 /*NOTREACHED*/
287             }
288             switch(t) {
289                 case tLOG_EQ:
290                     lhs = (lhs == rhs);
291                     break;
292                 case tLOG_NOT_EQ:
293                     lhs = (lhs != rhs);
294                     break;
295                 case tGREATER:
296                     lhs = (lhs > rhs);
297                     break;
298                 case tGREATER_EQ:
299                     lhs = (lhs >= rhs);
300                     break;
301                 case tLESS:
302                     lhs = (lhs < rhs);
303                     break;
304                 case tLESS_EQ:
305                     lhs = (lhs <= rhs);
306                     break;
307                 default:
308                     __unreachable();
309             }
310             t = db_read_token();
311         }
312         db_unread_token(t);
313         *valuep = lhs;
314         return (true);
315 }
316
317 static bool
318 db_logical_and_expr(
319         db_expr_t *valuep)
320 {
321         db_expr_t       lhs, rhs;
322         int             t;
323
324         if (!db_logical_relation_expr(&lhs))
325             return (false);
326
327         t = db_read_token();
328         while (t == tLOG_AND) {
329             if (!db_logical_relation_expr(&rhs)) {
330                 db_printf("Expression syntax error after '%s'\n", "&&");
331                 db_error(NULL);
332                 /*NOTREACHED*/
333             }
334             lhs = (lhs && rhs);
335             t = db_read_token();
336         }
337         db_unread_token(t);
338         *valuep = lhs;
339         return (true);
340 }
341
342 static bool
343 db_logical_or_expr(
344         db_expr_t *valuep)
345 {
346         db_expr_t       lhs, rhs;
347         int             t;
348
349         if (!db_logical_and_expr(&lhs))
350                 return(false);
351
352         t = db_read_token();
353         while (t == tLOG_OR) {
354                 if (!db_logical_and_expr(&rhs)) {
355                         db_printf("Expression syntax error after '%s'\n", "||");
356                         db_error(NULL);
357                         /*NOTREACHED*/
358                 }
359                 lhs = (lhs || rhs);
360                 t = db_read_token();
361         }
362         db_unread_token(t);
363         *valuep = lhs;
364         return (true);
365 }
366
367 int
368 db_expression(db_expr_t *valuep)
369 {
370         return (db_logical_or_expr(valuep));
371 }