1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use super::ast::Definition;
use super::report_code::ReportCode;
use super::report::Report;
use super::file_definition::FileID;
use super::function_data::{FunctionData, FunctionInfo};
use super::template_data::{TemplateData, TemplateInfo};
#[derive(Default)]
pub struct Merger {
fresh_id: usize,
function_info: FunctionInfo,
template_info: TemplateInfo,
}
impl Merger {
pub fn new() -> Merger {
Merger::default()
}
pub fn add_definitions(
&mut self,
file_id: FileID,
definitions: &Vec<Definition>,
) -> Result<(), Vec<Report>> {
let mut reports = vec![];
for definition in definitions {
let (name, meta) = match definition {
Definition::Template {
name,
args,
arg_location,
body,
meta,
parallel,
is_custom_gate,
} => {
if self.contains_function(name) || self.contains_template(name) {
(Option::Some(name), meta)
} else {
let new_data = TemplateData::new(
name.clone(),
file_id,
body.clone(),
args.len(),
args.clone(),
arg_location.clone(),
&mut self.fresh_id,
*parallel,
*is_custom_gate,
);
self.get_mut_template_info().insert(name.clone(), new_data);
(Option::None, meta)
}
}
Definition::Function { name, body, args, arg_location, meta } => {
if self.contains_function(name) || self.contains_template(name) {
(Option::Some(name), meta)
} else {
let new_data = FunctionData::new(
name.clone(),
file_id,
body.clone(),
args.len(),
args.clone(),
arg_location.clone(),
&mut self.fresh_id,
);
self.get_mut_function_info().insert(name.clone(), new_data);
(Option::None, meta)
}
}
};
if let Option::Some(definition_name) = name {
let mut report = Report::error(
String::from("Duplicated function or template."),
ReportCode::SameSymbolDeclaredTwice,
);
report.add_primary(
meta.file_location(),
file_id,
format!("The name `{}` is already used.", definition_name),
);
reports.push(report);
}
}
if reports.is_empty() {
Ok(())
} else {
Err(reports)
}
}
pub fn contains_function(&self, function_name: &str) -> bool {
self.get_function_info().contains_key(function_name)
}
fn get_function_info(&self) -> &FunctionInfo {
&self.function_info
}
fn get_mut_function_info(&mut self) -> &mut FunctionInfo {
&mut self.function_info
}
pub fn contains_template(&self, template_name: &str) -> bool {
self.get_template_info().contains_key(template_name)
}
fn get_template_info(&self) -> &TemplateInfo {
&self.template_info
}
fn get_mut_template_info(&mut self) -> &mut TemplateInfo {
&mut self.template_info
}
pub fn decompose(self) -> (usize, FunctionInfo, TemplateInfo) {
(self.fresh_id, self.function_info, self.template_info)
}
}