miden_assembly_syntax/ast/
block.rs1use alloc::vec::Vec;
2use core::fmt;
3
4use miden_debug_types::{SourceSpan, Span, Spanned};
5
6use super::Op;
7
8#[derive(Clone, Default)]
15pub struct Block {
16 span: SourceSpan,
17 body: Vec<Op>,
18}
19
20impl Block {
21 pub fn new(span: SourceSpan, body: Vec<Op>) -> Self {
23 Self { span, body }
24 }
25
26 pub fn push(&mut self, op: Op) {
28 self.body.push(op);
29 }
30
31 pub fn len(&self) -> usize {
36 self.body.len()
37 }
38
39 pub fn is_empty(&self) -> bool {
41 self.body.is_empty()
42 }
43
44 pub fn iter(&self) -> core::slice::Iter<'_, Op> {
46 self.body.iter()
47 }
48
49 pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, Op> {
51 self.body.iter_mut()
52 }
53}
54
55impl fmt::Debug for Block {
56 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57 f.debug_list().entries(&self.body).finish()
58 }
59}
60
61impl crate::prettier::PrettyPrint for Block {
62 fn render(&self) -> crate::prettier::Document {
63 use crate::{ast::Instruction, prettier::*};
64
65 let default_body = [Op::Inst(Span::new(self.span, Instruction::Nop))];
67 let body = if self.body.is_empty() {
68 default_body.as_slice().iter()
69 } else {
70 self.body.iter()
71 }
72 .map(PrettyPrint::render)
73 .reduce(|acc, doc| acc + nl() + doc)
74 .unwrap();
75
76 indent(4, nl() + body) + nl()
77 }
78}
79
80impl Spanned for Block {
81 fn span(&self) -> SourceSpan {
82 self.span
83 }
84}
85
86impl Eq for Block {}
87
88impl PartialEq for Block {
89 fn eq(&self, other: &Self) -> bool {
90 self.body == other.body
91 }
92}