citadel_frontend/ir/
irgen.rs

1//! The Generator for converting source code to an IR AST
2//! This will generate the ir and push it to a stream that
3//! the represents the AST. You can implement this yourself
4//! if you don't want to use the provided generator or need
5//! specific capabilities
6
7use std::{collections::HashMap, fmt::Display};
8
9use crate::{ir::IRStmt, util::CompositeDataType};
10
11use super::{IRTypedIdent, Ident};
12
13pub type TypeTable<'t> = HashMap<Ident<'t>, (CompositeDataType, Vec<IRTypedIdent<'t>>)>;
14
15#[derive(Default)]
16pub struct IRGenerator<'s> {
17    ir: HIRStream<'s>,
18}
19
20/// High-level IR stream that contains the ir stream
21/// as well as a typetable. This is output by the [IRGenerator]
22/// and used as an input for various optimizations.
23#[derive(Debug, Default)]
24pub struct HIRStream<'hir> {
25    pub stream: Vec<IRStmt<'hir>>,
26    pub types: TypeTable<'hir>,
27}
28
29impl<'g> IRGenerator<'g> {
30    pub fn gen_ir(&mut self, node: IRStmt<'g>) {
31        match &node {
32            IRStmt::Struct(node) => {
33                self.ir
34                    .types
35                    .insert(node.name, (CompositeDataType::Struct, node.fields.clone()));
36            }
37            IRStmt::Union(node) => {
38                self.ir
39                    .types
40                    .insert(node.name, (CompositeDataType::Union, node.variants.clone()));
41            }
42            _ => (),
43        }
44        self.ir.stream.push(node);
45    }
46
47    pub fn mut_stream_ref(&mut self) -> &mut HIRStream<'g> {
48        &mut self.ir
49    }
50
51    pub fn stream_ref(&self) -> &HIRStream<'g> {
52        &self.ir
53    }
54
55    pub fn stream(self) -> HIRStream<'g> {
56        self.ir
57    }
58}
59
60impl<'hir> HIRStream<'hir> {
61    pub fn stream_ref(&self) -> &Vec<IRStmt<'hir>> {
62        &self.stream
63    }
64
65    pub fn mut_stream_ref(&mut self) -> &mut Vec<IRStmt<'hir>> {
66        &mut self.stream
67    }
68}
69
70impl Display for HIRStream<'_> {
71    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72        f.write_str(
73            &self
74                .stream
75                .iter()
76                .map(|stmt| stmt.to_string())
77                .collect::<Vec<String>>()
78                .join("\n"),
79        )
80    }
81}