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