xref: /netbsd-src/sys/ddb/db_expr.c (revision 4472dbe5e3bd91ef2540bada7a7ca7384627ff9b)
1 /*	$NetBSD: db_expr.c,v 1.9 1999/04/12 20:38:21 pk 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@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(db_expr_t),
121 	        FALSE);
122 	    return (TRUE);
123 	}
124 	db_unread_token(t);
125 	return (db_term(valuep));
126 }
127 
128 boolean_t
129 db_mult_expr(valuep)
130 	db_expr_t *valuep;
131 {
132 	db_expr_t	lhs, rhs;
133 	int		t;
134 
135 	if (!db_unary(&lhs))
136 	    return (FALSE);
137 
138 	t = db_read_token();
139 	while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) {
140 	    if (!db_term(&rhs)) {
141 		db_error("Syntax error\n");
142 		/*NOTREACHED*/
143 	    }
144 	    if (t == tSTAR)
145 		lhs *= rhs;
146 	    else {
147 		if (rhs == 0) {
148 		    db_error("Divide by 0\n");
149 		    /*NOTREACHED*/
150 		}
151 		if (t == tSLASH)
152 		    lhs /= rhs;
153 		else if (t == tPCT)
154 		    lhs %= rhs;
155 		else
156 		    lhs = ((lhs+rhs-1)/rhs)*rhs;
157 	    }
158 	    t = db_read_token();
159 	}
160 	db_unread_token(t);
161 	*valuep = lhs;
162 	return (TRUE);
163 }
164 
165 boolean_t
166 db_add_expr(valuep)
167 	db_expr_t *valuep;
168 {
169 	db_expr_t	lhs, rhs;
170 	int		t;
171 
172 	if (!db_mult_expr(&lhs))
173 	    return (FALSE);
174 
175 	t = db_read_token();
176 	while (t == tPLUS || t == tMINUS) {
177 	    if (!db_mult_expr(&rhs)) {
178 		db_error("Syntax error\n");
179 		/*NOTREACHED*/
180 	    }
181 	    if (t == tPLUS)
182 		lhs += rhs;
183 	    else
184 		lhs -= rhs;
185 	    t = db_read_token();
186 	}
187 	db_unread_token(t);
188 	*valuep = lhs;
189 	return (TRUE);
190 }
191 
192 boolean_t
193 db_shift_expr(valuep)
194 	db_expr_t *valuep;
195 {
196 	db_expr_t	lhs, rhs;
197 	int		t;
198 
199 	if (!db_add_expr(&lhs))
200 	    return (FALSE);
201 
202 	t = db_read_token();
203 	while (t == tSHIFT_L || t == tSHIFT_R) {
204 	    if (!db_add_expr(&rhs)) {
205 		db_error("Syntax error\n");
206 		/*NOTREACHED*/
207 	    }
208 	    if (rhs < 0) {
209 		db_error("Negative shift amount\n");
210 		/*NOTREACHED*/
211 	    }
212 	    if (t == tSHIFT_L)
213 		lhs <<= rhs;
214 	    else {
215 		/* Shift right is unsigned */
216 		lhs = (unsigned long) lhs >> rhs;
217 	    }
218 	    t = db_read_token();
219 	}
220 	db_unread_token(t);
221 	*valuep = lhs;
222 	return (TRUE);
223 }
224 
225 int
226 db_expression(valuep)
227 	db_expr_t *valuep;
228 {
229 	return (db_shift_expr(valuep));
230 }
231