diff --git ddb/db_expr.c ddb/db_expr.c index b9aebce..9f69f84 100644 --- ddb/db_expr.c +++ ddb/db_expr.c @@ -43,6 +43,9 @@ static boolean_t db_mult_expr(db_expr_t *valuep); static boolean_t db_shift_expr(db_expr_t *valuep); static boolean_t db_term(db_expr_t *valuep); static boolean_t db_unary(db_expr_t *valuep); +static boolean_t db_logical_or_expr(db_expr_t *valuep); +static boolean_t db_logical_and_expr(db_expr_t *valuep); +static boolean_t db_logical_relation_expr(db_expr_t *valuep); static boolean_t db_term(db_expr_t *valuep) @@ -54,8 +57,8 @@ db_term(db_expr_t *valuep) if (!db_value_of_name(db_tok_string, valuep) && !db_value_of_name_pcpu(db_tok_string, valuep) && !db_value_of_name_vnet(db_tok_string, valuep)) { - db_error("Symbol not found\n"); - /*NOTREACHED*/ + db_error("Symbol not found\n"); + /*NOTREACHED*/ } return (TRUE); } @@ -81,18 +84,18 @@ db_term(db_expr_t *valuep) } if (t == tDOLLAR) { if (!db_get_variable(valuep)) - return (FALSE); + return (FALSE); return (TRUE); } if (t == tLPAREN) { if (!db_expression(valuep)) { - db_error("Syntax error\n"); - /*NOTREACHED*/ + db_error("Unmatched ()s\n"); + /*NOTREACHED*/ } t = db_read_token(); if (t != tRPAREN) { - db_error("Syntax error\n"); - /*NOTREACHED*/ + db_error("Syntax error\n"); + /*NOTREACHED*/ } return (TRUE); } @@ -108,19 +111,35 @@ db_unary(db_expr_t *valuep) t = db_read_token(); if (t == tMINUS) { if (!db_unary(valuep)) { - db_error("Syntax error\n"); - /*NOTREACHED*/ + 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); + *valuep = db_get_value((db_addr_t)*valuep, sizeof(void *), FALSE); return (TRUE); } db_unread_token(t); @@ -137,14 +156,20 @@ db_mult_expr(db_expr_t *valuep) 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*/ + db_error("Syntax error\n"); + /*NOTREACHED*/ } - if (t == tSTAR) - lhs *= rhs; - else { + switch(t) { + case tSTAR: + lhs *= rhs; + break; + case tBIT_AND: + lhs &= rhs; + break; + default: if (rhs == 0) { db_error("Divide by 0\n"); /*NOTREACHED*/ @@ -168,20 +193,25 @@ db_add_expr(db_expr_t *valuep) { 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"); - /*NOTREACHED*/ + c = db_tok_string[0]; + db_printf("Expression syntax error after '%c'\n",c); + db_error(NULL); + /*NOTREACHED*/ } if (t == tPLUS) - lhs += rhs; - else - lhs -= rhs; + lhs += rhs; + else if (t == tMINUS) + lhs -= rhs; + else + lhs |= rhs; t = db_read_token(); } db_unread_token(t); @@ -201,18 +231,18 @@ db_shift_expr(db_expr_t *valuep) t = db_read_token(); while (t == tSHIFT_L || t == tSHIFT_R) { if (!db_add_expr(&rhs)) { - db_error("Syntax error\n"); - /*NOTREACHED*/ + db_error("Syntax error\n"); + /*NOTREACHED*/ } if (rhs < 0) { - db_error("Negative shift amount\n"); - /*NOTREACHED*/ + db_error("Negative shift amount\n"); + /*NOTREACHED*/ } if (t == tSHIFT_L) - lhs <<= rhs; + lhs <<= rhs; else { - /* Shift right is unsigned */ - lhs = (unsigned) lhs >> rhs; + /* Shift right is unsigned */ + lhs = (unsigned) lhs >> rhs; } t = db_read_token(); } @@ -221,8 +251,105 @@ db_shift_expr(db_expr_t *valuep) 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; +} + +boolean_t +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)); } diff --git ddb/db_input.c ddb/db_input.c index 7c35f91..03ea339 100644 --- ddb/db_input.c +++ ddb/db_input.c @@ -372,3 +372,4 @@ db_check_interrupt() break; } } + diff --git ddb/db_lex.c ddb/db_lex.c index 54b5295..8ef8c54 100644 --- ddb/db_lex.c +++ ddb/db_lex.c @@ -260,51 +260,81 @@ db_lex() switch (c) { case '+': - return (tPLUS); + return (tPLUS); case '-': - return (tMINUS); + return (tMINUS); case '.': c = db_read_char(); if (c == '.') return (tDOTDOT); db_unread_char(c); - return (tDOT); + return (tDOT); case '*': - return (tSTAR); + return (tSTAR); case '/': - return (tSLASH); + return (tSLASH); case '=': - return (tEQ); + c = db_read_char(); + if (c == '=') { + return (tLOG_EQ); + } + db_unread_char(c); + return (tEQ); case '%': - return (tPCT); + return (tPCT); case '#': - return (tHASH); + return (tHASH); case '(': - return (tLPAREN); + return (tLPAREN); case ')': - return (tRPAREN); + return (tRPAREN); case ',': - return (tCOMMA); + return (tCOMMA); case '"': - return (tDITTO); + return (tDITTO); case '$': - return (tDOLLAR); + return (tDOLLAR); case '!': - return (tEXCL); + c = db_read_char(); + if (c == '='){ + return (tLOG_NOT_EQ); + } + db_unread_char(c); + return (tEXCL); case ';': - return (tSEMI); + 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); - db_unread_char(c); - break; + c = db_read_char(); + if (c == '<') + return (tSHIFT_L); + if (c == '=') + return (tLESS_EQ); + db_unread_char(c); + return (tLESS); case '>': - c = db_read_char(); - if (c == '>') - return (tSHIFT_R); - db_unread_char(c); - break; + c = db_read_char(); + if (c == '>') + return (tSHIFT_R); + if (c == '=') + return (tGREATER_EQ); + db_unread_char(c); + return (tGREATER); + case '?': + return (tQUESTION); + case '~': + return (tBIT_NOT); case -1: return (tEOF); } diff --git ddb/db_lex.h ddb/db_lex.h index 0c526cd..1c6ff28 100644 --- ddb/db_lex.h +++ ddb/db_lex.h @@ -69,5 +69,19 @@ extern char db_tok_string[TOK_STRING_SIZE]; #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_ */ + diff --git ddb/ddb.h ddb/ddb.h index f5afcd9..f69387c 100644 --- ddb/ddb.h +++ ddb/ddb.h @@ -187,7 +187,7 @@ void db_clear_watchpoints(void); db_addr_t db_disasm(db_addr_t loc, boolean_t altfmt); /* instruction disassembler */ void db_error(const char *s); -int db_expression(db_expr_t *valuep); +int db_expression(db_expr_t *valuep); int db_get_variable(db_expr_t *valuep); void db_iprintf(const char *,...) __printflike(1, 2); struct proc *db_lookup_proc(db_expr_t addr);