celestial_hub_astrolabe/ast/
to_string.rs1use crate::lexer::tokens::{Type, Value};
2use std::fmt;
3
4use super::{
5 DataSection, Instruction, InstructionArgument, Program, Statement, TextSection, Variable,
6};
7
8impl fmt::Display for Program {
9 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10 write!(f, "{}\n{}", self.data_section, self.text_section)
11 }
12}
13
14impl fmt::Display for DataSection {
15 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
16 let variables_str = self
17 .variables
18 .iter()
19 .map(|var| var.to_string())
20 .collect::<Vec<_>>()
21 .join("\t\n");
22 write!(
23 f,
24 ".data\n{}{}",
25 variables_str,
26 if variables_str.is_empty() { "" } else { "\n" }
27 )
28 }
29}
30
31impl fmt::Display for Variable {
32 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33 match &self.type_ {
34 Type::Asciiz => {
35 if let Value::String(value) = &self.value {
36 write!(f, "{name}: .asciiz {value}", name = self.name)
37 } else {
38 unreachable!()
39 }
40 }
41 Type::Space => {
42 if let Value::Bytes(size) = &self.value {
43 write!(f, "{name}: .space {size}", name = self.name)
44 } else {
45 unreachable!()
46 }
47 }
48 }
49 }
50}
51
52impl fmt::Display for TextSection {
53 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54 let statements_str = self
55 .statements
56 .iter()
57 .map(|stmt| stmt.to_string())
58 .collect::<Vec<_>>()
59 .join("\n");
60 write!(
61 f,
62 "\t.text\n\t.global {}\n{}",
63 self.entrypoint, statements_str
64 )
65 }
66}
67
68impl fmt::Display for Statement {
69 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70 match self {
71 Statement::Instruction(i) => write!(f, "\t{}", i),
72 Statement::Label(l) => write!(f, "{}:", l),
73 }
74 }
75}
76
77impl fmt::Display for Instruction {
78 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79 match self {
80 Instruction::Li(args) => write!(f, "li {}", write_args(args)),
81 Instruction::Add(args) => write!(f, "add {}", write_args(args)),
82 Instruction::Mul(args) => write!(f, "mul {}", write_args(args)),
83 Instruction::Div(args) => write!(f, "div {}", write_args(args)),
84 Instruction::La(args) => write!(f, "la {}", write_args(args)),
85 Instruction::Syscall => write!(f, "syscall"),
86 Instruction::Move(args) => write!(f, "move {}", write_args(args)),
87 Instruction::Jal(args) => write!(f, "jal {}", write_args(args)),
88 Instruction::Beq(args) => write!(f, "beq {}", write_args(args)),
89 Instruction::Sub(args) => write!(f, "sub {}", write_args(args)),
90 Instruction::Jr(args) => write!(f, "jr {}", write_args(args)),
91 Instruction::Addi(args) => write!(f, "addi {}", write_args(args)),
92 Instruction::Andi(args) => write!(f, "andi {}", write_args(args)),
93 Instruction::J(args) => write!(f, "j {}", write_args(args)),
94 Instruction::Sw(args) => write!(f, "sw {}, 0({})", args[0], args[1]),
95 Instruction::Lw(args) => write!(f, "lw {}", write_args(args)),
96 Instruction::Slt(args) => write!(f, "slt {}", write_args(args)),
97 Instruction::Beqz(args) => write!(f, "beqz {}", write_args(args)),
98 Instruction::Bnez(args) => write!(f, "bnez {}", write_args(args)),
99 Instruction::Bltz(args) => write!(f, "bltz {}", write_args(args)),
100 Instruction::Bgtz(args) => write!(f, "bgtz {}", write_args(args)),
101 Instruction::Blez(args) => write!(f, "blez {}", write_args(args)),
102 Instruction::Bgez(args) => write!(f, "bgez {}", write_args(args)),
103 Instruction::Blt(args) => write!(f, "blt {}", write_args(args)),
104 Instruction::Bgt(args) => write!(f, "bgt {}", write_args(args)),
105 Instruction::Ble(args) => write!(f, "ble {}", write_args(args)),
106 Instruction::Bge(args) => write!(f, "bge {}", write_args(args)),
107 Instruction::Bne(args) => write!(f, "bne {}", write_args(args)),
108 Instruction::Sle(args) => write!(f, "sle {}", write_args(args)),
109 Instruction::Sgt(args) => write!(f, "sgt {}", write_args(args)),
110 Instruction::Sge(args) => write!(f, "sge {}", write_args(args)),
111 Instruction::Seq(args) => write!(f, "seq {}", write_args(args)),
112 Instruction::Sne(args) => write!(f, "sne {}", write_args(args)),
113 Instruction::Halt => write!(f, "halt"),
114 }
115 }
116}
117
118fn write_args(args: &[InstructionArgument]) -> String {
119 args
120 .iter()
121 .map(|arg| arg.to_string())
122 .collect::<Vec<_>>()
123 .join(", ")
124}
125
126impl fmt::Display for InstructionArgument {
127 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128 match self {
129 InstructionArgument::Register(r) => write!(f, "{}", r.name),
130 InstructionArgument::Immediate(i) => write!(f, "{}", i),
131 InstructionArgument::Label(l) => write!(f, "{}", l),
132 InstructionArgument::Literal(l) => write!(f, "{}", l),
133 }
134 }
135}