feat: proper branching and support for instruction-line loops
Branching works through changing the value of the program counter, which represents the line number to process.
This commit is contained in:
parent
ebc3d6b0a8
commit
8f0da8a7f7
1 changed files with 19 additions and 5 deletions
22
src/main.rs
22
src/main.rs
|
@ -7,10 +7,19 @@ fn process(
|
||||||
accumulator: &mut i64,
|
accumulator: &mut i64,
|
||||||
memory: &mut HashMap<String, i64>,
|
memory: &mut HashMap<String, i64>,
|
||||||
labels: &HashMap<String, usize>,
|
labels: &HashMap<String, usize>,
|
||||||
|
pc: &mut usize,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
let ops: Vec<String> = line.trim().split_whitespace().map(String::from).collect();
|
let ops: Vec<String> = line.trim().split_whitespace().map(String::from).collect();
|
||||||
|
|
||||||
match ops[0].as_str() {
|
let options: Vec<&str>;
|
||||||
|
if ops.len() > 1 {
|
||||||
|
options = vec![ops[0].as_str(), ops[1].as_str()];
|
||||||
|
} else {
|
||||||
|
options = vec![ops[0].as_str()];
|
||||||
|
}
|
||||||
|
|
||||||
|
for op in options {
|
||||||
|
match op {
|
||||||
"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();
|
||||||
|
@ -21,8 +30,12 @@ fn process(
|
||||||
memory.insert(ops[1].clone(), *accumulator);
|
memory.insert(ops[1].clone(), *accumulator);
|
||||||
}
|
}
|
||||||
"LDA" => {
|
"LDA" => {
|
||||||
|
if ops.len() > 1 {
|
||||||
|
*accumulator = *memory.get(&ops[2]).unwrap_or(&0);
|
||||||
|
} else {
|
||||||
*accumulator = *memory.get(&ops[1]).unwrap_or(&0);
|
*accumulator = *memory.get(&ops[1]).unwrap_or(&0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"ADD" => {
|
"ADD" => {
|
||||||
if let Ok(value) = ops[1].parse::<i64>() {
|
if let Ok(value) = ops[1].parse::<i64>() {
|
||||||
*accumulator += value;
|
*accumulator += value;
|
||||||
|
@ -38,7 +51,7 @@ fn process(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"BRA" => {
|
"BRA" => {
|
||||||
return *labels.get(&ops[1]).unwrap_or(&0);
|
*pc = *labels.get(&ops[1]).unwrap();
|
||||||
}
|
}
|
||||||
"HLT" => std::process::exit(0),
|
"HLT" => std::process::exit(0),
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -50,6 +63,7 @@ fn process(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +85,7 @@ fn main() -> io::Result<()> {
|
||||||
if ops.len() > 1 && ops[1] == "DAT" {
|
if ops.len() > 1 && ops[1] == "DAT" {
|
||||||
labels.insert(ops[0].clone(), index);
|
labels.insert(ops[0].clone(), index);
|
||||||
} else if ops.len() > 1 {
|
} else if ops.len() > 1 {
|
||||||
labels.insert(ops[0].clone(), index);
|
labels.insert(ops[1].clone(), index);
|
||||||
}
|
}
|
||||||
code.push(line);
|
code.push(line);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +93,7 @@ fn main() -> io::Result<()> {
|
||||||
let mut pc: usize = 0;
|
let mut pc: usize = 0;
|
||||||
while pc < code.len() {
|
while pc < code.len() {
|
||||||
let line = &code[pc];
|
let line = &code[pc];
|
||||||
let next_pc = process(line.to_string(), &mut accumulator, &mut memory, &labels);
|
let next_pc = process(line.to_string(), &mut accumulator, &mut memory, &labels, &mut pc);
|
||||||
if next_pc != 0 {
|
if next_pc != 0 {
|
||||||
pc = next_pc;
|
pc = next_pc;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue