xref: /openbsd-src/sys/ddb/db_expr.c (revision 5abbae66b5e7fc2af1a57a9b0613a01a9b5801d6)
1*5abbae66Sderaadt /*	$OpenBSD: db_expr.c,v 1.18 2020/10/15 03:14:00 deraadt Exp $	*/
2d724e01aSderaadt /*	$NetBSD: db_expr.c,v 1.5 1996/02/05 01:56:58 christos Exp $	*/
3df930be7Sderaadt 
4df930be7Sderaadt /*
5df930be7Sderaadt  * Mach Operating System
6b2471a9dSmickey  * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
7df930be7Sderaadt  * All Rights Reserved.
8df930be7Sderaadt  *
9df930be7Sderaadt  * Permission to use, copy, modify and distribute this software and its
10df930be7Sderaadt  * documentation is hereby granted, provided that both the copyright
11df930be7Sderaadt  * notice and this permission notice appear in all copies of the
12df930be7Sderaadt  * software, derivative works or modified versions, and any portions
13df930be7Sderaadt  * thereof, and that both notices appear in supporting documentation.
14df930be7Sderaadt  *
15b2471a9dSmickey  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16df930be7Sderaadt  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
17df930be7Sderaadt  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18df930be7Sderaadt  *
19df930be7Sderaadt  * Carnegie Mellon requests users of this software to return to
20df930be7Sderaadt  *
21df930be7Sderaadt  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
22df930be7Sderaadt  *  School of Computer Science
23df930be7Sderaadt  *  Carnegie Mellon University
24df930be7Sderaadt  *  Pittsburgh PA 15213-3890
25df930be7Sderaadt  *
26b2471a9dSmickey  * any improvements or extensions that they make and grant Carnegie Mellon
27b2471a9dSmickey  * the rights to redistribute these changes.
28df930be7Sderaadt  *
29df930be7Sderaadt  *	Author: David B. Golub, Carnegie Mellon University
30df930be7Sderaadt  *	Date:	7/90
31df930be7Sderaadt  */
32df930be7Sderaadt 
33df930be7Sderaadt #include <sys/param.h>
34df930be7Sderaadt 
35df930be7Sderaadt #include <machine/db_machdep.h>
36df930be7Sderaadt 
37df930be7Sderaadt #include <ddb/db_lex.h>
38df930be7Sderaadt #include <ddb/db_access.h>
39df930be7Sderaadt #include <ddb/db_command.h>
403ed44a89Smickey #include <ddb/db_sym.h>
413ed44a89Smickey #include <ddb/db_extern.h>
423ed44a89Smickey #include <ddb/db_variables.h>
43df930be7Sderaadt 
448383b4f2Smpi int db_term(db_expr_t *);
458383b4f2Smpi int db_unary(db_expr_t *);
468383b4f2Smpi int db_mult_expr(db_expr_t *);
478383b4f2Smpi int db_add_expr(db_expr_t *);
488383b4f2Smpi int db_shift_expr(db_expr_t *);
49d6f4c764Smpi 
508383b4f2Smpi int
db_term(db_expr_t * valuep)516ecb06d0Sjsg db_term(db_expr_t *valuep)
52df930be7Sderaadt {
53df930be7Sderaadt 	int	t;
54df930be7Sderaadt 
55df930be7Sderaadt 	t = db_read_token();
56df930be7Sderaadt 	if (t == tIDENT) {
57ad205586Smpi 		if (db_symbol_by_name(db_tok_string, valuep) == NULL) {
58df930be7Sderaadt 			db_error("Symbol not found\n");
59df930be7Sderaadt 			/*NOTREACHED*/
60df930be7Sderaadt 		}
618383b4f2Smpi 		return 1;
62df930be7Sderaadt 	}
63df930be7Sderaadt 	if (t == tNUMBER) {
641bc2ec2bSniklas 		*valuep = db_tok_number;
658383b4f2Smpi 		return 1;
66df930be7Sderaadt 	}
67df930be7Sderaadt 	if (t == tDOT) {
68df930be7Sderaadt 		*valuep = (db_expr_t)db_dot;
698383b4f2Smpi 		return 1;
70df930be7Sderaadt 	}
71df930be7Sderaadt 	if (t == tDOTDOT) {
72df930be7Sderaadt 		*valuep = (db_expr_t)db_prev;
738383b4f2Smpi 		return 1;
74df930be7Sderaadt 	}
75df930be7Sderaadt 	if (t == tPLUS) {
76df930be7Sderaadt 		*valuep = (db_expr_t) db_next;
778383b4f2Smpi 		return 1;
78df930be7Sderaadt 	}
79df930be7Sderaadt 	if (t == tDITTO) {
80df930be7Sderaadt 		*valuep = (db_expr_t)db_last_addr;
818383b4f2Smpi 		return 1;
82df930be7Sderaadt 	}
83df930be7Sderaadt 	if (t == tDOLLAR) {
84df930be7Sderaadt 		if (!db_get_variable(valuep))
858383b4f2Smpi 			return 0;
868383b4f2Smpi 		return 1;
87df930be7Sderaadt 	}
88df930be7Sderaadt 	if (t == tLPAREN) {
89df930be7Sderaadt 		if (!db_expression(valuep)) {
90df930be7Sderaadt 			db_error("Syntax error\n");
91df930be7Sderaadt 			/*NOTREACHED*/
92df930be7Sderaadt 		}
93df930be7Sderaadt 		t = db_read_token();
94df930be7Sderaadt 		if (t != tRPAREN) {
95df930be7Sderaadt 			db_error("Syntax error\n");
96df930be7Sderaadt 			/*NOTREACHED*/
97df930be7Sderaadt 		}
988383b4f2Smpi 		return 1;
99df930be7Sderaadt 	}
100df930be7Sderaadt 	db_unread_token(t);
1018383b4f2Smpi 	return 0;
102df930be7Sderaadt }
103df930be7Sderaadt 
1048383b4f2Smpi int
db_unary(db_expr_t * valuep)1056ecb06d0Sjsg db_unary(db_expr_t *valuep)
106df930be7Sderaadt {
107df930be7Sderaadt 	int	t;
108df930be7Sderaadt 
109df930be7Sderaadt 	t = db_read_token();
110df930be7Sderaadt 	if (t == tMINUS) {
111df930be7Sderaadt 		if (!db_unary(valuep)) {
112df930be7Sderaadt 			db_error("Syntax error\n");
113df930be7Sderaadt 			/*NOTREACHED*/
114df930be7Sderaadt 		}
115df930be7Sderaadt 		*valuep = -*valuep;
1168383b4f2Smpi 		return 1;
117df930be7Sderaadt 	}
118df930be7Sderaadt 	if (t == tSTAR) {
119df930be7Sderaadt 		/* indirection */
120df930be7Sderaadt 		if (!db_unary(valuep)) {
121df930be7Sderaadt 			db_error("Syntax error\n");
122df930be7Sderaadt 			/*NOTREACHED*/
123df930be7Sderaadt 		}
12408f058f8Smpi 		*valuep = db_get_value((vaddr_t)*valuep, sizeof(vaddr_t), 0);
1258383b4f2Smpi 		return 1;
126df930be7Sderaadt 	}
127df930be7Sderaadt 	db_unread_token(t);
128df930be7Sderaadt 	return (db_term(valuep));
129df930be7Sderaadt }
130df930be7Sderaadt 
1318383b4f2Smpi int
db_mult_expr(db_expr_t * valuep)1326ecb06d0Sjsg db_mult_expr(db_expr_t *valuep)
133df930be7Sderaadt {
134df930be7Sderaadt 	db_expr_t	lhs, rhs;
135df930be7Sderaadt 	int		t;
136df930be7Sderaadt 
137df930be7Sderaadt 	if (!db_unary(&lhs))
1388383b4f2Smpi 		return 0;
139df930be7Sderaadt 
140df930be7Sderaadt 	t = db_read_token();
141df930be7Sderaadt 	while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) {
142df930be7Sderaadt 		if (!db_term(&rhs)) {
143df930be7Sderaadt 			db_error("Syntax error\n");
144df930be7Sderaadt 			/*NOTREACHED*/
145df930be7Sderaadt 		}
146df930be7Sderaadt 		if (t == tSTAR)
147df930be7Sderaadt 			lhs *= rhs;
148df930be7Sderaadt 		else {
149df930be7Sderaadt 			if (rhs == 0) {
150df930be7Sderaadt 				db_error("Divide by 0\n");
151df930be7Sderaadt 				/*NOTREACHED*/
152df930be7Sderaadt 			}
153df930be7Sderaadt 			if (t == tSLASH)
154df930be7Sderaadt 				lhs /= rhs;
155df930be7Sderaadt 			else if (t == tPCT)
156df930be7Sderaadt 				lhs %= rhs;
157df930be7Sderaadt 			else
158df930be7Sderaadt 				lhs = ((lhs+rhs-1)/rhs)*rhs;
159df930be7Sderaadt 		}
160df930be7Sderaadt 		t = db_read_token();
161df930be7Sderaadt 	}
162df930be7Sderaadt 	db_unread_token(t);
163df930be7Sderaadt 	*valuep = lhs;
1648383b4f2Smpi 	return 1;
165df930be7Sderaadt }
166df930be7Sderaadt 
1678383b4f2Smpi int
db_add_expr(db_expr_t * valuep)1686ecb06d0Sjsg db_add_expr(db_expr_t *valuep)
169df930be7Sderaadt {
170df930be7Sderaadt 	db_expr_t	lhs, rhs;
171df930be7Sderaadt 	int		t;
172df930be7Sderaadt 
173df930be7Sderaadt 	if (!db_mult_expr(&lhs))
1748383b4f2Smpi 		return 0;
175df930be7Sderaadt 
176df930be7Sderaadt 	t = db_read_token();
177df930be7Sderaadt 	while (t == tPLUS || t == tMINUS) {
178df930be7Sderaadt 		if (!db_mult_expr(&rhs)) {
179df930be7Sderaadt 			db_error("Syntax error\n");
180df930be7Sderaadt 			/*NOTREACHED*/
181df930be7Sderaadt 		}
182df930be7Sderaadt 		if (t == tPLUS)
183df930be7Sderaadt 			lhs += rhs;
184df930be7Sderaadt 		else
185df930be7Sderaadt 			lhs -= rhs;
186df930be7Sderaadt 		t = db_read_token();
187df930be7Sderaadt 	}
188df930be7Sderaadt 	db_unread_token(t);
189df930be7Sderaadt 	*valuep = lhs;
1908383b4f2Smpi 	return 1;
191df930be7Sderaadt }
192df930be7Sderaadt 
1938383b4f2Smpi int
db_shift_expr(db_expr_t * valuep)1946ecb06d0Sjsg db_shift_expr(db_expr_t *valuep)
195df930be7Sderaadt {
196df930be7Sderaadt 	db_expr_t	lhs, rhs;
197df930be7Sderaadt 	int		t;
198df930be7Sderaadt 
199df930be7Sderaadt 	if (!db_add_expr(&lhs))
2008383b4f2Smpi 		return 0;
201df930be7Sderaadt 
202df930be7Sderaadt 	t = db_read_token();
203df930be7Sderaadt 	while (t == tSHIFT_L || t == tSHIFT_R) {
204df930be7Sderaadt 		if (!db_add_expr(&rhs)) {
205df930be7Sderaadt 			db_error("Syntax error\n");
206df930be7Sderaadt 			/*NOTREACHED*/
207df930be7Sderaadt 		}
208df930be7Sderaadt 		if (rhs < 0) {
209df930be7Sderaadt 			db_error("Negative shift amount\n");
210df930be7Sderaadt 			/*NOTREACHED*/
211df930be7Sderaadt 		}
212df930be7Sderaadt 		if (t == tSHIFT_L)
213df930be7Sderaadt 			lhs <<= rhs;
214df930be7Sderaadt 		else {
215df930be7Sderaadt 			/* Shift right is unsigned */
216df930be7Sderaadt 			lhs = (unsigned) lhs >> rhs;
217df930be7Sderaadt 		}
218df930be7Sderaadt 		t = db_read_token();
219df930be7Sderaadt 	}
220df930be7Sderaadt 	db_unread_token(t);
221df930be7Sderaadt 	*valuep = lhs;
2228383b4f2Smpi 	return 1;
223df930be7Sderaadt }
224df930be7Sderaadt 
225df930be7Sderaadt int
db_expression(db_expr_t * valuep)2266ecb06d0Sjsg db_expression(db_expr_t *valuep)
227df930be7Sderaadt {
228df930be7Sderaadt 	return (db_shift_expr(valuep));
229df930be7Sderaadt }
230