db_expr.c revision 1.6 1 /* $NetBSD: db_expr.c,v 1.6 1997/02/03 19:56:04 cgd 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
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 db_error("Symbol not found\n");
54 /*NOTREACHED*/
55 }
56 return (TRUE);
57 }
58 if (t == tNUMBER) {
59 *valuep = (db_expr_t)db_tok_number;
60 return (TRUE);
61 }
62 if (t == tDOT) {
63 *valuep = (db_expr_t)db_dot;
64 return (TRUE);
65 }
66 if (t == tDOTDOT) {
67 *valuep = (db_expr_t)db_prev;
68 return (TRUE);
69 }
70 if (t == tPLUS) {
71 *valuep = (db_expr_t) db_next;
72 return (TRUE);
73 }
74 if (t == tDITTO) {
75 *valuep = (db_expr_t)db_last_addr;
76 return (TRUE);
77 }
78 if (t == tDOLLAR) {
79 if (!db_get_variable(valuep))
80 return (FALSE);
81 return (TRUE);
82 }
83 if (t == tLPAREN) {
84 if (!db_expression(valuep)) {
85 db_error("Syntax error\n");
86 /*NOTREACHED*/
87 }
88 t = db_read_token();
89 if (t != tRPAREN) {
90 db_error("Syntax error\n");
91 /*NOTREACHED*/
92 }
93 return (TRUE);
94 }
95 db_unread_token(t);
96 return (FALSE);
97 }
98
99 boolean_t
100 db_unary(valuep)
101 db_expr_t *valuep;
102 {
103 int t;
104
105 t = db_read_token();
106 if (t == tMINUS) {
107 if (!db_unary(valuep)) {
108 db_error("Syntax error\n");
109 /*NOTREACHED*/
110 }
111 *valuep = -*valuep;
112 return (TRUE);
113 }
114 if (t == tSTAR) {
115 /* indirection */
116 if (!db_unary(valuep)) {
117 db_error("Syntax error\n");
118 /*NOTREACHED*/
119 }
120 *valuep = db_get_value((db_addr_t)*valuep, sizeof(int), FALSE);
121 return (TRUE);
122 }
123 db_unread_token(t);
124 return (db_term(valuep));
125 }
126
127 boolean_t
128 db_mult_expr(valuep)
129 db_expr_t *valuep;
130 {
131 db_expr_t lhs, rhs;
132 int t;
133
134 if (!db_unary(&lhs))
135 return (FALSE);
136
137 t = db_read_token();
138 while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) {
139 if (!db_term(&rhs)) {
140 db_error("Syntax error\n");
141 /*NOTREACHED*/
142 }
143 if (t == tSTAR)
144 lhs *= rhs;
145 else {
146 if (rhs == 0) {
147 db_error("Divide by 0\n");
148 /*NOTREACHED*/
149 }
150 if (t == tSLASH)
151 lhs /= rhs;
152 else if (t == tPCT)
153 lhs %= rhs;
154 else
155 lhs = ((lhs+rhs-1)/rhs)*rhs;
156 }
157 t = db_read_token();
158 }
159 db_unread_token(t);
160 *valuep = lhs;
161 return (TRUE);
162 }
163
164 boolean_t
165 db_add_expr(valuep)
166 db_expr_t *valuep;
167 {
168 db_expr_t lhs, rhs;
169 int t;
170
171 if (!db_mult_expr(&lhs))
172 return (FALSE);
173
174 t = db_read_token();
175 while (t == tPLUS || t == tMINUS) {
176 if (!db_mult_expr(&rhs)) {
177 db_error("Syntax error\n");
178 /*NOTREACHED*/
179 }
180 if (t == tPLUS)
181 lhs += rhs;
182 else
183 lhs -= rhs;
184 t = db_read_token();
185 }
186 db_unread_token(t);
187 *valuep = lhs;
188 return (TRUE);
189 }
190
191 boolean_t
192 db_shift_expr(valuep)
193 db_expr_t *valuep;
194 {
195 db_expr_t lhs, rhs;
196 int t;
197
198 if (!db_add_expr(&lhs))
199 return (FALSE);
200
201 t = db_read_token();
202 while (t == tSHIFT_L || t == tSHIFT_R) {
203 if (!db_add_expr(&rhs)) {
204 db_error("Syntax error\n");
205 /*NOTREACHED*/
206 }
207 if (rhs < 0) {
208 db_error("Negative shift amount\n");
209 /*NOTREACHED*/
210 }
211 if (t == tSHIFT_L)
212 lhs <<= rhs;
213 else {
214 /* Shift right is unsigned */
215 lhs = (unsigned long) lhs >> rhs;
216 }
217 t = db_read_token();
218 }
219 db_unread_token(t);
220 *valuep = lhs;
221 return (TRUE);
222 }
223
224 int
225 db_expression(valuep)
226 db_expr_t *valuep;
227 {
228 return (db_shift_expr(valuep));
229 }
230