deimos-lang/dvm-lib/src/instruction.rs
2026-03-09 19:22:35 -05:00

194 lines
5.0 KiB
Rust

use std::fmt::{Display, Formatter};
use std::rc::Rc;
pub type Register = usize;
pub type StackFrameOffset = isize;
pub type ConstantName = Rc<str>;
pub type FunctionName = Rc<str>;
pub type ArgCount = usize;
pub type CallerPopCount = usize;
pub enum Instruction {
Move(MoveOperand, Location),
Push(PushOperand),
InvokeStatic(FunctionName, ArgCount),
InvokePlatformStatic(FunctionName, ArgCount),
Add(AddOperand, AddOperand, Location),
Subtract(SubtractOperand, SubtractOperand, Location),
Pop(Option<Location>),
SetReturnValue(ReturnOperand),
Return,
}
impl Display for Instruction {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Instruction::Move(source, destination) => {
write!(f, "mov {}, {}", source, destination)
}
Instruction::Push(source) => write!(f, "push {}", source),
Instruction::InvokeStatic(name, arg_count) => {
write!(f, "invoke_static {} (arg_count: {})", name, arg_count)
}
Instruction::InvokePlatformStatic(name, arg_count) => {
write!(
f,
"invoke_platform_static {} (arg_count: {})",
name, arg_count
)
}
Instruction::Pop(maybe_destination) => {
if let Some(destination) = maybe_destination {
write!(f, "pop {}", destination)
} else {
write!(f, "pop")
}
}
Instruction::Add(left, right, destination) => {
write!(f, "add {}, {}, {}", left, right, destination)
}
Instruction::Subtract(left, right, destination) => {
write!(f, "sub {}, {}, {}", left, right, destination)
}
Instruction::SetReturnValue(source) => {
write!(f, "srv {}", source)
}
Instruction::Return => {
write!(f, "ret")
}
}
}
}
pub enum Location {
Register(Register),
StackFrameOffset(StackFrameOffset),
}
impl Display for Location {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Location::Register(register) => {
write!(f, "r{}", register)
}
Location::StackFrameOffset(offset) => {
if offset.is_positive() || *offset == 0 {
write!(f, "fp+{}", offset)
} else {
write!(f, "fp{}", offset)
}
}
}
}
}
pub enum MoveOperand {
Location(Location),
Int(i32),
String(Rc<str>),
}
impl Display for MoveOperand {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
MoveOperand::Location(location) => {
write!(f, "{}", location)
}
MoveOperand::Int(i) => {
write!(f, "{}", i)
}
MoveOperand::String(s) => {
write!(f, "{}", s)
}
}
}
}
pub enum PushOperand {
Location(Location),
Int(i32),
String(Rc<str>),
}
impl Display for PushOperand {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
PushOperand::Location(location) => {
write!(f, "{}", location)
}
PushOperand::Int(i) => {
write!(f, "{}", i)
}
PushOperand::String(s) => {
write!(f, "{}", s)
}
}
}
}
pub enum AddOperand {
Location(Location),
Int(i32),
String(Rc<str>),
}
impl Display for AddOperand {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
AddOperand::Location(location) => {
write!(f, "{}", location)
}
AddOperand::Int(i) => {
write!(f, "{}", i)
}
AddOperand::String(s) => {
write!(f, "{}", s)
}
}
}
}
pub enum SubtractOperand {
Location(Location),
Int(i32),
}
impl Display for SubtractOperand {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
SubtractOperand::Location(location) => {
write!(f, "{}", location)
}
SubtractOperand::Int(i) => {
write!(f, "{}", i)
}
}
}
}
pub enum ReturnOperand {
Location(Location),
Int(i32),
String(Rc<str>),
}
impl Display for ReturnOperand {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ReturnOperand::Location(location) => {
write!(f, "{}", location)
}
ReturnOperand::Int(i) => {
write!(f, "{}", i)
}
ReturnOperand::String(s) => {
write!(f, "{}", s)
}
}
}
}