Skip to main content

celestial_hub_astrolabe/ast/
to_string.rs

1use 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}