ellie_vm 0.6.5

Ellie VM for running Ellie ByteCode
Documentation
use alloc::format;
use ellie_core::defs::PlatformArchitecture;

use crate::{
    heap_memory::HeapMemory,
    instruction_utils::EQ,
    raw_type::StaticRawType,
    stack::Stack,
    stack_memory::StackMemory,
    utils::{AddressingValues, ThreadPanicReason},
};

use super::{ExecuterPanic, ExecuterResult, StaticProgram};

impl super::InstructionExecuter for EQ {
    fn execute(
        &self,
        heap_memory: &mut HeapMemory,
        _program: StaticProgram,
        current_stack: &mut Stack,
        _stack_memory: &mut StackMemory,
        addressing_value: &AddressingValues,
        _arch: PlatformArchitecture,
    ) -> Result<super::ExecuterResult, super::ExecuterPanic> {
        match &addressing_value {
            AddressingValues::Implicit => {
                match (
                    current_stack.registers.B.type_id.id,
                    current_stack.registers.C.type_id.id,
                ) {
                    (1, 1) | (1, 4) => {
                        let b_value = current_stack.registers.B.to_int();
                        let c_value = current_stack.registers.C.to_int();
                        current_stack.registers.A = StaticRawType::from_bool(b_value == c_value);
                    }
                    (2, 2) => {
                        let b_value = current_stack.registers.B.to_float();
                        let c_value = current_stack.registers.C.to_float();
                        current_stack.registers.A = StaticRawType::from_bool(b_value == c_value);
                    }
                    (3, 3) => {
                        let b_value = current_stack.registers.B.to_double();
                        let c_value = current_stack.registers.C.to_double();
                        current_stack.registers.A = StaticRawType::from_bool(b_value == c_value);
                    }
                    (2, 3) | (3, 2) => {
                        let b_value = current_stack.registers.B.to_double();
                        let c_value = current_stack.registers.C.to_double();
                        current_stack.registers.A = StaticRawType::from_bool(b_value == c_value);
                    }
                    (4, 4) | (4, 1) => {
                        let b_value = current_stack.registers.B.to_byte();
                        let c_value = current_stack.registers.C.to_byte();
                        current_stack.registers.A = StaticRawType::from_bool(b_value == c_value);
                    }
                    (5, 5) => {
                        let b_value = current_stack.registers.B.to_bool();
                        let c_value = current_stack.registers.C.to_bool();
                        current_stack.registers.A = StaticRawType::from_bool(b_value == c_value);
                    }
                    (7, 7) => {
                        let b_value = current_stack.registers.B.to_char();
                        let c_value = current_stack.registers.C.to_char();
                        current_stack.registers.A = StaticRawType::from_bool(b_value == c_value);
                    }
                    (13, 13) => {
                        let b_pointer = current_stack.registers.B.to_int() as usize;
                        let b_ref = match heap_memory.get(&b_pointer) {
                            Some(e) => e.clone(),
                            None => {
                                return Err(ExecuterPanic {
                                    reason: ThreadPanicReason::NullReference(b_pointer),
                                    code_location: format!("{}:{}", file!(), line!()),
                                })
                            }
                        };
                        let c_pointer = current_stack.registers.C.to_int() as usize;
                        let c_ref = match heap_memory.get(&c_pointer) {
                            Some(e) => e.clone(),
                            None => {
                                return Err(ExecuterPanic {
                                    reason: ThreadPanicReason::NullReference(c_pointer),
                                    code_location: format!("{}:{}", file!(), line!()),
                                })
                            }
                        };
                        match (b_ref.type_id.id, c_ref.type_id.id) {
                            (6, 6) => {
                                let b_value = b_ref.to_string();
                                let c_value = c_ref.to_string();
                                current_stack.registers.A =
                                    StaticRawType::from_bool(b_value == c_value);
                            }
                            e => {
                                return Err(ExecuterPanic {
                                    reason: ThreadPanicReason::UncomparableTypes(e.0, e.1),
                                    code_location: format!("{}:{}", file!(), line!()),
                                });
                            }
                        }
                    }
                    _ => {
                        return Err(ExecuterPanic {
                            reason: ThreadPanicReason::UncomparableTypes(
                                current_stack.registers.B.type_id.id,
                                current_stack.registers.C.type_id.id,
                            ),
                            code_location: format!("{}:{}", file!(), line!()),
                        });
                    }
                }
            }
            _ => {
                return Err(ExecuterPanic {
                    reason: ThreadPanicReason::IllegalAddressingValue,
                    code_location: format!("{}:{}", file!(), line!()),
                })
            }
        }
        Ok(ExecuterResult::Continue)
    }
}