Index: sys/ddb/db_expr.c =================================================================== --- sys/ddb/db_expr.c +++ sys/ddb/db_expr.c @@ -43,6 +43,9 @@ static bool db_shift_expr(db_expr_t *valuep); static bool db_term(db_expr_t *valuep); static bool db_unary(db_expr_t *valuep); +static bool db_logical_or_expr(db_expr_t *valuep); +static bool db_logical_and_expr(db_expr_t *valuep); +static bool db_logical_relation_expr(db_expr_t *valuep); static bool db_term(db_expr_t *valuep) @@ -86,7 +89,7 @@ } if (t == tLPAREN) { if (!db_expression(valuep)) { - db_error("Syntax error\n"); + db_error("Unmatched ()s\n"); /*NOTREACHED*/ } t = db_read_token(); @@ -108,16 +111,32 @@ t = db_read_token(); if (t == tMINUS) { if (!db_unary(valuep)) { - db_error("Syntax error\n"); + db_error("Expression syntax error after '-'\n"); /*NOTREACHED*/ } *valuep = -*valuep; return (true); } + if (t == tEXCL) { + if(!db_unary(valuep)) { + db_error("Expression syntax error after '!'\n"); + /* NOTREACHED */ + } + *valuep = (!(*valuep)); + return (true); + } + if (t == tBIT_NOT) { + if(!db_unary(valuep)) { + db_error("Expression syntax error after '~'\n"); + /* NOTREACHED */ + } + *valuep = (~(*valuep)); + return (true); + } if (t == tSTAR) { /* indirection */ if (!db_unary(valuep)) { - db_error("Syntax error\n"); + db_error("Expression syntax error after '*'\n"); /*NOTREACHED*/ } *valuep = db_get_value((db_addr_t)*valuep, sizeof(void *), false); @@ -137,14 +156,20 @@ return (false); t = db_read_token(); - while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) { + while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH || + t == tBIT_AND ) { if (!db_term(&rhs)) { db_error("Syntax error\n"); /*NOTREACHED*/ } - if (t == tSTAR) + switch(t) { + case tSTAR: lhs *= rhs; - else { + break; + case tBIT_AND: + lhs &= rhs; + break; + default: if (rhs == 0) { db_error("Divide by 0\n"); /*NOTREACHED*/ @@ -168,14 +193,17 @@ { db_expr_t lhs, rhs; int t; + char c; if (!db_mult_expr(&lhs)) return (false); t = db_read_token(); - while (t == tPLUS || t == tMINUS) { + while (t == tPLUS || t == tMINUS || t == tBIT_OR) { if (!db_mult_expr(&rhs)) { - db_error("Syntax error\n"); + c = db_tok_string[0]; + db_printf("Expression syntax error after '%c'\n",c); + db_error(NULL); /*NOTREACHED*/ } if (t == tPLUS) @@ -182,6 +210,10 @@ lhs += rhs; else lhs -= rhs; + else if (t == tMINUS) + lhs -= rhs; + else + lhs |= rhs; t = db_read_token(); } db_unread_token(t); @@ -221,8 +253,104 @@ return (true); } +boolean_t +db_logical_relation_expr( + db_expr_t *valuep) +{ + db_expr_t lhs, rhs; + int t; + char op[3]; + + if (!db_shift_expr(&lhs)) + return (false); + + t = db_read_token(); + while (t == tLOG_EQ || t == tLOG_NOT_EQ || t == tGREATER || + t == tGREATER_EQ || t == tLESS || t == tLESS_EQ) { + op[0] = db_tok_string[0]; + op[1] = db_tok_string[1]; + op[2] = 0; + if (!db_shift_expr(&rhs)) { + db_printf("Expression syntax error after \"%s\"\n", op); + db_error(0); + /*NOTREACHED*/ + } + switch(t) { + case tLOG_EQ: + lhs = (lhs == rhs); + break; + case tLOG_NOT_EQ: + lhs = (lhs != rhs); + break; + case tGREATER: + lhs = (lhs > rhs); + break; + case tGREATER_EQ: + lhs = (lhs >= rhs); + break; + case tLESS: + lhs = (lhs < rhs); + break; + case tLESS_EQ: + lhs = (lhs <= rhs); + break; + } + t = db_read_token(); + } + db_unread_token(t); + *valuep = lhs; + return (true); +} + +boolean_t +db_logical_and_expr( + db_expr_t *valuep) +{ + db_expr_t lhs, rhs; + int t; + + if (!db_logical_relation_expr(&lhs)) + return (false); + + t = db_read_token(); + while (t == tLOG_AND) { + if (!db_logical_relation_expr(&rhs)) { + db_error("Expression syntax error after \"&&\"\n"); + /*NOTREACHED*/ + } + lhs = (lhs && rhs); + t = db_read_token(); + } + db_unread_token(t); + *valuep = lhs; + return (true); +} + +bool +db_logical_or_expr( + db_expr_t *valuep) +{ + db_expr_t lhs, rhs; + int t; + + if (!db_logical_and_expr(&lhs)) + return(false); + + t = db_read_token(); + while (t == tLOG_OR) { + if (!db_logical_and_expr(&rhs)) { + db_error("Expression syntax error after \"||\"\n"); + /*NOTREACHED*/ + } + lhs = (lhs || rhs); + t = db_read_token(); + } + db_unread_token(t); + *valuep = lhs; + return (true); +} int db_expression(db_expr_t *valuep) { - return (db_shift_expr(valuep)); + return (db_logical_or_expr(valuep)); } Index: sys/ddb/db_lex.h =================================================================== --- sys/ddb/db_lex.h +++ sys/ddb/db_lex.h @@ -69,5 +69,18 @@ #define tSHIFT_R 19 #define tDOTDOT 20 #define tSEMI 21 +#define tLOG_EQ 22 +#define tLOG_NOT_EQ 23 +#define tLESS 24 +#define tLESS_EQ 25 +#define tGREATER 26 +#define tGREATER_EQ 27 +#define tBIT_AND 28 +#define tBIT_OR 29 +#define tLOG_AND 30 +#define tLOG_OR 31 +#define tSTRING 32 +#define tQUESTION 33 +#define tBIT_NOT 34 #endif /* !_DDB_DB_LEX_H_ */ Index: sys/ddb/db_lex.c =================================================================== --- sys/ddb/db_lex.c +++ sys/ddb/db_lex.c @@ -274,6 +274,10 @@ case '/': return (tSLASH); case '=': + c = db_read_char(); + if (c == '=') + return (tLOG_EQ); + db_unread_char(c); return (tEQ); case '%': return (tPCT); @@ -290,21 +294,46 @@ case '$': return (tDOLLAR); case '!': + c = db_read_char(); + if (c == '='){ + return (tLOG_NOT_EQ); + } + db_unread_char(c); return (tEXCL); case ';': return (tSEMI); + case '&': + c = db_read_char(); + if (c == '&') + return (tLOG_AND); + db_unread_char(c); + return (tBIT_AND); + case '|': + c=db_read_char(); + if (c == '|') + return (tLOG_OR); + db_unread_char(c); + return (tBIT_OR); case '<': c = db_read_char(); if (c == '<') return (tSHIFT_L); + if (c == '=') + return (tLESS_EQ); db_unread_char(c); - break; + return (tLESS); case '>': c = db_read_char(); if (c == '>') return (tSHIFT_R); + if (c == '=') + return (tGREATER_EQ); db_unread_char(c); - break; + return (tGREATER); + case '?': + return (tQUESTION); + case '~': + return (tBIT_NOT); case -1: return (tEOF); }