112 lines
3.4 KiB
Rust
112 lines
3.4 KiB
Rust
//! Part of an [Instruction][crate::Instruction] that is encoded as a single byte.
|
|
|
|
use std::fmt::{self, Debug, Display, Formatter};
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
/// Part of an [Instruction][crate::Instruction] that is encoded as a single byte.
|
|
#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
|
pub struct Operation(pub u8);
|
|
|
|
impl Operation {
|
|
// Stack manipulation
|
|
pub const POINT: Operation = Operation(0);
|
|
pub const CLOSE: Operation = Operation(1);
|
|
|
|
// Loaders
|
|
pub const LOAD_ENCODED: Operation = Operation(2);
|
|
pub const LOAD_CONSTANT: Operation = Operation(3);
|
|
pub const LOAD_FUNCTION: Operation = Operation(4);
|
|
pub const LOAD_LIST: Operation = Operation(5);
|
|
pub const LOAD_SELF: Operation = Operation(6);
|
|
|
|
// Arithmetic
|
|
pub const ADD: Operation = Operation(7);
|
|
pub const SUBTRACT: Operation = Operation(8);
|
|
pub const MULTIPLY: Operation = Operation(9);
|
|
pub const DIVIDE: Operation = Operation(10);
|
|
pub const MODULO: Operation = Operation(11);
|
|
|
|
// Comparison
|
|
pub const EQUAL: Operation = Operation(12);
|
|
pub const LESS: Operation = Operation(13);
|
|
pub const LESS_EQUAL: Operation = Operation(14);
|
|
|
|
// Unary operations
|
|
pub const NEGATE: Operation = Operation(15);
|
|
pub const NOT: Operation = Operation(16);
|
|
|
|
// Logical operations
|
|
pub const TEST: Operation = Operation(17);
|
|
pub const TEST_SET: Operation = Operation(18);
|
|
|
|
// Function calls
|
|
pub const CALL: Operation = Operation(19);
|
|
pub const CALL_NATIVE: Operation = Operation(20);
|
|
|
|
// Control flow
|
|
pub const JUMP: Operation = Operation(21);
|
|
pub const RETURN: Operation = Operation(22);
|
|
}
|
|
|
|
impl Operation {
|
|
pub fn name(&self) -> &'static str {
|
|
match *self {
|
|
Self::POINT => "POINT",
|
|
Self::CLOSE => "CLOSE",
|
|
Self::LOAD_ENCODED => "LOAD_ENCODED",
|
|
Self::LOAD_CONSTANT => "LOAD_CONSTANT",
|
|
Self::LOAD_FUNCTION => "LOAD_FUNCTION",
|
|
Self::LOAD_LIST => "LOAD_LIST",
|
|
Self::LOAD_SELF => "LOAD_SELF",
|
|
Self::ADD => "ADD",
|
|
Self::SUBTRACT => "SUBTRACT",
|
|
Self::MULTIPLY => "MULTIPLY",
|
|
Self::DIVIDE => "DIVIDE",
|
|
Self::MODULO => "MODULO",
|
|
Self::EQUAL => "EQUAL",
|
|
Self::LESS => "LESS",
|
|
Self::LESS_EQUAL => "LESS_EQUAL",
|
|
Self::NEGATE => "NEGATE",
|
|
Self::NOT => "NOT",
|
|
Self::TEST => "TEST",
|
|
Self::TEST_SET => "TEST_SET",
|
|
Self::CALL => "CALL",
|
|
Self::CALL_NATIVE => "CALL_NATIVE",
|
|
Self::JUMP => "JUMP",
|
|
Self::RETURN => "RETURN",
|
|
unknown => panic!("Unknown operation: {}", unknown.0),
|
|
}
|
|
}
|
|
|
|
pub fn is_math(self) -> bool {
|
|
matches!(
|
|
self,
|
|
Operation::ADD
|
|
| Operation::SUBTRACT
|
|
| Operation::MULTIPLY
|
|
| Operation::DIVIDE
|
|
| Operation::MODULO
|
|
)
|
|
}
|
|
|
|
pub fn is_comparison(self) -> bool {
|
|
matches!(
|
|
self,
|
|
Operation::EQUAL | Operation::LESS | Operation::LESS_EQUAL
|
|
)
|
|
}
|
|
}
|
|
|
|
impl Debug for Operation {
|
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
write!(f, "{}", self.name())
|
|
}
|
|
}
|
|
|
|
impl Display for Operation {
|
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
write!(f, "{}", self.name())
|
|
}
|
|
}
|