306 lines
8.2 KiB
Rust
306 lines
8.2 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 type ClassFqn = Rc<str>;
|
|
pub type FieldIndex = usize;
|
|
|
|
pub enum Instruction {
|
|
Move(MoveOperand, Location),
|
|
Push(PushOperand),
|
|
|
|
InvokeStatic(FunctionName, ArgCount),
|
|
InvokePlatformStatic(FunctionName, ArgCount),
|
|
|
|
Allocate(ClassFqn, Location),
|
|
|
|
/// (self_location, field_index, destination)
|
|
GetFieldPointer(Location, FieldIndex, Location),
|
|
|
|
/// (self_location, field_index, destination)
|
|
GetFieldPointerMut(Location, FieldIndex, Location),
|
|
|
|
/// (field_pointer_location, destination)
|
|
ReadField(Location, Location),
|
|
|
|
/// (field_pointer_mut_location, operand)
|
|
SetField(Location, SetFieldOperand),
|
|
|
|
Add(AddOperand, AddOperand, Location),
|
|
Subtract(SubtractOperand, SubtractOperand, Location),
|
|
Multiply(MultiplyOperand, MultiplyOperand, 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::Multiply(left, right, destination) => {
|
|
write!(f, "mul {}, {}, {}", left, right, destination)
|
|
}
|
|
Instruction::SetReturnValue(source) => {
|
|
write!(f, "srv {}", source)
|
|
}
|
|
Instruction::Return => {
|
|
write!(f, "ret")
|
|
}
|
|
Instruction::Allocate(class_fqn, location) => {
|
|
write!(f, "alloc {}, {}", class_fqn, location)
|
|
}
|
|
|
|
Instruction::GetFieldPointer(self_location, field_index, destination) => {
|
|
write!(
|
|
f,
|
|
"getf &{}.{}, {}",
|
|
self_location, field_index, destination
|
|
)
|
|
}
|
|
Instruction::GetFieldPointerMut(self_location, field_index, destination) => {
|
|
write!(
|
|
f,
|
|
"getf &mut {}.{}, {}",
|
|
self_location, field_index, destination
|
|
)
|
|
}
|
|
Instruction::ReadField(field_pointer_location, destination) => {
|
|
write!(f, "readf *{}, {}", field_pointer_location, destination)
|
|
}
|
|
Instruction::SetField(self_location, destination) => {
|
|
write!(f, "setf {}, {}", self_location, destination)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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),
|
|
Double(f64),
|
|
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::Double(d) => {
|
|
write!(f, "{}", d)
|
|
}
|
|
MoveOperand::String(s) => {
|
|
write!(f, "{}", s)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum PushOperand {
|
|
Location(Location),
|
|
Int(i32),
|
|
Double(f64),
|
|
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::Double(d) => {
|
|
write!(f, "{}", d)
|
|
}
|
|
PushOperand::String(s) => {
|
|
write!(f, "{}", s)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum AddOperand {
|
|
Location(Location),
|
|
Int(i32),
|
|
Double(f64),
|
|
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::Double(d) => {
|
|
write!(f, "{}", d)
|
|
}
|
|
AddOperand::String(s) => {
|
|
write!(f, "{}", s)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum SubtractOperand {
|
|
Location(Location),
|
|
Int(i32),
|
|
Double(f64),
|
|
}
|
|
|
|
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)
|
|
}
|
|
SubtractOperand::Double(d) => {
|
|
write!(f, "{}", d)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum MultiplyOperand {
|
|
Location(Location),
|
|
Int(i32),
|
|
Double(f64),
|
|
}
|
|
|
|
impl Display for MultiplyOperand {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
MultiplyOperand::Location(location) => {
|
|
write!(f, "{}", location)
|
|
}
|
|
MultiplyOperand::Int(i) => {
|
|
write!(f, "{}", i)
|
|
}
|
|
MultiplyOperand::Double(d) => {
|
|
write!(f, "{}", d)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum ReturnOperand {
|
|
Location(Location),
|
|
Int(i32),
|
|
Double(f64),
|
|
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::Double(d) => {
|
|
write!(f, "{}", d)
|
|
}
|
|
ReturnOperand::String(s) => {
|
|
write!(f, "{}", s)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum SetFieldOperand {
|
|
Location(Location),
|
|
Int(i32),
|
|
Double(f64),
|
|
String(Rc<str>),
|
|
}
|
|
|
|
impl Display for SetFieldOperand {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
SetFieldOperand::Location(location) => {
|
|
write!(f, "{}", location)
|
|
}
|
|
SetFieldOperand::Int(i) => {
|
|
write!(f, "{}", i)
|
|
}
|
|
SetFieldOperand::Double(d) => {
|
|
write!(f, "{}", d)
|
|
}
|
|
SetFieldOperand::String(s) => {
|
|
write!(f, "{}", s)
|
|
}
|
|
}
|
|
}
|
|
}
|