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