feat: basic branch functionality

This commit is contained in:
Muhammad Nauman Raza 2025-01-24 12:44:20 +00:00
parent 9d55dd5fe8
commit fbedd10058
Signed by: devraza
GPG key ID: 91EAD6081011574B

View file

@ -1,21 +1,8 @@
use std::fs::File; use std::fs::File;
use std::io::{self, Result, prelude::*, BufReader}; use std::io::{self, BufRead, BufReader};
use std::collections::HashMap; use std::collections::HashMap;
fn main() -> Result<()> { fn process(line: String, accumulator: &mut i64, memory: &mut HashMap<String, i64>, labels: &HashMap<String, usize>) -> usize {
let code = File::open("code.asm")?;
let buffer = BufReader::new(&code);
let mut accumulator = 0;
let mut memory: HashMap<String, i64> = HashMap::new();
for line in buffer.lines() {
let line = line?;
if line.clone().trim().is_empty() {
continue;
}
let ops: Vec<String> = line.trim() let ops: Vec<String> = line.trim()
.split_whitespace() .split_whitespace()
.map(String::from) .map(String::from)
@ -25,64 +12,73 @@ fn main() -> Result<()> {
"INP" => { "INP" => {
let mut s = String::new(); let mut s = String::new();
io::stdin().read_line(&mut s).unwrap(); io::stdin().read_line(&mut s).unwrap();
accumulator = s.trim().parse::<i64>().unwrap(); *accumulator = s.trim().parse::<i64>().unwrap();
} }
"OUT" => println!("{}", accumulator), "OUT" => println!("{}", accumulator),
"STA" => { "STA" => {
memory.insert( memory.insert(ops[1].clone(), *accumulator);
ops[1].clone(),
accumulator
);
} }
"LDA" => { "LDA" => {
match memory.get(&ops[1].clone()) { *accumulator = *memory.get(&ops[1]).unwrap_or(&0);
Some(value) => accumulator = *value,
None => panic!(),
}
} }
"ADD" => { "ADD" => {
let addition = ops[1].clone().parse::<i64>(); if let Ok(value) = ops[1].parse::<i64>() {
if addition.is_ok() { *accumulator += value;
accumulator -= addition.unwrap();
} else { } else {
match memory.get(&ops[1].clone()) { *accumulator += *memory.get(&ops[1]).unwrap_or(&0);
Some(value) => accumulator += *value,
None => panic!(),
}
} }
} }
"SUB" => { "SUB" => {
let subtract = ops[1].clone().parse::<i64>(); if let Ok(value) = ops[1].parse::<i64>() {
if subtract.is_ok() { *accumulator -= value;
accumulator -= subtract.unwrap();
} else { } else {
match memory.get(&ops[1].clone()) { *accumulator -= *memory.get(&ops[1]).unwrap_or(&0);
Some(value) => accumulator -= *value,
None => panic!(),
} }
} }
"BRA" => {
return *labels.get(&ops[1]).unwrap_or(&0);
} }
"HLT" => std::process::exit(0), "HLT" => std::process::exit(0),
&_ => { _ => {
match ops[1].as_str() { if ops.len() > 1 && ops[1] == "DAT" {
"DAT" => { memory.insert(ops[0].clone(), ops.get(2).and_then(|s| s.parse::<i64>().ok()).unwrap_or(0));
if ops.get(2).is_some() { }
memory.insert( }
ops[0].clone(), }
ops[2].clone().parse::<i64>().unwrap(),
); return 0;
}
fn main() -> io::Result<()> {
let file = File::open("code.asm")?;
let reader = BufReader::new(file);
let mut accumulator: i64 = 0;
let mut memory: HashMap<String, i64> = HashMap::new();
let mut labels: HashMap<String, usize> = HashMap::new();
let mut code: Vec<String> = Vec::new();
for (index, line) in reader.lines().enumerate() {
let line = line?;
if line.trim().is_empty() {
continue;
}
let ops: Vec<String> = line.trim().split_whitespace().map(String::from).collect();
if ops.len() > 1 && ops[1] == "DAT" {
labels.insert(ops[0].clone(), index);
} else if ops.len() > 1 {
labels.insert(ops[0].clone(), index);
}
code.push(line);
}
let mut pc: usize = 0;
while pc < code.len() {
let line = &code[pc];
let next_pc = process(line.to_string(), &mut accumulator, &mut memory, &labels);
if next_pc != 0 {
pc = next_pc;
} else { } else {
memory.insert( pc += 1;
ops[0].clone(),
0,
);
}
}
&_ => {
panic!()
}
}
}
} }
} }