Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / ddb / db_expr.c
CommitLineData
984263bc
MD
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
40static boolean_t db_add_expr __P((db_expr_t *valuep));
41static boolean_t db_mult_expr __P((db_expr_t *valuep));
42static boolean_t db_shift_expr __P((db_expr_t *valuep));
43static boolean_t db_term __P((db_expr_t *valuep));
44static boolean_t db_unary __P((db_expr_t *valuep));
45
46static boolean_t
47db_term(valuep)
48 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
101static boolean_t
102db_unary(valuep)
103 db_expr_t *valuep;
104{
105 int t;
106
107 t = db_read_token();
108 if (t == tMINUS) {
109 if (!db_unary(valuep)) {
110 db_error("Syntax error\n");
111 /*NOTREACHED*/
112 }
113 *valuep = -*valuep;
114 return (TRUE);
115 }
116 if (t == tSTAR) {
117 /* indirection */
118 if (!db_unary(valuep)) {
119 db_error("Syntax error\n");
120 /*NOTREACHED*/
121 }
122 *valuep = db_get_value((db_addr_t)*valuep, sizeof(int), FALSE);
123 return (TRUE);
124 }
125 db_unread_token(t);
126 return (db_term(valuep));
127}
128
129static boolean_t
130db_mult_expr(valuep)
131 db_expr_t *valuep;
132{
133 db_expr_t lhs, rhs;
134 int t;
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
166static boolean_t
167db_add_expr(valuep)
168 db_expr_t *valuep;
169{
170 db_expr_t lhs, rhs;
171 int t;
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
193static boolean_t
194db_shift_expr(valuep)
195 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
226int
227db_expression(valuep)
228 db_expr_t *valuep;
229{
230 return (db_shift_expr(valuep));
231}