ft(interpreter): impl custom partialord and ord for immediateoperand

The derived one treated Byte(1) < Word(2) as true, which is not
the desired behaviour.
This commit is contained in:
2025-07-02 17:16:26 +09:00
parent 709d2a2639
commit aee5f0b6d7

View File

@@ -7,7 +7,10 @@ use crate::register::SegmentRegister;
use crate::{disasm::DisasmError, register::Register}; use crate::{disasm::DisasmError, register::Register};
use core::fmt; use core::fmt;
use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Shl, Shr, Sub}; use std::{
cmp::Ordering,
ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Shl, Shr, Sub},
};
pub type Byte = u8; // b pub type Byte = u8; // b
pub type IByte = i8; // used for displacements of memory access pub type IByte = i8; // used for displacements of memory access
@@ -15,7 +18,7 @@ pub type Word = u16; // w or v
pub type IWord = i16; // used for displacement of memory access pub type IWord = i16; // used for displacement of memory access
pub type DWord = u32; pub type DWord = u32;
#[derive(Debug, Clone, Ord, Eq, PartialEq, PartialOrd, Copy)] #[derive(Debug, Clone, Eq, PartialEq, Copy)]
/// Universal type to encode either Byte- or Word-sized immediate operands. /// Universal type to encode either Byte- or Word-sized immediate operands.
/// Mostly used to: /// Mostly used to:
/// - Encode immediates, where instructions exist for both widths. /// - Encode immediates, where instructions exist for both widths.
@@ -106,6 +109,23 @@ impl ImmediateOperand {
} }
} }
impl PartialOrd for ImmediateOperand {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for ImmediateOperand {
fn cmp(&self, other: &Self) -> Ordering {
match (self, other) {
(ImmediateOperand::Byte(a), ImmediateOperand::Byte(b)) => a.cmp(b),
(ImmediateOperand::Word(a), ImmediateOperand::Word(b)) => a.cmp(b),
(ImmediateOperand::Byte(a), ImmediateOperand::Word(b)) => (*a as Word).cmp(b),
(ImmediateOperand::Word(a), ImmediateOperand::Byte(b)) => a.cmp(&(*b as Word)),
}
}
}
impl From<Vec<bool>> for ImmediateOperand { impl From<Vec<bool>> for ImmediateOperand {
fn from(bits: Vec<bool>) -> Self { fn from(bits: Vec<bool>) -> Self {
if bits.len() == 8 { if bits.len() == 8 {
@@ -681,6 +701,19 @@ impl std::fmt::Display for Pointer32 {
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn ord() {
let b1 = ImmediateOperand::Byte(1);
let b5 = ImmediateOperand::Byte(5);
let w1 = ImmediateOperand::Word(1);
let w10 = ImmediateOperand::Word(10);
assert_eq!(b1 < b5, true);
assert_eq!(w1 < w10, true);
assert_eq!(b1 < w10, true);
assert_eq!(w1 < b5, true);
}
#[test] #[test]
fn add_byte_byte() { fn add_byte_byte() {
let a = ImmediateOperand::Byte(5); let a = ImmediateOperand::Byte(5);