refactor+perf: revamp codebase
This commit is contained in:
parent
faeedb7850
commit
f7fdda37f4
2 changed files with 51 additions and 64 deletions
67
src/main.rs
67
src/main.rs
|
@ -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,58 +27,46 @@ 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 {
|
|
||||||
vec![ops[0].as_str()]
|
|
||||||
};
|
|
||||||
|
|
||||||
for op in options {
|
|
||||||
match op {
|
|
||||||
"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),
|
Some("OUT") => println!("{}", accumulator),
|
||||||
"STA" => {
|
Some("STA") => {
|
||||||
if ops.len() >= 3 {
|
let key = if ops.len() >= 3 { &ops[2] } else { &ops[1] };
|
||||||
memory.insert(ops[2].clone(), *accumulator);
|
memory.insert(key.clone(), *accumulator);
|
||||||
} else {
|
|
||||||
memory.insert(ops[1].clone(), *accumulator);
|
|
||||||
}
|
}
|
||||||
|
Some("LDA") => {
|
||||||
|
*accumulator = retrieve(memory, &ops);
|
||||||
}
|
}
|
||||||
"LDA" => {
|
Some("ADD") => {
|
||||||
*accumulator = retrieve(memory, ops.clone());
|
|
||||||
}
|
|
||||||
"ADD" => {
|
|
||||||
if let Ok(value) = ops[1].parse::<i64>() {
|
if let Ok(value) = ops[1].parse::<i64>() {
|
||||||
*accumulator += value;
|
*accumulator += value;
|
||||||
} else {
|
} else {
|
||||||
*accumulator += retrieve(memory, ops.clone());
|
*accumulator += retrieve(memory, &ops);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"SUB" => {
|
Some("SUB") => {
|
||||||
if let Ok(value) = ops[1].parse::<i64>() {
|
if let Ok(value) = ops[1].parse::<i64>() {
|
||||||
*accumulator -= value;
|
*accumulator -= value;
|
||||||
} else {
|
} else {
|
||||||
*accumulator -= retrieve(memory, ops.clone());
|
*accumulator -= retrieve(memory, &ops);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"BRA" => {
|
Some("BRA") => return branch(labels, &ops),
|
||||||
return branch(labels, ops);
|
Some("BRP") => {
|
||||||
}
|
|
||||||
"BRP" => {
|
|
||||||
if *accumulator >= 0 {
|
if *accumulator >= 0 {
|
||||||
return branch(labels, ops);
|
return branch(labels, &ops);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"BRZ" => {
|
Some("BRZ") => {
|
||||||
if *accumulator == 0 {
|
if *accumulator == 0 {
|
||||||
return branch(labels, ops);
|
return branch(labels, &ops);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"HLT" => std::process::exit(0),
|
Some("HLT") => std::process::exit(0),
|
||||||
_ => {
|
_ => {
|
||||||
if ops.len() > 1 && ops[1] == "DAT" {
|
if ops.len() > 1 && ops[1] == "DAT" {
|
||||||
memory.insert(
|
memory.insert(
|
||||||
|
@ -88,9 +76,8 @@ fn process(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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
BIN
tinypc
Executable file
Binary file not shown.
Loading…
Reference in a new issue