1use crate::formatter::format;
2use crate::instruction::Instruction;
3
4#[macro_export]
5macro_rules! instruction_row {
6 ($instruction:expr) => {{
7 michelson_ast::wrapped_instruction::WrappedInstruction {
8 instruction: $instruction,
9 comment: None,
10 }
11 }};
12
13 ($instruction:expr, $comment:expr) => {{
14 michelson_ast::wrapped_instruction::WrappedInstruction {
15 instruction: $instruction,
16 comment: Some($comment),
17 }
18 }};
19}
20
21#[derive(Clone, Debug, Eq, PartialEq, Hash)]
22pub struct WrappedInstruction {
23 pub instruction: Instruction,
24 pub comment: Option<String>,
25}
26
27impl From<Instruction> for WrappedInstruction {
28 fn from(instruction: Instruction) -> Self {
29 Self {
30 comment: None,
31 instruction,
32 }
33 }
34}
35
36impl WrappedInstruction {
37 pub fn to_formatted_string(&self, accumulation: usize) -> String {
38 let indent = " ".repeat(accumulation);
39 let instruction = &self.instruction;
40 let formatted_string = match instruction {
41 Instruction::Comment(comment) => {
42 format!("{indent}{label} {comment}", label = instruction.get_label(),)
43 }
44 Instruction::If { instr1, instr2 } => {
48 format!(
49 r#"{indent}{label} {{
50{formatted_instr1}
51{indent}{space_label} }}
52{indent}{space_label} {{
53{formatted_instr2}
54{indent}{space_label} }}"#,
55 label = instruction.get_label(),
56 space_label = " ".repeat(instruction.get_label_len()),
57 formatted_instr1 =
58 format(instr1, accumulation + instruction.get_label_len() + 3),
59 formatted_instr2 =
60 format(instr2, accumulation + instruction.get_label_len() + 3)
61 )
62 }
63 Instruction::IfCons { instr1, instr2 } => {
64 format!(
65 r#"{indent}{label} {{
66{formatted_instr1}
67{indent}{space_label} }}
68{indent}{space_label} {{
69{formatted_instr2}
70{indent}{space_label} }}"#,
71 label = instruction.get_label(),
72 space_label = " ".repeat(instruction.get_label_len()),
73 formatted_instr1 =
74 format(instr1, accumulation + instruction.get_label_len() + 3),
75 formatted_instr2 =
76 format(instr2, accumulation + instruction.get_label_len() + 3)
77 )
78 }
79 Instruction::IfLeft { instr1, instr2 } => {
80 format!(
81 r#"{indent}{label} {{
82{formatted_instr1}
83{indent}{space_label} }}
84{indent}{space_label} {{
85{formatted_instr2}
86{indent}{space_label} }}"#,
87 label = instruction.get_label(),
88 space_label = " ".repeat(instruction.get_label_len()),
89 formatted_instr1 =
90 format(instr1, accumulation + instruction.get_label_len() + 3),
91 formatted_instr2 =
92 format(instr2, accumulation + instruction.get_label_len() + 3)
93 )
94 }
95 Instruction::IfNone { instr1, instr2 } => {
96 format!(
97 r#"{indent}{label} {{
98{formatted_instr1}
99{indent}{space_label} }}
100{indent}{space_label} {{
101{formatted_instr2}
102{indent}{space_label} }}"#,
103 label = instruction.get_label(),
104 space_label = " ".repeat(instruction.get_label_len()),
105 formatted_instr1 =
106 format(instr1, accumulation + instruction.get_label_len() + 3),
107 formatted_instr2 =
108 format(instr2, accumulation + instruction.get_label_len() + 3)
109 )
110 }
111 Instruction::Iter { .. } => {
112 todo!()
113 }
114 Instruction::Lambda { .. } => {
115 todo!()
116 }
117 Instruction::Loop { instr } => {
118 format!(
119 r#"{indent}{label} {{
120{formatted_instr}
121{indent}{space_label} }}"#,
122 label = instruction.get_label(),
123 space_label = " ".repeat(instruction.get_label_len()),
124 formatted_instr = format(instr, accumulation + instruction.get_label_len() + 3)
125 )
126 }
127 Instruction::LoopLeft { instr } => {
128 format!(
129 r#"{indent}{label} {{
130{formatted_instr}
131{indent}{space_label} }}"#,
132 label = instruction.get_label(),
133 space_label = " ".repeat(instruction.get_label_len()),
134 formatted_instr = format(instr, accumulation + instruction.get_label_len() + 3)
135 )
136 }
137 Instruction::EmptyBigMap { kty, vty } => format!(
141 "{indent}{} {} {}",
142 instruction.get_label(),
143 kty.to_string(),
144 vty.to_string()
145 ),
146 Instruction::EmptyMap { kty, vty } => {
147 format!(
148 "{indent}{} {} {}",
149 instruction.get_label(),
150 kty.to_string(),
151 vty.to_string()
152 )
153 }
154 Instruction::None { ty } => {
155 format!("{indent}{} {}", instruction.get_label(), ty.to_string())
156 }
157 Instruction::GetN(n) => format!("{indent}{} {}", instruction.get_label(), n),
158 Instruction::Left { .. } => todo!(),
159 Instruction::Map { .. } => todo!(),
160 Instruction::Nil { ty } => {
161 format!("{indent}{} {}", instruction.get_label(), ty.to_string())
162 }
163 Instruction::Right { .. } => todo!(),
164 Instruction::Unpack { .. } => todo!(),
165 Instruction::UnpairN { .. } => todo!(),
166 Instruction::UpdateN { .. } => todo!(),
167 Instruction::CreateContract { .. } => todo!(),
171 Instruction::Contract { ty } => {
172 format!("{indent}{} {}", instruction.get_label(), ty.to_string())
173 }
174 Instruction::Push { ty, val } => {
190 format!(
191 "{indent}{} {} {}",
192 instruction.get_label(),
193 ty.to_string(),
194 val.to_string()
195 )
196 }
197 Instruction::DupN(n) => format!("{indent}{} {n}", instruction.get_label()),
198 Instruction::DigN(n) => format!("{indent}{} {n}", instruction.get_label()),
199 Instruction::DugN(n) => format!("{indent}{} {n}", instruction.get_label()),
200 Instruction::PairN(n) => format!("{indent}{} {n}", instruction.get_label()),
201 _ => format!("{indent}{}", instruction.get_label()),
202 };
203 match &self.comment {
204 Some(s) => format!("{formatted_string}; # {s}"),
205 None => match instruction {
206 Instruction::Comment(_) => format!("{formatted_string}"),
207 _ => format!("{formatted_string};"),
208 },
209 }
210 }
211 pub fn count(&self) -> usize {
212 self.instruction.count()
213 }
214}