citadel_frontend/ir/
traits.rs

1//! This file contains trait implementations for the IR node and utility structs for the frontend ir representation.
2use crate::util::VecDisplay;
3use std::fmt::Display;
4
5use super::*;
6
7impl Display for DeclFuncStmt<'_> {
8    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9        write!(
10            f,
11            "decl func @{}({}) {}",
12            self.name.ident,
13            self.args.to_string(),
14            self.name._type
15        )
16    }
17}
18
19impl Display for FuncStmt<'_> {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        write!(
22            f,
23            "func @{}({}) {} {{\n{}\n}}",
24            self.name.ident,
25            self.args.to_string(),
26            self.name._type,
27            self.block
28        )
29    }
30}
31
32impl Display for VarStmt<'_> {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        write!(
35            f,
36            "{}{} {} = {}",
37            if self.is_const { '$' } else { '?' },
38            self.name.ident,
39            self.name._type,
40            self.val
41        )
42    }
43}
44
45impl Display for StructStmt<'_> {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        write!(
48            f,
49            "struct @{} {{\n{}\n}}",
50            self.name,
51            self.fields.to_string()
52        )
53    }
54}
55
56impl Display for UnionStmt<'_> {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        write!(
59            f,
60            "union @{} {{\n{}\n}}",
61            self.name,
62            self.variants.to_string()
63        )
64    }
65}
66
67impl Display for LabelStmt<'_> {
68    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69        write!(f, "'{}:", self.name)
70    }
71}
72
73impl Display for ReturnStmt<'_> {
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        write!(f, "ret {}", self.ret_val)
76    }
77}
78
79impl Display for JumpStmt<'_> {
80    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81        write!(f, "jmp {}", self.label)
82    }
83}
84
85impl Display for BlockStmt<'_> {
86    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87        let mut stmts = Vec::new();
88        for stmt in &self.stmts {
89            stmts.push("    ".into());
90            stmts.push(stmt.to_string());
91            stmts.push("\n".into());
92        }
93        stmts.pop();
94        write!(f, "{}", stmts.join(""))
95    }
96}
97
98impl Display for CallExpr<'_> {
99    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100        write!(f, "call %{}({})", self.name, self.args.to_string())
101    }
102}
103
104impl Display for ArithOpExpr<'_> {
105    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106        write!(
107            f,
108            "{} {}, {}",
109            match self.op {
110                Operator::Add => "add",
111                Operator::Sub => "sub",
112                Operator::Mul => "mul",
113                Operator::Div => "div",
114            },
115            self.values.0,
116            self.values.1
117        )
118    }
119}
120
121impl Display for IRStmt<'_> {
122    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123        f.write_str(&match self {
124            IRStmt::DeclaredFunction(func) => func.to_string(),
125            IRStmt::Function(func) => func.to_string(),
126            IRStmt::Variable(var) => var.to_string(),
127            IRStmt::Label(label) => label.to_string(),
128            IRStmt::Return(ret) => ret.to_string(),
129            IRStmt::Exit(exit) => exit.to_string(),
130            IRStmt::Jump(jump) => jump.to_string(),
131            IRStmt::Call(call) => call.to_string(),
132            IRStmt::Struct(_struct) => _struct.to_string(),
133            IRStmt::Union(union) => union.to_string(),
134            IRStmt::Entry(entry) => return entry_to_string(f, entry),
135        })
136    }
137}
138
139fn entry_to_string(f: &mut std::fmt::Formatter<'_>, entry: &BlockStmt<'_>) -> std::fmt::Result {
140    write!(f, "entry {{\n {} \n}}", entry)
141}
142
143impl Display for IRExpr<'_> {
144    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145        f.write_str(&match self {
146            IRExpr::Call(call) => call.to_string(),
147            IRExpr::Literal(lit, _type) => format!("l{{{}:{}}}", lit, _type),
148            IRExpr::ArithOp(op) => op.to_string(),
149            IRExpr::Ident(id) => id.to_string(),
150            IRExpr::StructInit(init) => init.to_string(),
151        })
152    }
153}
154
155impl Display for StructInitExpr<'_> {
156    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
157        write!(f, "struct %{} {{{}}}", self.name, self.values.to_string())
158    }
159}
160
161impl Display for Literal<'_> {
162    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163        write!(
164            f,
165            "{}",
166            &match self {
167                Literal::String(string) => format!("\"{}\"", string),
168                Literal::Char(char) => char.to_string(),
169                Literal::Float32(val) => val.to_string(),
170                Literal::Float64(val) => val.to_string(),
171                Literal::Bool(val) => val.to_string(),
172                Literal::Int8(val) => val.to_string(),
173                Literal::Int16(val) => val.to_string(),
174                Literal::Int32(val) => val.to_string(),
175                Literal::Int64(val) => val.to_string(),
176                Literal::Int128(val) => val.to_string(),
177                Literal::Array(len, val) => format!("[{}; {}]", val.to_string(), len),
178                Literal::Vector(val) => format!("<{}>", val.to_string()),
179            }
180        )
181    }
182}
183
184impl Display for Type<'_> {
185    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
186        match self {
187            Type::Ident(ident) => write!(f, "{ident}"),
188            Type::Array(_type, size) => write!(f, "[{_type}; {size}]"),
189        }
190    }
191}
192
193impl Display for ExitStmt<'_> {
194    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
195        write!(f, "exit {}", self.exit_code)
196    }
197}