xref: /dragonfly/sys/ddb/db_expr.c (revision 67640b13)
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  */
28 
29 /*
30  *	Author: David B. Golub, Carnegie Mellon University
31  *	Date:	7/90
32  */
33 #include <sys/param.h>
34 
35 #include <ddb/ddb.h>
36 #include <ddb/db_lex.h>
37 #include <ddb/db_access.h>
38 #include <ddb/db_command.h>
39 
40 static boolean_t	db_add_expr (db_expr_t *valuep);
41 static boolean_t	db_mult_expr (db_expr_t *valuep);
42 static boolean_t	db_shift_expr (db_expr_t *valuep);
43 static boolean_t	db_term (db_expr_t *valuep);
44 static boolean_t	db_unary (db_expr_t *valuep);
45 
46 static boolean_t
47 db_term(db_expr_t *valuep)
48 {
49 	int	t;
50 
51 	t = db_read_token();
52 	if (t == tIDENT) {
53 	    if (!db_value_of_name(db_tok_string, valuep)) {
54 		db_error("Symbol not found\n");
55 		/*NOTREACHED*/
56 	    }
57 	    return (TRUE);
58 	}
59 	if (t == tNUMBER) {
60 	    *valuep = (db_expr_t)db_tok_number;
61 	    return (TRUE);
62 	}
63 	if (t == tDOT) {
64 	    *valuep = (db_expr_t)db_dot;
65 	    return (TRUE);
66 	}
67 	if (t == tDOTDOT) {
68 	    *valuep = (db_expr_t)db_prev;
69 	    return (TRUE);
70 	}
71 	if (t == tPLUS) {
72 	    *valuep = (db_expr_t) db_next;
73 	    return (TRUE);
74 	}
75 	if (t == tDITTO) {
76 	    *valuep = (db_expr_t)db_last_addr;
77 	    return (TRUE);
78 	}
79 	if (t == tDOLLAR) {
80 	    if (!db_get_variable(valuep))
81 		return (FALSE);
82 	    return (TRUE);
83 	}
84 	if (t == tLPAREN) {
85 	    if (!db_expression(valuep)) {
86 		db_error("Syntax error\n");
87 		/*NOTREACHED*/
88 	    }
89 	    t = db_read_token();
90 	    if (t != tRPAREN) {
91 		db_error("Syntax error\n");
92 		/*NOTREACHED*/
93 	    }
94 	    return (TRUE);
95 	}
96 	db_unread_token(t);
97 	return (FALSE);
98 }
99 
100 static boolean_t
101 db_unary(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(int), FALSE);
121 	    return (TRUE);
122 	}
123 	db_unread_token(t);
124 	return (db_term(valuep));
125 }
126 
127 static boolean_t
128 db_mult_expr(db_expr_t *valuep)
129 {
130 	db_expr_t	lhs, rhs;
131 	int		t;
132 
133 	*valuep = 0;	/* silence gcc */
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 = roundup(lhs, rhs);
157 	    }
158 	    t = db_read_token();
159 	}
160 	db_unread_token(t);
161 	*valuep = lhs;
162 	return (TRUE);
163 }
164 
165 static boolean_t
166 db_add_expr(db_expr_t *valuep)
167 {
168 	db_expr_t	lhs, rhs;
169 	int		t;
170 
171 	*valuep = 0;	/* silence gcc */
172 
173 	if (!db_mult_expr(&lhs))
174 	    return (FALSE);
175 
176 	t = db_read_token();
177 	while (t == tPLUS || t == tMINUS) {
178 	    if (!db_mult_expr(&rhs)) {
179 		db_error("Syntax error\n");
180 		/*NOTREACHED*/
181 	    }
182 	    if (t == tPLUS)
183 		lhs += rhs;
184 	    else
185 		lhs -= rhs;
186 	    t = db_read_token();
187 	}
188 	db_unread_token(t);
189 	*valuep = lhs;
190 	return (TRUE);
191 }
192 
193 static boolean_t
194 db_shift_expr(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) 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(db_expr_t *valuep)
227 {
228 	return (db_shift_expr(valuep));
229 }
230