fe_mir/pretty_print/
inst.rs

1use std::fmt::{self, Write};
2
3use crate::{
4    db::MirDb,
5    ir::{function::BodyDataStore, inst::InstKind, InstId},
6};
7
8use super::PrettyPrint;
9
10impl PrettyPrint for InstId {
11    fn pretty_print<W: Write>(
12        &self,
13        db: &dyn MirDb,
14        store: &BodyDataStore,
15        w: &mut W,
16    ) -> fmt::Result {
17        if let Some(result) = store.inst_result(*self) {
18            result.pretty_print(db, store, w)?;
19            write!(w, ": ")?;
20
21            let result_ty = result.ty(db, store);
22            result_ty.pretty_print(db, store, w)?;
23            write!(w, " = ")?;
24        }
25
26        match &store.inst_data(*self).kind {
27            InstKind::Declare { local } => {
28                write!(w, "let ")?;
29                local.pretty_print(db, store, w)?;
30                write!(w, ": ")?;
31                store.value_ty(*local).pretty_print(db, store, w)
32            }
33
34            InstKind::Unary { op, value } => {
35                write!(w, "{op}")?;
36                value.pretty_print(db, store, w)
37            }
38
39            InstKind::Binary { op, lhs, rhs } => {
40                lhs.pretty_print(db, store, w)?;
41                write!(w, " {op} ")?;
42                rhs.pretty_print(db, store, w)
43            }
44
45            InstKind::Cast { value, to, .. } => {
46                value.pretty_print(db, store, w)?;
47                write!(w, " as ")?;
48                to.pretty_print(db, store, w)
49            }
50
51            InstKind::AggregateConstruct { ty, args } => {
52                ty.pretty_print(db, store, w)?;
53                write!(w, "{{")?;
54                if args.is_empty() {
55                    return write!(w, "}}");
56                }
57
58                let arg_len = args.len();
59                for (arg_idx, arg) in args.iter().enumerate().take(arg_len - 1) {
60                    write!(w, "<{arg_idx}>: ")?;
61                    arg.pretty_print(db, store, w)?;
62                    write!(w, ", ")?;
63                }
64                let arg = args[arg_len - 1];
65                write!(w, "<{}>: ", arg_len - 1)?;
66                arg.pretty_print(db, store, w)?;
67                write!(w, "}}")
68            }
69
70            InstKind::Bind { src } => {
71                write!(w, "bind ")?;
72                src.pretty_print(db, store, w)
73            }
74
75            InstKind::MemCopy { src } => {
76                write!(w, "memcopy ")?;
77                src.pretty_print(db, store, w)
78            }
79
80            InstKind::Load { src } => {
81                write!(w, "load ")?;
82                src.pretty_print(db, store, w)
83            }
84
85            InstKind::AggregateAccess { value, indices } => {
86                value.pretty_print(db, store, w)?;
87                for index in indices {
88                    write!(w, ".<")?;
89                    index.pretty_print(db, store, w)?;
90                    write!(w, ">")?
91                }
92                Ok(())
93            }
94
95            InstKind::MapAccess { value, key } => {
96                value.pretty_print(db, store, w)?;
97                write!(w, "{{")?;
98                key.pretty_print(db, store, w)?;
99                write!(w, "}}")
100            }
101
102            InstKind::Call {
103                func,
104                args,
105                call_type,
106            } => {
107                let name = func.debug_name(db);
108                write!(w, "{name}@{call_type}(")?;
109                args.as_slice().pretty_print(db, store, w)?;
110                write!(w, ")")
111            }
112
113            InstKind::Jump { dest } => {
114                write!(w, "jump BB{}", dest.index())
115            }
116
117            InstKind::Branch { cond, then, else_ } => {
118                write!(w, "branch ")?;
119                cond.pretty_print(db, store, w)?;
120                write!(w, " then: BB{} else: BB{}", then.index(), else_.index())
121            }
122
123            InstKind::Switch {
124                disc,
125                table,
126                default,
127            } => {
128                write!(w, "switch ")?;
129                disc.pretty_print(db, store, w)?;
130                for (value, block) in table.iter() {
131                    write!(w, " ")?;
132                    value.pretty_print(db, store, w)?;
133                    write!(w, ": BB{}", block.index())?;
134                }
135
136                if let Some(default) = default {
137                    write!(w, " default: BB{}", default.index())
138                } else {
139                    Ok(())
140                }
141            }
142
143            InstKind::Revert { arg } => {
144                write!(w, "revert ")?;
145                if let Some(arg) = arg {
146                    arg.pretty_print(db, store, w)?;
147                }
148                Ok(())
149            }
150
151            InstKind::Emit { arg } => {
152                write!(w, "emit ")?;
153                arg.pretty_print(db, store, w)
154            }
155
156            InstKind::Return { arg } => {
157                if let Some(arg) = arg {
158                    write!(w, "return ")?;
159                    arg.pretty_print(db, store, w)
160                } else {
161                    write!(w, "return")
162                }
163            }
164
165            InstKind::Keccak256 { arg } => {
166                write!(w, "keccak256 ")?;
167                arg.pretty_print(db, store, w)
168            }
169
170            InstKind::AbiEncode { arg } => {
171                write!(w, "abi_encode ")?;
172                arg.pretty_print(db, store, w)
173            }
174
175            InstKind::Nop => {
176                write!(w, "nop")
177            }
178
179            InstKind::Create { value, contract } => {
180                write!(w, "create ")?;
181                let contract_name = contract.name(db.upcast());
182                write!(w, "{contract_name} ")?;
183                value.pretty_print(db, store, w)
184            }
185
186            InstKind::Create2 {
187                value,
188                salt,
189                contract,
190            } => {
191                write!(w, "create2 ")?;
192                let contract_name = contract.name(db.upcast());
193                write!(w, "{contract_name} ")?;
194                value.pretty_print(db, store, w)?;
195                write!(w, " ")?;
196                salt.pretty_print(db, store, w)
197            }
198
199            InstKind::YulIntrinsic { op, args } => {
200                write!(w, "{op}(")?;
201                args.as_slice().pretty_print(db, store, w)?;
202                write!(w, ")")
203            }
204        }
205    }
206}