Break paragraph with driver rewrite.
[netbsd-mini2440.git] / sys / ddb / db_expr.c
blob6f51e2146c6df466af76f12ea0df24e1cd1fc35e
1 /* $NetBSD: db_expr.c,v 1.15 2007/02/22 06:41:01 thorpej Exp $ */
3 /*
4 * Mach Operating System
5 * Copyright (c) 1991,1990 Carnegie Mellon University
6 * All Rights Reserved.
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.
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.
18 * Carnegie Mellon requests users of this software to return to
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes.
28 * Author: David B. Golub, Carnegie Mellon University
29 * Date: 7/90
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: db_expr.c,v 1.15 2007/02/22 06:41:01 thorpej Exp $");
35 #include <sys/param.h>
36 #include <sys/proc.h>
38 #include <ddb/ddb.h>
40 static bool db_term(db_expr_t *);
41 static bool db_unary(db_expr_t *);
42 static bool db_mult_expr(db_expr_t *);
43 static bool db_add_expr(db_expr_t *);
44 static bool db_shift_expr(db_expr_t *);
46 static bool
47 db_term(db_expr_t *valuep)
49 int t;
51 t = db_read_token();
52 if (t == tIDENT) {
53 if (!db_value_of_name(db_tok_string, valuep)) {
54 db_expr_t v = 0;
55 int i, c, byte;
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;
71 *valuep = (db_expr_t)v;
73 return (true);
75 if (t == tNUMBER) {
76 *valuep = (db_expr_t)db_tok_number;
77 return (true);
79 if (t == tDOT) {
80 *valuep = (db_expr_t)db_dot;
81 return (true);
83 if (t == tDOTDOT) {
84 *valuep = (db_expr_t)db_prev;
85 return (true);
87 if (t == tPLUS) {
88 *valuep = (db_expr_t) db_next;
89 return (true);
91 if (t == tDITTO) {
92 *valuep = (db_expr_t)db_last_addr;
93 return (true);
95 if (t == tDOLLAR) {
96 if (!db_get_variable(valuep))
97 return (false);
98 return (true);
100 if (t == tLPAREN) {
101 if (!db_expression(valuep)) {
102 db_error("Syntax error\n");
103 /*NOTREACHED*/
105 t = db_read_token();
106 if (t != tRPAREN) {
107 db_error("Syntax error\n");
108 /*NOTREACHED*/
110 return (true);
112 db_unread_token(t);
113 return (false);
116 static bool
117 db_unary(db_expr_t *valuep)
119 int t;
121 t = db_read_token();
122 if (t == tMINUS) {
123 if (!db_unary(valuep)) {
124 db_error("Syntax error\n");
125 /*NOTREACHED*/
127 *valuep = -*valuep;
128 return (true);
130 if (t == tSTAR) {
131 /* indirection */
132 if (!db_unary(valuep)) {
133 db_error("Syntax error\n");
134 /*NOTREACHED*/
136 *valuep = db_get_value((db_addr_t)*valuep, sizeof(db_expr_t),
137 false);
138 return (true);
140 db_unread_token(t);
141 return (db_term(valuep));
144 static bool
145 db_mult_expr(db_expr_t *valuep)
147 db_expr_t lhs, rhs;
148 int t;
150 if (!db_unary(&lhs))
151 return (false);
153 t = db_read_token();
154 while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) {
155 if (!db_term(&rhs)) {
156 db_error("Syntax error\n");
157 /*NOTREACHED*/
159 if (t == tSTAR)
160 lhs *= rhs;
161 else {
162 if (rhs == 0) {
163 db_error("Divide by 0\n");
164 /*NOTREACHED*/
166 if (t == tSLASH)
167 lhs /= rhs;
168 else if (t == tPCT)
169 lhs %= rhs;
170 else
171 lhs = ((lhs+rhs-1)/rhs)*rhs;
173 t = db_read_token();
175 db_unread_token(t);
176 *valuep = lhs;
177 return (true);
180 static bool
181 db_add_expr(db_expr_t *valuep)
183 db_expr_t lhs, rhs;
184 int t;
186 if (!db_mult_expr(&lhs))
187 return (false);
189 t = db_read_token();
190 while (t == tPLUS || t == tMINUS) {
191 if (!db_mult_expr(&rhs)) {
192 db_error("Syntax error\n");
193 /*NOTREACHED*/
195 if (t == tPLUS)
196 lhs += rhs;
197 else
198 lhs -= rhs;
199 t = db_read_token();
201 db_unread_token(t);
202 *valuep = lhs;
203 return (true);
206 static bool
207 db_shift_expr(db_expr_t *valuep)
209 db_expr_t lhs, rhs;
210 int t;
212 if (!db_add_expr(&lhs))
213 return (false);
215 t = db_read_token();
216 while (t == tSHIFT_L || t == tSHIFT_R) {
217 if (!db_add_expr(&rhs)) {
218 db_error("Syntax error\n");
219 /*NOTREACHED*/
221 if (rhs < 0) {
222 db_error("Negative shift amount\n");
223 /*NOTREACHED*/
225 if (t == tSHIFT_L)
226 lhs <<= rhs;
227 else {
228 /* Shift right is unsigned */
229 lhs = (unsigned long) lhs >> rhs;
231 t = db_read_token();
233 db_unread_token(t);
234 *valuep = lhs;
235 return (true);
239 db_expression(db_expr_t *valuep)
242 return (db_shift_expr(valuep));