db_expr.c revision 12734
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 *	$Id: db_expr.c,v 1.8 1995/12/07 12:44:50 davidg Exp $
27 */
28
29/*
30 *	Author: David B. Golub, Carnegie Mellon University
31 *	Date:	7/90
32 */
33#include <sys/param.h>
34#include <sys/systm.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
41static boolean_t	db_add_expr __P((db_expr_t *valuep));
42static boolean_t	db_mult_expr __P((db_expr_t *valuep));
43static boolean_t	db_shift_expr __P((db_expr_t *valuep));
44static boolean_t	db_term __P((db_expr_t *valuep));
45static boolean_t	db_unary __P((db_expr_t *valuep));
46
47static boolean_t
48db_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
102static boolean_t
103db_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(int), FALSE);
124	    return (TRUE);
125	}
126	db_unread_token(t);
127	return (db_term(valuep));
128}
129
130static boolean_t
131db_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
167static boolean_t
168db_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
194static boolean_t
195db_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
227int
228db_expression(valuep)
229	db_expr_t *valuep;
230{
231	return (db_shift_expr(valuep));
232}
233