From f45a856835e7b39032d34d019ed99c14cc209cbb Mon Sep 17 00:00:00 2001 From: Michel Heily Date: Wed, 26 Jun 2019 16:34:42 +0300 Subject: [PATCH] Support assignment expressions for registers! --- src/debugger/mod.rs | 38 ++++++++++++++++++++++++-------------- src/debugger/parser.rs | 6 +++--- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/debugger/mod.rs b/src/debugger/mod.rs index f600292..483d15d 100644 --- a/src/debugger/mod.rs +++ b/src/debugger/mod.rs @@ -158,7 +158,7 @@ impl Debugger { } - fn decode_register(&self, s: &str) -> DebuggerResult { + fn decode_reg(&self, s: &str) -> DebuggerResult { 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 { + fn val_reg(&self, arg: &Value) -> DebuggerResult { 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 { + fn val_number(&self, arg: &Value) -> DebuggerResult { match arg { Value::Num(n) => Ok(*n), v => Err(DebuggerError::InvalidArgument(format!("expected a number, got {:?}", v))) } } - fn arg_address(&self, arg: &Value) -> DebuggerResult { + fn val_address(&self, arg: &Value) -> DebuggerResult { 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 ".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"), } } diff --git a/src/debugger/parser.rs b/src/debugger/parser.rs index 6fc3854..cc5fe59 100644 --- a/src/debugger/parser.rs +++ b/src/debugger/parser.rs @@ -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};