diff --git a/nemu/include/debug.h b/nemu/include/debug.h
index 924bcf1..0b422d2 100644
--- a/nemu/include/debug.h
+++ b/nemu/include/debug.h
@@ -21,7 +21,15 @@
 #include <utils.h>
 
 #define Log(format, ...) \
-    _Log(ANSI_FMT("[%s:%d %s] " format, ANSI_FG_BLUE) "\n", \
+    _Log(ANSI_FMT("%s:%d %s [INFO]" format, ANSI_FG_BLUE) "\n", \
+        __FILE__, __LINE__, __func__, ## __VA_ARGS__)
+
+#define Warning(format, ...) \
+    _Log(ANSI_FMT("%s:%d %s [WARNING]" format, ANSI_FG_YELLOW) "\n", \
+        __FILE__, __LINE__, __func__, ## __VA_ARGS__)
+
+#define Error(format, ...) \
+    _Log(ANSI_FMT("%s:%d %s [ERROR] " format, ANSI_FG_RED) "\n", \
         __FILE__, __LINE__, __func__, ## __VA_ARGS__)
 
 #define Assert(cond, format, ...) \
diff --git a/nemu/src/monitor/sdb/addrexp.y b/nemu/src/monitor/sdb/addrexp.y
index ab5035b..93c1cc0 100644
--- a/nemu/src/monitor/sdb/addrexp.y
+++ b/nemu/src/monitor/sdb/addrexp.y
@@ -42,10 +42,7 @@ expression
         $$ = $1 / $3;
       }
     | '-' number { $$ = -$2; }
-    | '*' expression {
-      // printf("deref: %u, value: %#x\n", $2, vaddr_read($2, WORD_BYTES));
-      $$ = vaddr_read($2, WORD_BYTES);
-    }
+    | '*' expression { $$ = vaddr_read($2, WORD_BYTES); }
     | '(' expression ')' { $$ = $2; }
 
 number
diff --git a/nemu/src/monitor/sdb/sdb.c b/nemu/src/monitor/sdb/sdb.c
index 6d6c621..8d4df29 100644
--- a/nemu/src/monitor/sdb/sdb.c
+++ b/nemu/src/monitor/sdb/sdb.c
@@ -125,17 +125,17 @@ static word_t parse_uint(const char *arg, bool *success) {
   }
 }
 
-static vaddr_t parse_expr(const char *arg, bool *success) {
+word_t parse_expr(const char *arg, bool *success) {
   if (arg == NULL) {
     puts("Invalid expr argument.");
     *success = false;
     return 0;
   } else {
-    vaddr_t addr;
+    word_t res;
     yy_scan_string(arg);
-    *success = !yyparse(&addr);
+    *success = !yyparse(&res);
     yylex_destroy();
-    return addr;
+    return res;
   }
 }
 
diff --git a/nemu/src/monitor/sdb/sdb.h b/nemu/src/monitor/sdb/sdb.h
index e94846c..d83d2c6 100644
--- a/nemu/src/monitor/sdb/sdb.h
+++ b/nemu/src/monitor/sdb/sdb.h
@@ -18,4 +18,6 @@
 
 #include <common.h>
 
+word_t parse_expr(const char *arg, bool *success);
+
 #endif
diff --git a/nemu/src/monitor/sdb/watchpoint.c b/nemu/src/monitor/sdb/watchpoint.c
index 2618bba..f84bed8 100644
--- a/nemu/src/monitor/sdb/watchpoint.c
+++ b/nemu/src/monitor/sdb/watchpoint.c
@@ -15,6 +15,7 @@
 
 #include "common.h"
 #include "sdb.h"
+#include <stdio.h>
 
 #define NR_WP 32
 
@@ -42,7 +43,7 @@ void init_wp_pool() {
 
 WP *wp_new() {
   if (free_ == NULL) {
-    Log("wp_pool: Watchpoint pool not initialized or is full.");
+    Error("wp_pool: Watchpoint pool not initialized or is full.");
     return NULL;
   }
   
@@ -63,7 +64,7 @@ void wp_delete(WP *wp) {
 int wp_add(char * expr) {
   WP *wp = wp_new();
   if (wp == NULL) {
-    Log("watchpoint: Failed to add watchpoint, pool is full.");
+    Error("watchpoint: Failed to add watchpoint, pool is full.");
     return 1;
   }
 
@@ -83,7 +84,7 @@ int wp_remove_by_number(int number) {
   // Find previous node of target number
   for (target_prev = head; target_prev != NULL && target_prev->next->NO != number; target_prev = target_prev->next) ;
   if (target_prev == NULL) {
-    Log("Watchpoint not found, you can check current watchpoints with `info w`");
+    Error("Watchpoint not found, you can check current watchpoints with `info w`");
     return 1;
   }
   WP *target = target_prev->next;
@@ -97,4 +98,20 @@ int wp_remove_by_number(int number) {
   return 0;
 }
 
+// int wp_eval(WP* wp) {
+//   bool success = false;
+//   word_t result;
+
+//   result = parse_expr(wp->expr, &success);
+//   if (!success) {
+    
+//   } 
+// }
+
+/* 
+  Check if watchpoint value changed after execution
+*/
+// int wp_eval_all() {
+// }
+
 /* TODO: Implement the functionality of watchpoint */