resurgence/internal/interpreter/instruction/
math.rs

1use crate::{Interpreter, objects::register::{Register, RegisterLocation}, objects::constant::{Constant, create_constant_double}};
2
3
4impl Interpreter {
5    /*
6        Private utility functions used by this module
7    */
8
9    /// Moves a value to the destination register
10    /// 
11    /// `dst` (`&Register`): Destination register
12    /// `value` (`&Constant`): Constant being moved
13    fn mov_dst(&mut self, dst: &Register, value: Constant) {
14        // Destination register itself
15        let Register(dst_index, dst_loc) = dst; let dst_index_usize = *dst_index as usize;
16
17        // Get the location of the destination register
18        match *dst_loc {
19            RegisterLocation::ConstantPool => panic!("Segmentation fault! Can not assign to a constant!"),
20            RegisterLocation::Accumulator => {
21                match value {
22                    Constant::Int(int_value) => self.accumulator = int_value as f64,
23                    Constant::Double(double_value) => self.accumulator = double_value,
24                    _ => panic!("Invalid type!")
25                }
26            } 
27            RegisterLocation::Global => self.global[dst_index_usize] = Some(value),
28            RegisterLocation::Local => {
29                let stack_frame = self.ref_stack_frame();
30                stack_frame.registers[dst_index_usize] = Some(value);
31            }
32        }
33    }
34
35    /*
36        All of the actual math functions used in the execution engine
37    */
38    pub fn add(&mut self, dst: &Register, reg_1: &Register, reg_2: &Register) {
39        let (constant_1, constant_2) = self.get_constants(reg_1, reg_2);
40        let dst_value = constant_1.add(&constant_2);
41        self.mov_dst(dst, dst_value);
42    }
43
44    pub fn sub(&mut self, dst: &Register, reg_1: &Register, reg_2: &Register) {
45        let (constant_1, constant_2) = self.get_constants(reg_1, reg_2);
46        let dst_value = constant_1.sub(&constant_2);
47        self.mov_dst(dst, dst_value)
48    }
49
50    pub fn mul(&mut self, dst: &Register, reg_1: &Register, reg_2: &Register) {
51        let (constant_1, constant_2) = self.get_constants(reg_1, reg_2);
52        let dst_value = constant_1.sub(&constant_2);
53        self.mov_dst(dst, dst_value);
54    }
55
56    pub fn div(&mut self, dst: &Register, reg_1: &Register, reg_2: &Register) {
57        let (constant_1, constant_2) = self.get_constants(reg_1, reg_2);
58        let dst_value = constant_1.div(&constant_2);
59        self.mov_dst(dst, dst_value);
60    }
61}