refactor+perf: revamp codebase

This commit is contained in:
Muhammad Nauman Raza 2025-01-29 19:54:15 +00:00
parent faeedb7850
commit f7fdda37f4
Signed by: devraza
GPG key ID: 91EAD6081011574B
2 changed files with 51 additions and 64 deletions

View file

@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::fs::File; use std::fs::File;
use std::io::{self, BufRead, BufReader}; use std::io::{self, BufRead, BufReader};
fn retrieve(memory: &mut HashMap<String, i64>, ops: Vec<String>) -> i64 { fn retrieve(memory: &HashMap<String, i64>, ops: &[String]) -> i64 {
if ops.len() >= 3 { if ops.len() >= 3 {
*memory.get(&ops[2]).unwrap_or(&0) *memory.get(&ops[2]).unwrap_or(&0)
} else { } else {
@ -10,16 +10,16 @@ fn retrieve(memory: &mut HashMap<String, i64>, ops: Vec<String>) -> i64 {
} }
} }
fn branch(labels: &HashMap<String, usize>, ops: Vec<String>) -> usize { fn branch(labels: &HashMap<String, usize>, ops: &[String]) -> usize {
if ops.len() >= 3 { if ops.len() >= 3 {
return *labels.get(&ops[2]).unwrap(); *labels.get(&ops[2]).unwrap_or(&0)
} else { } else {
return *labels.get(&ops[1]).unwrap(); *labels.get(&ops[1]).unwrap_or(&0)
} }
} }
fn process( fn process(
line: String, line: &str,
accumulator: &mut i64, accumulator: &mut i64,
memory: &mut HashMap<String, i64>, memory: &mut HashMap<String, i64>,
labels: &HashMap<String, usize>, labels: &HashMap<String, usize>,
@ -27,70 +27,57 @@ fn process(
) -> usize { ) -> usize {
let ops: Vec<String> = line.split_whitespace().map(String::from).collect(); let ops: Vec<String> = line.split_whitespace().map(String::from).collect();
let options: Vec<&str> = if ops.len() >= 3 { match ops.get(0).map(String::as_str) {
vec![ops[0].as_str(), ops[1].as_str()] Some("INP") => {
} else { let mut s = String::new();
vec![ops[0].as_str()] io::stdin().read_line(&mut s).unwrap();
}; *accumulator = s.trim().parse::<i64>().unwrap();
}
for op in options { Some("OUT") => println!("{}", accumulator),
match op { Some("STA") => {
"INP" => { let key = if ops.len() >= 3 { &ops[2] } else { &ops[1] };
let mut s = String::new(); memory.insert(key.clone(), *accumulator);
io::stdin().read_line(&mut s).unwrap(); }
*accumulator = s.trim().parse::<i64>().unwrap(); Some("LDA") => {
*accumulator = retrieve(memory, &ops);
}
Some("ADD") => {
if let Ok(value) = ops[1].parse::<i64>() {
*accumulator += value;
} else {
*accumulator += retrieve(memory, &ops);
} }
"OUT" => println!("{}", accumulator), }
"STA" => { Some("SUB") => {
if ops.len() >= 3 { if let Ok(value) = ops[1].parse::<i64>() {
memory.insert(ops[2].clone(), *accumulator); *accumulator -= value;
} else { } else {
memory.insert(ops[1].clone(), *accumulator); *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::<i64>() { Some("BRZ") => {
*accumulator += value; if *accumulator == 0 {
} else { return branch(labels, &ops);
*accumulator += retrieve(memory, ops.clone());
}
} }
"SUB" => { }
if let Ok(value) = ops[1].parse::<i64>() { Some("HLT") => std::process::exit(0),
*accumulator -= value; _ => {
} else { if ops.len() > 1 && ops[1] == "DAT" {
*accumulator -= retrieve(memory, ops.clone()); memory.insert(
} ops[0].clone(),
} ops.get(2).and_then(|s| s.parse::<i64>().ok()).unwrap_or(0),
"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::<i64>().ok()).unwrap_or(0),
);
}
} }
} }
} }
return pc + 1; pc + 1
} }
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
@ -111,8 +98,8 @@ fn main() -> io::Result<()> {
} }
let ops: Vec<String> = line.split_whitespace().map(String::from).collect(); let ops: Vec<String> = line.split_whitespace().map(String::from).collect();
if ops.len() > 1 && ops[1] == "DAT" { if ops.len() > 1 && ops[1] == "DAT" {
labels.insert(ops[0].clone(), ops[2].clone().parse::<usize>().unwrap()); labels.insert(ops[0].clone(), ops[2].parse::<usize>().unwrap_or(0));
} else if ops.len() > 1 && !valid.contains(&&*ops[0].clone()) { } else if ops.len() > 1 && !valid.contains(&&*ops[0]) {
labels.insert(ops[0].clone(), index); labels.insert(ops[0].clone(), index);
} }
code.push(line); code.push(line);
@ -121,7 +108,7 @@ fn main() -> io::Result<()> {
let mut pc: usize = 1; let mut pc: usize = 1;
while pc < code.len() { while pc < code.len() {
let line = &code[pc]; 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(()) Ok(())

BIN
tinypc Executable file

Binary file not shown.