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