1 /* $NetBSD: db_expr.c,v 1.11 2000/07/09 01:52:17 mycroft Exp $ */ 2 3 /* 4 * Mach Operating System 5 * Copyright (c) 1991,1990 Carnegie Mellon University 6 * All Rights Reserved. 7 * 8 * Permission to use, copy, modify and distribute this software and its 9 * documentation is hereby granted, provided that both the copyright 10 * notice and this permission notice appear in all copies of the 11 * software, derivative works or modified versions, and any portions 12 * thereof, and that both notices appear in supporting documentation. 13 * 14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 * 18 * Carnegie Mellon requests users of this software to return to 19 * 20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 21 * School of Computer Science 22 * Carnegie Mellon University 23 * Pittsburgh PA 15213-3890 24 * 25 * any improvements or extensions that they make and grant Carnegie the 26 * rights to redistribute these changes. 27 * 28 * Author: David B. Golub, Carnegie Mellon University 29 * Date: 7/90 30 */ 31 32 #include <sys/param.h> 33 #include <sys/proc.h> 34 35 #include <machine/db_machdep.h> 36 37 #include <ddb/db_lex.h> 38 #include <ddb/db_access.h> 39 #include <ddb/db_command.h> 40 #include <ddb/db_sym.h> 41 #include <ddb/db_extern.h> 42 #include <ddb/db_variables.h> 43 44 boolean_t 45 db_term(valuep) 46 db_expr_t *valuep; 47 { 48 int t; 49 50 t = db_read_token(); 51 if (t == tIDENT) { 52 if (!db_value_of_name(db_tok_string, valuep)) { 53 extern int db_radix; 54 db_expr_t v = 0; 55 int i, c, byte; 56 57 /* See if we can make a number out of all of it */ 58 for (i = 0; (c = db_tok_string[i]) != '\0'; i++) { 59 byte = 0; 60 if (c >= '0' && c <= '9') 61 byte = c - '0'; 62 else if (db_radix == 16 && c >= 'a' && c <= 'f') 63 byte = c - 'a' + 10; 64 else if (db_radix == 16 && c >= 'A' && c <= 'F') 65 byte = c - 'A' + 10; 66 else 67 db_error("Symbol not found\n"); 68 /*NOTREACHED*/ 69 v = v * db_radix + byte; 70 } 71 *valuep = (db_expr_t)v; 72 } 73 return (TRUE); 74 } 75 if (t == tNUMBER) { 76 *valuep = (db_expr_t)db_tok_number; 77 return (TRUE); 78 } 79 if (t == tDOT) { 80 *valuep = (db_expr_t)db_dot; 81 return (TRUE); 82 } 83 if (t == tDOTDOT) { 84 *valuep = (db_expr_t)db_prev; 85 return (TRUE); 86 } 87 if (t == tPLUS) { 88 *valuep = (db_expr_t) db_next; 89 return (TRUE); 90 } 91 if (t == tDITTO) { 92 *valuep = (db_expr_t)db_last_addr; 93 return (TRUE); 94 } 95 if (t == tDOLLAR) { 96 if (!db_get_variable(valuep)) 97 return (FALSE); 98 return (TRUE); 99 } 100 if (t == tLPAREN) { 101 if (!db_expression(valuep)) { 102 db_error("Syntax error\n"); 103 /*NOTREACHED*/ 104 } 105 t = db_read_token(); 106 if (t != tRPAREN) { 107 db_error("Syntax error\n"); 108 /*NOTREACHED*/ 109 } 110 return (TRUE); 111 } 112 db_unread_token(t); 113 return (FALSE); 114 } 115 116 boolean_t 117 db_unary(valuep) 118 db_expr_t *valuep; 119 { 120 int t; 121 122 t = db_read_token(); 123 if (t == tMINUS) { 124 if (!db_unary(valuep)) { 125 db_error("Syntax error\n"); 126 /*NOTREACHED*/ 127 } 128 *valuep = -*valuep; 129 return (TRUE); 130 } 131 if (t == tSTAR) { 132 /* indirection */ 133 if (!db_unary(valuep)) { 134 db_error("Syntax error\n"); 135 /*NOTREACHED*/ 136 } 137 *valuep = db_get_value((db_addr_t)*valuep, sizeof(db_expr_t), 138 FALSE); 139 return (TRUE); 140 } 141 db_unread_token(t); 142 return (db_term(valuep)); 143 } 144 145 boolean_t 146 db_mult_expr(valuep) 147 db_expr_t *valuep; 148 { 149 db_expr_t lhs, rhs; 150 int t; 151 152 if (!db_unary(&lhs)) 153 return (FALSE); 154 155 t = db_read_token(); 156 while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) { 157 if (!db_term(&rhs)) { 158 db_error("Syntax error\n"); 159 /*NOTREACHED*/ 160 } 161 if (t == tSTAR) 162 lhs *= rhs; 163 else { 164 if (rhs == 0) { 165 db_error("Divide by 0\n"); 166 /*NOTREACHED*/ 167 } 168 if (t == tSLASH) 169 lhs /= rhs; 170 else if (t == tPCT) 171 lhs %= rhs; 172 else 173 lhs = ((lhs+rhs-1)/rhs)*rhs; 174 } 175 t = db_read_token(); 176 } 177 db_unread_token(t); 178 *valuep = lhs; 179 return (TRUE); 180 } 181 182 boolean_t 183 db_add_expr(valuep) 184 db_expr_t *valuep; 185 { 186 db_expr_t lhs, rhs; 187 int t; 188 189 if (!db_mult_expr(&lhs)) 190 return (FALSE); 191 192 t = db_read_token(); 193 while (t == tPLUS || t == tMINUS) { 194 if (!db_mult_expr(&rhs)) { 195 db_error("Syntax error\n"); 196 /*NOTREACHED*/ 197 } 198 if (t == tPLUS) 199 lhs += rhs; 200 else 201 lhs -= rhs; 202 t = db_read_token(); 203 } 204 db_unread_token(t); 205 *valuep = lhs; 206 return (TRUE); 207 } 208 209 boolean_t 210 db_shift_expr(valuep) 211 db_expr_t *valuep; 212 { 213 db_expr_t lhs, rhs; 214 int t; 215 216 if (!db_add_expr(&lhs)) 217 return (FALSE); 218 219 t = db_read_token(); 220 while (t == tSHIFT_L || t == tSHIFT_R) { 221 if (!db_add_expr(&rhs)) { 222 db_error("Syntax error\n"); 223 /*NOTREACHED*/ 224 } 225 if (rhs < 0) { 226 db_error("Negative shift amount\n"); 227 /*NOTREACHED*/ 228 } 229 if (t == tSHIFT_L) 230 lhs <<= rhs; 231 else { 232 /* Shift right is unsigned */ 233 lhs = (unsigned long) lhs >> rhs; 234 } 235 t = db_read_token(); 236 } 237 db_unread_token(t); 238 *valuep = lhs; 239 return (TRUE); 240 } 241 242 int 243 db_expression(valuep) 244 db_expr_t *valuep; 245 { 246 return (db_shift_expr(valuep)); 247 } 248