1139747Simp/*-
24Srgrimes * Mach Operating System
34Srgrimes * Copyright (c) 1991,1990 Carnegie Mellon University
44Srgrimes * All Rights Reserved.
58876Srgrimes *
64Srgrimes * Permission to use, copy, modify and distribute this software and its
74Srgrimes * documentation is hereby granted, provided that both the copyright
84Srgrimes * notice and this permission notice appear in all copies of the
94Srgrimes * software, derivative works or modified versions, and any portions
104Srgrimes * thereof, and that both notices appear in supporting documentation.
118876Srgrimes *
128876Srgrimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
134Srgrimes * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
144Srgrimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
158876Srgrimes *
164Srgrimes * Carnegie Mellon requests users of this software to return to
178876Srgrimes *
184Srgrimes *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
194Srgrimes *  School of Computer Science
204Srgrimes *  Carnegie Mellon University
214Srgrimes *  Pittsburgh PA 15213-3890
228876Srgrimes *
234Srgrimes * any improvements or extensions that they make and grant Carnegie the
244Srgrimes * rights to redistribute these changes.
254Srgrimes */
264Srgrimes/*
274Srgrimes *	Author: David B. Golub, Carnegie Mellon University
284Srgrimes *	Date:	7/90
294Srgrimes */
30116176Sobrien
31116176Sobrien#include <sys/cdefs.h>
32116176Sobrien__FBSDID("$FreeBSD$");
33116176Sobrien
342056Swollman#include <sys/param.h>
3512734Sbde
362056Swollman#include <ddb/ddb.h>
374Srgrimes#include <ddb/db_lex.h>
384Srgrimes#include <ddb/db_access.h>
394Srgrimes#include <ddb/db_command.h>
404Srgrimes
4192756Salfredstatic boolean_t	db_add_expr(db_expr_t *valuep);
4292756Salfredstatic boolean_t	db_mult_expr(db_expr_t *valuep);
4392756Salfredstatic boolean_t	db_shift_expr(db_expr_t *valuep);
4492756Salfredstatic boolean_t	db_term(db_expr_t *valuep);
4592756Salfredstatic boolean_t	db_unary(db_expr_t *valuep);
4612473Sbde
4712515Sphkstatic boolean_t
48189581Simpdb_term(db_expr_t *valuep)
494Srgrimes{
504Srgrimes	int	t;
514Srgrimes
524Srgrimes	t = db_read_token();
534Srgrimes	if (t == tIDENT) {
54195699Srwatson	    if (!db_value_of_name(db_tok_string, valuep) &&
55195699Srwatson		!db_value_of_name_pcpu(db_tok_string, valuep) &&
56195699Srwatson		!db_value_of_name_vnet(db_tok_string, valuep)) {
574Srgrimes		db_error("Symbol not found\n");
584Srgrimes		/*NOTREACHED*/
594Srgrimes	    }
604Srgrimes	    return (TRUE);
614Srgrimes	}
624Srgrimes	if (t == tNUMBER) {
634Srgrimes	    *valuep = (db_expr_t)db_tok_number;
644Srgrimes	    return (TRUE);
654Srgrimes	}
664Srgrimes	if (t == tDOT) {
674Srgrimes	    *valuep = (db_expr_t)db_dot;
684Srgrimes	    return (TRUE);
694Srgrimes	}
704Srgrimes	if (t == tDOTDOT) {
714Srgrimes	    *valuep = (db_expr_t)db_prev;
724Srgrimes	    return (TRUE);
734Srgrimes	}
744Srgrimes	if (t == tPLUS) {
754Srgrimes	    *valuep = (db_expr_t) db_next;
764Srgrimes	    return (TRUE);
774Srgrimes	}
784Srgrimes	if (t == tDITTO) {
794Srgrimes	    *valuep = (db_expr_t)db_last_addr;
804Srgrimes	    return (TRUE);
814Srgrimes	}
824Srgrimes	if (t == tDOLLAR) {
834Srgrimes	    if (!db_get_variable(valuep))
844Srgrimes		return (FALSE);
854Srgrimes	    return (TRUE);
864Srgrimes	}
874Srgrimes	if (t == tLPAREN) {
884Srgrimes	    if (!db_expression(valuep)) {
894Srgrimes		db_error("Syntax error\n");
904Srgrimes		/*NOTREACHED*/
914Srgrimes	    }
924Srgrimes	    t = db_read_token();
934Srgrimes	    if (t != tRPAREN) {
944Srgrimes		db_error("Syntax error\n");
954Srgrimes		/*NOTREACHED*/
964Srgrimes	    }
974Srgrimes	    return (TRUE);
984Srgrimes	}
994Srgrimes	db_unread_token(t);
1004Srgrimes	return (FALSE);
1014Srgrimes}
1024Srgrimes
10312515Sphkstatic boolean_t
104189581Simpdb_unary(db_expr_t *valuep)
1054Srgrimes{
1064Srgrimes	int	t;
1074Srgrimes
1084Srgrimes	t = db_read_token();
1094Srgrimes	if (t == tMINUS) {
1104Srgrimes	    if (!db_unary(valuep)) {
1114Srgrimes		db_error("Syntax error\n");
1124Srgrimes		/*NOTREACHED*/
1134Srgrimes	    }
1144Srgrimes	    *valuep = -*valuep;
1154Srgrimes	    return (TRUE);
1164Srgrimes	}
1174Srgrimes	if (t == tSTAR) {
1184Srgrimes	    /* indirection */
1194Srgrimes	    if (!db_unary(valuep)) {
1204Srgrimes		db_error("Syntax error\n");
1214Srgrimes		/*NOTREACHED*/
1224Srgrimes	    }
12398815Stmm	    *valuep = db_get_value((db_addr_t)*valuep, sizeof(void *), FALSE);
1244Srgrimes	    return (TRUE);
1254Srgrimes	}
1264Srgrimes	db_unread_token(t);
1274Srgrimes	return (db_term(valuep));
1284Srgrimes}
1294Srgrimes
13012515Sphkstatic boolean_t
131189581Simpdb_mult_expr(db_expr_t *valuep)
1324Srgrimes{
1334Srgrimes	db_expr_t	lhs, rhs;
1344Srgrimes	int		t;
1354Srgrimes
1364Srgrimes	if (!db_unary(&lhs))
1374Srgrimes	    return (FALSE);
1384Srgrimes
1394Srgrimes	t = db_read_token();
1404Srgrimes	while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) {
1414Srgrimes	    if (!db_term(&rhs)) {
1424Srgrimes		db_error("Syntax error\n");
1434Srgrimes		/*NOTREACHED*/
1444Srgrimes	    }
1454Srgrimes	    if (t == tSTAR)
1464Srgrimes		lhs *= rhs;
1474Srgrimes	    else {
1484Srgrimes		if (rhs == 0) {
1494Srgrimes		    db_error("Divide by 0\n");
1504Srgrimes		    /*NOTREACHED*/
1514Srgrimes		}
1524Srgrimes		if (t == tSLASH)
1534Srgrimes		    lhs /= rhs;
1544Srgrimes		else if (t == tPCT)
1554Srgrimes		    lhs %= rhs;
1564Srgrimes		else
1574Srgrimes		    lhs = ((lhs+rhs-1)/rhs)*rhs;
1584Srgrimes	    }
1594Srgrimes	    t = db_read_token();
1604Srgrimes	}
1614Srgrimes	db_unread_token(t);
1624Srgrimes	*valuep = lhs;
1634Srgrimes	return (TRUE);
1644Srgrimes}
1654Srgrimes
16612515Sphkstatic boolean_t
167189581Simpdb_add_expr(db_expr_t *valuep)
1684Srgrimes{
1694Srgrimes	db_expr_t	lhs, rhs;
1704Srgrimes	int		t;
1714Srgrimes
1724Srgrimes	if (!db_mult_expr(&lhs))
1734Srgrimes	    return (FALSE);
1744Srgrimes
1754Srgrimes	t = db_read_token();
1764Srgrimes	while (t == tPLUS || t == tMINUS) {
1774Srgrimes	    if (!db_mult_expr(&rhs)) {
1784Srgrimes		db_error("Syntax error\n");
1794Srgrimes		/*NOTREACHED*/
1804Srgrimes	    }
1814Srgrimes	    if (t == tPLUS)
1824Srgrimes		lhs += rhs;
1834Srgrimes	    else
1844Srgrimes		lhs -= rhs;
1854Srgrimes	    t = db_read_token();
1864Srgrimes	}
1874Srgrimes	db_unread_token(t);
1884Srgrimes	*valuep = lhs;
1894Srgrimes	return (TRUE);
1904Srgrimes}
1914Srgrimes
19212515Sphkstatic boolean_t
193189581Simpdb_shift_expr(db_expr_t *valuep)
1944Srgrimes{
1954Srgrimes	db_expr_t	lhs, rhs;
1964Srgrimes	int		t;
1974Srgrimes
1984Srgrimes	if (!db_add_expr(&lhs))
1994Srgrimes	    return (FALSE);
2004Srgrimes
2014Srgrimes	t = db_read_token();
2024Srgrimes	while (t == tSHIFT_L || t == tSHIFT_R) {
2034Srgrimes	    if (!db_add_expr(&rhs)) {
2044Srgrimes		db_error("Syntax error\n");
2054Srgrimes		/*NOTREACHED*/
2064Srgrimes	    }
2074Srgrimes	    if (rhs < 0) {
2084Srgrimes		db_error("Negative shift amount\n");
2094Srgrimes		/*NOTREACHED*/
2104Srgrimes	    }
2114Srgrimes	    if (t == tSHIFT_L)
2124Srgrimes		lhs <<= rhs;
2134Srgrimes	    else {
2144Srgrimes		/* Shift right is unsigned */
2154Srgrimes		lhs = (unsigned) lhs >> rhs;
2164Srgrimes	    }
2174Srgrimes	    t = db_read_token();
2184Srgrimes	}
2194Srgrimes	db_unread_token(t);
2204Srgrimes	*valuep = lhs;
2214Srgrimes	return (TRUE);
2224Srgrimes}
2234Srgrimes
2244Srgrimesint
225189581Simpdb_expression(db_expr_t *valuep)
2264Srgrimes{
2274Srgrimes	return (db_shift_expr(valuep));
2284Srgrimes}
229