1pub use citadel_backend as backend;
4pub use citadel_frontend as frontend;
5pub use citadel_middleend as middleend;
6
7use std::{fs, io, marker::PhantomData, path::PathBuf};
8
9use citadel_backend::api::{Backend, Target};
10
11#[macro_export]
12macro_rules! compile {
13 ($backend:expr, $clir_stream:expr) => {{
14 use citadel_api::backend::api::Backend;
15 use citadel_api::Output;
16
17 Output::new($backend, $backend.generate($clir_stream))
18 }};
19}
20
21#[macro_export]
22macro_rules! optimize {
23 ($stream:expr,$($opt:expr),*) => {{
24 let stream = $stream;
25 $(
26 let stream = $opt.optimize(stream);
27 )*
28 stream
29 }};
30}
31
32pub struct Output<B>
33where
34 B: Backend,
35{
36 pub backend: B,
37 pub stream: B::Output,
38}
39
40impl<B> Output<B>
41where
42 B: Backend,
43{
44 pub fn new(backend: B, stream: B::Output) -> Self {
45 Self {
46 backend,
47 stream,
48 }
49 }
50
51 pub fn to_file(self, path: PathBuf) -> io::Result<()> {
52 if let Some(res) = self.backend.to_file(&self.stream) {
53 return res;
54 }
55
56 let contents = if let Some(formatted) = self.backend.format(&self.stream) {
57 formatted
58 } else {
59 self.stream
60 .into_iter()
61 .map(|elem| elem.to_string())
62 .collect::<Vec<String>>()
63 .join("\n")
64 };
65
66 fs::write(path, contents)
67 }
68}