1use crate::global::Global;
2use crate::{Block, Error, Var};
3use std::fmt;
4
5pub struct Program {
7 global: Global,
8 blocks: Vec<Block>,
9}
10
11impl Program {
12 pub fn new() -> Self {
14 Self {
15 global: Global::default(),
16 blocks: Vec::new(),
17 }
18 }
19
20 pub fn seal(&self) -> Result<(), Error> {
22 for block in &self.blocks {
23 block.seal()?;
24 }
25
26 Ok(())
27 }
28
29 pub fn var(&self) -> Var {
31 self.global.var()
32 }
33
34 pub fn block(&mut self) -> Block {
36 let block = self.global.block(None);
37 self.blocks.push(block.clone());
38 block
39 }
40
41 pub fn named(&mut self, name: &str) -> Block {
43 let block = self.global.block(Some(name.into()));
44 self.blocks.push(block.clone());
45 block
46 }
47
48 pub fn dump(&self) -> ProgramDump<'_> {
52 ProgramDump(self)
53 }
54}
55
56pub struct ProgramDump<'a>(&'a Program);
57
58impl fmt::Display for ProgramDump<'_> {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 let constants = self.0.global.constants();
61
62 if !constants.is_empty() {
63 writeln!(f, "constants:")?;
64
65 for (id, c) in constants.iter().enumerate() {
66 writeln!(f, " C{} <- {:?}", id, c)?;
67 }
68
69 if !self.0.blocks.is_empty() {
70 writeln!(f)?;
71 }
72 }
73
74 let mut it = self.0.blocks.iter();
75 let last = it.next_back();
76
77 for b in it {
78 writeln!(f, "{}", b.dump())?;
79 }
80
81 if let Some(b) = last {
82 write!(f, "{}", b.dump())?;
83 }
84
85 Ok(())
86 }
87}