db_expr.c revision 50477
162607Sitojun/* 262607Sitojun * Mach Operating System 355163Sshin * Copyright (c) 1991,1990 Carnegie Mellon University 455163Sshin * All Rights Reserved. 555163Sshin * 655163Sshin * Permission to use, copy, modify and distribute this software and its 762607Sitojun * documentation is hereby granted, provided that both the copyright 855163Sshin * notice and this permission notice appear in all copies of the 955163Sshin * software, derivative works or modified versions, and any portions 1055163Sshin * thereof, and that both notices appear in supporting documentation. 1155163Sshin * 1255163Sshin * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 1355163Sshin * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 1455163Sshin * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 1555163Sshin * 1655163Sshin * Carnegie Mellon requests users of this software to return to 1755163Sshin * 1855163Sshin * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 1962607Sitojun * School of Computer Science 2055163Sshin * Carnegie Mellon University 2155163Sshin * Pittsburgh PA 15213-3890 2255163Sshin * 2355163Sshin * any improvements or extensions that they make and grant Carnegie the 2455163Sshin * rights to redistribute these changes. 2555163Sshin * 2655163Sshin * $FreeBSD: head/sys/ddb/db_expr.c 50477 1999-08-28 01:08:13Z peter $ 2755163Sshin */ 2855163Sshin 2955163Sshin/* 3055163Sshin * Author: David B. Golub, Carnegie Mellon University 3155163Sshin * Date: 7/90 3255163Sshin */ 3355163Sshin#include <sys/param.h> 3462607Sitojun 3555163Sshin#include <ddb/ddb.h> 3655163Sshin#include <ddb/db_lex.h> 3755163Sshin#include <ddb/db_access.h> 3855163Sshin#include <ddb/db_command.h> 3955163Sshin 4055163Sshinstatic boolean_t db_add_expr __P((db_expr_t *valuep)); 4155163Sshinstatic boolean_t db_mult_expr __P((db_expr_t *valuep)); 4255163Sshinstatic boolean_t db_shift_expr __P((db_expr_t *valuep)); 4355163Sshinstatic boolean_t db_term __P((db_expr_t *valuep)); 4455163Sshinstatic boolean_t db_unary __P((db_expr_t *valuep)); 4555163Sshin 4655163Sshinstatic boolean_t 4755163Sshindb_term(valuep) 4855163Sshin db_expr_t *valuep; 4955163Sshin{ 5055163Sshin int t; 5162607Sitojun 5255163Sshin t = db_read_token(); 5355163Sshin if (t == tIDENT) { 5455163Sshin if (!db_value_of_name(db_tok_string, valuep)) { 5555163Sshin db_error("Symbol not found\n"); 5655163Sshin /*NOTREACHED*/ 5755163Sshin } 5855163Sshin return (TRUE); 5955163Sshin } 6062607Sitojun if (t == tNUMBER) { 6155163Sshin *valuep = (db_expr_t)db_tok_number; 6262607Sitojun return (TRUE); 6355163Sshin } 6462607Sitojun if (t == tDOT) { 6555163Sshin *valuep = (db_expr_t)db_dot; 6662607Sitojun return (TRUE); 6762607Sitojun } 6862607Sitojun if (t == tDOTDOT) { 6955163Sshin *valuep = (db_expr_t)db_prev; 7062607Sitojun return (TRUE); 7162607Sitojun } 7255163Sshin if (t == tPLUS) { 7355163Sshin *valuep = (db_expr_t) db_next; 7455163Sshin return (TRUE); 7555163Sshin } 7655163Sshin if (t == tDITTO) { 7762607Sitojun *valuep = (db_expr_t)db_last_addr; 7862607Sitojun return (TRUE); 7962607Sitojun } 8055163Sshin if (t == tDOLLAR) { 8155163Sshin if (!db_get_variable(valuep)) 8255163Sshin return (FALSE); 8355163Sshin return (TRUE); 8455163Sshin } 8555163Sshin if (t == tLPAREN) { 8655163Sshin if (!db_expression(valuep)) { 8755163Sshin db_error("Syntax error\n"); 8855163Sshin /*NOTREACHED*/ 8955163Sshin } 9055163Sshin t = db_read_token(); 9155163Sshin if (t != tRPAREN) { 9255163Sshin db_error("Syntax error\n"); 9355163Sshin /*NOTREACHED*/ 9462607Sitojun } 9555163Sshin return (TRUE); 9662607Sitojun } 9755163Sshin db_unread_token(t); 9855163Sshin return (FALSE); 9955163Sshin} 10055163Sshin 10155163Sshinstatic boolean_t 10255163Sshindb_unary(valuep) 10355163Sshin db_expr_t *valuep; 10455163Sshin{ 10555163Sshin int t; 10655163Sshin 10755163Sshin t = db_read_token(); 10855163Sshin if (t == tMINUS) { 10955163Sshin if (!db_unary(valuep)) { 11055163Sshin db_error("Syntax error\n"); 11155163Sshin /*NOTREACHED*/ 11255163Sshin } 11355163Sshin *valuep = -*valuep; 11455163Sshin return (TRUE); 11555163Sshin } 11655163Sshin if (t == tSTAR) { 11755163Sshin /* indirection */ 11855163Sshin if (!db_unary(valuep)) { 11955163Sshin db_error("Syntax error\n"); 12055163Sshin /*NOTREACHED*/ 12155163Sshin } 12255163Sshin *valuep = db_get_value((db_addr_t)*valuep, sizeof(int), FALSE); 12355163Sshin return (TRUE); 12462607Sitojun } 12555163Sshin db_unread_token(t); 12655163Sshin return (db_term(valuep)); 12755163Sshin} 12855163Sshin 12955163Sshinstatic boolean_t 13055163Sshindb_mult_expr(valuep) 13155163Sshin db_expr_t *valuep; 13255163Sshin{ 13355163Sshin db_expr_t lhs, rhs; 13455163Sshin int t; 13555163Sshin 13655163Sshin if (!db_unary(&lhs)) 13755163Sshin return (FALSE); 13855163Sshin 13955163Sshin t = db_read_token(); 14055163Sshin while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) { 14155163Sshin if (!db_term(&rhs)) { 14255163Sshin db_error("Syntax error\n"); 14355163Sshin /*NOTREACHED*/ 14455163Sshin } 14555163Sshin if (t == tSTAR) 14655163Sshin lhs *= rhs; 14755163Sshin else { 14855163Sshin if (rhs == 0) { 14955163Sshin db_error("Divide by 0\n"); 15055163Sshin /*NOTREACHED*/ 15155163Sshin } 15255163Sshin if (t == tSLASH) 15355163Sshin lhs /= rhs; 15455163Sshin else if (t == tPCT) 15555163Sshin lhs %= rhs; 15655163Sshin else 15755163Sshin lhs = ((lhs+rhs-1)/rhs)*rhs; 15855163Sshin } 15955163Sshin t = db_read_token(); 16055163Sshin } 16155163Sshin db_unread_token(t); 16255163Sshin *valuep = lhs; 16355163Sshin return (TRUE); 16455163Sshin} 16555163Sshin 16655163Sshinstatic boolean_t 16755163Sshindb_add_expr(valuep) 16862607Sitojun db_expr_t *valuep; 16962607Sitojun{ 17055163Sshin db_expr_t lhs, rhs; 17155163Sshin int t; 17255163Sshin 17355163Sshin if (!db_mult_expr(&lhs)) 17455163Sshin return (FALSE); 17555163Sshin 17655163Sshin t = db_read_token(); 17755163Sshin while (t == tPLUS || t == tMINUS) { 17855163Sshin if (!db_mult_expr(&rhs)) { 17955163Sshin db_error("Syntax error\n"); 18055163Sshin /*NOTREACHED*/ 18155163Sshin } 18255163Sshin if (t == tPLUS) 18355163Sshin lhs += rhs; 18462607Sitojun else 18555163Sshin lhs -= rhs; 18655163Sshin t = db_read_token(); 18755163Sshin } 18855163Sshin db_unread_token(t); 18955163Sshin *valuep = lhs; 19055163Sshin return (TRUE); 19155163Sshin} 19255163Sshin 19355163Sshinstatic boolean_t 19455163Sshindb_shift_expr(valuep) 19555163Sshin db_expr_t *valuep; 19655163Sshin{ 19755163Sshin db_expr_t lhs, rhs; 19855163Sshin int t; 19955163Sshin 20055163Sshin if (!db_add_expr(&lhs)) 20155163Sshin return (FALSE); 20255163Sshin 20355163Sshin t = db_read_token(); 20455163Sshin while (t == tSHIFT_L || t == tSHIFT_R) { 20555163Sshin if (!db_add_expr(&rhs)) { 20662607Sitojun db_error("Syntax error\n"); 20762607Sitojun /*NOTREACHED*/ 20862607Sitojun } 20962607Sitojun if (rhs < 0) { 21062607Sitojun db_error("Negative shift amount\n"); 21155163Sshin /*NOTREACHED*/ 21255163Sshin } 21355163Sshin if (t == tSHIFT_L) 21455163Sshin lhs <<= rhs; 21555163Sshin else { 21655163Sshin /* Shift right is unsigned */ 21755163Sshin lhs = (unsigned) lhs >> rhs; 21855163Sshin } 21962607Sitojun t = db_read_token(); 22055163Sshin } 22155163Sshin db_unread_token(t); 22255163Sshin *valuep = lhs; 22355163Sshin return (TRUE); 22455163Sshin} 22555163Sshin 22655163Sshinint 22755163Sshindb_expression(valuep) 22855163Sshin db_expr_t *valuep; 22955163Sshin{ 23055163Sshin return (db_shift_expr(valuep)); 23162607Sitojun} 23255163Sshin