db_expr.c revision 92756
160484Sobrien/* 278828Sobrien * Mach Operating System 360484Sobrien * Copyright (c) 1991,1990 Carnegie Mellon University 460484Sobrien * All Rights Reserved. 560484Sobrien * 660484Sobrien * Permission to use, copy, modify and distribute this software and its 760484Sobrien * documentation is hereby granted, provided that both the copyright 860484Sobrien * notice and this permission notice appear in all copies of the 960484Sobrien * software, derivative works or modified versions, and any portions 1060484Sobrien * thereof, and that both notices appear in supporting documentation. 1160484Sobrien * 1260484Sobrien * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 1360484Sobrien * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 1460484Sobrien * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 1560484Sobrien * 1660484Sobrien * Carnegie Mellon requests users of this software to return to 1760484Sobrien * 1860484Sobrien * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 1960484Sobrien * School of Computer Science 2060484Sobrien * Carnegie Mellon University 2160484Sobrien * Pittsburgh PA 15213-3890 2260484Sobrien * 2360484Sobrien * any improvements or extensions that they make and grant Carnegie the 2460484Sobrien * rights to redistribute these changes. 2560484Sobrien * 2660484Sobrien * $FreeBSD: head/sys/ddb/db_expr.c 92756 2002-03-20 05:14:42Z alfred $ 2760484Sobrien */ 2860484Sobrien 2960484Sobrien/* 3060484Sobrien * Author: David B. Golub, Carnegie Mellon University 3177298Sobrien * Date: 7/90 3260484Sobrien */ 3377298Sobrien#include <sys/param.h> 3477298Sobrien 3577298Sobrien#include <ddb/ddb.h> 3677298Sobrien#include <ddb/db_lex.h> 3777298Sobrien#include <ddb/db_access.h> 3877298Sobrien#include <ddb/db_command.h> 3977298Sobrien 4077298Sobrienstatic boolean_t db_add_expr(db_expr_t *valuep); 4177298Sobrienstatic boolean_t db_mult_expr(db_expr_t *valuep); 4277298Sobrienstatic boolean_t db_shift_expr(db_expr_t *valuep); 4377298Sobrienstatic boolean_t db_term(db_expr_t *valuep); 4477298Sobrienstatic boolean_t db_unary(db_expr_t *valuep); 4577298Sobrien 4660484Sobrienstatic boolean_t 4760484Sobriendb_term(valuep) 4860484Sobrien db_expr_t *valuep; 4960484Sobrien{ 5060484Sobrien int t; 5160484Sobrien 5260484Sobrien t = db_read_token(); 5360484Sobrien if (t == tIDENT) { 5460484Sobrien if (!db_value_of_name(db_tok_string, valuep)) { 5560484Sobrien db_error("Symbol not found\n"); 5660484Sobrien /*NOTREACHED*/ 5760484Sobrien } 5860484Sobrien return (TRUE); 5960484Sobrien } 6060484Sobrien if (t == tNUMBER) { 6160484Sobrien *valuep = (db_expr_t)db_tok_number; 6260484Sobrien return (TRUE); 6360484Sobrien } 6460484Sobrien if (t == tDOT) { 6560484Sobrien *valuep = (db_expr_t)db_dot; 6660484Sobrien return (TRUE); 6760484Sobrien } 6860484Sobrien if (t == tDOTDOT) { 6960484Sobrien *valuep = (db_expr_t)db_prev; 7060484Sobrien return (TRUE); 7160484Sobrien } 7260484Sobrien if (t == tPLUS) { 7360484Sobrien *valuep = (db_expr_t) db_next; 7460484Sobrien return (TRUE); 7560484Sobrien } 7660484Sobrien if (t == tDITTO) { 7760484Sobrien *valuep = (db_expr_t)db_last_addr; 7860484Sobrien return (TRUE); 7977298Sobrien } 8060484Sobrien if (t == tDOLLAR) { 8160484Sobrien if (!db_get_variable(valuep)) 8260484Sobrien return (FALSE); 8360484Sobrien return (TRUE); 8460484Sobrien } 8560484Sobrien if (t == tLPAREN) { 8660484Sobrien if (!db_expression(valuep)) { 8760484Sobrien db_error("Syntax error\n"); 8860484Sobrien /*NOTREACHED*/ 8960484Sobrien } 9060484Sobrien t = db_read_token(); 9160484Sobrien if (t != tRPAREN) { 9260484Sobrien db_error("Syntax error\n"); 9360484Sobrien /*NOTREACHED*/ 9460484Sobrien } 9560484Sobrien return (TRUE); 9660484Sobrien } 9760484Sobrien db_unread_token(t); 9860484Sobrien return (FALSE); 9977298Sobrien} 10077298Sobrien 10177298Sobrienstatic boolean_t 10277298Sobriendb_unary(valuep) 10377298Sobrien db_expr_t *valuep; 10477298Sobrien{ 10560484Sobrien int t; 10677298Sobrien 10777298Sobrien t = db_read_token(); 10877298Sobrien if (t == tMINUS) { 10977298Sobrien if (!db_unary(valuep)) { 11077298Sobrien db_error("Syntax error\n"); 11177298Sobrien /*NOTREACHED*/ 11260484Sobrien } 11377298Sobrien *valuep = -*valuep; 11477298Sobrien return (TRUE); 11577298Sobrien } 11677298Sobrien if (t == tSTAR) { 11777298Sobrien /* indirection */ 11877298Sobrien if (!db_unary(valuep)) { 11977298Sobrien db_error("Syntax error\n"); 12060484Sobrien /*NOTREACHED*/ 12177298Sobrien } 12277298Sobrien *valuep = db_get_value((db_addr_t)*valuep, sizeof(int), FALSE); 12360484Sobrien return (TRUE); 12477298Sobrien } 12577298Sobrien db_unread_token(t); 12677298Sobrien return (db_term(valuep)); 12777298Sobrien} 12860484Sobrien 12977298Sobrienstatic boolean_t 13077298Sobriendb_mult_expr(valuep) 13177298Sobrien db_expr_t *valuep; 13277298Sobrien{ 13377298Sobrien db_expr_t lhs, rhs; 13477298Sobrien int t; 13577298Sobrien 13677298Sobrien if (!db_unary(&lhs)) 13777298Sobrien return (FALSE); 13877298Sobrien 13977298Sobrien t = db_read_token(); 14077298Sobrien while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) { 14177298Sobrien if (!db_term(&rhs)) { 14277298Sobrien db_error("Syntax error\n"); 14377298Sobrien /*NOTREACHED*/ 14477298Sobrien } 14577298Sobrien if (t == tSTAR) 14677298Sobrien lhs *= rhs; 14777298Sobrien else { 14877298Sobrien if (rhs == 0) { 14977298Sobrien db_error("Divide by 0\n"); 15077298Sobrien /*NOTREACHED*/ 15177298Sobrien } 15277298Sobrien if (t == tSLASH) 15377298Sobrien lhs /= rhs; 15477298Sobrien else if (t == tPCT) 15577298Sobrien lhs %= rhs; 15677298Sobrien else 15777298Sobrien lhs = ((lhs+rhs-1)/rhs)*rhs; 15877298Sobrien } 15977298Sobrien t = db_read_token(); 16077298Sobrien } 16177298Sobrien db_unread_token(t); 16277298Sobrien *valuep = lhs; 16377298Sobrien return (TRUE); 16477298Sobrien} 16577298Sobrien 16677298Sobrienstatic boolean_t 16777298Sobriendb_add_expr(valuep) 16877298Sobrien db_expr_t *valuep; 16977298Sobrien{ 17077298Sobrien db_expr_t lhs, rhs; 17177298Sobrien int t; 17277298Sobrien 17377298Sobrien if (!db_mult_expr(&lhs)) 17477298Sobrien return (FALSE); 17577298Sobrien 17677298Sobrien t = db_read_token(); 17777298Sobrien while (t == tPLUS || t == tMINUS) { 17877298Sobrien if (!db_mult_expr(&rhs)) { 17977298Sobrien db_error("Syntax error\n"); 18077298Sobrien /*NOTREACHED*/ 18177298Sobrien } 18277298Sobrien if (t == tPLUS) 18377298Sobrien lhs += rhs; 18477298Sobrien else 18577298Sobrien lhs -= rhs; 18677298Sobrien t = db_read_token(); 18777298Sobrien } 18877298Sobrien db_unread_token(t); 18977298Sobrien *valuep = lhs; 19077298Sobrien return (TRUE); 19177298Sobrien} 19277298Sobrien 19377298Sobrienstatic boolean_t 19477298Sobriendb_shift_expr(valuep) 19577298Sobrien db_expr_t *valuep; 19677298Sobrien{ 19777298Sobrien db_expr_t lhs, rhs; 19877298Sobrien int t; 19977298Sobrien 20077298Sobrien if (!db_add_expr(&lhs)) 20177298Sobrien return (FALSE); 20260484Sobrien 20377298Sobrien t = db_read_token(); 20477298Sobrien while (t == tSHIFT_L || t == tSHIFT_R) { 20577298Sobrien if (!db_add_expr(&rhs)) { 20677298Sobrien db_error("Syntax error\n"); 20760484Sobrien /*NOTREACHED*/ 20860484Sobrien } 20977298Sobrien if (rhs < 0) { 21077298Sobrien db_error("Negative shift amount\n"); 21177298Sobrien /*NOTREACHED*/ 21277298Sobrien } 21377298Sobrien if (t == tSHIFT_L) 21477298Sobrien lhs <<= rhs; 21560484Sobrien else { 21677298Sobrien /* Shift right is unsigned */ 21777298Sobrien lhs = (unsigned) lhs >> rhs; 21877298Sobrien } 21977298Sobrien t = db_read_token(); 22060484Sobrien } 22177298Sobrien db_unread_token(t); 22277298Sobrien *valuep = lhs; 22360484Sobrien return (TRUE); 22477298Sobrien} 22560484Sobrien 22677298Sobrienint 22777298Sobriendb_expression(valuep) 22877298Sobrien db_expr_t *valuep; 22977298Sobrien{ 23060484Sobrien return (db_shift_expr(valuep)); 23177298Sobrien} 23277298Sobrien