feat: basic branch functionality
This commit is contained in:
parent
9d55dd5fe8
commit
fbedd10058
1 changed files with 71 additions and 75 deletions
108
src/main.rs
108
src/main.rs
|
@ -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!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue