Skip to content

Commit 70cf84b

Browse files
committed
implement GOSUB/RETURN/CLEAR
1 parent 0f29997 commit 70cf84b

1 file changed

Lines changed: 17 additions & 6 deletions

File tree

src/evaluator.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub enum Error {
1414

1515
pub struct Evaluator<'a> {
1616
storage: Vec<Option<Line>>,
17+
stack: Vec<usize>,
1718
program_counter: usize,
1819
variables: [i16; NUM_VARIABLES],
1920
output: &'a mut dyn Write,
@@ -23,6 +24,7 @@ impl<'a> Evaluator<'a> {
2324
pub fn new(output: &'a mut dyn Write) -> Self {
2425
Self {
2526
storage: vec![None; STORAGE_SIZE],
27+
stack: Vec::new(),
2628
program_counter: 0,
2729
variables: [0; NUM_VARIABLES],
2830
output,
@@ -116,14 +118,23 @@ impl<'a> Evaluator<'a> {
116118
let value = self.evaluate_expression(expression);
117119
self.store_variable(variable.identifier(), value);
118120
}
119-
Statement::GoSub { expression: _ } => {
120-
todo!()
121-
}
122-
Statement::Return => {
123-
todo!()
121+
Statement::GoSub { expression } => {
122+
let line_number = match u8::try_from(self.evaluate_expression(expression)) {
123+
Ok(line_number) => line_number,
124+
Err(_) => Err(Error::LineNumberOutOfRange)?,
125+
};
126+
127+
self.stack.push(self.program_counter);
128+
self.jump(line_number)?;
124129
}
130+
Statement::Return => match self.stack.pop() {
131+
Some(line_number) => self.program_counter = line_number,
132+
None => {
133+
self.program_counter = self.storage.len();
134+
}
135+
},
125136
Statement::Clear => {
126-
todo!()
137+
self.storage = vec![None; STORAGE_SIZE];
127138
}
128139
Statement::List => {
129140
self.storage.iter().for_each(|line| {

0 commit comments

Comments
 (0)