Skip to content

Instantly share code, notes, and snippets.

@misha-krainik
Created October 19, 2022 18:32
Show Gist options
  • Save misha-krainik/e38cc3cf4c18d92270feb0b596e3aa19 to your computer and use it in GitHub Desktop.
Save misha-krainik/e38cc3cf4c18d92270feb0b596e3aa19 to your computer and use it in GitHub Desktop.
Simple assembler interpreter on Rust
use std::collections::HashMap;
fn simple_assembler(program: Vec<&str>) -> HashMap<String, i64> {
let mut registers = HashMap::new();
let mut shift = 0i64;
'begin: while shift < program.len().try_into().unwrap_or(0) {
let instruction = program[shift as usize];
shift = shift + 1;
match instruction.split(" ").collect::<Vec<&str>>().get(..) {
Some([operator, register]) => match *operator {
"inc" => cmd_inc(&mut registers, register),
"dec" => cmd_dec(&mut registers, register),
_ => continue,
}
Some([operator, register, value]) => {
let value = match value.parse::<i64>() {
Ok(value) => value,
_ => registers[value]
};
match *operator {
"mov" => cmd_mov(&mut registers, register, value),
"jnz" => match cmd_jnz_if(&registers, register) {
true => match value {
x if x > 0 => { shift = shift + x; continue 'begin; }
x if x < 0 => { shift = shift - 1 - x.abs(); continue 'begin; }
_ => ()
},
false => continue
}
_ => continue,
}
}
_ => continue,
}
}
registers.into_iter().fold(HashMap::new(), |mut map, (k, v)| {
map.insert(k.to_string(), v);
map
})
}
fn cmd_mov<'a>(registers: &mut HashMap<&'a str, i64>, register: &'a str, value: i64) {
registers.insert(register, value);
}
fn cmd_inc<'a>(registers: &mut HashMap<&'a str, i64>, register: &'a str) {
*registers.entry(register).or_insert(0) += 1;
}
fn cmd_dec<'a>(registers: &mut HashMap<&'a str, i64>, register: &'a str) {
*registers.entry(register).or_insert(0) -= 1;
}
fn cmd_jnz_if<'a>(registers: &HashMap<&'a str, i64>, register: &'a str) -> bool {
if let Some(reg_val) = registers.get(register) {
*reg_val != 0
} else {
false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment