Add debug flag to trace instructions

pull/1/head
trivernis 5 years ago
parent f2e01ab003
commit 7f9140a97e

@ -6,6 +6,9 @@ use structopt::StructOpt;
#[derive(StructOpt, Debug)] #[derive(StructOpt, Debug)]
struct Opts { struct Opts {
#[structopt(long)]
debug: bool,
#[structopt(short = "i", name = "input")] #[structopt(short = "i", name = "input")]
input_file: String, input_file: String,
@ -22,6 +25,7 @@ fn main() -> io::Result<()> {
let mut runtime = Runtime::new(&opts.ip, opts.port); let mut runtime = Runtime::new(&opts.ip, opts.port);
let start = Instant::now(); let start = Instant::now();
runtime.set_debug(opts.debug);
runtime.parse_bytecode(bytecode); runtime.parse_bytecode(bytecode);
println!("Parsing took {:?}\n", start.elapsed()); println!("Parsing took {:?}\n", start.elapsed());

@ -5,10 +5,10 @@ use crate::registers::{
use crate::tokens::{ use crate::tokens::{
AddToken, AndToken, ClearToken, CmdToken, CopyToken, DebugToken, DivToken, ExitToken, AddToken, AndToken, ClearToken, CmdToken, CopyToken, DebugToken, DivToken, ExitToken,
FromBytecode, GotoToken, JeToken, JgToken, JlToken, LabelToken, LoadToken, LshToken, ModToken, FromBytecode, GotoToken, JeToken, JgToken, JlToken, LabelToken, LoadToken, LshToken, ModToken,
MulToken, NopToken, NotToken, NrtToken, OrToken, PauseToken, PowToken, PrintToken, RshToken, MulToken, NotToken, NrtToken, OrToken, PauseToken, PowToken, PrintToken, RshToken, SendToken,
SendToken, SetToken, SubToken, Token, WriteToken, XorToken, T_ADD, T_AND, T_CLEAR, T_CMD, SetToken, SubToken, Token, WriteToken, XorToken, T_ADD, T_AND, T_CLEAR, T_CMD, T_COPY, T_DEBUG,
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_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_NOT, T_NRT, T_OR, T_PAUSE, T_POW, T_PRINT, T_RSH, T_SEND, T_SET, T_SUB, T_WRITE, T_XOR, 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::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
@ -32,6 +32,7 @@ pub struct Runtime {
pub strip_controller: Rc<RefCell<LedStripController>>, pub strip_controller: Rc<RefCell<LedStripController>>,
exit: Option<u8>, exit: Option<u8>,
current_index: usize, current_index: usize,
debug: bool,
} }
impl Runtime { impl Runtime {
@ -56,9 +57,15 @@ impl Runtime {
strip_controller: controller, strip_controller: controller,
exit: None, exit: None,
current_index: 0, 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 /// Parses a vector containing the bytecode into a vector of tokens
/// that can be executed /// that can be executed
pub fn parse_bytecode(&mut self, bytecode: Vec<u8>) { pub fn parse_bytecode(&mut self, bytecode: Vec<u8>) {
@ -137,6 +144,9 @@ impl Runtime {
while self.current_index < text.len() { while self.current_index < text.len() {
let token = text.get(self.current_index).unwrap(); let token = text.get(self.current_index).unwrap();
token.invoke(self)?; token.invoke(self)?;
if self.debug {
println!("{:?}", token);
}
if let Some(code) = self.exit { if let Some(code) = self.exit {
self.strip_controller self.strip_controller

@ -1,8 +1,8 @@
use crate::registers::{Register, RCS}; use crate::registers::{Register, RCS};
use crate::runtime::Runtime; use crate::runtime::Runtime;
use num_integer::Roots; use num_integer::Roots;
use std::fmt::Debug;
use std::io; use std::io;
use std::mem;
use std::ops::BitXor; use std::ops::BitXor;
use std::thread::sleep; use std::thread::sleep;
use std::time::Duration; use std::time::Duration;
@ -38,7 +38,7 @@ pub const T_PAUSE: u8 = 0xF0;
pub const T_CMD: u8 = 0xF1; pub const T_CMD: u8 = 0xF1;
pub const T_SEND: u8 = 0xF2; pub const T_SEND: u8 = 0xF2;
pub trait Token { pub trait Token: Debug {
fn to_bytecode(&self) -> Vec<u8>; fn to_bytecode(&self) -> Vec<u8>;
fn invoke(&self, runtime: &mut Runtime) -> io::Result<()>; fn invoke(&self, runtime: &mut Runtime) -> io::Result<()>;
} }
@ -108,9 +108,9 @@ impl Token for SetToken {
} }
fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { 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); 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); rg.set(self.value as u32);
} else if self.register == RCS { } else if self.register == RCS {
runtime.rcs.set(self.value != 0); runtime.rcs.set(self.value != 0);
@ -141,7 +141,7 @@ impl Token for CopyToken {
} }
fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { 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) { if let Some(rg) = runtime.get_1byte_register(self.register_1) {
value = rg.get() as u32; value = rg.get() as u32;
} else if let Some(rg) = runtime.get_4byte_register(self.register_1) { } 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); 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); 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); rg.set(value);
} else if self.register_2 == RCS { } else if self.register_2 == RCS {
runtime.rcs.set(value != 0); runtime.rcs.set(value != 0);
@ -212,9 +212,9 @@ impl Token for ClearToken {
} }
fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { 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); 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); rg.set(0u32);
} else if self.register == RCS { } else if self.register == RCS {
runtime.rcs.set(false); runtime.rcs.set(false);
@ -331,7 +331,7 @@ impl Token for PrintToken {
} }
fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { 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 rg.get() as u32
} else if let Some(rg) = runtime.get_4byte_register(self.register) { } else if let Some(rg) = runtime.get_4byte_register(self.register) {
rg.get() rg.get()
@ -536,6 +536,7 @@ impl Token for PowToken {
} }
} }
#[derive(Debug, Clone)]
pub struct NrtToken; pub struct NrtToken;
impl Token for NrtToken { impl Token for NrtToken {
@ -626,13 +627,14 @@ impl Token for CmdToken {
vec![T_CMD] vec![T_CMD]
} }
fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { fn invoke(&self, _: &mut Runtime) -> io::Result<()> {
unimplemented!(); unimplemented!();
Ok(()) Ok(())
} }
} }
#[derive(Debug, Clone)]
pub struct SendToken; pub struct SendToken;
impl Token for SendToken { impl Token for SendToken {

Loading…
Cancel
Save