calyx_opt/passes_experimental/
metadata_table_gen.rs

1use crate::traversal::{Action, ConstructVisitor, Named, VisResult, Visitor};
2
3//use calyx_frontend::SetAttr::Pos;
4use calyx_ir::GetAttributes;
5use calyx_ir::source_info::{FileId, LineNum, SourceInfoTable};
6use calyx_utils::WithPos;
7use std::collections::HashMap;
8use std::path::PathBuf;
9
10/// Metadata creates and stores the source info table for the currently running program
11pub struct Metadata {
12    src_table: SourceInfoTable,
13    file_ids: HashMap<String, FileId>,
14}
15
16impl Metadata {
17    /// Create an empty metadata table
18    #[allow(clippy::new_without_default)]
19    pub fn new() -> Self {
20        Self {
21            src_table: SourceInfoTable::new_empty(),
22            file_ids: HashMap::new(),
23        }
24    }
25
26    pub fn add_control_node<A: GetAttributes>(&mut self, node: &mut A) {
27        let attr = node.get_mut_attributes();
28        let node_pos = attr.copy_span();
29        let (f, (line, endline)) = node_pos.get_line_num();
30        let fnum = self.file_ids.get(f).unwrap();
31        let pos = self.src_table.push_position(
32            *fnum,
33            LineNum::new(line as u32),
34            Some(LineNum::new(endline as u32)),
35        );
36        attr.insert_set(calyx_frontend::SetAttr::Pos, pos.value());
37    }
38}
39
40impl Named for Metadata {
41    fn name() -> &'static str {
42        "metadata-table-generation"
43    }
44    fn description() -> &'static str {
45        "generates metadata table for a file not containing one"
46    }
47}
48
49impl ConstructVisitor for Metadata {
50    fn from(_ctx: &calyx_ir::Context) -> calyx_utils::CalyxResult<Self>
51    where
52        Self: Sized,
53    {
54        Ok(Self::new())
55    }
56
57    fn clear_data(&mut self) {
58        // preserve across components
59        // hacky oops
60    }
61}
62impl Visitor for Metadata {
63    fn start_context(&mut self, ctx: &mut calyx_ir::Context) -> VisResult {
64        if let Some(x) = std::mem::take(&mut ctx.source_info_table) {
65            self.src_table = x;
66        }
67        Ok(Action::Continue)
68    }
69
70    // this visits each component
71    fn start(
72        &mut self,
73        comp: &mut calyx_ir::Component,
74        _sigs: &calyx_ir::LibrarySignatures,
75        _comps: &[calyx_ir::Component],
76    ) -> VisResult {
77        // implement visiting each component and adding the positions
78        // how this works:
79        // components have attributes !!
80        // check if file exists for component definition
81        let binding = comp.attributes.copy_span();
82        let (file, (line, endline)) = binding.get_line_num();
83
84        // add file to source table (if not already in)
85        if !self.file_ids.contains_key(file) {
86            let id = self.src_table.push_file(PathBuf::from(file));
87            self.file_ids.insert(String::from(file), id);
88        }
89
90        // add source position of the component itself
91        let component_file_id = self.file_ids.get(file).unwrap();
92        let component_pos = self.src_table.push_position(
93            *component_file_id,
94            LineNum::new(line as u32),
95            Some(LineNum::new(endline as u32)),
96        );
97        comp.attributes
98            .insert_set(calyx_frontend::SetAttr::Pos, component_pos.value());
99
100        // visit all groups in component
101        for rrcgrp in comp.groups.iter() {
102            let mut grp = rrcgrp.borrow_mut();
103            let attr = &mut grp.attributes;
104            let pos_data = attr.copy_span();
105            let (f, (line_start, line_end)) = pos_data.get_line_num();
106            let fid = self.file_ids.get(f).unwrap(); // this def should be in file_ids
107            let pos = self.src_table.push_position(
108                *fid,
109                LineNum::new(line_start as u32),
110                Some(LineNum::new(line_end as u32)),
111            );
112            // add tag to group attributes
113            attr.insert_set(calyx_frontend::SetAttr::Pos, pos.value());
114        }
115        Ok(Action::Continue)
116    }
117
118    fn finish_context(&mut self, ctx: &mut calyx_ir::Context) -> VisResult {
119        ctx.source_info_table = Some(std::mem::take(&mut self.src_table));
120        Ok(Action::Continue)
121    }
122
123    fn enable(
124        &mut self,
125        s: &mut calyx_ir::Enable,
126        _comp: &mut calyx_ir::Component,
127        _sigs: &calyx_ir::LibrarySignatures,
128        _comps: &[calyx_ir::Component],
129    ) -> VisResult {
130        self.add_control_node(s);
131        Ok(Action::Continue)
132    }
133
134    // control nodes
135    fn start_seq(
136        &mut self,
137        s: &mut calyx_ir::Seq,
138        _comp: &mut calyx_ir::Component,
139        _sigs: &calyx_ir::LibrarySignatures,
140        _comps: &[calyx_ir::Component],
141    ) -> VisResult {
142        self.add_control_node(s);
143        Ok(Action::Continue)
144    }
145
146    fn start_par(
147        &mut self,
148        s: &mut calyx_ir::Par,
149        _comp: &mut calyx_ir::Component,
150        _sigs: &calyx_ir::LibrarySignatures,
151        _comps: &[calyx_ir::Component],
152    ) -> VisResult {
153        self.add_control_node(s);
154        Ok(Action::Continue)
155    }
156
157    fn start_if(
158        &mut self,
159        s: &mut calyx_ir::If,
160        _comp: &mut calyx_ir::Component,
161        _sigs: &calyx_ir::LibrarySignatures,
162        _comps: &[calyx_ir::Component],
163    ) -> VisResult {
164        self.add_control_node(s);
165        Ok(Action::Continue)
166    }
167
168    fn start_while(
169        &mut self,
170        s: &mut calyx_ir::While,
171        _comp: &mut calyx_ir::Component,
172        _sigs: &calyx_ir::LibrarySignatures,
173        _comps: &[calyx_ir::Component],
174    ) -> VisResult {
175        self.add_control_node(s);
176        Ok(Action::Continue)
177    }
178
179    fn start_repeat(
180        &mut self,
181        s: &mut calyx_ir::Repeat,
182        _comp: &mut calyx_ir::Component,
183        _sigs: &calyx_ir::LibrarySignatures,
184        _comps: &[calyx_ir::Component],
185    ) -> VisResult {
186        self.add_control_node(s);
187        Ok(Action::Continue)
188    }
189}