std::fmt::Display for Assembly

This commit is contained in:
Andrew Morris
2023-03-03 19:33:47 +11:00
parent 9e5b65b594
commit d046ff8c3c

View File

@@ -4,40 +4,138 @@ struct Assembly {
definitions: Vec<Definition>,
}
impl std::fmt::Display for Assembly {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
for definition in &self.definitions {
write!(f, "{}\n", definition)?;
}
return Ok(());
}
}
struct Definition {
ref_: DefinitionRef,
content: DefinitionContent,
}
impl std::fmt::Display for Definition {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{} = {}", self.ref_, self.content)
}
}
enum DefinitionContent {
Function(Function),
Value(Value),
}
impl std::fmt::Display for DefinitionContent {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
DefinitionContent::Function(function) => {
write!(f, "{}", function)
}
DefinitionContent::Value(value) => {
write!(f, "{}", value)
}
}
}
}
struct DefinitionRef {
name: String,
}
impl std::fmt::Display for DefinitionRef {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "@{}", self.name)
}
}
struct Function {
parameters: Vec<Register>,
body: Vec<InstructionOrLabel>,
}
impl std::fmt::Display for Function {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "function(")?;
for (i, parameter) in self.parameters.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{}", parameter)?;
}
write!(f, ") {{\n")?;
for instruction_or_label in &self.body {
match instruction_or_label {
InstructionOrLabel::Instruction(instruction) => {
write!(f, " {}\n", instruction)?;
}
InstructionOrLabel::Label(label) => {
write!(f, "{}\n", label)?;
}
}
}
write!(f, "}}")
}
}
enum Register {
Return,
This,
Named(String),
}
impl std::fmt::Display for Register {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Register::Return => write!(f, "%return"),
Register::This => write!(f, "%this"),
Register::Named(name) => write!(f, "%{}", name),
}
}
}
enum InstructionOrLabel {
Instruction(Instruction),
Label(Label),
}
impl std::fmt::Display for InstructionOrLabel {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
InstructionOrLabel::Instruction(instruction) => {
write!(f, "{}", instruction)
}
InstructionOrLabel::Label(label) => {
write!(f, "{}", label)
}
}
}
}
struct Label {
name: String,
}
impl std::fmt::Display for Label {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}:", self.name)
}
}
struct LabelRef {
name: String,
}
impl std::fmt::Display for LabelRef {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, ":{}", self.name)
}
}
pub enum Instruction {
End,
Mov(Value, Register),
@@ -85,6 +183,137 @@ pub enum Instruction {
New(Value, Value, Register),
}
impl std::fmt::Display for Instruction {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Instruction::End => write!(f, "end"),
Instruction::Mov(value, register) => {
write!(f, "mov {} {}", value, register)
}
Instruction::OpInc(register) => write!(f, "op++ {}", register),
Instruction::OpDec(register) => write!(f, "op-- {}", register),
Instruction::OpPlus(lhs, rhs, register) => {
write!(f, "op+ {} {} {}", lhs, rhs, register)
}
Instruction::OpMinus(lhs, rhs, register) => {
write!(f, "op- {} {} {}", lhs, rhs, register)
}
Instruction::OpMul(lhs, rhs, register) => {
write!(f, "op* {} {} {}", lhs, rhs, register)
}
Instruction::OpDiv(lhs, rhs, register) => {
write!(f, "op/ {} {} {}", lhs, rhs, register)
}
Instruction::OpMod(lhs, rhs, register) => {
write!(f, "op% {} {} {}", lhs, rhs, register)
}
Instruction::OpExp(lhs, rhs, register) => {
write!(f, "op** {} {} {}", lhs, rhs, register)
}
Instruction::OpEq(lhs, rhs, register) => {
write!(f, "op== {} {} {}", lhs, rhs, register)
}
Instruction::OpNe(lhs, rhs, register) => {
write!(f, "op!= {} {} {}", lhs, rhs, register)
}
Instruction::OpTripleEq(lhs, rhs, register) => {
write!(f, "op=== {} {} {}", lhs, rhs, register)
}
Instruction::OpTripleNe(lhs, rhs, register) => {
write!(f, "op!== {} {} {}", lhs, rhs, register)
}
Instruction::OpAnd(lhs, rhs, register) => {
write!(f, "op&& {} {} {}", lhs, rhs, register)
}
Instruction::OpOr(lhs, rhs, register) => {
write!(f, "op|| {} {} {}", lhs, rhs, register)
}
Instruction::OpNot(value, register) => {
write!(f, "op! {} {}", value, register)
}
Instruction::OpLess(lhs, rhs, register) => {
write!(f, "op< {} {} {}", lhs, rhs, register)
}
Instruction::OpLessEq(lhs, rhs, register) => {
write!(f, "op<= {} {} {}", lhs, rhs, register)
}
Instruction::OpGreater(lhs, rhs, register) => {
write!(f, "op> {} {} {}", lhs, rhs, register)
}
Instruction::OpGreaterEq(lhs, rhs, register) => {
write!(f, "op>= {} {} {}", lhs, rhs, register)
}
Instruction::OpNullishCoalesce(lhs, rhs, register) => {
write!(f, "op?? {} {} {}", lhs, rhs, register)
}
Instruction::OpOptionalChain(lhs, rhs, register) => {
write!(f, "op?. {} {} {}", lhs, rhs, register)
}
Instruction::OpBitAnd(lhs, rhs, register) => {
write!(f, "op& {} {} {}", lhs, rhs, register)
}
Instruction::OpBitOr(lhs, rhs, register) => {
write!(f, "op| {} {} {}", lhs, rhs, register)
}
Instruction::OpBitNot(value, register) => {
write!(f, "op~ {} {}", value, register)
}
Instruction::OpBitXor(lhs, rhs, register) => {
write!(f, "op^ {} {} {}", lhs, rhs, register)
}
Instruction::OpLeftShift(lhs, rhs, register) => {
write!(f, "op<< {} {} {}", lhs, rhs, register)
}
Instruction::OpRightShift(lhs, rhs, register) => {
write!(f, "op>> {} {} {}", lhs, rhs, register)
}
Instruction::OpRightShiftUnsigned(lhs, rhs, register) => {
write!(f, "op>>> {} {} {}", lhs, rhs, register)
}
Instruction::TypeOf(value, register) => {
write!(f, "typeof {} {}", value, register)
}
Instruction::InstanceOf(lhs, rhs, register) => {
write!(f, "instanceof {} {} {}", lhs, rhs, register)
}
Instruction::In(lhs, rhs, register) => {
write!(f, "in {} {} {}", lhs, rhs, register)
}
Instruction::Call(value, args, register) => {
write!(f, "call {} {} {}", value, args, register)
}
Instruction::Apply(value, this, args, register) => {
write!(f, "apply {} {} {} {}", value, this, args, register)
}
Instruction::Bind(value, args, register) => {
write!(f, "bind {} {} {}", value, args, register)
}
Instruction::Sub(lhs, rhs, register) => {
write!(f, "sub {} {} {}", lhs, rhs, register)
}
Instruction::SubMov(subscript, value, register) => {
write!(f, "submov {} {} {}", subscript, value, register)
}
Instruction::SubCall(obj, subscript, args, register) => {
write!(f, "subcall {} {} {} {}", obj, subscript, args, register)
}
Instruction::Jmp(label) => write!(f, "jmp {}", label),
Instruction::JmpIf(value, label) => {
write!(f, "jmpif {} {}", value, label)
}
Instruction::UnaryPlus(value, register) => {
write!(f, "unary+ {} {}", value, register)
}
Instruction::UnaryMinus(value, register) => {
write!(f, "unary- {} {}", value, register)
}
Instruction::New(value, args, register) => {
write!(f, "new {} {} {}", value, args, register)
}
}
}
}
enum Value {
Undefined,
Null,
@@ -95,13 +324,69 @@ enum Value {
Object(Box<Object>),
Register(Register),
DefinitionRef(DefinitionRef),
Label(Label),
LabelRef(LabelRef),
}
impl std::fmt::Display for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Value::Undefined => write!(f, "undefined"),
Value::Null => write!(f, "null"),
Value::Boolean(value) => write!(f, "{}", value),
Value::Number(value) => write!(f, "{}", value),
Value::String(value) => write!(
f,
"{}",
serde_json::to_string(&value).expect("Failed json serialization")
),
Value::Array(value) => write!(f, "{}", value),
Value::Object(value) => write!(f, "{}", value),
Value::Register(value) => write!(f, "{}", value),
Value::DefinitionRef(value) => write!(f, "{}", value),
Value::LabelRef(value) => write!(f, "{}", value),
}
}
}
struct Array {
values: Vec<Value>,
}
impl std::fmt::Display for Array {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "[")?;
for (i, value) in self.values.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{}", value)?;
}
write!(f, "]")
}
}
struct Object {
properties: Vec<(String, Value)>,
}
impl std::fmt::Display for Object {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.properties.len() == 0 {
return write!(f, "{{}}");
}
write!(f, "{{ ")?;
for (i, (key, value)) in self.properties.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(
f,
"{}: {}",
serde_json::to_string(&key).expect("Failed json serialization"),
value
)?;
}
write!(f, " }}")
}
}