From 7f9140a97e9468138f0e0cc2c1fed3455cd04897 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sun, 3 May 2020 17:59:38 +0200 Subject: [PATCH] Add debug flag to trace instructions --- src/bin/lsvm.rs | 4 ++++ src/runtime.rs | 18 ++++++++++++++---- src/tokens.rs | 24 +++++++++++++----------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/bin/lsvm.rs b/src/bin/lsvm.rs index 85f0a51..8894654 100644 --- a/src/bin/lsvm.rs +++ b/src/bin/lsvm.rs @@ -6,6 +6,9 @@ use structopt::StructOpt; #[derive(StructOpt, Debug)] struct Opts { + #[structopt(long)] + debug: bool, + #[structopt(short = "i", name = "input")] input_file: String, @@ -22,6 +25,7 @@ fn main() -> io::Result<()> { let mut runtime = Runtime::new(&opts.ip, opts.port); let start = Instant::now(); + runtime.set_debug(opts.debug); runtime.parse_bytecode(bytecode); println!("Parsing took {:?}\n", start.elapsed()); diff --git a/src/runtime.rs b/src/runtime.rs index 17fbd85..1add9b6 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -5,10 +5,10 @@ use crate::registers::{ use crate::tokens::{ AddToken, AndToken, ClearToken, CmdToken, CopyToken, DebugToken, DivToken, ExitToken, FromBytecode, GotoToken, JeToken, JgToken, JlToken, LabelToken, LoadToken, LshToken, ModToken, - MulToken, NopToken, NotToken, NrtToken, OrToken, PauseToken, PowToken, PrintToken, RshToken, - SendToken, SetToken, SubToken, Token, WriteToken, XorToken, T_ADD, T_AND, T_CLEAR, T_CMD, - T_COPY, T_DEBUG, T_DIV, T_EXIT, T_GOTO, T_JE, T_JG, T_JL, T_LABEL, T_LOAD, T_LSH, T_MOD, T_MUL, - T_NOT, T_NRT, T_OR, T_PAUSE, T_POW, T_PRINT, T_RSH, T_SEND, T_SET, T_SUB, T_WRITE, T_XOR, + MulToken, NotToken, NrtToken, OrToken, PauseToken, PowToken, PrintToken, RshToken, SendToken, + SetToken, SubToken, Token, WriteToken, XorToken, T_ADD, T_AND, T_CLEAR, T_CMD, T_COPY, T_DEBUG, + T_DIV, T_EXIT, T_GOTO, T_JE, T_JG, T_JL, T_LABEL, T_LOAD, T_LSH, T_MOD, T_MUL, T_NOT, T_NRT, + T_OR, T_PAUSE, T_POW, T_PRINT, T_RSH, T_SEND, T_SET, T_SUB, T_WRITE, T_XOR, }; use std::cell::RefCell; use std::collections::HashMap; @@ -32,6 +32,7 @@ pub struct Runtime { pub strip_controller: Rc>, exit: Option, current_index: usize, + debug: bool, } impl Runtime { @@ -56,9 +57,15 @@ impl Runtime { strip_controller: controller, exit: None, current_index: 0, + debug: false, } } + /// Sets debug to the specified value + pub fn set_debug(&mut self, debug: bool) { + self.debug = debug; + } + /// Parses a vector containing the bytecode into a vector of tokens /// that can be executed pub fn parse_bytecode(&mut self, bytecode: Vec) { @@ -137,6 +144,9 @@ impl Runtime { while self.current_index < text.len() { let token = text.get(self.current_index).unwrap(); token.invoke(self)?; + if self.debug { + println!("{:?}", token); + } if let Some(code) = self.exit { self.strip_controller diff --git a/src/tokens.rs b/src/tokens.rs index 8d64541..58b76f5 100644 --- a/src/tokens.rs +++ b/src/tokens.rs @@ -1,8 +1,8 @@ use crate::registers::{Register, RCS}; use crate::runtime::Runtime; use num_integer::Roots; +use std::fmt::Debug; use std::io; -use std::mem; use std::ops::BitXor; use std::thread::sleep; use std::time::Duration; @@ -38,7 +38,7 @@ pub const T_PAUSE: u8 = 0xF0; pub const T_CMD: u8 = 0xF1; pub const T_SEND: u8 = 0xF2; -pub trait Token { +pub trait Token: Debug { fn to_bytecode(&self) -> Vec; fn invoke(&self, runtime: &mut Runtime) -> io::Result<()>; } @@ -108,9 +108,9 @@ impl Token for SetToken { } fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { - if let Some(mut rg) = runtime.get_1byte_register(self.register) { + if let Some(rg) = &mut runtime.get_1byte_register(self.register) { rg.set(self.value); - } else if let Some(mut rg) = runtime.get_4byte_register(self.register) { + } else if let Some(rg) = &mut runtime.get_4byte_register(self.register) { rg.set(self.value as u32); } else if self.register == RCS { runtime.rcs.set(self.value != 0); @@ -141,7 +141,7 @@ impl Token for CopyToken { } fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { - let mut value = 0u32; + let value; if let Some(rg) = runtime.get_1byte_register(self.register_1) { value = rg.get() as u32; } else if let Some(rg) = runtime.get_4byte_register(self.register_1) { @@ -152,9 +152,9 @@ impl Token for CopyToken { panic!("unknown register {}", self.register_1); } - if let Some(mut rg) = runtime.get_1byte_register(self.register_2) { + if let Some(rg) = &mut runtime.get_1byte_register(self.register_2) { rg.set(value as u8); - } else if let Some(mut rg) = runtime.get_4byte_register(self.register_2) { + } else if let Some(rg) = &mut runtime.get_4byte_register(self.register_2) { rg.set(value); } else if self.register_2 == RCS { runtime.rcs.set(value != 0); @@ -212,9 +212,9 @@ impl Token for ClearToken { } fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { - if let Some(mut rg) = runtime.get_1byte_register(self.register) { + if let Some(rg) = &mut runtime.get_1byte_register(self.register) { rg.set(0u8); - } else if let Some(mut rg) = runtime.get_4byte_register(self.register) { + } else if let Some(rg) = &mut runtime.get_4byte_register(self.register) { rg.set(0u32); } else if self.register == RCS { runtime.rcs.set(false); @@ -331,7 +331,7 @@ impl Token for PrintToken { } fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { - let mut value = if let Some(rg) = runtime.get_1byte_register(self.register) { + let value = if let Some(rg) = runtime.get_1byte_register(self.register) { rg.get() as u32 } else if let Some(rg) = runtime.get_4byte_register(self.register) { rg.get() @@ -536,6 +536,7 @@ impl Token for PowToken { } } +#[derive(Debug, Clone)] pub struct NrtToken; impl Token for NrtToken { @@ -626,13 +627,14 @@ impl Token for CmdToken { vec![T_CMD] } - fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { + fn invoke(&self, _: &mut Runtime) -> io::Result<()> { unimplemented!(); Ok(()) } } +#[derive(Debug, Clone)] pub struct SendToken; impl Token for SendToken {