Skip to content

Commit

Permalink
Reintroduces forgotten jr diagnostic (fixes #137)
Browse files Browse the repository at this point in the history
  • Loading branch information
insou22 committed Feb 5, 2022
1 parent caf979f commit 3781e2c
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 12 deletions.
66 changes: 56 additions & 10 deletions crates/mipsy_lib/src/error/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ impl RuntimeError {
"{}{} {}",
"error".bright_red().bold(),
":".bold(),
self.error.message(context, source_code, inst_set, binary, runtime)
self.error.message(context, &source_code, inst_set, binary, runtime)
);

for tip in self.error.tips(inst_set, binary, runtime) {
for tip in self.error.tips(&source_code, inst_set, binary, runtime) {
println!("{} {}", tip_header(), tip);
}
}
Expand Down Expand Up @@ -79,7 +79,7 @@ impl Error {
pub fn message(
&self,
context: ErrorContext,
source_code: Vec<(Rc<str>, Rc<str>)>,
source_code: &[(Rc<str>, Rc<str>)],
inst_set: &InstSet,
binary: &Binary,
runtime: &Runtime,
Expand Down Expand Up @@ -157,7 +157,7 @@ impl Error {
let (file_tag, line_num) = real_inst_parts.location.unwrap();
let mut file = None;

for (src_tag, src_file) in &source_code {
for (src_tag, src_file) in source_code {
if &*file_tag == &**src_tag {
file = Some(src_file);
break;
Expand Down Expand Up @@ -289,7 +289,7 @@ impl Error {
let (file_tag, line_num) = real_inst_parts.location.unwrap();
let mut file = None;

for (src_tag, src_file) in &source_code {
for (src_tag, src_file) in source_code {
if &*file_tag == &**src_tag {
file = Some(src_file);
break;
Expand Down Expand Up @@ -396,7 +396,7 @@ impl Error {
let (file_tag, line_num) = real_inst_parts.location.unwrap();
let mut file = None;

for (src_tag, src_file) in &source_code {
for (src_tag, src_file) in source_code {
if &*file_tag == &**src_tag {
file = Some(src_file);
break;
Expand Down Expand Up @@ -624,7 +624,7 @@ impl Error {
let (file_tag, line_num) = real_inst_parts.location.unwrap();
let mut file = None;

for (src_tag, src_file) in &source_code {
for (src_tag, src_file) in source_code {
if &*file_tag == &**src_tag {
file = Some(src_file);
break;
Expand Down Expand Up @@ -687,10 +687,56 @@ impl Error {
}
}

pub fn tips(&self, inst_set: &InstSet, binary: &Binary, runtime: &Runtime) -> Vec<String> {
pub fn tips(&self, source_code: &[(Rc<str>, Rc<str>)], inst_set: &InstSet, binary: &Binary, runtime: &Runtime) -> Vec<String> {
match self {
Error::UnknownInstruction { .. } => {
vec![]
Error::UnknownInstruction { addr } => {
if let Some(prev_state) = runtime.timeline().prev_state() {
// we got here in standard sequence,
// usually describing a missing return

if prev_state.pc() + 4 == *addr {
let jr = "jr".bold();
let dollar = "$".yellow();
let ra = "ra".bold();

let did_you_forget = format!("did you forget to use `{jr} {dollar}{ra}`?");

if let Ok(inst) = prev_state.read_mem_word(prev_state.pc()) {
let decompiled = decompile::decompile_inst_into_parts(binary, inst_set, inst, prev_state.pc());
let inst_str = inst_parts_to_string(&decompiled, &source_code, binary, false, true);

vec![
format!("the last instruction to execute was:\n{inst_str}\n"),
did_you_forget,
]
} else {
// how the hell did we get here?
// maybe we can analytic these cases in future..
vec![
did_you_forget,
]
}
} else if let Ok(inst) = prev_state.read_mem_word(prev_state.pc()) {
// we got here from some kind of botched jump,
// how peculiar!

let decompiled = decompile::decompile_inst_into_parts(binary, inst_set, inst, prev_state.pc());
let inst_str = inst_parts_to_string(&decompiled, &source_code, binary, false, true);

let back = "back".bold();

vec![
format!("try using the `{back}` command - the instruction that brought you here was:\n{inst_str}"),
]
} else {
// how the hell did we get here?
// maybe we can analytic these cases in future...
vec![]
}
} else {
// there's literally no instructions
vec![]
}
}
Error::Uninitialised { .. } => {
vec![]
Expand Down
4 changes: 2 additions & 2 deletions crates/mipsy_lib/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ impl Runtime {
}

pub fn step(mut self) -> Result<SteppedRuntime, (Runtime, MipsyError)> {
let state = self.timeline.push_next_state();

let state = self.timeline.state();
let inst = match state.read_mem_word(state.pc()) {
Ok(inst) => inst,
Err(_) => {
Expand All @@ -67,6 +66,7 @@ impl Runtime {
}
};

let state = self.timeline.push_next_state();
state.set_pc(state.pc() + 4);

match self.execute_in_current_state(inst) {
Expand Down
4 changes: 4 additions & 0 deletions crates/mipsy_lib/src/runtime/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ impl Timeline {
self.timeline.get(n)
}

pub fn prev_state(&self) -> Option<&State> {
self.nth_state(self.timeline_len() - 2)
}

pub fn push_next_state(&mut self) -> &mut State {
let last_state = self.timeline.back().expect("timelint cannot be empty");
let next_state = last_state.clone();
Expand Down

0 comments on commit 3781e2c

Please sign in to comment.