xref: /dragonfly/sys/ddb/db_expr.c (revision ef3ac1d1)
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  * $FreeBSD: src/sys/ddb/db_expr.c,v 1.13 1999/08/28 00:41:07 peter Exp $
27  * $DragonFly: src/sys/ddb/db_expr.c,v 1.4 2005/12/23 21:35:44 swildner Exp $
28  */
29 
30 /*
31  *	Author: David B. Golub, Carnegie Mellon University
32  *	Date:	7/90
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(db_expr_t *valuep)
49 {
50 	int	t;
51 
52 	t = db_read_token();
53 	if (t == tIDENT) {
54 	    if (!db_value_of_name(db_tok_string, valuep)) {
55 		db_error("Symbol not found\n");
56 		/*NOTREACHED*/
57 	    }
58 	    return (TRUE);
59 	}
60 	if (t == tNUMBER) {
61 	    *valuep = (db_expr_t)db_tok_number;
62 	    return (TRUE);
63 	}
64 	if (t == tDOT) {
65 	    *valuep = (db_expr_t)db_dot;
66 	    return (TRUE);
67 	}
68 	if (t == tDOTDOT) {
69 	    *valuep = (db_expr_t)db_prev;
70 	    return (TRUE);
71 	}
72 	if (t == tPLUS) {
73 	    *valuep = (db_expr_t) db_next;
74 	    return (TRUE);
75 	}
76 	if (t == tDITTO) {
77 	    *valuep = (db_expr_t)db_last_addr;
78 	    return (TRUE);
79 	}
80 	if (t == tDOLLAR) {
81 	    if (!db_get_variable(valuep))
82 		return (FALSE);
83 	    return (TRUE);
84 	}
85 	if (t == tLPAREN) {
86 	    if (!db_expression(valuep)) {
87 		db_error("Syntax error\n");
88 		/*NOTREACHED*/
89 	    }
90 	    t = db_read_token();
91 	    if (t != tRPAREN) {
92 		db_error("Syntax error\n");
93 		/*NOTREACHED*/
94 	    }
95 	    return (TRUE);
96 	}
97 	db_unread_token(t);
98 	return (FALSE);
99 }
100 
101 static boolean_t
102 db_unary(db_expr_t *valuep)
103 {
104 	int	t;
105 
106 	t = db_read_token();
107 	if (t == tMINUS) {
108 	    if (!db_unary(valuep)) {
109 		db_error("Syntax error\n");
110 		/*NOTREACHED*/
111 	    }
112 	    *valuep = -*valuep;
113 	    return (TRUE);
114 	}
115 	if (t == tSTAR) {
116 	    /* indirection */
117 	    if (!db_unary(valuep)) {
118 		db_error("Syntax error\n");
119 		/*NOTREACHED*/
120 	    }
121 	    *valuep = db_get_value((db_addr_t)*valuep, sizeof(int), FALSE);
122 	    return (TRUE);
123 	}
124 	db_unread_token(t);
125 	return (db_term(valuep));
126 }
127 
128 static boolean_t
129 db_mult_expr(db_expr_t *valuep)
130 {
131 	db_expr_t	lhs, rhs;
132 	int		t;
133 
134 	*valuep = 0;	/* silence gcc */
135 
136 	if (!db_unary(&lhs))
137 	    return (FALSE);
138 
139 	t = db_read_token();
140 	while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) {
141 	    if (!db_term(&rhs)) {
142 		db_error("Syntax error\n");
143 		/*NOTREACHED*/
144 	    }
145 	    if (t == tSTAR)
146 		lhs *= rhs;
147 	    else {
148 		if (rhs == 0) {
149 		    db_error("Divide by 0\n");
150 		    /*NOTREACHED*/
151 		}
152 		if (t == tSLASH)
153 		    lhs /= rhs;
154 		else if (t == tPCT)
155 		    lhs %= rhs;
156 		else
157 		    lhs = ((lhs+rhs-1)/rhs)*rhs;
158 	    }
159 	    t = db_read_token();
160 	}
161 	db_unread_token(t);
162 	*valuep = lhs;
163 	return (TRUE);
164 }
165 
166 static boolean_t
167 db_add_expr(db_expr_t *valuep)
168 {
169 	db_expr_t	lhs, rhs;
170 	int		t;
171 
172 	*valuep = 0;	/* silence gcc */
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(db_expr_t *valuep)
196 {
197 	db_expr_t	lhs, rhs;
198 	int		t;
199 
200 	if (!db_add_expr(&lhs))
201 	    return (FALSE);
202 
203 	t = db_read_token();
204 	while (t == tSHIFT_L || t == tSHIFT_R) {
205 	    if (!db_add_expr(&rhs)) {
206 		db_error("Syntax error\n");
207 		/*NOTREACHED*/
208 	    }
209 	    if (rhs < 0) {
210 		db_error("Negative shift amount\n");
211 		/*NOTREACHED*/
212 	    }
213 	    if (t == tSHIFT_L)
214 		lhs <<= rhs;
215 	    else {
216 		/* Shift right is unsigned */
217 		lhs = (unsigned) lhs >> rhs;
218 	    }
219 	    t = db_read_token();
220 	}
221 	db_unread_token(t);
222 	*valuep = lhs;
223 	return (TRUE);
224 }
225 
226 int
227 db_expression(db_expr_t *valuep)
228 {
229 	return (db_shift_expr(valuep));
230 }
231