dark_vm/
vm.rs

1//! The VM struct represents the VM state after any given changes.
2//! This struct maintains the code that is given and the stack.
3//! This struct also should not change that much. The only changes would be additions to value enum and evaluate_value function.
4//!
5//! The VM can be invoked after the lexer has been run.
6//!
7//! # Example
8//! ```
9//! # fn run() -> Result<(), Error> {
10//! let contents = "push 1";
11//! let tokens = Lexer::new().lex(contents)?;
12//! let result = VM::new(tokens).run()?;
13//! # Ok(())
14//! # }
15//! ```
16
17use crate::{
18    code::Code,
19    errors::{error::Error, error_kind::ErrorKind},
20    tokens::token::Token,
21    utils::{frames::Frame, stack::Stack},
22    values::{value::Value, value_kinds::ValueKind},
23};
24
25use std::{collections::VecDeque, rc::Rc};
26
27#[derive(Debug)]
28pub struct VM {
29    code: Code,
30    pub operand_stack: Stack<Rc<Value>>,
31    call_stack: Stack<Frame>,
32}
33
34impl VM {
35    /// Constructs a new VM with the specified tokens.
36    /// The tokens are usually generated through the lexer.
37    /// Internally, the tokens are converted to different values by the code object.
38    ///
39    /// # Arguments
40    /// `tokens` - The tokens produced by the lexer.
41    pub fn new(tokens: VecDeque<Token>) -> Result<VM, Error> {
42        let code = Code::new(tokens)?;
43        let main_frame = Frame::new(0, "main", None);
44        let mut call_stack = Stack::new();
45        call_stack.push(main_frame);
46        Ok(VM {
47            code,
48            operand_stack: Stack::new(),
49            call_stack,
50        })
51    }
52
53    /// Creates a VM in REPL mode.
54    pub fn repl() -> Result<VM, Error> {
55        let main_frame = Frame::new(0, "main", None);
56        let mut call_stack = Stack::new();
57        call_stack.push(main_frame);
58        Ok(
59            VM {
60                code: Code::repl(VecDeque::new())?,
61                operand_stack: Stack::new(),
62                call_stack
63            }
64        )
65    }
66
67    /// Loads the given tokens into the VM.
68    /// This function does not change the operand stack or the call stack.
69    /// This function can be used with the REPL mode to help facilitate a proper REPL experience.
70    ///
71    /// # Arguments
72    /// `tokens` - The tokens to load.
73    pub fn load_tokens(&mut self, tokens: VecDeque<Token>) -> Result<(), Error> {
74        self.code = Code::repl(tokens)?;
75        Ok(())
76    }
77
78    /// Runs the VM until the end of the code.
79    /// This function may return an optionally value, representing the value of the last expression.
80    /// It may also prematurely return an error. This may be updated to return a vector of errors.
81    pub fn run(&mut self) -> Result<Option<Rc<Value>>, Error> {
82        loop {
83            // A seperate function must be called here.
84            // Otherwise, Rust's borrow checker will complain with the error that self.code is mutabley borrowed more than once.
85            if self.is_finished() {
86                return Ok(None);
87            }
88
89            let next = self.next().unwrap();
90            let result = self.evaluate_value(next)?;
91            if self.is_finished() && result.is_some() {
92                return Ok(result);
93            }
94        }
95    }
96
97    /// Evaluates the next value.
98    /// This means every value is an expression in some sense.
99    ///
100    /// # Arguments
101    /// `value` - The value to evaluate.
102    fn evaluate_value(&mut self, value: Rc<Value>) -> Result<Option<Rc<Value>>, Error> {
103        match &value.kind {
104            ValueKind::Void => Ok(None),
105            ValueKind::Any => Ok(None),
106
107            ValueKind::Int(_)
108            | ValueKind::Float(_)
109            | ValueKind::Boolean(_)
110            | ValueKind::String(_) => Ok(Some(value)),
111
112            // Cloning here is cheap because val is reference counted, so only a counter is incremented.
113            ValueKind::Identifier(name) => self
114                .call_stack
115                .peek()
116                .unwrap()
117                .find(name, value.pos)
118                .map(Some),
119            ValueKind::Label(_) => {
120                let mut found_end = false;
121                while let Some(value) = self.next() {
122                    if let ValueKind::End = value.kind {
123                        found_end = true;
124                        break;
125                    }
126                }
127
128                if !found_end {
129                    Err(Error::new(ErrorKind::NoEndOfLabel, value.pos))
130                } else {
131                    Ok(None)
132                }
133            }
134            ValueKind::End => {
135                let frame = self.call_stack.pop(value.pos)?;
136                if let Some(error) = self
137                    .code
138                    .jump(frame.get_caller_position() as i64, value.pos)
139                {
140                    Err(error)
141                } else {
142                    Ok(None)
143                }
144            }
145
146            ValueKind::Push => self.push(value.pos),
147            ValueKind::Pop => self.pop(value.pos).map(|(_, value)| value),
148            ValueKind::Peek => self.operand_stack.peek().map_or(
149                Ok(Some(Rc::new(Value::new(value.pos, ValueKind::Void)))),
150                |peeked_value| Ok(Some(peeked_value.clone())),
151            ),
152            ValueKind::Add => self.add(value.pos),
153            ValueKind::Sub => self.sub(value.pos),
154            ValueKind::Mul => self.mul(value.pos),
155            ValueKind::Div => self.div(value.pos),
156            ValueKind::LessThan => self.lt(value.pos),
157            ValueKind::LessThanEqual => self.lte(value.pos),
158            ValueKind::GreaterThan => self.gt(value.pos),
159            ValueKind::GreaterThanEqual => self.gte(value.pos),
160            ValueKind::Equal => self.eq(value.pos),
161            ValueKind::NotEqual => self.neq(value.pos),
162            ValueKind::Jump => self.jmp(value.pos),
163            ValueKind::RelativeJump => self.rjmp(value.pos),
164            ValueKind::JumpIfTrue => self.jmpt(value.pos),
165            ValueKind::JumpIfFalse => self.jmpf(value.pos),
166            ValueKind::Print => self.print(value.pos),
167            ValueKind::PrintNewLine => self.printn(value.pos),
168            ValueKind::Set => self.set(value.pos),
169            ValueKind::Call => self.call(value.pos),
170        }
171    }
172
173    /// Pushes the next value on to the stack.
174    /// This will call the get_arg method, which calls the evaluate_value function again.
175    /// This ensures that instructions can be followed by more instructions as arguments.
176    ///
177    /// # Arguments
178    /// `pos` - The position where the instruction was called.
179    fn push(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
180        // Get the next argument. The two parameters passed are useful in the case of errors.
181        let (pos, arg) = self.get_arg(1, pos)?;
182
183        // If the argument does not exist, return an error, otherwise push it on to the stack.
184        match arg {
185            Some(value) => self.operand_stack.push(value),
186            None => {
187                return Err(Error::new(
188                    ErrorKind::ValueMismatch(
189                        ValueKind::Any.get_value_name(),
190                        ValueKind::Void.get_value_name(),
191                    ),
192                    pos,
193                ))
194            }
195        }
196
197        Ok(None)
198    }
199
200    /// Pops the top value from the stack.
201    ///
202    /// # Arguments
203    /// `pos` - The position where the instruction was called.
204    fn pop(&mut self, pos: usize) -> Result<(usize, Option<Rc<Value>>), Error> {
205        // Pop the value and if there are no errors, map it to an option with the value.
206        // stack.pop takes the position where the instruction was used in the case that the stack was empty.
207        self.operand_stack.pop(pos).map(|val| (val.pos, Some(val)))
208    }
209
210    /// Pops the top two values from the stack and adds them together.
211    /// This internally calls both the pop instruction and the add method on the Value struct.
212    ///
213    /// # Arguments
214    /// `pos` - The position where the instruction was called.
215    fn add(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
216        let (arg_pos_1, arg1) = self.pop(pos)?;
217        let (arg_pos_2, arg2) = self.pop(pos)?;
218
219        match (arg1, arg2) {
220            (Some(operand1), Some(operand2)) => operand1
221                .add(operand2.as_ref(), pos)
222                .map(|val| Some(Rc::new(val))),
223            (None, _) => Err(Error::new(
224                ErrorKind::ValueMismatch(
225                    ValueKind::Any.get_value_name(),
226                    ValueKind::Void.get_value_name(),
227                ),
228                arg_pos_1,
229            )),
230            (_, None) => Err(Error::new(
231                ErrorKind::ValueMismatch(
232                    ValueKind::Any.get_value_name(),
233                    ValueKind::Void.get_value_name(),
234                ),
235                arg_pos_2,
236            )),
237        }
238    }
239
240    /// Pops the top two values from the stack and subtracts them.
241    /// This internally calls both the pop instruction and the sub method on the Value struct.
242    ///
243    /// # Arguments
244    /// `pos` - The position where the instruction was called.
245    fn sub(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
246        let (arg_pos_1, arg1) = self.pop(pos)?;
247        let (arg_pos_2, arg2) = self.pop(pos)?;
248
249        match (arg1, arg2) {
250            (Some(operand1), Some(operand2)) => operand1
251                .sub(operand2.as_ref(), pos)
252                .map(|val| Some(Rc::new(val))),
253            (None, _) => Err(Error::new(
254                ErrorKind::ValueMismatch(
255                    ValueKind::Any.get_value_name(),
256                    ValueKind::Void.get_value_name(),
257                ),
258                arg_pos_1,
259            )),
260            (_, None) => Err(Error::new(
261                ErrorKind::ValueMismatch(
262                    ValueKind::Any.get_value_name(),
263                    ValueKind::Void.get_value_name(),
264                ),
265                arg_pos_2,
266            )),
267        }
268    }
269
270    /// Pops the top two values from the stack and multiplies them.
271    /// This internally calls both the pop instruction and the mul method on the Value struct.
272    ///
273    /// # Arguments
274    /// `pos` - The position where the instruction was called.
275    fn mul(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
276        let (arg_pos_1, arg1) = self.pop(pos)?;
277        let (arg_pos_2, arg2) = self.pop(pos)?;
278
279        match (arg1, arg2) {
280            (Some(operand1), Some(operand2)) => operand1
281                .mul(operand2.as_ref(), pos)
282                .map(|val| Some(Rc::new(val))),
283            (None, _) => Err(Error::new(
284                ErrorKind::ValueMismatch(
285                    ValueKind::Any.get_value_name(),
286                    ValueKind::Void.get_value_name(),
287                ),
288                arg_pos_1,
289            )),
290            (_, None) => Err(Error::new(
291                ErrorKind::ValueMismatch(
292                    ValueKind::Any.get_value_name(),
293                    ValueKind::Void.get_value_name(),
294                ),
295                arg_pos_2,
296            )),
297        }
298    }
299
300    /// Pops the top two values from the stack and divides them.
301    /// This internally calls both the pop instruction and the div method on the Value struct.
302    ///
303    /// # Arguments
304    /// `pos` - The position where the instruction was called.
305    fn div(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
306        let (arg_pos_1, arg1) = self.pop(pos)?;
307        let (arg_pos_2, arg2) = self.pop(pos)?;
308
309        match (arg1, arg2) {
310            (Some(operand1), Some(operand2)) => operand1
311                .div(operand2.as_ref(), pos)
312                .map(|val| Some(Rc::new(val))),
313            (None, _) => Err(Error::new(
314                ErrorKind::ValueMismatch(
315                    ValueKind::Any.get_value_name(),
316                    ValueKind::Void.get_value_name(),
317                ),
318                arg_pos_1,
319            )),
320            (_, None) => Err(Error::new(
321                ErrorKind::ValueMismatch(
322                    ValueKind::Any.get_value_name(),
323                    ValueKind::Void.get_value_name(),
324                ),
325                arg_pos_2,
326            )),
327        }
328    }
329
330    /// Compares the two arguments and returns if the first argument is less than the second argument.
331    ///
332    /// # Arguments
333    /// `pos` - The position where this instruction was called.
334    fn lt(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
335        let (arg_pos_1, arg1) = self.get_arg(2, pos)?;
336        let (arg_pos_2, arg2) = self.get_arg(1, pos)?;
337
338        match (arg1, arg2) {
339            (Some(operand1), Some(operand2)) => operand1
340                .lt(operand2.as_ref(), pos)
341                .map(|val| Some(Rc::new(val))),
342            (None, _) => Err(Error::new(
343                ErrorKind::ValueMismatch(
344                    ValueKind::Any.get_value_name(),
345                    ValueKind::Void.get_value_name(),
346                ),
347                arg_pos_1,
348            )),
349            (_, None) => Err(Error::new(
350                ErrorKind::ValueMismatch(
351                    ValueKind::Any.get_value_name(),
352                    ValueKind::Void.get_value_name(),
353                ),
354                arg_pos_2,
355            )),
356        }
357    }
358
359    /// Compares the two arguments and returns if the first argument is less than the second argument.
360    ///
361    /// # Arguments
362    /// `pos` - The position where this instruction was called.
363    fn lte(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
364        let (arg_pos_1, arg1) = self.get_arg(2, pos)?;
365        let (arg_pos_2, arg2) = self.get_arg(1, pos)?;
366
367        match (arg1, arg2) {
368            (Some(operand1), Some(operand2)) => operand1
369                .lte(operand2.as_ref(), pos)
370                .map(|val| Some(Rc::new(val))),
371            (None, _) => Err(Error::new(
372                ErrorKind::ValueMismatch(
373                    ValueKind::Any.get_value_name(),
374                    ValueKind::Void.get_value_name(),
375                ),
376                arg_pos_1,
377            )),
378            (_, None) => Err(Error::new(
379                ErrorKind::ValueMismatch(
380                    ValueKind::Any.get_value_name(),
381                    ValueKind::Void.get_value_name(),
382                ),
383                arg_pos_2,
384            )),
385        }
386    }
387
388    /// Compares the two arguments and returns if the first argument is less than the second argument.
389    ///
390    /// # Arguments
391    /// `pos` - The position where this instruction was called.
392    fn gt(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
393        let (arg_pos_1, arg1) = self.get_arg(2, pos)?;
394        let (arg_pos_2, arg2) = self.get_arg(1, pos)?;
395
396        match (arg1, arg2) {
397            (Some(operand1), Some(operand2)) => operand1
398                .gt(operand2.as_ref(), pos)
399                .map(|val| Some(Rc::new(val))),
400            (None, _) => Err(Error::new(
401                ErrorKind::ValueMismatch(
402                    ValueKind::Any.get_value_name(),
403                    ValueKind::Void.get_value_name(),
404                ),
405                arg_pos_1,
406            )),
407            (_, None) => Err(Error::new(
408                ErrorKind::ValueMismatch(
409                    ValueKind::Any.get_value_name(),
410                    ValueKind::Void.get_value_name(),
411                ),
412                arg_pos_2,
413            )),
414        }
415    }
416
417    /// Compares the two arguments and returns if the first argument is less than the second argument.
418    ///
419    /// # Arguments
420    /// `pos` - The position where this instruction was called.
421    fn gte(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
422        let (arg_pos_1, arg1) = self.get_arg(2, pos)?;
423        let (arg_pos_2, arg2) = self.get_arg(1, pos)?;
424
425        match (arg1, arg2) {
426            (Some(operand1), Some(operand2)) => operand1
427                .gte(operand2.as_ref(), pos)
428                .map(|val| Some(Rc::new(val))),
429            (None, _) => Err(Error::new(
430                ErrorKind::ValueMismatch(
431                    ValueKind::Any.get_value_name(),
432                    ValueKind::Void.get_value_name(),
433                ),
434                arg_pos_1,
435            )),
436            (_, None) => Err(Error::new(
437                ErrorKind::ValueMismatch(
438                    ValueKind::Any.get_value_name(),
439                    ValueKind::Void.get_value_name(),
440                ),
441                arg_pos_2,
442            )),
443        }
444    }
445
446    /// Compares the two arguments and returns if the first argument is less than the second argument.
447    ///
448    /// # Arguments
449    /// `pos` - The position where this instruction was called.
450    fn eq(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
451        let (arg_pos_1, arg1) = self.get_arg(2, pos)?;
452        let (arg_pos_2, arg2) = self.get_arg(1, pos)?;
453
454        match (arg1, arg2) {
455            (Some(operand1), Some(operand2)) => Ok(Some(Rc::new(operand1.equal(operand2.as_ref(), pos)))),
456            (None, _) => Err(Error::new(
457                ErrorKind::ValueMismatch(
458                    ValueKind::Any.get_value_name(),
459                    ValueKind::Void.get_value_name(),
460                ),
461                arg_pos_1,
462            )),
463            (_, None) => Err(Error::new(
464                ErrorKind::ValueMismatch(
465                    ValueKind::Any.get_value_name(),
466                    ValueKind::Void.get_value_name(),
467                ),
468                arg_pos_2,
469            )),
470        }
471    }
472
473    /// Compares the two arguments and returns if the first argument is less than the second argument.
474    ///
475    /// # Arguments
476    /// `pos` - The position where this instruction was called.
477    fn neq(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
478        let (arg_pos_1, arg1) = self.get_arg(2, pos)?;
479        let (arg_pos_2, arg2) = self.get_arg(1, pos)?;
480
481        match (arg1, arg2) {
482            (Some(operand1), Some(operand2)) => Ok(Some(Rc::new(operand1.not_equal(operand2.as_ref(), pos)))),
483            (None, _) => Err(Error::new(
484                ErrorKind::ValueMismatch(
485                    ValueKind::Any.get_value_name(),
486                    ValueKind::Void.get_value_name(),
487                ),
488                arg_pos_1,
489            )),
490            (_, None) => Err(Error::new(
491                ErrorKind::ValueMismatch(
492                    ValueKind::Any.get_value_name(),
493                    ValueKind::Void.get_value_name(),
494                ),
495                arg_pos_2,
496            )),
497        }
498    }
499
500    /// Changes the instruction pointer in the Code struct to the argument passed in.
501    /// However, there are restrictions on the argument:
502    /// - First, the argument must be an int.
503    /// - Second, the argument must fit in the range 0 and values.len() inclusive.
504    /// If either of these constraints are broken, an error is returned.
505    ///
506    /// # Arguments
507    /// `pos` - The position where this instruction was called.
508    fn jmp(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
509        let (arg_pos_1, arg1) = self.get_arg(1, pos)?;
510        match arg1 {
511            Some(value) => {
512                if let ValueKind::Int(jump_location) = value.kind {
513                    if let Some(error) = self.code.jump(jump_location, pos) {
514                        Err(error)
515                    } else {
516                        Ok(None)
517                    }
518                } else {
519                    Err(Error::new(
520                        ErrorKind::ValueMismatch(
521                            ValueKind::Int(0).get_value_name(),
522                            value.kind.get_value_name(),
523                        ),
524                        arg_pos_1,
525                    ))
526                }
527            }
528            None => Err(Error::new(
529                ErrorKind::ValueMismatch(
530                    ValueKind::Int(0).get_value_name(),
531                    ValueKind::Void.get_value_name(),
532                ),
533                arg_pos_1,
534            )),
535        }
536    }
537
538    /// Changes the instruction pointer in the Code struct by the argument passed in.
539    /// This argument can be positive or negative. However, it must meet the same bound requirements
540    /// as the jmp instruction.
541    ///
542    /// # Arguments
543    /// `pos` - The position where this instruction was called.
544    fn rjmp(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
545        let (arg_pos_1, arg1) = self.get_arg(1, pos)?;
546        match arg1 {
547            Some(value) => {
548                if let ValueKind::Int(jump_location) = value.kind {
549                    if let Some(error) = self.code.relative_jump(jump_location, pos) {
550                        Err(error)
551                    } else {
552                        Ok(None)
553                    }
554                } else {
555                    Err(Error::new(
556                        ErrorKind::ValueMismatch(
557                            ValueKind::Int(0).get_value_name(),
558                            value.kind.get_value_name(),
559                        ),
560                        arg_pos_1,
561                    ))
562                }
563            }
564            None => Err(Error::new(
565                ErrorKind::ValueMismatch(
566                    ValueKind::Int(0).get_value_name(),
567                    ValueKind::Void.get_value_name(),
568                ),
569                arg_pos_1,
570            )),
571        }
572    }
573
574    /// Changes the instruction pointer in the Code struct to the argument passed in
575    /// if the top value on the stack is true.
576    /// However, there are restrictions on the argument:
577    /// - First, the argument must be an int.
578    /// - Second, the argument must fit in the range 0 and values.len() inclusive.
579    /// If either of these constraints are broken, an error is returned.
580    ///
581    /// # Arguments
582    /// `pos` - The position where this instruction was called.
583    fn jmpt(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
584        match self.operand_stack.peek() {
585            Some(value) if value.is_truthy() => self.jmp(pos),
586            None => Err(Error::new(ErrorKind::EmptyStack, pos)),
587            _ => Ok(None),
588        }
589    }
590
591    /// Changes the instruction pointer in the Code struct to the argument passed in
592    /// if the top value on the stack is false.
593    /// However, there are restrictions on the argument:
594    /// - First, the argument must be an int.
595    /// - Second, the argument must fit in the range 0 and values.len() inclusive.
596    /// If either of these constraints are broken, an error is returned.
597    ///
598    /// # Arguments
599    /// `pos` - The position where this instruction was called.
600    fn jmpf(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
601        match self.operand_stack.peek() {
602            Some(value) if !value.is_truthy() => self.jmp(pos),
603            None => Err(Error::new(ErrorKind::EmptyStack, pos)),
604            _ => Ok(None),
605        }
606    }
607
608    /// Prints the argument passed in.
609    ///
610    /// # Arguments
611    /// `pos` - The position where this instruction was called.
612    fn print(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
613        let (arg_pos_1, arg1) = self.get_arg(1, pos)?;
614        match arg1 {
615            Some(value) => {
616                print!("{:#?}", value);
617                Ok(None)
618            }
619            None => Err(Error::new(
620                ErrorKind::ValueMismatch(
621                    ValueKind::Any.get_value_name(),
622                    ValueKind::Void.get_value_name(),
623                ),
624                arg_pos_1,
625            )),
626        }
627    }
628
629    /// Prints the argument passed in with a new line after it.
630    ///
631    /// # Arguments
632    /// `pos` - The position where this instruction was called.
633    fn printn(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
634        let (arg_pos_1, arg1) = self.get_arg(1, pos)?;
635        match arg1 {
636            Some(value) => {
637                println!("{:#?}", value);
638                Ok(None)
639            }
640            None => Err(Error::new(
641                ErrorKind::ValueMismatch(
642                    ValueKind::Any.get_value_name(),
643                    ValueKind::Void.get_value_name(),
644                ),
645                arg_pos_1,
646            )),
647        }
648    }
649
650    /// Sets the identifier passed in to the value passed in.
651    ///
652    /// # Arguments
653    /// `pos` - The position where this instruction was called.
654    fn set(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
655        let (arg_pos_1, arg1) = self.get_arg_unevaluated(2, pos)?;
656        let (arg_pos_2, arg2) = self.get_arg(1, pos)?;
657
658        match &arg1.kind {
659            ValueKind::Identifier(name) => {
660                if let Some(value) = arg2 {
661                    self.call_stack.peek_mut().unwrap().define(name, value);
662                    Ok(None)
663                } else {
664                    Err(Error::new(
665                        ErrorKind::ValueMismatch(
666                            ValueKind::Any.get_value_name(),
667                            ValueKind::Void.get_value_name(),
668                        ),
669                        arg_pos_2,
670                    ))
671                }
672            }
673            kind => Err(Error::new(
674                ErrorKind::ValueMismatch(
675                    ValueKind::Identifier("".to_owned()).get_value_name(),
676                    kind.get_value_name(),
677                ),
678                arg_pos_1,
679            )),
680        }
681    }
682
683    /// Calls the label passed in. In other words, it changes the instruction pointer.
684    /// In the future, this would be changed to include the number of parameters on the stack.
685    ///
686    /// # Arguments
687    /// `pos` - The position where this instruction was called.
688    fn call(&mut self, pos: usize) -> Result<Option<Rc<Value>>, Error> {
689        let (arg_pos_1, arg1) = self.get_arg_unevaluated(1, pos)?;
690        match &arg1.kind {
691            ValueKind::Identifier(label_name) => {
692                let caller_pos = self.code.get_current_pos();
693                let (start, end) = self.code.set_label_location(label_name, arg_pos_1)?;
694                let store = self.call_stack.peek().filter(|frame| {
695                    if let Some((cur_start, cur_end)) = self.code.get_label_start_end(&frame.name) {
696                        cur_start < start && end < cur_end
697                    } else {
698                        false
699                    }
700                }).map(|frame| &frame.current_store);
701
702                let new_frame = Frame::new(caller_pos, label_name, store);
703                self.call_stack.push(new_frame);
704
705                Ok(None)
706            },
707            kind => Err(Error::new(
708                ErrorKind::ValueMismatch(
709                    ValueKind::Label("".to_owned()).get_value_name(),
710                    kind.get_value_name(),
711                ),
712                arg_pos_1,
713            )),
714        }
715    }
716
717    /// Gets the next argument.
718    /// This funtion is usually called by instructions.
719    ///
720    /// # Arguments
721    /// * `expected_args` - The number of arguments remaining for the instruction.
722    /// * `pos` - The position where the instrution was called.
723    fn get_arg(
724        &mut self,
725        expected_args: usize,
726        pos: usize,
727    ) -> Result<(usize, Option<Rc<Value>>), Error> {
728        let arg = self
729            .next()
730            .ok_or_else(|| Error::new(ErrorKind::ExpectedArgs(expected_args), pos))?;
731        Ok((arg.pos, self.evaluate_value(arg)?))
732    }
733
734    /// Gets the next argument.
735    /// This funtion is usually called by instructions.
736    ///
737    /// # Arguments
738    /// * `expected_args` - The number of arguments remaining for the instruction.
739    /// * `pos` - The position where the instrution was called.
740    fn get_arg_unevaluated(
741        &mut self,
742        expected_args: usize,
743        pos: usize,
744    ) -> Result<(usize, Rc<Value>), Error> {
745        let arg = self
746            .next()
747            .ok_or_else(|| Error::new(ErrorKind::ExpectedArgs(expected_args), pos))?;
748        Ok((arg.pos, arg))
749    }
750
751    /// Gets the next value.
752    /// This method needs to be abstracted away because Rust will complain with the message that self.code was mutabley borrowed more than once.
753    fn next(&mut self) -> Option<Rc<Value>> {
754        self.code.next()
755    }
756
757    /// Checks if there are any more values left.
758    /// This method needs to be abstracted away because Rust will complain with the message that self.code was mutabley borrowed more than once.
759    fn is_finished(&self) -> bool {
760        self.code.is_finished() || self.call_stack.is_empty()
761    }
762}