194 lines
5.0 KiB
Rust
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)
|
|
}
|
|
}
|
|
}
|
|
}
|