Support assignment expressions for registers!
This commit is contained in:
parent
f1f33d8586
commit
f45a856835
|
@ -158,7 +158,7 @@ impl Debugger {
|
|||
}
|
||||
|
||||
|
||||
fn decode_register(&self, s: &str) -> DebuggerResult<usize> {
|
||||
fn decode_reg(&self, s: &str) -> DebuggerResult<usize> {
|
||||
let reg_names = vec![
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "fp", "ip", "sp", "lr",
|
||||
"pc"];
|
||||
|
@ -169,28 +169,27 @@ impl Debugger {
|
|||
}
|
||||
}
|
||||
|
||||
fn arg_reg(&self, arg: &Value) -> DebuggerResult<u32> {
|
||||
fn val_reg(&self, arg: &Value) -> DebuggerResult<usize> {
|
||||
match arg {
|
||||
Value::Name(reg) => {
|
||||
let reg = self.decode_register(®)?;
|
||||
Ok(self.cpu.get_reg(reg))
|
||||
self.decode_reg(®)
|
||||
},
|
||||
v => Err(DebuggerError::InvalidArgument(format!("expected a number, got {:?}", v)))
|
||||
}
|
||||
}
|
||||
|
||||
fn arg_number(&self, arg: &Value) -> DebuggerResult<u32> {
|
||||
fn val_number(&self, arg: &Value) -> DebuggerResult<u32> {
|
||||
match arg {
|
||||
Value::Num(n) => Ok(*n),
|
||||
v => Err(DebuggerError::InvalidArgument(format!("expected a number, got {:?}", v)))
|
||||
}
|
||||
}
|
||||
|
||||
fn arg_address(&self, arg: &Value) -> DebuggerResult<u32> {
|
||||
fn val_address(&self, arg: &Value) -> DebuggerResult<u32> {
|
||||
match arg {
|
||||
Value::Num(n) => Ok(*n),
|
||||
Value::Name(reg) => {
|
||||
let reg = self.decode_register(®)?;
|
||||
let reg = self.decode_reg(®)?;
|
||||
Ok(self.cpu.get_reg(reg))
|
||||
}
|
||||
v => Err(DebuggerError::InvalidArgument(format!("addr: expected a number or register, got {:?}", v)))
|
||||
|
@ -210,20 +209,20 @@ impl Debugger {
|
|||
"s" | "step" => Ok(Command::SingleStep),
|
||||
"c" | "continue" => Ok(Command::Continue),
|
||||
"xxd" => {
|
||||
let addr = self.arg_address(&args[0])?;
|
||||
let nbytes = self.arg_number(&args[1])?;
|
||||
let addr = self.val_address(&args[0])?;
|
||||
let nbytes = self.val_number(&args[1])?;
|
||||
Ok(Command::HexDump(addr, nbytes as usize))
|
||||
}
|
||||
"d" | "disass" => {
|
||||
let (addr, n) = match args.len() {
|
||||
2 => {
|
||||
let addr = self.arg_address(&args[0])?;
|
||||
let n = self.arg_number(&args[1])?;
|
||||
let addr = self.val_address(&args[0])?;
|
||||
let n = self.val_number(&args[1])?;
|
||||
|
||||
(addr, n as usize)
|
||||
}
|
||||
1 => {
|
||||
let addr = self.arg_address(&args[0])?;
|
||||
let addr = self.val_address(&args[0])?;
|
||||
|
||||
(addr, 10)
|
||||
}
|
||||
|
@ -243,7 +242,7 @@ impl Debugger {
|
|||
"disass <addr>".to_string(),
|
||||
))
|
||||
} else {
|
||||
let addr = self.arg_address(&args[0])?;
|
||||
let addr = self.val_address(&args[0])?;
|
||||
Ok(Command::AddBreakpoint(addr))
|
||||
}
|
||||
}
|
||||
|
@ -254,6 +253,14 @@ impl Debugger {
|
|||
}
|
||||
}
|
||||
|
||||
fn eval_assignment(&mut self, lvalue: Value, rvalue: Value) -> DebuggerResult<()> {
|
||||
let lvalue = self.val_reg(&lvalue)?;
|
||||
let rvalue = self.val_address(&rvalue)?;
|
||||
|
||||
self.cpu.set_reg(lvalue, rvalue);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn eval_expr(&mut self, expr: Expr) {
|
||||
match expr {
|
||||
Expr::Command(c, a) => match self.eval_command(c, a) {
|
||||
|
@ -269,7 +276,10 @@ impl Debugger {
|
|||
}
|
||||
Err(e) => println!("{} {:?}", "failed to build command".red(), e),
|
||||
},
|
||||
Expr::Assignment(_, _) => unimplemented!("assignments are not implemented"),
|
||||
Expr::Assignment(lvalue, rvalue) => match self.eval_assignment(lvalue, rvalue) {
|
||||
Err(DebuggerError::InvalidArgument(m)) => println!("{}: {}", "assignment error".red(), m),
|
||||
_ => ()
|
||||
}
|
||||
Expr::Empty => println!("Got empty expr"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@ use nom;
|
|||
use nom::branch::alt;
|
||||
use nom::bytes::complete::{tag, take_while_m_n};
|
||||
use nom::character::complete::{alphanumeric1, char, digit1, multispace0, multispace1};
|
||||
use nom::combinator::{cut, map, map_res, opt};
|
||||
use nom::combinator::{map, map_res};
|
||||
use nom::error::{context, convert_error, ParseError, VerboseError};
|
||||
use nom::multi::{many0, separated_list};
|
||||
use nom::sequence::{delimited, preceded, separated_pair, terminated, tuple};
|
||||
use nom::multi::separated_list;
|
||||
use nom::sequence::{preceded, separated_pair, terminated, tuple};
|
||||
use nom::IResult;
|
||||
|
||||
use super::{DebuggerError, DebuggerResult};
|
||||
|
|
Reference in a new issue