diff --git a/src/main.rs b/src/main.rs index 0ef6d66..ac130df 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::fs::File; use std::io::{self, BufRead, BufReader}; -fn retrieve(memory: &mut HashMap, ops: Vec) -> i64 { +fn retrieve(memory: &HashMap, ops: &[String]) -> i64 { if ops.len() >= 3 { *memory.get(&ops[2]).unwrap_or(&0) } else { @@ -10,16 +10,16 @@ fn retrieve(memory: &mut HashMap, ops: Vec) -> i64 { } } -fn branch(labels: &HashMap, ops: Vec) -> usize { +fn branch(labels: &HashMap, ops: &[String]) -> usize { if ops.len() >= 3 { - return *labels.get(&ops[2]).unwrap(); + *labels.get(&ops[2]).unwrap_or(&0) } else { - return *labels.get(&ops[1]).unwrap(); + *labels.get(&ops[1]).unwrap_or(&0) } } fn process( - line: String, + line: &str, accumulator: &mut i64, memory: &mut HashMap, labels: &HashMap, @@ -27,70 +27,57 @@ fn process( ) -> usize { let ops: Vec = line.split_whitespace().map(String::from).collect(); - let options: Vec<&str> = if ops.len() >= 3 { - vec![ops[0].as_str(), ops[1].as_str()] - } else { - vec![ops[0].as_str()] - }; - - for op in options { - match op { - "INP" => { - let mut s = String::new(); - io::stdin().read_line(&mut s).unwrap(); - *accumulator = s.trim().parse::().unwrap(); + match ops.get(0).map(String::as_str) { + Some("INP") => { + let mut s = String::new(); + io::stdin().read_line(&mut s).unwrap(); + *accumulator = s.trim().parse::().unwrap(); + } + Some("OUT") => println!("{}", accumulator), + Some("STA") => { + let key = if ops.len() >= 3 { &ops[2] } else { &ops[1] }; + memory.insert(key.clone(), *accumulator); + } + Some("LDA") => { + *accumulator = retrieve(memory, &ops); + } + Some("ADD") => { + if let Ok(value) = ops[1].parse::() { + *accumulator += value; + } else { + *accumulator += retrieve(memory, &ops); } - "OUT" => println!("{}", accumulator), - "STA" => { - if ops.len() >= 3 { - memory.insert(ops[2].clone(), *accumulator); - } else { - memory.insert(ops[1].clone(), *accumulator); - } + } + Some("SUB") => { + if let Ok(value) = ops[1].parse::() { + *accumulator -= value; + } else { + *accumulator -= retrieve(memory, &ops); } - "LDA" => { - *accumulator = retrieve(memory, ops.clone()); + } + Some("BRA") => return branch(labels, &ops), + Some("BRP") => { + if *accumulator >= 0 { + return branch(labels, &ops); } - "ADD" => { - if let Ok(value) = ops[1].parse::() { - *accumulator += value; - } else { - *accumulator += retrieve(memory, ops.clone()); - } + } + Some("BRZ") => { + if *accumulator == 0 { + return branch(labels, &ops); } - "SUB" => { - if let Ok(value) = ops[1].parse::() { - *accumulator -= value; - } else { - *accumulator -= retrieve(memory, ops.clone()); - } - } - "BRA" => { - return branch(labels, ops); - } - "BRP" => { - if *accumulator >= 0 { - return branch(labels, ops); - } - } - "BRZ" => { - if *accumulator == 0 { - return branch(labels, ops); - } - } - "HLT" => std::process::exit(0), - _ => { - if ops.len() > 1 && ops[1] == "DAT" { - memory.insert( - ops[0].clone(), - ops.get(2).and_then(|s| s.parse::().ok()).unwrap_or(0), - ); - } + } + Some("HLT") => std::process::exit(0), + _ => { + if ops.len() > 1 && ops[1] == "DAT" { + memory.insert( + ops[0].clone(), + ops.get(2).and_then(|s| s.parse::().ok()).unwrap_or(0), + ); } } } - return pc + 1; + pc + 1 } fn main() -> io::Result<()> { @@ -111,8 +98,8 @@ fn main() -> io::Result<()> { } let ops: Vec = line.split_whitespace().map(String::from).collect(); if ops.len() > 1 && ops[1] == "DAT" { - labels.insert(ops[0].clone(), ops[2].clone().parse::().unwrap()); - } else if ops.len() > 1 && !valid.contains(&&*ops[0].clone()) { + labels.insert(ops[0].clone(), ops[2].parse::().unwrap_or(0)); + } else if ops.len() > 1 && !valid.contains(&&*ops[0]) { labels.insert(ops[0].clone(), index); } code.push(line); @@ -121,7 +108,7 @@ fn main() -> io::Result<()> { let mut pc: usize = 1; while pc < code.len() { let line = &code[pc]; - pc = process(line.to_string(), &mut accumulator, &mut memory, &labels, pc); + pc = process(line, &mut accumulator, &mut memory, &labels, pc); } Ok(()) diff --git a/tinypc b/tinypc new file mode 100755 index 0000000..54014df Binary files /dev/null and b/tinypc differ