michelson_ast/
wrapped_instruction.rs

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            ////////////////////////////////////////////////
45            ////////////////Control Structures//////////////
46            ////////////////////////////////////////////////
47            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            ////////////////////////////////////////////////
138            //////////Operations on data structures/////////
139            ////////////////////////////////////////////////
140            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            ////////////////////////////////////////////////
168            /////////////Blockchain operations//////////////
169            ////////////////////////////////////////////////
170            Instruction::CreateContract { .. } => todo!(),
171            Instruction::Contract { ty } => {
172                format!("{indent}{} {}", instruction.get_label(), ty.to_string())
173            }
174            ////////////////////////////////////////////////
175            ////////////Operations on tickets///////////////
176            ////////////////////////////////////////////////
177            ////////////////////////////////////////////////
178            ////////////Cryptographic operations////////////
179            ////////////////////////////////////////////////
180            ////////////////////////////////////////////////
181            //////////////Boolean operations////////////////
182            ////////////////////////////////////////////////
183            ////////////////////////////////////////////////
184            ////////////Arithmetic operations///////////////
185            ////////////////////////////////////////////////
186            ////////////////////////////////////////////////
187            /////////////Stack manipulation/////////////////
188            ////////////////////////////////////////////////
189            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}