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 /* 27 * $Id: db_expr.c,v 1.2 1993/05/20 03:39:13 cgd Exp $ 28 * 29 * HISTORY 30 * $Log: db_expr.c,v $ 31 * Revision 1.2 1993/05/20 03:39:13 cgd 32 * add explicit rcs id 33 * 34 * Revision 1.1.1.1 1993/03/21 09:46:26 cgd 35 * initial import of 386bsd-0.1 sources 36 * 37 * Revision 1.1 1992/03/25 21:45:09 pace 38 * Initial revision 39 * 40 * Revision 2.3 91/02/05 17:06:25 mrt 41 * Changed to new Mach copyright 42 * [91/01/31 16:17:46 mrt] 43 * 44 * Revision 2.2 90/08/27 21:50:57 dbg 45 * Use '..' instead of '$$' for db_prev. 46 * Use '+' for db_next. 47 * [90/08/22 dbg] 48 * 49 * Allow repeated unary operators. 50 * [90/08/20 dbg] 51 * 52 * Reflected back rename of db_symbol_value->db_value_of_name 53 * [90/08/20 af] 54 * Reduce lint. 55 * [90/08/07 dbg] 56 * Created. 57 * [90/07/25 dbg] 58 * 59 */ 60 /* 61 * Author: David B. Golub, Carnegie Mellon University 62 * Date: 7/90 63 */ 64 #include "param.h" 65 #include "proc.h" 66 #include <machine/db_machdep.h> 67 #include <ddb/db_lex.h> 68 #include <ddb/db_access.h> 69 #include <ddb/db_command.h> 70 71 boolean_t 72 db_term(valuep) 73 db_expr_t *valuep; 74 { 75 int t; 76 77 t = db_read_token(); 78 if (t == tIDENT) { 79 if (!db_value_of_name(db_tok_string, valuep)) { 80 db_error("Symbol not found\n"); 81 /*NOTREACHED*/ 82 } 83 return (TRUE); 84 } 85 if (t == tNUMBER) { 86 *valuep = (db_expr_t)db_tok_number; 87 return (TRUE); 88 } 89 if (t == tDOT) { 90 *valuep = (db_expr_t)db_dot; 91 return (TRUE); 92 } 93 if (t == tDOTDOT) { 94 *valuep = (db_expr_t)db_prev; 95 return (TRUE); 96 } 97 if (t == tPLUS) { 98 *valuep = (db_expr_t) db_next; 99 return (TRUE); 100 } 101 if (t == tDITTO) { 102 *valuep = (db_expr_t)db_last_addr; 103 return (TRUE); 104 } 105 if (t == tDOLLAR) { 106 if (!db_get_variable(valuep)) 107 return (FALSE); 108 return (TRUE); 109 } 110 if (t == tLPAREN) { 111 if (!db_expression(valuep)) { 112 db_error("Syntax error\n"); 113 /*NOTREACHED*/ 114 } 115 t = db_read_token(); 116 if (t != tRPAREN) { 117 db_error("Syntax error\n"); 118 /*NOTREACHED*/ 119 } 120 return (TRUE); 121 } 122 db_unread_token(t); 123 return (FALSE); 124 } 125 126 boolean_t 127 db_unary(valuep) 128 db_expr_t *valuep; 129 { 130 int t; 131 132 t = db_read_token(); 133 if (t == tMINUS) { 134 if (!db_unary(valuep)) { 135 db_error("Syntax error\n"); 136 /*NOTREACHED*/ 137 } 138 *valuep = -*valuep; 139 return (TRUE); 140 } 141 if (t == tSTAR) { 142 /* indirection */ 143 if (!db_unary(valuep)) { 144 db_error("Syntax error\n"); 145 /*NOTREACHED*/ 146 } 147 *valuep = db_get_value((db_addr_t)*valuep, sizeof(int), FALSE); 148 return (TRUE); 149 } 150 db_unread_token(t); 151 return (db_term(valuep)); 152 } 153 154 boolean_t 155 db_mult_expr(valuep) 156 db_expr_t *valuep; 157 { 158 db_expr_t lhs, rhs; 159 int t; 160 161 if (!db_unary(&lhs)) 162 return (FALSE); 163 164 t = db_read_token(); 165 while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) { 166 if (!db_term(&rhs)) { 167 db_error("Syntax error\n"); 168 /*NOTREACHED*/ 169 } 170 if (t == tSTAR) 171 lhs *= rhs; 172 else { 173 if (rhs == 0) { 174 db_error("Divide by 0\n"); 175 /*NOTREACHED*/ 176 } 177 if (t == tSLASH) 178 lhs /= rhs; 179 else if (t == tPCT) 180 lhs %= rhs; 181 else 182 lhs = ((lhs+rhs-1)/rhs)*rhs; 183 } 184 t = db_read_token(); 185 } 186 db_unread_token(t); 187 *valuep = lhs; 188 return (TRUE); 189 } 190 191 boolean_t 192 db_add_expr(valuep) 193 db_expr_t *valuep; 194 { 195 db_expr_t lhs, rhs; 196 int t; 197 198 if (!db_mult_expr(&lhs)) 199 return (FALSE); 200 201 t = db_read_token(); 202 while (t == tPLUS || t == tMINUS) { 203 if (!db_mult_expr(&rhs)) { 204 db_error("Syntax error\n"); 205 /*NOTREACHED*/ 206 } 207 if (t == tPLUS) 208 lhs += rhs; 209 else 210 lhs -= rhs; 211 t = db_read_token(); 212 } 213 db_unread_token(t); 214 *valuep = lhs; 215 return (TRUE); 216 } 217 218 boolean_t 219 db_shift_expr(valuep) 220 db_expr_t *valuep; 221 { 222 db_expr_t lhs, rhs; 223 int t; 224 225 if (!db_add_expr(&lhs)) 226 return (FALSE); 227 228 t = db_read_token(); 229 while (t == tSHIFT_L || t == tSHIFT_R) { 230 if (!db_add_expr(&rhs)) { 231 db_error("Syntax error\n"); 232 /*NOTREACHED*/ 233 } 234 if (rhs < 0) { 235 db_error("Negative shift amount\n"); 236 /*NOTREACHED*/ 237 } 238 if (t == tSHIFT_L) 239 lhs <<= rhs; 240 else { 241 /* Shift right is unsigned */ 242 lhs = (unsigned) lhs >> rhs; 243 } 244 t = db_read_token(); 245 } 246 db_unread_token(t); 247 *valuep = lhs; 248 return (TRUE); 249 } 250 251 int 252 db_expression(valuep) 253 db_expr_t *valuep; 254 { 255 return (db_shift_expr(valuep)); 256 } 257