use super::ast::{Definition, Expression, MainComponent};
use super::file_definition::{FileID, FileLibrary};
use super::function_data::{FunctionData, FunctionInfo};
use super::program_merger::Merger;
use super::template_data::{TemplateData, TemplateInfo};
use crate::abstract_syntax_tree::ast::FillMeta;
use crate::report::Report;
use std::collections::{HashMap, HashSet};
type Contents = HashMap<FileID, Vec<Definition>>;
#[derive(Clone)]
pub struct ProgramArchive {
pub id_max: usize,
pub file_id_main: FileID,
pub file_library: FileLibrary,
pub functions: FunctionInfo,
pub templates: TemplateInfo,
pub function_keys: HashSet<String>,
pub template_keys: HashSet<String>,
pub public_inputs: Vec<String>,
pub initial_template_call: Expression,
pub custom_gates: bool,
}
impl ProgramArchive {
pub fn new(
file_library: FileLibrary,
file_id_main: FileID,
main_component: &MainComponent,
program_contents: &Contents,
custom_gates: bool,
) -> Result<ProgramArchive, (FileLibrary, Vec<Report>)> {
let mut merger = Merger::new();
let mut reports = vec![];
for (file_id, definitions) in program_contents {
if let Err(mut errs) = merger.add_definitions(*file_id, definitions) {
reports.append(&mut errs);
}
}
let (mut fresh_id, functions, templates) = merger.decompose();
let mut function_keys = HashSet::new();
let mut template_keys = HashSet::new();
for key in functions.keys() {
function_keys.insert(key.clone());
}
for key in templates.keys() {
template_keys.insert(key.clone());
}
let (public_inputs, mut initial_template_call) = main_component.clone();
initial_template_call.fill(file_id_main, &mut fresh_id);
if reports.is_empty() {
Ok(ProgramArchive {
id_max: fresh_id,
file_id_main,
file_library,
functions,
templates,
initial_template_call,
function_keys,
template_keys,
public_inputs,
custom_gates,
})
} else {
Err((file_library, reports))
}
}
pub fn get_file_id_main(&self) -> &FileID {
&self.file_id_main
}
pub fn contains_template(&self, template_name: &str) -> bool {
self.templates.contains_key(template_name)
}
pub fn get_template_data(&self, template_name: &str) -> &TemplateData {
assert!(self.contains_template(template_name));
self.templates.get(template_name).unwrap()
}
pub fn get_mut_template_data(&mut self, template_name: &str) -> &mut TemplateData {
assert!(self.contains_template(template_name));
self.templates.get_mut(template_name).unwrap()
}
pub fn get_template_names(&self) -> &HashSet<String> {
&self.template_keys
}
pub fn get_templates(&self) -> &TemplateInfo {
&self.templates
}
pub fn get_mut_templates(&mut self) -> &mut TemplateInfo {
&mut self.templates
}
pub fn remove_template(&mut self, id: &str) {
self.template_keys.remove(id);
self.templates.remove(id);
}
pub fn contains_function(&self, function_name: &str) -> bool {
self.get_functions().contains_key(function_name)
}
pub fn get_function_data(&self, function_name: &str) -> &FunctionData {
assert!(self.contains_function(function_name));
self.get_functions().get(function_name).unwrap()
}
pub fn get_mut_function_data(&mut self, function_name: &str) -> &mut FunctionData {
assert!(self.contains_function(function_name));
self.functions.get_mut(function_name).unwrap()
}
pub fn get_function_names(&self) -> &HashSet<String> {
&self.function_keys
}
pub fn get_functions(&self) -> &FunctionInfo {
&self.functions
}
pub fn get_mut_functions(&mut self) -> &mut FunctionInfo {
&mut self.functions
}
pub fn remove_function(&mut self, id: &str) {
self.function_keys.remove(id);
self.functions.remove(id);
}
pub fn get_public_inputs_main_component(&self) -> &Vec<String> {
&self.public_inputs
}
pub fn main_expression(&self) -> &Expression {
&self.initial_template_call
}
pub fn get_file_library(&self) -> &FileLibrary {
&self.file_library
}
}