db_expr.c revision 1.11 1 /* $NetBSD: db_expr.c,v 1.11 2000/07/09 01:52:17 mycroft Exp $ */
2
3 /*
4 * Mach Operating System
5 * Copyright (c) 1991,1990 Carnegie Mellon University
6 * All Rights Reserved.
7 *
8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes.
27 *
28 * Author: David B. Golub, Carnegie Mellon University
29 * Date: 7/90
30 */
31
32 #include <sys/param.h>
33 #include <sys/proc.h>
34
35 #include <machine/db_machdep.h>
36
37 #include <ddb/db_lex.h>
38 #include <ddb/db_access.h>
39 #include <ddb/db_command.h>
40 #include <ddb/db_sym.h>
41 #include <ddb/db_extern.h>
42 #include <ddb/db_variables.h>
43
44 boolean_t
45 db_term(valuep)
46 db_expr_t *valuep;
47 {
48 int t;
49
50 t = db_read_token();
51 if (t == tIDENT) {
52 if (!db_value_of_name(db_tok_string, valuep)) {
53 extern int db_radix;
54 db_expr_t v = 0;
55 int i, c, byte;
56
57 /* See if we can make a number out of all of it */
58 for (i = 0; (c = db_tok_string[i]) != '\0'; i++) {
59 byte = 0;
60 if (c >= '0' && c <= '9')
61 byte = c - '0';
62 else if (db_radix == 16 && c >= 'a' && c <= 'f')
63 byte = c - 'a' + 10;
64 else if (db_radix == 16 && c >= 'A' && c <= 'F')
65 byte = c - 'A' + 10;
66 else
67 db_error("Symbol not found\n");
68 /*NOTREACHED*/
69 v = v * db_radix + byte;
70 }
71 *valuep = (db_expr_t)v;
72 }
73 return (TRUE);
74 }
75 if (t == tNUMBER) {
76 *valuep = (db_expr_t)db_tok_number;
77 return (TRUE);
78 }
79 if (t == tDOT) {
80 *valuep = (db_expr_t)db_dot;
81 return (TRUE);
82 }
83 if (t == tDOTDOT) {
84 *valuep = (db_expr_t)db_prev;
85 return (TRUE);
86 }
87 if (t == tPLUS) {
88 *valuep = (db_expr_t) db_next;
89 return (TRUE);
90 }
91 if (t == tDITTO) {
92 *valuep = (db_expr_t)db_last_addr;
93 return (TRUE);
94 }
95 if (t == tDOLLAR) {
96 if (!db_get_variable(valuep))
97 return (FALSE);
98 return (TRUE);
99 }
100 if (t == tLPAREN) {
101 if (!db_expression(valuep)) {
102 db_error("Syntax error\n");
103 /*NOTREACHED*/
104 }
105 t = db_read_token();
106 if (t != tRPAREN) {
107 db_error("Syntax error\n");
108 /*NOTREACHED*/
109 }
110 return (TRUE);
111 }
112 db_unread_token(t);
113 return (FALSE);
114 }
115
116 boolean_t
117 db_unary(valuep)
118 db_expr_t *valuep;
119 {
120 int t;
121
122 t = db_read_token();
123 if (t == tMINUS) {
124 if (!db_unary(valuep)) {
125 db_error("Syntax error\n");
126 /*NOTREACHED*/
127 }
128 *valuep = -*valuep;
129 return (TRUE);
130 }
131 if (t == tSTAR) {
132 /* indirection */
133 if (!db_unary(valuep)) {
134 db_error("Syntax error\n");
135 /*NOTREACHED*/
136 }
137 *valuep = db_get_value((db_addr_t)*valuep, sizeof(db_expr_t),
138 FALSE);
139 return (TRUE);
140 }
141 db_unread_token(t);
142 return (db_term(valuep));
143 }
144
145 boolean_t
146 db_mult_expr(valuep)
147 db_expr_t *valuep;
148 {
149 db_expr_t lhs, rhs;
150 int t;
151
152 if (!db_unary(&lhs))
153 return (FALSE);
154
155 t = db_read_token();
156 while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) {
157 if (!db_term(&rhs)) {
158 db_error("Syntax error\n");
159 /*NOTREACHED*/
160 }
161 if (t == tSTAR)
162 lhs *= rhs;
163 else {
164 if (rhs == 0) {
165 db_error("Divide by 0\n");
166 /*NOTREACHED*/
167 }
168 if (t == tSLASH)
169 lhs /= rhs;
170 else if (t == tPCT)
171 lhs %= rhs;
172 else
173 lhs = ((lhs+rhs-1)/rhs)*rhs;
174 }
175 t = db_read_token();
176 }
177 db_unread_token(t);
178 *valuep = lhs;
179 return (TRUE);
180 }
181
182 boolean_t
183 db_add_expr(valuep)
184 db_expr_t *valuep;
185 {
186 db_expr_t lhs, rhs;
187 int t;
188
189 if (!db_mult_expr(&lhs))
190 return (FALSE);
191
192 t = db_read_token();
193 while (t == tPLUS || t == tMINUS) {
194 if (!db_mult_expr(&rhs)) {
195 db_error("Syntax error\n");
196 /*NOTREACHED*/
197 }
198 if (t == tPLUS)
199 lhs += rhs;
200 else
201 lhs -= rhs;
202 t = db_read_token();
203 }
204 db_unread_token(t);
205 *valuep = lhs;
206 return (TRUE);
207 }
208
209 boolean_t
210 db_shift_expr(valuep)
211 db_expr_t *valuep;
212 {
213 db_expr_t lhs, rhs;
214 int t;
215
216 if (!db_add_expr(&lhs))
217 return (FALSE);
218
219 t = db_read_token();
220 while (t == tSHIFT_L || t == tSHIFT_R) {
221 if (!db_add_expr(&rhs)) {
222 db_error("Syntax error\n");
223 /*NOTREACHED*/
224 }
225 if (rhs < 0) {
226 db_error("Negative shift amount\n");
227 /*NOTREACHED*/
228 }
229 if (t == tSHIFT_L)
230 lhs <<= rhs;
231 else {
232 /* Shift right is unsigned */
233 lhs = (unsigned long) lhs >> rhs;
234 }
235 t = db_read_token();
236 }
237 db_unread_token(t);
238 *valuep = lhs;
239 return (TRUE);
240 }
241
242 int
243 db_expression(valuep)
244 db_expr_t *valuep;
245 {
246 return (db_shift_expr(valuep));
247 }
248