From 1d1c094b1e77ea1c4d2ff659449ba7238bd8ed80 Mon Sep 17 00:00:00 2001 From: David Wong Date: Tue, 1 Aug 2023 20:13:23 -0700 Subject: [PATCH] cargo fmt --- circom/src/compilation_user.rs | 62 +- circom/src/execution_user.rs | 11 +- circom/src/input_user.rs | 108 +- circom/src/main.rs | 11 +- circom/src/parser_user.rs | 4 +- circom_algebra/src/algebra.rs | 38 +- circom_algebra/src/modular_arithmetic.rs | 28 +- circom_algebra/src/simplification_utils.rs | 246 +-- .../src/c_elements/c_code_generator.rs | 103 +- code_producers/src/c_elements/mod.rs | 2 +- code_producers/src/components/mod.rs | 2 +- code_producers/src/wasm_elements/mod.rs | 12 +- .../src/wasm_elements/wasm_code_generator.rs | 69 +- compiler/src/circuit_design/build.rs | 83 +- compiler/src/circuit_design/circuit.rs | 172 +- compiler/src/circuit_design/function.rs | 6 +- compiler/src/circuit_design/template.rs | 194 ++- compiler/src/compiler_interface.rs | 18 +- compiler/src/hir/component_preprocess.rs | 21 +- compiler/src/hir/merger.rs | 14 +- compiler/src/hir/sugar_cleaner.rs | 68 +- compiler/src/hir/type_inference.rs | 4 +- compiler/src/hir/very_concrete_program.rs | 2 +- .../address_type.rs | 9 +- .../assert_bucket.rs | 6 +- .../branch_bucket.rs | 8 +- .../call_bucket.rs | 568 ++++--- .../compute_bucket.rs | 112 +- .../create_component_bucket.rs | 137 +- .../ir_interface.rs | 7 +- .../load_bucket.rs | 218 +-- .../intermediate_representation/log_bucket.rs | 67 +- .../loop_bucket.rs | 7 +- .../return_bucket.rs | 6 +- .../store_bucket.rs | 549 ++++--- .../intermediate_representation/translate.rs | 304 ++-- .../value_bucket.rs | 4 +- .../src/ir_processing/build_inputs_info.rs | 359 +++-- compiler/src/ir_processing/mod.rs | 5 +- compiler/src/ir_processing/reduce_stack.rs | 21 +- compiler/src/ir_processing/set_arena_size.rs | 3 +- .../src/compute_constants.rs | 64 +- .../component_representation.rs | 216 +-- .../src/environment_utils/environment.rs | 60 +- .../src/environment_utils/slice_types.rs | 6 +- constraint_generation/src/execute.rs | 1434 +++++++++-------- .../src/execution_data/executed_program.rs | 21 +- .../src/execution_data/executed_template.rs | 74 +- .../src/execution_data/filters.rs | 19 +- .../src/execution_data/type_definitions.rs | 1 - constraint_generation/src/lib.rs | 18 +- .../src/constraint_simplification.rs | 53 +- .../src/non_linear_simplification.rs | 3 +- constraint_list/src/r1cs_porting.rs | 19 +- constraint_writers/src/r1cs_writer.rs | 84 +- constraint_writers/src/sym_writer.rs | 6 +- dag/src/constraint_correctness_analysis.rs | 74 +- dag/src/lib.rs | 42 +- dag/src/map_to_constraint_list.rs | 2 +- dag/src/r1cs_porting.rs | 17 +- parser/src/include_logic.rs | 4 +- parser/src/lib.rs | 42 +- parser/src/parser_logic.rs | 33 +- parser/src/syntax_sugar_remover.rs | 1073 +++++++----- .../src/abstract_syntax_tree/ast.rs | 255 +-- .../src/abstract_syntax_tree/ast_impl.rs | 4 +- .../src/abstract_syntax_tree/ast_shortcuts.rs | 45 +- .../expression_builders.rs | 27 +- .../abstract_syntax_tree/expression_impl.rs | 159 +- .../statement_builders.rs | 24 +- .../abstract_syntax_tree/statement_impl.rs | 34 +- .../src/program_library/error_code.rs | 8 +- .../src/program_library/program_archive.rs | 1 - .../src/program_library/program_merger.rs | 23 +- .../src/program_library/template_data.rs | 68 +- program_structure/src/utils/constants.rs | 42 +- program_structure/src/utils/environment.rs | 2 +- program_structure/src/utils/memory_slice.rs | 66 +- .../src/analyzers/custom_gate_analysis.rs | 30 +- .../functions_free_of_template_elements.rs | 12 +- .../analyzers/signal_declaration_analysis.rs | 2 +- .../src/analyzers/symbol_analysis.rs | 28 +- type_analysis/src/analyzers/type_check.rs | 217 +-- .../src/analyzers/type_given_function.rs | 10 +- .../src/analyzers/unknown_known_analysis.rs | 137 +- type_analysis/src/check_types.rs | 9 +- .../decorators/component_type_inference.rs | 14 +- .../src/decorators/constants_handler.rs | 23 +- .../src/decorators/type_reduction.rs | 15 +- 89 files changed, 4653 insertions(+), 3635 deletions(-) diff --git a/circom/src/compilation_user.rs b/circom/src/compilation_user.rs index c2b03bfa7..5ca5ee6e7 100644 --- a/circom/src/compilation_user.rs +++ b/circom/src/compilation_user.rs @@ -6,7 +6,6 @@ use program_structure::error_code::ReportCode; use program_structure::file_definition::FileLibrary; use crate::VERSION; - pub struct CompilerConfig { pub js_folder: String, pub wasm_name: String, @@ -25,17 +24,25 @@ pub struct CompilerConfig { } pub fn compile(config: CompilerConfig) -> Result<(), ()> { - - - if config.c_flag || config.wat_flag || config.wasm_flag{ + if config.c_flag || config.wat_flag || config.wasm_flag { let circuit = compiler_interface::run_compiler( config.vcp, - Config { debug_output: config.debug_output, produce_input_log: config.produce_input_log, wat_flag: config.wat_flag }, - VERSION + Config { + debug_output: config.debug_output, + produce_input_log: config.produce_input_log, + wat_flag: config.wat_flag, + }, + VERSION, )?; - + if config.c_flag { - compiler_interface::write_c(&circuit, &config.c_folder, &config.c_run_name, &config.c_file, &config.dat_file)?; + compiler_interface::write_c( + &circuit, + &config.c_folder, + &config.c_run_name, + &config.c_file, + &config.dat_file, + )?; println!( "{} {} and {}", Colour::Green.paint("Written successfully:"), @@ -45,7 +52,7 @@ pub fn compile(config: CompilerConfig) -> Result<(), ()> { println!( "{} {}/{}, {}, {}, {}, {}, {}, {} and {}", Colour::Green.paint("Written successfully:"), - &config.c_folder, + &config.c_folder, "main.cpp".to_string(), "circom.hpp".to_string(), "calcwit.hpp".to_string(), @@ -56,10 +63,15 @@ pub fn compile(config: CompilerConfig) -> Result<(), ()> { "Makefile".to_string() ); } - + match (config.wat_flag, config.wasm_flag) { (true, true) => { - compiler_interface::write_wasm(&circuit, &config.js_folder, &config.wasm_name, &config.wat_file)?; + compiler_interface::write_wasm( + &circuit, + &config.js_folder, + &config.wasm_name, + &config.wat_file, + )?; println!("{} {}", Colour::Green.paint("Written successfully:"), config.wat_file); let result = wat_to_wasm(&config.wat_file, &config.wasm_file); match result { @@ -68,12 +80,21 @@ pub fn compile(config: CompilerConfig) -> Result<(), ()> { return Err(()); } Result::Ok(()) => { - println!("{} {}", Colour::Green.paint("Written successfully:"), config.wasm_file); + println!( + "{} {}", + Colour::Green.paint("Written successfully:"), + config.wasm_file + ); } } } (false, true) => { - compiler_interface::write_wasm(&circuit, &config.js_folder, &config.wasm_name, &config.wat_file)?; + compiler_interface::write_wasm( + &circuit, + &config.js_folder, + &config.wasm_name, + &config.wat_file, + )?; let result = wat_to_wasm(&config.wat_file, &config.wasm_file); std::fs::remove_file(&config.wat_file).unwrap(); match result { @@ -82,23 +103,30 @@ pub fn compile(config: CompilerConfig) -> Result<(), ()> { return Err(()); } Result::Ok(()) => { - println!("{} {}", Colour::Green.paint("Written successfully:"), config.wasm_file); + println!( + "{} {}", + Colour::Green.paint("Written successfully:"), + config.wasm_file + ); } } } (true, false) => { - compiler_interface::write_wasm(&circuit, &config.js_folder, &config.wasm_name, &config.wat_file)?; + compiler_interface::write_wasm( + &circuit, + &config.js_folder, + &config.wasm_name, + &config.wat_file, + )?; println!("{} {}", Colour::Green.paint("Written successfully:"), config.wat_file); } (false, false) => {} } } - Ok(()) } - fn wat_to_wasm(wat_file: &str, wasm_file: &str) -> Result<(), Report> { use std::fs::read_to_string; use std::fs::File; diff --git a/circom/src/execution_user.rs b/circom/src/execution_user.rs index 751a37436..a7282ac89 100644 --- a/circom/src/execution_user.rs +++ b/circom/src/execution_user.rs @@ -4,7 +4,6 @@ use constraint_writers::debug_writer::DebugWriter; use constraint_writers::ConstraintExporter; use program_structure::program_archive::ProgramArchive; - pub struct ExecutionConfig { pub r1cs: String, pub sym: String, @@ -13,7 +12,7 @@ pub struct ExecutionConfig { pub flag_s: bool, pub flag_f: bool, pub flag_p: bool, - pub flag_old_heuristics:bool, + pub flag_old_heuristics: bool, pub flag_verbose: bool, pub inspect_constraints_flag: bool, pub sym_flag: bool, @@ -38,7 +37,7 @@ pub fn execute_project( flag_verbose: config.flag_verbose, inspect_constraints: config.inspect_constraints_flag, flag_old_heuristics: config.flag_old_heuristics, - prime : config.prime, + prime: config.prime, }; let custom_gates = program_archive.custom_gates; let (exporter, vcp) = build_circuit(program_archive, build_config)?; @@ -54,7 +53,11 @@ pub fn execute_project( Result::Ok(vcp) } -fn generate_output_r1cs(file: &str, exporter: &dyn ConstraintExporter, custom_gates: bool) -> Result<(), ()> { +fn generate_output_r1cs( + file: &str, + exporter: &dyn ConstraintExporter, + custom_gates: bool, +) -> Result<(), ()> { if let Result::Ok(()) = exporter.r1cs(file, custom_gates) { println!("{} {}", Colour::Green.paint("Written successfully:"), file); Result::Ok(()) diff --git a/circom/src/input_user.rs b/circom/src/input_user.rs index 7f63975a0..1335776a2 100644 --- a/circom/src/input_user.rs +++ b/circom/src/input_user.rs @@ -31,10 +31,9 @@ pub struct Input { pub no_rounds: usize, pub flag_verbose: bool, pub prime: String, - pub link_libraries : Vec + pub link_libraries: Vec, } - const R1CS: &'static str = "r1cs"; const WAT: &'static str = "wat"; const WASM: &'static str = "wasm"; @@ -44,7 +43,6 @@ const DAT: &'static str = "dat"; const SYM: &'static str = "sym"; const JSON: &'static str = "json"; - impl Input { pub fn new() -> Result { use ansi_term::Colour; @@ -56,7 +54,7 @@ impl Input { let c_flag = input_processing::get_c(&matches); - if c_flag && (file_name == "main" || file_name == "fr" || file_name == "calcwit"){ + if c_flag && (file_name == "main" || file_name == "fr" || file_name == "calcwit") { println!("{}", Colour::Yellow.paint(format!("The name {} is reserved in Circom when using de --c flag. The files generated for your circuit will use the name {}_c instead of {}.", file_name, file_name, file_name))); file_name = format!("{}_c", file_name) }; @@ -70,10 +68,10 @@ impl Input { out_r1cs: Input::build_output(&output_path, &file_name, R1CS), out_wat_code: Input::build_output(&output_js_path, &file_name, WAT), out_wasm_code: Input::build_output(&output_js_path, &file_name, WASM), - out_js_folder: output_js_path.clone(), - out_wasm_name: file_name.clone(), - out_c_folder: output_c_path.clone(), - out_c_run_name: file_name.clone(), + out_js_folder: output_js_path.clone(), + out_wasm_name: file_name.clone(), + out_c_folder: output_c_path.clone(), + out_c_run_name: file_name.clone(), out_c_code: Input::build_output(&output_c_path, &file_name, CPP), out_c_dat: Input::build_output(&output_c_path, &file_name, DAT), out_sym: Input::build_output(&output_path, &file_name, SYM), @@ -82,7 +80,7 @@ impl Input { &format!("{}_constraints", file_name), JSON, ), - wat_flag:input_processing::get_wat(&matches), + wat_flag: input_processing::get_wat(&matches), wasm_flag: input_processing::get_wasm(&matches), c_flag: c_flag, r1cs_flag: input_processing::get_r1cs(&matches), @@ -97,22 +95,22 @@ impl Input { parallel_simplification_flag: input_processing::get_parallel_simplification(&matches), inspect_constraints_flag: input_processing::get_inspect_constraints(&matches), flag_old_heuristics: input_processing::get_flag_old_heuristics(&matches), - flag_verbose: input_processing::get_flag_verbose(&matches), + flag_verbose: input_processing::get_flag_verbose(&matches), prime: input_processing::get_prime(&matches)?, - link_libraries + link_libraries, }) } fn build_folder(output_path: &PathBuf, filename: &str, ext: &str) -> PathBuf { let mut file = output_path.clone(); - let folder_name = format!("{}_{}",filename,ext); - file.push(folder_name); - file + let folder_name = format!("{}_{}", filename, ext); + file.push(folder_name); + file } - + fn build_output(output_path: &PathBuf, filename: &str, ext: &str) -> PathBuf { let mut file = output_path.clone(); - file.push(format!("{}.{}",filename,ext)); + file.push(format!("{}.{}", filename, ext)); file } @@ -206,7 +204,7 @@ impl Input { pub fn no_rounds(&self) -> usize { self.no_rounds } - pub fn prime(&self) -> String{ + pub fn prime(&self) -> String { self.prime.clone() } } @@ -221,8 +219,15 @@ mod input_processing { if route.is_file() { Result::Ok(route) } else { - let route = if route.to_str().is_some() { ": ".to_owned() + route.to_str().unwrap()} else { "".to_owned() }; - Result::Err(eprintln!("{}", Colour::Red.paint("Input file does not exist".to_owned() + &route))) + let route = if route.to_str().is_some() { + ": ".to_owned() + route.to_str().unwrap() + } else { + "".to_owned() + }; + Result::Err(eprintln!( + "{}", + Colour::Red.paint("Input file does not exist".to_owned() + &route) + )) } } @@ -236,9 +241,12 @@ mod input_processing { } #[derive(Copy, Clone, Eq, PartialEq)] - pub enum SimplificationStyle { O0, O1, O2(usize) } + pub enum SimplificationStyle { + O0, + O1, + O2(usize), + } pub fn get_simplification_style(matches: &ArgMatches) -> Result { - let o_0 = matches.is_present("no_simplification"); let o_1 = matches.is_present("reduced_simplification"); let o_2 = matches.is_present("full_simplification"); @@ -246,15 +254,20 @@ mod input_processing { match (o_0, o_1, o_2round, o_2) { (true, _, _, _) => Ok(SimplificationStyle::O0), (_, true, _, _) => Ok(SimplificationStyle::O1), - (_, _, true, _) => { + (_, _, true, _) => { let o_2_argument = matches.value_of("simplification_rounds").unwrap(); let rounds_r = usize::from_str_radix(o_2_argument, 10); - if let Result::Ok(no_rounds) = rounds_r { - if no_rounds == 0 { Ok(SimplificationStyle::O1) } - else {Ok(SimplificationStyle::O2(no_rounds))}} - else { Result::Err(eprintln!("{}", Colour::Red.paint("invalid number of rounds"))) } - }, - + if let Result::Ok(no_rounds) = rounds_r { + if no_rounds == 0 { + Ok(SimplificationStyle::O1) + } else { + Ok(SimplificationStyle::O2(no_rounds)) + } + } else { + Result::Err(eprintln!("{}", Colour::Red.paint("invalid number of rounds"))) + } + } + (false, false, false, true) => Ok(SimplificationStyle::O2(usize::MAX)), (false, false, false, false) => Ok(SimplificationStyle::O2(usize::MAX)), } @@ -311,25 +324,22 @@ mod input_processing { matches.is_present("flag_old_heuristics") } pub fn get_prime(matches: &ArgMatches) -> Result { - - match matches.is_present("prime"){ - true => - { - let prime_value = matches.value_of("prime").unwrap(); - if prime_value == "bn128" - || prime_value == "bls12381" - || prime_value == "goldilocks" - || prime_value == "grumpkin" - || prime_value == "pallas" - || prime_value == "vesta" - { - Ok(String::from(matches.value_of("prime").unwrap())) - } - else{ - Result::Err(eprintln!("{}", Colour::Red.paint("invalid prime number"))) - } - } - + match matches.is_present("prime") { + true => { + let prime_value = matches.value_of("prime").unwrap(); + if prime_value == "bn128" + || prime_value == "bls12381" + || prime_value == "goldilocks" + || prime_value == "grumpkin" + || prime_value == "pallas" + || prime_value == "vesta" + { + Ok(String::from(matches.value_of("prime").unwrap())) + } else { + Result::Err(eprintln!("{}", Colour::Red.paint("invalid prime number"))) + } + } + false => Ok(String::from("bn128")), } } @@ -449,8 +459,8 @@ mod input_processing { .short("l") .takes_value(true) .multiple(true) - .number_of_values(1) - .display_order(330) + .number_of_values(1) + .display_order(330) .help("Adds directory to library search path"), ) .arg( diff --git a/circom/src/main.rs b/circom/src/main.rs index b07eef64d..c020674b3 100644 --- a/circom/src/main.rs +++ b/circom/src/main.rs @@ -6,7 +6,6 @@ mod type_analysis_user; const VERSION: &'static str = env!("CARGO_PKG_VERSION"); - use ansi_term::Colour; use input_user::Input; fn main() { @@ -42,7 +41,7 @@ fn start() -> Result<(), ()> { sym: user_input.sym_file().to_string(), r1cs: user_input.r1cs_file().to_string(), json_constraints: user_input.json_constraints_file().to_string(), - prime: user_input.prime(), + prime: user_input.prime(), }; let circuit = execution_user::execute_project(program_archive, config)?; let compilation_config = CompilerConfig { @@ -51,10 +50,10 @@ fn start() -> Result<(), ()> { c_flag: user_input.c_flag(), wasm_flag: user_input.wasm_flag(), wat_flag: user_input.wat_flag(), - js_folder: user_input.js_folder().to_string(), - wasm_name: user_input.wasm_name().to_string(), - c_folder: user_input.c_folder().to_string(), - c_run_name: user_input.c_run_name().to_string(), + js_folder: user_input.js_folder().to_string(), + wasm_name: user_input.wasm_name().to_string(), + c_folder: user_input.c_folder().to_string(), + c_run_name: user_input.c_run_name().to_string(), c_file: user_input.c_file().to_string(), dat_file: user_input.dat_file().to_string(), wat_file: user_input.wat_file().to_string(), diff --git a/circom/src/parser_user.rs b/circom/src/parser_user.rs index cd93e3b52..68427285a 100644 --- a/circom/src/parser_user.rs +++ b/circom/src/parser_user.rs @@ -3,10 +3,10 @@ use program_structure::error_definition::Report; use program_structure::program_archive::ProgramArchive; use crate::VERSION; - pub fn parse_project(input_info: &Input) -> Result { let initial_file = input_info.input_file().to_string(); - let result_program_archive = parser::run_parser(initial_file, VERSION, input_info.get_link_libraries().to_vec()); + let result_program_archive = + parser::run_parser(initial_file, VERSION, input_info.get_link_libraries().to_vec()); match result_program_archive { Result::Err((file_library, report_collection)) => { Report::print_reports(&report_collection, &file_library); diff --git a/circom_algebra/src/algebra.rs b/circom_algebra/src/algebra.rs index bfddd49e2..2f8020e6a 100644 --- a/circom_algebra/src/algebra.rs +++ b/circom_algebra/src/algebra.rs @@ -234,12 +234,12 @@ impl ArithmeticExpression { field: &BigInt, ) -> Result<(), ArithmeticError> { debug_assert!(ArithmeticExpression::valid_hashmap_for_expression(coefficients)); - let inverse_constant = modular_arithmetic::div( - &BigInt::from(1), - constant, - &field - )?; - ArithmeticExpression::multiply_coefficients_by_constant(&inverse_constant, coefficients, field); + let inverse_constant = modular_arithmetic::div(&BigInt::from(1), constant, &field)?; + ArithmeticExpression::multiply_coefficients_by_constant( + &inverse_constant, + coefficients, + field, + ); debug_assert!(ArithmeticExpression::valid_hashmap_for_expression(coefficients)); Result::Ok(()) } @@ -534,12 +534,12 @@ impl ArithmeticExpression { let value = modular_arithmetic::pow(value_0, value_1, field); Number { value } } - (Signal { symbol }, Number { value }) if *value == BigInt::from(2) => { + (Signal { symbol }, Number { value }) if *value == BigInt::from(2) => { let left = Signal { symbol: symbol.clone() }; let right = Signal { symbol: symbol.clone() }; ArithmeticExpression::mul(&left, &right, field) } - (Linear { coefficients }, Number {value}) if *value == BigInt::from(2) => { + (Linear { coefficients }, Number { value }) if *value == BigInt::from(2) => { let left = Linear { coefficients: coefficients.clone() }; let right = Linear { coefficients: coefficients.clone() }; ArithmeticExpression::mul(&left, &right, field) @@ -763,8 +763,8 @@ impl ArithmeticExpression { use ArithmeticExpression::*; match expr { Linear { coefficients } => { - raw_substitution(coefficients, substitution, field); - *coefficients = remove_zero_value_coefficients(std::mem::take(coefficients)); + raw_substitution(coefficients, substitution, field); + *coefficients = remove_zero_value_coefficients(std::mem::take(coefficients)); } Signal { symbol } if *symbol == substitution.from => { *expr = Linear { coefficients: substitution.to.clone() }; @@ -1071,8 +1071,9 @@ impl Constraint { ) -> (BigInt, Substitution) { debug_assert!(Constraint::is_linear(&constraint)); debug_assert!(constraint.c.contains_key(signal)); - let (coefficient, raw_expression) = Constraint::clear_signal_not_normalized(constraint.c, &signal, field); - (coefficient, Substitution {from: signal.clone(), to: raw_expression}) + let (coefficient, raw_expression) = + Constraint::clear_signal_not_normalized(constraint.c, &signal, field); + (coefficient, Substitution { from: signal.clone(), to: raw_expression }) } pub fn take_cloned_signals(&self) -> HashSet { @@ -1185,14 +1186,15 @@ impl Constraint { signal_equals_constant(&self.a, &self.b, &self.c) } - pub fn into_arithmetic_expressions(self) -> (ArithmeticExpression, ArithmeticExpression, ArithmeticExpression) { + pub fn into_arithmetic_expressions( + self, + ) -> (ArithmeticExpression, ArithmeticExpression, ArithmeticExpression) { ( ArithmeticExpression::Linear { coefficients: self.a }, ArithmeticExpression::Linear { coefficients: self.b }, - ArithmeticExpression::Linear { coefficients: self.c } + ArithmeticExpression::Linear { coefficients: self.c }, ) } - } impl Constraint { @@ -1210,7 +1212,6 @@ impl Constraint { signals.remove(&Constraint::constant_coefficient()); signals } - } impl Constraint { @@ -1366,9 +1367,8 @@ where let cq: C = ArithmeticExpression::constant_coefficient(); HashMap::is_empty(a) && HashMap::is_empty(b) - && - ((HashMap::contains_key(c, &cq) && HashMap::len(c) == 2) || - (!HashMap::contains_key(c, &cq) && HashMap::len(c) == 1)) + && ((HashMap::contains_key(c, &cq) && HashMap::len(c) == 2) + || (!HashMap::contains_key(c, &cq) && HashMap::len(c) == 1)) } fn is_constant_expression(expr: &RawExpr) -> bool diff --git a/circom_algebra/src/modular_arithmetic.rs b/circom_algebra/src/modular_arithmetic.rs index 6fdfce35a..dfce16e57 100644 --- a/circom_algebra/src/modular_arithmetic.rs +++ b/circom_algebra/src/modular_arithmetic.rs @@ -68,23 +68,23 @@ pub fn prefix_sub(elem: &BigInt, field: &BigInt) -> BigInt { mul(elem, &minus_one, field) } -pub fn multi_inv(values: &Vec, field: &BigInt) -> Vec{ - let one : BigInt = BigInt::from(1); - let mut partials : Vec = Vec::new(); +pub fn multi_inv(values: &Vec, field: &BigInt) -> Vec { + let one: BigInt = BigInt::from(1); + let mut partials: Vec = Vec::new(); partials.push(one.clone()); - for i in 0..values.len(){ - partials.push(mul(partials.get(partials.len()-1).unwrap(), - values.get(i).unwrap(), - &field)); + for i in 0..values.len() { + partials.push(mul( + partials.get(partials.len() - 1).unwrap(), + values.get(i).unwrap(), + &field, + )); } - let mut inverse = div(&one, - partials.get(partials.len()-1).unwrap(), - &field).ok().unwrap(); - let mut outputs : Vec = vec![BigInt::from(0); partials.len()]; + let mut inverse = div(&one, partials.get(partials.len() - 1).unwrap(), &field).ok().unwrap(); + let mut outputs: Vec = vec![BigInt::from(0); partials.len()]; let mut i = values.len(); - while i > 0{ - outputs[i-1] = mul(partials.get(i-1).unwrap(), &inverse, &field); - inverse = mul(&inverse, values.get(i-1).unwrap(), &field); + while i > 0 { + outputs[i - 1] = mul(partials.get(i - 1).unwrap(), &inverse, &field); + inverse = mul(&inverse, values.get(i - 1).unwrap(), &field); i = i - 1; } return outputs; diff --git a/circom_algebra/src/simplification_utils.rs b/circom_algebra/src/simplification_utils.rs index 6219843fb..807718434 100644 --- a/circom_algebra/src/simplification_utils.rs +++ b/circom_algebra/src/simplification_utils.rs @@ -62,18 +62,21 @@ struct SignalsInformation { } impl SignalsInformation { - - pub fn new(constraints: &Vec, signals: &SignalDefinition4, num_signals: usize) -> (SignalsInformation, BTreeMap) { + pub fn new( + constraints: &Vec, + signals: &SignalDefinition4, + num_signals: usize, + ) -> (SignalsInformation, BTreeMap) { let mut signal_to_ocurrences: HashMap = HashMap::with_capacity(num_signals); let mut signal_to_rep: HashMap = HashMap::with_capacity(num_signals); let mut uniques: BTreeMap = BTreeMap::new(); - for pos in 0..constraints.len(){ + for pos in 0..constraints.len() { for k in constraints[pos].c().keys() { if signals.can_be_taken(*k) { - match signal_to_ocurrences.get_mut(k){ - Some(prev_ocu) =>{ + match signal_to_ocurrences.get_mut(k) { + Some(prev_ocu) => { *prev_ocu = *prev_ocu + 1; - }, + } None => { signal_to_ocurrences.insert(*k, 1); signal_to_rep.insert(*k, pos); @@ -83,33 +86,30 @@ impl SignalsInformation { } } - for (k, ocu) in &signal_to_ocurrences{ - if *ocu == 1{ + for (k, ocu) in &signal_to_ocurrences { + if *ocu == 1 { uniques.insert(*k, *signal_to_rep.get(k).unwrap()); } } - (SignalsInformation{signal_to_ocurrences}, uniques) + (SignalsInformation { signal_to_ocurrences }, uniques) } - pub fn remove_constraint(&mut self, constraint: &C, signals: &SignalDefinition4){ - for signal in constraint.c().keys(){ - if signals.can_be_taken(*signal){ - match self.signal_to_ocurrences.get_mut(&signal){ - Some(ocurrences) =>{ + pub fn remove_constraint(&mut self, constraint: &C, signals: &SignalDefinition4) { + for signal in constraint.c().keys() { + if signals.can_be_taken(*signal) { + match self.signal_to_ocurrences.get_mut(&signal) { + Some(ocurrences) => { *ocurrences = *ocurrences - 1; - }, - None => {}, + } + None => {} } } } - } - - pub fn remove_signal(&mut self, signal: usize){ + pub fn remove_signal(&mut self, signal: usize) { self.signal_to_ocurrences.remove(&signal); } - } #[allow(dead_code)] @@ -162,23 +162,39 @@ fn substitution_process_4( ) { let mut lconst = LinkedList::new(); let mut vec_constraints = Vec::new(); - for c in &mut *constraints{ + for c in &mut *constraints { vec_constraints.push(c.clone()); } - let (mut info_ocurrences, uniques) = SignalsInformation::new(&vec_constraints, signals, num_signals); - for (signal, index) in uniques{ - if !vec_constraints[index].is_empty(){ + let (mut info_ocurrences, uniques) = + SignalsInformation::new(&vec_constraints, signals, num_signals); + for (signal, index) in uniques { + if !vec_constraints[index].is_empty() { let actual_constraint = replace(&mut vec_constraints[index], C::empty()); - info_ocurrences.remove_constraint(&actual_constraint, signals); - treat_unique_constraint_4(signals, substitutions, &mut lconst, actual_constraint, &mut info_ocurrences, signal, field); + info_ocurrences.remove_constraint(&actual_constraint, signals); + treat_unique_constraint_4( + signals, + substitutions, + &mut lconst, + actual_constraint, + &mut info_ocurrences, + signal, + field, + ); } } - while !vec_constraints.is_empty(){ + while !vec_constraints.is_empty() { if let Option::Some(actual_constraint) = Vec::pop(&mut vec_constraints) { - info_ocurrences.remove_constraint(&actual_constraint, signals); - treat_constraint_4(signals, substitutions, &mut lconst, actual_constraint, &mut info_ocurrences, field); + info_ocurrences.remove_constraint(&actual_constraint, signals); + treat_constraint_4( + signals, + substitutions, + &mut lconst, + actual_constraint, + &mut info_ocurrences, + field, + ); } } *constraints = lconst; @@ -237,7 +253,8 @@ fn treat_constraint_2( } let out = out.unwrap(); signals.delete(out); - let (coefficient, substitution) = C::clear_signal_from_linear_not_normalized(work, &out, field); + let (coefficient, substitution) = + C::clear_signal_from_linear_not_normalized(work, &out, field); let in_conflict = substitutions.get(&substitution.from()).cloned(); if in_conflict.is_none() { substitutions.insert(*substitution.from(), (coefficient, substitution)); @@ -246,10 +263,10 @@ fn treat_constraint_2( let (in_conflict_coef, in_conflict_subs) = in_conflict.unwrap(); let right = S::decompose(in_conflict_subs).1; let left = S::decompose(substitution).1; - let exp_coef_right = A::Number {value : in_conflict_coef}; - let exp_coef_left = A::Number {value : coefficient}; - let new_left = A::mul(&exp_coef_right,&left,field); - let new_right = A::mul(&exp_coef_left,&right,field); + let exp_coef_right = A::Number { value: in_conflict_coef }; + let exp_coef_left = A::Number { value: coefficient }; + let new_left = A::mul(&exp_coef_right, &left, field); + let new_right = A::mul(&exp_coef_left, &right, field); let merge = A::sub(&new_left, &new_right, field); work = A::transform_expression_to_constraint_form(merge, field).unwrap(); C::remove_zero_value_coefficients(&mut work); @@ -274,7 +291,8 @@ fn treat_constraint_3( } let out = out.unwrap(); signals.delete(out); - let (coefficient, substitution) = C::clear_signal_from_linear_not_normalized(work, &out, field); + let (coefficient, substitution) = + C::clear_signal_from_linear_not_normalized(work, &out, field); let in_conflict = substitutions.get(&substitution.from()).cloned(); if in_conflict.is_none() { substitutions.insert(*substitution.from(), (coefficient, substitution)); @@ -283,10 +301,10 @@ fn treat_constraint_3( let (in_conflict_coef, in_conflict_subs) = in_conflict.unwrap(); let right = S::decompose(in_conflict_subs).1; let left = S::decompose(substitution).1; - let exp_coef_right = A::Number {value : in_conflict_coef}; - let exp_coef_left = A::Number {value : coefficient}; - let new_left = A::mul(&exp_coef_right,&left,field); - let new_right = A::mul(&exp_coef_left,&right,field); + let exp_coef_right = A::Number { value: in_conflict_coef }; + let exp_coef_left = A::Number { value: coefficient }; + let new_left = A::mul(&exp_coef_right, &left, field); + let new_right = A::mul(&exp_coef_left, &right, field); let merge = A::sub(&new_left, &new_right, field); work = A::transform_expression_to_constraint_form(merge, field).unwrap(); C::remove_zero_value_coefficients(&mut work); @@ -302,8 +320,8 @@ fn treat_unique_constraint_4( signal: usize, field: &BigInt, ) { - - let (coefficient, substitution) = C::clear_signal_from_linear_not_normalized(work, &signal, field); + let (coefficient, substitution) = + C::clear_signal_from_linear_not_normalized(work, &signal, field); substitutions.insert(*substitution.from(), (coefficient, substitution)); info_ocurrences.remove_signal(signal); signals.delete(signal); @@ -327,7 +345,8 @@ fn treat_constraint_4( break; } let out = out.unwrap(); - let (coefficient, substitution) = C::clear_signal_from_linear_not_normalized(work, &out, field); + let (coefficient, substitution) = + C::clear_signal_from_linear_not_normalized(work, &out, field); let in_conflict = substitutions.get(&substitution.from()).cloned(); if in_conflict.is_none() { signals.delete(out); @@ -338,10 +357,10 @@ fn treat_constraint_4( let (in_conflict_coef, in_conflict_subs) = in_conflict.unwrap(); let right = S::decompose(in_conflict_subs).1; let left = S::decompose(substitution).1; - let exp_coef_right = A::Number {value : in_conflict_coef}; - let exp_coef_left = A::Number {value : coefficient}; - let new_left = A::mul(&exp_coef_right,&left,field); - let new_right = A::mul(&exp_coef_left,&right,field); + let exp_coef_right = A::Number { value: in_conflict_coef }; + let exp_coef_left = A::Number { value: coefficient }; + let new_left = A::mul(&exp_coef_right, &left, field); + let new_right = A::mul(&exp_coef_left, &right, field); let merge = A::sub(&new_left, &new_right, field); work = A::transform_expression_to_constraint_form(merge, field).unwrap(); C::remove_zero_value_coefficients(&mut work); @@ -376,7 +395,11 @@ fn take_signal_3(signals: &SignalDefinition, constraint: &C) -> Option { ret } -fn take_signal_4(signals: &SignalDefinition4, info_ocurrences: &SignalsInformation, constraint: &C) -> Option { +fn take_signal_4( + signals: &SignalDefinition4, + info_ocurrences: &SignalsInformation, + constraint: &C, +) -> Option { let mut ret = Option::None; let mut ocurrences_ret: Option = Option::None; for k in constraint.c().keys() { @@ -384,52 +407,45 @@ fn take_signal_4(signals: &SignalDefinition4, info_ocurrences: &SignalsInformati if signals.is_deleted(*k) { ret = Some(*k); break; - } - else { + } else { let new_ocurrences = info_ocurrences.signal_to_ocurrences.get(k).unwrap(); - match ocurrences_ret{ + match ocurrences_ret { Some(val_ant) => { - if *new_ocurrences < val_ant{ + if *new_ocurrences < val_ant { ret = Some(*k); ocurrences_ret = Some(*new_ocurrences); - } - else if *new_ocurrences == val_ant{ - if ret.unwrap() < *k{ + } else if *new_ocurrences == val_ant { + if ret.unwrap() < *k { ret = Some(*k); } } - }, + } None => { ret = Some(*k); ocurrences_ret = Some(*new_ocurrences); } - } + } } } } ret } +fn normalize_substitutions(substitutions: SHNotNormalized, field: &BigInt) -> SH { + let mut coeffs: Vec = Vec::new(); -fn normalize_substitutions(substitutions: SHNotNormalized, field: &BigInt) -> SH{ - let mut coeffs : Vec = Vec::new(); - - for (_signal, (coeff, _sub)) in &substitutions{ + for (_signal, (coeff, _sub)) in &substitutions { coeffs.push(coeff.clone()); } - + let inverses = modular_arithmetic::multi_inv(&coeffs, field); - let mut tree : BTreeMap = BTreeMap::new(); + let mut tree: BTreeMap = BTreeMap::new(); let mut i = 0; - for (signal, (_coeff, sub)) in substitutions{ + for (signal, (_coeff, sub)) in substitutions { let inv = inverses.get(i).unwrap(); let arith_sub = A::hashmap_into_arith(sub.to().clone()); - let mult_by_inverse = A::mul( - &arith_sub, - &A::Number {value : inv.clone()}, - field - ); - let new_sub = S::new(signal.clone(), mult_by_inverse).unwrap(); + let mult_by_inverse = A::mul(&arith_sub, &A::Number { value: inv.clone() }, field); + let new_sub = S::new(signal.clone(), mult_by_inverse).unwrap(); tree.insert(signal, new_sub); i = i + 1; } @@ -462,11 +478,15 @@ fn create_nonoverlapping_substitutions(possible_overlap: SH, field: &BigInt) -> no_overlap } -fn create_nonoverlapping_substitutions_4(mut possible_overlap: SH, signals: &SignalDefinition4,field: &BigInt) -> HashMap { +fn create_nonoverlapping_substitutions_4( + mut possible_overlap: SH, + signals: &SignalDefinition4, + field: &BigInt, +) -> HashMap { debug_assert!(debug_check_keys_in_order(&possible_overlap)); let mut no_overlap = HashMap::with_capacity(possible_overlap.len()); - for s in &signals.order_signals{ + for s in &signals.order_signals { let mut substitution = possible_overlap.remove(s).unwrap(); let to_be_applied = take_substitutions_to_be_applied(&no_overlap, &substitution); for sub in to_be_applied { @@ -493,7 +513,11 @@ pub fn debug_substitution_check(substitutions: &HashMap) -> bool { result } -pub fn fast_encoded_constraint_substitution(c: &mut C, enc: &HashMap, field: &BigInt)-> bool { +pub fn fast_encoded_constraint_substitution( + c: &mut C, + enc: &HashMap, + field: &BigInt, +) -> bool { let signals = C::take_cloned_signals(c); let mut applied_substitution = false; for signal in signals { @@ -547,10 +571,9 @@ where //debug_new_substitutions(&config); let min = 350; let max = 1000000; - let apply_less_ocurrences = - config.constraints.len() >= min && - config.constraints.len() < max && - !config.use_old_heuristics; + let apply_less_ocurrences = config.constraints.len() >= min + && config.constraints.len() < max + && !config.use_old_heuristics; let field = config.field; let mut constraints = config.constraints; @@ -558,14 +581,27 @@ where let normalized_holder: SH; let non_overlapping: HashMap; - if apply_less_ocurrences{ - let mut signals = SignalDefinition4 { forbidden: config.forbidden.as_ref(), deleted_symbols: HashSet::new(), order_signals: LinkedList::new() }; - substitution_process_4(&mut signals, &mut constraints, &mut holder, config.num_signals, &field); + if apply_less_ocurrences { + let mut signals = SignalDefinition4 { + forbidden: config.forbidden.as_ref(), + deleted_symbols: HashSet::new(), + order_signals: LinkedList::new(), + }; + substitution_process_4( + &mut signals, + &mut constraints, + &mut holder, + config.num_signals, + &field, + ); normalized_holder = normalize_substitutions(holder, &field); - non_overlapping = create_nonoverlapping_substitutions_4(normalized_holder, &signals, &field); - } - else{ - let mut signals = SignalDefinition { forbidden: config.forbidden.as_ref(), deleted_symbols: HashSet::new() }; + non_overlapping = + create_nonoverlapping_substitutions_4(normalized_holder, &signals, &field); + } else { + let mut signals = SignalDefinition { + forbidden: config.forbidden.as_ref(), + deleted_symbols: HashSet::new(), + }; substitution_process_3(&mut signals, &mut constraints, &mut holder, &field); normalized_holder = normalize_substitutions(holder, &field); non_overlapping = create_nonoverlapping_substitutions(normalized_holder, &field); @@ -586,12 +622,23 @@ where { let field = config.field.clone(); // build the subs using always the complete new version - let mut signals_4 = SignalDefinition4 { forbidden: config.forbidden.as_ref(), deleted_symbols: HashSet::new(), order_signals: LinkedList::new() }; + let mut signals_4 = SignalDefinition4 { + forbidden: config.forbidden.as_ref(), + deleted_symbols: HashSet::new(), + order_signals: LinkedList::new(), + }; let mut constraints_4 = config.constraints.clone(); let mut holder_4 = SHNotNormalized::new(); - substitution_process_4(&mut signals_4, &mut constraints_4, &mut holder_4, config.num_signals, &field); + substitution_process_4( + &mut signals_4, + &mut constraints_4, + &mut holder_4, + config.num_signals, + &field, + ); let normalized_holder_4 = normalize_substitutions(holder_4, &field); - let non_overlapping_4 = create_nonoverlapping_substitutions_4(normalized_holder_4, &signals_4, &field); + let non_overlapping_4 = + create_nonoverlapping_substitutions_4(normalized_holder_4, &signals_4, &field); let mut substitutions_4 = LinkedList::new(); let mut removed_4 = LinkedList::new(); for (s, v) in non_overlapping_4 { @@ -599,7 +646,7 @@ where LinkedList::push_back(&mut substitutions_4, v); } - // build the subs using the multi-inv and taking the bigger signal + // build the subs using the multi-inv and taking the bigger signal let mut signals_3 = SignalDefinition { forbidden: config.forbidden.as_ref(), deleted_symbols: HashSet::new() }; let mut constraints_3 = config.constraints.clone(); @@ -650,40 +697,35 @@ where } #[allow(dead_code)] -pub fn check_substitutions( - subs_1: &LinkedList, - subs_2: &LinkedList, - field: &BigInt, -){ +pub fn check_substitutions(subs_1: &LinkedList, subs_2: &LinkedList, field: &BigInt) { // First consider the constraints of the first substitution and apply on them the second substitution. // The result should be the identity - for s in subs_1{ + for s in subs_1 { let mut cons = S::substitution_into_constraint(s.clone(), field); - for s_2 in subs_2{ + for s_2 in subs_2 { C::apply_substitution(&mut cons, s_2, field); C::fix_constraint(&mut cons, field); } - if !cons.is_empty(){ + if !cons.is_empty() { println!("ERROR: FOUND NOT EMPTY SUBS"); - for (s, v) in &cons.c{ + for (s, v) in &cons.c { println!("Signal {} value {}", s, v) } } } // Consider the second substitution and apply on it the first one, the result should be the identity again. - for s in subs_2{ + for s in subs_2 { let mut cons = S::substitution_into_constraint(s.clone(), field); - for s_2 in subs_1{ + for s_2 in subs_1 { C::apply_substitution(&mut cons, s_2, field); C::fix_constraint(&mut cons, field); } - if !cons.is_empty(){ + if !cons.is_empty() { println!("ERROR: FOUND NOT EMPTY SUBS"); - for (s, v) in &cons.c{ + for (s, v) in &cons.c { println!("Signal {} value {}", s, v) } } } - -} \ No newline at end of file +} diff --git a/code_producers/src/c_elements/c_code_generator.rs b/code_producers/src/c_elements/c_code_generator.rs index acd9ab475..b85e75b4f 100644 --- a/code_producers/src/c_elements/c_code_generator.rs +++ b/code_producers/src/c_elements/c_code_generator.rs @@ -165,16 +165,12 @@ pub fn declare_my_template_name() -> CInstruction { ) } pub fn declare_my_template_name_function(name: &String) -> CInstruction { - format!( - "std::string {} = \"{}\"", - MY_TEMPLATE_NAME, name.to_string() - ) + format!("std::string {} = \"{}\"", MY_TEMPLATE_NAME, name.to_string()) } pub fn my_template_name() -> CInstruction { format!("{}", MY_TEMPLATE_NAME) } - pub const MY_COMPONENT_NAME: &str = "myComponentName"; pub fn declare_my_component_name() -> CInstruction { format!( @@ -188,10 +184,7 @@ pub fn my_component_name() -> CInstruction { pub const MY_FATHER: &str = "myFather"; pub fn declare_my_father() -> CInstruction { - format!( - "u64 {} = {}->componentMemory[{}].idFather", - MY_FATHER, CIRCOM_CALC_WIT, CTX_INDEX - ) + format!("u64 {} = {}->componentMemory[{}].idFather", MY_FATHER, CIRCOM_CALC_WIT, CTX_INDEX) } pub fn my_father() -> CInstruction { format!("{}", MY_FATHER) @@ -199,10 +192,7 @@ pub fn my_father() -> CInstruction { pub const MY_ID: &str = "myId"; pub fn declare_my_id() -> CInstruction { - format!( - "u64 {} = {}", - MY_ID, CTX_INDEX - ) + format!("u64 {} = {}", MY_ID, CTX_INDEX) } pub fn my_id() -> CInstruction { format!("{}", MY_ID) @@ -367,7 +357,7 @@ pub fn set_list(elems: Vec) -> String { set_string = format!("{}{},", set_string, elem); } set_string.pop(); - set_string .push('}'); + set_string.push('}'); set_string } @@ -385,16 +375,22 @@ pub fn add_return() -> String { "return;".to_string() } -pub fn generate_my_array_position(aux_dimensions: String, len_dimensions: String, param: String) -> String { - format!("{}->generate_position_array({}, {}, {})", CIRCOM_CALC_WIT, aux_dimensions, len_dimensions, param) +pub fn generate_my_array_position( + aux_dimensions: String, + len_dimensions: String, + param: String, +) -> String { + format!( + "{}->generate_position_array({}, {}, {})", + CIRCOM_CALC_WIT, aux_dimensions, len_dimensions, param + ) } pub fn generate_my_trace() -> String { format!("{}->getTrace({})", CIRCOM_CALC_WIT, MY_ID) } -pub fn build_failed_assert_message(line: usize) -> String{ - +pub fn build_failed_assert_message(line: usize) -> String { format!("std::cout << \"Failed assert in template/function \" << {} << \" line {}. \" << \"Followed trace of components: \" << {} << std::endl" , MY_TEMPLATE_NAME, line, @@ -402,7 +398,6 @@ pub fn build_failed_assert_message(line: usize) -> String{ ) } - pub fn build_conditional( cond: Vec, if_body: Vec, @@ -427,20 +422,21 @@ pub fn collect_template_headers(instances: &TemplateListParallel) -> Vec let params_run = vec![declare_ctx_index(), declare_circom_calc_wit()]; let params_run = argument_list(params_run); let params_create = vec![ - declare_signal_offset(), - declare_component_offset(), + declare_signal_offset(), + declare_component_offset(), declare_circom_calc_wit(), declare_component_name(), declare_component_father(), ]; let params_create = argument_list(params_create); - if instance.is_parallel{ + if instance.is_parallel { let run_header = format!("void {}_run_parallel({});", instance.name, params_run); - let create_header = format!("void {}_create_parallel({});", instance.name, params_create); + let create_header = + format!("void {}_create_parallel({});", instance.name, params_create); template_headers.push(create_header); template_headers.push(run_header); } - if instance.is_not_parallel{ + if instance.is_not_parallel { let run_header = format!("void {}_run({});", instance.name, params_run); let create_header = format!("void {}_create({});", instance.name, params_create); template_headers.push(create_header); @@ -686,32 +682,35 @@ pub fn generate_dat_file(dat_file: &mut dyn Write, producer: &CProducer) -> std: dat_file.flush()?; Ok(()) } -pub fn generate_function_list(_producer: &CProducer, list: &TemplateListParallel) -> (String, String) { - let mut func_list= "".to_string(); - let mut func_list_parallel= "".to_string(); +pub fn generate_function_list( + _producer: &CProducer, + list: &TemplateListParallel, +) -> (String, String) { + let mut func_list = "".to_string(); + let mut func_list_parallel = "".to_string(); if list.len() > 0 { - if list[0].is_parallel{ - func_list_parallel.push_str(&format!("\n{}_run_parallel",list[0].name)); - }else{ + if list[0].is_parallel { + func_list_parallel.push_str(&format!("\n{}_run_parallel", list[0].name)); + } else { func_list_parallel.push_str(&format!("\nNULL")); } - if list[0].is_not_parallel{ - func_list.push_str(&format!("\n{}_run",list[0].name)); - }else{ + if list[0].is_not_parallel { + func_list.push_str(&format!("\n{}_run", list[0].name)); + } else { func_list.push_str(&format!("\nNULL")); } - for i in 1..list.len() { - if list[i].is_parallel{ - func_list_parallel.push_str(&format!(",\n{}_run_parallel",list[i].name)); - }else{ + for i in 1..list.len() { + if list[i].is_parallel { + func_list_parallel.push_str(&format!(",\n{}_run_parallel", list[i].name)); + } else { func_list_parallel.push_str(&format!(",\nNULL")); } - if list[i].is_not_parallel{ - func_list.push_str(&format!(",\n{}_run",list[i].name)); - }else{ + if list[i].is_not_parallel { + func_list.push_str(&format!(",\n{}_run", list[i].name)); + } else { func_list.push_str(&format!(",\nNULL")); } - } + } } (func_list, func_list_parallel) } @@ -734,9 +733,10 @@ pub fn generate_message_list_def(_producer: &CProducer, message_list: &MessageLi instructions } -pub fn generate_function_release_memory_component() -> Vec{ +pub fn generate_function_release_memory_component() -> Vec { let mut instructions = vec![]; - instructions.push("void release_memory_component(Circom_CalcWit* ctx, uint pos) {{\n".to_string()); + instructions + .push("void release_memory_component(Circom_CalcWit* ctx, uint pos) {{\n".to_string()); instructions.push("if (pos != 0){{\n".to_string()); instructions.push("if(ctx->componentMemory[pos].subcomponents)".to_string()); instructions.push("delete []ctx->componentMemory[pos].subcomponents;\n".to_string()); @@ -755,7 +755,7 @@ pub fn generate_function_release_memory_component() -> Vec{ instructions } -pub fn generate_function_release_memory_circuit() -> Vec{ +pub fn generate_function_release_memory_circuit() -> Vec { // deleting each one of the components let mut instructions = vec![]; instructions.push("void release_memory(Circom_CalcWit* ctx) {{\n".to_string()); @@ -764,7 +764,7 @@ pub fn generate_function_release_memory_circuit() -> Vec{ instructions.push("}}\n".to_string()); instructions.push("}}\n".to_string()); instructions - } +} pub fn generate_main_cpp_file(c_folder: &PathBuf) -> std::io::Result<()> { use std::io::BufWriter; @@ -808,7 +808,7 @@ pub fn generate_fr_hpp_file(c_folder: &PathBuf, prime: &String) -> std::io::Resu let file_name = file_path.to_str().unwrap(); let mut c_file = BufWriter::new(File::create(file_name).unwrap()); let mut code = "".to_string(); - let file = match prime.as_ref(){ + let file = match prime.as_ref() { "bn128" => include_str!("bn128/fr.hpp"), "bls12381" => include_str!("bls12381/fr.hpp"), "goldilocks" => include_str!("goldilocks/fr.hpp"), @@ -850,14 +850,14 @@ pub fn generate_fr_cpp_file(c_folder: &PathBuf, prime: &String) -> std::io::Resu let file_name = file_path.to_str().unwrap(); let mut c_file = BufWriter::new(File::create(file_name).unwrap()); let mut code = "".to_string(); - let file = match prime.as_ref(){ + let file = match prime.as_ref() { "bn128" => include_str!("bn128/fr.cpp"), "bls12381" => include_str!("bls12381/fr.cpp"), "goldilocks" => include_str!("goldilocks/fr.cpp"), "grumpkin" => include_str!("grumpkin/fr.cpp"), "pallas" => include_str!("pallas/fr.cpp"), "vesta" => include_str!("vesta/fr.cpp"), - + _ => unreachable!(), }; for line in file.lines() { @@ -893,7 +893,7 @@ pub fn generate_fr_asm_file(c_folder: &PathBuf, prime: &String) -> std::io::Resu let file_name = file_path.to_str().unwrap(); let mut c_file = BufWriter::new(File::create(file_name).unwrap()); let mut code = "".to_string(); - let file = match prime.as_ref(){ + let file = match prime.as_ref() { "bn128" => include_str!("bn128/fr.asm"), "bls12381" => include_str!("bls12381/fr.asm"), "goldilocks" => include_str!("goldilocks/fr.asm"), @@ -901,7 +901,7 @@ pub fn generate_fr_asm_file(c_folder: &PathBuf, prime: &String) -> std::io::Resu "pallas" => include_str!("pallas/fr.asm"), "vesta" => include_str!("vesta/fr.asm"), _ => unreachable!(), - }; + }; for line in file.lines() { code = format!("{}{}\n", code, line); } @@ -953,7 +953,8 @@ pub fn generate_c_file(name: String, producer: &CProducer) -> std::io::Result<() let mut run_defs = collect_template_headers(producer.get_template_instance_list()); code.append(&mut run_defs); - let (func_list_no_parallel, func_list_parallel) = generate_function_list(producer, producer.get_template_instance_list()); + let (func_list_no_parallel, func_list_parallel) = + generate_function_list(producer, producer.get_template_instance_list()); code.push(format!( "Circom_TemplateFunction _functionTable[{}] = {{ {} }};", diff --git a/code_producers/src/c_elements/mod.rs b/code_producers/src/c_elements/mod.rs index 47aef5eec..079e49839 100644 --- a/code_producers/src/c_elements/mod.rs +++ b/code_producers/src/c_elements/mod.rs @@ -126,7 +126,7 @@ impl CProducer { &self.prime } pub fn get_number_of_main_outputs(&self) -> usize { - self.number_of_main_outputs+1 + self.number_of_main_outputs + 1 } pub fn get_number_of_main_inputs(&self) -> usize { self.number_of_main_inputs diff --git a/code_producers/src/components/mod.rs b/code_producers/src/components/mod.rs index 3c1dcc5cc..8b8325f0b 100644 --- a/code_producers/src/components/mod.rs +++ b/code_producers/src/components/mod.rs @@ -10,7 +10,7 @@ pub struct IODef { // It is an array that contains (name, start position, size) pub type InputList = Vec<(String, usize, usize)>; pub type TemplateList = Vec; -pub struct InfoParallel{ +pub struct InfoParallel { pub name: String, pub is_parallel: bool, pub is_not_parallel: bool, diff --git a/code_producers/src/wasm_elements/mod.rs b/code_producers/src/wasm_elements/mod.rs index 760f4896a..06558fedd 100644 --- a/code_producers/src/wasm_elements/mod.rs +++ b/code_producers/src/wasm_elements/mod.rs @@ -56,7 +56,7 @@ pub struct WASMProducer { create_loop_offset_tag: String, create_loop_counter_tag: String, merror_tag: String, - string_table: Vec, + string_table: Vec, } impl Default for WASMProducer { @@ -77,7 +77,7 @@ impl Default for WASMProducer { number_of_main_outputs: 0, //2, number_of_main_inputs: 0, // 4, main_input_list: [("in1".to_string(), 1, 1), ("in2".to_string(), 2, 1)].to_vec(), //("inpair".to_string(),2), - signals_in_witness: 0, //20, + signals_in_witness: 0, //20, witness_to_signal_list: [].to_vec(), //[0,1,2,3,4,5,6,12,16,19,24,27,33,42,46,50,51,65,78,79].to_vec(), message_list: [].to_vec(), //["Main".to_string(),"Hola Herme".to_string(),"Hola Albert".to_string()].to_vec(), total_number_of_signals: 0, //80, @@ -117,7 +117,7 @@ impl Default for WASMProducer { create_loop_sub_cmp_tag: "$createloopsubcmp".to_string(), create_loop_offset_tag: "$createloopoffset".to_string(), create_loop_counter_tag: "$createloopcounter".to_string(), - merror_tag: "$merror".to_string(), + merror_tag: "$merror".to_string(), string_table: Vec::new(), } } @@ -324,7 +324,7 @@ impl WASMProducer { pub fn get_constant_numbers_start(&self) -> usize { self.get_string_list_start() + self.size_of_message_in_bytes * self.string_table.len() } - + pub fn get_var_stack_memory_start(&self) -> usize { self.get_constant_numbers_start() + (self.size_32_bit + 2) * 4 * self.field_tracking.len() } @@ -401,9 +401,9 @@ impl WASMProducer { &self.create_loop_counter_tag } pub fn get_merror_tag(&self) -> &str { - &self.merror_tag + &self.merror_tag } - pub fn needs_comments(&self) -> bool{ + pub fn needs_comments(&self) -> bool { self.wat_flag } diff --git a/code_producers/src/wasm_elements/wasm_code_generator.rs b/code_producers/src/wasm_elements/wasm_code_generator.rs index 7277066ad..f9d4a816c 100644 --- a/code_producers/src/wasm_elements/wasm_code_generator.rs +++ b/code_producers/src/wasm_elements/wasm_code_generator.rs @@ -226,7 +226,9 @@ pub fn get_initial_size_of_memory(producer: &WASMProducer) -> usize { //------------------- generate all kinds of Data ------------------ -pub fn generate_hash_map(signal_name_list: &Vec<(String, usize, usize)>) -> Vec<(u64, usize, usize)> { +pub fn generate_hash_map( + signal_name_list: &Vec<(String, usize, usize)>, +) -> Vec<(u64, usize, usize)> { assert!(signal_name_list.len() <= 256); let len = 256; let mut hash_map = vec![(0, 0, 0); len]; @@ -560,7 +562,7 @@ pub fn generate_data_list(producer: &WASMProducer) -> Vec { wdata.push(format!( "(data (i32.const {}) \"{}\")", producer.get_raw_prime_start(), - wasm_hexa(producer.get_size_32_bit()*4, &p) + wasm_hexa(producer.get_size_32_bit() * 4, &p) )); wdata.push(format!( "(data (i32.const {}) \"{}\")", @@ -579,7 +581,12 @@ pub fn generate_data_list(producer: &WASMProducer) -> Vec { producer.get_witness_signal_id_list_start(), s )); - wdata.push(format!("(data (i32.const {}) \"{}{}\")",producer.get_signal_memory_start(),"\\00\\00\\00\\00\\00\\00\\00\\80",wasm_hexa(producer.get_size_32_bit()*4, &BigInt::from(1)))); //setting 'one' as long normal 1 + wdata.push(format!( + "(data (i32.const {}) \"{}{}\")", + producer.get_signal_memory_start(), + "\\00\\00\\00\\00\\00\\00\\00\\80", + wasm_hexa(producer.get_size_32_bit() * 4, &BigInt::from(1)) + )); //setting 'one' as long normal 1 wdata.push(format!( "(data (i32.const {}) \"{}\")", producer.get_template_instance_to_io_signal_start(), @@ -608,7 +615,7 @@ pub fn generate_data_list(producer: &WASMProducer) -> Vec { wdata.push(format!( "(data (i32.const {}) \"{}\\00\")", m + i * producer.get_size_of_message_in_bytes(), - &ml[i][..producer.get_size_of_message_in_bytes()-1] + &ml[i][..producer.get_size_of_message_in_bytes() - 1] )); } } @@ -625,7 +632,7 @@ pub fn generate_data_list(producer: &WASMProducer) -> Vec { wdata.push(format!( "(data (i32.const {}) \"{}\\00\")", s + i * producer.get_size_of_message_in_bytes(), - &st[i][..producer.get_size_of_message_in_bytes()-1] + &st[i][..producer.get_size_of_message_in_bytes() - 1] )); } } @@ -833,17 +840,17 @@ pub fn init_generator(producer: &WASMProducer) -> Vec { // instructions.push(store32(None)); instructions.push(set_constant(&next_to_one.to_string())); let funcname = format!("${}_create", producer.get_main_header()); - instructions.push(call(&funcname)); + instructions.push(call(&funcname)); instructions.push(drop()); if producer.get_number_of_main_inputs() == 0 { - instructions.push(set_constant(&producer.get_component_tree_start().to_string())); - let funcname = format!("${}_run", producer.get_main_header()); - instructions.push(call(&funcname)); - instructions.push(tee_local(producer.get_merror_tag())); - instructions.push(add_if()); - instructions.push(get_local("$merror")); - instructions.push(call("$exceptionHandler")); - instructions.push(add_end()); + instructions.push(set_constant(&producer.get_component_tree_start().to_string())); + let funcname = format!("${}_run", producer.get_main_header()); + instructions.push(call(&funcname)); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(get_local("$merror")); + instructions.push(call("$exceptionHandler")); + instructions.push(add_end()); } instructions.push(")".to_string()); instructions @@ -970,7 +977,7 @@ pub fn set_input_signal_generator(producer: &WASMProducer) -> Vec Vec Vec Vec { instructions.push(shl32()); instructions.push(add32()); // address of the witness in the witness list instructions.push(load32(None)); // number of the signal in the signal Memory - instructions.push(set_constant(&format!("{}",producer.get_size_32_bit()*4+8)));//40 + instructions.push(set_constant(&format!("{}", producer.get_size_32_bit() * 4 + 8))); //40 instructions.push(mul32()); instructions.push(set_constant(&producer.get_signal_memory_start().to_string())); instructions.push(add32()); // address of the signal in the signal Memory @@ -1559,7 +1566,7 @@ fn get_file_instructions(name: &str) -> Vec { pub fn fr_types(prime: &String) -> Vec { let mut instructions = vec![]; - let file = match prime.as_ref(){ + let file = match prime.as_ref() { "bn128" => include_str!("bn128/fr-types.wat"), "bls12381" => include_str!("bls12381/fr-types.wat"), "goldilocks" => include_str!("goldilocks/fr-types.wat"), @@ -1567,7 +1574,7 @@ pub fn fr_types(prime: &String) -> Vec { "pallas" => include_str!("pallas/fr-types.wat"), "vesta" => include_str!("vesta/fr-types.wat"), _ => unreachable!(), - }; + }; for line in file.lines() { instructions.push(line.to_string()); } @@ -1576,7 +1583,7 @@ pub fn fr_types(prime: &String) -> Vec { pub fn fr_data(prime: &String) -> Vec { let mut instructions = vec![]; - let file = match prime.as_ref(){ + let file = match prime.as_ref() { "bn128" => include_str!("bn128/fr-data.wat"), "bls12381" => include_str!("bls12381/fr-data.wat"), "goldilocks" => include_str!("goldilocks/fr-data.wat"), @@ -1584,7 +1591,7 @@ pub fn fr_data(prime: &String) -> Vec { "pallas" => include_str!("pallas/fr-data.wat"), "vesta" => include_str!("vesta/fr-data.wat"), _ => unreachable!(), - }; + }; for line in file.lines() { instructions.push(line.to_string()); } @@ -1592,7 +1599,7 @@ pub fn fr_data(prime: &String) -> Vec { } pub fn fr_code(prime: &String) -> Vec { let mut instructions = vec![]; - let file = match prime.as_ref(){ + let file = match prime.as_ref() { "bn128" => include_str!("bn128/fr-code.wat"), "bls12381" => include_str!("bls12381/fr-code.wat"), "goldilocks" => include_str!("goldilocks/fr-code.wat"), @@ -1600,7 +1607,7 @@ pub fn fr_code(prime: &String) -> Vec { "pallas" => include_str!("pallas/fr-code.wat"), "vesta" => include_str!("vesta/fr-code.wat"), _ => unreachable!(), - }; + }; for line in file.lines() { instructions.push(line.to_string()); } @@ -1628,7 +1635,7 @@ pub fn generate_utils_js_file(js_folder: &PathBuf) -> std::io::Result<()> { pub fn generate_generate_witness_js_file(js_folder: &PathBuf) -> std::io::Result<()> { use std::io::BufWriter; - let mut file_path = js_folder.clone(); + let mut file_path = js_folder.clone(); file_path.push("generate_witness"); file_path.set_extension("js"); let file_name = file_path.to_str().unwrap(); @@ -1645,7 +1652,7 @@ pub fn generate_generate_witness_js_file(js_folder: &PathBuf) -> std::io::Result pub fn generate_witness_calculator_js_file(js_folder: &PathBuf) -> std::io::Result<()> { use std::io::BufWriter; - let mut file_path = js_folder.clone(); + let mut file_path = js_folder.clone(); file_path.push("witness_calculator"); file_path.set_extension("js"); let file_name = file_path.to_str().unwrap(); @@ -1790,7 +1797,7 @@ mod tests { code_aux = build_log_message_generator(&producer); code.append(&mut code_aux); - + //code_aux = main_sample_generator(&producer); //code.append(&mut code_aux); diff --git a/compiler/src/circuit_design/build.rs b/compiler/src/circuit_design/build.rs index ce3dac392..a1982c943 100644 --- a/compiler/src/circuit_design/build.rs +++ b/compiler/src/circuit_design/build.rs @@ -3,7 +3,9 @@ use crate::circuit_design::function::FunctionCodeInfo; use crate::circuit_design::template::TemplateCodeInfo; use crate::hir::very_concrete_program::*; use crate::intermediate_representation::translate; -use crate::intermediate_representation::translate::{CodeInfo, FieldTracker, TemplateDB, ParallelClusters}; +use crate::intermediate_representation::translate::{ + CodeInfo, FieldTracker, TemplateDB, ParallelClusters, +}; use code_producers::c_elements::*; use code_producers::wasm_elements::*; use program_structure::file_definition::FileLibrary; @@ -25,8 +27,7 @@ fn build_template_instances( c_info: &CircuitInfo, ti: Vec, mut field_tracker: FieldTracker, -) -> (FieldTracker, HashMap) { - +) -> (FieldTracker, HashMap) { fn compute_jump(lengths: &Vec, indexes: &[usize]) -> usize { let mut jump = 0; let mut full_length = lengths.iter().fold(1, |p, c| p * (*c)); @@ -55,31 +56,34 @@ fn build_template_instances( cmp_to_type.insert(name, xtype); } circuit.wasm_producer.message_list.push(msg); - circuit.c_producer.has_parallelism |= template.is_parallel || template.is_parallel_component; + circuit.c_producer.has_parallelism |= + template.is_parallel || template.is_parallel_component; let mut component_to_parallel: HashMap = HashMap::new(); - for trigger in &template.triggers{ - match component_to_parallel.get_mut(&trigger.component_name){ + for trigger in &template.triggers { + match component_to_parallel.get_mut(&trigger.component_name) { Some(parallel_info) => { - parallel_info.positions_to_parallel.insert(trigger.indexed_with.clone(), trigger.is_parallel); - if parallel_info.uniform_parallel_value.is_some(){ - if parallel_info.uniform_parallel_value.unwrap() != trigger.is_parallel{ + parallel_info + .positions_to_parallel + .insert(trigger.indexed_with.clone(), trigger.is_parallel); + if parallel_info.uniform_parallel_value.is_some() { + if parallel_info.uniform_parallel_value.unwrap() != trigger.is_parallel { parallel_info.uniform_parallel_value = None; } } - }, + } None => { let mut positions_to_parallel = BTreeMap::new(); - positions_to_parallel.insert(trigger.indexed_with.clone(), trigger.is_parallel); + positions_to_parallel.insert(trigger.indexed_with.clone(), trigger.is_parallel); let new_parallel_info = ParallelClusters { positions_to_parallel, uniform_parallel_value: Some(trigger.is_parallel), }; component_to_parallel.insert(trigger.component_name.clone(), new_parallel_info); - }, + } } } - + let code_info = CodeInfo { cmp_to_type, field_tracker, @@ -96,7 +100,7 @@ fn build_template_instances( fresh_cmp_id: cmp_id, components: template.components, template_database: &c_info.template_database, - string_table : string_table, + string_table: string_table, signals_to_tags: template.signals_to_tags, }; let mut template_info = TemplateCodeInfo { @@ -133,7 +137,7 @@ fn build_function_instances( c_info: &CircuitInfo, instances: Vec, mut field_tracker: FieldTracker, - mut string_table : HashMap + mut string_table: HashMap, ) -> (FieldTracker, HashMap, HashMap) { let mut function_to_arena_size = HashMap::new(); for instance in instances { @@ -160,7 +164,7 @@ fn build_function_instances( cmp_to_type: HashMap::with_capacity(0), component_to_parallel: HashMap::with_capacity(0), template_database: &c_info.template_database, - string_table : string_table, + string_table: string_table, signals_to_tags: BTreeMap::new(), }; let mut function_info = FunctionCodeInfo { @@ -184,7 +188,12 @@ fn build_function_instances( } // WASM producer builder -fn initialize_wasm_producer(vcp: &VCP, database: &TemplateDB, wat_flag:bool, version: &str) -> WASMProducer { +fn initialize_wasm_producer( + vcp: &VCP, + database: &TemplateDB, + wat_flag: bool, + version: &str, +) -> WASMProducer { use program_structure::utils::constants::UsefulConstants; let initial_node = vcp.get_main_id(); let prime = UsefulConstants::new(&vcp.prime).get_p().clone(); @@ -194,18 +203,19 @@ fn initialize_wasm_producer(vcp: &VCP, database: &TemplateDB, wat_flag:bool, ver producer.main_signal_offset = 1; producer.prime = prime.to_str_radix(10); producer.prime_str = vcp.prime.clone(); - producer.fr_memory_size = match vcp.prime.as_str(){ + producer.fr_memory_size = match vcp.prime.as_str() { "goldilocks" => 412, "bn128" => 1948, "bls12381" => 1948, "grumpkin" => 1948, "pallas" => 1948, "vesta" => 1948, - _ => unreachable!() + _ => unreachable!(), }; //producer.fr_memory_size = 412 if goldilocks and 1948 for bn128 and bls12381 // for each created component we store three u32, for each son we store a u32 in its father - producer.size_of_component_tree = stats.all_created_components * 3 + stats.all_needed_subcomponents_indexes; + producer.size_of_component_tree = + stats.all_created_components * 3 + stats.all_needed_subcomponents_indexes; producer.total_number_of_signals = stats.all_signals + 1; producer.size_32_bit = prime.bits() / 32 + if prime.bits() % 32 != 0 { 1 } else { 0 }; producer.size_32_shift = 0; @@ -225,7 +235,8 @@ fn initialize_wasm_producer(vcp: &VCP, database: &TemplateDB, wat_flag:bool, ver producer.template_instance_list = build_template_list(vcp); producer.field_tracking.clear(); producer.wat_flag = wat_flag; - (producer.major_version, producer.minor_version, producer.patch_version) = get_number_version(version); + (producer.major_version, producer.minor_version, producer.patch_version) = + get_number_version(version); producer } @@ -239,7 +250,8 @@ fn initialize_c_producer(vcp: &VCP, database: &TemplateDB, version: &str) -> CPr producer.main_signal_offset = 1; producer.prime = prime.to_str_radix(10); producer.prime_str = vcp.prime.clone(); - producer.size_of_component_tree = stats.all_created_components * 3 + stats.all_needed_subcomponents_indexes; + producer.size_of_component_tree = + stats.all_created_components * 3 + stats.all_needed_subcomponents_indexes; producer.total_number_of_signals = stats.all_signals + 1; producer.size_32_bit = prime.bits() / 32 + if prime.bits() % 32 != 0 { 1 } else { 0 }; producer.size_32_shift = 0; @@ -254,11 +266,12 @@ fn initialize_c_producer(vcp: &VCP, database: &TemplateDB, version: &str) -> CPr producer.signals_in_witness = producer.witness_to_signal_list.len(); producer.number_of_main_inputs = vcp.templates[initial_node].number_of_inputs; producer.number_of_main_outputs = vcp.templates[initial_node].number_of_outputs; - producer.main_input_list = main_input_list(&vcp.templates[initial_node]); + producer.main_input_list = main_input_list(&vcp.templates[initial_node]); producer.io_map = build_io_map(vcp, database); producer.template_instance_list = build_template_list_parallel(vcp); producer.field_tracking.clear(); - (producer.major_version, producer.minor_version, producer.patch_version) = get_number_version(version); + (producer.major_version, producer.minor_version, producer.patch_version) = + get_number_version(version); producer } @@ -284,8 +297,8 @@ fn build_template_list(vcp: &VCP) -> TemplateList { fn build_template_list_parallel(vcp: &VCP) -> TemplateListParallel { let mut tmp_list = TemplateListParallel::new(); for instance in &vcp.templates { - tmp_list.push(InfoParallel{ - name: instance.template_header.clone(), + tmp_list.push(InfoParallel { + name: instance.template_header.clone(), is_parallel: instance.is_parallel || instance.is_parallel_component, is_not_parallel: !instance.is_parallel && instance.is_not_parallel_component, }); @@ -365,7 +378,8 @@ pub fn build_circuit(vcp: VCP, flag: CompilationFlags, version: &str) -> Circuit } let template_database = TemplateDB::build(&vcp.templates); let mut circuit = Circuit::default(); - circuit.wasm_producer = initialize_wasm_producer(&vcp, &template_database, flag.wat_flag, version); + circuit.wasm_producer = + initialize_wasm_producer(&vcp, &template_database, flag.wat_flag, version); circuit.c_producer = initialize_c_producer(&vcp, &template_database, version); let field_tracker = FieldTracker::new(); @@ -377,8 +391,13 @@ pub fn build_circuit(vcp: VCP, flag: CompilationFlags, version: &str) -> Circuit let (field_tracker, string_table) = build_template_instances(&mut circuit, &circuit_info, vcp.templates, field_tracker); - let (field_tracker, function_to_arena_size, table_string_to_usize) = - build_function_instances(&mut circuit, &circuit_info, vcp.functions, field_tracker,string_table); + let (field_tracker, function_to_arena_size, table_string_to_usize) = build_function_instances( + &mut circuit, + &circuit_info, + vcp.functions, + field_tracker, + string_table, + ); let table_usize_to_string = create_table_usize_to_string(table_string_to_usize); circuit.wasm_producer.set_string_table(table_usize_to_string.clone()); @@ -398,12 +417,12 @@ pub fn build_circuit(vcp: VCP, flag: CompilationFlags, version: &str) -> Circuit circuit } -pub fn create_table_usize_to_string( string_table : HashMap) -> Vec { +pub fn create_table_usize_to_string(string_table: HashMap) -> Vec { let size = string_table.len(); - let mut table_usize_to_string = vec![String::new(); size]; + let mut table_usize_to_string = vec![String::new(); size]; for (string, us) in string_table { table_usize_to_string[us] = string; - } + } table_usize_to_string } diff --git a/compiler/src/circuit_design/circuit.rs b/compiler/src/circuit_design/circuit.rs index e6dd24cd7..6821ec08e 100644 --- a/compiler/src/circuit_design/circuit.rs +++ b/compiler/src/circuit_design/circuit.rs @@ -9,7 +9,7 @@ use std::io::Write; pub struct CompilationFlags { pub main_inputs_log: bool, - pub wat_flag:bool, + pub wat_flag: bool, } pub struct Circuit { @@ -85,7 +85,7 @@ impl WriteWasm for Circuit { code.append(&mut code_aux); code_aux = get_input_size_generator(&producer); - code.append(&mut code_aux); + code.append(&mut code_aux); code_aux = get_witness_size_generator(&producer); code.append(&mut code_aux); @@ -226,7 +226,7 @@ impl WriteWasm for Circuit { code = merge_code(code_aux); writer.write_all(code.as_bytes()).map_err(|_| {})?; //writer.flush().map_err(|_| {})?; - + code_aux = get_witness_size_generator(&producer); code = merge_code(code_aux); writer.write_all(code.as_bytes()).map_err(|_| {})?; @@ -306,34 +306,35 @@ impl WriteC for Circuit { code.push("#include \"calcwit.hpp\"".to_string()); let mut template_headers = collect_template_headers(producer.get_template_instance_list()); - let function_headers: Vec<_> = self.functions - .iter() - .map(|f| f.header.clone()) - .collect(); + let function_headers: Vec<_> = self.functions.iter().map(|f| f.header.clone()).collect(); let mut function_headers = collect_function_headers(function_headers); code.append(&mut template_headers); code.append(&mut function_headers); std::mem::drop(template_headers); std::mem::drop(function_headers); - let (func_list_no_parallel, func_list_parallel) = generate_function_list( - producer, - producer.get_template_instance_list() - ); + let (func_list_no_parallel, func_list_parallel) = + generate_function_list(producer, producer.get_template_instance_list()); - code.push(format!("Circom_TemplateFunction {}[{}] = {{ {} }};", - function_table(), producer.get_number_of_template_instances(), func_list_no_parallel, + code.push(format!( + "Circom_TemplateFunction {}[{}] = {{ {} }};", + function_table(), + producer.get_number_of_template_instances(), + func_list_no_parallel, )); - code.push(format!("Circom_TemplateFunction {}[{}] = {{ {} }};", - function_table_parallel(), producer.get_number_of_template_instances(), func_list_parallel, - )); + code.push(format!( + "Circom_TemplateFunction {}[{}] = {{ {} }};", + function_table_parallel(), + producer.get_number_of_template_instances(), + func_list_parallel, + )); code.push(format!( "uint get_main_input_signal_start() {{return {};}}\n", producer.get_number_of_main_outputs() )); - + code.push(format!( "uint get_main_input_signal_no() {{return {};}}\n", producer.get_number_of_main_inputs() @@ -360,7 +361,7 @@ impl WriteC for Circuit { producer.get_io_map().len() )); //code.append(&mut generate_message_list_def(producer, producer.get_message_list())); - + // Functions to release the memory let mut release_component_code = generate_function_release_memory_component(); code.append(&mut release_component_code); @@ -377,31 +378,36 @@ impl WriteC for Circuit { code.append(&mut t_code); } - // Epilogue let run_circuit = "void run".to_string(); let run_circuit_args = vec![declare_circom_calc_wit()]; - let main_template_create = if producer.main_is_parallel{ + let main_template_create = if producer.main_is_parallel { producer.main_header.clone() + "_create_parallel" - } else{ + } else { producer.main_header.clone() + "_create" }; // We use 0 to indicate that the main component has no father - let create_args = vec!["1".to_string(), "0".to_string(), CIRCOM_CALC_WIT.to_string(), "\"main\"".to_string(), "0".to_string()]; + let create_args = vec![ + "1".to_string(), + "0".to_string(), + CIRCOM_CALC_WIT.to_string(), + "\"main\"".to_string(), + "0".to_string(), + ]; let create_call = build_call(main_template_create, create_args); // let ctx_index = format!("{} = {};", declare_ctx_index(), create_call); let ctx_index = format!("{};", create_call); // let start_msg = "printf(\"Starting...\\n\");".to_string(); // let end_msg = "printf(\"End\\n\");".to_string(); - let main_template_run = if producer.main_is_parallel{ + let main_template_run = if producer.main_is_parallel { producer.main_header.clone() + "_run_parallel" - } else{ + } else { producer.main_header.clone() + "_run" }; let mut run_args = vec![]; // run_args.push(CTX_INDEX.to_string()); - run_args.push("0".to_string()); + run_args.push("0".to_string()); run_args.push(CIRCOM_CALC_WIT.to_string()); let run_call = format!("{};", build_call(main_template_run, run_args.clone())); @@ -411,10 +417,10 @@ impl WriteC for Circuit { } fn write_c(&self, writer: &mut T, producer: &CProducer) -> Result<(), ()> { - use code_producers::wasm_elements::wasm_code_generator::merge_code; + use code_producers::wasm_elements::wasm_code_generator::merge_code; use c_code_generator::*; let mut code = vec![]; - let mut code_write; + let mut code_write; // Prologue code.push("#include ".to_string()); code.push("#include ".to_string()); @@ -422,36 +428,36 @@ impl WriteC for Circuit { code.push("#include \"circom.hpp\"".to_string()); code.push("#include \"calcwit.hpp\"".to_string()); - let mut template_headers = collect_template_headers(producer.get_template_instance_list()); - let function_headers: Vec<_> = self.functions - .iter() - .map(|f| f.header.clone()) - .collect(); + let function_headers: Vec<_> = self.functions.iter().map(|f| f.header.clone()).collect(); let mut function_headers = collect_function_headers(function_headers); code.append(&mut template_headers); code.append(&mut function_headers); std::mem::drop(template_headers); std::mem::drop(function_headers); - let (func_list_no_parallel, func_list_parallel) = generate_function_list( - producer, - producer.get_template_instance_list() - ); + let (func_list_no_parallel, func_list_parallel) = + generate_function_list(producer, producer.get_template_instance_list()); - code.push(format!("Circom_TemplateFunction {}[{}] = {{ {} }};", - function_table(), producer.get_number_of_template_instances(), func_list_no_parallel, + code.push(format!( + "Circom_TemplateFunction {}[{}] = {{ {} }};", + function_table(), + producer.get_number_of_template_instances(), + func_list_no_parallel, )); - code.push(format!("Circom_TemplateFunction {}[{}] = {{ {} }};", - function_table_parallel(), producer.get_number_of_template_instances(), func_list_parallel, - )); + code.push(format!( + "Circom_TemplateFunction {}[{}] = {{ {} }};", + function_table_parallel(), + producer.get_number_of_template_instances(), + func_list_parallel, + )); code.push(format!( "uint get_main_input_signal_start() {{return {};}}\n", producer.get_number_of_main_outputs() )); - + code.push(format!( "uint get_main_input_signal_no() {{return {};}}\n", producer.get_number_of_main_inputs() @@ -478,71 +484,74 @@ impl WriteC for Circuit { producer.get_io_map().len() )); //code.append(&mut generate_message_list_def(producer, producer.get_message_list())); - + // Functions to release the memory let mut release_component_code = generate_function_release_memory_component(); code.append(&mut release_component_code); // Actual code of the circuit - code_write = merge_code(code); + code_write = merge_code(code); writer.write_all(code_write.as_bytes()).map_err(|_| {})?; - + code_write = "// function declarations\n".to_string(); writer.write_all(code_write.as_bytes()).map_err(|_| {})?; - + for f in &self.functions { let (f_code, _) = f.produce_c(producer, None); //code.append(&mut f_code); - code_write = merge_code(f_code); + code_write = merge_code(f_code); writer.write_all(code_write.as_bytes()).map_err(|_| {})?; } - - code_write = "// template declarations\n".to_string(); + + code_write = "// template declarations\n".to_string(); writer.write_all(code_write.as_bytes()).map_err(|_| {})?; - + for t in &self.templates { let (t_code, _) = t.produce_c(producer, None); - code_write = merge_code(t_code); + code_write = merge_code(t_code); writer.write_all(code_write.as_bytes()).map_err(|_| {})?; //code.append(&mut t_code); } - // Epilogue let run_circuit = "void run".to_string(); let run_circuit_args = vec![declare_circom_calc_wit()]; - let main_template_create = if producer.main_is_parallel{ + let main_template_create = if producer.main_is_parallel { producer.main_header.clone() + "_create_parallel" - } else{ + } else { producer.main_header.clone() + "_create" }; // We use 0 to indicate that the main component has no father - let create_args = vec!["1".to_string(), "0".to_string(), CIRCOM_CALC_WIT.to_string(), "\"main\"".to_string(), "0".to_string()]; + let create_args = vec![ + "1".to_string(), + "0".to_string(), + CIRCOM_CALC_WIT.to_string(), + "\"main\"".to_string(), + "0".to_string(), + ]; let create_call = build_call(main_template_create, create_args); // let ctx_index = format!("{} = {};", declare_ctx_index(), create_call); let ctx_index = format!("{};", create_call); // let start_msg = "printf(\"Starting...\\n\");".to_string(); // let end_msg = "printf(\"End\\n\");".to_string(); - let main_template_run = if producer.main_is_parallel{ + let main_template_run = if producer.main_is_parallel { producer.main_header.clone() + "_run_parallel" - } else{ + } else { producer.main_header.clone() + "_run" }; let mut run_args = vec![]; // run_args.push(CTX_INDEX.to_string()); - run_args.push("0".to_string()); + run_args.push("0".to_string()); run_args.push(CIRCOM_CALC_WIT.to_string()); let run_call = format!("{};", build_call(main_template_run, run_args.clone())); let main_run_body = vec![ctx_index, run_call]; - code_write = build_callable(run_circuit, run_circuit_args, main_run_body) + "\n"; + code_write = build_callable(run_circuit, run_circuit_args, main_run_body) + "\n"; writer.write_all(code_write.as_bytes()).map_err(|_| {})?; writer.flush().map_err(|_| {}) - } - } impl Circuit { @@ -574,25 +583,42 @@ impl Circuit { pub fn produce_ir_string_for_function(&self, id: ID) -> String { self.functions[id].to_string() } - pub fn produce_c(&self, c_folder: &str, run_name: &str, c_circuit: &mut W, c_dat: &mut W) -> Result<(), ()> { - use std::path::Path; - let c_folder_path = Path::new(c_folder.clone()).to_path_buf(); + pub fn produce_c( + &self, + c_folder: &str, + run_name: &str, + c_circuit: &mut W, + c_dat: &mut W, + ) -> Result<(), ()> { + use std::path::Path; + let c_folder_path = Path::new(c_folder.clone()).to_path_buf(); c_code_generator::generate_main_cpp_file(&c_folder_path).map_err(|_err| {})?; c_code_generator::generate_circom_hpp_file(&c_folder_path).map_err(|_err| {})?; - c_code_generator::generate_fr_hpp_file(&c_folder_path, &self.c_producer.prime_str).map_err(|_err| {})?; + c_code_generator::generate_fr_hpp_file(&c_folder_path, &self.c_producer.prime_str) + .map_err(|_err| {})?; c_code_generator::generate_calcwit_hpp_file(&c_folder_path).map_err(|_err| {})?; - c_code_generator::generate_fr_cpp_file(&c_folder_path, &self.c_producer.prime_str).map_err(|_err| {})?; + c_code_generator::generate_fr_cpp_file(&c_folder_path, &self.c_producer.prime_str) + .map_err(|_err| {})?; c_code_generator::generate_calcwit_cpp_file(&c_folder_path).map_err(|_err| {})?; - c_code_generator::generate_fr_asm_file(&c_folder_path, &self.c_producer.prime_str).map_err(|_err| {})?; - c_code_generator::generate_make_file(&c_folder_path,run_name,&self.c_producer).map_err(|_err| {})?; + c_code_generator::generate_fr_asm_file(&c_folder_path, &self.c_producer.prime_str) + .map_err(|_err| {})?; + c_code_generator::generate_make_file(&c_folder_path, run_name, &self.c_producer) + .map_err(|_err| {})?; c_code_generator::generate_dat_file(c_dat, &self.c_producer).map_err(|_err| {})?; self.write_c(c_circuit, &self.c_producer) } - pub fn produce_wasm(&self, js_folder: &str, _wasm_name: &str, writer: &mut W) -> Result<(), ()> { - use std::path::Path; - let js_folder_path = Path::new(js_folder.clone()).to_path_buf(); - wasm_code_generator::generate_generate_witness_js_file(&js_folder_path).map_err(|_err| {})?; - wasm_code_generator::generate_witness_calculator_js_file(&js_folder_path).map_err(|_err| {})?; + pub fn produce_wasm( + &self, + js_folder: &str, + _wasm_name: &str, + writer: &mut W, + ) -> Result<(), ()> { + use std::path::Path; + let js_folder_path = Path::new(js_folder.clone()).to_path_buf(); + wasm_code_generator::generate_generate_witness_js_file(&js_folder_path) + .map_err(|_err| {})?; + wasm_code_generator::generate_witness_calculator_js_file(&js_folder_path) + .map_err(|_err| {})?; self.write_wasm(writer, &self.wasm_producer) } } diff --git a/compiler/src/circuit_design/function.rs b/compiler/src/circuit_design/function.rs index 305a000dd..be99efe27 100644 --- a/compiler/src/circuit_design/function.rs +++ b/compiler/src/circuit_design/function.rs @@ -37,7 +37,7 @@ impl WriteWasm for FunctionCodeInfo { instructions.push(funcdef); instructions.push(format!("(param {} i32)", producer.get_result_address_tag())); instructions.push(format!("(param {} i32)", producer.get_result_size_tag())); - instructions.push("(result i32)".to_string()); //state 0 = OK; > 0 error + instructions.push("(result i32)".to_string()); //state 0 = OK; > 0 error instructions.push(format!("(local {} i32)", producer.get_cstack_tag())); instructions.push(format!("(local {} i32)", producer.get_lvar_tag())); instructions.push(format!("(local {} i32)", producer.get_expaux_tag())); @@ -75,14 +75,14 @@ impl WriteWasm for FunctionCodeInfo { instructions.append(&mut reserve_stack_fr_code); //gives value to $cstack if producer.needs_comments() { instructions.push(";; start of the function code".to_string()); - } + } //generate code for t in &self.body { let mut instructions_body = t.produce_wasm(producer); instructions.append(&mut instructions_body); } - instructions.push(set_constant("0")); + instructions.push(set_constant("0")); instructions.push(")".to_string()); instructions } diff --git a/compiler/src/circuit_design/template.rs b/compiler/src/circuit_design/template.rs index 399ca43e8..6d293ab41 100644 --- a/compiler/src/circuit_design/template.rs +++ b/compiler/src/circuit_design/template.rs @@ -16,7 +16,7 @@ pub struct TemplateCodeInfo { pub is_not_parallel_component: bool, pub has_parallel_sub_cmp: bool, pub number_of_inputs: usize, - pub number_of_outputs: usize, + pub number_of_outputs: usize, pub number_of_intermediates: usize, // Not used now pub body: InstructionList, pub var_stack_depth: usize, @@ -78,7 +78,7 @@ impl WriteWasm for TemplateCodeInfo { let funcdef2 = format!("(func ${}_run (type $_t_i32ri32)", self.header); instructions.push(funcdef2); instructions.push(format!(" (param {} i32)", producer.get_offset_tag())); - instructions.push("(result i32)".to_string()); //state 0 = OK; > 0 error + instructions.push("(result i32)".to_string()); //state 0 = OK; > 0 error instructions.push(format!(" (local {} i32)", producer.get_cstack_tag())); instructions.push(format!(" (local {} i32)", producer.get_signal_start_tag())); instructions.push(format!(" (local {} i32)", producer.get_sub_cmp_tag())); @@ -123,7 +123,7 @@ impl WriteWasm for TemplateCodeInfo { instructions.append(&mut reserve_stack_fr_code); if producer.needs_comments() { instructions.push(";; start of the template code".to_string()); - } + } //set signalstart local instructions.push(get_local(producer.get_offset_tag())); instructions @@ -141,7 +141,7 @@ impl WriteWasm for TemplateCodeInfo { //free stack let mut free_stack_code = free_stack(producer); instructions.append(&mut free_stack_code); - instructions.push(set_constant("0")); + instructions.push(set_constant("0")); instructions.push(")".to_string()); instructions } @@ -150,23 +150,25 @@ impl WriteWasm for TemplateCodeInfo { impl WriteC for TemplateCodeInfo { fn produce_c(&self, producer: &CProducer, _parallel: Option) -> (Vec, String) { let mut produced_c = Vec::new(); - if self.is_parallel || self.is_parallel_component{ + if self.is_parallel || self.is_parallel_component { produced_c.append(&mut self.produce_c_parallel_case(producer, true)); } - if !self.is_parallel && self.is_not_parallel_component{ + if !self.is_parallel && self.is_not_parallel_component { produced_c.append(&mut self.produce_c_parallel_case(producer, false)); - } + } (produced_c, "".to_string()) } } - impl TemplateCodeInfo { fn produce_c_parallel_case(&self, producer: &CProducer, parallel: bool) -> Vec { use c_code_generator::*; - let create_header = if parallel {format!("void {}_create_parallel", self.header)} - else{format!("void {}_create", self.header)} ; + let create_header = if parallel { + format!("void {}_create_parallel", self.header) + } else { + format!("void {}_create", self.header) + }; let mut create_params = vec![]; create_params.push(declare_signal_offset()); create_params.push(declare_component_offset()); @@ -178,47 +180,47 @@ impl TemplateCodeInfo { create_body.push(format!( "{}->componentMemory[{}].templateId = {};", CIRCOM_CALC_WIT, - component_offset(), + component_offset(), &self.id.to_string() )); create_body.push(format!( "{}->componentMemory[{}].templateName = \"{}\";", CIRCOM_CALC_WIT, - component_offset(), + component_offset(), &self.name.to_string() )); create_body.push(format!( "{}->componentMemory[{}].signalStart = {};", CIRCOM_CALC_WIT, - component_offset(), - SIGNAL_OFFSET + component_offset(), + SIGNAL_OFFSET )); create_body.push(format!( "{}->componentMemory[{}].inputCounter = {};", CIRCOM_CALC_WIT, - component_offset(), + component_offset(), &self.number_of_inputs.to_string() )); create_body.push(format!( "{}->componentMemory[{}].componentName = {};", CIRCOM_CALC_WIT, - component_offset(), + component_offset(), COMPONENT_NAME )); create_body.push(format!( "{}->componentMemory[{}].idFather = {};", CIRCOM_CALC_WIT, - component_offset(), + component_offset(), COMPONENT_FATHER )); - if self.number_of_components > 0{ + if self.number_of_components > 0 { create_body.push(format!( "{}->componentMemory[{}].subcomponents = new uint[{}]{{0}};", CIRCOM_CALC_WIT, component_offset(), &self.number_of_components.to_string() )); - } else{ + } else { create_body.push(format!( "{}->componentMemory[{}].subcomponents = new uint[{}];", CIRCOM_CALC_WIT, @@ -226,51 +228,54 @@ impl TemplateCodeInfo { &self.number_of_components.to_string() )); } - if self.has_parallel_sub_cmp { + if self.has_parallel_sub_cmp { create_body.push(format!( - "{}->componentMemory[{}].sbct = new std::thread[{}];", - CIRCOM_CALC_WIT, - component_offset(), - &self.number_of_components.to_string() + "{}->componentMemory[{}].sbct = new std::thread[{}];", + CIRCOM_CALC_WIT, + component_offset(), + &self.number_of_components.to_string() )); - create_body.push(format!( - "{}->componentMemory[{}].subcomponentsParallel = new bool[{}];", - CIRCOM_CALC_WIT, - component_offset(), - &self.number_of_components.to_string() - )); - } - if parallel { create_body.push(format!( - "{}->componentMemory[{}].outputIsSet = new bool[{}]();", - CIRCOM_CALC_WIT, - component_offset(), - &self.number_of_outputs.to_string() + "{}->componentMemory[{}].subcomponentsParallel = new bool[{}];", + CIRCOM_CALC_WIT, + component_offset(), + &self.number_of_components.to_string() + )); + } + if parallel { + create_body.push(format!( + "{}->componentMemory[{}].outputIsSet = new bool[{}]();", + CIRCOM_CALC_WIT, + component_offset(), + &self.number_of_outputs.to_string() )); create_body.push(format!( - "{}->componentMemory[{}].mutexes = new std::mutex[{}];", - CIRCOM_CALC_WIT, - component_offset(), - &self.number_of_outputs.to_string() + "{}->componentMemory[{}].mutexes = new std::mutex[{}];", + CIRCOM_CALC_WIT, + component_offset(), + &self.number_of_outputs.to_string() )); create_body.push(format!( - "{}->componentMemory[{}].cvs = new std::condition_variable[{}];", - CIRCOM_CALC_WIT, - component_offset(), - &self.number_of_outputs.to_string() + "{}->componentMemory[{}].cvs = new std::condition_variable[{}];", + CIRCOM_CALC_WIT, + component_offset(), + &self.number_of_outputs.to_string() )); - } - // if has no inputs should be runned - if self.number_of_inputs == 0 { - let cmp_call_name = format!("{}_run", self.header); - let cmp_call_arguments = vec![component_offset(), CIRCOM_CALC_WIT.to_string()]; - create_body.push(format!("{};",build_call(cmp_call_name, cmp_call_arguments))); + } + // if has no inputs should be runned + if self.number_of_inputs == 0 { + let cmp_call_name = format!("{}_run", self.header); + let cmp_call_arguments = vec![component_offset(), CIRCOM_CALC_WIT.to_string()]; + create_body.push(format!("{};", build_call(cmp_call_name, cmp_call_arguments))); } let create_fun = build_callable(create_header, create_params, create_body); - let run_header = if parallel {format!("void {}_run_parallel", self.header)} - else{format!("void {}_run", self.header)} ; + let run_header = if parallel { + format!("void {}_run_parallel", self.header) + } else { + format!("void {}_run", self.header) + }; let mut run_params = vec![]; run_params.push(declare_ctx_index()); run_params.push(declare_circom_calc_wit()); @@ -289,51 +294,74 @@ impl TemplateCodeInfo { run_body.push(format!("{};", declare_lvar(self.var_stack_depth))); run_body.push(format!("{};", declare_sub_component_aux())); run_body.push(format!("{};", declare_index_multiple_eq())); - + for t in &self.body { let (mut instructions_body, _) = t.produce_c(producer, Some(parallel)); run_body.append(&mut instructions_body); } - // parallelism (join at the end of the function) - if self.number_of_components > 0 && self.has_parallel_sub_cmp { + // parallelism (join at the end of the function) + if self.number_of_components > 0 && self.has_parallel_sub_cmp { run_body.push(format!("{{")); - run_body.push(format!("for (uint i = 0; i < {}; i++) {{",&self.number_of_components.to_string())); - run_body.push(format!("if (ctx->componentMemory[ctx_index].sbct[i].joinable()) {{")); - run_body.push(format!("ctx->componentMemory[ctx_index].sbct[i].join();")); - run_body.push(format!("}}")); - run_body.push(format!("}}")); - run_body.push(format!("}}")); - } - if parallel { - // parallelism - // set to true all outputs - run_body.push(format!("for (uint i = 0; i < {}; i++) {{", &self.number_of_outputs.to_string())); - run_body.push(format!("{}->componentMemory[{}].mutexes[i].lock();",CIRCOM_CALC_WIT,CTX_INDEX)); - run_body.push(format!("{}->componentMemory[{}].outputIsSet[i]=true;",CIRCOM_CALC_WIT,CTX_INDEX)); - run_body.push(format!("{}->componentMemory[{}].mutexes[i].unlock();",CIRCOM_CALC_WIT,CTX_INDEX)); - run_body.push(format!("{}->componentMemory[{}].cvs[i].notify_all();",CIRCOM_CALC_WIT,CTX_INDEX)); - run_body.push(format!("}}")); - //parallelism - run_body.push(format!("ctx->numThreadMutex.lock();")); - run_body.push(format!("ctx->numThread--;")); - //run_body.push(format!("printf(\"%i \\n\", ctx->numThread);")); - run_body.push(format!("ctx->numThreadMutex.unlock();")); - run_body.push(format!("ctx->ntcvs.notify_one();")); - } + run_body.push(format!( + "for (uint i = 0; i < {}; i++) {{", + &self.number_of_components.to_string() + )); + run_body.push(format!("if (ctx->componentMemory[ctx_index].sbct[i].joinable()) {{")); + run_body.push(format!("ctx->componentMemory[ctx_index].sbct[i].join();")); + run_body.push(format!("}}")); + run_body.push(format!("}}")); + run_body.push(format!("}}")); + } + if parallel { + // parallelism + // set to true all outputs + run_body.push(format!( + "for (uint i = 0; i < {}; i++) {{", + &self.number_of_outputs.to_string() + )); + run_body.push(format!( + "{}->componentMemory[{}].mutexes[i].lock();", + CIRCOM_CALC_WIT, CTX_INDEX + )); + run_body.push(format!( + "{}->componentMemory[{}].outputIsSet[i]=true;", + CIRCOM_CALC_WIT, CTX_INDEX + )); + run_body.push(format!( + "{}->componentMemory[{}].mutexes[i].unlock();", + CIRCOM_CALC_WIT, CTX_INDEX + )); + run_body.push(format!( + "{}->componentMemory[{}].cvs[i].notify_all();", + CIRCOM_CALC_WIT, CTX_INDEX + )); + run_body.push(format!("}}")); + //parallelism + run_body.push(format!("ctx->numThreadMutex.lock();")); + run_body.push(format!("ctx->numThread--;")); + //run_body.push(format!("printf(\"%i \\n\", ctx->numThread);")); + run_body.push(format!("ctx->numThreadMutex.unlock();")); + run_body.push(format!("ctx->ntcvs.notify_one();")); + } // to release the memory of its subcomponents - run_body.push(format!("for (uint i = 0; i < {}; i++){{", &self.number_of_components.to_string())); + run_body.push(format!( + "for (uint i = 0; i < {}; i++){{", + &self.number_of_components.to_string() + )); run_body.push(format!( "uint index_subc = {}->componentMemory[{}].subcomponents[i];", CIRCOM_CALC_WIT, ctx_index(), )); - run_body.push(format!("if (index_subc != 0){};", + run_body.push(format!( + "if (index_subc != 0){};", build_call( - "release_memory_component".to_string(), + "release_memory_component".to_string(), vec![CIRCOM_CALC_WIT.to_string(), "index_subc".to_string()] - ))); - + ) + )); + run_body.push(format!("}}")); let run_fun = build_callable(run_header, run_params, run_body); vec![create_fun, run_fun] diff --git a/compiler/src/compiler_interface.rs b/compiler/src/compiler_interface.rs index cb84476c8..b3e051f28 100644 --- a/compiler/src/compiler_interface.rs +++ b/compiler/src/compiler_interface.rs @@ -10,7 +10,8 @@ pub struct Config { } pub fn run_compiler(vcp: VCP, config: Config, version: &str) -> Result { - let flags = CompilationFlags { main_inputs_log: config.produce_input_log, wat_flag: config.wat_flag }; + let flags = + CompilationFlags { main_inputs_log: config.produce_input_log, wat_flag: config.wat_flag }; let circuit = Circuit::build(vcp, flags, version); if config.debug_output { produce_debug_output(&circuit)?; @@ -18,7 +19,12 @@ pub fn run_compiler(vcp: VCP, config: Config, version: &str) -> Result Result<(), ()> { +pub fn write_wasm( + circuit: &Circuit, + js_folder: &str, + wasm_name: &str, + file: &str, +) -> Result<(), ()> { use std::path::Path; if Path::new(js_folder).is_dir() { std::fs::remove_dir_all(js_folder).map_err(|_err| {})?; @@ -29,7 +35,13 @@ pub fn write_wasm(circuit: &Circuit, js_folder: &str, wasm_name: &str, file: &st circuit.produce_wasm(js_folder, wasm_name, &mut writer) } -pub fn write_c(circuit: &Circuit, c_folder: &str, c_run_name: &str, c_file: &str, dat_file: &str) -> Result<(), ()> { +pub fn write_c( + circuit: &Circuit, + c_folder: &str, + c_run_name: &str, + c_file: &str, + dat_file: &str, +) -> Result<(), ()> { use std::path::Path; if Path::new(c_folder).is_dir() { std::fs::remove_dir_all(c_folder).map_err(|_err| {})?; diff --git a/compiler/src/hir/component_preprocess.rs b/compiler/src/hir/component_preprocess.rs index 60362f04f..68fe415a2 100644 --- a/compiler/src/hir/component_preprocess.rs +++ b/compiler/src/hir/component_preprocess.rs @@ -16,17 +16,17 @@ fn rm_statement(stmt: &mut Statement) { rm_block(stmt); } else if stmt.is_initialization_block() { rm_init(stmt); - } else if stmt.is_substitution(){ + } else if stmt.is_substitution() { rm_substitution(stmt); - } else if stmt.is_underscore_substitution(){ + } else if stmt.is_underscore_substitution() { rm_underscore_substitution(stmt); } } -fn rm_underscore_substitution(stmt: &mut Statement){ +fn rm_underscore_substitution(stmt: &mut Statement) { use Statement::{Block, UnderscoreSubstitution}; - if let UnderscoreSubstitution { meta, .. } = stmt{ - *stmt = Block{ meta: meta.clone(), stmts: Vec::new() }; + if let UnderscoreSubstitution { meta, .. } = stmt { + *stmt = Block { meta: meta.clone(), stmts: Vec::new() }; } } @@ -75,8 +75,7 @@ fn rm_init(stmt: &mut Statement) { for mut i in work { if i.is_substitution() { initializations.push(i); - } - else if i.is_block(){ + } else if i.is_block() { rm_block(&mut i); initializations.push(i); } @@ -95,11 +94,11 @@ fn rm_init(stmt: &mut Statement) { } } -fn rm_substitution(stmt: &mut Statement){ +fn rm_substitution(stmt: &mut Statement) { use Statement::{Block, Substitution}; - if should_be_removed(stmt){ - if let Substitution { meta, .. } = stmt{ - *stmt = Block{ meta: meta.clone(), stmts: Vec::new() }; + if should_be_removed(stmt) { + if let Substitution { meta, .. } = stmt { + *stmt = Block { meta: meta.clone(), stmts: Vec::new() }; } } } diff --git a/compiler/src/hir/merger.rs b/compiler/src/hir/merger.rs index 4cb428b79..660fc5d4b 100644 --- a/compiler/src/hir/merger.rs +++ b/compiler/src/hir/merger.rs @@ -6,7 +6,6 @@ use program_structure::ast::*; use program_structure::program_archive::ProgramArchive; use num_traits::{ToPrimitive}; - pub fn run_preprocessing(vcp: &mut VCP, program_archive: ProgramArchive) { let mut state = build_function_knowledge(program_archive); produce_vcf(vcp, &mut state); @@ -131,7 +130,7 @@ fn produce_vcf_expr(expr: &Expression, state: &mut State, environment: &E) { produce_vcf_call(expr, state, environment); } else if expr.is_array() { produce_vcf_array(expr, state, environment); - } else if expr.is_parallel(){ + } else if expr.is_parallel() { produce_vcf_parallel(expr, state, environment); } else { unreachable!(); @@ -162,8 +161,8 @@ fn produce_vcf_log_call(stmt: &Statement, state: &mut State, environment: &E) { for arglog in args { if let LogArgument::LogExp(arg) = arglog { produce_vcf_expr(arg, state, environment); - } - else {}// unimplemented!(); } + } else { + } // unimplemented!(); } } } else { unreachable!(); @@ -419,10 +418,10 @@ fn link_log_call(stmt: &mut Statement, state: &State, env: &mut E) { use Statement::LogCall; if let LogCall { args, .. } = stmt { for arglog in args { - if let LogArgument::LogExp(arg) = arglog{ + if let LogArgument::LogExp(arg) = arglog { link_expression(arg, state, env); } - } + } } else { unreachable!(); } @@ -496,7 +495,7 @@ fn link_expression(expr: &mut Expression, state: &State, env: &E) { link_infix(expr, state, env); } else if expr.is_prefix() { link_prefix(expr, state, env); - } else if expr.is_parallel(){ + } else if expr.is_parallel() { link_parallel(expr, state, env); } else { unreachable!(); @@ -637,7 +636,6 @@ fn cast_dimension(ae_index: &Expression) -> Option { } } - fn cast_type_array(expr: &Expression, state: &State, environment: &E) -> VCT { use Expression::{ArrayInLine, UniformArray}; if let ArrayInLine { values, .. } = expr { diff --git a/compiler/src/hir/sugar_cleaner.rs b/compiler/src/hir/sugar_cleaner.rs index 693d58c6b..20bd8aa64 100644 --- a/compiler/src/hir/sugar_cleaner.rs +++ b/compiler/src/hir/sugar_cleaner.rs @@ -2,7 +2,6 @@ use super::very_concrete_program::*; use program_structure::ast::*; use num_traits::{ToPrimitive}; - struct ExtendedSyntax { initializations: Vec, } @@ -62,7 +61,7 @@ fn extend_statement(stmt: &mut Statement, state: &mut State, context: &Context) extend_log_call(stmt, state, context) } else if stmt.is_assert() { extend_assert(stmt, state, context) - } else{ + } else { unreachable!() } } @@ -137,7 +136,7 @@ fn extend_substitution( use Statement::Substitution; if let Substitution { rhe, access, .. } = stmt { let mut expands = extend_expression(rhe, state, context).initializations; - + let mut inits = vec![]; for acc in access { if let Access::ArrayAccess(e) = acc { @@ -223,9 +222,9 @@ fn extend_expression( extend_infix(expr, state, context) } else if expr.is_switch() { extend_switch(expr, state, context) - } else if expr.is_parallel(){ + } else if expr.is_parallel() { extend_parallel(expr, state, context) - }else { + } else { unreachable!() } } @@ -298,37 +297,32 @@ fn extend_infix(expr: &mut Expression, state: &mut State, context: &Context) -> let expr_lhe = expr.pop().unwrap(); // remove when fixed fr in wasm - if *infix_op == Pow{ - match (&expr_rhe, &expr_lhe){ - (Variable{name: name_1, ..}, Variable{name: name_2, ..}) - if name_1 == name_2 =>{ - expr_rhe = Expression::InfixOp{ + if *infix_op == Pow { + match (&expr_rhe, &expr_lhe) { + (Variable { name: name_1, .. }, Variable { name: name_2, .. }) + if name_1 == name_2 => + { + expr_rhe = Expression::InfixOp { meta: rhe.get_meta().clone(), lhe: Box::new(Number(rhe.get_meta().clone(), BigInt::from(0))), rhe: Box::new(expr_rhe), infix_op: Add, }; } - (Number(_, value_1 ), Number(_, value_2)) - if value_1 == value_2 =>{ - expr_rhe = Expression::InfixOp{ + (Number(_, value_1), Number(_, value_2)) if value_1 == value_2 => { + expr_rhe = Expression::InfixOp { meta: rhe.get_meta().clone(), lhe: Box::new(Number(rhe.get_meta().clone(), BigInt::from(0))), rhe: Box::new(expr_rhe), infix_op: Add, }; } - _ =>{ - - } - + _ => {} } - *rhe = Box::new(expr_rhe); - *lhe = Box::new(expr_lhe); - - - } else{ + *rhe = Box::new(expr_rhe); + *lhe = Box::new(expr_lhe); + } else { *rhe = Box::new(expr_rhe); *lhe = Box::new(expr_lhe); } @@ -666,14 +660,12 @@ fn rhe_array_case(stmt: Statement, stmts: &mut Vec) { fn into_single_constraint_equality(stmt: Statement, stmts: &mut Vec) { use Statement::ConstraintEquality; match &stmt { - ConstraintEquality { rhe, lhe, meta, .. } =>{ + ConstraintEquality { rhe, lhe, meta, .. } => { if lhe.is_array() { lhe_array_ce(meta, lhe, rhe, stmts) - } - else if rhe.is_array(){ + } else if rhe.is_array() { lhe_array_ce(meta, rhe, lhe, stmts) - } - else{ + } else { stmts.push(stmt); } } @@ -681,7 +673,12 @@ fn into_single_constraint_equality(stmt: Statement, stmts: &mut Vec) } } -fn lhe_array_ce(meta: &Meta, expr_array: &Expression, other_expr: &Expression, stmts: &mut Vec) { +fn lhe_array_ce( + meta: &Meta, + expr_array: &Expression, + other_expr: &Expression, + stmts: &mut Vec, +) { use num_bigint_dig::BigInt; use Expression::{ArrayInLine, Number, UniformArray, Variable}; use Statement::ConstraintEquality; @@ -695,8 +692,7 @@ fn lhe_array_ce(meta: &Meta, expr_array: &Expression, other_expr: &Expression, s }; stmts.push(ce); } - } - else if let UniformArray {value, ..} = other_expr { + } else if let UniformArray { value, .. } = other_expr { for i in 0..values_l.len() { let ce = ConstraintEquality { lhe: values_l[i].clone(), @@ -705,8 +701,7 @@ fn lhe_array_ce(meta: &Meta, expr_array: &Expression, other_expr: &Expression, s }; stmts.push(ce); } - } - else if let Variable { meta: meta_var, name, access, ..} = other_expr { + } else if let Variable { meta: meta_var, name, access, .. } = other_expr { for i in 0..values_l.len() { let mut index_meta = meta.clone(); index_meta.get_mut_memory_knowledge().set_concrete_dimensions(vec![]); @@ -716,14 +711,17 @@ fn lhe_array_ce(meta: &Meta, expr_array: &Expression, other_expr: &Expression, s accessed_with.push(as_access); let ce = ConstraintEquality { lhe: values_l[i].clone(), - rhe: Variable {name: name.clone(), access: accessed_with, meta: meta_var.clone()}, + rhe: Variable { + name: name.clone(), + access: accessed_with, + meta: meta_var.clone(), + }, meta: meta.clone(), }; stmts.push(ce); } } - } else { unreachable!() } -} \ No newline at end of file +} diff --git a/compiler/src/hir/type_inference.rs b/compiler/src/hir/type_inference.rs index 02b82ee9d..7ba41decd 100644 --- a/compiler/src/hir/type_inference.rs +++ b/compiler/src/hir/type_inference.rs @@ -40,7 +40,7 @@ fn infer_type_stmt(stmt: &Statement, state: &State, context: &mut SearchInfo) -> Option::None } else if stmt.is_assert() { Option::None - } else{ + } else { unreachable!() } } @@ -141,7 +141,7 @@ fn infer_type_expresion(expr: &Expression, state: &State, context: &mut SearchIn Option::Some(VCT::with_capacity(0)) } else if expr.is_prefix() { Option::Some(VCT::with_capacity(0)) - } else if expr.is_parallel(){ + } else if expr.is_parallel() { infer_type_parallel(expr, state, context) } else if expr.is_number() { Option::Some(VCT::with_capacity(0)) diff --git a/compiler/src/hir/very_concrete_program.rs b/compiler/src/hir/very_concrete_program.rs index f6834f9d7..0506b52cc 100644 --- a/compiler/src/hir/very_concrete_program.rs +++ b/compiler/src/hir/very_concrete_program.rs @@ -67,7 +67,7 @@ pub struct Trigger { #[derive(Clone)] pub enum ClusterType { Mixed { tmp_name: String }, - Uniform { offset_jump: usize, component_offset_jump:usize, instance_id: usize, header: String }, + Uniform { offset_jump: usize, component_offset_jump: usize, instance_id: usize, header: String }, } #[derive(Clone)] pub struct TriggerCluster { diff --git a/compiler/src/intermediate_representation/address_type.rs b/compiler/src/intermediate_representation/address_type.rs index ec05b3e90..04773f96e 100644 --- a/compiler/src/intermediate_representation/address_type.rs +++ b/compiler/src/intermediate_representation/address_type.rs @@ -10,14 +10,19 @@ pub enum StatusInput { #[derive(Clone)] pub enum InputInformation { NoInput, - Input {status: StatusInput}, + Input { status: StatusInput }, } #[derive(Clone)] pub enum AddressType { Variable, Signal, - SubcmpSignal { cmp_address: InstructionPointer, uniform_parallel_value: Option, is_output: bool, input_information: InputInformation }, + SubcmpSignal { + cmp_address: InstructionPointer, + uniform_parallel_value: Option, + is_output: bool, + input_information: InputInformation, + }, } impl ToString for AddressType { diff --git a/compiler/src/intermediate_representation/assert_bucket.rs b/compiler/src/intermediate_representation/assert_bucket.rs index 00820d128..8fe4ef060 100644 --- a/compiler/src/intermediate_representation/assert_bucket.rs +++ b/compiler/src/intermediate_representation/assert_bucket.rs @@ -46,7 +46,7 @@ impl WriteWasm for AssertBucket { let mut instructions = vec![]; if producer.needs_comments() { instructions.push(";; assert bucket".to_string()); - } + } let mut instructions_eval = self.evaluate.produce_wasm(producer); instructions.append(&mut instructions_eval); instructions.push(call("$Fr_isTrue")); @@ -61,7 +61,7 @@ impl WriteWasm for AssertBucket { instructions.push(add_end()); if producer.needs_comments() { instructions.push(";; end of assert bucket".to_string()); - } + } instructions } } @@ -71,7 +71,7 @@ impl WriteC for AssertBucket { use c_code_generator::*; let (prologue, value) = self.evaluate.produce_c(producer, parallel); let is_true = build_call("Fr_isTrue".to_string(), vec![value]); - let if_condition = format!("if (!{}) {};", is_true, build_failed_assert_message(self.line)); + let if_condition = format!("if (!{}) {};", is_true, build_failed_assert_message(self.line)); let assertion = format!("{};", build_call("assert".to_string(), vec![is_true])); let mut assert_c = prologue; assert_c.push(if_condition); diff --git a/compiler/src/intermediate_representation/branch_bucket.rs b/compiler/src/intermediate_representation/branch_bucket.rs index 830b361ef..eca09f68b 100644 --- a/compiler/src/intermediate_representation/branch_bucket.rs +++ b/compiler/src/intermediate_representation/branch_bucket.rs @@ -58,7 +58,7 @@ impl WriteWasm for BranchBucket { let mut instructions = vec![]; if producer.needs_comments() { instructions.push(";; branch bucket".to_string()); - } + } if self.if_branch.len() > 0 { let mut instructions_cond = self.cond.produce_wasm(producer); instructions.append(&mut instructions_cond); @@ -75,7 +75,7 @@ impl WriteWasm for BranchBucket { instructions.append(&mut instructions_else); } } - instructions.push(add_end()); + instructions.push(add_end()); } else { if self.else_branch.len() > 0 { let mut instructions_cond = self.cond.produce_wasm(producer); @@ -87,12 +87,12 @@ impl WriteWasm for BranchBucket { let mut instructions_else = ins.produce_wasm(producer); instructions.append(&mut instructions_else); } - instructions.push(add_end()); + instructions.push(add_end()); } } if producer.needs_comments() { instructions.push(";; end of branch bucket".to_string()); - } + } instructions } } diff --git a/compiler/src/intermediate_representation/call_bucket.rs b/compiler/src/intermediate_representation/call_bucket.rs index dbe6fb0ce..96a98c642 100644 --- a/compiler/src/intermediate_representation/call_bucket.rs +++ b/compiler/src/intermediate_representation/call_bucket.rs @@ -54,15 +54,22 @@ impl ToString for CallBucket { fn to_string(&self) -> String { let line = self.line.to_string(); let template_id = self.message_id.to_string(); - let ret = match &self.return_info { - ReturnType::Intermediate { op_aux_no } => {format!("Intermediate({})",op_aux_no.to_string())} - _ => {format!("Final")} - }; + let ret = match &self.return_info { + ReturnType::Intermediate { op_aux_no } => { + format!("Intermediate({})", op_aux_no.to_string()) + } + _ => { + format!("Final") + } + }; let mut args = "".to_string(); for i in &self.arguments { args = format!("{}{},", args, i.to_string()); } - format!("CALL(line:{},template_id:{},id:{},return_type:{},args:{})", line, template_id, self.symbol, ret, args) + format!( + "CALL(line:{},template_id:{},id:{},return_type:{},args:{})", + line, template_id, self.symbol, ret, args + ) } } @@ -72,7 +79,7 @@ impl WriteWasm for CallBucket { let mut instructions = vec![]; if producer.needs_comments() { instructions.push(";; call bucket".to_string()); - } + } if self.arguments.len() > 0 { let local_info_size_u32 = producer.get_local_info_size_u32(); instructions.push(set_constant("0")); @@ -86,9 +93,9 @@ impl WriteWasm for CallBucket { let mut count = 0; let mut i = 0; for p in &self.arguments { - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(format!(";; copying argument {}", i)); - } + } instructions.push(get_local(producer.get_call_lvar_tag())); instructions.push(set_constant(&count.to_string())); instructions.push(add32()); @@ -128,9 +135,9 @@ impl WriteWasm for CallBucket { instructions.push(add_end()); instructions.push(add_end()); } - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(format!(";; end copying argument {}", i)); - } + } count += self.argument_types[i].size * 4 * producer.get_size_32_bits_in_memory(); i += 1; } @@ -142,10 +149,10 @@ impl WriteWasm for CallBucket { instructions.push(add32()); instructions.push(set_constant("1")); instructions.push(call(&format!("${}", self.symbol))); - instructions.push(tee_local(producer.get_merror_tag())); - instructions.push(add_if()); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); instructions.push(call("$printErrorMessage")); - instructions.push(get_local(producer.get_merror_tag())); + instructions.push(get_local(producer.get_merror_tag())); instructions.push(add_return()); instructions.push(add_end()); instructions.push(get_local(producer.get_expaux_tag())); @@ -156,9 +163,9 @@ impl WriteWasm for CallBucket { let mut my_template_header = Option::::None; match &data.dest { LocationRule::Indexed { location, template_header } => { - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; getting result address".to_string()); - } + } let mut instructions_dest = location.produce_wasm(producer); instructions.append(&mut instructions_dest); let size = producer.get_size_32_bits_in_memory() * 4; @@ -198,9 +205,9 @@ impl WriteWasm for CallBucket { LocationRule::Mapped { signal_code, indexes } => { match &data.dest_address_type { AddressType::SubcmpSignal { cmp_address, .. } => { - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; is subcomponent".to_string()); - } + } instructions.push(get_local(producer.get_offset_tag())); instructions.push(set_constant( &producer.get_sub_component_start_in_component().to_string(), @@ -276,20 +283,21 @@ impl WriteWasm for CallBucket { instructions.push(set_constant(&data.context.size.to_string())); instructions.push(call(&format!("${}", self.symbol))); instructions.push(tee_local(producer.get_merror_tag())); - instructions.push(add_if()); + instructions.push(add_if()); instructions.push(set_constant(&self.message_id.to_string())); instructions.push(set_constant(&self.line.to_string())); instructions.push(call("$buildBufferMessage")); instructions.push(call("$printErrorMessage")); - instructions.push(get_local(producer.get_merror_tag())); + instructions.push(get_local(producer.get_merror_tag())); instructions.push(add_return()); instructions.push(add_end()); match &data.dest_address_type { AddressType::SubcmpSignal { .. } => { // if subcomponent input check if run needed - if producer.needs_comments() { - instructions.push(";; decrease counter".to_string()); // by self.context.size - } + if producer.needs_comments() { + instructions.push(";; decrease counter".to_string()); + // by self.context.size + } instructions.push(get_local(producer.get_sub_cmp_tag())); instructions.push(get_local(producer.get_sub_cmp_tag())); instructions.push(load32(Some( @@ -300,18 +308,18 @@ impl WriteWasm for CallBucket { instructions.push(store32(Some( &producer.get_input_counter_address_in_component().to_string(), ))); // update remaining inputs to be set - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; check if run is needed".to_string()); - } + } instructions.push(get_local(producer.get_sub_cmp_tag())); instructions.push(load32(Some( &producer.get_input_counter_address_in_component().to_string(), ))); instructions.push(eqz32()); instructions.push(add_if()); - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; run sub component".to_string()); - } + } instructions.push(get_local(producer.get_sub_cmp_tag())); match &data.dest { LocationRule::Indexed { .. } => { @@ -323,7 +331,7 @@ impl WriteWasm for CallBucket { instructions.push(set_constant(&self.line.to_string())); instructions.push(call("$buildBufferMessage")); instructions.push(call("$printErrorMessage")); - instructions.push(get_local(producer.get_merror_tag())); + instructions.push(get_local(producer.get_merror_tag())); instructions.push(add_return()); instructions.push(add_end()); } else { @@ -343,14 +351,14 @@ impl WriteWasm for CallBucket { instructions.push(set_constant(&self.line.to_string())); instructions.push(call("$buildBufferMessage")); instructions.push(call("$printErrorMessage")); - instructions.push(get_local(producer.get_merror_tag())); + instructions.push(get_local(producer.get_merror_tag())); instructions.push(add_return()); instructions.push(add_end()); } } - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; end run sub component".to_string()); - } + } instructions.push(add_end()); } _ => (), @@ -359,7 +367,7 @@ impl WriteWasm for CallBucket { } if producer.needs_comments() { instructions.push(";; end call bucket".to_string()); - } + } instructions } } @@ -384,12 +392,10 @@ impl WriteC for CallBucket { if self.argument_types[i].size > 1 { let copy_arguments = vec![arena_position, src, self.argument_types[i].size.to_string()]; - prologue - .push(format!("{};", build_call("Fr_copyn".to_string(), copy_arguments))); + prologue.push(format!("{};", build_call("Fr_copyn".to_string(), copy_arguments))); } else { let copy_arguments = vec![arena_position, src]; - prologue - .push(format!("{};", build_call("Fr_copy".to_string(), copy_arguments))); + prologue.push(format!("{};", build_call("Fr_copy".to_string(), copy_arguments))); } prologue.push(format!("// end copying argument {}", i)); count += self.argument_types[i].size; @@ -411,48 +417,69 @@ impl WriteC for CallBucket { } ReturnType::Final(data) => { let cmp_index_ref = "cmp_index_ref".to_string(); - if let AddressType::SubcmpSignal { cmp_address, .. } = &data.dest_address_type { - let (mut cmp_prologue, cmp_index) = cmp_address.produce_c(producer, parallel); - prologue.append(&mut cmp_prologue); - prologue.push(format!("{{")); - prologue.push(format!("uint {} = {};", cmp_index_ref, cmp_index)); - - } + if let AddressType::SubcmpSignal { cmp_address, .. } = &data.dest_address_type { + let (mut cmp_prologue, cmp_index) = cmp_address.produce_c(producer, parallel); + prologue.append(&mut cmp_prologue); + prologue.push(format!("{{")); + prologue.push(format!("uint {} = {};", cmp_index_ref, cmp_index)); + } let ((mut dest_prologue, dest_index), my_template_header) = if let LocationRule::Indexed { location, template_header } = &data.dest { (location.produce_c(producer, parallel), template_header.clone()) - } else if let LocationRule::Mapped { signal_code, indexes } = &data.dest { - let mut map_prologue = vec![]; - let sub_component_pos_in_memory = format!("{}[{}]",MY_SUBCOMPONENTS,cmp_index_ref.clone()); - let mut map_access = format!("{}->{}[{}].defs[{}].offset", - circom_calc_wit(), template_ins_2_io_info(), - template_id_in_component(sub_component_pos_in_memory.clone()), - signal_code.to_string()); - if indexes.len()>0 { - map_prologue.push(format!("{{")); - map_prologue.push(format!("uint map_index_aux[{}];",indexes.len().to_string())); - let (mut index_code_0, mut map_index) = indexes[0].produce_c(producer, parallel); - map_prologue.append(&mut index_code_0); - map_prologue.push(format!("map_index_aux[0]={};",map_index)); - map_index = format!("map_index_aux[0]"); - for i in 1..indexes.len() { - let (mut index_code, index_exp) = indexes[i].produce_c(producer, parallel); - map_prologue.append(&mut index_code); - map_prologue.push(format!("map_index_aux[{}]={};",i.to_string(),index_exp)); - map_index = format!("({})*{}->{}[{}].defs[{}].lengths[{}]+map_index_aux[{}]", - map_index, circom_calc_wit(), template_ins_2_io_info(), - template_id_in_component(sub_component_pos_in_memory.clone()), - signal_code.to_string(),(i-1).to_string(),i.to_string()); - } - map_access = format!("{}+{}",map_access,map_index); - } - ((map_prologue, map_access),Some(template_id_in_component(sub_component_pos_in_memory.clone()))) + } else if let LocationRule::Mapped { signal_code, indexes } = &data.dest { + let mut map_prologue = vec![]; + let sub_component_pos_in_memory = + format!("{}[{}]", MY_SUBCOMPONENTS, cmp_index_ref.clone()); + let mut map_access = format!( + "{}->{}[{}].defs[{}].offset", + circom_calc_wit(), + template_ins_2_io_info(), + template_id_in_component(sub_component_pos_in_memory.clone()), + signal_code.to_string() + ); + if indexes.len() > 0 { + map_prologue.push(format!("{{")); + map_prologue.push(format!( + "uint map_index_aux[{}];", + indexes.len().to_string() + )); + let (mut index_code_0, mut map_index) = + indexes[0].produce_c(producer, parallel); + map_prologue.append(&mut index_code_0); + map_prologue.push(format!("map_index_aux[0]={};", map_index)); + map_index = format!("map_index_aux[0]"); + for i in 1..indexes.len() { + let (mut index_code, index_exp) = + indexes[i].produce_c(producer, parallel); + map_prologue.append(&mut index_code); + map_prologue.push(format!( + "map_index_aux[{}]={};", + i.to_string(), + index_exp + )); + map_index = format!( + "({})*{}->{}[{}].defs[{}].lengths[{}]+map_index_aux[{}]", + map_index, + circom_calc_wit(), + template_ins_2_io_info(), + template_id_in_component(sub_component_pos_in_memory.clone()), + signal_code.to_string(), + (i - 1).to_string(), + i.to_string() + ); + } + map_access = format!("{}+{}", map_access, map_index); + } + ( + (map_prologue, map_access), + Some(template_id_in_component(sub_component_pos_in_memory.clone())), + ) } else { - assert!(false); - ((vec![], "".to_string()),Option::::None) + assert!(false); + ((vec![], "".to_string()), Option::::None) }; - prologue.append(&mut dest_prologue); + prologue.append(&mut dest_prologue); let result_ref = match &data.dest_address_type { AddressType::Variable => { format!("&{}", lvar(dest_index.clone())) @@ -467,178 +494,275 @@ impl WriteC for CallBucket { ); format!( "&{}->signalValues[{} + {}]", - CIRCOM_CALC_WIT, sub_cmp_start, dest_index.clone() + CIRCOM_CALC_WIT, + sub_cmp_start, + dest_index.clone() ) } }; call_arguments.push(result_ref); call_arguments.push(data.context.size.to_string()); prologue.push(format!("{};", build_call(self.symbol.clone(), call_arguments))); - if let LocationRule::Mapped { indexes, .. } = &data.dest { - if indexes.len() > 0 { - prologue.push(format!("}}")); - } - } - // if output and parallel send notify - if let AddressType::Signal = &data.dest_address_type { - if parallel.unwrap() && data.dest_is_output { - if data.context.size > 0 { - prologue.push(format!("{{")); - prologue.push(format!("for (int i = 0; i < {}; i++) {{",data.context.size)); - prologue.push(format!("{}->componentMemory[{}].mutexes[{}+i].lock();",CIRCOM_CALC_WIT,CTX_INDEX,dest_index.clone())); - prologue.push(format!("{}->componentMemory[{}].outputIsSet[{}+i]=true;",CIRCOM_CALC_WIT,CTX_INDEX,dest_index.clone())); - prologue.push(format!("{}->componentMemory[{}].mutexes[{}+i].unlock();",CIRCOM_CALC_WIT,CTX_INDEX,dest_index.clone())); - prologue.push(format!("{}->componentMemory[{}].cvs[{}+i].notify_all();",CIRCOM_CALC_WIT,CTX_INDEX,dest_index.clone())); - prologue.push(format!("}}")); - prologue.push(format!("}}")); - } else { - prologue.push(format!("{}->componentMemory[{}].mutexes[{}].lock();",CIRCOM_CALC_WIT,CTX_INDEX,dest_index.clone())); - prologue.push(format!("{}->componentMemory[{}].outputIsSet[{}]=true;",CIRCOM_CALC_WIT,CTX_INDEX,dest_index.clone())); - prologue.push(format!("{}->componentMemory[{}].mutexes[{}].unlock();",CIRCOM_CALC_WIT,CTX_INDEX,dest_index.clone())); - prologue.push(format!("{}->componentMemory[{}].cvs[{}].notify_all();",CIRCOM_CALC_WIT,CTX_INDEX,dest_index.clone())); - } - } - } + if let LocationRule::Mapped { indexes, .. } = &data.dest { + if indexes.len() > 0 { + prologue.push(format!("}}")); + } + } + // if output and parallel send notify + if let AddressType::Signal = &data.dest_address_type { + if parallel.unwrap() && data.dest_is_output { + if data.context.size > 0 { + prologue.push(format!("{{")); + prologue.push(format!( + "for (int i = 0; i < {}; i++) {{", + data.context.size + )); + prologue.push(format!( + "{}->componentMemory[{}].mutexes[{}+i].lock();", + CIRCOM_CALC_WIT, + CTX_INDEX, + dest_index.clone() + )); + prologue.push(format!( + "{}->componentMemory[{}].outputIsSet[{}+i]=true;", + CIRCOM_CALC_WIT, + CTX_INDEX, + dest_index.clone() + )); + prologue.push(format!( + "{}->componentMemory[{}].mutexes[{}+i].unlock();", + CIRCOM_CALC_WIT, + CTX_INDEX, + dest_index.clone() + )); + prologue.push(format!( + "{}->componentMemory[{}].cvs[{}+i].notify_all();", + CIRCOM_CALC_WIT, + CTX_INDEX, + dest_index.clone() + )); + prologue.push(format!("}}")); + prologue.push(format!("}}")); + } else { + prologue.push(format!( + "{}->componentMemory[{}].mutexes[{}].lock();", + CIRCOM_CALC_WIT, + CTX_INDEX, + dest_index.clone() + )); + prologue.push(format!( + "{}->componentMemory[{}].outputIsSet[{}]=true;", + CIRCOM_CALC_WIT, + CTX_INDEX, + dest_index.clone() + )); + prologue.push(format!( + "{}->componentMemory[{}].mutexes[{}].unlock();", + CIRCOM_CALC_WIT, + CTX_INDEX, + dest_index.clone() + )); + prologue.push(format!( + "{}->componentMemory[{}].cvs[{}].notify_all();", + CIRCOM_CALC_WIT, + CTX_INDEX, + dest_index.clone() + )); + } + } + } // like store update counters and check if Subcomponent needs to be run match &data.dest_address_type { - AddressType::SubcmpSignal { uniform_parallel_value, input_information, .. } => { + AddressType::SubcmpSignal { + uniform_parallel_value, input_information, .. + } => { // if subcomponent input check if run needed let sub_cmp_counter = format!( "{}->componentMemory[{}[{}]].inputCounter", CIRCOM_CALC_WIT, MY_SUBCOMPONENTS, cmp_index_ref ); - let sub_cmp_counter_decrease = format!( - "{} -= {}", - sub_cmp_counter, &data.context.size - ); - if let InputInformation::Input{status} = input_information { - if let StatusInput::NoLast = status { - // no need to run subcomponent - prologue.push("// no need to run sub component".to_string()); - prologue.push(format!("{};", sub_cmp_counter_decrease)); - prologue.push(format!("assert({} > 0);", sub_cmp_counter)); - } else { - let sub_cmp_pos = format!("{}[{}]", MY_SUBCOMPONENTS, cmp_index_ref); - let sub_cmp_call_arguments = - vec![sub_cmp_pos, CIRCOM_CALC_WIT.to_string()]; + let sub_cmp_counter_decrease = + format!("{} -= {}", sub_cmp_counter, &data.context.size); + if let InputInformation::Input { status } = input_information { + if let StatusInput::NoLast = status { + // no need to run subcomponent + prologue.push("// no need to run sub component".to_string()); + prologue.push(format!("{};", sub_cmp_counter_decrease)); + prologue.push(format!("assert({} > 0);", sub_cmp_counter)); + } else { + let sub_cmp_pos = + format!("{}[{}]", MY_SUBCOMPONENTS, cmp_index_ref); + let sub_cmp_call_arguments = + vec![sub_cmp_pos, CIRCOM_CALC_WIT.to_string()]; - // to create the call instruction we need to consider the cases of parallel/not parallel/ known only at execution - if uniform_parallel_value.is_some(){ - // Case parallel - let mut call_instructions = if uniform_parallel_value.unwrap(){ - let sub_cmp_call_name = if let LocationRule::Indexed { .. } = &data.dest { - format!("{}_run_parallel", my_template_header.unwrap()) - } else { - format!("(*{}[{}])", function_table_parallel(), my_template_header.unwrap()) - }; - let mut thread_call_instr = vec![]; - - // parallelism - thread_call_instr.push(format!("{}->componentMemory[{}].sbct[{}] = std::thread({},{});",CIRCOM_CALC_WIT,CTX_INDEX,cmp_index_ref, sub_cmp_call_name, argument_list(sub_cmp_call_arguments))); - thread_call_instr.push(format!("std::unique_lock lkt({}->numThreadMutex);",CIRCOM_CALC_WIT)); - thread_call_instr.push(format!("{}->ntcvs.wait(lkt, [{}]() {{return {}->numThread < {}->maxThread; }});",CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT)); - thread_call_instr.push(format!("ctx->numThread++;")); - //thread_call_instr.push(format!("printf(\"%i \\n\", ctx->numThread);")); - thread_call_instr + // to create the call instruction we need to consider the cases of parallel/not parallel/ known only at execution + if uniform_parallel_value.is_some() { + // Case parallel + let mut call_instructions = if uniform_parallel_value.unwrap() { + let sub_cmp_call_name = if let LocationRule::Indexed { + .. + } = &data.dest + { + format!("{}_run_parallel", my_template_header.unwrap()) + } else { + format!( + "(*{}[{}])", + function_table_parallel(), + my_template_header.unwrap() + ) + }; + let mut thread_call_instr = vec![]; - } - // Case not parallel - else{ - let sub_cmp_call_name = if let LocationRule::Indexed { .. } = &data.dest { - format!("{}_run", my_template_header.unwrap()) - } else { - format!("(*{}[{}])", function_table(), my_template_header.unwrap()) - }; - vec![format!( - "{};", - build_call(sub_cmp_call_name, sub_cmp_call_arguments) - )] - }; - if let StatusInput::Unknown = status { - let sub_cmp_counter_decrease_andcheck = format!("!({})",sub_cmp_counter_decrease); - let if_condition = vec![sub_cmp_counter_decrease_andcheck]; - prologue.push("// run sub component if needed".to_string()); - let else_instructions = vec![]; - prologue.push(build_conditional(if_condition,call_instructions,else_instructions)); - } else { - prologue.push("// need to run sub component".to_string()); - prologue.push(format!("{};", sub_cmp_counter_decrease)); - prologue.push(format!("assert(!({}));", sub_cmp_counter)); - prologue.append(&mut call_instructions); - } - } - // Case we only know if it is parallel at execution - else{ - prologue.push(format!( - "if ({}[{}]){{", - MY_SUBCOMPONENTS_PARALLEL, - cmp_index_ref - )); + // parallelism + thread_call_instr.push(format!("{}->componentMemory[{}].sbct[{}] = std::thread({},{});",CIRCOM_CALC_WIT,CTX_INDEX,cmp_index_ref, sub_cmp_call_name, argument_list(sub_cmp_call_arguments))); + thread_call_instr.push(format!( + "std::unique_lock lkt({}->numThreadMutex);", + CIRCOM_CALC_WIT + )); + thread_call_instr.push(format!("{}->ntcvs.wait(lkt, [{}]() {{return {}->numThread < {}->maxThread; }});",CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT)); + thread_call_instr.push(format!("ctx->numThread++;")); + //thread_call_instr.push(format!("printf(\"%i \\n\", ctx->numThread);")); + thread_call_instr + } + // Case not parallel + else { + let sub_cmp_call_name = + if let LocationRule::Indexed { .. } = &data.dest { + format!("{}_run", my_template_header.unwrap()) + } else { + format!( + "(*{}[{}])", + function_table(), + my_template_header.unwrap() + ) + }; + vec![format!( + "{};", + build_call(sub_cmp_call_name, sub_cmp_call_arguments) + )] + }; + if let StatusInput::Unknown = status { + let sub_cmp_counter_decrease_andcheck = + format!("!({})", sub_cmp_counter_decrease); + let if_condition = vec![sub_cmp_counter_decrease_andcheck]; + prologue.push("// run sub component if needed".to_string()); + let else_instructions = vec![]; + prologue.push(build_conditional( + if_condition, + call_instructions, + else_instructions, + )); + } else { + prologue.push("// need to run sub component".to_string()); + prologue.push(format!("{};", sub_cmp_counter_decrease)); + prologue.push(format!("assert(!({}));", sub_cmp_counter)); + prologue.append(&mut call_instructions); + } + } + // Case we only know if it is parallel at execution + else { + prologue.push(format!( + "if ({}[{}]){{", + MY_SUBCOMPONENTS_PARALLEL, cmp_index_ref + )); - // case parallel - let sub_cmp_call_name = if let LocationRule::Indexed { .. } = &data.dest { - format!("{}_run_parallel", my_template_header.clone().unwrap()) - } else { - format!("(*{}[{}])", function_table_parallel(), my_template_header.clone().unwrap()) - }; - let mut call_instructions = vec![]; - // parallelism - call_instructions.push(format!("{}->componentMemory[{}].sbct[{}] = std::thread({},{});",CIRCOM_CALC_WIT,CTX_INDEX,cmp_index_ref, sub_cmp_call_name, argument_list(sub_cmp_call_arguments.clone()))); - call_instructions.push(format!("std::unique_lock lkt({}->numThreadMutex);",CIRCOM_CALC_WIT)); - call_instructions.push(format!("{}->ntcvs.wait(lkt, [{}]() {{return {}->numThread < {}->maxThread; }});",CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT)); - call_instructions.push(format!("ctx->numThread++;")); - //call_instructions.push(format!("printf(\"%i \\n\", ctx->numThread);")); - if let StatusInput::Unknown = status { - let sub_cmp_counter_decrease_andcheck = format!("!({})",sub_cmp_counter_decrease); - let if_condition = vec![sub_cmp_counter_decrease_andcheck]; - prologue.push("// run sub component if needed".to_string()); - let else_instructions = vec![]; - prologue.push(build_conditional(if_condition,call_instructions,else_instructions)); - } else { - prologue.push("// need to run sub component".to_string()); - prologue.push(format!("{};", sub_cmp_counter_decrease)); - prologue.push(format!("assert(!({}));", sub_cmp_counter)); - prologue.append(&mut call_instructions); - } - // end of case parallel + // case parallel + let sub_cmp_call_name = + if let LocationRule::Indexed { .. } = &data.dest { + format!( + "{}_run_parallel", + my_template_header.clone().unwrap() + ) + } else { + format!( + "(*{}[{}])", + function_table_parallel(), + my_template_header.clone().unwrap() + ) + }; + let mut call_instructions = vec![]; + // parallelism + call_instructions.push(format!( + "{}->componentMemory[{}].sbct[{}] = std::thread({},{});", + CIRCOM_CALC_WIT, + CTX_INDEX, + cmp_index_ref, + sub_cmp_call_name, + argument_list(sub_cmp_call_arguments.clone()) + )); + call_instructions.push(format!( + "std::unique_lock lkt({}->numThreadMutex);", + CIRCOM_CALC_WIT + )); + call_instructions.push(format!("{}->ntcvs.wait(lkt, [{}]() {{return {}->numThread < {}->maxThread; }});",CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT)); + call_instructions.push(format!("ctx->numThread++;")); + //call_instructions.push(format!("printf(\"%i \\n\", ctx->numThread);")); + if let StatusInput::Unknown = status { + let sub_cmp_counter_decrease_andcheck = + format!("!({})", sub_cmp_counter_decrease); + let if_condition = vec![sub_cmp_counter_decrease_andcheck]; + prologue.push("// run sub component if needed".to_string()); + let else_instructions = vec![]; + prologue.push(build_conditional( + if_condition, + call_instructions, + else_instructions, + )); + } else { + prologue.push("// need to run sub component".to_string()); + prologue.push(format!("{};", sub_cmp_counter_decrease)); + prologue.push(format!("assert(!({}));", sub_cmp_counter)); + prologue.append(&mut call_instructions); + } + // end of case parallel - prologue.push(format!("}} else {{")); - - // case not parallel - let sub_cmp_call_name = if let LocationRule::Indexed { .. } = &data.dest { - format!("{}_run", my_template_header.unwrap()) - } else { - format!("(*{}[{}])", function_table(), my_template_header.unwrap()) - }; - let mut call_instructions = vec![format!( - "{};", - build_call(sub_cmp_call_name, sub_cmp_call_arguments) - )]; - if let StatusInput::Unknown = status { - let sub_cmp_counter_decrease_andcheck = format!("!({})",sub_cmp_counter_decrease); - let if_condition = vec![sub_cmp_counter_decrease_andcheck]; - prologue.push("// run sub component if needed".to_string()); - let else_instructions = vec![]; - prologue.push(build_conditional(if_condition,call_instructions,else_instructions)); - } else { - prologue.push("// need to run sub component".to_string()); - prologue.push(format!("{};", sub_cmp_counter_decrease)); - prologue.push(format!("assert(!({}));", sub_cmp_counter)); - prologue.append(&mut call_instructions); - } + prologue.push(format!("}} else {{")); - prologue.push(format!("}}")); - } - } - } else { - assert!(false); - } - } + // case not parallel + let sub_cmp_call_name = + if let LocationRule::Indexed { .. } = &data.dest { + format!("{}_run", my_template_header.unwrap()) + } else { + format!( + "(*{}[{}])", + function_table(), + my_template_header.unwrap() + ) + }; + let mut call_instructions = vec![format!( + "{};", + build_call(sub_cmp_call_name, sub_cmp_call_arguments) + )]; + if let StatusInput::Unknown = status { + let sub_cmp_counter_decrease_andcheck = + format!("!({})", sub_cmp_counter_decrease); + let if_condition = vec![sub_cmp_counter_decrease_andcheck]; + prologue.push("// run sub component if needed".to_string()); + let else_instructions = vec![]; + prologue.push(build_conditional( + if_condition, + call_instructions, + else_instructions, + )); + } else { + prologue.push("// need to run sub component".to_string()); + prologue.push(format!("{};", sub_cmp_counter_decrease)); + prologue.push(format!("assert(!({}));", sub_cmp_counter)); + prologue.append(&mut call_instructions); + } + + prologue.push(format!("}}")); + } + } + } else { + assert!(false); + } + } _ => (), } if let AddressType::SubcmpSignal { .. } = &data.dest_address_type { - prologue.push(format!("}}")); - } + prologue.push(format!("}}")); + } result = "".to_string(); } } diff --git a/compiler/src/intermediate_representation/compute_bucket.rs b/compiler/src/intermediate_representation/compute_bucket.rs index 1f14a1ffa..883ea13f2 100644 --- a/compiler/src/intermediate_representation/compute_bucket.rs +++ b/compiler/src/intermediate_representation/compute_bucket.rs @@ -43,7 +43,7 @@ impl OperatorType { pub fn is_multiple_eq(&self) -> bool { match self { OperatorType::Eq(n) => *n > 1, - _ => false + _ => false, } } } @@ -51,39 +51,39 @@ impl OperatorType { impl ToString for OperatorType { fn to_string(&self) -> String { use OperatorType::*; - if let Eq(n) = self { - format!("EQ({})", n) - } else { - match self { - Mul => "MUL", - Div => "DIV", - Add => "ADD", - Sub => "SUB", - Pow => "POW", - IntDiv => "INT_DIV", - Mod => "MOD", - ShiftL => "SHIFT_L", - ShiftR => "SHIFT_R", - LesserEq => "LESSER_EQ", - GreaterEq => "GREATER_EQ", - Lesser => "LESSER", - Greater => "GREATER", - NotEq => "NOT_EQ", - BoolOr => "BOOL_OR", - BoolAnd => "BOOL_AND", - BitOr => "BITOR", - BitAnd => "BITAND", - BitXor => "BITXOR", - PrefixSub => "PREFIX_SUB", - BoolNot => "BOOL_NOT", - Complement => "COMPLEMENT", - ToAddress => "TO_ADDRESS", - MulAddress => "MUL_ADDRESS", - AddAddress => "ADD_ADDRESS", - _ => "", + if let Eq(n) = self { + format!("EQ({})", n) + } else { + match self { + Mul => "MUL", + Div => "DIV", + Add => "ADD", + Sub => "SUB", + Pow => "POW", + IntDiv => "INT_DIV", + Mod => "MOD", + ShiftL => "SHIFT_L", + ShiftR => "SHIFT_R", + LesserEq => "LESSER_EQ", + GreaterEq => "GREATER_EQ", + Lesser => "LESSER", + Greater => "GREATER", + NotEq => "NOT_EQ", + BoolOr => "BOOL_OR", + BoolAnd => "BOOL_AND", + BitOr => "BITOR", + BitAnd => "BITAND", + BitXor => "BITXOR", + PrefixSub => "PREFIX_SUB", + BoolNot => "BOOL_NOT", + Complement => "COMPLEMENT", + ToAddress => "TO_ADDRESS", + MulAddress => "MUL_ADDRESS", + AddAddress => "ADD_ADDRESS", + _ => "", + } + .to_string() } - .to_string() - } } } @@ -139,7 +139,7 @@ impl WriteWasm for ComputeBucket { let mut instructions = vec![]; if producer.needs_comments() { instructions.push(";; compute bucket".to_string()); - } + } match &self.op { OperatorType::AddAddress => {} OperatorType::MulAddress => {} @@ -158,7 +158,7 @@ impl WriteWasm for ComputeBucket { } if producer.needs_comments() { instructions.push(format!(";; OP({})", self.op.to_string())); - } + } match &self.op { OperatorType::AddAddress => { instructions.push(add32()); @@ -211,13 +211,13 @@ impl WriteWasm for ComputeBucket { instructions.push(call("$Fr_gt")); } OperatorType::Eq(n) => { - assert!(n != 0); - if n == 1 { + assert!(n != 0); + if n == 1 { instructions.push(call("$Fr_eq")); } else { instructions.push(set_local(producer.get_aux_2_tag())); - instructions.push(set_local(producer.get_aux_1_tag())); - instructions.push(set_local(producer.get_aux_0_tag())); + instructions.push(set_local(producer.get_aux_1_tag())); + instructions.push(set_local(producer.get_aux_0_tag())); instructions.push(set_constant(&n.to_string())); instructions.push(set_local(producer.get_counter_tag())); instructions.push(add_block()); @@ -229,7 +229,7 @@ impl WriteWasm for ComputeBucket { instructions.push(get_local(producer.get_aux_0_tag())); instructions.push(call("$Fr_isTrue")); instructions.push(eqz32()); - instructions.push(br_if("1")); + instructions.push(br_if("1")); instructions.push(get_local(producer.get_counter_tag())); instructions.push(set_constant("1")); instructions.push(sub32()); @@ -287,7 +287,7 @@ impl WriteWasm for ComputeBucket { } if producer.needs_comments() { instructions.push(";; end of compute bucket".to_string()); - } + } instructions } } @@ -351,24 +351,34 @@ impl WriteC for ComputeBucket { let mut arguments = vec![result_ref.clone()]; let operands_copy = operands.clone(); arguments.append(&mut operands); - compute_c.push(format!("{}; // line circom {}", build_call(operator.clone(), arguments),self.line.to_string())); + compute_c.push(format!( + "{}; // line circom {}", + build_call(operator.clone(), arguments), + self.line.to_string() + )); if *n > 1 { compute_c.push(format!("{} = 1;", index_multiple_eq())); - compute_c.push(format!("while({} < {} && Fr_isTrue({})) {{", index_multiple_eq(), n, result_ref)); + compute_c.push(format!( + "while({} < {} && Fr_isTrue({})) {{", + index_multiple_eq(), + n, + result_ref + )); operands = vec![]; arguments = vec![result_ref.clone()]; for operand in &operands_copy { operands.push(format!("{} + {}", operand, index_multiple_eq())); } arguments.append(&mut operands); - compute_c.push(format!("{}; // line circom {}", build_call(operator.clone(), arguments),self.line.to_string())); + compute_c.push(format!( + "{}; // line circom {}", + build_call(operator.clone(), arguments), + self.line.to_string() + )); compute_c.push(format!("{}++;", index_multiple_eq())); compute_c.push(format!("}}")); - } result = result_ref; - - } _ => { @@ -378,13 +388,17 @@ impl WriteC for ComputeBucket { let result_ref = format!("&{}", expaux(exp_aux_index.clone())); let mut arguments = vec![result_ref.clone()]; arguments.append(&mut operands); - compute_c.push(format!("{}; // line circom {}", build_call(operator, arguments),self.line.to_string())); + compute_c.push(format!( + "{}; // line circom {}", + build_call(operator, arguments), + self.line.to_string() + )); //value address result = result_ref; } } - //compute_c.push(format!("// end of compute with result {}",result)); + //compute_c.push(format!("// end of compute with result {}",result)); (compute_c, result) } } diff --git a/compiler/src/intermediate_representation/create_component_bucket.rs b/compiler/src/intermediate_representation/create_component_bucket.rs index 28407439b..7fdecde82 100644 --- a/compiler/src/intermediate_representation/create_component_bucket.rs +++ b/compiler/src/intermediate_representation/create_component_bucket.rs @@ -25,7 +25,7 @@ pub struct CreateCmpBucket { pub signal_offset_jump: usize, // component number offset with respect to the father's component id pub component_offset: usize, - pub component_offset_jump:usize, + pub component_offset_jump: usize, pub number_of_cmp: usize, pub has_inputs: bool, } @@ -70,7 +70,7 @@ impl WriteWasm for CreateCmpBucket { let mut instructions = vec![]; if producer.needs_comments() { instructions.push(";; create component bucket".to_string()); - } + } //obtain address of the subcomponent inside the component instructions.push(get_local(producer.get_offset_tag())); instructions @@ -100,15 +100,14 @@ impl WriteWasm for CreateCmpBucket { instructions.push(set_constant(&self.message_id.to_string())); instructions.push(set_constant(&self.line.to_string())); instructions.push(call("$buildBufferMessage")); - instructions.push(call("$printErrorMessage")); - instructions.push(get_local(producer.get_merror_tag())); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); instructions.push(add_return()); instructions.push(add_end()); - } - else { + } else { instructions.push(store32(None)); //store the offset given by create in the subcomponent address } - } else { + } else { instructions.push(set_local(producer.get_create_loop_offset_tag())); if self.number_of_cmp == self.defined_positions.len() { instructions.push(set_constant(&self.number_of_cmp.to_string())); @@ -130,13 +129,12 @@ impl WriteWasm for CreateCmpBucket { instructions.push(set_constant(&self.line.to_string())); instructions.push(call("$buildBufferMessage")); instructions.push(call("$printErrorMessage")); - instructions.push(get_local(producer.get_merror_tag())); + instructions.push(get_local(producer.get_merror_tag())); instructions.push(add_return()); instructions.push(add_end()); - } - else { + } else { instructions.push(store32(None)); //store the offset given by create in the subcomponent address - } + } instructions.push(get_local(producer.get_create_loop_counter_tag())); instructions.push(set_constant("1")); instructions.push(sub32()); @@ -151,7 +149,8 @@ impl WriteWasm for CreateCmpBucket { instructions.push(set_local(producer.get_create_loop_sub_cmp_tag())); // next signal offset instructions.push(get_local(producer.get_create_loop_offset_tag())); - let jump_in_bytes = self.signal_offset_jump * producer.get_size_32_bits_in_memory() * 4; + let jump_in_bytes = + self.signal_offset_jump * producer.get_size_32_bits_in_memory() * 4; instructions.push(set_constant(&jump_in_bytes.to_string())); instructions.push(add32()); instructions.push(set_local(producer.get_create_loop_offset_tag())); @@ -162,27 +161,29 @@ impl WriteWasm for CreateCmpBucket { } else { if self.defined_positions[0].0 != 0 { instructions.push(get_local(producer.get_create_loop_sub_cmp_tag())); //sub_component address in component - let jump = 4*self.defined_positions[0].0; + let jump = 4 * self.defined_positions[0].0; instructions.push(set_constant(&jump.to_string())); instructions.push(add32()); - instructions.push(set_local(producer.get_create_loop_sub_cmp_tag())); //sub_component address in component + instructions.push(set_local(producer.get_create_loop_sub_cmp_tag())); + //sub_component address in component } instructions.push(get_local(producer.get_create_loop_sub_cmp_tag())); //sub_component address in component instructions.push(get_local(producer.get_create_loop_offset_tag())); //sub_component signal address start instructions.push(call(&format!("${}_create", self.symbol))); instructions.push(store32(None)); //store the offset given by create in the subcomponent address - //producer.get_create_loop_sub_cmp_tag() contains the position of last created subcomponent - //producer.get_create_loop_offset_tag() contains the offset of last created subcomponent + //producer.get_create_loop_sub_cmp_tag() contains the position of last created subcomponent + //producer.get_create_loop_offset_tag() contains the offset of last created subcomponent for i in 1..self.defined_positions.len() { instructions.push(get_local(producer.get_create_loop_sub_cmp_tag())); - let jump = 4*(self.defined_positions[i].0-self.defined_positions[i-1].0); + let jump = 4 * (self.defined_positions[i].0 - self.defined_positions[i - 1].0); instructions.push(set_constant(&jump.to_string())); instructions.push(add32()); instructions.push(set_local(producer.get_create_loop_sub_cmp_tag())); // next signal offset instructions.push(get_local(producer.get_create_loop_offset_tag())); - let jump_in_bytes = self.signal_offset_jump * producer.get_size_32_bits_in_memory() * 4; + let jump_in_bytes = + self.signal_offset_jump * producer.get_size_32_bits_in_memory() * 4; instructions.push(set_constant(&jump_in_bytes.to_string())); instructions.push(add32()); instructions.push(set_local(producer.get_create_loop_offset_tag())); @@ -196,7 +197,7 @@ impl WriteWasm for CreateCmpBucket { } if producer.needs_comments() { instructions.push(";; end create component bucket".to_string()); - } + } instructions } } @@ -212,14 +213,23 @@ impl WriteC for CreateCmpBucket { instructions.push("{".to_string()); instructions.push(format!("uint aux_create = {};", scmp_idx)); instructions.push(format!("int aux_cmp_num = {}+{}+1;", self.component_offset, CTX_INDEX)); - instructions.push(format!("uint csoffset = {}+{};", MY_SIGNAL_START.to_string(), self.signal_offset)); - if self.number_of_cmp > 1{ - instructions.push(format!("uint aux_dimensions[{}] = {};", self.dimensions.len(), set_list(self.dimensions.clone()))); + instructions.push(format!( + "uint csoffset = {}+{};", + MY_SIGNAL_START.to_string(), + self.signal_offset + )); + if self.number_of_cmp > 1 { + instructions.push(format!( + "uint aux_dimensions[{}] = {};", + self.dimensions.len(), + set_list(self.dimensions.clone()) + )); } // if the array is not uniform with respect to parallelism - if self.uniform_parallel.is_none(){ - instructions.push(format!("bool aux_parallel[{}] = {};", - self.number_of_cmp, + if self.uniform_parallel.is_none() { + instructions.push(format!( + "bool aux_parallel[{}] = {};", + self.number_of_cmp, set_list_bool(self.defined_positions.iter().map(|(_x, y)| *y).collect()), )); } @@ -227,79 +237,92 @@ impl WriteC for CreateCmpBucket { if complete_array { instructions.push(format!("for (uint i = 0; i < {}; i++) {{", self.number_of_cmp)); // update the value of the the paralel status if it is not uniform parallel using the array aux_parallel - if self.uniform_parallel.is_none(){ + if self.uniform_parallel.is_none() { instructions.push(format!("bool status_parallel = aux_parallel[i];")); } } // generate array with the positions that are actually created if there are empty components // if not only traverse the defined positions, but i gets the value of the indexed accesed position - else{ - instructions.push(format!("uint aux_positions [{}]= {};", self.defined_positions.len(), set_list(self.defined_positions.iter().map(|(x, _y)| *x).collect()))); - instructions.push(format!("for (uint i_aux = 0; i_aux < {}; i_aux++) {{", self.defined_positions.len())); + else { + instructions.push(format!( + "uint aux_positions [{}]= {};", + self.defined_positions.len(), + set_list(self.defined_positions.iter().map(|(x, _y)| *x).collect()) + )); + instructions.push(format!( + "for (uint i_aux = 0; i_aux < {}; i_aux++) {{", + self.defined_positions.len() + )); instructions.push(format!("uint i = aux_positions[i_aux];")); // update the value of the the paralel status if it is not uniform parallel using the array aux_parallel - if self.uniform_parallel.is_none(){ + if self.uniform_parallel.is_none() { instructions.push(format!("bool status_parallel = aux_parallel[i_aux];")); } } - if self.number_of_cmp > 1{ - instructions.push( - format!("std::string new_cmp_name = \"{}\"+{};", - self.name_subcomponent.to_string(), - generate_my_array_position("aux_dimensions".to_string(), self.dimensions.len().to_string(), "i".to_string()) + if self.number_of_cmp > 1 { + instructions.push(format!( + "std::string new_cmp_name = \"{}\"+{};", + self.name_subcomponent.to_string(), + generate_my_array_position( + "aux_dimensions".to_string(), + self.dimensions.len().to_string(), + "i".to_string() ) - ); - } - else { - instructions.push(format!("std::string new_cmp_name = \"{}\";", self.name_subcomponent.to_string())); + )); + } else { + instructions.push(format!( + "std::string new_cmp_name = \"{}\";", + self.name_subcomponent.to_string() + )); } let create_args = vec![ - "csoffset".to_string(), - "aux_cmp_num".to_string(), - CIRCOM_CALC_WIT.to_string(), + "csoffset".to_string(), + "aux_cmp_num".to_string(), + CIRCOM_CALC_WIT.to_string(), "new_cmp_name".to_string(), - MY_ID.to_string() + MY_ID.to_string(), ]; // if it is not uniform parallel check the value of status parallel to create the component - if self.uniform_parallel.is_none(){ - instructions.push(format!("{}[aux_create+i] = status_parallel;", MY_SUBCOMPONENTS_PARALLEL)); + if self.uniform_parallel.is_none() { + instructions + .push(format!("{}[aux_create+i] = status_parallel;", MY_SUBCOMPONENTS_PARALLEL)); instructions.push(format!( - "if (status_parallel) {}_create_parallel({});", - self.symbol, + "if (status_parallel) {}_create_parallel({});", + self.symbol, argument_list(create_args.clone()) )); instructions.push(format!( - "else {}_create({});", - self.symbol, + "else {}_create({});", + self.symbol, argument_list(create_args) )); } // if it is uniform parallel we can know if it is parallel or not at compile time - else{ - if self.is_part_mixed_array_not_uniform_parallel{ + else { + if self.is_part_mixed_array_not_uniform_parallel { instructions.push(format!( "{}[aux_create+i] = {};", - MY_SUBCOMPONENTS_PARALLEL, + MY_SUBCOMPONENTS_PARALLEL, self.uniform_parallel.unwrap() )); } - let sub_cmp_template_create = if self.uniform_parallel.unwrap() { + let sub_cmp_template_create = if self.uniform_parallel.unwrap() { format!("{}_create_parallel", self.symbol) - }else { + } else { format!("{}_create", self.symbol) }; let create_call = build_call(sub_cmp_template_create, create_args); instructions.push(format!("{};", create_call)); } - instructions.push(format!("{}[aux_create+i] = aux_cmp_num;", MY_SUBCOMPONENTS)); + instructions.push(format!("{}[aux_create+i] = aux_cmp_num;", MY_SUBCOMPONENTS)); instructions.push(format!("csoffset += {} ;", self.signal_offset_jump)); - instructions.push(format!("aux_cmp_num += {};",self.component_offset_jump)); + instructions.push(format!("aux_cmp_num += {};", self.component_offset_jump)); instructions.push("}".to_string()); instructions.push("}".to_string()); (instructions, "".to_string()) } -} \ No newline at end of file +} diff --git a/compiler/src/intermediate_representation/ir_interface.rs b/compiler/src/intermediate_representation/ir_interface.rs index 5dc9fc33d..37bc873a4 100644 --- a/compiler/src/intermediate_representation/ir_interface.rs +++ b/compiler/src/intermediate_representation/ir_interface.rs @@ -98,10 +98,9 @@ impl CheckCompute for Instruction { fn has_compute_in(&self) -> bool { use Instruction::*; match self { - Load(_v) => {true - }, - Compute(_) => true, - _ => false, + Load(_v) => true, + Compute(_) => true, + _ => false, } } } diff --git a/compiler/src/intermediate_representation/load_bucket.rs b/compiler/src/intermediate_representation/load_bucket.rs index 18001e331..0cf3e8f62 100644 --- a/compiler/src/intermediate_representation/load_bucket.rs +++ b/compiler/src/intermediate_representation/load_bucket.rs @@ -51,7 +51,7 @@ impl WriteWasm for LoadBucket { let mut instructions = vec![]; if producer.needs_comments() { instructions.push(";; load bucket".to_string()); - } + } match &self.src { LocationRule::Indexed { location, .. } => { let mut instructions_src = location.produce_wasm(producer); @@ -67,9 +67,9 @@ impl WriteWasm for LoadBucket { instructions.push(get_local(producer.get_signal_start_tag()).to_string()); } AddressType::SubcmpSignal { cmp_address, .. } => { - if producer.needs_comments() { - instructions.push(";; is subcomponent".to_string()); - } + if producer.needs_comments() { + instructions.push(";; is subcomponent".to_string()); + } instructions.push(get_local(producer.get_offset_tag())); instructions.push(set_constant( &producer.get_sub_component_start_in_component().to_string(), @@ -89,16 +89,16 @@ impl WriteWasm for LoadBucket { } } instructions.push(add32()); - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; end of load bucket".to_string()); - } + } } LocationRule::Mapped { signal_code, indexes } => { match &self.address_type { AddressType::SubcmpSignal { cmp_address, .. } => { - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; is subcomponent".to_string()); - } + } instructions.push(get_local(producer.get_offset_tag())); instructions.push(set_constant( &producer.get_sub_component_start_in_component().to_string(), @@ -160,9 +160,9 @@ impl WriteWasm for LoadBucket { instructions.push(add32()); instructions.push(load32(None)); //subcomponent start_of_signals instructions.push(add32()); // we get the position of the signal (with indexes) in memory - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; end of load bucket".to_string()); - } + } } _ => { assert!(false); @@ -178,44 +178,55 @@ impl WriteC for LoadBucket { fn produce_c(&self, producer: &CProducer, parallel: Option) -> (Vec, String) { use c_code_generator::*; let mut prologue = vec![]; - //prologue.push(format!("// start of load line {} bucket {}",self.line.to_string(),self.to_string())); - let cmp_index_ref; + //prologue.push(format!("// start of load line {} bucket {}",self.line.to_string(),self.to_string())); + let cmp_index_ref; if let AddressType::SubcmpSignal { cmp_address, .. } = &self.address_type { let (mut cmp_prologue, cmp_index) = cmp_address.produce_c(producer, parallel); prologue.append(&mut cmp_prologue); - cmp_index_ref = cmp_index; - } else { + cmp_index_ref = cmp_index; + } else { cmp_index_ref = "".to_string(); - } + } - let (mut src_prologue, src_index) = - if let LocationRule::Indexed { location, .. } = &self.src { - location.produce_c(producer, parallel) - } else if let LocationRule::Mapped { signal_code, indexes } = &self.src { - let mut map_prologue = vec![]; - let sub_component_pos_in_memory = format!("{}[{}]",MY_SUBCOMPONENTS,cmp_index_ref.clone()); - let mut map_access = format!("{}->{}[{}].defs[{}].offset", - circom_calc_wit(), template_ins_2_io_info(), - template_id_in_component(sub_component_pos_in_memory.clone()), - signal_code.to_string()); - if indexes.len()>0 { - let (mut index_code_0, mut map_index) = indexes[0].produce_c(producer, parallel); - map_prologue.append(&mut index_code_0); - for i in 1..indexes.len() { - let (mut index_code, index_exp) = indexes[i].produce_c(producer, parallel); - map_prologue.append(&mut index_code); - map_index = format!("({})*{}->{}[{}].defs[{}].lengths[{}]+{}", - map_index, circom_calc_wit(), template_ins_2_io_info(), - template_id_in_component(sub_component_pos_in_memory.clone()), - signal_code.to_string(), (i-1).to_string(),index_exp); - } - map_access = format!("{}+{}",map_access,map_index); - } - (map_prologue, map_access) - } else { - assert!(false); - (vec![], "".to_string()) - }; + let (mut src_prologue, src_index) = if let LocationRule::Indexed { location, .. } = + &self.src + { + location.produce_c(producer, parallel) + } else if let LocationRule::Mapped { signal_code, indexes } = &self.src { + let mut map_prologue = vec![]; + let sub_component_pos_in_memory = + format!("{}[{}]", MY_SUBCOMPONENTS, cmp_index_ref.clone()); + let mut map_access = format!( + "{}->{}[{}].defs[{}].offset", + circom_calc_wit(), + template_ins_2_io_info(), + template_id_in_component(sub_component_pos_in_memory.clone()), + signal_code.to_string() + ); + if indexes.len() > 0 { + let (mut index_code_0, mut map_index) = indexes[0].produce_c(producer, parallel); + map_prologue.append(&mut index_code_0); + for i in 1..indexes.len() { + let (mut index_code, index_exp) = indexes[i].produce_c(producer, parallel); + map_prologue.append(&mut index_code); + map_index = format!( + "({})*{}->{}[{}].defs[{}].lengths[{}]+{}", + map_index, + circom_calc_wit(), + template_ins_2_io_info(), + template_id_in_component(sub_component_pos_in_memory.clone()), + signal_code.to_string(), + (i - 1).to_string(), + index_exp + ); + } + map_access = format!("{}+{}", map_access, map_index); + } + (map_prologue, map_access) + } else { + assert!(false); + (vec![], "".to_string()) + }; prologue.append(&mut src_prologue); let access = match &self.address_type { AddressType::Variable => { @@ -225,85 +236,94 @@ impl WriteC for LoadBucket { format!("&{}", signal_values(src_index)) } AddressType::SubcmpSignal { uniform_parallel_value, is_output, .. } => { - if *is_output { - if uniform_parallel_value.is_some(){ - if uniform_parallel_value.unwrap(){ - prologue.push(format!("{{")); - prologue.push(format!("int aux1 = {};",cmp_index_ref.clone())); - prologue.push(format!("int aux2 = {};",src_index.clone())); - // check each one of the outputs of the assignment, we add i to check them one by one - prologue.push(format!("for (int i = 0; i < {}; i++) {{",self.context.size)); - prologue.push(format!("ctx->numThreadMutex.lock();")); - prologue.push(format!("ctx->numThread--;")); - //prologue.push(format!("printf(\"%i \\n\", ctx->numThread);")); - prologue.push(format!("ctx->numThreadMutex.unlock();")); - prologue.push(format!("ctx->ntcvs.notify_one();")); - prologue.push(format!( + if *is_output { + if uniform_parallel_value.is_some() { + if uniform_parallel_value.unwrap() { + prologue.push(format!("{{")); + prologue.push(format!("int aux1 = {};", cmp_index_ref.clone())); + prologue.push(format!("int aux2 = {};", src_index.clone())); + // check each one of the outputs of the assignment, we add i to check them one by one + prologue.push(format!( + "for (int i = 0; i < {}; i++) {{", + self.context.size + )); + prologue.push(format!("ctx->numThreadMutex.lock();")); + prologue.push(format!("ctx->numThread--;")); + //prologue.push(format!("printf(\"%i \\n\", ctx->numThread);")); + prologue.push(format!("ctx->numThreadMutex.unlock();")); + prologue.push(format!("ctx->ntcvs.notify_one();")); + prologue.push(format!( "std::unique_lock lk({}->componentMemory[{}[aux1]].mutexes[aux2 + i]);", CIRCOM_CALC_WIT, MY_SUBCOMPONENTS) ); - prologue.push(format!( + prologue.push(format!( "{}->componentMemory[{}[aux1]].cvs[aux2 + i].wait(lk, [{},{},aux1,aux2, i]() {{return {}->componentMemory[{}[aux1]].outputIsSet[aux2 + i];}});", CIRCOM_CALC_WIT, MY_SUBCOMPONENTS, CIRCOM_CALC_WIT, MY_SUBCOMPONENTS, CIRCOM_CALC_WIT, MY_SUBCOMPONENTS) ); - prologue.push(format!("std::unique_lock lkt({}->numThreadMutex);",CIRCOM_CALC_WIT)); - prologue.push(format!("{}->ntcvs.wait(lkt, [{}]() {{return {}->numThread < {}->maxThread; }});",CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT)); - prologue.push(format!("ctx->numThread++;")); - //prologue.push(format!("printf(\"%i \\n\", ctx->numThread);")); - prologue.push(format!("}}")); - prologue.push(format!("}}")); - } - } - // Case we only know if it is parallel at execution - else{ - prologue.push(format!( - "if ({}[{}]){{", - MY_SUBCOMPONENTS_PARALLEL, - cmp_index_ref - )); + prologue.push(format!( + "std::unique_lock lkt({}->numThreadMutex);", + CIRCOM_CALC_WIT + )); + prologue.push(format!("{}->ntcvs.wait(lkt, [{}]() {{return {}->numThread < {}->maxThread; }});",CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT)); + prologue.push(format!("ctx->numThread++;")); + //prologue.push(format!("printf(\"%i \\n\", ctx->numThread);")); + prologue.push(format!("}}")); + prologue.push(format!("}}")); + } + } + // Case we only know if it is parallel at execution + else { + prologue.push(format!( + "if ({}[{}]){{", + MY_SUBCOMPONENTS_PARALLEL, cmp_index_ref + )); - // case parallel - prologue.push(format!("{{")); - prologue.push(format!("int aux1 = {};",cmp_index_ref.clone())); - prologue.push(format!("int aux2 = {};",src_index.clone())); - // check each one of the outputs of the assignment, we add i to check them one by one - prologue.push(format!("for (int i = 0; i < {}; i++) {{",self.context.size)); - prologue.push(format!("ctx->numThreadMutex.lock();")); - prologue.push(format!("ctx->numThread--;")); - //prologue.push(format!("printf(\"%i \\n\", ctx->numThread);")); - prologue.push(format!("ctx->numThreadMutex.unlock();")); - prologue.push(format!("ctx->ntcvs.notify_one();")); - prologue.push(format!( + // case parallel + prologue.push(format!("{{")); + prologue.push(format!("int aux1 = {};", cmp_index_ref.clone())); + prologue.push(format!("int aux2 = {};", src_index.clone())); + // check each one of the outputs of the assignment, we add i to check them one by one + prologue + .push(format!("for (int i = 0; i < {}; i++) {{", self.context.size)); + prologue.push(format!("ctx->numThreadMutex.lock();")); + prologue.push(format!("ctx->numThread--;")); + //prologue.push(format!("printf(\"%i \\n\", ctx->numThread);")); + prologue.push(format!("ctx->numThreadMutex.unlock();")); + prologue.push(format!("ctx->ntcvs.notify_one();")); + prologue.push(format!( "std::unique_lock lk({}->componentMemory[{}[aux1]].mutexes[aux2 + i]);", CIRCOM_CALC_WIT, MY_SUBCOMPONENTS) ); - prologue.push(format!( + prologue.push(format!( "{}->componentMemory[{}[aux1]].cvs[aux2 + i].wait(lk, [{},{},aux1,aux2, i]() {{return {}->componentMemory[{}[aux1]].outputIsSet[aux2 + i];}});", CIRCOM_CALC_WIT, MY_SUBCOMPONENTS, CIRCOM_CALC_WIT, MY_SUBCOMPONENTS, CIRCOM_CALC_WIT, MY_SUBCOMPONENTS) ); - prologue.push(format!("std::unique_lock lkt({}->numThreadMutex);",CIRCOM_CALC_WIT)); - prologue.push(format!("{}->ntcvs.wait(lkt, [{}]() {{return {}->numThread < {}->maxThread; }});",CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT)); - prologue.push(format!("ctx->numThread++;")); - //prologue.push(format!("printf(\"%i \\n\", ctx->numThread);")); - prologue.push(format!("}}")); - prologue.push(format!("}}")); - - // end of case parallel, in case no parallel we do nothing + prologue.push(format!( + "std::unique_lock lkt({}->numThreadMutex);", + CIRCOM_CALC_WIT + )); + prologue.push(format!("{}->ntcvs.wait(lkt, [{}]() {{return {}->numThread < {}->maxThread; }});",CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT)); + prologue.push(format!("ctx->numThread++;")); + //prologue.push(format!("printf(\"%i \\n\", ctx->numThread);")); + prologue.push(format!("}}")); + prologue.push(format!("}}")); - prologue.push(format!("}}")); - } - } + // end of case parallel, in case no parallel we do nothing + + prologue.push(format!("}}")); + } + } let sub_cmp_start = format!( "{}->componentMemory[{}[{}]].signalStart", CIRCOM_CALC_WIT, MY_SUBCOMPONENTS, cmp_index_ref ); - + format!("&{}->signalValues[{} + {}]", CIRCOM_CALC_WIT, sub_cmp_start, src_index) } }; - //prologue.push(format!("// end of load line {} with access {}",self.line.to_string(),access)); + //prologue.push(format!("// end of load line {} with access {}",self.line.to_string(),access)); (prologue, access) } } diff --git a/compiler/src/intermediate_representation/log_bucket.rs b/compiler/src/intermediate_representation/log_bucket.rs index 30044146e..6bbfa8085 100644 --- a/compiler/src/intermediate_representation/log_bucket.rs +++ b/compiler/src/intermediate_representation/log_bucket.rs @@ -3,22 +3,20 @@ use crate::translating_traits::*; use code_producers::c_elements::*; use code_producers::wasm_elements::*; - #[derive(Clone)] pub enum LogBucketArg { LogExp(InstructionPointer), - LogStr(usize) + LogStr(usize), } -impl LogBucketArg{ - pub fn get_mut_arg_logexp(&mut self)-> &mut InstructionPointer{ - match self{ +impl LogBucketArg { + pub fn get_mut_arg_logexp(&mut self) -> &mut InstructionPointer { + match self { LogBucketArg::LogExp(arg) => arg, LogBucketArg::LogStr(_) => unreachable!(), } } } - #[derive(Clone)] pub struct LogBucket { pub line: usize, @@ -55,7 +53,8 @@ impl ToString for LogBucket { for print in self.argsprint.clone() { if let LogBucketArg::LogExp(exp) = print { let print = exp.to_string(); - let log = format!("LOG(line: {},template_id: {},evaluate: {})", line, template_id, print); + let log = + format!("LOG(line: {},template_id: {},evaluate: {})", line, template_id, print); ret = ret + &log; } } @@ -69,35 +68,36 @@ impl WriteWasm for LogBucket { let mut instructions = vec![]; if producer.needs_comments() { instructions.push(";; log bucket".to_string()); - } + } for logarg in self.argsprint.clone() { - match &logarg { + match &logarg { LogBucketArg::LogExp(exp) => { let mut instructions_print = exp.produce_wasm(producer); instructions.append(&mut instructions_print); instructions.push(call("$copyFr2SharedRWMemory")); instructions.push(call("$showSharedRWMemory")); - } - LogBucketArg::LogStr(stringid) => { - let pos = producer.get_string_list_start() + - stringid * producer.get_size_of_message_in_bytes(); + } + LogBucketArg::LogStr(stringid) => { + let pos = producer.get_string_list_start() + + stringid * producer.get_size_of_message_in_bytes(); instructions.push(set_constant(&pos.to_string())); instructions.push(call("$buildLogMessage")); - instructions.push(call("$writeBufferMessage")); - } + instructions.push(call("$writeBufferMessage")); + } } - } - // add nl + } + // add nl instructions.push(set_constant(&producer.get_message_buffer_start().to_string())); instructions.push(set_constant("0x0000000a")); - instructions.push(store32(None)); // stores \n000 - instructions.push(set_constant(&producer.get_message_buffer_counter_position().to_string())); + instructions.push(store32(None)); // stores \n000 + instructions + .push(set_constant(&producer.get_message_buffer_counter_position().to_string())); instructions.push(set_constant("0")); instructions.push(store32(None)); instructions.push(call("$writeBufferMessage")); if producer.needs_comments() { instructions.push(";; end of log bucket".to_string()); - } + } instructions } } @@ -110,7 +110,8 @@ impl WriteC for LogBucket { for logarg in &self.argsprint { if let LogBucketArg::LogExp(exp) = logarg { let (mut argument_code, argument_result) = exp.produce_c(producer, parallel); - let to_string_call = build_call("Fr_element2str".to_string(), vec![argument_result]); + let to_string_call = + build_call("Fr_element2str".to_string(), vec![argument_result]); let temp_var = "temp".to_string(); let into_temp = format!("char* temp = {}", to_string_call); let print_c = @@ -122,38 +123,26 @@ impl WriteC for LogBucket { log_c.push(format!("{};", print_c)); log_c.push(format!("{};", delete_temp)); log_c.push("}".to_string()); - } - else if let LogBucketArg::LogStr(string_id) = logarg { + } else if let LogBucketArg::LogStr(string_id) = logarg { let string_value = &producer.get_string_table()[*string_id]; let print_c = - build_call( - "printf".to_string(), - vec![format!("\"{}\"", string_value)] - ); + build_call("printf".to_string(), vec![format!("\"{}\"", string_value)]); log_c.push("{".to_string()); log_c.push(format!("{};", print_c)); log_c.push("}".to_string()); - } - else{ + } else { unreachable!(); } - if index != self.argsprint.len() - 1 { - let print_c = - build_call( - "printf".to_string(), - vec![format!("\" \"")] - ); + if index != self.argsprint.len() - 1 { + let print_c = build_call("printf".to_string(), vec![format!("\" \"")]); log_c.push("{".to_string()); log_c.push(format!("{};", print_c)); log_c.push("}".to_string()); } index += 1; } - let print_end_line = build_call( - "printf".to_string(), - vec![format!("\"\\n\"")] - ); + let print_end_line = build_call("printf".to_string(), vec![format!("\"\\n\"")]); log_c.push("{".to_string()); log_c.push(format!("{};", print_end_line)); log_c.push("}".to_string()); diff --git a/compiler/src/intermediate_representation/loop_bucket.rs b/compiler/src/intermediate_representation/loop_bucket.rs index 7dd30b54c..951e1eae8 100644 --- a/compiler/src/intermediate_representation/loop_bucket.rs +++ b/compiler/src/intermediate_representation/loop_bucket.rs @@ -51,7 +51,7 @@ impl WriteWasm for LoopBucket { let mut instructions = vec![]; if producer.needs_comments() { instructions.push(format!(";; loop bucket. Line {}", self.line)); //.to_string() - } + } instructions.push(add_block()); instructions.push(add_loop()); let mut instructions_continue = self.continue_condition.produce_wasm(producer); @@ -68,7 +68,7 @@ impl WriteWasm for LoopBucket { instructions.push(add_end()); if producer.needs_comments() { instructions.push(";; end of loop bucket".to_string()); - } + } instructions } } @@ -76,7 +76,8 @@ impl WriteWasm for LoopBucket { impl WriteC for LoopBucket { fn produce_c(&self, producer: &CProducer, parallel: Option) -> (Vec, String) { use c_code_generator::merge_code; - let (continue_code, continue_result) = self.continue_condition.produce_c(producer, parallel); + let (continue_code, continue_result) = + self.continue_condition.produce_c(producer, parallel); let continue_result = format!("Fr_isTrue({})", continue_result); let mut body = vec![]; for instr in &self.body { diff --git a/compiler/src/intermediate_representation/return_bucket.rs b/compiler/src/intermediate_representation/return_bucket.rs index b4b541e41..2b236f790 100644 --- a/compiler/src/intermediate_representation/return_bucket.rs +++ b/compiler/src/intermediate_representation/return_bucket.rs @@ -47,7 +47,7 @@ impl WriteWasm for ReturnBucket { let mut instructions = vec![]; if producer.needs_comments() { instructions.push(";; return bucket".to_string()); - } + } if self.with_size == 1 { instructions.push(get_local(producer.get_result_address_tag())); //result address let mut instructions_value = self.value.produce_wasm(producer); @@ -84,11 +84,11 @@ impl WriteWasm for ReturnBucket { } let mut free_stack_code = free_stack(producer); instructions.append(&mut free_stack_code); - instructions.push(set_constant("0")); + instructions.push(set_constant("0")); instructions.push(add_return()); if producer.needs_comments() { instructions.push(";; end of return bucket".to_string()); - } + } instructions } } diff --git a/compiler/src/intermediate_representation/store_bucket.rs b/compiler/src/intermediate_representation/store_bucket.rs index 25111ddf1..48857a983 100644 --- a/compiler/src/intermediate_representation/store_bucket.rs +++ b/compiler/src/intermediate_representation/store_bucket.rs @@ -57,12 +57,12 @@ impl WriteWasm for StoreBucket { return vec![]; } if producer.needs_comments() { - instructions.push(format!(";; store bucket. Line {}", self.line)); //.to_string() - } + instructions.push(format!(";; store bucket. Line {}", self.line)); //.to_string() + } let mut my_template_header = Option::::None; if producer.needs_comments() { instructions.push(";; getting dest".to_string()); - } + } match &self.dest { LocationRule::Indexed { location, template_header } => { let mut instructions_dest = location.produce_wasm(producer); @@ -104,9 +104,9 @@ impl WriteWasm for StoreBucket { LocationRule::Mapped { signal_code, indexes } => { match &self.dest_address_type { AddressType::SubcmpSignal { cmp_address, .. } => { - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; is subcomponent".to_string()); - } + } instructions.push(get_local(producer.get_offset_tag())); instructions.push(set_constant( &producer.get_sub_component_start_in_component().to_string(), @@ -128,7 +128,7 @@ impl WriteWasm for StoreBucket { ))); // get position in component io signal to info list let signal_code_in_bytes = signal_code * 4; //position in the list of the signal code instructions.push(load32(Some(&signal_code_in_bytes.to_string()))); // get where the info of this signal is - //now we have first the offset, and then the all size dimensions but the last one + //now we have first the offset, and then the all size dimensions but the last one if indexes.len() <= 1 { instructions.push(load32(None)); // get signal offset (it is already the actual one in memory); if indexes.len() == 1 { @@ -177,7 +177,7 @@ impl WriteWasm for StoreBucket { } if producer.needs_comments() { instructions.push(";; getting src".to_string()); - } + } if self.context.size > 1 { instructions.push(set_local(producer.get_store_aux_1_tag())); } @@ -217,9 +217,9 @@ impl WriteWasm for StoreBucket { match &self.dest_address_type { AddressType::SubcmpSignal { .. } => { // if subcomponent input check if run needed - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; decrease counter".to_string()); // by self.context.size - } + } instructions.push(get_local(producer.get_sub_cmp_tag())); // to update input signal counter instructions.push(get_local(producer.get_sub_cmp_tag())); // to read input signal counter instructions.push(load32(Some( @@ -230,18 +230,18 @@ impl WriteWasm for StoreBucket { instructions.push(store32(Some( &producer.get_input_counter_address_in_component().to_string(), ))); // update remaining inputs to be set - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; check if run is needed".to_string()); - } + } instructions.push(get_local(producer.get_sub_cmp_tag())); instructions.push(load32(Some( &producer.get_input_counter_address_in_component().to_string(), ))); instructions.push(eqz32()); instructions.push(add_if()); - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; run sub component".to_string()); - } + } instructions.push(get_local(producer.get_sub_cmp_tag())); match &self.dest { LocationRule::Indexed { .. } => { @@ -253,7 +253,7 @@ impl WriteWasm for StoreBucket { instructions.push(set_constant(&self.line.to_string())); instructions.push(call("$buildBufferMessage")); instructions.push(call("$printErrorMessage")); - instructions.push(get_local(producer.get_merror_tag())); + instructions.push(get_local(producer.get_merror_tag())); instructions.push(add_return()); instructions.push(add_end()); } else { @@ -273,21 +273,21 @@ impl WriteWasm for StoreBucket { instructions.push(set_constant(&self.line.to_string())); instructions.push(call("$buildBufferMessage")); instructions.push(call("$printErrorMessage")); - instructions.push(get_local(producer.get_merror_tag())); + instructions.push(get_local(producer.get_merror_tag())); instructions.push(add_return()); instructions.push(add_end()); } } - if producer.needs_comments() { + if producer.needs_comments() { instructions.push(";; end run sub component".to_string()); - } + } instructions.push(add_end()); } _ => (), } if producer.needs_comments() { instructions.push(";; end of store bucket".to_string()); - } + } instructions } } @@ -296,49 +296,65 @@ impl WriteC for StoreBucket { fn produce_c(&self, producer: &CProducer, parallel: Option) -> (Vec, String) { use c_code_generator::*; let mut prologue = vec![]; - let cmp_index_ref = "cmp_index_ref".to_string(); - let aux_dest_index = "aux_dest_index".to_string(); + let cmp_index_ref = "cmp_index_ref".to_string(); + let aux_dest_index = "aux_dest_index".to_string(); if let AddressType::SubcmpSignal { cmp_address, .. } = &self.dest_address_type { let (mut cmp_prologue, cmp_index) = cmp_address.produce_c(producer, parallel); prologue.append(&mut cmp_prologue); - prologue.push(format!("{{")); - prologue.push(format!("uint {} = {};", cmp_index_ref, cmp_index)); - } - let ((mut dest_prologue, dest_index), my_template_header) = - if let LocationRule::Indexed { location, template_header } = &self.dest { - (location.produce_c(producer, parallel), template_header.clone()) - } else if let LocationRule::Mapped { signal_code, indexes } = &self.dest { - //if Mapped must be SubcmpSignal - let mut map_prologue = vec![]; - let sub_component_pos_in_memory = format!("{}[{}]",MY_SUBCOMPONENTS,cmp_index_ref.clone()); - let mut map_access = format!("{}->{}[{}].defs[{}].offset", - circom_calc_wit(), template_ins_2_io_info(), - template_id_in_component(sub_component_pos_in_memory.clone()), - signal_code.to_string()); - if indexes.len()>0 { - map_prologue.push(format!("{{")); - map_prologue.push(format!("uint map_index_aux[{}];",indexes.len().to_string())); - let (mut index_code_0, mut map_index) = indexes[0].produce_c(producer, parallel); - map_prologue.append(&mut index_code_0); - map_prologue.push(format!("map_index_aux[0]={};",map_index)); - map_index = format!("map_index_aux[0]"); - for i in 1..indexes.len() { - let (mut index_code, index_exp) = indexes[i].produce_c(producer, parallel); - map_prologue.append(&mut index_code); - map_prologue.push(format!("map_index_aux[{}]={};",i.to_string(),index_exp)); - map_index = format!("({})*{}->{}[{}].defs[{}].lengths[{}]+map_index_aux[{}]", - map_index, circom_calc_wit(), template_ins_2_io_info(), - template_id_in_component(sub_component_pos_in_memory.clone()), - signal_code.to_string(),(i-1).to_string(),i.to_string()); - } - map_access = format!("{}+{}",map_access,map_index); - } - ((map_prologue, map_access),Some(template_id_in_component(sub_component_pos_in_memory.clone()))) - } else { - assert!(false); - ((vec![], "".to_string()),Option::::None) - }; - prologue.append(&mut dest_prologue); + prologue.push(format!("{{")); + prologue.push(format!("uint {} = {};", cmp_index_ref, cmp_index)); + } + let ((mut dest_prologue, dest_index), my_template_header) = if let LocationRule::Indexed { + location, + template_header, + } = &self.dest + { + (location.produce_c(producer, parallel), template_header.clone()) + } else if let LocationRule::Mapped { signal_code, indexes } = &self.dest { + //if Mapped must be SubcmpSignal + let mut map_prologue = vec![]; + let sub_component_pos_in_memory = + format!("{}[{}]", MY_SUBCOMPONENTS, cmp_index_ref.clone()); + let mut map_access = format!( + "{}->{}[{}].defs[{}].offset", + circom_calc_wit(), + template_ins_2_io_info(), + template_id_in_component(sub_component_pos_in_memory.clone()), + signal_code.to_string() + ); + if indexes.len() > 0 { + map_prologue.push(format!("{{")); + map_prologue.push(format!("uint map_index_aux[{}];", indexes.len().to_string())); + let (mut index_code_0, mut map_index) = indexes[0].produce_c(producer, parallel); + map_prologue.append(&mut index_code_0); + map_prologue.push(format!("map_index_aux[0]={};", map_index)); + map_index = format!("map_index_aux[0]"); + for i in 1..indexes.len() { + let (mut index_code, index_exp) = indexes[i].produce_c(producer, parallel); + map_prologue.append(&mut index_code); + map_prologue.push(format!("map_index_aux[{}]={};", i.to_string(), index_exp)); + map_index = format!( + "({})*{}->{}[{}].defs[{}].lengths[{}]+map_index_aux[{}]", + map_index, + circom_calc_wit(), + template_ins_2_io_info(), + template_id_in_component(sub_component_pos_in_memory.clone()), + signal_code.to_string(), + (i - 1).to_string(), + i.to_string() + ); + } + map_access = format!("{}+{}", map_access, map_index); + } + ( + (map_prologue, map_access), + Some(template_id_in_component(sub_component_pos_in_memory.clone())), + ) + } else { + assert!(false); + ((vec![], "".to_string()), Option::::None) + }; + prologue.append(&mut dest_prologue); // Build dest let dest = match &self.dest_address_type { AddressType::Variable => { @@ -352,198 +368,289 @@ impl WriteC for StoreBucket { "{}->componentMemory[{}[{}]].signalStart", CIRCOM_CALC_WIT, MY_SUBCOMPONENTS, cmp_index_ref ); - format!("&{}->signalValues[{} + {}]", CIRCOM_CALC_WIT, sub_cmp_start, dest_index.clone()) + format!( + "&{}->signalValues[{} + {}]", + CIRCOM_CALC_WIT, + sub_cmp_start, + dest_index.clone() + ) } }; - //keep dest_index in an auxiliar if parallel and out put - if let AddressType::Signal = &self.dest_address_type { - if parallel.unwrap() && self.dest_is_output { - prologue.push(format!("{{")); - prologue.push(format!("uint {} = {};", aux_dest_index, dest_index.clone())); - } - } + //keep dest_index in an auxiliar if parallel and out put + if let AddressType::Signal = &self.dest_address_type { + if parallel.unwrap() && self.dest_is_output { + prologue.push(format!("{{")); + prologue.push(format!("uint {} = {};", aux_dest_index, dest_index.clone())); + } + } // store src in dest - prologue.push(format!("{{")); - let aux_dest = "aux_dest".to_string(); - prologue.push(format!("{} {} = {};", T_P_FR_ELEMENT, aux_dest, dest)); + prologue.push(format!("{{")); + let aux_dest = "aux_dest".to_string(); + prologue.push(format!("{} {} = {};", T_P_FR_ELEMENT, aux_dest, dest)); // Load src - prologue.push(format!("// load src")); - let (mut src_prologue, src) = self.src.produce_c(producer, parallel); - prologue.append(&mut src_prologue); - prologue.push(format!("// end load src")); + prologue.push(format!("// load src")); + let (mut src_prologue, src) = self.src.produce_c(producer, parallel); + prologue.append(&mut src_prologue); + prologue.push(format!("// end load src")); std::mem::drop(src_prologue); if self.context.size > 1 { let copy_arguments = vec![aux_dest, src, self.context.size.to_string()]; prologue.push(format!("{};", build_call("Fr_copyn".to_string(), copy_arguments))); - if let AddressType::Signal = &self.dest_address_type { - if parallel.unwrap() && self.dest_is_output { - prologue.push(format!("{{")); - prologue.push(format!("for (int i = 0; i < {}; i++) {{",self.context.size)); - prologue.push(format!("{}->componentMemory[{}].mutexes[{}+i].lock();",CIRCOM_CALC_WIT,CTX_INDEX,aux_dest_index.clone())); - prologue.push(format!("{}->componentMemory[{}].outputIsSet[{}+i]=true;",CIRCOM_CALC_WIT,CTX_INDEX,aux_dest_index.clone())); - prologue.push(format!("{}->componentMemory[{}].mutexes[{}+i].unlock();",CIRCOM_CALC_WIT,CTX_INDEX,aux_dest_index.clone())); - prologue.push(format!("{}->componentMemory[{}].cvs[{}+i].notify_all();",CIRCOM_CALC_WIT,CTX_INDEX,aux_dest_index.clone())); - prologue.push(format!("}}")); - prologue.push(format!("}}")); - prologue.push(format!("}}")); - } - } + if let AddressType::Signal = &self.dest_address_type { + if parallel.unwrap() && self.dest_is_output { + prologue.push(format!("{{")); + prologue.push(format!("for (int i = 0; i < {}; i++) {{", self.context.size)); + prologue.push(format!( + "{}->componentMemory[{}].mutexes[{}+i].lock();", + CIRCOM_CALC_WIT, + CTX_INDEX, + aux_dest_index.clone() + )); + prologue.push(format!( + "{}->componentMemory[{}].outputIsSet[{}+i]=true;", + CIRCOM_CALC_WIT, + CTX_INDEX, + aux_dest_index.clone() + )); + prologue.push(format!( + "{}->componentMemory[{}].mutexes[{}+i].unlock();", + CIRCOM_CALC_WIT, + CTX_INDEX, + aux_dest_index.clone() + )); + prologue.push(format!( + "{}->componentMemory[{}].cvs[{}+i].notify_all();", + CIRCOM_CALC_WIT, + CTX_INDEX, + aux_dest_index.clone() + )); + prologue.push(format!("}}")); + prologue.push(format!("}}")); + prologue.push(format!("}}")); + } + } } else { let copy_arguments = vec![aux_dest, src]; prologue.push(format!("{};", build_call("Fr_copy".to_string(), copy_arguments))); - if let AddressType::Signal = &self.dest_address_type { - if parallel.unwrap() && self.dest_is_output { - prologue.push(format!("{}->componentMemory[{}].mutexes[{}].lock();",CIRCOM_CALC_WIT,CTX_INDEX,aux_dest_index.clone())); - prologue.push(format!("{}->componentMemory[{}].outputIsSet[{}]=true;",CIRCOM_CALC_WIT,CTX_INDEX,aux_dest_index.clone())); - prologue.push(format!("{}->componentMemory[{}].mutexes[{}].unlock();",CIRCOM_CALC_WIT,CTX_INDEX,aux_dest_index.clone())); - prologue.push(format!("{}->componentMemory[{}].cvs[{}].notify_all();",CIRCOM_CALC_WIT,CTX_INDEX,aux_dest_index.clone())); - prologue.push(format!("}}")); - } - } + if let AddressType::Signal = &self.dest_address_type { + if parallel.unwrap() && self.dest_is_output { + prologue.push(format!( + "{}->componentMemory[{}].mutexes[{}].lock();", + CIRCOM_CALC_WIT, + CTX_INDEX, + aux_dest_index.clone() + )); + prologue.push(format!( + "{}->componentMemory[{}].outputIsSet[{}]=true;", + CIRCOM_CALC_WIT, + CTX_INDEX, + aux_dest_index.clone() + )); + prologue.push(format!( + "{}->componentMemory[{}].mutexes[{}].unlock();", + CIRCOM_CALC_WIT, + CTX_INDEX, + aux_dest_index.clone() + )); + prologue.push(format!( + "{}->componentMemory[{}].cvs[{}].notify_all();", + CIRCOM_CALC_WIT, + CTX_INDEX, + aux_dest_index.clone() + )); + prologue.push(format!("}}")); + } + } } - prologue.push(format!("}}")); + prologue.push(format!("}}")); match &self.dest_address_type { - AddressType::SubcmpSignal{ uniform_parallel_value, input_information, .. } => { + AddressType::SubcmpSignal { uniform_parallel_value, input_information, .. } => { // if subcomponent input check if run needed let sub_cmp_counter = format!( "{}->componentMemory[{}[{}]].inputCounter", CIRCOM_CALC_WIT, MY_SUBCOMPONENTS, cmp_index_ref ); - let sub_cmp_counter_decrease = format!( - "{} -= {}", - sub_cmp_counter, self.context.size - ); - if let InputInformation::Input{status} = input_information { - if let StatusInput::NoLast = status { - // no need to run subcomponent - prologue.push("// no need to run sub component".to_string()); - prologue.push(format!("{};", sub_cmp_counter_decrease)); - prologue.push(format!("assert({} > 0);", sub_cmp_counter)); - } else { - let sub_cmp_pos = format!("{}[{}]", MY_SUBCOMPONENTS, cmp_index_ref); - let sub_cmp_call_arguments = - vec![sub_cmp_pos, CIRCOM_CALC_WIT.to_string()]; - // to create the call instruction we need to consider the cases of parallel/not parallel/ known only at execution - if uniform_parallel_value.is_some(){ - // Case parallel - let mut call_instructions = if uniform_parallel_value.unwrap(){ - let sub_cmp_call_name = if let LocationRule::Indexed { .. } = &self.dest { - format!("{}_run_parallel", my_template_header.unwrap()) + let sub_cmp_counter_decrease = + format!("{} -= {}", sub_cmp_counter, self.context.size); + if let InputInformation::Input { status } = input_information { + if let StatusInput::NoLast = status { + // no need to run subcomponent + prologue.push("// no need to run sub component".to_string()); + prologue.push(format!("{};", sub_cmp_counter_decrease)); + prologue.push(format!("assert({} > 0);", sub_cmp_counter)); } else { - format!("(*{}[{}])", function_table_parallel(), my_template_header.unwrap()) - }; - let mut thread_call_instr = vec![]; - - // parallelism - thread_call_instr.push(format!("{}->componentMemory[{}].sbct[{}] = std::thread({},{});",CIRCOM_CALC_WIT,CTX_INDEX,cmp_index_ref, sub_cmp_call_name, argument_list(sub_cmp_call_arguments))); - thread_call_instr.push(format!("std::unique_lock lkt({}->numThreadMutex);",CIRCOM_CALC_WIT)); - thread_call_instr.push(format!("{}->ntcvs.wait(lkt, [{}]() {{return {}->numThread < {}->maxThread; }});",CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT)); - thread_call_instr.push(format!("ctx->numThread++;")); - thread_call_instr + let sub_cmp_pos = format!("{}[{}]", MY_SUBCOMPONENTS, cmp_index_ref); + let sub_cmp_call_arguments = vec![sub_cmp_pos, CIRCOM_CALC_WIT.to_string()]; + // to create the call instruction we need to consider the cases of parallel/not parallel/ known only at execution + if uniform_parallel_value.is_some() { + // Case parallel + let mut call_instructions = if uniform_parallel_value.unwrap() { + let sub_cmp_call_name = + if let LocationRule::Indexed { .. } = &self.dest { + format!("{}_run_parallel", my_template_header.unwrap()) + } else { + format!( + "(*{}[{}])", + function_table_parallel(), + my_template_header.unwrap() + ) + }; + let mut thread_call_instr = vec![]; - } - // Case not parallel - else{ - let sub_cmp_call_name = if let LocationRule::Indexed { .. } = &self.dest { - format!("{}_run", my_template_header.unwrap()) - } else { - format!("(*{}[{}])", function_table(), my_template_header.unwrap()) - }; - vec![format!( - "{};", - build_call(sub_cmp_call_name, sub_cmp_call_arguments) - )] - }; - if let StatusInput::Unknown = status { - let sub_cmp_counter_decrease_andcheck = format!("!({})",sub_cmp_counter_decrease); - let if_condition = vec![sub_cmp_counter_decrease_andcheck]; - prologue.push("// run sub component if needed".to_string()); - let else_instructions = vec![]; - prologue.push(build_conditional(if_condition,call_instructions,else_instructions)); - } else { - prologue.push("// need to run sub component".to_string()); - prologue.push(format!("{};", sub_cmp_counter_decrease)); - prologue.push(format!("assert(!({}));", sub_cmp_counter)); - prologue.append(&mut call_instructions); - } - } - // Case we only know if it is parallel at execution - else{ - prologue.push(format!( - "if ({}[{}]){{", - MY_SUBCOMPONENTS_PARALLEL, - cmp_index_ref - )); + // parallelism + thread_call_instr.push(format!( + "{}->componentMemory[{}].sbct[{}] = std::thread({},{});", + CIRCOM_CALC_WIT, + CTX_INDEX, + cmp_index_ref, + sub_cmp_call_name, + argument_list(sub_cmp_call_arguments) + )); + thread_call_instr.push(format!( + "std::unique_lock lkt({}->numThreadMutex);", + CIRCOM_CALC_WIT + )); + thread_call_instr.push(format!("{}->ntcvs.wait(lkt, [{}]() {{return {}->numThread < {}->maxThread; }});",CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT)); + thread_call_instr.push(format!("ctx->numThread++;")); + thread_call_instr + } + // Case not parallel + else { + let sub_cmp_call_name = + if let LocationRule::Indexed { .. } = &self.dest { + format!("{}_run", my_template_header.unwrap()) + } else { + format!( + "(*{}[{}])", + function_table(), + my_template_header.unwrap() + ) + }; + vec![format!( + "{};", + build_call(sub_cmp_call_name, sub_cmp_call_arguments) + )] + }; + if let StatusInput::Unknown = status { + let sub_cmp_counter_decrease_andcheck = + format!("!({})", sub_cmp_counter_decrease); + let if_condition = vec![sub_cmp_counter_decrease_andcheck]; + prologue.push("// run sub component if needed".to_string()); + let else_instructions = vec![]; + prologue.push(build_conditional( + if_condition, + call_instructions, + else_instructions, + )); + } else { + prologue.push("// need to run sub component".to_string()); + prologue.push(format!("{};", sub_cmp_counter_decrease)); + prologue.push(format!("assert(!({}));", sub_cmp_counter)); + prologue.append(&mut call_instructions); + } + } + // Case we only know if it is parallel at execution + else { + prologue.push(format!( + "if ({}[{}]){{", + MY_SUBCOMPONENTS_PARALLEL, cmp_index_ref + )); - // case parallel - let sub_cmp_call_name = if let LocationRule::Indexed { .. } = &self.dest { - format!("{}_run_parallel", my_template_header.clone().unwrap()) - } else { - format!("(*{}[{}])", function_table_parallel(), my_template_header.clone().unwrap()) - }; - let mut call_instructions = vec![]; - // parallelism - call_instructions.push(format!("{}->componentMemory[{}].sbct[{}] = std::thread({},{});",CIRCOM_CALC_WIT,CTX_INDEX,cmp_index_ref, sub_cmp_call_name, argument_list(sub_cmp_call_arguments.clone()))); - call_instructions.push(format!("std::unique_lock lkt({}->numThreadMutex);",CIRCOM_CALC_WIT)); - call_instructions.push(format!("{}->ntcvs.wait(lkt, [{}]() {{return {}->numThread < {}->maxThread; }});",CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT)); - call_instructions.push(format!("ctx->numThread++;")); + // case parallel + let sub_cmp_call_name = if let LocationRule::Indexed { .. } = &self.dest + { + format!("{}_run_parallel", my_template_header.clone().unwrap()) + } else { + format!( + "(*{}[{}])", + function_table_parallel(), + my_template_header.clone().unwrap() + ) + }; + let mut call_instructions = vec![]; + // parallelism + call_instructions.push(format!( + "{}->componentMemory[{}].sbct[{}] = std::thread({},{});", + CIRCOM_CALC_WIT, + CTX_INDEX, + cmp_index_ref, + sub_cmp_call_name, + argument_list(sub_cmp_call_arguments.clone()) + )); + call_instructions.push(format!( + "std::unique_lock lkt({}->numThreadMutex);", + CIRCOM_CALC_WIT + )); + call_instructions.push(format!("{}->ntcvs.wait(lkt, [{}]() {{return {}->numThread < {}->maxThread; }});",CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT,CIRCOM_CALC_WIT)); + call_instructions.push(format!("ctx->numThread++;")); - if let StatusInput::Unknown = status { - let sub_cmp_counter_decrease_andcheck = format!("!({})",sub_cmp_counter_decrease); - let if_condition = vec![sub_cmp_counter_decrease_andcheck]; - prologue.push("// run sub component if needed".to_string()); - let else_instructions = vec![]; - prologue.push(build_conditional(if_condition,call_instructions,else_instructions)); - } else { - prologue.push("// need to run sub component".to_string()); - prologue.push(format!("{};", sub_cmp_counter_decrease)); - prologue.push(format!("assert(!({}));", sub_cmp_counter)); - prologue.append(&mut call_instructions); - } - // end of case parallel + if let StatusInput::Unknown = status { + let sub_cmp_counter_decrease_andcheck = + format!("!({})", sub_cmp_counter_decrease); + let if_condition = vec![sub_cmp_counter_decrease_andcheck]; + prologue.push("// run sub component if needed".to_string()); + let else_instructions = vec![]; + prologue.push(build_conditional( + if_condition, + call_instructions, + else_instructions, + )); + } else { + prologue.push("// need to run sub component".to_string()); + prologue.push(format!("{};", sub_cmp_counter_decrease)); + prologue.push(format!("assert(!({}));", sub_cmp_counter)); + prologue.append(&mut call_instructions); + } + // end of case parallel - prologue.push(format!("}} else {{")); - - // case not parallel - let sub_cmp_call_name = if let LocationRule::Indexed { .. } = &self.dest { - format!("{}_run", my_template_header.unwrap()) - } else { - format!("(*{}[{}])", function_table(), my_template_header.unwrap()) - }; - let mut call_instructions = vec![format!( - "{};", - build_call(sub_cmp_call_name, sub_cmp_call_arguments) - )]; - if let StatusInput::Unknown = status { - let sub_cmp_counter_decrease_andcheck = format!("!({})",sub_cmp_counter_decrease); - let if_condition = vec![sub_cmp_counter_decrease_andcheck]; - prologue.push("// run sub component if needed".to_string()); - let else_instructions = vec![]; - prologue.push(build_conditional(if_condition,call_instructions,else_instructions)); + prologue.push(format!("}} else {{")); + + // case not parallel + let sub_cmp_call_name = if let LocationRule::Indexed { .. } = &self.dest + { + format!("{}_run", my_template_header.unwrap()) + } else { + format!("(*{}[{}])", function_table(), my_template_header.unwrap()) + }; + let mut call_instructions = vec![format!( + "{};", + build_call(sub_cmp_call_name, sub_cmp_call_arguments) + )]; + if let StatusInput::Unknown = status { + let sub_cmp_counter_decrease_andcheck = + format!("!({})", sub_cmp_counter_decrease); + let if_condition = vec![sub_cmp_counter_decrease_andcheck]; + prologue.push("// run sub component if needed".to_string()); + let else_instructions = vec![]; + prologue.push(build_conditional( + if_condition, + call_instructions, + else_instructions, + )); + } else { + prologue.push("// need to run sub component".to_string()); + prologue.push(format!("{};", sub_cmp_counter_decrease)); + prologue.push(format!("assert(!({}));", sub_cmp_counter)); + prologue.append(&mut call_instructions); + } + // end of not parallel case + prologue.push(format!("}}")); + } + } } else { - prologue.push("// need to run sub component".to_string()); - prologue.push(format!("{};", sub_cmp_counter_decrease)); - prologue.push(format!("assert(!({}));", sub_cmp_counter)); - prologue.append(&mut call_instructions); + assert!(false); } - // end of not parallel case - prologue.push(format!("}}")); } + _ => (), } - } else { - assert!(false); - } + if let AddressType::SubcmpSignal { .. } = &self.dest_address_type { + prologue.push(format!("}}")); + } + if let LocationRule::Mapped { indexes, .. } = &self.dest { + if indexes.len() > 0 { + prologue.push(format!("}}")); } - _ => (), } - if let AddressType::SubcmpSignal { .. } = &self.dest_address_type { - prologue.push(format!("}}")); - } - if let LocationRule::Mapped { indexes, .. } = &self.dest { - if indexes.len() > 0 { - prologue.push(format!("}}")); - } - } (prologue, "".to_string()) } diff --git a/compiler/src/intermediate_representation/translate.rs b/compiler/src/intermediate_representation/translate.rs index 04309bb23..7058b7555 100644 --- a/compiler/src/intermediate_representation/translate.rs +++ b/compiler/src/intermediate_representation/translate.rs @@ -19,7 +19,7 @@ pub struct SymbolInfo { } #[derive(Clone)] -pub struct SignalInfo{ +pub struct SignalInfo { signal_type: SignalType, lengths: Vec, } @@ -77,7 +77,7 @@ impl TemplateDB { ); let mut signal_info = HashMap::new(); for signal in instance.signals.clone() { - let info = SignalInfo{ signal_type: signal.xtype, lengths: signal.lengths}; + let info = SignalInfo { signal_type: signal.xtype, lengths: signal.lengths }; signal_info.insert(signal.name, info); } initialize_signals(&mut state, instance.signals.clone()); @@ -89,7 +89,7 @@ impl TemplateDB { struct State { field_tracker: FieldTracker, environment: E, - component_to_parallel: HashMap, + component_to_parallel: HashMap, component_to_instance: HashMap>, signal_to_type: HashMap, signal_to_tags: BTreeMap, @@ -109,8 +109,8 @@ impl State { msg_id: usize, cmp_id_offset: usize, field_tracker: FieldTracker, - component_to_parallel: HashMap, - signal_to_tags: BTreeMap + component_to_parallel: HashMap, + signal_to_tags: BTreeMap, ) -> State { State { field_tracker, @@ -126,7 +126,7 @@ impl State { fresh_cmp_id: cmp_id_offset, max_stack_depth: 0, code: vec![], - string_table : HashMap::new(), + string_table: HashMap::new(), } } fn reserve(fresh: &mut usize, size: usize) -> usize { @@ -173,8 +173,11 @@ fn initialize_parameters(state: &mut State, params: Vec) { op_aux_no: 0, }; let address_instruction = address_instruction.allocate(); - let symbol_info = - SymbolInfo { dimensions: lengths, access_instruction: address_instruction.clone(), is_component:false }; + let symbol_info = SymbolInfo { + dimensions: lengths, + access_instruction: address_instruction.clone(), + is_component: false, + }; state.environment.add_variable(&p.name, symbol_info); } } @@ -192,8 +195,11 @@ fn initialize_constants(state: &mut State, constants: Vec) { op_aux_no: 0, } .allocate(); - let symbol_info = - SymbolInfo { access_instruction: address_instruction.clone(), dimensions, is_component:false }; + let symbol_info = SymbolInfo { + access_instruction: address_instruction.clone(), + dimensions, + is_component: false, + }; state.environment.add_variable(&arg.name, symbol_info); let mut index = 0; for value in arg.values { @@ -250,7 +256,11 @@ fn initialize_signals(state: &mut State, signals: Vec) { op_aux_no: 0, } .allocate(); - let info = SymbolInfo { access_instruction: instruction, dimensions: signal.lengths, is_component:false }; + let info = SymbolInfo { + access_instruction: instruction, + dimensions: signal.lengths, + is_component: false, + }; state.environment.add_variable(&signal.name, info); state.signal_to_type.insert(signal.name.clone(), signal.xtype); } @@ -268,7 +278,11 @@ fn initialize_components(state: &mut State, components: Vec) { op_aux_no: 0, } .allocate(); - let info = SymbolInfo { access_instruction: instruction, dimensions: component.lengths, is_component: true }; + let info = SymbolInfo { + access_instruction: instruction, + dimensions: component.lengths, + is_component: true, + }; state.environment.add_variable(&component.name, info); } } @@ -278,11 +292,11 @@ fn create_components(state: &mut State, triggers: &[Trigger], clusters: Vec{ + match component_info { + Some(info) => { info.insert(trigger.template_id); } - None =>{ + None => { let mut new_info = HashSet::new(); new_info.insert(trigger.template_id); state.component_to_instance.insert(trigger.component_name.clone(), new_info); @@ -319,10 +333,11 @@ fn create_uniform_components(state: &mut State, triggers: &[Trigger], cluster: T let first = cluster.slice.start; let c_info = &triggers[first]; let symbol = state.environment.get_variable(&c_info.component_name).unwrap().clone(); - - let info_parallel_cluster = state.component_to_parallel.get(&c_info.component_name).unwrap(); + + let info_parallel_cluster = + state.component_to_parallel.get(&c_info.component_name).unwrap(); let mut defined_positions = Vec::new(); - for (pos, value) in &info_parallel_cluster.positions_to_parallel{ + for (pos, value) in &info_parallel_cluster.positions_to_parallel { let flattened_pos = compute_jump(&symbol.dimensions, pos); defined_positions.push((flattened_pos, *value)); } @@ -339,12 +354,12 @@ fn create_uniform_components(state: &mut State, triggers: &[Trigger], cluster: T sub_cmp_id: symbol.access_instruction.clone(), template_id: c_info.template_id, signal_offset: c_info.offset, - component_offset: c_info.component_offset, + component_offset: c_info.component_offset, has_inputs: c_info.has_inputs, number_of_cmp: compute_number_cmp(&symbol.dimensions), dimensions: symbol.dimensions, signal_offset_jump: offset_jump, - component_offset_jump: component_offset_jump, + component_offset_jump: component_offset_jump, } .allocate(); state.code.push(creation_instr); @@ -388,34 +403,44 @@ fn create_mixed_components(state: &mut State, triggers: &[Trigger], cluster: Tri } .allocate(); - let info_parallel_cluster = state.component_to_parallel.get(&c_info.component_name).unwrap(); + let info_parallel_cluster = + state.component_to_parallel.get(&c_info.component_name).unwrap(); let parallel_value: bool; - if info_parallel_cluster.uniform_parallel_value.is_some(){ + if info_parallel_cluster.uniform_parallel_value.is_some() { parallel_value = info_parallel_cluster.uniform_parallel_value.unwrap(); - } - else{ - parallel_value = *info_parallel_cluster. - positions_to_parallel.get(&c_info.indexed_with).unwrap(); + } else { + parallel_value = + *info_parallel_cluster.positions_to_parallel.get(&c_info.indexed_with).unwrap(); } let creation_instr = CreateCmpBucket { line: 0, message_id: state.message_id, symbol: c_info.runs.clone(), - name_subcomponent: format!("{}{}",c_info.component_name.clone(), c_info.indexed_with.iter().fold(String::new(), |acc, &num| format!("{}[{}]", acc, &num.to_string()))), + name_subcomponent: format!( + "{}{}", + c_info.component_name.clone(), + c_info.indexed_with.iter().fold(String::new(), |acc, &num| format!( + "{}[{}]", + acc, + &num.to_string() + )) + ), defined_positions: vec![(0, parallel_value)], - is_part_mixed_array_not_uniform_parallel: info_parallel_cluster.uniform_parallel_value.is_none(), + is_part_mixed_array_not_uniform_parallel: info_parallel_cluster + .uniform_parallel_value + .is_none(), uniform_parallel: Some(parallel_value), dimensions: symbol.dimensions, cmp_unique_id: id, sub_cmp_id: location, template_id: c_info.template_id, signal_offset: c_info.offset, - component_offset: c_info.component_offset, + component_offset: c_info.component_offset, has_inputs: c_info.has_inputs, number_of_cmp: 1, signal_offset_jump: 0, - component_offset_jump: 0, + component_offset_jump: 0, } .allocate(); state.code.push(creation_instr); @@ -583,11 +608,13 @@ fn translate_constraint_equality(stmt: Statement, state: &mut State, context: &C if let ConstraintEquality { meta, lhe, rhe } = stmt { let starts_at = context.files.get_line(meta.start, meta.get_file_id()).unwrap(); - let length = if let Variable { meta, name, access} = lhe.clone() { + let length = if let Variable { meta, name, access } = lhe.clone() { let def = SymbolDef { meta, symbol: name, acc: access }; ProcessedSymbol::new(def, state, context).length - } else {1}; - + } else { + 1 + }; + let lhe_pointer = translate_expression(lhe, state, context); let rhe_pointer = translate_expression(rhe, state, context); let stack = vec![lhe_pointer, rhe_pointer]; @@ -629,24 +656,20 @@ fn translate_log(stmt: Statement, state: &mut State, context: &Context) { let code = translate_expression(arg, state, context); logbucket_args.push(LogBucketArg::LogExp(code)); } - LogArgument::LogStr(exp) => { - match state.string_table.get(&exp) { - Some( idx) => {logbucket_args.push(LogBucketArg::LogStr(*idx));}, - None => { - logbucket_args.push(LogBucketArg::LogStr(state.string_table.len())); - state.string_table.insert(exp, state.string_table.len()); - }, + LogArgument::LogStr(exp) => match state.string_table.get(&exp) { + Some(idx) => { + logbucket_args.push(LogBucketArg::LogStr(*idx)); } - - } + None => { + logbucket_args.push(LogBucketArg::LogStr(state.string_table.len())); + state.string_table.insert(exp, state.string_table.len()); + } + }, } } - - let log = LogBucket { - line, - message_id: state.message_id, - argsprint: logbucket_args, - }.allocate(); + + let log = + LogBucket { line, message_id: state.message_id, argsprint: logbucket_args }.allocate(); state.code.push(log); } } @@ -757,24 +780,25 @@ fn translate_prefix( } } -fn check_tag_access(name_signal: &String, access: &Vec, state: &mut State) -> Option { +fn check_tag_access( + name_signal: &String, + access: &Vec, + state: &mut State, +) -> Option { use Access::*; let symbol_info = state.environment.get_variable(name_signal).unwrap().clone(); let mut value_tag = None; - if !symbol_info.is_component{ + if !symbol_info.is_component { for acc in access { match acc { - ArrayAccess(..) => {}, + ArrayAccess(..) => {} ComponentAccess(name) => { let tags_signal = state.signal_to_tags.get(name_signal).unwrap(); let value = tags_signal.get(name).unwrap(); - value_tag = if value.is_some() { - Some(value.clone().unwrap()) - } else { - unreachable!() - }; + value_tag = + if value.is_some() { Some(value.clone().unwrap()) } else { unreachable!() }; } } } @@ -790,9 +814,9 @@ fn translate_variable( use Expression::{Variable}; if let Variable { meta, name, access, .. } = expression { let tag_access = check_tag_access(&name, &access, state); - if tag_access.is_some(){ - translate_number( Expression::Number(meta.clone(), tag_access.unwrap()), state, context) - } else{ + if tag_access.is_some() { + translate_number(Expression::Number(meta.clone(), tag_access.unwrap()), state, context) + } else { let def = SymbolDef { meta, symbol: name, acc: access }; ProcessedSymbol::new(def, state, context).into_load(state) } @@ -929,14 +953,15 @@ impl ProcessedSymbol { bf_index.push(translate_expression(exp, state, context)); } ArrayAccess(exp) => { - for possible_length in &mut multiple_possible_lengths{ + for possible_length in &mut multiple_possible_lengths { possible_length.pop(); } af_index.push(translate_expression(exp, state, context)); } ComponentAccess(name) => { - let possible_cmp_id = state.component_to_instance.get(&symbol_name).unwrap().clone(); - for cmp_id in possible_cmp_id{ + let possible_cmp_id = + state.component_to_instance.get(&symbol_name).unwrap().clone(); + for cmp_id in possible_cmp_id { let aux = context.tmp_database.signal_info[cmp_id].get(&name).unwrap(); signal_type = Some(aux.signal_type); let mut new_length = aux.lengths.clone(); @@ -947,29 +972,22 @@ impl ProcessedSymbol { } } } - if signal.is_some(){ + if signal.is_some() { let mut is_first = true; - for possible_length in multiple_possible_lengths{ - if is_first{ + for possible_length in multiple_possible_lengths { + if is_first { with_length = possible_length.iter().fold(1, |r, c| r * (*c)); is_first = false; - } - else{ - if with_length != possible_length.iter().fold(1, |r, c| r * (*c)){ + } else { + if with_length != possible_length.iter().fold(1, |r, c| r * (*c)) { unreachable!("On development: Circom compiler does not accept for now the assignment of arrays of unknown sizes during the execution of loops"); } } - } + } } let signal_location = signal.map(|signal_name| { - build_signal_location( - &signal_name, - &symbol_name, - af_index, - context, - state, - ) + build_signal_location(&signal_name, &symbol_name, af_index, context, state) }); ProcessedSymbol { xtype: meta.get_type_knowledge().get_reduces_to(), @@ -980,23 +998,22 @@ impl ProcessedSymbol { name: symbol_name, before_signal: bf_index, signal: signal_location, - signal_type + signal_type, } } - fn into_call_assign( - self, - id: String, - args: ArgData, - state: &State, - ) -> InstructionPointer { + fn into_call_assign(self, id: String, args: ArgData, state: &State) -> InstructionPointer { let data = if let Option::Some(signal) = self.signal { let dest_type = AddressType::SubcmpSignal { cmp_address: compute_full_address(state, self.symbol, self.before_signal), is_output: self.signal_type.unwrap() == SignalType::Output, - uniform_parallel_value: state.component_to_parallel.get(&self.name).unwrap().uniform_parallel_value, - input_information : match self.signal_type.unwrap() { - SignalType::Input => InputInformation::Input { status: StatusInput:: Unknown}, + uniform_parallel_value: state + .component_to_parallel + .get(&self.name) + .unwrap() + .uniform_parallel_value, + input_information: match self.signal_type.unwrap() { + SignalType::Input => InputInformation::Input { status: StatusInput::Unknown }, _ => InputInformation::NoInput, }, }; @@ -1035,10 +1052,14 @@ impl ProcessedSymbol { if let Option::Some(signal) = self.signal { let dest_type = AddressType::SubcmpSignal { cmp_address: compute_full_address(state, self.symbol, self.before_signal), - uniform_parallel_value: state.component_to_parallel.get(&self.name).unwrap().uniform_parallel_value, + uniform_parallel_value: state + .component_to_parallel + .get(&self.name) + .unwrap() + .uniform_parallel_value, is_output: self.signal_type.unwrap() == SignalType::Output, - input_information : match self.signal_type.unwrap() { - SignalType::Input => InputInformation::Input { status:StatusInput:: Unknown}, + input_information: match self.signal_type.unwrap() { + SignalType::Input => InputInformation::Input { status: StatusInput::Unknown }, _ => InputInformation::NoInput, }, }; @@ -1075,10 +1096,14 @@ impl ProcessedSymbol { if let Option::Some(signal) = self.signal { let dest_type = AddressType::SubcmpSignal { cmp_address: compute_full_address(state, self.symbol, self.before_signal), - uniform_parallel_value: state.component_to_parallel.get(&self.name).unwrap().uniform_parallel_value, + uniform_parallel_value: state + .component_to_parallel + .get(&self.name) + .unwrap() + .uniform_parallel_value, is_output: self.signal_type.unwrap() == SignalType::Output, - input_information : match self.signal_type.unwrap() { - SignalType::Input => InputInformation::Input { status: StatusInput:: Unknown}, + input_information: match self.signal_type.unwrap() { + SignalType::Input => InputInformation::Input { status: StatusInput::Unknown }, _ => InputInformation::NoInput, }, }; @@ -1151,70 +1176,59 @@ fn compute_full_address( fn indexing_instructions_filter( indexing: Vec, state: &State, - ) -> Vec{ +) -> Vec { let mut index_stack = vec![]; for i in indexing { - let (possible_to_usize, _) = check_if_possible_to_usize_single(&i, state); - if possible_to_usize{ + if possible_to_usize { let new_index = convert_to_usize_single(i, state); index_stack.push(new_index); - } else{ - + } else { let to_usize = ComputeBucket { line: i.get_line(), message_id: i.get_message_id(), op_aux_no: 0, op: OperatorType::ToAddress, stack: vec![i.allocate()], - }.allocate(); + } + .allocate(); index_stack.push(to_usize); - } } index_stack } -fn check_if_possible_to_usize_single( // returns if it is possible to convert to usize and if it is a small usize - // we consider that a usize is small if it is a number < 100 - // we consider that a multiplication is usize if at least one of its operands is usize - // and the other is usize +fn check_if_possible_to_usize_single( + // returns if it is possible to convert to usize and if it is a small usize + // we consider that a usize is small if it is a number < 100 + // we consider that a multiplication is usize if at least one of its operands is usize + // and the other is usize index: &InstructionPointer, state: &State, -)-> (bool, bool){ - +) -> (bool, bool) { use Instruction::{Value, Compute}; match &**index { - Value(v) if v.parse_as == ValueType::U32 => { - (true, v.value < 100) - } + Value(v) if v.parse_as == ValueType::U32 => (true, v.value < 100), Value(v) if v.parse_as == ValueType::BigInt => { let field = state.field_tracker.get_constant(v.value).unwrap(); - let new_value = usize::from_str_radix(field, 10); + let new_value = usize::from_str_radix(field, 10); - match new_value{ - Ok(_) =>{ - (true, new_value.unwrap() < 100) - } - _ =>{ - (false, false) - } + match new_value { + Ok(_) => (true, new_value.unwrap() < 100), + _ => (false, false), } - } Compute(v) if v.op == OperatorType::Add => { let (are_usize, _) = check_if_possible_to_usize_multiple(&v.stack, state); (are_usize, false) - } + } Compute(v) if v.op == OperatorType::Mul => { let (are_usize, are_small) = check_if_possible_to_usize_multiple(&v.stack, state); (are_usize && are_small, false) } - Compute(_) =>{ - (false, false) - } + Compute(_) => (false, false), _ => { // Case variable (true, false) @@ -1222,50 +1236,42 @@ fn check_if_possible_to_usize_single( // returns if it is possible to convert to } } -fn check_if_possible_to_usize_multiple( // returns if all of them are usize and if the number of non small usizes is at most one +fn check_if_possible_to_usize_multiple( + // returns if all of them are usize and if the number of non small usizes is at most one indexing: &Vec, state: &State, -) -> (bool, bool) { +) -> (bool, bool) { let mut is_usize = true; let mut number_non_small = 0; for i in indexing { let (is_usize_i, is_small_i) = check_if_possible_to_usize_single(i, state); is_usize &= is_usize_i; - if !is_small_i{ + if !is_small_i { number_non_small += 1; } } (is_usize, number_non_small <= 1) } - - -fn convert_to_usize_single( - index: InstructionPointer, - state: &State, -)-> InstructionPointer{ - +fn convert_to_usize_single(index: InstructionPointer, state: &State) -> InstructionPointer { use Instruction::{Value, Compute}; match *index { - Value(v) if v.parse_as == ValueType::U32 => { - v.allocate() - } + Value(v) if v.parse_as == ValueType::U32 => v.allocate(), Value(mut v) if v.parse_as == ValueType::BigInt => { let field = state.field_tracker.get_constant(v.value).unwrap(); - let new_value = usize::from_str_radix(field, 10); + let new_value = usize::from_str_radix(field, 10); - match new_value{ - Ok(value) =>{ + match new_value { + Ok(value) => { v.parse_as = ValueType::U32; v.value = value; v.allocate() } - _ =>{ + _ => { unreachable!() } } - } Compute(mut v) if v.op == OperatorType::Add => { v.stack = convert_to_usize_multiple(v.stack, state); @@ -1277,7 +1283,7 @@ fn convert_to_usize_single( v.op = OperatorType::MulAddress; v.into_instruction().allocate() } - Compute(_) =>{ + Compute(_) => { unreachable!() } _ => { @@ -1288,16 +1294,16 @@ fn convert_to_usize_single( op_aux_no: 0, op: OperatorType::ToAddress, stack: vec![index.allocate()], - }.allocate() + } + .allocate() } - } } fn convert_to_usize_multiple( indexing: Vec, state: &State, -) -> Vec { +) -> Vec { let mut index_stack = vec![]; for i in indexing { let new_index = convert_to_usize_single(i, state); @@ -1306,8 +1312,11 @@ fn convert_to_usize_multiple( index_stack } - -fn fold(using: OperatorType, mut stack: Vec, state: &State) -> InstructionPointer { +fn fold( + using: OperatorType, + mut stack: Vec, + state: &State, +) -> InstructionPointer { let instruction = stack.pop().unwrap(); if stack.len() == 0 { instruction @@ -1347,7 +1356,7 @@ fn translate_call_arguments( info } -pub struct ParallelClusters{ +pub struct ParallelClusters { pub positions_to_parallel: BTreeMap, bool>, pub uniform_parallel_value: Option, } @@ -1412,7 +1421,6 @@ pub fn translate_code(body: Statement, code_info: CodeInfo) -> CodeOutput { let mut code = ir_processing::reduce_intermediate_operations(state.code); let expression_depth = ir_processing::build_auxiliary_stack(&mut code); - CodeOutput { code, @@ -1421,6 +1429,6 @@ pub fn translate_code(body: Statement, code_info: CodeInfo) -> CodeOutput { stack_depth: state.max_stack_depth, signal_depth: state.signal_stack, constant_tracker: state.field_tracker, - string_table : state.string_table + string_table: state.string_table, } } diff --git a/compiler/src/intermediate_representation/value_bucket.rs b/compiler/src/intermediate_representation/value_bucket.rs index 8575e5335..3333f4127 100644 --- a/compiler/src/intermediate_representation/value_bucket.rs +++ b/compiler/src/intermediate_representation/value_bucket.rs @@ -53,7 +53,7 @@ impl WriteWasm for ValueBucket { let mut instructions = vec![]; if producer.needs_comments() { instructions.push(";; value bucket".to_string()); - } + } match &self.parse_as { ValueType::U32 => { instructions.push(set_constant(&self.value.to_string())); @@ -67,7 +67,7 @@ impl WriteWasm for ValueBucket { } if producer.needs_comments() { instructions.push(";; end of value bucket".to_string()); - } + } instructions } } diff --git a/compiler/src/ir_processing/build_inputs_info.rs b/compiler/src/ir_processing/build_inputs_info.rs index fa15534fd..49755f1dd 100644 --- a/compiler/src/ir_processing/build_inputs_info.rs +++ b/compiler/src/ir_processing/build_inputs_info.rs @@ -3,286 +3,353 @@ use std::collections::{HashSet}; type ComponentsSet = HashSet; - pub fn visit_list( - instructions: &mut InstructionList, - known_last_component: &mut ComponentsSet, - unknown_last_component: &mut ComponentsSet, + instructions: &mut InstructionList, + known_last_component: &mut ComponentsSet, + unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - inside_loop: bool -)-> bool { + inside_loop: bool, +) -> bool { let len_instructions = instructions.len(); let mut found_unkown_aux = found_unknown_address; - for i in 0..instructions.len(){ + for i in 0..instructions.len() { found_unkown_aux = visit_instruction( &mut instructions[len_instructions - 1 - i], known_last_component, - unknown_last_component, + unknown_last_component, found_unkown_aux, - inside_loop + inside_loop, ); } found_unkown_aux } pub fn visit_instruction( - instruction: &mut Instruction, - known_last_component: &mut ComponentsSet, - unknown_last_component: &mut ComponentsSet, + instruction: &mut Instruction, + known_last_component: &mut ComponentsSet, + unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - inside_loop: bool -) ->bool { + inside_loop: bool, +) -> bool { use Instruction::*; match instruction { - Branch(b) => visit_branch(b, known_last_component, unknown_last_component, found_unknown_address, inside_loop), - Call(b) => visit_call(b, known_last_component, unknown_last_component, found_unknown_address, inside_loop), - Compute(b) => visit_compute(b, known_last_component, unknown_last_component, found_unknown_address, inside_loop), - Load(b) => visit_load(b, known_last_component, unknown_last_component, found_unknown_address, inside_loop), - Loop(b) => visit_loop(b, known_last_component, unknown_last_component, found_unknown_address, inside_loop), - Return(b) => visit_return(b, known_last_component, unknown_last_component, found_unknown_address, inside_loop), - Store(b) => visit_store(b, known_last_component, unknown_last_component, found_unknown_address, inside_loop), - Value(b) => visit_value(b, known_last_component, unknown_last_component, found_unknown_address, inside_loop), - Assert(b) => visit_assert(b, known_last_component, unknown_last_component, found_unknown_address, inside_loop), - CreateCmp(b) => visit_create_cmp(b, known_last_component, unknown_last_component, found_unknown_address, inside_loop), - Log(b) => visit_log(b, known_last_component, unknown_last_component, found_unknown_address, inside_loop), + Branch(b) => visit_branch( + b, + known_last_component, + unknown_last_component, + found_unknown_address, + inside_loop, + ), + Call(b) => visit_call( + b, + known_last_component, + unknown_last_component, + found_unknown_address, + inside_loop, + ), + Compute(b) => visit_compute( + b, + known_last_component, + unknown_last_component, + found_unknown_address, + inside_loop, + ), + Load(b) => visit_load( + b, + known_last_component, + unknown_last_component, + found_unknown_address, + inside_loop, + ), + Loop(b) => visit_loop( + b, + known_last_component, + unknown_last_component, + found_unknown_address, + inside_loop, + ), + Return(b) => visit_return( + b, + known_last_component, + unknown_last_component, + found_unknown_address, + inside_loop, + ), + Store(b) => visit_store( + b, + known_last_component, + unknown_last_component, + found_unknown_address, + inside_loop, + ), + Value(b) => visit_value( + b, + known_last_component, + unknown_last_component, + found_unknown_address, + inside_loop, + ), + Assert(b) => visit_assert( + b, + known_last_component, + unknown_last_component, + found_unknown_address, + inside_loop, + ), + CreateCmp(b) => visit_create_cmp( + b, + known_last_component, + unknown_last_component, + found_unknown_address, + inside_loop, + ), + Log(b) => visit_log( + b, + known_last_component, + unknown_last_component, + found_unknown_address, + inside_loop, + ), } } pub fn visit_branch( - bucket: &mut BranchBucket, - known_last_component: &mut ComponentsSet, - unknown_last_component: &mut ComponentsSet, + bucket: &mut BranchBucket, + known_last_component: &mut ComponentsSet, + unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - inside_loop: bool + inside_loop: bool, ) -> bool { - let mut known_last_component_if: ComponentsSet = known_last_component.clone(); + let mut known_last_component_if: ComponentsSet = known_last_component.clone(); let mut known_last_component_else: ComponentsSet = known_last_component.clone(); let mut unknown_last_component_if: ComponentsSet = unknown_last_component.clone(); let mut unknown_last_component_else: ComponentsSet = unknown_last_component.clone(); - let found_unknown_if :bool = visit_list( - &mut bucket.if_branch, - &mut known_last_component_if, - &mut unknown_last_component_if, + let found_unknown_if: bool = visit_list( + &mut bucket.if_branch, + &mut known_last_component_if, + &mut unknown_last_component_if, found_unknown_address, - inside_loop + inside_loop, ); - let found_unknown_else :bool = visit_list( - &mut bucket.if_branch, - &mut known_last_component_else, - &mut unknown_last_component_else, + let found_unknown_else: bool = visit_list( + &mut bucket.if_branch, + &mut known_last_component_else, + &mut unknown_last_component_else, found_unknown_address, - inside_loop + inside_loop, ); - let known_component_both_branches: ComponentsSet = known_last_component_if.intersection(& known_last_component_else).map(|s| s.clone()).collect(); - let known_component_one_branch: ComponentsSet = known_last_component_if.symmetric_difference(&known_last_component_else).map(|s| s.clone()).collect(); - - let mut new_unknown_component: ComponentsSet = unknown_last_component_if.union(&unknown_last_component_else).map(|s| s.clone()).collect(); - new_unknown_component = new_unknown_component.union(&known_component_one_branch).map(|s| s.clone()).collect(); - - let joined_unknown_component: ComponentsSet = unknown_last_component.union(&new_unknown_component).map(|s| s.clone()).collect(); - - *known_last_component = known_last_component.union(&known_component_both_branches).map(|s| s.clone()).collect(); - *unknown_last_component = joined_unknown_component.difference(&known_component_both_branches).map(|s| s.clone()).collect(); + let known_component_both_branches: ComponentsSet = known_last_component_if + .intersection(&known_last_component_else) + .map(|s| s.clone()) + .collect(); + let known_component_one_branch: ComponentsSet = known_last_component_if + .symmetric_difference(&known_last_component_else) + .map(|s| s.clone()) + .collect(); + + let mut new_unknown_component: ComponentsSet = + unknown_last_component_if.union(&unknown_last_component_else).map(|s| s.clone()).collect(); + new_unknown_component = + new_unknown_component.union(&known_component_one_branch).map(|s| s.clone()).collect(); + + let joined_unknown_component: ComponentsSet = + unknown_last_component.union(&new_unknown_component).map(|s| s.clone()).collect(); + + *known_last_component = + known_last_component.union(&known_component_both_branches).map(|s| s.clone()).collect(); + *unknown_last_component = joined_unknown_component + .difference(&known_component_both_branches) + .map(|s| s.clone()) + .collect(); found_unknown_if || found_unknown_else } pub fn visit_call( - bucket: &mut CallBucket, - known_last_component: &mut ComponentsSet, - unknown_last_component: &mut ComponentsSet, + bucket: &mut CallBucket, + known_last_component: &mut ComponentsSet, + unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - inside_loop: bool -)-> bool { + inside_loop: bool, +) -> bool { use ReturnType::*; if let Final(data) = &mut bucket.return_info { visit_address_type( - &mut data.dest_address_type, + &mut data.dest_address_type, known_last_component, unknown_last_component, found_unknown_address, - inside_loop + inside_loop, ) - } - else{ + } else { found_unknown_address } } pub fn visit_compute( - _bucket: &mut ComputeBucket, - _known_last_component: &mut ComponentsSet, - _unknown_last_component: &mut ComponentsSet, + _bucket: &mut ComputeBucket, + _known_last_component: &mut ComponentsSet, + _unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - _inside_loop: bool -) -> bool{ + _inside_loop: bool, +) -> bool { found_unknown_address } pub fn visit_load( - _bucket: &mut LoadBucket, - _known_last_component: &mut ComponentsSet, - _unknown_last_component: &mut ComponentsSet, + _bucket: &mut LoadBucket, + _known_last_component: &mut ComponentsSet, + _unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - _inside_loop: bool -) -> bool{ + _inside_loop: bool, +) -> bool { found_unknown_address } pub fn visit_loop( bucket: &mut LoopBucket, - known_last_component: &mut ComponentsSet, - unknown_last_component: &mut ComponentsSet, + known_last_component: &mut ComponentsSet, + unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - _inside_loop: bool -)-> bool{ + _inside_loop: bool, +) -> bool { let mut known_last_component_loop: ComponentsSet = known_last_component.clone(); let mut unknown_last_component_loop: ComponentsSet = unknown_last_component.clone(); - let found_unknown_address_new = visit_list( - &mut bucket.body, - &mut known_last_component_loop, - &mut unknown_last_component_loop, + let found_unknown_address_new = visit_list( + &mut bucket.body, + &mut known_last_component_loop, + &mut unknown_last_component_loop, found_unknown_address, - true + true, ); - let new_unknown_component: ComponentsSet = known_last_component_loop.union(&unknown_last_component_loop).map(|s| s.clone()).collect(); + let new_unknown_component: ComponentsSet = + known_last_component_loop.union(&unknown_last_component_loop).map(|s| s.clone()).collect(); - *known_last_component = known_last_component.difference(&new_unknown_component).map(|s| s.clone()).collect(); - *unknown_last_component = unknown_last_component.union(&new_unknown_component).map(|s| s.clone()).collect(); + *known_last_component = + known_last_component.difference(&new_unknown_component).map(|s| s.clone()).collect(); + *unknown_last_component = + unknown_last_component.union(&new_unknown_component).map(|s| s.clone()).collect(); found_unknown_address_new } pub fn visit_create_cmp( _bucket: &mut CreateCmpBucket, - _known_last_component: &mut ComponentsSet, - _unknown_last_component: &mut ComponentsSet, + _known_last_component: &mut ComponentsSet, + _unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - _inside_loop: bool -) -> bool{ + _inside_loop: bool, +) -> bool { found_unknown_address } pub fn visit_return( - _bucket: &mut ReturnBucket, - _known_last_component: &mut ComponentsSet, - _unknown_last_component: &mut ComponentsSet, + _bucket: &mut ReturnBucket, + _known_last_component: &mut ComponentsSet, + _unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - _inside_loop: bool -) -> bool{ + _inside_loop: bool, +) -> bool { found_unknown_address } pub fn visit_log( _bucket: &mut LogBucket, - _known_last_component: &mut ComponentsSet, - _unknown_last_component: &mut ComponentsSet, + _known_last_component: &mut ComponentsSet, + _unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - _inside_loop: bool -) -> bool{ + _inside_loop: bool, +) -> bool { found_unknown_address } -pub fn visit_assert(_bucket: &mut AssertBucket, - _known_last_component: &mut ComponentsSet, - _unknown_last_component: &mut ComponentsSet, +pub fn visit_assert( + _bucket: &mut AssertBucket, + _known_last_component: &mut ComponentsSet, + _unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - _inside_loop: bool -) -> bool{ + _inside_loop: bool, +) -> bool { found_unknown_address } -pub fn visit_value(_bucket: &mut ValueBucket, - _known_last_component: &mut ComponentsSet, - _unknown_last_component: &mut ComponentsSet, +pub fn visit_value( + _bucket: &mut ValueBucket, + _known_last_component: &mut ComponentsSet, + _unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - _inside_loop: bool -) -> bool{ + _inside_loop: bool, +) -> bool { found_unknown_address } - - pub fn visit_store( bucket: &mut StoreBucket, - known_last_component: &mut ComponentsSet, - unknown_last_component: &mut ComponentsSet, + known_last_component: &mut ComponentsSet, + unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - inside_loop: bool -)-> bool{ + inside_loop: bool, +) -> bool { visit_address_type( - &mut bucket.dest_address_type, + &mut bucket.dest_address_type, known_last_component, unknown_last_component, found_unknown_address, - inside_loop + inside_loop, ) } - pub fn visit_address_type( xtype: &mut AddressType, - known_last_component: &mut ComponentsSet, - unknown_last_component: &mut ComponentsSet, + known_last_component: &mut ComponentsSet, + unknown_last_component: &mut ComponentsSet, found_unknown_address: bool, - inside_loop: bool + inside_loop: bool, ) -> bool { use AddressType::*; use InputInformation::*; use StatusInput::*; use Instruction::*; - if let SubcmpSignal { cmp_address, input_information ,..} = xtype { - if let Input {..} = input_information{ - - if known_last_component.contains(&cmp_address.to_string()){ - *input_information = Input{status: NoLast}; + if let SubcmpSignal { cmp_address, input_information, .. } = xtype { + if let Input { .. } = input_information { + if known_last_component.contains(&cmp_address.to_string()) { + *input_information = Input { status: NoLast }; //println!("Poniendo un nolast en {}", cmp_address.to_string()); found_unknown_address - } - else if unknown_last_component.contains(&cmp_address.to_string()){ - *input_information = Input{status: Unknown}; + } else if unknown_last_component.contains(&cmp_address.to_string()) { + *input_information = Input { status: Unknown }; //println!("Poniendo un unknown en {}", cmp_address.to_string()); found_unknown_address - } - else{ - if let Value {..} = **cmp_address{ - if found_unknown_address{ - *input_information = Input{status: Unknown}; + } else { + if let Value { .. } = **cmp_address { + if found_unknown_address { + *input_information = Input { status: Unknown }; //println!("Poniendo un unknown en {}", cmp_address.to_string()); - } - else{ + } else { if inside_loop { - *input_information = Input{status: Unknown}; + *input_information = Input { status: Unknown }; //println!("Poniendo un unknown en {}", cmp_address.to_string()); - } - else{ - *input_information = Input{status: Last}; + } else { + *input_information = Input { status: Last }; //println!("Poniendo un last en {}", cmp_address.to_string()); } } known_last_component.insert(cmp_address.to_string()); unknown_last_component.remove(&cmp_address.to_string()); found_unknown_address - } - else{ - *input_information = Input{status: Unknown}; + } else { + *input_information = Input { status: Unknown }; //println!("Poniendo un unknown en {}", cmp_address.to_string()); false } } - } - else{ + } else { found_unknown_address } - } - else{ + } else { found_unknown_address } } - - - - diff --git a/compiler/src/ir_processing/mod.rs b/compiler/src/ir_processing/mod.rs index 4dee18a91..ad8e0e4f4 100644 --- a/compiler/src/ir_processing/mod.rs +++ b/compiler/src/ir_processing/mod.rs @@ -20,7 +20,6 @@ pub fn set_arena_size_in_calls( set_arena_size::visit_list(code, function_to_arena_size); } -pub fn build_inputs_info(code: &mut InstructionList){ - build_inputs_info::visit_list(code, &mut HashSet::new(), &mut HashSet::new(),false, false); +pub fn build_inputs_info(code: &mut InstructionList) { + build_inputs_info::visit_list(code, &mut HashSet::new(), &mut HashSet::new(), false, false); } - diff --git a/compiler/src/ir_processing/reduce_stack.rs b/compiler/src/ir_processing/reduce_stack.rs index c59bed223..13fefeed7 100644 --- a/compiler/src/ir_processing/reduce_stack.rs +++ b/compiler/src/ir_processing/reduce_stack.rs @@ -28,17 +28,16 @@ pub fn reduce_instruction(instr: Instruction) -> Instruction { pub fn reduce_compute(mut bucket: ComputeBucket) -> Instruction { use OperatorType::*; bucket.stack = reduce_list(bucket.stack); - if !bucket.op.is_address_op() || bucket.op == ToAddress { + if !bucket.op.is_address_op() || bucket.op == ToAddress { return IntoInstruction::into_instruction(bucket); } - + let op0 = *bucket.stack[0].clone(); let op1 = *bucket.stack[1].clone(); - let res = reduce_operands(op0, op1) - .map(|(a, b)| match bucket.op { + let res = reduce_operands(op0, op1).map(|(a, b)| match bucket.op { MulAddress => a * b, AddAddress => a + b, - _ => unreachable!() + _ => unreachable!(), }); if let Some(value) = res { let v_bucket = ValueBucket { @@ -81,21 +80,19 @@ pub fn reduce_loop(mut bucket: LoopBucket) -> Instruction { } pub fn reduce_log(mut bucket: LogBucket) -> Instruction { - let mut new_args_prints : Vec = Vec::new(); + let mut new_args_prints: Vec = Vec::new(); for print in bucket.argsprint { match print { - LogBucketArg::LogExp(exp)=> { + LogBucketArg::LogExp(exp) => { let print_aux = Allocate::allocate(reduce_instruction(*exp)); new_args_prints.push(LogBucketArg::LogExp(print_aux)); - - }, + } LogBucketArg::LogStr(s) => { new_args_prints.push(LogBucketArg::LogStr(s)); - }, + } } - } - + bucket.argsprint = new_args_prints; IntoInstruction::into_instruction(bucket) } diff --git a/compiler/src/ir_processing/set_arena_size.rs b/compiler/src/ir_processing/set_arena_size.rs index 8d772b8e0..3e57c2213 100644 --- a/compiler/src/ir_processing/set_arena_size.rs +++ b/compiler/src/ir_processing/set_arena_size.rs @@ -78,11 +78,10 @@ pub fn visit_return(bucket: &mut ReturnBucket, function_to_arena_size: &HashMap< pub fn visit_log(bucket: &mut LogBucket, function_to_arena_size: &HashMap) { for print in bucket.argsprint.clone() { - if let LogBucketArg::LogExp(mut exp) = print { + if let LogBucketArg::LogExp(mut exp) = print { visit_instruction(&mut exp, function_to_arena_size); } } - } pub fn visit_assert(bucket: &mut AssertBucket, function_to_arena_size: &HashMap) { diff --git a/constraint_generation/src/compute_constants.rs b/constraint_generation/src/compute_constants.rs index 9d515d22b..a13b60e1f 100644 --- a/constraint_generation/src/compute_constants.rs +++ b/constraint_generation/src/compute_constants.rs @@ -18,7 +18,11 @@ struct Context<'a> { program_archive: &'a ProgramArchive, } -pub fn manage_functions(program_archive: &mut ProgramArchive, flags: FlagsExecution, prime: &String) -> CCResult { +pub fn manage_functions( + program_archive: &mut ProgramArchive, + flags: FlagsExecution, + prime: &String, +) -> CCResult { let mut reports = vec![]; let mut processed = HashMap::new(); for (name, data) in program_archive.get_functions() { @@ -43,7 +47,7 @@ pub fn compute_vct( instances: &mut Vec, program_archive: &ProgramArchive, flags: FlagsExecution, - prime: &String + prime: &String, ) -> CCResult { let mut reports = vec![]; for instance in instances { @@ -76,7 +80,13 @@ fn argument_into_slice(argument: &Argument) -> AExpressionSlice { AExpressionSlice::new_array(dimensions, arithmetic_expressions) } -fn treat_statement(stmt: &mut Statement, context: &Context, reports: &mut ReportCollection, flags: FlagsExecution, prime: &String) { +fn treat_statement( + stmt: &mut Statement, + context: &Context, + reports: &mut ReportCollection, + flags: FlagsExecution, + prime: &String, +) { if stmt.is_initialization_block() { treat_init_block(stmt, context, reports, flags, prime) } else if stmt.is_block() { @@ -85,13 +95,19 @@ fn treat_statement(stmt: &mut Statement, context: &Context, reports: &mut Report treat_conditional(stmt, context, reports, flags, prime) } else if stmt.is_while() { treat_while(stmt, context, reports, flags, prime) - } else if stmt.is_declaration(){ + } else if stmt.is_declaration() { treat_declaration(stmt, context, reports, flags, prime) } else { } } -fn treat_init_block(stmt: &mut Statement, context: &Context, reports: &mut ReportCollection, flags: FlagsExecution, prime: &String) { +fn treat_init_block( + stmt: &mut Statement, + context: &Context, + reports: &mut ReportCollection, + flags: FlagsExecution, + prime: &String, +) { use Statement::InitializationBlock; if let InitializationBlock { initializations, .. } = stmt { for init in initializations { @@ -104,7 +120,13 @@ fn treat_init_block(stmt: &mut Statement, context: &Context, reports: &mut Repor } } -fn treat_block(stmt: &mut Statement, context: &Context, reports: &mut ReportCollection, flags: FlagsExecution, prime: &String) { +fn treat_block( + stmt: &mut Statement, + context: &Context, + reports: &mut ReportCollection, + flags: FlagsExecution, + prime: &String, +) { use Statement::Block; if let Block { stmts, .. } = stmt { for s in stmts { @@ -115,7 +137,13 @@ fn treat_block(stmt: &mut Statement, context: &Context, reports: &mut ReportColl } } -fn treat_while(stmt: &mut Statement, context: &Context, reports: &mut ReportCollection, flags: FlagsExecution, prime: &String) { +fn treat_while( + stmt: &mut Statement, + context: &Context, + reports: &mut ReportCollection, + flags: FlagsExecution, + prime: &String, +) { use Statement::While; if let While { stmt, .. } = stmt { treat_statement(stmt, context, reports, flags, prime); @@ -124,7 +152,13 @@ fn treat_while(stmt: &mut Statement, context: &Context, reports: &mut ReportColl } } -fn treat_conditional(stmt: &mut Statement, context: &Context, reports: &mut ReportCollection, flags: FlagsExecution, prime: &String) { +fn treat_conditional( + stmt: &mut Statement, + context: &Context, + reports: &mut ReportCollection, + flags: FlagsExecution, + prime: &String, +) { use Statement::IfThenElse; if let IfThenElse { if_case, else_case, .. } = stmt { treat_statement(if_case, context, reports, flags, prime); @@ -136,15 +170,21 @@ fn treat_conditional(stmt: &mut Statement, context: &Context, reports: &mut Repo } } -fn treat_declaration(stmt: &mut Statement, context: &Context, reports: &mut ReportCollection, flags: FlagsExecution, prime: &String) { +fn treat_declaration( + stmt: &mut Statement, + context: &Context, + reports: &mut ReportCollection, + flags: FlagsExecution, + prime: &String, +) { use Statement::Declaration; use program_structure::ast::VariableType::AnonymousComponent; if let Declaration { meta, dimensions, xtype, .. } = stmt { let mut concrete_dimensions = vec![]; - match xtype { + match xtype { AnonymousComponent => { meta.get_mut_memory_knowledge().set_concrete_dimensions(vec![]); - }, + } _ => { for d in dimensions.iter_mut() { let execution_response = treat_dimension(d, context, reports, flags, prime); @@ -166,7 +206,7 @@ fn treat_dimension( dim: &Expression, context: &Context, reports: &mut ReportCollection, - flags: FlagsExecution, + flags: FlagsExecution, prime: &String, ) -> Option { use crate::execute::execute_constant_expression; diff --git a/constraint_generation/src/environment_utils/component_representation.rs b/constraint_generation/src/environment_utils/component_representation.rs index 4bd36fe87..12cf47bf6 100644 --- a/constraint_generation/src/environment_utils/component_representation.rs +++ b/constraint_generation/src/environment_utils/component_representation.rs @@ -1,7 +1,9 @@ -use super::slice_types::{MemoryError, TypeInvalidAccess, TypeAssignmentError, SignalSlice, SliceCapacity,TagInfo}; +use super::slice_types::{ + MemoryError, TypeInvalidAccess, TypeAssignmentError, SignalSlice, SliceCapacity, TagInfo, +}; use crate::execution_data::type_definitions::NodePointer; use crate::execution_data::ExecutedProgram; -use std::collections::{BTreeMap,HashMap, HashSet}; +use std::collections::{BTreeMap, HashMap, HashSet}; use crate::ast::Meta; pub struct ComponentRepresentation { @@ -48,7 +50,7 @@ impl Clone for ComponentRepresentation { outputs: self.outputs.clone(), outputs_tags: self.outputs_tags.clone(), is_initialized: self.is_initialized, - meta : self.meta.clone(), + meta: self.meta.clone(), } } } @@ -61,9 +63,11 @@ impl ComponentRepresentation { scheme: &ExecutedProgram, is_anonymous_component: bool, meta: &Meta, - ) -> Result<(), MemoryError>{ + ) -> Result<(), MemoryError> { if !is_anonymous_component && component.is_preinitialized() { - return Result::Err(MemoryError::AssignmentError(TypeAssignmentError::MultipleAssignments)); + return Result::Err(MemoryError::AssignmentError( + TypeAssignmentError::MultipleAssignments, + )); } let possible_node = ExecutedProgram::get_prenode(scheme, prenode_pointer); assert!(possible_node.is_some()); @@ -77,7 +81,7 @@ impl ComponentRepresentation { unassigned_tags.insert(symbol.clone()); } let mut new_tags = TagInfo::new(); - for t in tags{ + for t in tags { new_tags.insert(t.clone(), Option::None); } inputs_tags.insert(symbol.clone(), new_tags); @@ -85,7 +89,7 @@ impl ComponentRepresentation { for (symbol, tags) in node.outputs() { let mut new_tags = TagInfo::new(); - for t in tags{ + for t in tags { new_tags.insert(t.clone(), Option::None); } outputs_tags.insert(symbol.clone(), new_tags); @@ -120,24 +124,23 @@ impl ComponentRepresentation { for (symbol, route) in node.inputs() { let signal_slice = SignalSlice::new_with_route(route, &false); let signal_slice_size = SignalSlice::get_number_of_cells(&signal_slice); - if signal_slice_size > 0{ - component.unassigned_inputs - .insert(symbol.clone(), signal_slice_size); + if signal_slice_size > 0 { + component.unassigned_inputs.insert(symbol.clone(), signal_slice_size); } component.inputs.insert(symbol.clone(), signal_slice); } for (symbol, route) in node.outputs() { component.outputs.insert(symbol.clone(), SignalSlice::new_with_route(route, &true)); - + let tags_output = node.signal_to_tags.get(symbol); let component_tags_output = component.outputs_tags.get_mut(symbol); - if tags_output.is_some() && component_tags_output.is_some(){ + if tags_output.is_some() && component_tags_output.is_some() { let result_tags_output = tags_output.unwrap(); let result_component_tags_output = component_tags_output.unwrap(); - for (tag, value) in result_tags_output{ + for (tag, value) in result_tags_output { // only update the output tag in case it contains the tag in the definition - if result_component_tags_output.contains_key(tag){ + if result_component_tags_output.contains_key(tag) { result_component_tags_output.insert(tag.clone(), value.clone()); } } @@ -146,60 +149,71 @@ impl ComponentRepresentation { component.node_pointer = Option::Some(node_pointer); let to_assign = component.to_assign_inputs.clone(); - for s in to_assign{ + for s in to_assign { let tags_input = component.inputs_tags.get(&s.0).unwrap(); - ComponentRepresentation::assign_value_to_signal_init(component, &s.0, &s.1, &s.2, tags_input.clone())?; + ComponentRepresentation::assign_value_to_signal_init( + component, + &s.0, + &s.1, + &s.2, + tags_input.clone(), + )?; } Result::Ok(()) } -/* - pub fn signal_has_value( - component: &ComponentRepresentation, - signal_name: &str, - access: &[SliceCapacity], - ) -> Result { - if component.node_pointer.is_none() { - return Result::Err(MemoryError::InvalidAccess); - } - if component.outputs.contains_key(signal_name) && !component.unassigned_inputs.is_empty() { - return Result::Err(MemoryError::InvalidAccess); - } - if !component.is_initialized{ - return Result::Err(MemoryError::InvalidAccess); - } + /* + pub fn signal_has_value( + component: &ComponentRepresentation, + signal_name: &str, + access: &[SliceCapacity], + ) -> Result { + if component.node_pointer.is_none() { + return Result::Err(MemoryError::InvalidAccess); + } + if component.outputs.contains_key(signal_name) && !component.unassigned_inputs.is_empty() { + return Result::Err(MemoryError::InvalidAccess); + } + if !component.is_initialized{ + return Result::Err(MemoryError::InvalidAccess); + } - let slice = if component.inputs.contains_key(signal_name) { - component.inputs.get(signal_name).unwrap() - } else { - component.outputs.get(signal_name).unwrap() - }; + let slice = if component.inputs.contains_key(signal_name) { + component.inputs.get(signal_name).unwrap() + } else { + component.outputs.get(signal_name).unwrap() + }; - let enabled_slice = SignalSlice::access_values(&slice, &access)?; - let mut enabled = false; - for i in 0..SignalSlice::get_number_of_cells(&enabled_slice) { - enabled |= SignalSlice::get_reference_to_single_value_by_index(&enabled_slice, i)?; + let enabled_slice = SignalSlice::access_values(&slice, &access)?; + let mut enabled = false; + for i in 0..SignalSlice::get_number_of_cells(&enabled_slice) { + enabled |= SignalSlice::get_reference_to_single_value_by_index(&enabled_slice, i)?; + } + Result::Ok(enabled) } - Result::Ok(enabled) - } -*/ + */ pub fn get_signal(&self, signal_name: &str) -> Result<(&TagInfo, &SignalSlice), MemoryError> { - if self.node_pointer.is_none() { - return Result::Err(MemoryError::InvalidAccess(TypeInvalidAccess::NoInitializedComponent)); + return Result::Err(MemoryError::InvalidAccess( + TypeInvalidAccess::NoInitializedComponent, + )); } if self.outputs.contains_key(signal_name) && !self.unassigned_inputs.is_empty() { // we return the name of an input that has not been assigned let ex_signal = self.unassigned_inputs.iter().next().unwrap().0.clone(); - return Result::Err(MemoryError::InvalidAccess(TypeInvalidAccess::MissingInputs(ex_signal))); + return Result::Err(MemoryError::InvalidAccess(TypeInvalidAccess::MissingInputs( + ex_signal, + ))); } if !self.is_initialized { // we return the name of an input with tags that has not been assigned let ex_signal = self.unassigned_tags.iter().next().unwrap().clone(); - return Result::Err(MemoryError::InvalidAccess(TypeInvalidAccess::MissingInputTags(ex_signal))); + return Result::Err(MemoryError::InvalidAccess(TypeInvalidAccess::MissingInputTags( + ex_signal, + ))); } - + let slice = if self.inputs.contains_key(signal_name) { (self.inputs_tags.get(signal_name).unwrap(), self.inputs.get(signal_name).unwrap()) } else { @@ -215,31 +229,31 @@ impl ComponentRepresentation { slice_route: &[SliceCapacity], tags: TagInfo, ) -> Result<(), MemoryError> { - if !component.is_initialized{ + if !component.is_initialized { ComponentRepresentation::assign_value_to_signal_no_init( - component, - signal_name, - access, + component, + signal_name, + access, slice_route, - tags + tags, ) } else { ComponentRepresentation::assign_value_to_signal_init( component, - signal_name, - access, + signal_name, + access, slice_route, - tags + tags, ) } } /* - Tags: - - If an input receives a value that does not contain a expected tag ==> error - - If an input receives a tag whose value is different to the expected (the one received earlier) ==> error - - */ + Tags: + - If an input receives a value that does not contain a expected tag ==> error + - If an input receives a tag whose value is different to the expected (the one received earlier) ==> error + + */ pub fn assign_value_to_signal_no_init( component: &mut ComponentRepresentation, @@ -248,11 +262,12 @@ impl ComponentRepresentation { slice_route: &[SliceCapacity], tags: TagInfo, ) -> Result<(), MemoryError> { - // We copy tags in any case, complete or incomplete assignment // The values of the tags must be the same than the ones stored before - if !component.inputs_tags.contains_key(signal_name){ - return Result::Err(MemoryError::AssignmentError(TypeAssignmentError::AssignmentOutput)); + if !component.inputs_tags.contains_key(signal_name) { + return Result::Err(MemoryError::AssignmentError( + TypeAssignmentError::AssignmentOutput, + )); } let tags_input = component.inputs_tags.get_mut(signal_name).unwrap(); @@ -260,22 +275,25 @@ impl ComponentRepresentation { let is_first_assignment_signal = component.unassigned_tags.contains(signal_name); component.unassigned_tags.remove(signal_name); - for (t, value) in tags_input{ - if !tags.contains_key(t){ + for (t, value) in tags_input { + if !tags.contains_key(t) { return Result::Err(MemoryError::AssignmentMissingTags(t.clone())); - } else{ - if is_first_assignment_signal{ + } else { + if is_first_assignment_signal { *value = tags.get(t).unwrap().clone(); - } - else{ + } else { // already given a value, check that it is the same - if value != tags.get(t).unwrap(){ + if value != tags.get(t).unwrap() { return Result::Err(MemoryError::AssignmentTagInputTwice(t.clone())); } } } } - component.to_assign_inputs.push((signal_name.to_string(), access.to_vec(), slice_route.to_vec())); + component.to_assign_inputs.push(( + signal_name.to_string(), + access.to_vec(), + slice_route.to_vec(), + )); Result::Ok(()) } @@ -286,55 +304,51 @@ impl ComponentRepresentation { slice_route: &[SliceCapacity], tags: TagInfo, ) -> Result<(), MemoryError> { - - if !component.inputs.contains_key(signal_name){ - return Result::Err(MemoryError::AssignmentError(TypeAssignmentError::AssignmentOutput)); + if !component.inputs.contains_key(signal_name) { + return Result::Err(MemoryError::AssignmentError( + TypeAssignmentError::AssignmentOutput, + )); } let tags_input = component.inputs_tags.get_mut(signal_name).unwrap(); - for (t, value) in tags_input{ - if !tags.contains_key(t){ + for (t, value) in tags_input { + if !tags.contains_key(t) { return Result::Err(MemoryError::AssignmentMissingTags(t.clone())); - } else{ - // We are in the case where the component is initialized, so we + } else { + // We are in the case where the component is initialized, so we // assume that all tags already have their value and check if it is // the same as the one we are receiving - if value != tags.get(t).unwrap(){ + if value != tags.get(t).unwrap() { return Result::Err(MemoryError::AssignmentTagInputTwice(t.clone())); } } } let inputs_response = component.inputs.get_mut(signal_name).unwrap(); - let signal_previous_value = SignalSlice::access_values( - inputs_response, - &access, - )?; + let signal_previous_value = SignalSlice::access_values(inputs_response, &access)?; let new_value_slice = &SignalSlice::new_with_route(slice_route, &true); SignalSlice::check_correct_dims( - &signal_previous_value, - &Vec::new(), - &new_value_slice, - true + &signal_previous_value, + &Vec::new(), + &new_value_slice, + true, )?; - for i in 0..SignalSlice::get_number_of_cells(&signal_previous_value){ - let signal_was_assigned = SignalSlice::access_value_by_index(&signal_previous_value, i)?; + for i in 0..SignalSlice::get_number_of_cells(&signal_previous_value) { + let signal_was_assigned = + SignalSlice::access_value_by_index(&signal_previous_value, i)?; if signal_was_assigned { - return Result::Err(MemoryError::AssignmentError(TypeAssignmentError::MultipleAssignments)); + return Result::Err(MemoryError::AssignmentError( + TypeAssignmentError::MultipleAssignments, + )); } } - - SignalSlice::insert_values( - inputs_response, - &access, - &new_value_slice, - true - )?; + + SignalSlice::insert_values(inputs_response, &access, &new_value_slice, true)?; let dim = SignalSlice::get_number_of_cells(new_value_slice); - match component.unassigned_inputs.get_mut(signal_name){ + match component.unassigned_inputs.get_mut(signal_name) { Some(left) => { *left -= dim; if *left == 0 { @@ -345,7 +359,6 @@ impl ComponentRepresentation { } Result::Ok(()) - } pub fn is_preinitialized(&self) -> bool { self.node_pointer.is_some() @@ -355,8 +368,7 @@ impl ComponentRepresentation { self.unassigned_tags.is_empty() } - pub fn has_unassigned_inputs(&self) -> bool{ + pub fn has_unassigned_inputs(&self) -> bool { !self.unassigned_inputs.is_empty() } - } diff --git a/constraint_generation/src/environment_utils/environment.rs b/constraint_generation/src/environment_utils/environment.rs index 3dca8c5a8..3a5f35fe5 100644 --- a/constraint_generation/src/environment_utils/environment.rs +++ b/constraint_generation/src/environment_utils/environment.rs @@ -1,19 +1,17 @@ use super::slice_types::{ - AExpressionSlice, - ComponentRepresentation, - ComponentSlice, - SignalSlice, - SliceCapacity, - TagInfo, - TagDefinitions, - TagState + AExpressionSlice, ComponentRepresentation, ComponentSlice, SignalSlice, SliceCapacity, TagInfo, + TagDefinitions, TagState, }; use super::{ArithmeticExpression, CircomEnvironment, CircomEnvironmentError}; use program_structure::memory_slice::MemoryError; use crate::ast::Meta; pub type ExecutionEnvironmentError = CircomEnvironmentError; -pub type ExecutionEnvironment = CircomEnvironment; +pub type ExecutionEnvironment = CircomEnvironment< + ComponentSlice, + (TagInfo, TagDefinitions, SignalSlice), + (TagInfo, AExpressionSlice), +>; pub fn environment_shortcut_add_component( environment: &mut ExecutionEnvironment, @@ -31,11 +29,14 @@ pub fn environment_shortcut_add_input( ) { let slice = SignalSlice::new_with_route(dimensions, &true); let mut tags_defined = TagDefinitions::new(); - for (t, value) in tags{ - tags_defined.insert(t.clone(), TagState{defined:true, value_defined: value.is_some(), complete: true}); + for (t, value) in tags { + tags_defined.insert( + t.clone(), + TagState { defined: true, value_defined: value.is_some(), complete: true }, + ); } - - environment.add_input(input_name, (tags.clone(), tags_defined, slice)); + + environment.add_input(input_name, (tags.clone(), tags_defined, slice)); } pub fn environment_shortcut_add_output( environment: &mut ExecutionEnvironment, @@ -45,8 +46,11 @@ pub fn environment_shortcut_add_output( ) { let slice = SignalSlice::new_with_route(dimensions, &false); let mut tags_defined = TagDefinitions::new(); - for (t, value) in tags{ - tags_defined.insert(t.clone(), TagState{defined:true, value_defined: value.is_some(), complete: false}); + for (t, value) in tags { + tags_defined.insert( + t.clone(), + TagState { defined: true, value_defined: value.is_some(), complete: false }, + ); } environment.add_output(output_name, (tags.clone(), tags_defined, slice)); } @@ -58,8 +62,11 @@ pub fn environment_shortcut_add_intermediate( ) { let slice = SignalSlice::new_with_route(dimensions, &false); let mut tags_defined = TagDefinitions::new(); - for (t, value) in tags{ - tags_defined.insert(t.clone(), TagState{defined:true, value_defined: value.is_some(), complete: false}); + for (t, value) in tags { + tags_defined.insert( + t.clone(), + TagState { defined: true, value_defined: value.is_some(), complete: false }, + ); } environment.add_intermediate(intermediate_name, (tags.clone(), tags_defined, slice)); } @@ -72,15 +79,20 @@ pub fn environment_shortcut_add_variable( environment.add_variable(variable_name, (TagInfo::new(), slice)); } -pub fn environment_check_all_components_assigned(environment: &ExecutionEnvironment)-> Result<(), (MemoryError, Meta)>{ +pub fn environment_check_all_components_assigned( + environment: &ExecutionEnvironment, +) -> Result<(), (MemoryError, Meta)> { use program_structure::memory_slice::MemorySlice; - for (name, slice) in environment.get_components_ref(){ - for i in 0..MemorySlice::get_number_of_cells(slice){ + for (name, slice) in environment.get_components_ref() { + for i in 0..MemorySlice::get_number_of_cells(slice) { let component = MemorySlice::get_reference_to_single_value_by_index_or_break(slice, i); - if component.is_preinitialized() && component.has_unassigned_inputs(){ - return Result::Err((MemoryError::MissingInputs(name.clone()), component.meta.as_ref().unwrap().clone())); - } + if component.is_preinitialized() && component.has_unassigned_inputs() { + return Result::Err(( + MemoryError::MissingInputs(name.clone()), + component.meta.as_ref().unwrap().clone(), + )); + } } } Result::Ok(()) -} \ No newline at end of file +} diff --git a/constraint_generation/src/environment_utils/slice_types.rs b/constraint_generation/src/environment_utils/slice_types.rs index 83e99fc4b..4d6832e10 100644 --- a/constraint_generation/src/environment_utils/slice_types.rs +++ b/constraint_generation/src/environment_utils/slice_types.rs @@ -6,10 +6,10 @@ pub use num_bigint::BigInt; use std::collections::BTreeMap; #[derive(Debug, Copy, Clone)] -pub struct TagState{ - pub defined: bool, // if it appears in the definition of the signal +pub struct TagState { + pub defined: bool, // if it appears in the definition of the signal pub value_defined: bool, // if the value is given by the user - pub complete: bool, // if the signal is completely initialized + pub complete: bool, // if the signal is completely initialized } pub type TagInfo = BTreeMap>; pub type TagDefinitions = BTreeMap; // the tags defined for each signal and if the info about their state diff --git a/constraint_generation/src/execute.rs b/constraint_generation/src/execute.rs index 775dcb501..364ca3000 100644 --- a/constraint_generation/src/execute.rs +++ b/constraint_generation/src/execute.rs @@ -3,12 +3,12 @@ use super::environment_utils::{ environment_shortcut_add_component, environment_shortcut_add_input, environment_shortcut_add_intermediate, environment_shortcut_add_output, environment_shortcut_add_variable, ExecutionEnvironment, ExecutionEnvironmentError, - environment_check_all_components_assigned + environment_check_all_components_assigned, }, slice_types::{ AExpressionSlice, ArithmeticExpression as ArithmeticExpressionGen, ComponentRepresentation, - ComponentSlice, MemoryError, TypeInvalidAccess, TypeAssignmentError, MemorySlice, - SignalSlice, SliceCapacity, TagInfo, TagState + ComponentSlice, MemoryError, TypeInvalidAccess, TypeAssignmentError, MemorySlice, + SignalSlice, SliceCapacity, TagInfo, TagState, }, }; @@ -16,9 +16,7 @@ use program_structure::constants::UsefulConstants; use super::execution_data::analysis::Analysis; use super::execution_data::{ExecutedProgram, ExecutedTemplate, PreExecutedTemplate, NodePointer}; -use super::{ - ast::*, ArithmeticError, FileID, ProgramArchive, Report, ReportCode, ReportCollection -}; +use super::{ast::*, ArithmeticError, FileID, ProgramArchive, Report, ReportCode, ReportCollection}; use circom_algebra::num_bigint::BigInt; use std::collections::{HashMap, BTreeMap}; use std::mem; @@ -69,19 +67,23 @@ struct FoldedValue { } impl FoldedValue { pub fn valid_arithmetic_slice(f_value: &FoldedValue) -> bool { - f_value.arithmetic_slice.is_some() && f_value.node_pointer.is_none() && f_value.is_parallel.is_none() + f_value.arithmetic_slice.is_some() + && f_value.node_pointer.is_none() + && f_value.is_parallel.is_none() } pub fn valid_node_pointer(f_value: &FoldedValue) -> bool { - f_value.node_pointer.is_some() && f_value.is_parallel.is_some() && f_value.arithmetic_slice.is_none() + f_value.node_pointer.is_some() + && f_value.is_parallel.is_some() + && f_value.arithmetic_slice.is_none() } } impl Default for FoldedValue { fn default() -> Self { - FoldedValue { - arithmetic_slice: Option::None, - node_pointer: Option::None, - is_parallel: Option::None, + FoldedValue { + arithmetic_slice: Option::None, + node_pointer: Option::None, + is_parallel: Option::None, tags: Option::None, } } @@ -90,7 +92,7 @@ impl Default for FoldedValue { enum ExecutionError { NonQuadraticConstraint, FalseAssert, - ArraySizeTooBig + ArraySizeTooBig, } enum ExecutionWarning { @@ -98,40 +100,43 @@ enum ExecutionWarning { CanBeQuadraticConstraintMultiple(Vec), } - - pub fn constraint_execution( program_archive: &ProgramArchive, - flags: FlagsExecution, + flags: FlagsExecution, prime: &String, -) -> Result<(ExecutedProgram, ReportCollection), ReportCollection> { +) -> Result<(ExecutedProgram, ReportCollection), ReportCollection> { let main_file_id = program_archive.get_file_id_main(); - let mut runtime_information = RuntimeInformation::new(*main_file_id, program_archive.id_max, prime); + let mut runtime_information = + RuntimeInformation::new(*main_file_id, program_archive.id_max, prime); use Expression::Call; runtime_information.public_inputs = program_archive.get_public_inputs_main_component().clone(); - - let folded_value_result = - if let Call { id, args, .. } = &program_archive.get_main_expression() { - let mut arg_values = Vec::new(); - for arg_expression in args.iter() { - let f_arg = execute_expression(arg_expression, program_archive, &mut runtime_information, flags); - arg_values.push(safe_unwrap_to_arithmetic_slice(f_arg.unwrap(), line!())); - // improve - } - execute_template_call_complete( - id, - arg_values, - BTreeMap::new(), + + let folded_value_result = if let Call { id, args, .. } = &program_archive.get_main_expression() + { + let mut arg_values = Vec::new(); + for arg_expression in args.iter() { + let f_arg = execute_expression( + arg_expression, program_archive, &mut runtime_information, flags, - ) - } else { - unreachable!("The main expression should be a call."); - }; - - + ); + arg_values.push(safe_unwrap_to_arithmetic_slice(f_arg.unwrap(), line!())); + // improve + } + execute_template_call_complete( + id, + arg_values, + BTreeMap::new(), + program_archive, + &mut runtime_information, + flags, + ) + } else { + unreachable!("The main expression should be a call."); + }; + match folded_value_result { Result::Err(_) => Result::Err(runtime_information.runtime_errors), Result::Ok(folded_value) => { @@ -149,7 +154,8 @@ pub fn execute_constant_expression( prime: &String, ) -> Result { let current_file = expression.get_meta().get_file_id(); - let mut runtime_information = RuntimeInformation::new(current_file, program_archive.id_max, prime); + let mut runtime_information = + RuntimeInformation::new(current_file, program_archive.id_max, prime); runtime_information.environment = environment; let folded_value_result = execute_expression(expression, program_archive, &mut runtime_information, flags); @@ -187,8 +193,8 @@ fn execute_statement( program_archive, runtime, actual_node, - flags, - false + flags, + false, )?; debug_assert!(possible_fold.is_none()); possible_fold @@ -207,10 +213,12 @@ fn execute_statement( _ => { let mut arithmetic_values = Vec::new(); for dimension in dimensions.iter() { - let f_dimensions = + let f_dimensions = execute_expression(dimension, program_archive, runtime, flags)?; - arithmetic_values - .push(safe_unwrap_to_single_arithmetic_expression(f_dimensions, line!())); + arithmetic_values.push(safe_unwrap_to_single_arithmetic_expression( + f_dimensions, + line!(), + )); } treat_result_with_memory_error_void( valid_array_declaration(&arithmetic_values), @@ -250,27 +258,38 @@ fn execute_statement( &mut runtime.environment, actual_node, ), - _ =>{ + _ => { unreachable!() } } - } } Option::None } Substitution { meta, var, access, op, rhe, .. } => { - let access_information = treat_accessing(meta, access, program_archive, runtime, flags)?; + let access_information = + treat_accessing(meta, access, program_archive, runtime, flags)?; let r_folded = execute_expression(rhe, program_archive, runtime, flags)?; - let possible_constraint = - perform_assign(meta, var, *op, &access_information, r_folded, actual_node, runtime, program_archive, flags)?; + let possible_constraint = perform_assign( + meta, + var, + *op, + &access_information, + r_folded, + actual_node, + runtime, + program_archive, + flags, + )?; if let Option::Some(node) = actual_node { - if *op == AssignOp::AssignConstraintSignal || (*op == AssignOp::AssignSignal && flags.inspect){ + if *op == AssignOp::AssignConstraintSignal + || (*op == AssignOp::AssignSignal && flags.inspect) + { debug_assert!(possible_constraint.is_some()); let constrained = possible_constraint.unwrap(); let mut needs_double_arrow = Vec::new(); - for i in 0..AExpressionSlice::get_number_of_cells(&constrained.right){ + for i in 0..AExpressionSlice::get_number_of_cells(&constrained.right) { let value_right = treat_result_with_memory_error( AExpressionSlice::access_value_by_index(&constrained.right, i), meta, @@ -278,18 +297,15 @@ fn execute_statement( &runtime.call_trace, )?; - let access_left = treat_result_with_memory_error( AExpressionSlice::get_access_index(&constrained.right, i), meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; - - let full_symbol = format!("{}{}", - constrained.left, - create_index_appendix(&access_left), - ); + + let full_symbol = + format!("{}{}", constrained.left, create_index_appendix(&access_left),); if let AssignOp::AssignConstraintSignal = op { if value_right.is_nonquadratic() { let err = Result::Err(ExecutionError::NonQuadraticConstraint); @@ -303,10 +319,12 @@ fn execute_statement( let p = runtime.constants.get_p().clone(); let symbol = AExpr::Signal { symbol: full_symbol }; let expr = AExpr::sub(&symbol, &value_right, &p); - let ctr = AExpr::transform_expression_to_constraint_form(expr, &p).unwrap(); + let ctr = AExpr::transform_expression_to_constraint_form(expr, &p) + .unwrap(); node.add_constraint(ctr); } - } else if let AssignOp::AssignSignal = op {// needs fix, check case arrays + } else if let AssignOp::AssignSignal = op { + // needs fix, check case arrays //debug_assert!(possible_constraint.is_some()); if !value_right.is_nonquadratic() && !node.is_custom_gate { needs_double_arrow.push(full_symbol); @@ -314,32 +332,36 @@ fn execute_statement( } } - if !needs_double_arrow.is_empty() && flags.inspect{ + if !needs_double_arrow.is_empty() && flags.inspect { // in case we can subsitute the complete expression to ==> - if needs_double_arrow.len() == AExpressionSlice::get_number_of_cells(&constrained.right){ - let err : Result<(),ExecutionWarning> = + if needs_double_arrow.len() + == AExpressionSlice::get_number_of_cells(&constrained.right) + { + let err: Result<(), ExecutionWarning> = Result::Err(ExecutionWarning::CanBeQuadraticConstraintSingle()); - + treat_result_with_execution_warning( err, meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; - } else{ - let err : Result<(),ExecutionWarning> = - Result::Err(ExecutionWarning::CanBeQuadraticConstraintMultiple(needs_double_arrow)); - + } else { + let err: Result<(), ExecutionWarning> = + Result::Err(ExecutionWarning::CanBeQuadraticConstraintMultiple( + needs_double_arrow, + )); + treat_result_with_execution_warning( - err, + err, meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; } } - } - } + } + } Option::None } ConstraintEquality { meta, lhe, rhe, .. } => { @@ -349,14 +371,15 @@ fn execute_statement( let arith_left = safe_unwrap_to_arithmetic_slice(f_left, line!()); let arith_right = safe_unwrap_to_arithmetic_slice(f_right, line!()); - let correct_dims_result = AExpressionSlice::check_correct_dims(&arith_left, &Vec::new(), &arith_right, true); + let correct_dims_result = + AExpressionSlice::check_correct_dims(&arith_left, &Vec::new(), &arith_right, true); treat_result_with_memory_error_void( correct_dims_result, meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; - for i in 0..AExpressionSlice::get_number_of_cells(&arith_left){ + for i in 0..AExpressionSlice::get_number_of_cells(&arith_left) { let value_left = treat_result_with_memory_error( AExpressionSlice::access_value_by_index(&arith_left, i), meta, @@ -370,11 +393,7 @@ fn execute_statement( &runtime.call_trace, )?; let possible_non_quadratic = - AExpr::sub( - &value_left, - &value_right, - &runtime.constants.get_p() - ); + AExpr::sub(&value_left, &value_right, &runtime.constants.get_p()); if possible_non_quadratic.is_nonquadratic() { treat_result_with_execution_error( Result::Err(ExecutionError::NonQuadraticConstraint), @@ -391,7 +410,7 @@ fn execute_statement( .unwrap(); if let Option::Some(node) = actual_node { node.add_constraint(constraint_expression); - } + } } Option::None } @@ -414,7 +433,7 @@ fn execute_statement( program_archive, runtime, actual_node, - flags + flags, )?; can_be_simplified = can_simplify; possible_return @@ -427,7 +446,7 @@ fn execute_statement( program_archive, runtime, actual_node, - flags + flags, )?; can_be_simplified &= can_simplify; if returned.is_some() { @@ -440,7 +459,7 @@ fn execute_statement( program_archive, runtime, actual_node, - flags + flags, )?; break returned; } else if !condition_result.unwrap() { @@ -449,39 +468,43 @@ fn execute_statement( }, Block { stmts, .. } => { ExecutionEnvironment::add_variable_block(&mut runtime.environment); - let (return_value, can_simplify_block) = - execute_sequence_of_statements(stmts, program_archive, runtime, actual_node, flags, false)?; + let (return_value, can_simplify_block) = execute_sequence_of_statements( + stmts, + program_archive, + runtime, + actual_node, + flags, + false, + )?; ExecutionEnvironment::remove_variable_block(&mut runtime.environment); can_be_simplified = can_simplify_block; return_value } LogCall { args, .. } => { can_be_simplified = false; - if flags.verbose{ + if flags.verbose { let mut index = 0; for arglog in args { - if let LogArgument::LogExp(arg) = arglog{ + if let LogArgument::LogExp(arg) = arglog { let f_result = execute_expression(arg, program_archive, runtime, flags)?; let arith = safe_unwrap_to_single_arithmetic_expression(f_result, line!()); - if AExpr::is_number(&arith){ + if AExpr::is_number(&arith) { print!("{}", arith); - } - else{ + } else { print!("Unknown") } + } else if let LogArgument::LogStr(s) = arglog { + print!("{}", s); } - else if let LogArgument::LogStr(s) = arglog { - print!("{}",s); - } - if index != args.len()-1{ + if index != args.len() - 1 { print!(" "); } index += 1; } println!(""); - } else{ + } else { for arglog in args { - if let LogArgument::LogExp(arg) = arglog{ + if let LogArgument::LogExp(arg) = arglog { let f_result = execute_expression(arg, program_archive, runtime, flags)?; let _arith = safe_unwrap_to_single_arithmetic_expression(f_result, line!()); } @@ -508,11 +531,11 @@ fn execute_statement( &runtime.call_trace, )? } - UnderscoreSubstitution{ meta, rhe, op} =>{ + UnderscoreSubstitution { meta, rhe, op } => { let f_result = execute_expression(rhe, program_archive, runtime, flags)?; let arithmetic_slice = safe_unwrap_to_arithmetic_slice(f_result, line!()); - if *op == AssignOp::AssignConstraintSignal{ - for i in 0..AExpressionSlice::get_number_of_cells(&arithmetic_slice){ + if *op == AssignOp::AssignConstraintSignal { + for i in 0..AExpressionSlice::get_number_of_cells(&arithmetic_slice) { let value_cell = treat_result_with_memory_error( AExpressionSlice::access_value_by_index(&arithmetic_slice, i), meta, @@ -522,11 +545,12 @@ fn execute_statement( let constraint_expression = AExpr::transform_expression_to_constraint_form( value_cell, runtime.constants.get_p(), - ).unwrap(); + ) + .unwrap(); if let Option::Some(node) = actual_node { - for signal in constraint_expression.take_signals(){ + for signal in constraint_expression.take_signals() { node.add_underscored_signal(signal); - } + } } } } @@ -540,7 +564,7 @@ fn execute_expression( expr: &Expression, program_archive: &ProgramArchive, runtime: &mut RuntimeInformation, - flags: FlagsExecution + flags: FlagsExecution, ) -> Result { use Expression::*; let mut can_be_simplified = true; @@ -581,7 +605,7 @@ fn execute_expression( &mut array_slice, &[row], &arithmetic_slice_array[row], - false + false, ); treat_result_with_memory_error_void( memory_insert_result, @@ -595,16 +619,18 @@ fn execute_expression( } UniformArray { meta, value, dimension, .. } => { let f_dimension = execute_expression(dimension, program_archive, runtime, flags)?; - let arithmetic_dimension = safe_unwrap_to_single_arithmetic_expression(f_dimension, line!()); - let usable_dimension = if let Option::Some(dimension) = cast_index(&arithmetic_dimension) { - dimension - } else { - unreachable!() - }; + let arithmetic_dimension = + safe_unwrap_to_single_arithmetic_expression(f_dimension, line!()); + let usable_dimension = + if let Option::Some(dimension) = cast_index(&arithmetic_dimension) { + dimension + } else { + unreachable!() + }; let f_value = execute_expression(value, program_archive, runtime, flags)?; let slice_value = safe_unwrap_to_arithmetic_slice(f_value, line!()); - + let mut dims = vec![usable_dimension]; for dim in slice_value.route() { dims.push(*dim); @@ -613,12 +639,8 @@ fn execute_expression( let mut array_slice = AExpressionSlice::new_with_route(&dims, &AExpr::default()); let mut row: SliceCapacity = 0; while row < usable_dimension { - let memory_insert_result = AExpressionSlice::insert_values( - &mut array_slice, - &[row], - &slice_value, - false - ); + let memory_insert_result = + AExpressionSlice::insert_values(&mut array_slice, &[row], &slice_value, false); treat_result_with_memory_error_void( memory_insert_result, meta, @@ -667,18 +689,23 @@ fn execute_expression( can_be_simplified = can_simplify; value } - ParallelOp{rhe, ..} => { + ParallelOp { rhe, .. } => { let folded_value = execute_expression(rhe, program_archive, runtime, flags)?; - let (node_pointer, _) = - safe_unwrap_to_valid_node_pointer(folded_value, line!()); - FoldedValue { node_pointer: Option::Some(node_pointer), is_parallel: Option::Some(true), ..FoldedValue::default() } + let (node_pointer, _) = safe_unwrap_to_valid_node_pointer(folded_value, line!()); + FoldedValue { + node_pointer: Option::Some(node_pointer), + is_parallel: Option::Some(true), + ..FoldedValue::default() + } + } + _ => { + unreachable!("Anonymous calls should not be reachable at this point."); } - _ => {unreachable!("Anonymous calls should not be reachable at this point."); } }; let expr_id = expr.get_meta().elem_id; let res_p = res.arithmetic_slice.clone(); if let Some(slice) = res_p { - if slice.is_single() && can_be_simplified{ + if slice.is_single() && can_be_simplified { let value = AExpressionSlice::unwrap_to_single(slice); Analysis::computed(&mut runtime.analysis, expr_id, value); } @@ -686,7 +713,6 @@ fn execute_expression( Result::Ok(res) } - //************************************************* Statement execution support ************************************************* fn execute_call( @@ -701,11 +727,13 @@ fn execute_call( let f_arg = execute_expression(arg_expression, program_archive, runtime, flags)?; arg_values.push(safe_unwrap_to_arithmetic_slice(f_arg, line!())); } - if program_archive.contains_function(id){ // in this case we execute + if program_archive.contains_function(id) { + // in this case we execute let new_environment = prepare_environment_for_call(id, &arg_values, program_archive); let previous_environment = std::mem::replace(&mut runtime.environment, new_environment); let previous_block_type = std::mem::replace(&mut runtime.block_type, BlockType::Known); - let previous_anonymous_components = std::mem::replace(&mut runtime.anonymous_components, AnonymousComponentsInfo::new()); + let previous_anonymous_components = + std::mem::replace(&mut runtime.anonymous_components, AnonymousComponentsInfo::new()); let new_file_id = program_archive.get_function_data(id).get_file_id(); let previous_id = std::mem::replace(&mut runtime.current_file, new_file_id); @@ -719,7 +747,8 @@ fn execute_call( runtime.anonymous_components = previous_anonymous_components; runtime.call_trace.pop(); Ok(folded_result) - } else { // in this case we preexecute and check if it needs tags + } else { + // in this case we preexecute and check if it needs tags let folded_result = preexecute_template_call(id, &arg_values, program_archive, runtime)?; Ok((folded_result, true)) } @@ -733,17 +762,20 @@ fn execute_template_call_complete( runtime: &mut RuntimeInformation, flags: FlagsExecution, ) -> Result { - if program_archive.contains_template(id){ // in this case we execute + if program_archive.contains_template(id) { + // in this case we execute let new_environment = prepare_environment_for_call(id, &arg_values, program_archive); let previous_environment = std::mem::replace(&mut runtime.environment, new_environment); let previous_block_type = std::mem::replace(&mut runtime.block_type, BlockType::Known); - let previous_anonymous_components = std::mem::replace(&mut runtime.anonymous_components, AnonymousComponentsInfo::new()); + let previous_anonymous_components = + std::mem::replace(&mut runtime.anonymous_components, AnonymousComponentsInfo::new()); let new_file_id = program_archive.get_template_data(id).get_file_id(); let previous_id = std::mem::replace(&mut runtime.current_file, new_file_id); runtime.call_trace.push(id.clone()); - let folded_result = execute_template_call(id, arg_values, tags, program_archive, runtime, flags)?; + let folded_result = + execute_template_call(id, arg_values, tags, program_archive, runtime, flags)?; runtime.environment = previous_environment; runtime.current_file = previous_id; @@ -751,8 +783,8 @@ fn execute_template_call_complete( runtime.anonymous_components = previous_anonymous_components; runtime.call_trace.pop(); Ok(folded_result) - } else { - unreachable!(); + } else { + unreachable!(); } } @@ -791,16 +823,21 @@ fn execute_signal_declaration( ) { use SignalType::*; let mut tags = TagInfo::new(); - for t in list_tags{ + for t in list_tags { tags.insert(t.clone(), None); - } + } if let Option::Some(node) = actual_node { node.add_ordered_signal(signal_name, dimensions); match signal_type { Input => { - if let Some(tags_input) = node.tag_instances().get(signal_name){ - environment_shortcut_add_input(environment, signal_name, dimensions, &tags_input); - } else{ + if let Some(tags_input) = node.tag_instances().get(signal_name) { + environment_shortcut_add_input( + environment, + signal_name, + dimensions, + &tags_input, + ); + } else { environment_shortcut_add_input(environment, signal_name, dimensions, &tags); } node.add_input(signal_name, dimensions); @@ -836,517 +873,529 @@ fn perform_assign( actual_node: &mut Option, runtime: &mut RuntimeInformation, program_archive: &ProgramArchive, - flags: FlagsExecution + flags: FlagsExecution, ) -> Result, ()> { use super::execution_data::type_definitions::SubComponentData; let full_symbol = create_symbol(symbol, &accessing_information); - let possible_arithmetic_slice = if ExecutionEnvironment::has_variable(&runtime.environment, symbol) - { - debug_assert!(accessing_information.signal_access.is_none()); - debug_assert!(accessing_information.after_signal.is_empty()); - let environment_result = ExecutionEnvironment::get_mut_variable_mut(&mut runtime.environment, symbol); - let (symbol_tags, symbol_content) = treat_result_with_environment_error( - environment_result, - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )?; - let mut r_tags = if r_folded.tags.is_some(){ - r_folded.tags.as_ref().unwrap().clone() - } else{ - TagInfo::new() - }; - let mut r_slice = safe_unwrap_to_arithmetic_slice(r_folded, line!()); - if runtime.block_type == BlockType::Unknown { - r_slice = AExpressionSlice::new_with_route(r_slice.route(), &AExpr::NonQuadratic); - r_tags = TagInfo::new(); - } - if accessing_information.undefined { - let new_value = - AExpressionSlice::new_with_route(symbol_content.route(), &AExpr::NonQuadratic); - let memory_result = - AExpressionSlice::insert_values(symbol_content, &vec![], &new_value, false); - treat_result_with_memory_error_void( - memory_result, + let possible_arithmetic_slice = + if ExecutionEnvironment::has_variable(&runtime.environment, symbol) { + debug_assert!(accessing_information.signal_access.is_none()); + debug_assert!(accessing_information.after_signal.is_empty()); + let environment_result = + ExecutionEnvironment::get_mut_variable_mut(&mut runtime.environment, symbol); + let (symbol_tags, symbol_content) = treat_result_with_environment_error( + environment_result, meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; - *symbol_tags = TagInfo::new(); - } else { + let mut r_tags = if r_folded.tags.is_some() { + r_folded.tags.as_ref().unwrap().clone() + } else { + TagInfo::new() + }; + let mut r_slice = safe_unwrap_to_arithmetic_slice(r_folded, line!()); + if runtime.block_type == BlockType::Unknown { + r_slice = AExpressionSlice::new_with_route(r_slice.route(), &AExpr::NonQuadratic); + r_tags = TagInfo::new(); + } + if accessing_information.undefined { + let new_value = + AExpressionSlice::new_with_route(symbol_content.route(), &AExpr::NonQuadratic); + let memory_result = + AExpressionSlice::insert_values(symbol_content, &vec![], &new_value, false); + treat_result_with_memory_error_void( + memory_result, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; + *symbol_tags = TagInfo::new(); + } else { + let memory_result = AExpressionSlice::insert_values( + symbol_content, + &accessing_information.before_signal, + &r_slice, + false, + ); + treat_result_with_memory_error_void( + memory_result, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; + // in case it is a complete assignment assign the tags, if not set the tags to empty + if AExpressionSlice::get_number_of_cells(symbol_content) + == AExpressionSlice::get_number_of_cells(&r_slice) + { + *symbol_tags = r_tags; + } else { + *symbol_tags = TagInfo::new(); + } + } + Option::None + } else if ExecutionEnvironment::has_signal(&runtime.environment, symbol) + && accessing_information.signal_access.is_some() + { + if ExecutionEnvironment::has_input(&runtime.environment, symbol) { + treat_result_with_memory_error( + Result::Err(MemoryError::AssignmentTagInput), + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )? + } + let tag = accessing_information.signal_access.clone().unwrap(); + let environment_response = + ExecutionEnvironment::get_mut_signal_res(&mut runtime.environment, symbol); + let (reference_to_tags, reference_to_tags_defined, reference_to_signal_content) = + treat_result_with_environment_error( + environment_response, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; - let memory_result = AExpressionSlice::insert_values( - symbol_content, + if SignalSlice::get_number_of_inserts(&reference_to_signal_content) > 0 { + treat_result_with_memory_error( + Result::Err(MemoryError::AssignmentTagAfterInit), + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )? + } else if let Some(a_slice) = r_folded.arithmetic_slice { + let value = AExpressionSlice::unwrap_to_single(a_slice); + match value { + ArithmeticExpressionGen::Number { value } => { + let possible_tag = reference_to_tags.get(&tag.clone()); + if let Some(val) = possible_tag { + if let Some(_) = val { + treat_result_with_memory_error( + Result::Err(MemoryError::AssignmentTagTwice), + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )? + } else { + // we add the info saying that the tag is defined + reference_to_tags.insert(tag.clone(), Option::Some(value.clone())); + let tag_state = reference_to_tags_defined.get_mut(&tag).unwrap(); + tag_state.value_defined = true; + if let Option::Some(node) = actual_node { + node.add_tag_signal(symbol, &tag, Some(value)); + } else { + unreachable!(); + } + } + } else { + unreachable!() + } + } + _ => unreachable!(), + } + } else { + unreachable!() + } + Option::None + } else if ExecutionEnvironment::has_signal(&runtime.environment, symbol) { + debug_assert!(accessing_information.signal_access.is_none()); + debug_assert!(accessing_information.after_signal.is_empty()); + + let environment_response = + ExecutionEnvironment::get_mut_signal_res(&mut runtime.environment, symbol); + let (reference_to_tags, reference_to_tags_defined, reference_to_signal_content) = + treat_result_with_environment_error( + environment_response, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; + let memory_response_for_signal_previous_value = SignalSlice::access_values( + reference_to_signal_content, &accessing_information.before_signal, - &r_slice, - false ); - treat_result_with_memory_error_void( - memory_result, + let signal_previous_value = treat_result_with_memory_error( + memory_response_for_signal_previous_value, meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; - // in case it is a complete assignment assign the tags, if not set the tags to empty - if AExpressionSlice::get_number_of_cells(symbol_content) == AExpressionSlice::get_number_of_cells(&r_slice){ - *symbol_tags = r_tags; - } else { - *symbol_tags = TagInfo::new(); - } - } - Option::None - } else if ExecutionEnvironment::has_signal(&runtime.environment, symbol) && - accessing_information.signal_access.is_some() { - if ExecutionEnvironment::has_input(&runtime.environment, symbol) { - treat_result_with_memory_error( - Result::Err(MemoryError::AssignmentTagInput), - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )? - } - let tag = accessing_information.signal_access.clone().unwrap(); - let environment_response = ExecutionEnvironment::get_mut_signal_res(&mut runtime.environment, symbol); - let (reference_to_tags, reference_to_tags_defined, reference_to_signal_content) = treat_result_with_environment_error( - environment_response, - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )?; - if SignalSlice::get_number_of_inserts(&reference_to_signal_content) > 0{ - treat_result_with_memory_error( - Result::Err(MemoryError::AssignmentTagAfterInit), - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )? - } - else if let Some(a_slice) = r_folded.arithmetic_slice { - let value = AExpressionSlice::unwrap_to_single(a_slice); - match value { - ArithmeticExpressionGen::Number { value } => { - let possible_tag = reference_to_tags.get(&tag.clone()); - if let Some(val) = possible_tag { - if let Some(_) = val { - treat_result_with_memory_error( - Result::Err(MemoryError::AssignmentTagTwice), - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )? - } else { // we add the info saying that the tag is defined - reference_to_tags.insert(tag.clone(), Option::Some(value.clone())); - let tag_state = reference_to_tags_defined.get_mut(&tag).unwrap(); - tag_state.value_defined = true; - if let Option::Some(node) = actual_node{ - node.add_tag_signal(symbol, &tag, Some(value)); - } else{ - unreachable!(); - } - - } - } else {unreachable!()} - }, - _ => unreachable!(), - } - } - else { - unreachable!() - } - Option::None - } else if ExecutionEnvironment::has_signal(&runtime.environment, symbol) { - debug_assert!(accessing_information.signal_access.is_none()); - debug_assert!(accessing_information.after_signal.is_empty()); - - let environment_response = ExecutionEnvironment::get_mut_signal_res(&mut runtime.environment, symbol); - let (reference_to_tags, reference_to_tags_defined, reference_to_signal_content) = treat_result_with_environment_error( - environment_response, - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )?; - let memory_response_for_signal_previous_value = SignalSlice::access_values( - reference_to_signal_content, - &accessing_information.before_signal, - ); - let signal_previous_value = treat_result_with_memory_error( - memory_response_for_signal_previous_value, - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )?; + // Study the tags: add the new ones and copy their content. + /* + Cases: + + Inherance in arrays => We only have a tag in case it inherites the tag in all positions + + - Tag defined by user: + * Already with value defined by user => do not copy new values + * No value defined by user + - Already initialized: + * If same value as previous preserve + * If not set value to None + - No initialized: + * Set value to new one + - Tag not defined by user: + * Already initialized: + - If contains same tag with same value preserve + - No tag or different value => do not save tag or loose it + * No initialized: + - Save tag + + + */ + let previous_tags = mem::take(reference_to_tags); + + let new_tags = if r_folded.tags.is_some() && op == AssignOp::AssignConstraintSignal { + r_folded.tags.clone().unwrap() + } else { + TagInfo::new() + }; - // Study the tags: add the new ones and copy their content. - /* - Cases: - - Inherance in arrays => We only have a tag in case it inherites the tag in all positions - - - Tag defined by user: - * Already with value defined by user => do not copy new values - * No value defined by user - - Already initialized: - * If same value as previous preserve - * If not set value to None - - No initialized: - * Set value to new one - - Tag not defined by user: - * Already initialized: - - If contains same tag with same value preserve - - No tag or different value => do not save tag or loose it - * No initialized: - - Save tag - - - */ - let previous_tags = mem::take(reference_to_tags); - - let new_tags = if r_folded.tags.is_some() && op == AssignOp::AssignConstraintSignal{ - r_folded.tags.clone().unwrap() - } else{ - TagInfo::new() - }; + let signal_is_init = + SignalSlice::get_number_of_inserts(reference_to_signal_content) > 0; - let signal_is_init = SignalSlice::get_number_of_inserts(reference_to_signal_content) > 0; - - for (tag, value) in previous_tags{ - let tag_state = reference_to_tags_defined.get(&tag).unwrap(); - if tag_state.defined{// is signal defined by user - if tag_state.value_defined{ - // already with value, store the same value - reference_to_tags.insert(tag, value); - } else{ - if signal_is_init { - // only keep value if same as previous - let to_store_value = if new_tags.contains_key(&tag){ - let value_new = new_tags.get(&tag).unwrap(); - if value != *value_new{ + for (tag, value) in previous_tags { + let tag_state = reference_to_tags_defined.get(&tag).unwrap(); + if tag_state.defined { + // is signal defined by user + if tag_state.value_defined { + // already with value, store the same value + reference_to_tags.insert(tag, value); + } else { + if signal_is_init { + // only keep value if same as previous + let to_store_value = if new_tags.contains_key(&tag) { + let value_new = new_tags.get(&tag).unwrap(); + if value != *value_new { + None + } else { + value + } + } else { None - } else{ - value + }; + reference_to_tags.insert(tag, to_store_value); + } else { + // always keep + if new_tags.contains_key(&tag) { + let value_new = new_tags.get(&tag).unwrap(); + reference_to_tags.insert(tag, value_new.clone()); + } else { + reference_to_tags.insert(tag, None); } - } else{ - None - }; - reference_to_tags.insert(tag, to_store_value); - } else{ - // always keep - if new_tags.contains_key(&tag){ - let value_new = new_tags.get(&tag).unwrap(); - reference_to_tags.insert(tag, value_new.clone()); - } else{ - reference_to_tags.insert(tag, None); } } - } - } else{ - // it is not defined by user - if new_tags.contains_key(&tag){ - let value_new = new_tags.get(&tag).unwrap(); - if value == *value_new{ - reference_to_tags.insert(tag, value); - } else{ + } else { + // it is not defined by user + if new_tags.contains_key(&tag) { + let value_new = new_tags.get(&tag).unwrap(); + if value == *value_new { + reference_to_tags.insert(tag, value); + } else { + reference_to_tags_defined.remove(&tag); + } + } else { reference_to_tags_defined.remove(&tag); } - } else{ - reference_to_tags_defined.remove(&tag); } } - } - - if !signal_is_init{ // first init, add new tags - for (tag, value) in new_tags{ - if !reference_to_tags.contains_key(&tag){ // in case it is a new tag (not defined by user) - reference_to_tags.insert(tag.clone(), value.clone()); - let state = TagState{defined: false, value_defined: false, complete: false}; - reference_to_tags_defined.insert(tag.clone(), state); + + if !signal_is_init { + // first init, add new tags + for (tag, value) in new_tags { + if !reference_to_tags.contains_key(&tag) { + // in case it is a new tag (not defined by user) + reference_to_tags.insert(tag.clone(), value.clone()); + let state = + TagState { defined: false, value_defined: false, complete: false }; + reference_to_tags_defined.insert(tag.clone(), state); + } } } - } + let r_slice = safe_unwrap_to_arithmetic_slice(r_folded, line!()); + let new_value_slice = &SignalSlice::new_with_route(r_slice.route(), &true); - - let r_slice = safe_unwrap_to_arithmetic_slice(r_folded, line!()); - let new_value_slice = &SignalSlice::new_with_route(r_slice.route(), &true); - - let correct_dims_result = SignalSlice::check_correct_dims( - &signal_previous_value, - &Vec::new(), - &new_value_slice, - true - ); - treat_result_with_memory_error_void( - correct_dims_result, - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )?; - - for i in 0..SignalSlice::get_number_of_cells(&signal_previous_value){ - let signal_was_assigned = treat_result_with_memory_error( - SignalSlice::access_value_by_index(&signal_previous_value, i), + let correct_dims_result = SignalSlice::check_correct_dims( + &signal_previous_value, + &Vec::new(), + &new_value_slice, + true, + ); + treat_result_with_memory_error_void( + correct_dims_result, meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; - if signal_was_assigned { - let access_response = Result::Err(MemoryError::AssignmentError(TypeAssignmentError::MultipleAssignments)); - treat_result_with_memory_error( - access_response, + + for i in 0..SignalSlice::get_number_of_cells(&signal_previous_value) { + let signal_was_assigned = treat_result_with_memory_error( + SignalSlice::access_value_by_index(&signal_previous_value, i), meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; + if signal_was_assigned { + let access_response = Result::Err(MemoryError::AssignmentError( + TypeAssignmentError::MultipleAssignments, + )); + treat_result_with_memory_error( + access_response, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; + } } - } - - - - let access_response = SignalSlice::insert_values( - reference_to_signal_content, - &accessing_information.before_signal, - &new_value_slice, - true - ); - - let signal_is_completely_initialized = - SignalSlice::get_number_of_inserts(reference_to_signal_content) == - SignalSlice::get_number_of_cells(reference_to_signal_content); - + let access_response = SignalSlice::insert_values( + reference_to_signal_content, + &accessing_information.before_signal, + &new_value_slice, + true, + ); - if signal_is_completely_initialized { + let signal_is_completely_initialized = + SignalSlice::get_number_of_inserts(reference_to_signal_content) + == SignalSlice::get_number_of_cells(reference_to_signal_content); - for (tag, value) in reference_to_tags{ - let tag_state = reference_to_tags_defined.get_mut(tag).unwrap(); - tag_state.complete = true; - if let Option::Some(node) = actual_node{ - if !tag_state.value_defined{ - node.add_tag_signal(symbol, &tag, value.clone()); + if signal_is_completely_initialized { + for (tag, value) in reference_to_tags { + let tag_state = reference_to_tags_defined.get_mut(tag).unwrap(); + tag_state.complete = true; + if let Option::Some(node) = actual_node { + if !tag_state.value_defined { + node.add_tag_signal(symbol, &tag, value.clone()); + } + } else { + unreachable!(); } - } else{ - unreachable!(); } } - } - - - treat_result_with_memory_error_void( - access_response, - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )?; - - Option::Some(r_slice) - } else if ExecutionEnvironment::has_component(&runtime.environment, symbol) { - if accessing_information.tag_access.is_some() { - unreachable!() - } - let environment_response = ExecutionEnvironment::get_mut_component_res(&mut runtime.environment, symbol); - let component_slice = treat_result_with_environment_error( - environment_response, - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )?; - - let is_anonymous_component = runtime.anonymous_components.contains_key(symbol); - let memory_response = if is_anonymous_component{ - ComponentSlice::get_mut_reference_to_single_value( - component_slice, - &Vec::new(), - ) - } else{ - ComponentSlice::get_mut_reference_to_single_value( - component_slice, - &accessing_information.before_signal, - ) - }; - let component = treat_result_with_memory_error( - memory_response, - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )?; - if accessing_information.signal_access.is_none() { - let (prenode_pointer, is_parallel) = safe_unwrap_to_valid_node_pointer(r_folded, line!()); - let memory_result = ComponentRepresentation::preinitialize_component( - component, - is_parallel, - prenode_pointer, - &runtime.exec_program, - is_anonymous_component, - meta - ); treat_result_with_memory_error_void( - memory_result, + access_response, meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; - if component.is_ready_initialize() { - // calls to execute and initialize the component - let pretemplate_info = runtime.exec_program.get_prenode_value(prenode_pointer).unwrap(); - let inputs_tags = component.inputs_tags.clone(); - let result = execute_template_call_complete( - pretemplate_info.template_name(), - pretemplate_info.parameter_instances().clone(), - inputs_tags, - program_archive, - runtime, - flags, - )?; - - let (node_pointer, is_parallel) = safe_unwrap_to_valid_node_pointer(result, line!()); - - let environment_response = ExecutionEnvironment::get_mut_component_res(&mut runtime.environment, symbol); - let component_slice = treat_result_with_environment_error( - environment_response, - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )?; - let memory_response = if is_anonymous_component { - ComponentSlice::get_mut_reference_to_single_value( - component_slice, - &Vec::new(), - ) - } else{ - ComponentSlice::get_mut_reference_to_single_value( - component_slice, - &accessing_information.before_signal, - ) - }; - let component = treat_result_with_memory_error( - memory_response, - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )?; - - let init_result = ComponentRepresentation::initialize_component( - component, - node_pointer, - &mut runtime.exec_program, - ); - treat_result_with_memory_error( - init_result, - meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )?; - if let Option::Some(actual_node) = actual_node { - let data = SubComponentData { - name: symbol.to_string(), - is_parallel, - goes_to: node_pointer, - indexed_with: accessing_information.before_signal.clone(), - }; - actual_node.add_arrow(full_symbol.clone(), data); - } else { - unreachable!(); - } + + Option::Some(r_slice) + } else if ExecutionEnvironment::has_component(&runtime.environment, symbol) { + if accessing_information.tag_access.is_some() { + unreachable!() } - Option::None - } else { - let signal_accessed = accessing_information.signal_access.clone().unwrap(); - debug_assert!(FoldedValue::valid_arithmetic_slice(&r_folded)); - let arithmetic_slice = r_folded.arithmetic_slice.unwrap(); - let tags = if r_folded.tags.is_some() { - r_folded.tags.unwrap() + let environment_response = + ExecutionEnvironment::get_mut_component_res(&mut runtime.environment, symbol); + let component_slice = treat_result_with_environment_error( + environment_response, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; + + let is_anonymous_component = runtime.anonymous_components.contains_key(symbol); + let memory_response = if is_anonymous_component { + ComponentSlice::get_mut_reference_to_single_value(component_slice, &Vec::new()) } else { - TagInfo::new() + ComponentSlice::get_mut_reference_to_single_value( + component_slice, + &accessing_information.before_signal, + ) }; - - let memory_response = ComponentRepresentation::assign_value_to_signal( - component, - &signal_accessed, - &accessing_information.after_signal, - &arithmetic_slice.route(), - tags, - ); - treat_result_with_memory_error_void( + let component = treat_result_with_memory_error( memory_response, meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; - if !component.is_initialized && component.is_ready_initialize() { - // calls to execute and initialize the component - let pretemplate_info = runtime.exec_program.get_prenode_value( - component.node_pointer.unwrap() - ).unwrap(); - let inputs_tags = component.inputs_tags.clone(); - - let folded_result = execute_template_call_complete( - pretemplate_info.template_name(), - pretemplate_info.parameter_instances().clone(), - inputs_tags, - program_archive, - runtime, - flags, - )?; - - let (node_pointer, is_parallel) = safe_unwrap_to_valid_node_pointer(folded_result, line!()); - - let environment_response = ExecutionEnvironment::get_mut_component_res(&mut runtime.environment, symbol); - let component_slice = treat_result_with_environment_error( - environment_response, + if accessing_information.signal_access.is_none() { + let (prenode_pointer, is_parallel) = + safe_unwrap_to_valid_node_pointer(r_folded, line!()); + let memory_result = ComponentRepresentation::preinitialize_component( + component, + is_parallel, + prenode_pointer, + &runtime.exec_program, + is_anonymous_component, meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )?; - let memory_response = if is_anonymous_component { - ComponentSlice::get_mut_reference_to_single_value( - component_slice, - &Vec::new(), - ) - } else{ - ComponentSlice::get_mut_reference_to_single_value( - component_slice, - &accessing_information.before_signal, - ) - }; - let component = treat_result_with_memory_error( - memory_response, + ); + treat_result_with_memory_error_void( + memory_result, meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; - - let init_result = ComponentRepresentation::initialize_component( + if component.is_ready_initialize() { + // calls to execute and initialize the component + let pretemplate_info = + runtime.exec_program.get_prenode_value(prenode_pointer).unwrap(); + let inputs_tags = component.inputs_tags.clone(); + let result = execute_template_call_complete( + pretemplate_info.template_name(), + pretemplate_info.parameter_instances().clone(), + inputs_tags, + program_archive, + runtime, + flags, + )?; + + let (node_pointer, is_parallel) = + safe_unwrap_to_valid_node_pointer(result, line!()); + + let environment_response = ExecutionEnvironment::get_mut_component_res( + &mut runtime.environment, + symbol, + ); + let component_slice = treat_result_with_environment_error( + environment_response, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; + let memory_response = if is_anonymous_component { + ComponentSlice::get_mut_reference_to_single_value( + component_slice, + &Vec::new(), + ) + } else { + ComponentSlice::get_mut_reference_to_single_value( + component_slice, + &accessing_information.before_signal, + ) + }; + let component = treat_result_with_memory_error( + memory_response, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; + + let init_result = ComponentRepresentation::initialize_component( + component, + node_pointer, + &mut runtime.exec_program, + ); + treat_result_with_memory_error( + init_result, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; + if let Option::Some(actual_node) = actual_node { + let data = SubComponentData { + name: symbol.to_string(), + is_parallel, + goes_to: node_pointer, + indexed_with: accessing_information.before_signal.clone(), + }; + actual_node.add_arrow(full_symbol.clone(), data); + } else { + unreachable!(); + } + } + Option::None + } else { + let signal_accessed = accessing_information.signal_access.clone().unwrap(); + debug_assert!(FoldedValue::valid_arithmetic_slice(&r_folded)); + let arithmetic_slice = r_folded.arithmetic_slice.unwrap(); + let tags = + if r_folded.tags.is_some() { r_folded.tags.unwrap() } else { TagInfo::new() }; + + let memory_response = ComponentRepresentation::assign_value_to_signal( component, - node_pointer, - &mut runtime.exec_program, + &signal_accessed, + &accessing_information.after_signal, + &arithmetic_slice.route(), + tags, ); treat_result_with_memory_error_void( - init_result, + memory_response, meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; - if let Option::Some(actual_node) = actual_node { - let data = SubComponentData { - name: symbol.to_string(), - goes_to: node_pointer, - is_parallel, - indexed_with: accessing_information.before_signal.clone(), + if !component.is_initialized && component.is_ready_initialize() { + // calls to execute and initialize the component + let pretemplate_info = runtime + .exec_program + .get_prenode_value(component.node_pointer.unwrap()) + .unwrap(); + let inputs_tags = component.inputs_tags.clone(); + + let folded_result = execute_template_call_complete( + pretemplate_info.template_name(), + pretemplate_info.parameter_instances().clone(), + inputs_tags, + program_archive, + runtime, + flags, + )?; + + let (node_pointer, is_parallel) = + safe_unwrap_to_valid_node_pointer(folded_result, line!()); + + let environment_response = ExecutionEnvironment::get_mut_component_res( + &mut runtime.environment, + symbol, + ); + let component_slice = treat_result_with_environment_error( + environment_response, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; + let memory_response = if is_anonymous_component { + ComponentSlice::get_mut_reference_to_single_value( + component_slice, + &Vec::new(), + ) + } else { + ComponentSlice::get_mut_reference_to_single_value( + component_slice, + &accessing_information.before_signal, + ) }; - let component_symbol = create_component_symbol(symbol, &accessing_information); - actual_node.add_arrow(component_symbol, data); - } else { - unreachable!(); + let component = treat_result_with_memory_error( + memory_response, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; + + let init_result = ComponentRepresentation::initialize_component( + component, + node_pointer, + &mut runtime.exec_program, + ); + treat_result_with_memory_error_void( + init_result, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; + if let Option::Some(actual_node) = actual_node { + let data = SubComponentData { + name: symbol.to_string(), + goes_to: node_pointer, + is_parallel, + indexed_with: accessing_information.before_signal.clone(), + }; + let component_symbol = + create_component_symbol(symbol, &accessing_information); + actual_node.add_arrow(component_symbol, data); + } else { + unreachable!(); + } } + Option::Some(arithmetic_slice) } - Option::Some(arithmetic_slice) - } - } else { - unreachable!(); - }; + } else { + unreachable!(); + }; if let Option::Some(arithmetic_slice) = possible_arithmetic_slice { let ret = Constrained { left: full_symbol, right: arithmetic_slice }; Result::Ok(Some(ret)) @@ -1355,7 +1404,6 @@ fn perform_assign( } } - // Evaluates the given condition and executes the corresponding statement. Returns a tuple (a,b) where a is the possible value returned and b is the value of the condition (in case the evaluation was successful) fn execute_conditional_statement( condition: &Expression, @@ -1382,9 +1430,11 @@ fn execute_conditional_statement( } else { let previous_block_type = runtime.block_type; runtime.block_type = BlockType::Unknown; - let (mut ret_value, mut can_simplify) = execute_statement(true_case, program_archive, runtime, actual_node, flags)?; + let (mut ret_value, mut can_simplify) = + execute_statement(true_case, program_archive, runtime, actual_node, flags)?; if let Option::Some(else_stmt) = false_case { - let (else_ret, can_simplify_else) = execute_statement(else_stmt, program_archive, runtime, actual_node, flags)?; + let (else_ret, can_simplify_else) = + execute_statement(else_stmt, program_archive, runtime, actual_node, flags)?; can_simplify &= can_simplify_else; if ret_value.is_none() { ret_value = else_ret; @@ -1401,17 +1451,18 @@ fn execute_sequence_of_statements( runtime: &mut RuntimeInformation, actual_node: &mut Option, flags: FlagsExecution, - is_complete_template: bool + is_complete_template: bool, ) -> Result<(Option, bool), ()> { let mut can_be_simplified = true; for stmt in stmts.iter() { - let (f_value, can_simplify) = execute_statement(stmt, program_archive, runtime, actual_node, flags)?; + let (f_value, can_simplify) = + execute_statement(stmt, program_archive, runtime, actual_node, flags)?; can_be_simplified &= can_simplify; if f_value.is_some() { return Result::Ok((f_value, can_be_simplified)); } } - if is_complete_template{ + if is_complete_template { execute_delayed_declarations(program_archive, runtime, actual_node, flags)?; } Result::Ok((Option::None, can_be_simplified)) @@ -1422,8 +1473,8 @@ fn execute_delayed_declarations( runtime: &mut RuntimeInformation, actual_node: &mut Option, flags: FlagsExecution, -)-> Result<(), ()> { - for (component_name, (meta, dimensions)) in runtime.anonymous_components.clone(){ +) -> Result<(), ()> { + for (component_name, (meta, dimensions)) in runtime.anonymous_components.clone() { let mut arithmetic_values = Vec::new(); for dimension in dimensions.iter() { let f_dimensions = execute_expression(dimension, program_archive, runtime, flags)?; @@ -1436,21 +1487,21 @@ fn execute_delayed_declarations( &mut runtime.runtime_errors, &runtime.call_trace, )?; - let usable_dimensions = - if let Option::Some(dimensions) = cast_indexing(&arithmetic_values) { - dimensions - } else { - let err = Result::Err(ExecutionError::ArraySizeTooBig); - treat_result_with_execution_error( - err, - &meta, - &mut runtime.runtime_errors, - &runtime.call_trace, - )? - }; + let usable_dimensions = if let Option::Some(dimensions) = cast_indexing(&arithmetic_values) + { + dimensions + } else { + let err = Result::Err(ExecutionError::ArraySizeTooBig); + treat_result_with_execution_error( + err, + &meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )? + }; if let Option::Some(node) = actual_node { node.add_component(&component_name, &usable_dimensions); - } + } } Result::Ok(()) } @@ -1492,7 +1543,7 @@ fn execute_variable( access: &[Access], program_archive: &ProgramArchive, runtime: &mut RuntimeInformation, - flags: FlagsExecution + flags: FlagsExecution, ) -> Result { let access_information = treat_accessing(meta, access, program_archive, runtime, flags)?; if access_information.undefined { @@ -1516,7 +1567,11 @@ fn execute_variable( &mut runtime.runtime_errors, &runtime.call_trace, )?; - Result::Ok(FoldedValue { arithmetic_slice: Option::Some(ae_slice), tags: Option::Some(var_tag.clone()), ..FoldedValue::default() }) + Result::Ok(FoldedValue { + arithmetic_slice: Option::Some(ae_slice), + tags: Option::Some(var_tag.clone()), + ..FoldedValue::default() + }) } fn execute_signal( @@ -1525,7 +1580,7 @@ fn execute_signal( access: &[Access], program_archive: &ProgramArchive, runtime: &mut RuntimeInformation, - flags: FlagsExecution + flags: FlagsExecution, ) -> Result { let access_information = treat_accessing(meta, access, program_archive, runtime, flags)?; if access_information.undefined { @@ -1543,7 +1598,7 @@ fn execute_signal( } else { unreachable!(); }; - let (tags,tags_definitions, signal_slice) = treat_result_with_environment_error( + let (tags, tags_definitions, signal_slice) = treat_result_with_environment_error( environment_response, meta, &mut runtime.runtime_errors, @@ -1553,13 +1608,17 @@ fn execute_signal( if tags.contains_key(&acc) { let value_tag = tags.get(&acc).unwrap(); let state = tags_definitions.get(&acc).unwrap(); - if let Some(value_tag) = value_tag { // tag has value + if let Some(value_tag) = value_tag { + // tag has value // access only allowed when (1) it is value defined by user or (2) it is completely assigned - if state.value_defined || state.complete{ + if state.value_defined || state.complete { let a_value = AExpr::Number { value: value_tag.clone() }; let ae_slice = AExpressionSlice::new(&a_value); - Result::Ok(FoldedValue { arithmetic_slice: Option::Some(ae_slice), ..FoldedValue::default() }) - } else{ + Result::Ok(FoldedValue { + arithmetic_slice: Option::Some(ae_slice), + ..FoldedValue::default() + }) + } else { let error = MemoryError::TagValueNotInitializedAccess; treat_result_with_memory_error( Result::Err(error), @@ -1568,9 +1627,7 @@ fn execute_signal( &runtime.call_trace, )? } - - } - else { + } else { let error = MemoryError::TagValueNotInitializedAccess; treat_result_with_memory_error( Result::Err(error), @@ -1579,9 +1636,8 @@ fn execute_signal( &runtime.call_trace, )? } - } - else { - unreachable!() + } else { + unreachable!() } } else { let memory_response = SignalSlice::access_values(signal_slice, indexing); @@ -1601,11 +1657,11 @@ fn execute_signal( )?; let mut tags_propagated = TagInfo::new(); - for (tag, value) in tags{ + for (tag, value) in tags { let state = tags_definitions.get(tag).unwrap(); - if state.value_defined || state.complete{ + if state.value_defined || state.complete { tags_propagated.insert(tag.clone(), value.clone()); - } else if state.defined{ + } else if state.defined { tags_propagated.insert(tag.clone(), None); } } @@ -1651,7 +1707,7 @@ fn execute_component( access: &[Access], program_archive: &ProgramArchive, runtime: &mut RuntimeInformation, - flags: FlagsExecution + flags: FlagsExecution, ) -> Result { let access_information = treat_accessing(meta, access, program_archive, runtime, flags)?; if access_information.undefined { @@ -1668,7 +1724,7 @@ fn execute_component( )?; let memory_response = if runtime.anonymous_components.contains_key(symbol) { ComponentSlice::access_values(component_slice, &Vec::new()) - } else{ + } else { ComponentSlice::access_values(component_slice, &access_information.before_signal) }; let slice_result = treat_result_with_memory_error( @@ -1678,7 +1734,7 @@ fn execute_component( &runtime.call_trace, )?; let resulting_component = safe_unwrap_to_single(slice_result, line!()); - + if let Some(acc) = access_information.tag_access { let (tags_signal, _) = treat_result_with_memory_error( resulting_component.get_signal(&access_information.signal_access.unwrap()), @@ -1686,15 +1742,17 @@ fn execute_component( &mut runtime.runtime_errors, &runtime.call_trace, )?; - + if tags_signal.contains_key(&acc) { let value_tag = tags_signal.get(&acc).unwrap(); if let Some(value_tag) = value_tag { let a_value = AExpr::Number { value: value_tag.clone() }; let ae_slice = AExpressionSlice::new(&a_value); - Result::Ok(FoldedValue { arithmetic_slice: Option::Some(ae_slice), ..FoldedValue::default() }) - } - else { + Result::Ok(FoldedValue { + arithmetic_slice: Option::Some(ae_slice), + ..FoldedValue::default() + }) + } else { let error = MemoryError::TagValueNotInitializedAccess; treat_result_with_memory_error( Result::Err(error), @@ -1706,9 +1764,7 @@ fn execute_component( } else { unreachable!() } - - } - else if let Option::Some(signal_name) = &access_information.signal_access { + } else if let Option::Some(signal_name) = &access_information.signal_access { let access_after_signal = &access_information.after_signal; let (tags_signal, signal) = treat_result_with_memory_error( resulting_component.get_signal(signal_name), @@ -1724,12 +1780,11 @@ fn execute_component( &runtime.call_trace, )?; let symbol = create_symbol(symbol, &access_information); - let result = signal_to_arith(symbol, slice) - .map(|s| FoldedValue { - arithmetic_slice: Option::Some(s), - tags: Option::Some(tags_signal.clone()), - ..FoldedValue::default() - }); + let result = signal_to_arith(symbol, slice).map(|s| FoldedValue { + arithmetic_slice: Option::Some(s), + tags: Option::Some(tags_signal.clone()), + ..FoldedValue::default() + }); treat_result_with_memory_error( result, meta, @@ -1773,7 +1828,11 @@ fn prepare_environment_for_call( let mut environment = ExecutionEnvironment::new(); debug_assert_eq!(arg_names.len(), arg_values.len()); for (arg_name, arg_value) in arg_names.iter().zip(arg_values) { - ExecutionEnvironment::add_variable(&mut environment, arg_name, (TagInfo::new(), arg_value.clone())); + ExecutionEnvironment::add_variable( + &mut environment, + arg_name, + (TagInfo::new(), arg_value.clone()), + ); } environment } @@ -1782,13 +1841,19 @@ fn execute_function_call( id: &str, program_archive: &ProgramArchive, runtime: &mut RuntimeInformation, - flags: FlagsExecution + flags: FlagsExecution, ) -> Result<(FoldedValue, bool), ()> { let previous_block = runtime.block_type; runtime.block_type = BlockType::Known; let function_body = program_archive.get_function_data(id).get_body_as_vec(); - let (function_result, can_be_simplified) = - execute_sequence_of_statements(function_body, program_archive, runtime, &mut Option::None, flags, true)?; + let (function_result, can_be_simplified) = execute_sequence_of_statements( + function_body, + program_archive, + runtime, + &mut Option::None, + flags, + true, + )?; runtime.block_type = previous_block; let return_value = function_result.unwrap(); debug_assert!(FoldedValue::valid_arithmetic_slice(&return_value)); @@ -1801,7 +1866,7 @@ fn execute_template_call( tag_values: BTreeMap, program_archive: &ProgramArchive, runtime: &mut RuntimeInformation, - flags: FlagsExecution + flags: FlagsExecution, ) -> Result { debug_assert!(runtime.block_type == BlockType::Known); let is_main = std::mem::replace(&mut runtime.public_inputs, vec![]); @@ -1818,12 +1883,11 @@ fn execute_template_call( not_empty_name = true; args_to_values.insert(name.clone(), value.clone()); } - for (_input, input_tags) in &tag_values{ + for (_input, input_tags) in &tag_values { for (_tag, value) in input_tags { - if value.is_none(){ + if value.is_none() { instantiation_name.push_str("null,"); - } - else{ + } else { let value = value.clone().unwrap(); instantiation_name.push_str(&format!("{},", value.to_string())); } @@ -1831,7 +1895,7 @@ fn execute_template_call( } } - if not_empty_name { + if not_empty_name { instantiation_name.pop(); } instantiation_name.push(')'); @@ -1850,29 +1914,30 @@ fn execute_template_call( tag_values, code, is_parallel, - is_custom_gate + is_custom_gate, )); let (ret, _) = execute_sequence_of_statements( template_body, program_archive, runtime, &mut node_wrap, - flags, - true + flags, + true, )?; debug_assert!(ret.is_none()); - let result_check_components = environment_check_all_components_assigned(&runtime.environment); - match result_check_components{ - Err((error, meta)) =>{ + let result_check_components = + environment_check_all_components_assigned(&runtime.environment); + match result_check_components { + Err((error, meta)) => { treat_result_with_memory_error_void( Err(error), &meta, &mut runtime.runtime_errors, &runtime.call_trace, )?; - }, - Ok(_) => {}, + } + Ok(_) => {} } let new_node = node_wrap.unwrap(); @@ -1880,7 +1945,11 @@ fn execute_template_call( let node_pointer = runtime.exec_program.add_node_to_scheme(new_node, analysis); node_pointer }; - Result::Ok(FoldedValue { node_pointer: Option::Some(node_pointer), is_parallel: Option::Some(false), ..FoldedValue::default() }) + Result::Ok(FoldedValue { + node_pointer: Option::Some(node_pointer), + is_parallel: Option::Some(false), + ..FoldedValue::default() + }) } fn preexecute_template_call( @@ -1890,13 +1959,12 @@ fn preexecute_template_call( runtime: &mut RuntimeInformation, ) -> Result { debug_assert!(runtime.block_type == BlockType::Known); - let inputs = program_archive.get_template_data(id).get_inputs(); - let outputs = program_archive.get_template_data(id).get_outputs(); + let inputs = program_archive.get_template_data(id).get_inputs(); + let outputs = program_archive.get_template_data(id).get_outputs(); let mut inputs_to_tags = HashMap::new(); let mut outputs_to_tags = HashMap::new(); - for (name, info_input) in inputs { inputs_to_tags.insert(name.clone(), info_input.1.clone()); } @@ -1914,7 +1982,11 @@ fn preexecute_template_call( let new_node = node_wrap.unwrap(); let node_pointer = runtime.exec_program.add_prenode_to_scheme(new_node); - Result::Ok(FoldedValue { node_pointer: Option::Some(node_pointer), is_parallel: Option::Some(false), ..FoldedValue::default() }) + Result::Ok(FoldedValue { + node_pointer: Option::Some(node_pointer), + is_parallel: Option::Some(false), + ..FoldedValue::default() + }) } fn execute_infix_op( @@ -1984,7 +2056,7 @@ fn treat_indexing( access: &[Access], program_archive: &ProgramArchive, runtime: &mut RuntimeInformation, - flags: FlagsExecution + flags: FlagsExecution, ) -> Result<(Vec, Option, usize), ()> { let mut index_accesses = Vec::new(); let mut signal_name = Option::None; @@ -2045,8 +2117,12 @@ fn cast_indexing(ae_indexes: &[AExpr]) -> Option> { return Option::None; } match AExpr::get_usize(ae_index) { - Some(index) => { sc_indexes.push(index); }, - None => { return Option::None; }, + Some(index) => { + sc_indexes.push(index); + } + None => { + return Option::None; + } } } Option::Some(sc_indexes) @@ -2057,8 +2133,8 @@ fn cast_index(ae_index: &AExpr) -> Option { return Option::None; } match AExpr::get_usize(ae_index) { - Some(index) => { Option::Some(index) }, - None => { Option::None }, + Some(index) => Option::Some(index), + None => Option::None, } } @@ -2077,18 +2153,18 @@ struct AccessingInformation { pub before_signal: Vec, pub signal_access: Option, pub after_signal: Vec, - pub tag_access: Option + pub tag_access: Option, } fn treat_accessing( meta: &Meta, access: &[Access], program_archive: &ProgramArchive, runtime: &mut RuntimeInformation, - flags: FlagsExecution + flags: FlagsExecution, ) -> Result { let (ae_before_signal, signal_name, signal_index) = treat_indexing(0, access, program_archive, runtime, flags)?; - let (ae_after_signal, tag_name , _tag_index) = + let (ae_after_signal, tag_name, _tag_index) = treat_indexing(signal_index + 1, access, program_archive, runtime, flags)?; treat_result_with_memory_error( valid_indexing(&ae_before_signal), @@ -2114,7 +2190,13 @@ fn treat_accessing( } else { (Vec::new(), Vec::new()) }; - Result::Ok(AccessingInformation { undefined, before_signal, after_signal, signal_access, tag_access}) + Result::Ok(AccessingInformation { + undefined, + before_signal, + after_signal, + signal_access, + tag_access, + }) } //************************************************* Safe transformations ************************************************* @@ -2172,13 +2254,13 @@ fn treat_result_with_memory_error_void( match memory_error { Result::Ok(()) => Result::Ok(()), Result::Err(MemoryError::MismatchedDimensionsWeak(dim_given, dim_original)) => { - let report = Report::warning( + let report = Report::warning( format!("Typing warning: Mismatched dimensions, assigning to an array an expression of smaller length, the remaining positions are assigned to 0.\n Expected length: {}, given {}", dim_original, dim_given), RuntimeError); - add_report_to_runtime(report, meta, runtime_errors, call_trace); - Ok(()) - }, + add_report_to_runtime(report, meta, runtime_errors, call_trace); + Ok(()) + } Result::Err(memory_error) => { let report = match memory_error { MemoryError::InvalidAccess(type_invalid_access) => { @@ -2257,7 +2339,7 @@ fn treat_result_with_memory_error_void( MemoryError::TagValueNotInitializedAccess => Report::error( "Tag value has not been previously initialized".to_string(), RuntimeError) - , + , MemoryError::MissingInputs(name) => Report::error( format!("Component {} is created but not all its inputs are initialized", name), RuntimeError, @@ -2352,8 +2434,7 @@ fn treat_result_with_memory_error( } MemoryError::TagValueNotInitializedAccess => { Report::error("Tag value has not been previously initialized".to_string(), RuntimeError) - - } + } MemoryError::MismatchedDimensionsWeak(..) => { unreachable!() }, @@ -2361,7 +2442,6 @@ fn treat_result_with_memory_error( format!("Component {} is created but not all its inputs are initialized", name), RuntimeError, ) - }; add_report_to_runtime(report, meta, runtime_errors, call_trace); Result::Err(()) @@ -2434,28 +2514,20 @@ fn treat_result_with_execution_warning( let msg = format!( "Consider using <== instead of <-- to add the corresponding constraint.\n The constraint representing the assignment satisfies the R1CS format and can be added to the constraint system." ); - Report::warning( - msg, - ReportCode::RuntimeWarning, - ) - }, - CanBeQuadraticConstraintMultiple(positions) =>{ + Report::warning(msg, ReportCode::RuntimeWarning) + } + CanBeQuadraticConstraintMultiple(positions) => { let mut msg_positions = positions[0].clone(); - for i in 1..positions.len(){ - msg_positions = format!("{}, {}", msg_positions, positions[i].clone()) - }; + for i in 1..positions.len() { + msg_positions = format!("{}, {}", msg_positions, positions[i].clone()) + } let msg = format!( "Consider using <== instead of <-- for some of positions of the array of signals being assigned.\n The constraints representing the assignment of the positions {} satisfy the R1CS format and can be added to the constraint system.", msg_positions ); - Report::warning( - msg, - ReportCode::RuntimeWarning, - ) + Report::warning(msg, ReportCode::RuntimeWarning) } - - }; add_report_to_runtime(report, meta, runtime_errors, call_trace); Result::Ok(()) @@ -2481,4 +2553,4 @@ fn add_report_to_runtime( } report.add_note(trace); runtime_errors.push(report); -} \ No newline at end of file +} diff --git a/constraint_generation/src/execution_data/executed_program.rs b/constraint_generation/src/execution_data/executed_program.rs index dcb1ce2da..f8b4f9ed8 100644 --- a/constraint_generation/src/execution_data/executed_program.rs +++ b/constraint_generation/src/execution_data/executed_program.rs @@ -20,7 +20,7 @@ pub struct ExecutedProgram { impl ExecutedProgram { pub fn new(prime: &String) -> ExecutedProgram { - ExecutedProgram{ + ExecutedProgram { model: Vec::new(), template_to_nodes: HashMap::new(), prime: prime.clone(), @@ -28,7 +28,12 @@ impl ExecutedProgram { } } - pub fn identify_node(&self, name: &str, context: &ParameterContext, tag_context: &TagContext) -> Option { + pub fn identify_node( + &self, + name: &str, + context: &ParameterContext, + tag_context: &TagContext, + ) -> Option { if !self.template_to_nodes.contains_key(name) { return Option::None; } @@ -65,10 +70,7 @@ impl ExecutedProgram { Option::Some(self.model_pretemplates[node_pointer].clone()) } - pub fn add_prenode_to_scheme( - &mut self, - node: PreExecutedTemplate, - ) -> NodePointer { + pub fn add_prenode_to_scheme(&mut self, node: PreExecutedTemplate) -> NodePointer { // Insert pretemplate let node_index = self.model_pretemplates.len(); self.model_pretemplates.push(node); @@ -86,7 +88,7 @@ impl ExecutedProgram { apply_computed(&mut node.code, &analysis); // Insert template let possible_index = self.identify_node( - node.template_name(), + node.template_name(), node.parameter_instances(), node.tag_instances(), ); @@ -134,7 +136,7 @@ impl ExecutedProgram { temp_instances[dag.main_id()].is_not_parallel_component = true; dag.clean_constraints(); - if flags.inspect{ + if flags.inspect { let mut w = dag.constraint_analysis()?; warnings.append(&mut w); } @@ -179,7 +181,8 @@ fn produce_dags_stats(dag: &DAG) -> Stats { all_needed_subcomponents_indexes[index] += node.number_of_subcomponents_indexes(); for c in dag.get_edges(index).unwrap() { all_created_cmp[index] += all_created_cmp[c.get_goes_to()]; - all_needed_subcomponents_indexes[index] += all_needed_subcomponents_indexes[c.get_goes_to()]; + all_needed_subcomponents_indexes[index] += + all_needed_subcomponents_indexes[c.get_goes_to()]; all_signals[index] += all_signals[c.get_goes_to()]; all_io[index] += all_io[c.get_goes_to()]; } diff --git a/constraint_generation/src/execution_data/executed_template.rs b/constraint_generation/src/execution_data/executed_template.rs index a56fc328a..1a46db153 100644 --- a/constraint_generation/src/execution_data/executed_template.rs +++ b/constraint_generation/src/execution_data/executed_template.rs @@ -8,7 +8,6 @@ use std::collections::{HashMap, HashSet}; use crate::execution_data::AExpressionSlice; use crate::execution_data::TagInfo; - struct Connexion { full_name: String, inspect: SubComponentData, @@ -24,7 +23,7 @@ pub struct PreExecutedTemplate { pub parameter_instances: Vec, pub inputs: HashMap>, pub outputs: HashMap>, -} +} impl PreExecutedTemplate { pub fn new( @@ -33,19 +32,14 @@ impl PreExecutedTemplate { inputs: HashMap>, outputs: HashMap>, ) -> PreExecutedTemplate { - PreExecutedTemplate { - template_name: name, - parameter_instances: instance, - inputs, - outputs, - } + PreExecutedTemplate { template_name: name, parameter_instances: instance, inputs, outputs } } pub fn template_name(&self) -> &String { &self.template_name } - pub fn parameter_instances(&self) -> &Vec{ + pub fn parameter_instances(&self) -> &Vec { &self.parameter_instances } @@ -58,8 +52,6 @@ impl PreExecutedTemplate { } } - - pub struct ExecutedTemplate { pub code: Statement, pub template_name: String, @@ -91,7 +83,7 @@ impl ExecutedTemplate { tag_instances: TagContext, code: Statement, is_parallel: bool, - is_custom_gate: bool + is_custom_gate: bool, ) -> ExecutedTemplate { let public_inputs: HashSet<_> = public.iter().cloned().collect(); ExecutedTemplate { @@ -117,16 +109,27 @@ impl ExecutedTemplate { } } - pub fn is_equal(&self, name: &str, context: &ParameterContext, tag_context: &TagContext) -> bool { - self.template_name == name + pub fn is_equal( + &self, + name: &str, + context: &ParameterContext, + tag_context: &TagContext, + ) -> bool { + self.template_name == name && self.parameter_instances == *context && self.tag_instances == *tag_context } pub fn add_arrow(&mut self, component_name: String, data: SubComponentData) { - let cnn = - Connexion { full_name: component_name, inspect: data, dag_offset: 0, dag_component_offset: 0, dag_jump: 0, dag_component_jump: 0}; - self.connexions.push(cnn); + let cnn = Connexion { + full_name: component_name, + inspect: data, + dag_offset: 0, + dag_component_offset: 0, + dag_jump: 0, + dag_component_jump: 0, + }; + self.connexions.push(cnn); } pub fn add_input(&mut self, input_name: &str, dimensions: &[usize]) { @@ -151,7 +154,11 @@ impl ExecutedTemplate { let mut index = 0; while index < dimensions[current] { let new_name = format!("{}[{}]", symbol_name, index); - generated_symbols.append(&mut generate_symbols(new_name, current + 1, dimensions)); + generated_symbols.append(&mut generate_symbols( + new_name, + current + 1, + dimensions, + )); index += 1; } generated_symbols @@ -162,9 +169,9 @@ impl ExecutedTemplate { } } - pub fn add_tag_signal(&mut self, signal_name: &str, tag_name: &str, value: Option){ + pub fn add_tag_signal(&mut self, signal_name: &str, tag_name: &str, value: Option) { let tags_signal = self.signal_to_tags.get_mut(signal_name); - if tags_signal.is_none(){ + if tags_signal.is_none() { let mut new_tags_signal = TagInfo::new(); new_tags_signal.insert(tag_name.to_string(), value); self.signal_to_tags.insert(signal_name.to_string(), new_tags_signal); @@ -227,7 +234,7 @@ impl ExecutedTemplate { parameters, self.ordered_signals.clone(), // pensar si calcularlo en este momento para no hacer clone self.is_parallel, - self.is_custom_gate + self.is_custom_gate, ); self.build_signals(dag); self.build_connexions(dag); @@ -279,19 +286,19 @@ impl ExecutedTemplate { cnn.dag_component_offset = dag.get_entry().unwrap().get_out_component(); dag.add_edge(cnn.inspect.goes_to, &cnn.full_name, cnn.inspect.is_parallel); cnn.dag_jump = dag.get_entry().unwrap().get_out() - cnn.dag_offset; - cnn.dag_component_jump = dag.get_entry().unwrap().get_out_component() - cnn.dag_component_offset; + cnn.dag_component_jump = + dag.get_entry().unwrap().get_out_component() - cnn.dag_component_offset; } self.has_parallel_sub_cmp = dag.nodes[dag.main_id()].has_parallel_sub_cmp(); dag.set_number_of_subcomponents_indexes(self.number_of_components); } fn build_constraints(&self, dag: &mut DAG) { - for c in &self.constraints { let correspondence = dag.get_main().unwrap().correspondence(); let cc = Constraint::apply_correspondence(c, correspondence); dag.add_constraint(cc); } - for s in &self.underscored_signals{ + for s in &self.underscored_signals { let correspondence = dag.get_main().unwrap().correspondence(); let new_s = correspondence.get(s).unwrap().clone(); dag.add_underscored_signal(new_s); @@ -359,7 +366,7 @@ impl ExecutedTemplate { has_parallel_sub_cmp: self.has_parallel_sub_cmp, code: self.code, name: self.template_name, - number_of_components : self.number_of_components, + number_of_components: self.number_of_components, signals_to_tags: self.signal_to_tags, }; @@ -377,25 +384,25 @@ impl ExecutedTemplate { let mut local_id = 0; let mut dag_local_id = 1; for (name, lengths) in self.outputs { - let signal = Signal { name, lengths, local_id, dag_local_id, xtype: Output}; + let signal = Signal { name, lengths, local_id, dag_local_id, xtype: Output }; local_id += signal.size(); dag_local_id += signal.size(); instance.add_signal(signal); } for (name, lengths) in public { - let signal = Signal { name, lengths, local_id, dag_local_id, xtype: Input}; + let signal = Signal { name, lengths, local_id, dag_local_id, xtype: Input }; local_id += signal.size(); dag_local_id += signal.size(); instance.add_signal(signal); } for (name, lengths) in not_public { - let signal = Signal { name, lengths, local_id, dag_local_id, xtype: Input}; + let signal = Signal { name, lengths, local_id, dag_local_id, xtype: Input }; local_id += signal.size(); dag_local_id += signal.size(); instance.add_signal(signal); } for (name, lengths) in self.intermediates { - let signal = Signal { name, lengths, local_id, dag_local_id, xtype: Intermediate}; + let signal = Signal { name, lengths, local_id, dag_local_id, xtype: Intermediate }; local_id += signal.size(); dag_local_id += signal.size(); instance.add_signal(signal); @@ -535,13 +542,18 @@ fn build_clusters(tmp: &ExecutedTemplate, instances: &[TemplateInstance]) -> Vec end += 1; } } - + let cluster = TriggerCluster { slice: start..end, length: end - start, defined_positions: defined_positions, cmp_name: cnn_data.name.clone(), - xtype: ClusterType::Uniform { offset_jump, component_offset_jump, instance_id, header: sub_cmp_header }, + xtype: ClusterType::Uniform { + offset_jump, + component_offset_jump, + instance_id, + header: sub_cmp_header, + }, }; cmp_data.insert(cnn_data.name.clone(), cluster); index = end; diff --git a/constraint_generation/src/execution_data/filters.rs b/constraint_generation/src/execution_data/filters.rs index 20b080ab4..8c2f67cbe 100644 --- a/constraint_generation/src/execution_data/filters.rs +++ b/constraint_generation/src/execution_data/filters.rs @@ -15,8 +15,11 @@ fn clean_dead_code(stmt: &mut Statement, analysis: &Analysis, prime: &String) -> let field = program_structure::constants::UsefulConstants::new(prime).get_p().clone(); let empty_block = Box::new(Block { meta: meta.clone(), stmts: vec![] }); let if_case_empty = clean_dead_code(if_case, analysis, prime); - let else_case_empty = - if let Some(case) = else_case { clean_dead_code(case, analysis, prime) } else { true }; + let else_case_empty = if let Some(case) = else_case { + clean_dead_code(case, analysis, prime) + } else { + true + }; if else_case_empty { *else_case = None; } @@ -90,7 +93,7 @@ pub fn apply_computed(stmt: &mut Statement, analysis: &Analysis) { } LogCall { args, .. } => { for arglog in args { - if let LogArgument::LogExp(arg) = arglog{ + if let LogArgument::LogExp(arg) = arglog { *arg = computed_or_original(analysis, arg); apply_computed_expr(arg, analysis); } @@ -100,10 +103,10 @@ pub fn apply_computed(stmt: &mut Statement, analysis: &Analysis) { *arg = computed_or_original(analysis, arg); apply_computed_expr(arg, analysis); } - UnderscoreSubstitution { rhe, .. } => { + UnderscoreSubstitution { rhe, .. } => { *rhe = computed_or_original(analysis, rhe); apply_computed_expr(rhe, analysis); - }, + } } } @@ -185,10 +188,12 @@ fn apply_computed_expr(expr: &mut Expression, analysis: &Analysis) { apply_computed_expr(value, analysis); apply_computed_expr(dimension, analysis); } - ParallelOp {rhe, .. } => { + ParallelOp { rhe, .. } => { *rhe = Box::new(computed_or_original(analysis, rhe)); apply_computed_expr(rhe, analysis); } - _ => {unreachable!("Anonymous calls should not be reachable at this point."); } + _ => { + unreachable!("Anonymous calls should not be reachable at this point."); + } } } diff --git a/constraint_generation/src/execution_data/type_definitions.rs b/constraint_generation/src/execution_data/type_definitions.rs index 03ef731c3..10c337f9d 100644 --- a/constraint_generation/src/execution_data/type_definitions.rs +++ b/constraint_generation/src/execution_data/type_definitions.rs @@ -3,7 +3,6 @@ use super::Constraint as ConstraintGen; use std::collections::BTreeMap; use num_bigint_dig::BigInt; - pub type NodePointer = usize; pub type Constraint = ConstraintGen; pub type ParameterContext = BTreeMap; diff --git a/constraint_generation/src/lib.rs b/constraint_generation/src/lib.rs index 33af998bd..9111647c3 100644 --- a/constraint_generation/src/lib.rs +++ b/constraint_generation/src/lib.rs @@ -34,7 +34,7 @@ pub struct BuildConfig { } #[derive(Debug, Copy, Clone)] -pub struct FlagsExecution{ +pub struct FlagsExecution { pub verbose: bool, pub inspect: bool, } @@ -43,10 +43,8 @@ pub type ConstraintWriter = Box; type BuildResponse = Result<(ConstraintWriter, VCP), ()>; pub fn build_circuit(program: ProgramArchive, config: BuildConfig) -> BuildResponse { let files = program.file_library.clone(); - let flags = FlagsExecution{ - verbose: config.flag_verbose, - inspect: config.inspect_constraints, - }; + let flags = + FlagsExecution { verbose: config.flag_verbose, inspect: config.inspect_constraints }; let (exe, warnings) = instantiation(&program, flags, &config.prime).map_err(|r| { Report::print_reports(&r, &files); })?; @@ -67,7 +65,11 @@ pub fn build_circuit(program: ProgramArchive, config: BuildConfig) -> BuildRespo } type InstantiationResponse = Result<(ExecutedProgram, ReportCollection), ReportCollection>; -fn instantiation(program: &ProgramArchive, flags: FlagsExecution, prime: &String) -> InstantiationResponse { +fn instantiation( + program: &ProgramArchive, + flags: FlagsExecution, + prime: &String, +) -> InstantiationResponse { let execution_result = execute::constraint_execution(&program, flags, prime); match execution_result { Ok((program_exe, warnings)) => { @@ -75,7 +77,7 @@ fn instantiation(program: &ProgramArchive, flags: FlagsExecution, prime: &String let success = Colour::Green.paint("template instances"); let nodes_created = format!("{}: {}", success, no_nodes); println!("{}", &nodes_created); - InstantiationResponse::Ok((program_exe,warnings)) + InstantiationResponse::Ok((program_exe, warnings)) } Err(reports) => InstantiationResponse::Err(reports), } @@ -99,7 +101,7 @@ fn simplification_process(vcp: &mut VCP, dag: DAG, config: &BuildConfig) -> Cons port_substitution: config.flag_json_sub, no_rounds: config.no_rounds, flag_old_heuristics: config.flag_old_heuristics, - prime : config.prime.clone(), + prime: config.prime.clone(), }; let list = DAG::map_to_list(dag, flags); VCP::add_witness_list(vcp, Rc::new(list.get_witness_as_vec())); diff --git a/constraint_list/src/constraint_simplification.rs b/constraint_list/src/constraint_simplification.rs index 99476cff5..7cbe96494 100644 --- a/constraint_list/src/constraint_simplification.rs +++ b/constraint_list/src/constraint_simplification.rs @@ -21,7 +21,7 @@ fn log_substitutions(substitutions: &LinkedList, writer: &mut Option, - num_signals: usize + num_signals: usize, } impl Cluster { pub fn new(constraint: C, num_signals: usize) -> Cluster { @@ -75,7 +75,7 @@ fn build_clusters(linear: LinkedList, no_vars: usize) -> Vec { let mut cluster_to_current = ClusterPath::with_capacity(no_linear); let mut signal_to_cluster = vec![no_linear; no_vars]; for constraint in linear { - if !constraint.is_empty(){ + if !constraint.is_empty() { let signals = C::take_cloned_signals(&constraint); let dest = ClusterArena::len(&arena); ClusterArena::push(&mut arena, Some(Cluster::new(constraint, signals.len()))); @@ -101,10 +101,10 @@ fn build_clusters(linear: LinkedList, no_vars: usize) -> Vec { } fn rebuild_witness( - max_signal: usize, - deleted: HashSet, - forbidden: &HashSet, - non_linear_map: SignalToConstraints, + max_signal: usize, + deleted: HashSet, + forbidden: &HashSet, + non_linear_map: SignalToConstraints, remove_unused: bool, ) -> SignalMap { let mut map = SignalMap::with_capacity(max_signal); @@ -112,7 +112,10 @@ fn rebuild_witness( for signal in 0..max_signal { if deleted.contains(&signal) { free.push_back(signal); - } else if remove_unused && !forbidden.contains(&signal) && !non_linear_map.contains_key(&signal){ + } else if remove_unused + && !forbidden.contains(&signal) + && !non_linear_map.contains_key(&signal) + { free.push_back(signal); } else if let Some(new_pos) = free.pop_front() { map.insert(signal, new_pos); @@ -260,7 +263,8 @@ fn constant_eq_simplification( let mut cons = LinkedList::new(); let mut subs = LinkedList::new(); for constraint in c_eq { - let mut signals: Vec<_> = C::take_cloned_signals_ordered(&constraint).iter().cloned().collect(); + let mut signals: Vec<_> = + C::take_cloned_signals_ordered(&constraint).iter().cloned().collect(); let signal = signals.pop().unwrap(); if HashSet::contains(&forbidden, &signal) { LinkedList::push_back(&mut cons, constraint); @@ -487,12 +491,12 @@ pub fn simplification(smp: &mut Simplifier) -> (ConstraintStorage, SignalMap) { LinkedList::append(&mut lconst, &mut cons); let mut substitutions = build_encoded_fast_substitutions(subs); for constraint in &mut linear { - if fast_encoded_constraint_substitution(constraint, &substitutions, &field){ + if fast_encoded_constraint_substitution(constraint, &substitutions, &field) { C::fix_constraint(constraint, &field); } } for constraint in &mut cons_equalities { - if fast_encoded_constraint_substitution(constraint, &substitutions, &field){ + if fast_encoded_constraint_substitution(constraint, &substitutions, &field) { C::fix_constraint(constraint, &field); } } @@ -513,7 +517,7 @@ pub fn simplification(smp: &mut Simplifier) -> (ConstraintStorage, SignalMap) { LinkedList::append(&mut lconst, &mut cons); let substitutions = build_encoded_fast_substitutions(subs); for constraint in &mut linear { - if fast_encoded_constraint_substitution(constraint, &substitutions, &field){ + if fast_encoded_constraint_substitution(constraint, &substitutions, &field) { C::fix_constraint(constraint, &field); } } @@ -562,7 +566,7 @@ pub fn simplification(smp: &mut Simplifier) -> (ConstraintStorage, SignalMap) { // println!("End of cluster simplification: {} ms", dur); LinkedList::append(&mut lconst, &mut cons); for constraint in &mut lconst { - if fast_encoded_constraint_substitution(constraint, &substitutions, &field){ + if fast_encoded_constraint_substitution(constraint, &substitutions, &field) { C::fix_constraint(constraint, &field); } } @@ -640,7 +644,7 @@ pub fn simplification(smp: &mut Simplifier) -> (ConstraintStorage, SignalMap) { for constraint in linear { if remove_unused { - let signals = C::take_cloned_signals(&constraint); + let signals = C::take_cloned_signals(&constraint); let c_id = constraint_storage.add_constraint(constraint); for signal in signals { if let Some(list) = non_linear_map.get_mut(&signal) { @@ -651,15 +655,14 @@ pub fn simplification(smp: &mut Simplifier) -> (ConstraintStorage, SignalMap) { non_linear_map.insert(signal, new); } } - } - else{ + } else { constraint_storage.add_constraint(constraint); } } for mut constraint in lconst { - if remove_unused{ + if remove_unused { C::fix_constraint(&mut constraint, &field); - let signals = C::take_cloned_signals(&constraint); + let signals = C::take_cloned_signals(&constraint); let c_id = constraint_storage.add_constraint(constraint); for signal in signals { if let Some(list) = non_linear_map.get_mut(&signal) { @@ -670,18 +673,14 @@ pub fn simplification(smp: &mut Simplifier) -> (ConstraintStorage, SignalMap) { non_linear_map.insert(signal, new); } } - } - else{ + } else { C::fix_constraint(&mut constraint, &field); constraint_storage.add_constraint(constraint); } } - let erased = crate::non_linear_simplification::simplify( - &mut constraint_storage, - &forbidden, - &field - ); + let erased = + crate::non_linear_simplification::simplify(&mut constraint_storage, &forbidden, &field); for signal in erased { deleted.insert(signal); @@ -692,7 +691,8 @@ pub fn simplification(smp: &mut Simplifier) -> (ConstraintStorage, SignalMap) { let signal_map = { // println!("Rebuild witness"); let now = SystemTime::now(); - let signal_map = rebuild_witness(max_signal, deleted, &forbidden, non_linear_map, remove_unused); + let signal_map = + rebuild_witness(max_signal, deleted, &forbidden, non_linear_map, remove_unused); let _dur = now.elapsed().unwrap().as_millis(); // println!("End of rebuild witness: {} ms", dur); signal_map @@ -704,6 +704,3 @@ pub fn simplification(smp: &mut Simplifier) -> (ConstraintStorage, SignalMap) { // println!("NO CONSTANTS: {}", constraint_storage.no_constants()); (constraint_storage, signal_map) } - - - diff --git a/constraint_list/src/non_linear_simplification.rs b/constraint_list/src/non_linear_simplification.rs index b0d3b7d56..9454d1f10 100644 --- a/constraint_list/src/non_linear_simplification.rs +++ b/constraint_list/src/non_linear_simplification.rs @@ -2,11 +2,10 @@ use circom_algebra::num_bigint::BigInt; use circom_algebra::constraint_storage::ConstraintStorage; use std::collections::{HashSet, LinkedList}; - pub fn simplify( _storage: &mut ConstraintStorage, _forbidden: &HashSet, - _field: &BigInt + _field: &BigInt, ) -> LinkedList { LinkedList::new() } diff --git a/constraint_list/src/r1cs_porting.rs b/constraint_list/src/r1cs_porting.rs index 7f012dda6..bce4cbd94 100644 --- a/constraint_list/src/r1cs_porting.rs +++ b/constraint_list/src/r1cs_porting.rs @@ -1,11 +1,13 @@ use super::{ConstraintList, C, EncodingIterator, SignalMap}; -use constraint_writers::r1cs_writer::{ConstraintSection, CustomGatesAppliedData, HeaderData, R1CSWriter, SignalSection}; +use constraint_writers::r1cs_writer::{ + ConstraintSection, CustomGatesAppliedData, HeaderData, R1CSWriter, SignalSection, +}; pub fn port_r1cs(list: &ConstraintList, output: &str, custom_gates: bool) -> Result<(), ()> { use constraint_writers::log_writer::Log; let field_size = if list.field.bits() % 64 == 0 { list.field.bits() / 8 - } else{ + } else { (list.field.bits() / 64 + 1) * 8 }; let mut log = Log::new(); @@ -51,7 +53,7 @@ pub fn port_r1cs(list: &ConstraintList, output: &str, custom_gates: bool) -> Res } let r1cs = signal_section.end_section()?; if !custom_gates { - R1CSWriter::finish_writing(r1cs)?; + R1CSWriter::finish_writing(r1cs)?; } else { let mut custom_gates_used_section = R1CSWriter::start_custom_gates_used_section(r1cs)?; let (usage_data, occurring_order) = { @@ -61,7 +63,7 @@ pub fn port_r1cs(list: &ConstraintList, output: &str, custom_gates: bool) -> Res if node.is_custom_gate { let mut name = node.name.clone(); occurring_order.push(name.clone()); - while name.pop() != Some('(') {}; + while name.pop() != Some('(') {} usage_data.push((name, node.parameters.clone())); } } @@ -70,11 +72,12 @@ pub fn port_r1cs(list: &ConstraintList, output: &str, custom_gates: bool) -> Res custom_gates_used_section.write_custom_gates_usages(usage_data)?; let r1cs = custom_gates_used_section.end_section()?; - let mut custom_gates_applied_section = R1CSWriter::start_custom_gates_applied_section(r1cs)?; + let mut custom_gates_applied_section = + R1CSWriter::start_custom_gates_applied_section(r1cs)?; let application_data = { fn find_indexes( occurring_order: Vec, - application_data: Vec<(String, Vec)> + application_data: Vec<(String, Vec)>, ) -> CustomGatesAppliedData { let mut new_application_data = vec![]; for (custom_gate_name, signals) in application_data { @@ -90,7 +93,7 @@ pub fn port_r1cs(list: &ConstraintList, output: &str, custom_gates: bool) -> Res fn iterate( iterator: EncodingIterator, map: &SignalMap, - application_data: &mut Vec<(String, Vec)> + application_data: &mut Vec<(String, Vec)>, ) { let node = &iterator.encoding.nodes[iterator.node_id]; if node.is_custom_gate { @@ -116,7 +119,7 @@ pub fn port_r1cs(list: &ConstraintList, output: &str, custom_gates: bool) -> Res }; custom_gates_applied_section.write_custom_gates_applications(application_data)?; let r1cs = custom_gates_applied_section.end_section()?; - R1CSWriter::finish_writing(r1cs)?; + R1CSWriter::finish_writing(r1cs)?; } Log::print(&log); Ok(()) diff --git a/constraint_writers/src/r1cs_writer.rs b/constraint_writers/src/r1cs_writer.rs index 7bc0fd7bc..9d400e462 100644 --- a/constraint_writers/src/r1cs_writer.rs +++ b/constraint_writers/src/r1cs_writer.rs @@ -49,7 +49,10 @@ fn end_section(writer: &mut BufWriter, go_back: u64, size: usize) -> Resul fn obtain_linear_combination_block( linear_combination: &HashMap, field_size: usize, -) -> (Vec, usize) where T: AsRef<[u8]> + std::cmp::Ord + std::hash::Hash { +) -> (Vec, usize) +where + T: AsRef<[u8]> + std::cmp::Ord + std::hash::Hash, +{ let mut block = Vec::new(); let non_zero_factors = BigInt::from(linear_combination.len()); let mut size = 0; @@ -77,7 +80,10 @@ fn write_constraint( b: &HashMap, c: &HashMap, field_size: usize, -) -> Result where T: AsRef<[u8]> + std::cmp::Ord + std::hash::Hash { +) -> Result +where + T: AsRef<[u8]> + std::cmp::Ord + std::hash::Hash, +{ let (block_a, size_a) = obtain_linear_combination_block(a, field_size); let (block_b, size_b) = obtain_linear_combination_block(b, field_size); let (block_c, size_c) = obtain_linear_combination_block(c, field_size); @@ -103,7 +109,7 @@ fn initialize_file(writer: &mut BufWriter, num_sections: u8) -> Result<(), pub struct R1CSWriter { field_size: usize, writer: BufWriter, - sections: [bool; SECTIONS as usize] + sections: [bool; SECTIONS as usize], } pub struct HeaderSection { @@ -112,7 +118,7 @@ pub struct HeaderSection { size: usize, index: usize, field_size: usize, - sections: [bool; SECTIONS as usize] + sections: [bool; SECTIONS as usize], } pub struct ConstraintSection { @@ -122,7 +128,7 @@ pub struct ConstraintSection { size: usize, index: usize, field_size: usize, - sections: [bool; SECTIONS as usize] + sections: [bool; SECTIONS as usize], } pub struct SignalSection { @@ -131,7 +137,7 @@ pub struct SignalSection { size: usize, index: usize, field_size: usize, - sections: [bool; SECTIONS as usize] + sections: [bool; SECTIONS as usize], } pub struct CustomGatesUsedSection { @@ -140,7 +146,7 @@ pub struct CustomGatesUsedSection { size: usize, index: usize, field_size: usize, - sections: [bool; SECTIONS as usize] + sections: [bool; SECTIONS as usize], } pub struct CustomGatesAppliedSection { @@ -149,14 +155,14 @@ pub struct CustomGatesAppliedSection { size: usize, index: usize, field_size: usize, - sections: [bool; SECTIONS as usize] + sections: [bool; SECTIONS as usize], } impl R1CSWriter { pub fn new( output_file: String, field_size: usize, - custom_gates: bool + custom_gates: bool, ) -> Result { let sections = [false; SECTIONS as usize]; let num_sections: u8 = if custom_gates { 5 } else { 3 }; @@ -203,7 +209,9 @@ impl R1CSWriter { }) } - pub fn start_custom_gates_used_section(mut r1cs: R1CSWriter) -> Result { + pub fn start_custom_gates_used_section( + mut r1cs: R1CSWriter, + ) -> Result { let start = initialize_section(&mut r1cs.writer, CUSTOM_GATES_USED_TYPE)?; Result::Ok(CustomGatesUsedSection { writer: r1cs.writer, @@ -211,11 +219,13 @@ impl R1CSWriter { size: 0, index: 3, field_size: r1cs.field_size, - sections: r1cs.sections + sections: r1cs.sections, }) } - pub fn start_custom_gates_applied_section(mut r1cs: R1CSWriter) -> Result { + pub fn start_custom_gates_applied_section( + mut r1cs: R1CSWriter, + ) -> Result { let start = initialize_section(&mut r1cs.writer, CUSTOM_GATES_APPLIED_TYPE)?; Result::Ok(CustomGatesAppliedSection { writer: r1cs.writer, @@ -223,12 +233,12 @@ impl R1CSWriter { size: 0, index: 4, field_size: r1cs.field_size, - sections: r1cs.sections + sections: r1cs.sections, }) } pub fn finish_writing(mut r1cs: R1CSWriter) -> Result<(), ()> { - r1cs.writer.flush().map_err(|_err| {}) + r1cs.writer.flush().map_err(|_err| {}) } } @@ -312,11 +322,7 @@ impl ConstraintSection { let mut sections = self.sections; let index = self.index; sections[index] = true; - Result::Ok(R1CSWriter { - writer: self.writer, - field_size: self.field_size, - sections - }) + Result::Ok(R1CSWriter { writer: self.writer, field_size: self.field_size, sections }) } pub fn constraints_written(&self) -> usize { @@ -325,14 +331,14 @@ impl ConstraintSection { } impl SignalSection { - pub fn write_signal( - &mut self, - bytes: &T - ) -> Result<(), ()> where T: AsRef<[u8]> { + pub fn write_signal(&mut self, bytes: &T) -> Result<(), ()> + where + T: AsRef<[u8]>, + { let (bytes, size) = into_format(bytes.as_ref(), 8); self.size += size; - self.writer.write_all(&bytes).map_err(|_err| {})//?; - //self.writer.flush().map_err(|_err| {}) + self.writer.write_all(&bytes).map_err(|_err| {}) //?; + //self.writer.flush().map_err(|_err| {}) } pub fn write_signal_usize(&mut self, signal: usize) -> Result<(), ()> { @@ -345,11 +351,7 @@ impl SignalSection { let mut sections = self.sections; let index = self.index; sections[index] = true; - Result::Ok(R1CSWriter { - writer: self.writer, - field_size: self.field_size, - sections - }) + Result::Ok(R1CSWriter { writer: self.writer, field_size: self.field_size, sections }) } } @@ -380,7 +382,8 @@ impl CustomGatesUsedSection { //self.writer.flush().map_err(|_err| {})?; for parameter in custom_gate_parameters { - let (parameter_stream, parameter_size) = bigint_as_bytes(¶meter, self.field_size); + let (parameter_stream, parameter_size) = + bigint_as_bytes(¶meter, self.field_size); self.size += parameter_size; self.writer.write(¶meter_stream).map_err(|_err| {})?; //self.writer.flush().map_err(|_err| {})?; @@ -395,17 +398,16 @@ impl CustomGatesUsedSection { let mut sections = self.sections; let index = self.index; sections[index] = true; - Result::Ok(R1CSWriter { - writer: self.writer, - field_size: self.field_size, - sections - }) + Result::Ok(R1CSWriter { writer: self.writer, field_size: self.field_size, sections }) } } pub type CustomGatesAppliedData = Vec<(usize, Vec)>; impl CustomGatesAppliedSection { - pub fn write_custom_gates_applications(&mut self, data: CustomGatesAppliedData) -> Result<(), ()> { + pub fn write_custom_gates_applications( + &mut self, + data: CustomGatesAppliedData, + ) -> Result<(), ()> { let no_custom_gate_applications = data.len(); let (no_custom_gate_applications_stream, no_custom_gate_applications_size) = bigint_as_bytes(&BigInt::from(no_custom_gate_applications), 4); @@ -436,7 +438,7 @@ impl CustomGatesAppliedSection { //self.writer.flush().map_err(|_err| {})?; } } - //self.writer.flush().map_err(|_err| {})?; + //self.writer.flush().map_err(|_err| {})?; Result::Ok(()) } @@ -445,10 +447,6 @@ impl CustomGatesAppliedSection { let mut sections = self.sections; let index = self.index; sections[index] = true; - Result::Ok(R1CSWriter { - writer: self.writer, - field_size: self.field_size, - sections - }) + Result::Ok(R1CSWriter { writer: self.writer, field_size: self.field_size, sections }) } } diff --git a/constraint_writers/src/sym_writer.rs b/constraint_writers/src/sym_writer.rs index 8299c07e9..43e592ebd 100644 --- a/constraint_writers/src/sym_writer.rs +++ b/constraint_writers/src/sym_writer.rs @@ -27,11 +27,11 @@ impl SymFile { pub fn write_sym_elem(sym: &mut SymFile, elem: SymElem) -> Result<(), ()> { sym.writer.write_all(elem.to_string().as_bytes()).map_err(|_err| {})?; sym.writer.write_all(b"\n").map_err(|_err| {}) //?; - //sym.writer.flush().map_err(|_err| {}) + //sym.writer.flush().map_err(|_err| {}) } - + pub fn finish_writing(mut sym: SymFile) -> Result<(), ()> { - sym.writer.flush().map_err(|_err| {}) + sym.writer.flush().map_err(|_err| {}) } // pub fn close(_sym: SymFile) {} diff --git a/dag/src/constraint_correctness_analysis.rs b/dag/src/constraint_correctness_analysis.rs index edb216b4f..8bb1612e9 100644 --- a/dag/src/constraint_correctness_analysis.rs +++ b/dag/src/constraint_correctness_analysis.rs @@ -8,17 +8,17 @@ type C = Constraint; const UNCONSTRAINED_SIGNAL_CODE: ReportCode = ReportCode::UnconstrainedSignal; const UNCONSTRAINED_IOSIGNAL_CODE: ReportCode = ReportCode::UnconstrainedIOSignal; - - struct UnconstrainedSignal; impl UnconstrainedSignal { pub fn new(signal: &str, template: &str, examples: &Vec) -> Report { - - if examples.len() == 1{ - let msg = format!("In template \"{}\": Local signal {} does not appear in any constraint", template, examples[0]); + if examples.len() == 1 { + let msg = format!( + "In template \"{}\": Local signal {} does not appear in any constraint", + template, examples[0] + ); let report = Report::warning(msg, UNCONSTRAINED_SIGNAL_CODE); report - } else{ + } else { let msg = format!("In template \"{}\": Array of local signals {} contains a total of {} signals that do not appear in any constraint", template, signal, examples.len()); let mut report = Report::warning(msg, UNCONSTRAINED_SIGNAL_CODE); let ex = format!("For example: {}, {}.", examples[0], examples[1]); @@ -31,12 +31,11 @@ impl UnconstrainedSignal { struct UnconstrainedIOSignal; impl UnconstrainedIOSignal { pub fn new(signal: &str, template: &str, examples: &Vec) -> Report { - - if examples.len() == 1{ + if examples.len() == 1 { let msg = format!("In template \"{}\": Subcomponent input/output signal {} does not appear in any constraint of the father component", template, examples[0]); let report = Report::warning(msg, UNCONSTRAINED_IOSIGNAL_CODE); report - } else{ + } else { let msg = format!("In template \"{}\": Array of subcomponent input/output signals {} contains a total of {} signals that do not appear in any constraint of the father component", template, signal, examples.len()); let mut report = Report::warning(msg, UNCONSTRAINED_IOSIGNAL_CODE); let ex = format!("For example: {}, {}.", examples[0], examples[1]); @@ -57,16 +56,15 @@ struct Analysis { signal_stats: Vec<(String, SignalType, usize)>, } -fn split_signal_name_index(name: &String)-> String{ - let split_components:Vec<&str> = name.split(".").collect(); // split the name of components +fn split_signal_name_index(name: &String) -> String { + let split_components: Vec<&str> = name.split(".").collect(); // split the name of components let mut signal_name = "".to_string(); - for i in 0..split_components.len()-1{ + for i in 0..split_components.len() - 1 { signal_name = signal_name + split_components[i] + "."; // take the index of the components } // no take the index of the array position - let aux_last_component = split_components[split_components.len()-1].to_string(); - let split_index_last_component = - aux_last_component.split("[").next().unwrap(); + let aux_last_component = split_components[split_components.len() - 1].to_string(); + let split_index_last_component = aux_last_component.split("[").next().unwrap(); signal_name + split_index_last_component } @@ -79,32 +77,32 @@ fn analysis_interpretation(analysis: Analysis, result: &mut AnalysisResult) { for (name, xtype, no_appearances) in stats { if no_appearances == 0 { let signal_name = split_signal_name_index(&name); - - match signal2unconstrainedex.get_mut(&signal_name){ - Some((_, examples)) =>{ + + match signal2unconstrainedex.get_mut(&signal_name) { + Some((_, examples)) => { examples.push(name.clone()); - }, - None =>{ - signal2unconstrainedex.insert(signal_name.to_string(), (xtype, vec![name.clone()])); + } + None => { + signal2unconstrainedex + .insert(signal_name.to_string(), (xtype, vec![name.clone()])); } } } } - for (name, (xtype, examples)) in signal2unconstrainedex{ - if xtype == SignalType::Local{ + for (name, (xtype, examples)) in signal2unconstrainedex { + if xtype == SignalType::Local { result.warnings.push(UnconstrainedSignal::new(&name, &tmp_name, &examples)); - } else{ + } else { result.warnings.push(UnconstrainedIOSignal::new(&name, &tmp_name, &examples)); } } } fn visit_node(node: &Node) -> Analysis { - let mut constraint_counter = HashMap::new(); let mut rev_correspondence = HashMap::new(); for (name, id) in &node.signal_correspondence { - if node.is_reachable_signal(*id){ + if node.is_reachable_signal(*id) { rev_correspondence.insert(*id, name.to_string()); constraint_counter.insert(*id, 0); } @@ -117,7 +115,7 @@ fn visit_node(node: &Node) -> Analysis { } } - for signal in &node.underscored_signals{ + for signal in &node.underscored_signals { let prev = constraint_counter.remove(&signal).unwrap(); constraint_counter.insert(*signal, prev + 1); } @@ -125,26 +123,20 @@ fn visit_node(node: &Node) -> Analysis { let mut signal_stats = vec![]; for (id, appearances) in constraint_counter { let name = rev_correspondence.remove(&id).unwrap(); - let signal_type = if node.is_local_signal(id) { - SignalType::Local - } else { - SignalType::IOSubcomponent - }; + let signal_type = + if node.is_local_signal(id) { SignalType::Local } else { SignalType::IOSubcomponent }; signal_stats.push((name, signal_type, appearances)); } signal_stats.sort_by(|a, b| a.0.cmp(&b.0)); - Analysis { - template_name: node.template_name.clone(), - signal_stats, - } + Analysis { template_name: node.template_name.clone(), signal_stats } } pub struct AnalysisResult { pub errors: ReportCollection, pub warnings: ReportCollection, } -pub fn clean_constraints(nodes: &mut [Node]){ - for node in nodes{ +pub fn clean_constraints(nodes: &mut [Node]) { + for node in nodes { let length_bound = Vec::len(&node.constraints); let work = std::mem::replace(&mut node.constraints, Vec::with_capacity(length_bound)); for mut constraint in work { @@ -158,12 +150,12 @@ pub fn clean_constraints(nodes: &mut [Node]){ pub fn analyse(nodes: &[Node]) -> AnalysisResult { let mut result = AnalysisResult { errors: vec![], warnings: vec![] }; - let mut visited : HashSet = HashSet::new(); + let mut visited: HashSet = HashSet::new(); for node in nodes { - if !node.is_custom_gate() && !visited.contains(&node.template_name.clone()){ + if !node.is_custom_gate() && !visited.contains(&node.template_name.clone()) { let analysis = visit_node(node); let mut result2 = AnalysisResult { errors: vec![], warnings: vec![] }; - analysis_interpretation(analysis, &mut result2); + analysis_interpretation(analysis, &mut result2); result.errors.append(&mut result2.errors); result.warnings.append(&mut result2.warnings); visited.insert(node.template_name.clone()); diff --git a/dag/src/lib.rs b/dag/src/lib.rs index cd494b800..20831ae9e 100644 --- a/dag/src/lib.rs +++ b/dag/src/lib.rs @@ -91,11 +91,18 @@ pub struct Edge { in_number: usize, out_number: usize, in_component_number: usize, - out_component_number: usize + out_component_number: usize, } impl Edge { fn new_entry(id: usize) -> Edge { - Edge { label: "main".to_string(), goes_to: id, in_number: 0, out_number: 0, in_component_number: 0, out_component_number: 0 } + Edge { + label: "main".to_string(), + goes_to: id, + in_number: 0, + out_number: 0, + in_component_number: 0, + out_component_number: 0, + } } pub fn get_goes_to(&self) -> usize { @@ -163,10 +170,11 @@ impl Node { parameters: Vec, ordered_signals: Vec, is_parallel: bool, - is_custom_gate: bool + is_custom_gate: bool, ) -> Node { Node { - template_name, entry: Edge::new_entry(id), + template_name, + entry: Edge::new_entry(id), parameters, number_of_components: 1, ordered_signals, @@ -315,12 +323,7 @@ impl ConstraintExporter for DAG { impl DAG { pub fn new(prime: &String) -> DAG { - DAG{ - prime : prime.clone(), - one_signal: 0, - nodes: Vec::new(), - adjacency: Vec::new(), - } + DAG { prime: prime.clone(), one_signal: 0, nodes: Vec::new(), adjacency: Vec::new() } } pub fn add_edge(&mut self, to: usize, label: &str, is_parallel: bool) -> Option<&Edge> { @@ -352,7 +355,7 @@ impl DAG { let concrete_name = format!("{}.{}", label, signal); let concrete_value = with.in_number + *id; correspondence.insert(concrete_name, concrete_value); - if *id <= self.nodes[to].inputs_length + self.nodes[to].outputs_length{ + if *id <= self.nodes[to].inputs_length + self.nodes[to].outputs_length { // in case it is an input/output signal reachables.insert(concrete_value); } @@ -374,12 +377,17 @@ impl DAG { parameters: Vec, ordered_signals: Vec, is_parallel: bool, - is_custom_gate: bool + is_custom_gate: bool, ) -> usize { let id = self.nodes.len(); - self.nodes.push( - Node::new(id, template_name, parameters, ordered_signals, is_parallel, is_custom_gate) - ); + self.nodes.push(Node::new( + id, + template_name, + parameters, + ordered_signals, + is_parallel, + is_custom_gate, + )); self.adjacency.push(vec![]); id } @@ -414,7 +422,7 @@ impl DAG { } } - pub fn set_number_of_subcomponents_indexes(&mut self, number_scmp: usize){ + pub fn set_number_of_subcomponents_indexes(&mut self, number_scmp: usize) { if let Option::Some(node) = self.get_mut_main() { node.set_number_of_subcomponents_indexes(number_scmp); } @@ -542,5 +550,5 @@ pub struct SimplificationFlags { pub parallel_flag: bool, pub port_substitution: bool, pub flag_old_heuristics: bool, - pub prime : String, + pub prime: String, } diff --git a/dag/src/map_to_constraint_list.rs b/dag/src/map_to_constraint_list.rs index 96968c370..62c7bd169 100644 --- a/dag/src/map_to_constraint_list.rs +++ b/dag/src/map_to_constraint_list.rs @@ -13,7 +13,7 @@ fn map_tree( tree: &Tree, witness: &mut Vec, c_holder: &mut CHolder, - forbidden: &mut HashSet + forbidden: &mut HashSet, ) -> usize { let mut no_constraints = 0; diff --git a/dag/src/r1cs_porting.rs b/dag/src/r1cs_porting.rs index 27eae18bd..1a268dc29 100644 --- a/dag/src/r1cs_porting.rs +++ b/dag/src/r1cs_porting.rs @@ -1,12 +1,14 @@ use super::{Constraint, Tree, DAG}; use constraint_writers::log_writer::Log; -use constraint_writers::r1cs_writer::{ConstraintSection, CustomGatesAppliedData, HeaderData, R1CSWriter}; +use constraint_writers::r1cs_writer::{ + ConstraintSection, CustomGatesAppliedData, HeaderData, R1CSWriter, +}; pub fn write(dag: &DAG, output: &str, custom_gates: bool) -> Result<(), ()> { let tree = Tree::new(dag); let field_size = if tree.field.bits() % 64 == 0 { tree.field.bits() / 8 - } else{ + } else { (tree.field.bits() / 64 + 1) * 8 }; let mut log = Log::new(); @@ -43,9 +45,9 @@ pub fn write(dag: &DAG, output: &str, custom_gates: bool) -> Result<(), ()> { signal_section.write_signal_usize(signal)?; } let r1cs = signal_section.end_section()?; - + if !custom_gates { - R1CSWriter::finish_writing(r1cs)?; + R1CSWriter::finish_writing(r1cs)?; } else { let mut custom_gates_used_section = R1CSWriter::start_custom_gates_used_section(r1cs)?; let (usage_data, occurring_order) = { @@ -55,7 +57,7 @@ pub fn write(dag: &DAG, output: &str, custom_gates: bool) -> Result<(), ()> { if node.is_custom_gate() { let mut name = node.template_name.clone(); occurring_order.push(name.clone()); - while name.pop() != Some('(') {}; + while name.pop() != Some('(') {} usage_data.push((name, node.parameters().clone())); } } @@ -64,11 +66,12 @@ pub fn write(dag: &DAG, output: &str, custom_gates: bool) -> Result<(), ()> { custom_gates_used_section.write_custom_gates_usages(usage_data)?; let r1cs = custom_gates_used_section.end_section()?; - let mut custom_gates_applied_section = R1CSWriter::start_custom_gates_applied_section(r1cs)?; + let mut custom_gates_applied_section = + R1CSWriter::start_custom_gates_applied_section(r1cs)?; let application_data = { fn find_indexes( occurring_order: Vec, - application_data: Vec<(String, Vec)> + application_data: Vec<(String, Vec)>, ) -> CustomGatesAppliedData { let mut new_application_data = vec![]; for (custom_gate_name, signals) in application_data { diff --git a/parser/src/include_logic.rs b/parser/src/include_logic.rs index 88d95a034..d6ada395e 100644 --- a/parser/src/include_logic.rs +++ b/parser/src/include_logic.rs @@ -42,7 +42,7 @@ impl FileStack { } } } - Result::Err( produce_report_with_message(ReportCode::IncludeNotFound, name)) + Result::Err(produce_report_with_message(ReportCode::IncludeNotFound, name)) } pub fn take_next(f_stack: &mut FileStack) -> Option { @@ -91,7 +91,7 @@ impl IncludesGraph { let mut crr = PathBuf::new(); crr.push(old_path.clone()); let path = std::fs::canonicalize(crr) - .map_err(|_e| produce_report_with_message(ReportCode::FileOs,old_path))?; + .map_err(|_e| produce_report_with_message(ReportCode::FileOs, old_path))?; let edges = self.adjacency.entry(path).or_insert(vec![]); edges.push(self.nodes.len() - 1); Ok(()) diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 825e385fd..76ae57802 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -12,7 +12,10 @@ mod parser_logic; mod syntax_sugar_remover; use include_logic::{FileStack, IncludesGraph}; -use program_structure::ast::{produce_compiler_version_report, produce_report, produce_report_with_message, produce_version_warning_report, Expression}; +use program_structure::ast::{ + produce_compiler_version_report, produce_report, produce_report_with_message, + produce_version_warning_report, Expression, +}; use program_structure::error_code::ReportCode; use program_structure::error_definition::ReportCollection; use program_structure::error_definition::Report; @@ -110,7 +113,7 @@ pub fn run_parser( } if main_components.len() == 0 { - let report = produce_report(ReportCode::NoMainFoundInProject,0..0, 0); + let report = produce_report(ReportCode::NoMainFoundInProject, 0..0, 0); warnings.push(report); Err((file_library, warnings)) } else if main_components.len() > 1 { @@ -129,7 +132,7 @@ pub fn run_parser( ) ).collect(); if errors.len() > 0 { - warnings.append(& mut errors); + warnings.append(&mut errors); Err((file_library, warnings)) } else { let (main_id, main_component, custom_gates) = main_components.pop().unwrap(); @@ -147,11 +150,12 @@ pub fn run_parser( } Ok(mut program_archive) => { let lib = program_archive.get_file_library().clone(); - let program_archive_result = apply_syntactic_sugar( &mut program_archive); + let program_archive_result = apply_syntactic_sugar(&mut program_archive); match program_archive_result { Result::Err(v) => { warnings.push(v); - Result::Err((lib,warnings))}, + Result::Err((lib, warnings)) + } Result::Ok(_) => Ok((program_archive, warnings)), } } @@ -160,17 +164,26 @@ pub fn run_parser( } } -fn produce_report_with_main_components(main_components: Vec<(usize, (Vec, Expression), bool)>) -> Report { +fn produce_report_with_main_components( + main_components: Vec<(usize, (Vec, Expression), bool)>, +) -> Report { let mut j = 0; let mut r = produce_report(ReportCode::MultipleMain, 0..0, 0); - for (i,exp,_) in main_components{ + for (i, exp, _) in main_components { if j > 0 { - r.add_secondary(exp.1.get_meta().location.clone(), i, Option::Some("Here it is another main component".to_string())); - } - else { - r.add_primary(exp.1.get_meta().location.clone(), i, "This is a main component".to_string()); + r.add_secondary( + exp.1.get_meta().location.clone(), + i, + Option::Some("Here it is another main component".to_string()), + ); + } else { + r.add_primary( + exp.1.get_meta().location.clone(), + i, + "This is a main component".to_string(), + ); } - j+=1; + j += 1; } r } @@ -208,8 +221,7 @@ fn check_number_version( Err(produce_compiler_version_report(file_path, required_version, version_compiler)) } } else { - let report = - produce_version_warning_report(file_path, version_compiler); + let report = produce_version_warning_report(file_path, version_compiler); Ok(vec![report]) } } @@ -260,4 +272,4 @@ fn check_custom_gates_version( } } Ok(()) -} \ No newline at end of file +} diff --git a/parser/src/parser_logic.rs b/parser/src/parser_logic.rs index a572c53e7..cba22dd66 100644 --- a/parser/src/parser_logic.rs +++ b/parser/src/parser_logic.rs @@ -75,9 +75,7 @@ pub fn preprocess(expr: &str, file_id: FileID) -> Result Result { .parse(file_id, &mut errors, &preprocess) // TODO: is this always fatal? .map_err(|parse_error| match parse_error { - InvalidToken { location } => - produce_generic_report( - format!("{:?}", parse_error), - location..location, file_id - ), - UnrecognizedToken { ref token, .. } => - produce_generic_report( - format!("{:?}", parse_error), - token.0..token.2, file_id - ), - ExtraToken { ref token } => produce_generic_report( - format!("{:?}", parse_error), - token.0..token.2, file_id - ), - _ => produce_generic_report( - format!("{:?}", parse_error), - 0..0, file_id - ) + InvalidToken { location } => { + produce_generic_report(format!("{:?}", parse_error), location..location, file_id) + } + UnrecognizedToken { ref token, .. } => { + produce_generic_report(format!("{:?}", parse_error), token.0..token.2, file_id) + } + ExtraToken { ref token } => { + produce_generic_report(format!("{:?}", parse_error), token.0..token.2, file_id) + } + _ => produce_generic_report(format!("{:?}", parse_error), 0..0, file_id), }) .map_err(|e| vec![e])?; @@ -126,4 +116,3 @@ fn produce_generic_report(format: String, token: std::ops::Range, file_id report.add_primary(token, file_id, "here".to_string()); report } - diff --git a/parser/src/syntax_sugar_remover.rs b/parser/src/syntax_sugar_remover.rs index 2d84affdc..bf3fa641e 100644 --- a/parser/src/syntax_sugar_remover.rs +++ b/parser/src/syntax_sugar_remover.rs @@ -4,38 +4,60 @@ use program_structure::error_definition::{Report}; use program_structure::expression_builders::{build_call, build_tuple, build_parallel_op}; use program_structure::file_definition::FileLibrary; use program_structure::program_archive::ProgramArchive; -use program_structure::statement_builders::{build_declaration, build_log_call, build_assert, build_return, build_constraint_equality, build_initialization_block}; +use program_structure::statement_builders::{ + build_declaration, build_log_call, build_assert, build_return, build_constraint_equality, + build_initialization_block, +}; use program_structure::template_data::{TemplateData}; use std::collections::HashMap; use num_bigint::BigInt; - - -pub fn apply_syntactic_sugar(program_archive : &mut ProgramArchive) -> Result<(), Report> { - let mut new_templates : HashMap = HashMap::new(); +pub fn apply_syntactic_sugar(program_archive: &mut ProgramArchive) -> Result<(), Report> { + let mut new_templates: HashMap = HashMap::new(); if program_archive.get_main_expression().is_anonymous_comp() { - return Result::Err(anonymous_general_error(program_archive.get_main_expression().get_meta().clone(),"The main component cannot contain an anonymous call ".to_string())); - + return Result::Err(anonymous_general_error( + program_archive.get_main_expression().get_meta().clone(), + "The main component cannot contain an anonymous call ".to_string(), + )); } for temp in program_archive.templates.clone() { let t = temp.1.clone(); let body = t.get_body().clone(); check_anonymous_components_statement(&body)?; - let (new_body, initializations) = remove_anonymous_from_statement(&mut program_archive.templates, &program_archive.file_library, body, &None)?; + let (new_body, initializations) = remove_anonymous_from_statement( + &mut program_archive.templates, + &program_archive.file_library, + body, + &None, + )?; if let Statement::Block { meta, mut stmts } = new_body { - let (component_decs, variable_decs, mut substitutions) = separate_declarations_in_comp_var_subs(initializations); + let (component_decs, variable_decs, mut substitutions) = + separate_declarations_in_comp_var_subs(initializations); let mut init_block = vec![ build_initialization_block(meta.clone(), VariableType::Var, variable_decs), - build_initialization_block(meta.clone(), VariableType::Component, component_decs)]; + build_initialization_block(meta.clone(), VariableType::Component, component_decs), + ]; init_block.append(&mut substitutions); init_block.append(&mut stmts); let new_body_with_inits = build_block(meta, init_block); check_tuples_statement(&new_body_with_inits)?; let new_body = remove_tuples_from_statement(new_body_with_inits)?; - let t2 = TemplateData::copy(t.get_name().to_string(), t.get_file_id(), new_body, t.get_num_of_params(), t.get_name_of_params().clone(), - t.get_param_location(), t.get_inputs().clone(), t.get_outputs().clone(), t.is_parallel(), t.is_custom_gate(), t.get_declaration_inputs().clone(), t.get_declaration_outputs().clone()); - new_templates.insert(temp.0.clone(), t2); - } else{ + let t2 = TemplateData::copy( + t.get_name().to_string(), + t.get_file_id(), + new_body, + t.get_num_of_params(), + t.get_name_of_params().clone(), + t.get_param_location(), + t.get_inputs().clone(), + t.get_outputs().clone(), + t.is_parallel(), + t.is_custom_gate(), + t.get_declaration_inputs().clone(), + t.get_declaration_outputs().clone(), + ); + new_templates.insert(temp.0.clone(), t2); + } else { unreachable!() } } @@ -43,117 +65,128 @@ pub fn apply_syntactic_sugar(program_archive : &mut ProgramArchive) -> Result<( Result::Ok(()) } - -fn check_anonymous_components_statement( - stm : &Statement, -) -> Result<(), Report>{ +fn check_anonymous_components_statement(stm: &Statement) -> Result<(), Report> { match stm { - Statement::MultSubstitution {meta, lhe, rhe, op, ..} => { + Statement::MultSubstitution { meta, lhe, rhe, op, .. } => { if lhe.contains_anonymous_comp() { Result::Err(anonymous_general_error( meta.clone(), - "An anonymous component cannot be used in the left side of an assignment".to_string()) - ) - } else{ - if rhe.contains_anonymous_comp() && *op == AssignOp::AssignSignal{ - let error = format!("Anonymous components only admit the use of the operator <=="); - Result::Err(anonymous_general_error(meta.clone(),error)) - } else{ + "An anonymous component cannot be used in the left side of an assignment" + .to_string(), + )) + } else { + if rhe.contains_anonymous_comp() && *op == AssignOp::AssignSignal { + let error = + format!("Anonymous components only admit the use of the operator <=="); + Result::Err(anonymous_general_error(meta.clone(), error)) + } else { check_anonymous_components_expression(rhe) } } - }, - Statement::IfThenElse { meta, cond, if_case, else_case, .. } - => { + } + Statement::IfThenElse { meta, cond, if_case, else_case, .. } => { if cond.contains_anonymous_comp() { Result::Err(anonymous_inside_condition_error(meta.clone())) - } else{ + } else { check_anonymous_components_statement(if_case)?; - if else_case.is_some(){ + if else_case.is_some() { check_anonymous_components_statement(else_case.as_ref().unwrap())?; } Result::Ok(()) } } - Statement::While { meta, cond, stmt, .. } => { + Statement::While { meta, cond, stmt, .. } => { if cond.contains_anonymous_comp() { Result::Err(anonymous_inside_condition_error(meta.clone())) - } else{ + } else { check_anonymous_components_statement(stmt) } - } - Statement::LogCall {meta, args } => { + } + Statement::LogCall { meta, args } => { for arg in args { - if let program_structure::ast::LogArgument::LogExp( exp ) = arg { + if let program_structure::ast::LogArgument::LogExp(exp) = arg { if exp.contains_anonymous_comp() { - return Result::Err(anonymous_general_error(meta.clone() ,"An anonymous component cannot be used inside a log".to_string())) + return Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used inside a log".to_string(), + )); } } } Result::Ok(()) - } - Statement::Assert { meta, arg} => { + } + Statement::Assert { meta, arg } => { if arg.contains_anonymous_comp() { - Result::Err(anonymous_general_error(meta.clone(), "An anonymous component cannot be used inside an assert".to_string())) - } else{ + Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used inside an assert".to_string(), + )) + } else { Result::Ok(()) } } - Statement::Return { meta, value: arg}=> { - if arg.contains_anonymous_comp(){ - Result::Err(anonymous_general_error(meta.clone(), "An anonymous component cannot be used inside a function ".to_string())) - } else{ + Statement::Return { meta, value: arg } => { + if arg.contains_anonymous_comp() { + Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used inside a function ".to_string(), + )) + } else { Result::Ok(()) } } - Statement::ConstraintEquality {meta, lhe, rhe } => { + Statement::ConstraintEquality { meta, lhe, rhe } => { if lhe.contains_anonymous_comp() || rhe.contains_anonymous_comp() { - Result::Err(anonymous_general_error(meta.clone(), "An anonymous component cannot be used with operator === ".to_string())) - } - else{ - Result::Ok(()) + Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used with operator === ".to_string(), + )) + } else { + Result::Ok(()) } } Statement::Declaration { meta, dimensions, .. } => { - for exp in dimensions{ - if exp.contains_anonymous_comp(){ - return Result::Err(anonymous_general_error(meta.clone(),"An anonymous component cannot be used to define a dimension of an array".to_string())); + for exp in dimensions { + if exp.contains_anonymous_comp() { + return Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used to define a dimension of an array" + .to_string(), + )); } } Result::Ok(()) } - Statement::InitializationBlock { initializations, .. } => - { + Statement::InitializationBlock { initializations, .. } => { for stmt in initializations { check_anonymous_components_statement(stmt)?; } Result::Ok(()) } - Statement::Block {stmts, .. } => { - + Statement::Block { stmts, .. } => { for stmt in stmts { check_anonymous_components_statement(stmt)?; } Result::Ok(()) } - Statement::Substitution { meta, rhe, access, op, ..} => { + Statement::Substitution { meta, rhe, access, op, .. } => { use program_structure::ast::Access::ComponentAccess; use program_structure::ast::Access::ArrayAccess; - for acc in access{ - match acc{ - ArrayAccess(exp) =>{ - if exp.contains_anonymous_comp(){ + for acc in access { + match acc { + ArrayAccess(exp) => { + if exp.contains_anonymous_comp() { return Result::Err(anonymous_general_error(meta.clone(),"An anonymous component cannot be used to define a dimension of an array".to_string())); } - }, - ComponentAccess(_)=>{}, + } + ComponentAccess(_) => {} } } - if rhe.contains_anonymous_comp() && *op == AssignOp::AssignSignal{ + if rhe.contains_anonymous_comp() && *op == AssignOp::AssignSignal { let error = format!("Anonymous components only admit the use of the operator <=="); - Result::Err(anonymous_general_error(meta.clone(),error)) - } else{ + Result::Err(anonymous_general_error(meta.clone(), error)) + } else { check_anonymous_components_expression(rhe) } } @@ -161,234 +194,296 @@ fn check_anonymous_components_statement( } } -pub fn check_anonymous_components_expression( - exp : &Expression, -) -> Result<(),Report>{ +pub fn check_anonymous_components_expression(exp: &Expression) -> Result<(), Report> { use Expression::*; match exp { - ArrayInLine { meta, values, .. } => { - for value in values{ + ArrayInLine { meta, values, .. } => { + for value in values { if value.contains_anonymous_comp() { - return Result::Err(anonymous_general_error(meta.clone(),"An anonymous component cannot be used to define a dimension of an array".to_string())); + return Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used to define a dimension of an array" + .to_string(), + )); } } Result::Ok(()) - }, + } UniformArray { meta, value, dimension } => { if value.contains_anonymous_comp() || dimension.contains_anonymous_comp() { - Result::Err(anonymous_general_error(meta.clone(),"An anonymous component cannot be used to define a dimension of an array".to_string())) - } else{ + Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used to define a dimension of an array" + .to_string(), + )) + } else { Result::Ok(()) } - }, - Number(_, _) => { - Result::Ok(()) - }, + } + Number(_, _) => Result::Ok(()), Variable { meta, access, .. } => { use program_structure::ast::Access::ComponentAccess; use program_structure::ast::Access::ArrayAccess; - for acc in access{ - match acc{ - ArrayAccess(exp) =>{ - if exp.contains_anonymous_comp(){ + for acc in access { + match acc { + ArrayAccess(exp) => { + if exp.contains_anonymous_comp() { return Result::Err(anonymous_general_error(meta.clone(),"An anonymous component cannot be used to define a dimension of an array".to_string())); } - }, - ComponentAccess(_)=>{}, + } + ComponentAccess(_) => {} } } Result::Ok(()) - }, + } InfixOp { meta, lhe, rhe, .. } => { if lhe.contains_anonymous_comp() || rhe.contains_anonymous_comp() { - Result::Err(anonymous_general_error(meta.clone(),"An anonymous component cannot be used in the middle of an operation ".to_string())) - } else{ + Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used in the middle of an operation " + .to_string(), + )) + } else { Result::Ok(()) } - }, + } PrefixOp { meta, rhe, .. } => { - if rhe.contains_anonymous_comp() { - Result::Err(anonymous_general_error(meta.clone(),"An anonymous component cannot be used in the middle of an operation ".to_string())) - } else{ + if rhe.contains_anonymous_comp() { + Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used in the middle of an operation " + .to_string(), + )) + } else { Result::Ok(()) } - }, - InlineSwitchOp { meta, cond, if_true, if_false } => { - if cond.contains_anonymous_comp() || if_true.contains_anonymous_comp() || if_false.contains_anonymous_comp() { - Result::Err(anonymous_general_error(meta.clone(),"An anonymous component cannot be used inside an inline switch ".to_string())) - } else{ + } + InlineSwitchOp { meta, cond, if_true, if_false } => { + if cond.contains_anonymous_comp() + || if_true.contains_anonymous_comp() + || if_false.contains_anonymous_comp() + { + Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used inside an inline switch ".to_string(), + )) + } else { Result::Ok(()) } - }, + } Call { meta, args, .. } => { - for value in args{ + for value in args { if value.contains_anonymous_comp() { - return Result::Err(anonymous_general_error(meta.clone(),"An anonymous component cannot be used as a parameter in a template call ".to_string())); + return Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used as a parameter in a template call " + .to_string(), + )); } } Result::Ok(()) - }, - AnonymousComp {meta, params, signals, .. } => { - for value in params{ + } + AnonymousComp { meta, params, signals, .. } => { + for value in params { if value.contains_anonymous_comp() { - return Result::Err(anonymous_general_error(meta.clone(),"An anonymous component cannot be used as a parameter in a template call ".to_string())); + return Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used as a parameter in a template call " + .to_string(), + )); } } - for value in signals{ + for value in signals { check_anonymous_components_expression(value)?; } Result::Ok(()) - }, - Tuple {values, .. } => { - - for val in values{ + } + Tuple { values, .. } => { + for val in values { check_anonymous_components_expression(val)?; } Result::Ok(()) - }, + } ParallelOp { meta, rhe } => { if !rhe.is_call() && !rhe.is_anonymous_comp() && rhe.contains_anonymous_comp() { - return Result::Err(anonymous_general_error(meta.clone(),"Bad use of parallel operator in combination with anonymous components ".to_string())); - } - else if rhe.is_call() && rhe.contains_anonymous_comp() { - return Result::Err(anonymous_general_error(meta.clone(),"An anonymous component cannot be used as a parameter in a template call ".to_string())); + return Result::Err(anonymous_general_error( + meta.clone(), + "Bad use of parallel operator in combination with anonymous components " + .to_string(), + )); + } else if rhe.is_call() && rhe.contains_anonymous_comp() { + return Result::Err(anonymous_general_error( + meta.clone(), + "An anonymous component cannot be used as a parameter in a template call " + .to_string(), + )); } Result::Ok(()) - }, + } } } - fn remove_anonymous_from_statement( - templates : &HashMap, - file_lib : &FileLibrary, - stm : Statement, - var_access: &Option -) -> Result<(Statement, Vec),Report>{ + templates: &HashMap, + file_lib: &FileLibrary, + stm: Statement, + var_access: &Option, +) -> Result<(Statement, Vec), Report> { match stm { Statement::MultSubstitution { meta, lhe, op, rhe } => { - - let (mut stmts, declarations, new_rhe) = remove_anonymous_from_expression(templates, file_lib, rhe, var_access)?; - let subs = Statement::MultSubstitution { meta: meta.clone(), lhe: lhe, op: op, rhe: new_rhe }; - let mut substs = Vec::new(); - if stmts.is_empty(){ + let (mut stmts, declarations, new_rhe) = + remove_anonymous_from_expression(templates, file_lib, rhe, var_access)?; + let subs = + Statement::MultSubstitution { meta: meta.clone(), lhe: lhe, op: op, rhe: new_rhe }; + let mut substs = Vec::new(); + if stmts.is_empty() { Result::Ok((subs, declarations)) - }else{ + } else { substs.append(&mut stmts); substs.push(subs); - Result::Ok((Statement::Block { meta : meta, stmts : substs}, declarations)) + Result::Ok((Statement::Block { meta: meta, stmts: substs }, declarations)) } - }, - Statement::IfThenElse { meta, cond, if_case, else_case } - => { - - let (if_ok,mut declarations) = remove_anonymous_from_statement(templates, file_lib, *if_case, var_access)?; + } + Statement::IfThenElse { meta, cond, if_case, else_case } => { + let (if_ok, mut declarations) = + remove_anonymous_from_statement(templates, file_lib, *if_case, var_access)?; let b_if = Box::new(if_ok); - if else_case.is_none(){ - Result::Ok((Statement::IfThenElse { meta : meta, cond : cond, if_case: b_if, else_case: Option::None},declarations)) - }else { + if else_case.is_none() { + Result::Ok(( + Statement::IfThenElse { + meta: meta, + cond: cond, + if_case: b_if, + else_case: Option::None, + }, + declarations, + )) + } else { let else_c = *(else_case.unwrap()); - let (else_ok, mut declarations2) = remove_anonymous_from_statement(templates, file_lib, else_c, var_access)?; + let (else_ok, mut declarations2) = + remove_anonymous_from_statement(templates, file_lib, else_c, var_access)?; let b_else = Box::new(else_ok); declarations.append(&mut declarations2); - Result::Ok((Statement::IfThenElse { meta : meta, cond : cond, if_case: b_if, else_case: Option::Some(b_else)},declarations)) + Result::Ok(( + Statement::IfThenElse { + meta: meta, + cond: cond, + if_case: b_if, + else_case: Option::Some(b_else), + }, + declarations, + )) } } - Statement::While { meta, cond, stmt } => { - let id_var_while = "anon_var_".to_string() + &file_lib.get_line(meta.start, meta.get_file_id()).unwrap().to_string() + "_" + &meta.start.to_string(); - let var_access = Expression::Variable{meta: meta.clone(), name: id_var_while.clone(), access: Vec::new()}; + Statement::While { meta, cond, stmt } => { + let id_var_while = "anon_var_".to_string() + + &file_lib.get_line(meta.start, meta.get_file_id()).unwrap().to_string() + + "_" + + &meta.start.to_string(); + let var_access = Expression::Variable { + meta: meta.clone(), + name: id_var_while.clone(), + access: Vec::new(), + }; let mut declarations = vec![]; - let (while_ok, mut declarations2) = remove_anonymous_from_statement(templates, file_lib, *stmt, &Some(var_access.clone()))?; - let b_while = if !declarations2.is_empty(){ - declarations.push( - build_declaration( - meta.clone(), - VariableType::Var, - id_var_while.clone(), - Vec::new(), - ) - ); - declarations.push( - build_substitution( - meta.clone(), - id_var_while.clone(), - vec![], - AssignOp::AssignVar, - Expression::Number(meta.clone(), BigInt::from(0)) - ) - ); + let (while_ok, mut declarations2) = remove_anonymous_from_statement( + templates, + file_lib, + *stmt, + &Some(var_access.clone()), + )?; + let b_while = if !declarations2.is_empty() { + declarations.push(build_declaration( + meta.clone(), + VariableType::Var, + id_var_while.clone(), + Vec::new(), + )); + declarations.push(build_substitution( + meta.clone(), + id_var_while.clone(), + vec![], + AssignOp::AssignVar, + Expression::Number(meta.clone(), BigInt::from(0)), + )); declarations.append(&mut declarations2); - let next_access = Expression::InfixOp{ + let next_access = Expression::InfixOp { meta: meta.clone(), infix_op: ExpressionInfixOpcode::Add, lhe: Box::new(var_access), - rhe: Box::new(Expression::Number(meta.clone(), BigInt::from(1))), + rhe: Box::new(Expression::Number(meta.clone(), BigInt::from(1))), }; - let subs_access = Statement::Substitution{ + let subs_access = Statement::Substitution { meta: meta.clone(), var: id_var_while, access: Vec::new(), op: AssignOp::AssignVar, rhe: next_access, }; - - let new_block = Statement::Block{ - meta: meta.clone(), - stmts: vec![while_ok, subs_access], - }; + + let new_block = + Statement::Block { meta: meta.clone(), stmts: vec![while_ok, subs_access] }; Box::new(new_block) - } else{ + } else { Box::new(while_ok) }; - Result::Ok((Statement::While { meta: meta, cond: cond, stmt: b_while}, declarations)) - }, - Statement::LogCall {meta, args } => { - Result::Ok((build_log_call(meta, args),Vec::new())) - } - Statement::Assert { meta, arg} => { - Result::Ok((build_assert(meta, arg),Vec::new())) - } - Statement::Return { meta, value: arg}=> { - Result::Ok((build_return(meta, arg),Vec::new())) - } - Statement::ConstraintEquality {meta, lhe, rhe } => { - Result::Ok((build_constraint_equality(meta, lhe, rhe),Vec::new())) - } - Statement::Declaration { meta , xtype , name , - dimensions, .. } => { - Result::Ok((build_declaration(meta, xtype, name, dimensions),Vec::new())) - } - Statement::InitializationBlock { meta, xtype, initializations } => - { + Result::Ok((Statement::While { meta: meta, cond: cond, stmt: b_while }, declarations)) + } + Statement::LogCall { meta, args } => Result::Ok((build_log_call(meta, args), Vec::new())), + Statement::Assert { meta, arg } => Result::Ok((build_assert(meta, arg), Vec::new())), + Statement::Return { meta, value: arg } => Result::Ok((build_return(meta, arg), Vec::new())), + Statement::ConstraintEquality { meta, lhe, rhe } => { + Result::Ok((build_constraint_equality(meta, lhe, rhe), Vec::new())) + } + Statement::Declaration { meta, xtype, name, dimensions, .. } => { + Result::Ok((build_declaration(meta, xtype, name, dimensions), Vec::new())) + } + Statement::InitializationBlock { meta, xtype, initializations } => { let mut new_inits = Vec::new(); let mut declarations = Vec::new(); for stmt in initializations { - let (stmt_ok, mut declaration) = remove_anonymous_from_statement(templates, file_lib, stmt, var_access)?; + let (stmt_ok, mut declaration) = + remove_anonymous_from_statement(templates, file_lib, stmt, var_access)?; new_inits.push(stmt_ok); declarations.append(&mut declaration) } - Result::Ok((Statement::InitializationBlock { meta: meta, xtype: xtype, initializations: new_inits }, declarations)) + Result::Ok(( + Statement::InitializationBlock { + meta: meta, + xtype: xtype, + initializations: new_inits, + }, + declarations, + )) } - Statement::Block { meta, stmts } => { + Statement::Block { meta, stmts } => { let mut new_stmts = Vec::new(); - let mut declarations = Vec::new(); + let mut declarations = Vec::new(); for stmt in stmts { - let (stmt_ok, mut declaration) = remove_anonymous_from_statement(templates, file_lib, stmt, var_access)?; + let (stmt_ok, mut declaration) = + remove_anonymous_from_statement(templates, file_lib, stmt, var_access)?; new_stmts.push(stmt_ok); declarations.append(&mut declaration); } - Result::Ok((Statement::Block { meta : meta, stmts: new_stmts},declarations)) + Result::Ok((Statement::Block { meta: meta, stmts: new_stmts }, declarations)) } - Statement::Substitution { meta, var, op, rhe, access} => { - let (mut stmts, declarations, new_rhe) = remove_anonymous_from_expression(templates, file_lib, rhe, var_access)?; - let subs = Statement::Substitution { meta: meta.clone(), var: var, access: access, op: op, rhe: new_rhe }; - let mut substs = Vec::new(); - if stmts.is_empty(){ + Statement::Substitution { meta, var, op, rhe, access } => { + let (mut stmts, declarations, new_rhe) = + remove_anonymous_from_expression(templates, file_lib, rhe, var_access)?; + let subs = Statement::Substitution { + meta: meta.clone(), + var: var, + access: access, + op: op, + rhe: new_rhe, + }; + let mut substs = Vec::new(); + if stmts.is_empty() { Result::Ok((subs, declarations)) - }else{ + } else { substs.append(&mut stmts); substs.push(subs); - Result::Ok((Statement::Block { meta : meta, stmts : substs}, declarations)) + Result::Ok((Statement::Block { meta: meta, stmts: substs }, declarations)) } } Statement::UnderscoreSubstitution { .. } => unreachable!(), @@ -397,36 +492,44 @@ fn remove_anonymous_from_statement( // returns a block with the substitutions, the declarations and finally the output expression pub fn remove_anonymous_from_expression( - templates : &HashMap, - file_lib : &FileLibrary, - exp : Expression, + templates: &HashMap, + file_lib: &FileLibrary, + exp: Expression, var_access: &Option, // in case the call is inside a loop, variable used to control the access -) -> Result<(Vec, Vec, Expression),Report>{ +) -> Result<(Vec, Vec, Expression), Report> { use Expression::*; match exp { - AnonymousComp { meta, id, params, signals, names, is_parallel } => { + AnonymousComp { meta, id, params, signals, names, is_parallel } => { let mut declarations = Vec::new(); let mut seq_substs = Vec::new(); // get the template we are calling to let template = templates.get(&id); - if template.is_none(){ - return Result::Err(anonymous_general_error(meta.clone(),"The template does not exist ".to_string())); + if template.is_none() { + return Result::Err(anonymous_general_error( + meta.clone(), + "The template does not exist ".to_string(), + )); } - let id_anon_temp = id.to_string() + "_" + &file_lib.get_line(meta.start, meta.get_file_id()).unwrap().to_string() + "_" + &meta.start.to_string(); - + let id_anon_temp = id.to_string() + + "_" + + &file_lib.get_line(meta.start, meta.get_file_id()).unwrap().to_string() + + "_" + + &meta.start.to_string(); + // in case we are not inside a loop, we can automatically convert into a component - if var_access.is_none(){ + if var_access.is_none() { declarations.push(build_declaration( - meta.clone(), - VariableType::Component, + meta.clone(), + VariableType::Component, id_anon_temp.clone(), Vec::new(), )); - } else{ // we generate an anonymous component, it depends on the var_access indicating the loop + } else { + // we generate an anonymous component, it depends on the var_access indicating the loop declarations.push(build_declaration( - meta.clone(), - VariableType::AnonymousComponent, + meta.clone(), + VariableType::AnonymousComponent, id_anon_temp.clone(), vec![var_access.as_ref().unwrap().clone()], )); @@ -434,25 +537,22 @@ pub fn remove_anonymous_from_expression( // build the call generating the component let call = build_call(meta.clone(), id.clone(), params.clone()); - let exp_with_call = if is_parallel { - build_parallel_op(meta.clone(), call) - } else { - call - }; + let exp_with_call = + if is_parallel { build_parallel_op(meta.clone(), call) } else { call }; // in case we are in a loop in only generates a position, needs the var_access reference - let access = if var_access.is_none(){ - Vec::new() - } else{ + let access = if var_access.is_none() { + Vec::new() + } else { vec![build_array_access(var_access.as_ref().unwrap().clone())] }; // in loop: id_anon_temp[var_access] = (parallel) Template(params); // out loop: id_anon_temp = (parallel) Template(params) let sub = build_substitution( - meta.clone(), - id_anon_temp.clone(), - access.clone(), - AssignOp::AssignVar, - exp_with_call + meta.clone(), + id_anon_temp.clone(), + access.clone(), + AssignOp::AssignVar, + exp_with_call, ); seq_substs.push(sub); @@ -460,243 +560,277 @@ pub fn remove_anonymous_from_expression( // reorder the signals in new_signals (case names) let mut inputs_to_assignments = HashMap::new(); - if let Some(m) = names { // in case we have a list of names and assignments + if let Some(m) = names { + // in case we have a list of names and assignments let inputs = template.unwrap().get_inputs(); let mut n_expr = 0; - for (operator, name) in m{ - if operator != AssignOp::AssignConstraintSignal{ - let error = format!("Anonymous components only admit the use of the operator <=="); - return Result::Err(anonymous_general_error(meta.clone(),error)); + for (operator, name) in m { + if operator != AssignOp::AssignConstraintSignal { + let error = + format!("Anonymous components only admit the use of the operator <=="); + return Result::Err(anonymous_general_error(meta.clone(), error)); } - if inputs.contains_key(&name){ + if inputs.contains_key(&name) { inputs_to_assignments.insert(name, (operator, signals[n_expr].clone())); - } else{ - let error = format!("The template {} does not have an input signal named {}", template.unwrap().get_name(), name); - return Result::Err(anonymous_general_error(meta.clone(),error)); + } else { + let error = format!( + "The template {} does not have an input signal named {}", + template.unwrap().get_name(), + name + ); + return Result::Err(anonymous_general_error(meta.clone(), error)); } n_expr += 1; - } + } if inputs.len() != inputs_to_assignments.len() { return Result::Err(anonymous_general_error(meta.clone(),"The number of template input signals must coincide with the number of input parameters ".to_string())); - } - } - else{ + } + } else { let inputs = template.unwrap().get_declaration_inputs(); let mut n_expr = 0; for value in signals { - inputs_to_assignments.insert(inputs[n_expr].0.clone(), (AssignOp::AssignConstraintSignal, value)); + inputs_to_assignments.insert( + inputs[n_expr].0.clone(), + (AssignOp::AssignConstraintSignal, value), + ); n_expr += 1; } - + if inputs.len() != inputs_to_assignments.len() { return Result::Err(anonymous_general_error(meta.clone(),"The number of template input signals must coincide with the number of input parameters ".to_string())); } } - // generate the substitutions for the inputs - for (name_signal, (operator, expr)) in inputs_to_assignments{ - let mut acc = if var_access.is_none(){ + for (name_signal, (operator, expr)) in inputs_to_assignments { + let mut acc = if var_access.is_none() { Vec::new() - } else{ + } else { vec![build_array_access(var_access.as_ref().unwrap().clone())] }; acc.push(Access::ComponentAccess(name_signal.clone())); - let (mut stmts, mut declarations2, new_exp) = remove_anonymous_from_expression( - templates, - file_lib, - expr, - var_access - )?; - + let (mut stmts, mut declarations2, new_exp) = + remove_anonymous_from_expression(templates, file_lib, expr, var_access)?; + seq_substs.append(&mut stmts); declarations.append(&mut declarations2); - let subs = Statement::Substitution { meta: meta.clone(), var: id_anon_temp.clone(), access: acc, op: operator, rhe: new_exp }; + let subs = Statement::Substitution { + meta: meta.clone(), + var: id_anon_temp.clone(), + access: acc, + op: operator, + rhe: new_exp, + }; seq_substs.push(subs); } // generate the expression for the outputs -> return as expression (if single out) or tuple let outputs = template.unwrap().get_declaration_outputs(); if outputs.len() == 1 { let output = outputs.get(0).unwrap().0.clone(); - let mut acc = if var_access.is_none(){ + let mut acc = if var_access.is_none() { Vec::new() - } else{ + } else { vec![build_array_access(var_access.as_ref().unwrap().clone())] }; acc.push(Access::ComponentAccess(output.clone())); - let out_exp = Expression::Variable { meta: meta.clone(), name: id_anon_temp, access: acc }; - Result::Ok((vec![Statement::Block { meta: meta.clone(), stmts: seq_substs }], declarations, out_exp)) - - } else{ - let mut new_values = Vec::new(); + let out_exp = + Expression::Variable { meta: meta.clone(), name: id_anon_temp, access: acc }; + Result::Ok(( + vec![Statement::Block { meta: meta.clone(), stmts: seq_substs }], + declarations, + out_exp, + )) + } else { + let mut new_values = Vec::new(); for output in outputs { - let mut acc = if var_access.is_none(){ + let mut acc = if var_access.is_none() { Vec::new() - } else{ + } else { vec![build_array_access(var_access.as_ref().unwrap().clone())] }; acc.push(Access::ComponentAccess(output.0.clone())); - let out_exp = Expression::Variable { meta: meta.clone(), name: id_anon_temp.clone(), access: acc }; + let out_exp = Expression::Variable { + meta: meta.clone(), + name: id_anon_temp.clone(), + access: acc, + }; new_values.push(out_exp); } - let out_exp = Tuple {meta : meta.clone(), values : new_values}; - Result::Ok((vec![Statement::Block { meta: meta.clone(), stmts: seq_substs }], declarations, out_exp)) - + let out_exp = Tuple { meta: meta.clone(), values: new_values }; + Result::Ok(( + vec![Statement::Block { meta: meta.clone(), stmts: seq_substs }], + declarations, + out_exp, + )) } - }, + } Tuple { meta, values } => { let mut new_values = Vec::new(); - let mut new_stmts : Vec = Vec::new(); - let mut declarations : Vec = Vec::new(); - for val in values{ + let mut new_stmts: Vec = Vec::new(); + let mut declarations: Vec = Vec::new(); + for val in values { let result = remove_anonymous_from_expression(templates, file_lib, val, var_access); match result { Ok((mut stm, mut declaration, val2)) => { new_stmts.append(&mut stm); new_values.push(val2); declarations.append(&mut declaration); - }, - Err(er) => {return Result::Err(er);}, + } + Err(er) => { + return Result::Err(er); + } } } Result::Ok((new_stmts, declarations, build_tuple(meta.clone(), new_values))) - }, + } ParallelOp { meta, rhe } => { - if rhe.is_anonymous_comp(){ + if rhe.is_anonymous_comp() { let rhe2 = rhe.make_anonymous_parallel(); remove_anonymous_from_expression(templates, file_lib, rhe2, var_access) - } else{ - Result::Ok((Vec::new(),Vec::new(), ParallelOp { meta, rhe })) + } else { + Result::Ok((Vec::new(), Vec::new(), ParallelOp { meta, rhe })) } - }, - _ =>{ - Result::Ok((Vec::new(),Vec::new(),exp)) } + _ => Result::Ok((Vec::new(), Vec::new(), exp)), } } -pub fn separate_declarations_in_comp_var_subs(declarations: Vec) -> (Vec, Vec, Vec){ +pub fn separate_declarations_in_comp_var_subs( + declarations: Vec, +) -> (Vec, Vec, Vec) { let mut components_dec = Vec::new(); let mut variables_dec = Vec::new(); let mut substitutions = Vec::new(); for dec in declarations { - if let Statement::Declaration { ref xtype, .. } = dec { - if VariableType::Component.eq(&xtype) || VariableType::AnonymousComponent.eq(&xtype){ + if let Statement::Declaration { ref xtype, .. } = dec { + if VariableType::Component.eq(&xtype) || VariableType::AnonymousComponent.eq(&xtype) { components_dec.push(dec); - } - else if VariableType::Var.eq(&xtype) { + } else if VariableType::Var.eq(&xtype) { variables_dec.push(dec); - } - else { + } else { unreachable!(); } - } - else if let Statement::Substitution {.. } = dec { + } else if let Statement::Substitution { .. } = dec { substitutions.push(dec); - } else{ + } else { unreachable!(); } } (components_dec, variables_dec, substitutions) } -fn check_tuples_statement(stm: &Statement)-> Result<(), Report>{ - match stm{ - Statement::MultSubstitution { lhe, rhe, .. } => { +fn check_tuples_statement(stm: &Statement) -> Result<(), Report> { + match stm { + Statement::MultSubstitution { lhe, rhe, .. } => { check_tuples_expression(lhe)?; check_tuples_expression(rhe)?; Result::Ok(()) - }, - Statement::IfThenElse { cond, if_case, else_case, meta, .. } - => { + } + Statement::IfThenElse { cond, if_case, else_case, meta, .. } => { if cond.contains_tuple() { - Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used inside a condition ".to_string())) - } else{ + Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used inside a condition ".to_string(), + )) + } else { check_tuples_statement(if_case)?; - if else_case.is_some(){ + if else_case.is_some() { check_tuples_statement(else_case.as_ref().unwrap())?; } Result::Ok(()) } } - Statement::While { meta, cond, stmt } => { + Statement::While { meta, cond, stmt } => { if cond.contains_tuple() { - Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used inside a condition ".to_string())) - } else{ + Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used inside a condition ".to_string(), + )) + } else { check_tuples_statement(stmt) } - } - Statement::LogCall {args, .. } => { + } + Statement::LogCall { args, .. } => { for arg in args { match arg { - LogArgument::LogStr(_) => {}, + LogArgument::LogStr(_) => {} LogArgument::LogExp(exp) => { check_tuples_expression(&exp)?; - }, + } } } Result::Ok(()) - } - Statement::Assert { meta, arg} => { - if arg.contains_tuple(){ - Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used in a return ".to_string())) - } - else{ + } + Statement::Assert { meta, arg } => { + if arg.contains_tuple() { + Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used in a return ".to_string(), + )) + } else { Result::Ok(()) } } - Statement::Return { meta, value: arg}=> { - if arg.contains_tuple(){ - Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used inside a function ".to_string())) - } - else{ + Statement::Return { meta, value: arg } => { + if arg.contains_tuple() { + Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used inside a function ".to_string(), + )) + } else { Result::Ok(()) } } - Statement::ConstraintEquality {meta, lhe, rhe } => { + Statement::ConstraintEquality { meta, lhe, rhe } => { if lhe.contains_tuple() || rhe.contains_tuple() { - Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used with the operator === ".to_string())) - } - else{ - Result::Ok(()) + Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used with the operator === ".to_string(), + )) + } else { + Result::Ok(()) } } - Statement::Declaration { meta, - dimensions, .. } => - { - for exp in dimensions.clone(){ - if exp.contains_tuple(){ - return Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used to define a dimension of an array ".to_string())); + Statement::Declaration { meta, dimensions, .. } => { + for exp in dimensions.clone() { + if exp.contains_tuple() { + return Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used to define a dimension of an array ".to_string(), + )); } } Result::Ok(()) } - Statement::InitializationBlock {initializations, ..} => - { + Statement::InitializationBlock { initializations, .. } => { for stmt in initializations { check_tuples_statement(stmt)?; } Result::Ok(()) } - Statement::Block { stmts, ..} => { + Statement::Block { stmts, .. } => { for stmt in stmts { check_tuples_statement(stmt)?; } Result::Ok(()) } - Statement::Substitution { rhe, access, meta, ..} => { + Statement::Substitution { rhe, access, meta, .. } => { use program_structure::ast::Access::ComponentAccess; use program_structure::ast::Access::ArrayAccess; - for acc in access{ - match acc{ - ArrayAccess(exp) =>{ - if exp.contains_tuple(){ - return Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used to define a dimension of an array".to_string())); + for acc in access { + match acc { + ArrayAccess(exp) => { + if exp.contains_tuple() { + return Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used to define a dimension of an array" + .to_string(), + )); } - }, - ComponentAccess(_)=>{}, + } + ComponentAccess(_) => {} } } check_tuples_expression(rhe) @@ -705,188 +839,250 @@ fn check_tuples_statement(stm: &Statement)-> Result<(), Report>{ } } - -pub fn check_tuples_expression(exp: &Expression) -> Result<(), Report>{ +pub fn check_tuples_expression(exp: &Expression) -> Result<(), Report> { use Expression::*; - match exp{ - ArrayInLine { meta, values } => { - for value in values{ + match exp { + ArrayInLine { meta, values } => { + for value in values { if value.contains_tuple() { - return Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used to define a dimension of an array ".to_string())); + return Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used to define a dimension of an array ".to_string(), + )); } } Result::Ok(()) - }, + } UniformArray { meta, value, dimension } => { if value.contains_tuple() || dimension.contains_tuple() { - return Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used to define a dimension of an array ".to_string())); + return Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used to define a dimension of an array ".to_string(), + )); } Result::Ok(()) - }, - Number(_, _) => { - Result::Ok(()) - }, - Variable { access, meta, .. } => { + } + Number(_, _) => Result::Ok(()), + Variable { access, meta, .. } => { use program_structure::ast::Access::*; - for acc in access{ - match acc{ - ArrayAccess(exp) =>{ - if exp.contains_tuple(){ - return Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used to define a dimension of an array".to_string())); + for acc in access { + match acc { + ArrayAccess(exp) => { + if exp.contains_tuple() { + return Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used to define a dimension of an array" + .to_string(), + )); } - }, - ComponentAccess(_)=>{}, + } + ComponentAccess(_) => {} } } Result::Ok(()) - }, + } InfixOp { meta, lhe, rhe, .. } => { if lhe.contains_tuple() || rhe.contains_tuple() { - Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used in the middle of an operation".to_string())) - } else{ + Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used in the middle of an operation".to_string(), + )) + } else { Result::Ok(()) } - }, + } PrefixOp { meta, rhe, .. } => { - if rhe.contains_tuple() { - Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used in the middle of an operation".to_string())) - } else{ + if rhe.contains_tuple() { + Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used in the middle of an operation".to_string(), + )) + } else { Result::Ok(()) } - }, - InlineSwitchOp { meta, cond, if_true, if_false } => { + } + InlineSwitchOp { meta, cond, if_true, if_false } => { if cond.contains_tuple() || if_true.contains_tuple() || if_false.contains_tuple() { - Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used inside an inline switch".to_string())) - } else{ + Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used inside an inline switch".to_string(), + )) + } else { Result::Ok(()) } - }, + } Call { meta, args, .. } => { - for value in args{ + for value in args { if value.contains_tuple() { - return Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used as a parameter of a function call".to_string())); + return Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used as a parameter of a function call".to_string(), + )); } } Result::Ok(()) - }, + } AnonymousComp { .. } => { unreachable!(); } Tuple { values, .. } => { for val in values { - check_tuples_expression(val)?; + check_tuples_expression(val)?; } Result::Ok(()) - }, - ParallelOp { meta, rhe} => { - if rhe.contains_tuple() { - Result::Err(tuple_general_error(meta.clone(),"A tuple cannot be used in a parallel operator ".to_string())) - } else{ + } + ParallelOp { meta, rhe } => { + if rhe.contains_tuple() { + Result::Err(tuple_general_error( + meta.clone(), + "A tuple cannot be used in a parallel operator ".to_string(), + )) + } else { Result::Ok(()) } - }, + } } } fn remove_tuples_from_statement(stm: Statement) -> Result { - match stm{ - Statement::MultSubstitution { meta, lhe, op, rhe } => { + match stm { + Statement::MultSubstitution { meta, lhe, op, rhe } => { let new_exp_lhe = remove_tuple_from_expression(lhe); let new_exp_rhe = remove_tuple_from_expression(rhe); match (new_exp_lhe, new_exp_rhe) { - (Expression::Tuple { values: mut values1, .. }, - Expression::Tuple { values: mut values2, .. }) => { + ( + Expression::Tuple { values: mut values1, .. }, + Expression::Tuple { values: mut values2, .. }, + ) => { if values1.len() == values2.len() { let mut substs = Vec::new(); - while values1.len() > 0 { + while values1.len() > 0 { let lhe = values1.remove(0); - if let Expression::Variable { meta, name, access } = lhe { + if let Expression::Variable { meta, name, access } = lhe { let rhe = values2.remove(0); - if name != "_" { + if name != "_" { substs.push(build_substitution(meta, name, access, op, rhe)); - } else{ - substs.push(Statement::UnderscoreSubstitution { meta: meta, op, rhe: rhe }); + } else { + substs.push(Statement::UnderscoreSubstitution { + meta: meta, + op, + rhe: rhe, + }); } - } else{ + } else { return Result::Err(tuple_general_error(meta.clone(),"The elements of the receiving tuple must be signals or variables.".to_string())); } } - return Result::Ok(build_block(meta.clone(),substs)); + return Result::Ok(build_block(meta.clone(), substs)); } else if values1.len() > 0 { - return Result::Err(tuple_general_error(meta.clone(),"The number of elements in both tuples does not coincide".to_string())); + return Result::Err(tuple_general_error( + meta.clone(), + "The number of elements in both tuples does not coincide".to_string(), + )); } else { - return Result::Err(tuple_general_error(meta.clone(),"This expression must be in the right side of an assignment".to_string())); + return Result::Err(tuple_general_error( + meta.clone(), + "This expression must be in the right side of an assignment" + .to_string(), + )); } - }, - (lhe, rhe) => { - if lhe.is_tuple() || lhe.is_variable(){ - return Result::Err(tuple_general_error(rhe.get_meta().clone(),"This expression must be a tuple or an anonymous component".to_string())); + } + (lhe, rhe) => { + if lhe.is_tuple() || lhe.is_variable() { + return Result::Err(tuple_general_error( + rhe.get_meta().clone(), + "This expression must be a tuple or an anonymous component".to_string(), + )); } else { - return Result::Err(tuple_general_error(lhe.get_meta().clone(),"This expression must be a tuple, a component, a signal or a variable ".to_string())); + return Result::Err(tuple_general_error( + lhe.get_meta().clone(), + "This expression must be a tuple, a component, a signal or a variable " + .to_string(), + )); } } } - }, - Statement::IfThenElse { meta, cond, if_case, else_case } - => { + } + Statement::IfThenElse { meta, cond, if_case, else_case } => { let if_ok = remove_tuples_from_statement(*if_case)?; let b_if = Box::new(if_ok); - if else_case.is_none(){ - Result::Ok(Statement::IfThenElse { meta : meta, cond : cond, if_case: b_if, else_case: Option::None}) - }else { + if else_case.is_none() { + Result::Ok(Statement::IfThenElse { + meta: meta, + cond: cond, + if_case: b_if, + else_case: Option::None, + }) + } else { let else_c = *(else_case.unwrap()); let else_ok = remove_tuples_from_statement(else_c)?; let b_else = Box::new(else_ok); - Result::Ok(Statement::IfThenElse { meta : meta, cond : cond, if_case: b_if, else_case: Option::Some(b_else)}) + Result::Ok(Statement::IfThenElse { + meta: meta, + cond: cond, + if_case: b_if, + else_case: Option::Some(b_else), + }) } } - Statement::While { meta, cond, stmt } => { + Statement::While { meta, cond, stmt } => { let while_ok = remove_tuples_from_statement(*stmt)?; let b_while = Box::new(while_ok); - Result::Ok(Statement::While { meta : meta, cond : cond, stmt : b_while}) - } - Statement::LogCall {meta, args } => { + Result::Ok(Statement::While { meta: meta, cond: cond, stmt: b_while }) + } + Statement::LogCall { meta, args } => { let mut newargs = Vec::new(); for arg in args { match arg { LogArgument::LogStr(str) => { newargs.push(LogArgument::LogStr(str)); - }, + } LogArgument::LogExp(exp) => { let mut args2 = separate_tuple_for_logcall(vec![exp]); newargs.append(&mut args2); - }, + } } } Result::Ok(build_log_call(meta, newargs)) - } - Statement::InitializationBlock { meta, xtype, initializations } => - { + } + Statement::InitializationBlock { meta, xtype, initializations } => { let mut new_inits = Vec::new(); for stmt in initializations { let stmt_ok = remove_tuples_from_statement(stmt)?; new_inits.push(stmt_ok); } - Result::Ok(Statement::InitializationBlock { meta: meta, xtype: xtype, initializations: new_inits }) + Result::Ok(Statement::InitializationBlock { + meta: meta, + xtype: xtype, + initializations: new_inits, + }) } - Statement::Block { meta, stmts } => { + Statement::Block { meta, stmts } => { let mut new_stmts = Vec::new(); for stmt in stmts { let stmt_ok = remove_tuples_from_statement(stmt)?; new_stmts.push(stmt_ok); } - Result::Ok(Statement::Block { meta : meta, stmts: new_stmts}) + Result::Ok(Statement::Block { meta: meta, stmts: new_stmts }) } - Statement::Substitution { meta, var, op, rhe, access} => { + Statement::Substitution { meta, var, op, rhe, access } => { let new_rhe = remove_tuple_from_expression(rhe); if new_rhe.is_tuple() { - return Result::Err(tuple_general_error(meta.clone(),"Left-side of the statement is not a tuple".to_string())); - } - if var != "_" { - Result::Ok(Statement::Substitution { meta: meta.clone(), var: var, access: access, op: op, rhe: new_rhe }) + return Result::Err(tuple_general_error( + meta.clone(), + "Left-side of the statement is not a tuple".to_string(), + )); } - else { + if var != "_" { + Result::Ok(Statement::Substitution { + meta: meta.clone(), + var: var, + access: access, + op: op, + rhe: new_rhe, + }) + } else { Result::Ok(Statement::UnderscoreSubstitution { meta: meta, op, rhe: new_rhe }) } } @@ -895,42 +1091,39 @@ fn remove_tuples_from_statement(stm: Statement) -> Result { } } -fn separate_tuple_for_logcall(values: Vec) -> Vec { +fn separate_tuple_for_logcall(values: Vec) -> Vec { let mut new_values = Vec::new(); for val in values { - if let Expression::Tuple { values : values2, .. } = val { + if let Expression::Tuple { values: values2, .. } = val { new_values.push(LogArgument::LogStr("(".to_string())); let mut new_values2 = separate_tuple_for_logcall(values2); new_values.append(&mut new_values2); new_values.push(LogArgument::LogStr(")".to_string())); - } - else { + } else { new_values.push(LogArgument::LogExp(val)); } } new_values } - -pub fn remove_tuple_from_expression(exp : Expression) -> Expression{ +pub fn remove_tuple_from_expression(exp: Expression) -> Expression { use Expression::*; match exp { AnonymousComp { .. } => { unreachable!(); } Tuple { meta, values } => { - let mut unfolded_values = Vec::new(); + let mut unfolded_values = Vec::new(); for val in values { let exp = remove_tuple_from_expression(val); - if let Tuple { values: mut values2, ..} = exp { + if let Tuple { values: mut values2, .. } = exp { unfolded_values.append(&mut values2); - } else { + } else { unfolded_values.push(exp); - } + } } build_tuple(meta, unfolded_values) - }, + } _ => exp, } } - diff --git a/program_structure/src/abstract_syntax_tree/ast.rs b/program_structure/src/abstract_syntax_tree/ast.rs index 7f2dffb8d..beff2366e 100644 --- a/program_structure/src/abstract_syntax_tree/ast.rs +++ b/program_structure/src/abstract_syntax_tree/ast.rs @@ -1,11 +1,15 @@ -use crate::{file_definition::{FileLocation, FileID}, error_definition::Report, error_code::{ReportCode}}; +use crate::{ + file_definition::{FileLocation, FileID}, + error_definition::Report, + error_code::{ReportCode}, +}; use num_bigint::BigInt; use serde_derive::{Deserialize, Serialize}; #[derive(Clone)] pub enum Pragma { Version(Meta, FileID, Version), - CustomGates(Meta ,FileID), + CustomGates(Meta, FileID), Unrecognized, } @@ -99,7 +103,7 @@ impl AST { includes: Vec, definitions: Vec, main_component: Option, - ) -> (AST,Vec) { + ) -> (AST, Vec) { let mut custom_gates = None; let mut compiler_version = None; let mut reports = Vec::new(); @@ -108,16 +112,22 @@ impl AST { // TODO: don't panic Pragma::Version(location, file_id, ver) => match compiler_version { Some(_) => reports.push(produce_report( - ReportCode::MultiplePragma,location.start..location.end, file_id)), + ReportCode::MultiplePragma, + location.start..location.end, + file_id, + )), None => compiler_version = Some(ver), }, - Pragma::CustomGates(location, file_id ) => match custom_gates { + Pragma::CustomGates(location, file_id) => match custom_gates { Some(_) => reports.push(produce_report( - ReportCode::MultiplePragma, location.start..location.end, file_id)), + ReportCode::MultiplePragma, + location.start..location.end, + file_id, + )), None => custom_gates = Some(true), }, - Pragma::Unrecognized => {}, //This error is previously handled, and the - //parsing continues to catch more parsing errors. + Pragma::Unrecognized => {} //This error is previously handled, and the + //parsing continues to catch more parsing errors. } } @@ -125,15 +135,18 @@ impl AST { matches!(definition, Definition::Template { is_custom_gate: true, .. }) }); - (AST { - meta, - compiler_version, - custom_gates: custom_gates.unwrap_or(false), - custom_gates_declared, - includes, - definitions, - main_component, - }, reports) + ( + AST { + meta, + compiler_version, + custom_gates: custom_gates.unwrap_or(false), + custom_gates_declared, + includes, + definitions, + main_component, + }, + reports, + ) } } @@ -220,7 +233,7 @@ pub enum Statement { op: AssignOp, rhe: Expression, }, - UnderscoreSubstitution{ + UnderscoreSubstitution { meta: Meta, op: AssignOp, rhe: Expression, @@ -295,7 +308,7 @@ pub enum Expression { id: String, args: Vec, }, - AnonymousComp{ + AnonymousComp { meta: Meta, id: String, is_parallel: bool, @@ -390,7 +403,6 @@ pub fn build_log_expression(expr: Expression) -> LogArgument { LogArgument::LogExp(expr) } - #[derive(Default, Clone)] pub struct TypeKnowledge { reduces_to: Option, @@ -463,75 +475,79 @@ impl MemoryKnowledge { } } - pub fn produce_report(error_code: ReportCode, location : FileLocation, file_id : FileID) -> Report { +pub fn produce_report(error_code: ReportCode, location: FileLocation, file_id: FileID) -> Report { use ReportCode::*; - let report = match error_code { - UnclosedComment => { - let mut report = - Report::error("unterminated /* */".to_string(), ReportCode::UnclosedComment); - report.add_primary(location, file_id, "Comment starts here".to_string()); - report - } - NoMainFoundInProject => Report::error( - "No main specified in the project structure".to_string(), - ReportCode::NoMainFoundInProject, - ), - MultipleMain =>{ - Report::error( - "Multiple main components in the project structure".to_string(), - ReportCode::MultipleMain, - ) - } - MissingSemicolon => { - let mut report = Report::error(format!("Missing semicolon"), - ReportCode::MissingSemicolon); - report.add_primary(location, file_id, "A semicolon is needed here".to_string()); - report - } - UnrecognizedInclude => { - let mut report = - Report::error("unrecognized argument in include directive".to_string(), ReportCode::UnrecognizedInclude); + let report = match error_code { + UnclosedComment => { + let mut report = + Report::error("unterminated /* */".to_string(), ReportCode::UnclosedComment); + report.add_primary(location, file_id, "Comment starts here".to_string()); + report + } + NoMainFoundInProject => Report::error( + "No main specified in the project structure".to_string(), + ReportCode::NoMainFoundInProject, + ), + MultipleMain => Report::error( + "Multiple main components in the project structure".to_string(), + ReportCode::MultipleMain, + ), + MissingSemicolon => { + let mut report = + Report::error(format!("Missing semicolon"), ReportCode::MissingSemicolon); + report.add_primary(location, file_id, "A semicolon is needed here".to_string()); + report + } + UnrecognizedInclude => { + let mut report = Report::error( + "unrecognized argument in include directive".to_string(), + ReportCode::UnrecognizedInclude, + ); report.add_primary(location, file_id, "this argument".to_string()); report - - } - UnrecognizedPragma => { - let mut report = - Report::error("unrecognized argument in pragma directive".to_string(), ReportCode::UnrecognizedPragma); + } + UnrecognizedPragma => { + let mut report = Report::error( + "unrecognized argument in pragma directive".to_string(), + ReportCode::UnrecognizedPragma, + ); report.add_primary(location, file_id, "this argument".to_string()); report - - } - UnrecognizedVersion => { - let mut report = - Report::error("unrecognized version argument in pragma directive".to_string(), ReportCode::UnrecognizedVersion); + } + UnrecognizedVersion => { + let mut report = Report::error( + "unrecognized version argument in pragma directive".to_string(), + ReportCode::UnrecognizedVersion, + ); report.add_primary(location, file_id, "this argument".to_string()); report - } - IllegalExpression => { - let mut report = + } + IllegalExpression => { + let mut report = Report::error("illegal expression".to_string(), ReportCode::IllegalExpression); report.add_primary(location, file_id, "here".to_string()); report - } - MultiplePragma => { - let mut report = + } + MultiplePragma => { + let mut report = Report::error("Multiple pragma directives".to_string(), ReportCode::MultiplePragma); report.add_primary(location, file_id, "here".to_string()); report - }, - ExpectedIdentifier => { - let mut report = - Report::error("An identifier is expected".to_string(), ReportCode::ExpectedIdentifier); + } + ExpectedIdentifier => { + let mut report = Report::error( + "An identifier is expected".to_string(), + ReportCode::ExpectedIdentifier, + ); report.add_primary(location, file_id, "This should be an identifier".to_string()); report - }, - _ => unreachable!(), + } + _ => unreachable!(), }; report } -pub fn produce_version_warning_report(path : String, version : Version) -> Report { +pub fn produce_version_warning_report(path: String, version: Version) -> Report { let mut r = Report::warning( format!( "File {} does not include pragma version. Assuming pragma version {:?}", @@ -543,28 +559,30 @@ pub fn produce_version_warning_report(path : String, version : Version) -> Repor r } - -pub fn produce_report_with_message(error_code : ReportCode, msg : String) -> Report { +pub fn produce_report_with_message(error_code: ReportCode, msg: String) -> Report { match error_code { ReportCode::FileOs => { - Report::error( - format!("Could not open file {}", msg), - ReportCode::FileOs, - ) + Report::error(format!("Could not open file {}", msg), ReportCode::FileOs) } ReportCode::IncludeNotFound => { let mut r = Report::error( format!(" The file {} to be included has not been found", msg), ReportCode::IncludeNotFound, - ); - r.add_note("Consider using compilation option -l to indicate include paths".to_string()); - r - }, - _ => unreachable!() + ); + r.add_note( + "Consider using compilation option -l to indicate include paths".to_string(), + ); + r + } + _ => unreachable!(), } } -pub fn produce_compiler_version_report(path : String, required_version : Version, version : Version) -> Report { +pub fn produce_compiler_version_report( + path: String, + required_version: Version, + version: Version, +) -> Report { let report = Report::error( format!("File {} requires pragma version {:?} that is not supported by the compiler (version {:?})", path, required_version, version ), ReportCode::CompilerVersionError, @@ -572,45 +590,36 @@ pub fn produce_compiler_version_report(path : String, required_version : Version report } -pub fn anonymous_inside_condition_error(meta : Meta) -> Report { +pub fn anonymous_inside_condition_error(meta: Meta) -> Report { let msg = "An anonymous component cannot be used inside a condition ".to_string(); - let mut report = Report::error( - format!("{}", msg), - ReportCode::AnonymousCompError, - ); - let file_id = meta.get_file_id().clone(); - report.add_primary( - meta.location, - file_id, - "This is an anonymous component used inside a condition".to_string(), - ); - report -} - -pub fn anonymous_general_error(meta : Meta, msg : String) -> Report { - let mut report = Report::error( - format!("{}", msg), - ReportCode::AnonymousCompError, - ); - let file_id = meta.get_file_id().clone(); - report.add_primary( - meta.location, - file_id, - "This is the anonymous component whose use is not allowed".to_string(), - ); - report -} - -pub fn tuple_general_error(meta : Meta, msg : String) -> Report { - let mut report = Report::error( - format!("{}", msg), - ReportCode::TupleError, - ); - let file_id = meta.get_file_id().clone(); - report.add_primary( - meta.location, - file_id, - "This is the tuple whose use is not allowed".to_string(), - ); - report -} \ No newline at end of file + let mut report = Report::error(format!("{}", msg), ReportCode::AnonymousCompError); + let file_id = meta.get_file_id().clone(); + report.add_primary( + meta.location, + file_id, + "This is an anonymous component used inside a condition".to_string(), + ); + report +} + +pub fn anonymous_general_error(meta: Meta, msg: String) -> Report { + let mut report = Report::error(format!("{}", msg), ReportCode::AnonymousCompError); + let file_id = meta.get_file_id().clone(); + report.add_primary( + meta.location, + file_id, + "This is the anonymous component whose use is not allowed".to_string(), + ); + report +} + +pub fn tuple_general_error(meta: Meta, msg: String) -> Report { + let mut report = Report::error(format!("{}", msg), ReportCode::TupleError); + let file_id = meta.get_file_id().clone(); + report.add_primary( + meta.location, + file_id, + "This is the tuple whose use is not allowed".to_string(), + ); + report +} diff --git a/program_structure/src/abstract_syntax_tree/ast_impl.rs b/program_structure/src/abstract_syntax_tree/ast_impl.rs index 20f70ab37..657ea181f 100644 --- a/program_structure/src/abstract_syntax_tree/ast_impl.rs +++ b/program_structure/src/abstract_syntax_tree/ast_impl.rs @@ -12,7 +12,9 @@ impl AST { pub fn get_definitions(&self) -> &Vec { &self.definitions } - pub fn decompose(self) -> (Meta, Option, Vec, Vec, Option) { + pub fn decompose( + self, + ) -> (Meta, Option, Vec, Vec, Option) { (self.meta, self.compiler_version, self.includes, self.definitions, self.main_component) } } diff --git a/program_structure/src/abstract_syntax_tree/ast_shortcuts.rs b/program_structure/src/abstract_syntax_tree/ast_shortcuts.rs index 2041797d0..3732165c1 100644 --- a/program_structure/src/abstract_syntax_tree/ast_shortcuts.rs +++ b/program_structure/src/abstract_syntax_tree/ast_shortcuts.rs @@ -11,8 +11,8 @@ pub struct Symbol { pub init: Option, } -pub struct TupleInit{ - pub tuple_init : (AssignOp,Expression) +pub struct TupleInit { + pub tuple_init: (AssignOp, Expression), } pub fn assign_with_op_shortcut( @@ -68,18 +68,15 @@ pub fn split_declaration_into_single_nodes( let single_declaration = build_declaration(with_meta, has_type, name, dimensions.clone()); initializations.push(single_declaration); if let Option::Some(init) = possible_init { - let substitution = - build_substitution(meta.clone(), symbol.name, vec![], op, init); + let substitution = build_substitution(meta.clone(), symbol.name, vec![], op, init); initializations.push(substitution); - } - else if xtype == Var { - let mut value = Expression:: Number(meta.clone(), BigInt::from(0)); - for dim_expr in dimensions.iter().rev(){ + } else if xtype == Var { + let mut value = Expression::Number(meta.clone(), BigInt::from(0)); + for dim_expr in dimensions.iter().rev() { value = build_uniform_array(meta.clone(), value, dim_expr.clone()); } - let substitution = - build_substitution(meta.clone(), symbol.name, vec![], op, value); + let substitution = build_substitution(meta.clone(), symbol.name, vec![], op, value); initializations.push(substitution); } } @@ -102,24 +99,34 @@ pub fn split_declaration_into_single_nodes_and_multisubstitution( let name = symbol.name.clone(); let dimensions = symbol.is_array; debug_assert!(symbol.init.is_none()); - let single_declaration = build_declaration(with_meta.clone(), has_type, name.clone(), dimensions.clone()); + let single_declaration = + build_declaration(with_meta.clone(), has_type, name.clone(), dimensions.clone()); initializations.push(single_declaration); if xtype == Var && init.is_none() { - let mut value = Expression:: Number(meta.clone(), BigInt::from(0)); - for dim_expr in dimensions.iter().rev(){ + let mut value = Expression::Number(meta.clone(), BigInt::from(0)); + for dim_expr in dimensions.iter().rev() { value = build_uniform_array(meta.clone(), value, dim_expr.clone()); } - let substitution = + let substitution = build_substitution(meta.clone(), symbol.name, vec![], AssignOp::AssignVar, value); initializations.push(substitution); } - values.push(Expression::Variable { meta: with_meta.clone(), name: name, access: Vec::new() }) + values.push(Expression::Variable { + meta: with_meta.clone(), + name: name, + access: Vec::new(), + }) } - if let Some( tuple) = init { - let (op,expression) = tuple.tuple_init; - let multi_sub = build_mult_substitution(meta.clone(), build_tuple(meta.clone(), values), op, expression); + if let Some(tuple) = init { + let (op, expression) = tuple.tuple_init; + let multi_sub = build_mult_substitution( + meta.clone(), + build_tuple(meta.clone(), values), + op, + expression, + ); initializations.push(multi_sub); } build_initialization_block(meta, xtype, initializations) -} \ No newline at end of file +} diff --git a/program_structure/src/abstract_syntax_tree/expression_builders.rs b/program_structure/src/abstract_syntax_tree/expression_builders.rs index 0e7d2a0ba..bead779a4 100644 --- a/program_structure/src/abstract_syntax_tree/expression_builders.rs +++ b/program_structure/src/abstract_syntax_tree/expression_builders.rs @@ -29,14 +29,8 @@ pub fn build_inline_switch_op( } } -pub fn build_parallel_op( - meta: Meta, - rhe: Expression, -)-> Expression { - ParallelOp{ - meta, - rhe: Box::new(rhe), - } +pub fn build_parallel_op(meta: Meta, rhe: Expression) -> Expression { + ParallelOp { meta, rhe: Box::new(rhe) } } pub fn build_variable(meta: Meta, name: String, access: Vec) -> Expression { @@ -51,7 +45,14 @@ pub fn build_call(meta: Meta, id: String, args: Vec) -> Expression { Call { meta, id, args } } -pub fn build_anonymous_component(meta: Meta, id: String, params: Vec, signals: Vec, names: Option>, is_parallel: bool) -> Expression { +pub fn build_anonymous_component( + meta: Meta, + id: String, + params: Vec, + signals: Vec, + names: Option>, + is_parallel: bool, +) -> Expression { AnonymousComp { meta, id, params, signals, names, is_parallel } } pub fn build_array_in_line(meta: Meta, values: Vec) -> Expression { @@ -66,12 +67,14 @@ pub fn build_uniform_array(meta: Meta, value: Expression, dimension: Expression) UniformArray { meta, value: Box::new(value), dimension: Box::new(dimension) } } -pub fn unzip_3(vec : Vec<(String, AssignOp, Expression)>) -> (Vec<(AssignOp, String)>, Vec){ +pub fn unzip_3( + vec: Vec<(String, AssignOp, Expression)>, +) -> (Vec<(AssignOp, String)>, Vec) { let mut op_name = Vec::new(); let mut exprs = Vec::new(); - for i in vec{ + for i in vec { op_name.push((i.1, i.0)); exprs.push(i.2); } (op_name, exprs) -} \ No newline at end of file +} diff --git a/program_structure/src/abstract_syntax_tree/expression_impl.rs b/program_structure/src/abstract_syntax_tree/expression_impl.rs index 900827e6f..d68071c50 100644 --- a/program_structure/src/abstract_syntax_tree/expression_impl.rs +++ b/program_structure/src/abstract_syntax_tree/expression_impl.rs @@ -9,14 +9,14 @@ impl Expression { InfixOp { meta, .. } | PrefixOp { meta, .. } | InlineSwitchOp { meta, .. } - | ParallelOp {meta, .. } + | ParallelOp { meta, .. } | Variable { meta, .. } | Number(meta, ..) | Call { meta, .. } - | AnonymousComp { meta, ..} + | AnonymousComp { meta, .. } | ArrayInLine { meta, .. } => meta, - | UniformArray { meta, .. } => meta, - | Tuple {meta, ..} => meta, + UniformArray { meta, .. } => meta, + Tuple { meta, .. } => meta, } } pub fn get_mut_meta(&mut self) -> &mut Meta { @@ -25,14 +25,14 @@ impl Expression { InfixOp { meta, .. } | PrefixOp { meta, .. } | InlineSwitchOp { meta, .. } - | ParallelOp {meta, .. } + | ParallelOp { meta, .. } | Variable { meta, .. } | Number(meta, ..) | Call { meta, .. } - | AnonymousComp {meta, ..} + | AnonymousComp { meta, .. } | ArrayInLine { meta, .. } => meta, - | UniformArray { meta, .. } => meta, - | Tuple {meta, ..} => meta, + UniformArray { meta, .. } => meta, + Tuple { meta, .. } => meta, } } @@ -40,7 +40,7 @@ impl Expression { use Expression::*; if let ArrayInLine { .. } = self { true - } else if let UniformArray { .. } = self{ + } else if let UniformArray { .. } = self { true } else { false @@ -64,7 +64,7 @@ impl Expression { false } } - + pub fn is_tuple(&self) -> bool { use Expression::*; if let Tuple { .. } = self { @@ -134,82 +134,96 @@ impl Expression { build_anonymous_component(meta, id, params, signals, names, true) } _ => self, - } - } + } + } pub fn contains_anonymous_comp(&self) -> bool { use Expression::*; match &self { - InfixOp { lhe, rhe , ..} | UniformArray { value : lhe, dimension : rhe, .. } => { - lhe.contains_anonymous_comp() || rhe.contains_anonymous_comp() - }, - PrefixOp { rhe, .. } => { - rhe.contains_anonymous_comp() - }, - InlineSwitchOp { cond, if_true, if_false, .. } => { - cond.contains_anonymous_comp() || if_true.contains_anonymous_comp() || if_false.contains_anonymous_comp() - }, - Call { args, .. } | Tuple {values: args, ..} | ArrayInLine { values : args, .. } => { - for arg in args{ - if arg.contains_anonymous_comp() { return true;} + InfixOp { lhe, rhe, .. } | UniformArray { value: lhe, dimension: rhe, .. } => { + lhe.contains_anonymous_comp() || rhe.contains_anonymous_comp() + } + PrefixOp { rhe, .. } => rhe.contains_anonymous_comp(), + InlineSwitchOp { cond, if_true, if_false, .. } => { + cond.contains_anonymous_comp() + || if_true.contains_anonymous_comp() + || if_false.contains_anonymous_comp() + } + Call { args, .. } | Tuple { values: args, .. } | ArrayInLine { values: args, .. } => { + for arg in args { + if arg.contains_anonymous_comp() { + return true; + } } false - }, - AnonymousComp { .. } => { true }, + } + AnonymousComp { .. } => true, Variable { access, .. } => { - for ac in access{ + for ac in access { match ac { - Access::ComponentAccess(_) => {}, - Access::ArrayAccess( exp ) => if exp.contains_anonymous_comp() {return true;}, + Access::ComponentAccess(_) => {} + Access::ArrayAccess(exp) => { + if exp.contains_anonymous_comp() { + return true; + } + } } } false - }, - Number(_, _) => {false } - ParallelOp { rhe , .. } => { rhe.contains_anonymous_comp() }, - } + } + Number(_, _) => false, + ParallelOp { rhe, .. } => rhe.contains_anonymous_comp(), + } } pub fn contains_tuple(&self) -> bool { use Expression::*; match &self { - InfixOp { lhe, rhe , ..} | UniformArray { value : lhe, dimension : rhe, .. } => { - lhe.contains_tuple() || rhe.contains_tuple() - }, - PrefixOp { rhe, .. } => { - rhe.contains_tuple() - }, - InlineSwitchOp { cond, if_true, if_false, .. } => { - cond.contains_tuple() || if_true.contains_tuple() || if_false.contains_tuple() - }, - Call { args, .. } | ArrayInLine { values : args, .. } => { - for arg in args{ - if arg.contains_tuple() { return true;} + InfixOp { lhe, rhe, .. } | UniformArray { value: lhe, dimension: rhe, .. } => { + lhe.contains_tuple() || rhe.contains_tuple() + } + PrefixOp { rhe, .. } => rhe.contains_tuple(), + InlineSwitchOp { cond, if_true, if_false, .. } => { + cond.contains_tuple() || if_true.contains_tuple() || if_false.contains_tuple() + } + Call { args, .. } | ArrayInLine { values: args, .. } => { + for arg in args { + if arg.contains_tuple() { + return true; + } } false - }, - AnonymousComp { params, signals, .. } => { - for ac in params{ - if ac.contains_tuple() {return true;} + } + AnonymousComp { params, signals, .. } => { + for ac in params { + if ac.contains_tuple() { + return true; + } } - for ac in signals{ - if ac.contains_tuple() {return true;} + for ac in signals { + if ac.contains_tuple() { + return true; + } } false - }, + } Variable { access, .. } => { - for ac in access{ + for ac in access { match ac { - Access::ComponentAccess(_) => {}, - Access::ArrayAccess( exp ) => if exp.contains_tuple() {return true;}, + Access::ComponentAccess(_) => {} + Access::ArrayAccess(exp) => { + if exp.contains_tuple() { + return true; + } + } } } false - }, - Number(_, _) => {false }, - Tuple { .. } => {true}, - ParallelOp { rhe, .. } => {rhe.contains_tuple()}, - } + } + Number(_, _) => false, + Tuple { .. } => true, + ParallelOp { rhe, .. } => rhe.contains_tuple(), + } } } @@ -223,7 +237,7 @@ impl FillMeta for Expression { Variable { meta, access, .. } => fill_variable(meta, access, file_id, element_id), InfixOp { meta, lhe, rhe, .. } => fill_infix(meta, lhe, rhe, file_id, element_id), PrefixOp { meta, rhe, .. } => fill_prefix(meta, rhe, file_id, element_id), - ParallelOp{ meta, rhe, ..} => fill_parallel(meta, rhe, file_id, element_id), + ParallelOp { meta, rhe, .. } => fill_parallel(meta, rhe, file_id, element_id), InlineSwitchOp { meta, cond, if_false, if_true, .. } => { fill_inline_switch_op(meta, cond, if_true, if_false, file_id, element_id) } @@ -234,10 +248,10 @@ impl FillMeta for Expression { UniformArray { meta, value, dimension, .. } => { fill_uniform_array(meta, value, dimension, file_id, element_id) } - AnonymousComp { meta, params, signals, .. } => { - fill_anonymous_comp(meta, params, signals, file_id, element_id) - }, - Tuple { meta, values} => {fill_tuple(meta,values,file_id,element_id)} + AnonymousComp { meta, params, signals, .. } => { + fill_anonymous_comp(meta, params, signals, file_id, element_id) + } + Tuple { meta, values } => fill_tuple(meta, values, file_id, element_id), } } } @@ -298,7 +312,13 @@ fn fill_call(meta: &mut Meta, args: &mut [Expression], file_id: usize, element_i } } -fn fill_anonymous_comp(meta: &mut Meta, params: &mut [Expression],signals: &mut [Expression], file_id: usize, element_id: &mut usize) { +fn fill_anonymous_comp( + meta: &mut Meta, + params: &mut [Expression], + signals: &mut [Expression], + file_id: usize, + element_id: &mut usize, +) { meta.set_file_id(file_id); for a in params { a.fill(file_id, element_id); @@ -319,12 +339,7 @@ fn fill_array_inline( } } -fn fill_tuple( - meta: &mut Meta, - values: &mut [Expression], - file_id: usize, - element_id: &mut usize, -) { +fn fill_tuple(meta: &mut Meta, values: &mut [Expression], file_id: usize, element_id: &mut usize) { meta.set_file_id(file_id); for v in values { v.fill(file_id, element_id); diff --git a/program_structure/src/abstract_syntax_tree/statement_builders.rs b/program_structure/src/abstract_syntax_tree/statement_builders.rs index aebcbc04c..f50387095 100644 --- a/program_structure/src/abstract_syntax_tree/statement_builders.rs +++ b/program_structure/src/abstract_syntax_tree/statement_builders.rs @@ -57,8 +57,12 @@ pub fn build_log_call(meta: Meta, args: Vec) -> Statement { let mut new_args = Vec::new(); for arg in args { match arg { - LogArgument::LogExp(..) => { new_args.push(arg);} - LogArgument::LogStr(str) => { new_args.append(&mut split_string(str));} + LogArgument::LogExp(..) => { + new_args.push(arg); + } + LogArgument::LogStr(str) => { + new_args.append(&mut split_string(str)); + } } } LogCall { meta, args: new_args } @@ -80,10 +84,20 @@ pub fn build_assert(meta: Meta, arg: Expression) -> Statement { Assert { meta, arg } } -pub fn build_mult_substitution(meta: Meta, lhe: Expression, op : AssignOp, rhe: Expression) -> Statement { +pub fn build_mult_substitution( + meta: Meta, + lhe: Expression, + op: AssignOp, + rhe: Expression, +) -> Statement { MultSubstitution { meta: meta.clone(), lhe, op, rhe } } pub fn build_anonymous_component_statement(meta: Meta, arg: Expression) -> Statement { - MultSubstitution { meta: meta.clone(), lhe: crate::expression_builders::build_tuple(meta, Vec::new()), op: AssignOp::AssignConstraintSignal, rhe: arg } -} \ No newline at end of file + MultSubstitution { + meta: meta.clone(), + lhe: crate::expression_builders::build_tuple(meta, Vec::new()), + op: AssignOp::AssignConstraintSignal, + rhe: arg, + } +} diff --git a/program_structure/src/abstract_syntax_tree/statement_impl.rs b/program_structure/src/abstract_syntax_tree/statement_impl.rs index 48f681012..26ec00b5c 100644 --- a/program_structure/src/abstract_syntax_tree/statement_impl.rs +++ b/program_structure/src/abstract_syntax_tree/statement_impl.rs @@ -14,8 +14,8 @@ impl Statement { | Assert { meta, .. } | ConstraintEquality { meta, .. } | InitializationBlock { meta, .. } => meta, - | MultSubstitution { meta, ..} => meta, - | UnderscoreSubstitution { meta, .. } => meta, + MultSubstitution { meta, .. } => meta, + UnderscoreSubstitution { meta, .. } => meta, } } pub fn get_mut_meta(&mut self) -> &mut Meta { @@ -31,8 +31,8 @@ impl Statement { | Assert { meta, .. } | ConstraintEquality { meta, .. } | InitializationBlock { meta, .. } => meta, - | MultSubstitution { meta, ..} => meta, - | UnderscoreSubstitution { meta, .. } => meta, + MultSubstitution { meta, .. } => meta, + UnderscoreSubstitution { meta, .. } => meta, } } @@ -147,8 +147,7 @@ impl FillMeta for Statement { Substitution { meta, access, rhe, .. } => { fill_substitution(meta, access, rhe, file_id, element_id) } - MultSubstitution { meta, lhe, rhe, .. } - => { + MultSubstitution { meta, lhe, rhe, .. } => { fill_mult_substitution(meta, lhe, rhe, file_id, element_id); } ConstraintEquality { meta, lhe, rhe } => { @@ -159,13 +158,11 @@ impl FillMeta for Statement { Assert { meta, arg, .. } => fill_assert(meta, arg, file_id, element_id), UnderscoreSubstitution { meta, rhe, .. } => { fill_underscore_substitution(meta, rhe, file_id, element_id); - }, - + } } } } - fn fill_conditional( meta: &mut Meta, cond: &mut Expression, @@ -248,7 +245,7 @@ fn fill_mult_substitution( ) { meta.set_file_id(file_id); rhe.fill(file_id, element_id); - lhe.fill(file_id,element_id); + lhe.fill(file_id, element_id); } fn fill_constraint_equality( @@ -263,7 +260,12 @@ fn fill_constraint_equality( rhe.fill(file_id, element_id); } -fn fill_log_call(meta: &mut Meta, args: &mut Vec, file_id: usize, element_id: &mut usize) { +fn fill_log_call( + meta: &mut Meta, + args: &mut Vec, + file_id: usize, + element_id: &mut usize, +) { meta.set_file_id(file_id); for arg in args { if let LogArgument::LogExp(e) = arg { @@ -284,8 +286,12 @@ fn fill_assert(meta: &mut Meta, arg: &mut Expression, file_id: usize, element_id arg.fill(file_id, element_id); } -fn fill_underscore_substitution(meta: &mut Meta, rhe: &mut Expression, file_id: usize, element_id: &mut usize) { +fn fill_underscore_substitution( + meta: &mut Meta, + rhe: &mut Expression, + file_id: usize, + element_id: &mut usize, +) { meta.set_file_id(file_id); rhe.fill(file_id, element_id); - -} \ No newline at end of file +} diff --git a/program_structure/src/program_library/error_code.rs b/program_structure/src/program_library/error_code.rs index ba1ca693a..851402c0b 100644 --- a/program_structure/src/program_library/error_code.rs +++ b/program_structure/src/program_library/error_code.rs @@ -1,13 +1,13 @@ use core::fmt; use std::fmt::Formatter; -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub enum ReportCode { //Parse Errors UnclosedComment, FileOs, NoMainFoundInProject, - MultipleMain, + MultipleMain, MissingSemicolon, UnrecognizedInclude, UnrecognizedVersion, @@ -16,7 +16,7 @@ pub enum ReportCode { IncludeNotFound, IllegalExpression, MultiplePragma, - NoCompilerVersionWarning, + NoCompilerVersionWarning, CompilerVersionError, WrongTypesInAssignOperationOperatorSignal, WrongTypesInAssignOperationOperatorNoSignal, @@ -123,7 +123,7 @@ impl fmt::Display for ReportCode { WrongTypesInAssignOperationExpression => "T2000", WrongTypesInAssignOperationDims(..) => "T2000", UnclosedComment => "P1005", - FileOs => "P1006", + FileOs => "P1006", MissingSemicolon => "P1008", UnrecognizedInclude => "P1009", UnrecognizedVersion => "P1010", diff --git a/program_structure/src/program_library/program_archive.rs b/program_structure/src/program_library/program_archive.rs index 69f6d18a4..c6dae8020 100644 --- a/program_structure/src/program_library/program_archive.rs +++ b/program_structure/src/program_library/program_archive.rs @@ -64,7 +64,6 @@ impl ProgramArchive { } else { Err((file_library, reports)) } - } //file_id_main pub fn get_file_id_main(&self) -> &FileID { diff --git a/program_structure/src/program_library/program_merger.rs b/program_structure/src/program_library/program_merger.rs index 7e44cac09..cb46f70fc 100644 --- a/program_structure/src/program_library/program_merger.rs +++ b/program_structure/src/program_library/program_merger.rs @@ -25,11 +25,23 @@ impl Merger { Merger::default() } - pub fn add_definitions(&mut self, file_id: FileID, definitions: Vec) -> Result<(), Vec> { + pub fn add_definitions( + &mut self, + file_id: FileID, + definitions: Vec, + ) -> Result<(), Vec> { 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 } => { + 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 { @@ -79,7 +91,11 @@ impl Merger { reports.push(report); } } - if reports.is_empty() { Ok(()) } else { Err(reports) } + 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) @@ -101,7 +117,6 @@ impl Merger { &mut self.template_info } - pub fn decompose(self) -> (usize, FunctionInfo, TemplateInfo) { (self.fresh_id, self.function_info, self.template_info) } diff --git a/program_structure/src/program_library/template_data.rs b/program_structure/src/program_library/template_data.rs index 134f7e405..43d12ba24 100644 --- a/program_structure/src/program_library/template_data.rs +++ b/program_structure/src/program_library/template_data.rs @@ -41,9 +41,15 @@ impl TemplateData { body.fill(file_id, elem_id); let mut input_signals = SignalInfo::new(); let mut output_signals = SignalInfo::new(); - let mut input_declarations = SignalDeclarationOrder::new(); + let mut input_declarations = SignalDeclarationOrder::new(); let mut output_declarations = SignalDeclarationOrder::new(); - fill_inputs_and_outputs(&body, &mut input_signals, &mut output_signals, &mut input_declarations, &mut output_declarations); + fill_inputs_and_outputs( + &body, + &mut input_signals, + &mut output_signals, + &mut input_declarations, + &mut output_declarations, + ); TemplateData { name, file_id, @@ -56,7 +62,7 @@ impl TemplateData { is_parallel, is_custom_gate, input_declarations, - output_declarations + output_declarations, } } @@ -71,8 +77,8 @@ impl TemplateData { output_signals: SignalInfo, is_parallel: bool, is_custom_gate: bool, - input_declarations :SignalDeclarationOrder, - output_declarations : SignalDeclarationOrder + input_declarations: SignalDeclarationOrder, + output_declarations: SignalDeclarationOrder, ) -> TemplateData { TemplateData { name, @@ -86,7 +92,7 @@ impl TemplateData { is_parallel, is_custom_gate, input_declarations, - output_declarations + output_declarations, } } pub fn get_file_id(&self) -> FileID { @@ -152,27 +158,57 @@ fn fill_inputs_and_outputs( template_statement: &Statement, input_signals: &mut SignalInfo, output_signals: &mut SignalInfo, - input_declarations : &mut SignalDeclarationOrder, - output_declarations : &mut SignalDeclarationOrder + input_declarations: &mut SignalDeclarationOrder, + output_declarations: &mut SignalDeclarationOrder, ) { match template_statement { Statement::IfThenElse { if_case, else_case, .. } => { - fill_inputs_and_outputs(if_case, input_signals, output_signals, input_declarations, output_declarations); + fill_inputs_and_outputs( + if_case, + input_signals, + output_signals, + input_declarations, + output_declarations, + ); if let Option::Some(else_value) = else_case { - fill_inputs_and_outputs(else_value, input_signals, output_signals, input_declarations, output_declarations); + fill_inputs_and_outputs( + else_value, + input_signals, + output_signals, + input_declarations, + output_declarations, + ); } } Statement::Block { stmts, .. } => { for stmt in stmts.iter() { - fill_inputs_and_outputs(stmt, input_signals, output_signals, input_declarations, output_declarations); + fill_inputs_and_outputs( + stmt, + input_signals, + output_signals, + input_declarations, + output_declarations, + ); } } Statement::While { stmt, .. } => { - fill_inputs_and_outputs(stmt, input_signals, output_signals, input_declarations, output_declarations); + fill_inputs_and_outputs( + stmt, + input_signals, + output_signals, + input_declarations, + output_declarations, + ); } Statement::InitializationBlock { initializations, .. } => { for initialization in initializations.iter() { - fill_inputs_and_outputs(initialization, input_signals, output_signals, input_declarations, output_declarations); + fill_inputs_and_outputs( + initialization, + input_signals, + output_signals, + input_declarations, + output_declarations, + ); } } Statement::Declaration { xtype, name, dimensions, .. } => { @@ -180,18 +216,18 @@ fn fill_inputs_and_outputs( let signal_name = name.clone(); let dim = dimensions.len(); let mut tag_info = HashSet::new(); - for tag in tag_list{ + for tag in tag_list { tag_info.insert(tag.clone()); } match stype { ast::SignalType::Input => { input_signals.insert(signal_name.clone(), (dim, tag_info)); - input_declarations.push((signal_name,dim)); + input_declarations.push((signal_name, dim)); } ast::SignalType::Output => { output_signals.insert(signal_name.clone(), (dim, tag_info)); - output_declarations.push((signal_name,dim)); + output_declarations.push((signal_name, dim)); } _ => {} //no need to deal with intermediate signals } diff --git a/program_structure/src/utils/constants.rs b/program_structure/src/utils/constants.rs index 42ae5f289..32bd3c8bd 100644 --- a/program_structure/src/utils/constants.rs +++ b/program_structure/src/utils/constants.rs @@ -2,13 +2,15 @@ use num_bigint::BigInt; const P_BN128: &str = "21888242871839275222246405745257275088548364400416034343698204186575808495617"; -const P_BLS12381: &str = +const P_BLS12381: &str = "52435875175126190479447740508185965837690552500527637822603658699938581184513"; -const P_GOLDILOCKS: &str = - "18446744069414584321"; -const P_GRUMPKIN: &str = "21888242871839275222246405745257275088696311157297823662689037894645226208583"; -const P_PALLAS: &str = "28948022309329048855892746252171976963363056481941560715954676764349967630337"; -const P_VESTA : &str = "28948022309329048855892746252171976963363056481941647379679742748393362948097"; +const P_GOLDILOCKS: &str = "18446744069414584321"; +const P_GRUMPKIN: &str = + "21888242871839275222246405745257275088696311157297823662689037894645226208583"; +const P_PALLAS: &str = + "28948022309329048855892746252171976963363056481941560715954676764349967630337"; +const P_VESTA: &str = + "28948022309329048855892746252171976963363056481941647379679742748393362948097"; //const P_STR: &str = "21888242871839275222246405745257275088548364400416034343698204186575808495617"; pub struct UsefulConstants { @@ -23,17 +25,27 @@ impl Clone for UsefulConstants { impl UsefulConstants { pub fn new(possible_prime: &String) -> UsefulConstants { - let prime_to_use = if possible_prime.eq("bn128") {P_BN128} - else if possible_prime.eq("bls12381") { P_BLS12381} - else if possible_prime.eq("goldilocks") { P_GOLDILOCKS} - else if possible_prime.eq("grumpkin") { P_GRUMPKIN} - else if possible_prime.eq("pallas") { P_PALLAS} - else if possible_prime.eq("vesta") { P_VESTA} - else {unreachable!()}; + let prime_to_use = if possible_prime.eq("bn128") { + P_BN128 + } else if possible_prime.eq("bls12381") { + P_BLS12381 + } else if possible_prime.eq("goldilocks") { + P_GOLDILOCKS + } else if possible_prime.eq("grumpkin") { + P_GRUMPKIN + } else if possible_prime.eq("pallas") { + P_PALLAS + } else if possible_prime.eq("vesta") { + P_VESTA + } else { + unreachable!() + }; - UsefulConstants { p: BigInt::parse_bytes(prime_to_use.as_bytes(), 10).expect("can not parse p") } + UsefulConstants { + p: BigInt::parse_bytes(prime_to_use.as_bytes(), 10).expect("can not parse p"), + } } - + pub fn get_p(&self) -> &BigInt { &self.p } diff --git a/program_structure/src/utils/environment.rs b/program_structure/src/utils/environment.rs index 0215dce61..b13c7e10c 100644 --- a/program_structure/src/utils/environment.rs +++ b/program_structure/src/utils/environment.rs @@ -234,7 +234,7 @@ where assert!(self.has_component(symbol), "Method call in file {} line {}", file, line); self.components.get_mut(symbol).unwrap() } - pub fn get_components_ref(&self)-> &HashMap{ + pub fn get_components_ref(&self) -> &HashMap { &self.components } } diff --git a/program_structure/src/utils/memory_slice.rs b/program_structure/src/utils/memory_slice.rs index 2a719a710..5ce67e39d 100644 --- a/program_structure/src/utils/memory_slice.rs +++ b/program_structure/src/utils/memory_slice.rs @@ -1,16 +1,16 @@ use num_bigint_dig::BigInt; use std::fmt::{Display, Formatter}; -pub enum TypeInvalidAccess{ +pub enum TypeInvalidAccess { MissingInputs(String), MissingInputTags(String), NoInitializedComponent, - NoInitializedSignal + NoInitializedSignal, } -pub enum TypeAssignmentError{ +pub enum TypeAssignmentError { MultipleAssignments, - AssignmentOutput + AssignmentOutput, } pub enum MemoryError { @@ -26,7 +26,7 @@ pub enum MemoryError { AssignmentTagInputTwice(String), AssignmentTagInput, TagValueNotInitializedAccess, - MissingInputs(String) + MissingInputs(String), } pub type SliceCapacity = usize; pub type SimpleSlice = MemorySlice; @@ -44,7 +44,11 @@ pub struct MemorySlice { impl Clone for MemorySlice { fn clone(&self) -> Self { - MemorySlice { route: self.route.clone(), values: self.values.clone(), number_inserts: self.number_inserts} + MemorySlice { + route: self.route.clone(), + values: self.values.clone(), + number_inserts: self.number_inserts, + } } } @@ -71,7 +75,6 @@ impl MemorySlice { memory_slice: &MemorySlice, access: &[SliceCapacity], ) -> Result { - if access.len() > memory_slice.route.len() { return Result::Err(MemoryError::OutOfBoundsError); } @@ -95,13 +98,12 @@ impl MemorySlice { new_values: &MemorySlice, is_strict: bool, ) -> Result<(), MemoryError> { - if access.len() + new_values.route.len() > memory_slice.route.len() { return Result::Err(MemoryError::OutOfBoundsError); } let mut i: SliceCapacity = 0; - + while i < access.len() { if access[i] >= memory_slice.route[i] { return Result::Err(MemoryError::OutOfBoundsError); @@ -114,14 +116,25 @@ impl MemorySlice { while i < new_values.route.len() { if new_values.route[i] < memory_slice.route[initial_index_new + i] { - if is_strict{ // case signals: we do not allow - return Result::Err(MemoryError::MismatchedDimensions(new_values.route[i], memory_slice.route[initial_index_new + i])); - } else{ // case variables: we allow the assignment of smaller arrays - return Result::Err(MemoryError::MismatchedDimensionsWeak(new_values.route[i], memory_slice.route[initial_index_new + i])); + if is_strict { + // case signals: we do not allow + return Result::Err(MemoryError::MismatchedDimensions( + new_values.route[i], + memory_slice.route[initial_index_new + i], + )); + } else { + // case variables: we allow the assignment of smaller arrays + return Result::Err(MemoryError::MismatchedDimensionsWeak( + new_values.route[i], + memory_slice.route[initial_index_new + i], + )); } } if new_values.route[i] > memory_slice.route[initial_index_new + i] { - return Result::Err(MemoryError::MismatchedDimensions(new_values.route[i], memory_slice.route[initial_index_new + i])); + return Result::Err(MemoryError::MismatchedDimensions( + new_values.route[i], + memory_slice.route[initial_index_new + i], + )); } i += 1; } @@ -193,9 +206,9 @@ impl MemorySlice { memory_slice: &mut MemorySlice, access: &[SliceCapacity], new_values: &MemorySlice, - is_strict:bool, + is_strict: bool, ) -> Result<(), MemoryError> { - match MemorySlice::check_correct_dims(memory_slice, access, new_values, is_strict){ + match MemorySlice::check_correct_dims(memory_slice, access, new_values, is_strict) { Result::Ok(_) => { let mut cell = MemorySlice::get_initial_cell(memory_slice, access)?; @@ -203,14 +216,14 @@ impl MemorySlice { // > (MemorySlice::get_number_of_cells(memory_slice) - cell) // { // return Result::Err(MemoryError::OutOfBoundsError); - - memory_slice.number_inserts += MemorySlice::get_number_of_cells(new_values); + + memory_slice.number_inserts += MemorySlice::get_number_of_cells(new_values); for value in new_values.values.iter() { memory_slice.values[cell] = value.clone(); cell += 1; } Result::Ok(()) - }, + } Result::Err(MemoryError::MismatchedDimensionsWeak(dim_1, dim_2)) => { let mut cell = MemorySlice::get_initial_cell(memory_slice, access)?; // if MemorySlice::get_number_of_cells(new_values) @@ -223,7 +236,7 @@ impl MemorySlice { cell += 1; } Result::Err(MemoryError::MismatchedDimensionsWeak(dim_1, dim_2)) - }, + } Result::Err(error) => return Err(error), } } @@ -232,7 +245,7 @@ impl MemorySlice { memory_slice: &mut MemorySlice, index: usize, new_value: C, - )-> Result<(), MemoryError> { + ) -> Result<(), MemoryError> { if index > MemorySlice::get_number_of_cells(memory_slice) { return Result::Err(MemoryError::OutOfBoundsError); } @@ -244,16 +257,15 @@ impl MemorySlice { pub fn get_access_index( memory_slice: &MemorySlice, index: usize, - ) -> Result, MemoryError>{ + ) -> Result, MemoryError> { let mut number_cells = MemorySlice::get_number_of_cells(memory_slice); if index > number_cells { return Result::Err(MemoryError::OutOfBoundsError); - } - else{ + } else { let mut access = vec![]; let mut index_aux = index; - for pos in &memory_slice.route{ - number_cells = number_cells/pos; + for pos in &memory_slice.route { + number_cells = number_cells / pos; access.push(index_aux / number_cells); index_aux = index_aux % number_cells; } @@ -270,7 +282,7 @@ impl MemorySlice { pub fn access_value_by_index( memory_slice: &MemorySlice, index: usize, - )-> Result { + ) -> Result { if index > MemorySlice::get_number_of_cells(memory_slice) { return Result::Err(MemoryError::OutOfBoundsError); } diff --git a/type_analysis/src/analyzers/custom_gate_analysis.rs b/type_analysis/src/analyzers/custom_gate_analysis.rs index 8269bbde2..39e9d825a 100644 --- a/type_analysis/src/analyzers/custom_gate_analysis.rs +++ b/type_analysis/src/analyzers/custom_gate_analysis.rs @@ -4,13 +4,13 @@ use program_structure::error_definition::{Report, ReportCollection}; pub fn custom_gate_analysis( custom_gate_name: &str, - custom_gate_body: &Statement + custom_gate_body: &Statement, ) -> Result { fn custom_gate_analysis( custom_gate_name: &str, stmt: &Statement, errors: &mut ReportCollection, - warnings: &mut ReportCollection + warnings: &mut ReportCollection, ) { use Statement::*; match stmt { @@ -34,32 +34,30 @@ pub fn custom_gate_analysis( Signal(SignalType::Intermediate, _) => { let mut warning = Report::warning( String::from("Intermediate signal inside custom template"), - ReportCode::CustomGateIntermediateSignalWarning + ReportCode::CustomGateIntermediateSignalWarning, ); warning.add_primary( meta.location.clone(), meta.file_id.unwrap(), format!( "Intermediate signal {} declared in custom template {}", - name, - custom_gate_name - ) + name, custom_gate_name + ), ); warnings.push(warning); } Component | AnonymousComponent => { let mut error = Report::error( String::from("Component inside custom template"), - ReportCode::CustomGateSubComponentError + ReportCode::CustomGateSubComponentError, ); error.add_primary( meta.location.clone(), meta.file_id.unwrap(), format!( "Component {} declared in custom template {}", - name, - custom_gate_name - ) + name, custom_gate_name + ), ); errors.push(error); } @@ -72,12 +70,12 @@ pub fn custom_gate_analysis( AssignConstraintSignal => { let mut error = Report::error( String::from("Added constraint inside custom template"), - ReportCode::CustomGateConstraintError + ReportCode::CustomGateConstraintError, ); error.add_primary( meta.location.clone(), meta.file_id.unwrap(), - String::from("Added constraint") + String::from("Added constraint"), ); errors.push(error); } @@ -87,12 +85,12 @@ pub fn custom_gate_analysis( ConstraintEquality { meta, .. } => { let mut error = Report::error( String::from("Added constraint inside custom template"), - ReportCode::CustomGateConstraintError + ReportCode::CustomGateConstraintError, ); error.add_primary( meta.location.clone(), meta.file_id.unwrap(), - String::from("Added constraint") + String::from("Added constraint"), ); errors.push(error); } @@ -107,12 +105,12 @@ pub fn custom_gate_analysis( AssignConstraintSignal => { let mut error = Report::error( String::from("Added constraint inside custom template"), - ReportCode::CustomGateConstraintError + ReportCode::CustomGateConstraintError, ); error.add_primary( meta.location.clone(), meta.file_id.unwrap(), - String::from("Added constraint") + String::from("Added constraint"), ); errors.push(error); } diff --git a/type_analysis/src/analyzers/functions_free_of_template_elements.rs b/type_analysis/src/analyzers/functions_free_of_template_elements.rs index b5330864c..e87883dd8 100644 --- a/type_analysis/src/analyzers/functions_free_of_template_elements.rs +++ b/type_analysis/src/analyzers/functions_free_of_template_elements.rs @@ -127,7 +127,7 @@ fn analyse_statement( reports.push(report); } analyse_expression(rhe, function_names, reports); - }, + } } } @@ -169,7 +169,7 @@ fn analyse_expression( PrefixOp { rhe, .. } => { analyse_expression(rhe, function_names, reports); } - ParallelOp{ rhe, ..} =>{ + ParallelOp { rhe, .. } => { analyse_expression(rhe, function_names, reports); } InlineSwitchOp { cond, if_true, if_false, .. } => { @@ -199,12 +199,12 @@ fn analyse_expression( analyse_expression(value, function_names, reports); } } - UniformArray {value, dimension, .. } => { + UniformArray { value, dimension, .. } => { analyse_expression(value, function_names, reports); analyse_expression(dimension, function_names, reports); - - } - _ => {unreachable!("Anonymous calls should not be reachable at this point."); } + _ => { + unreachable!("Anonymous calls should not be reachable at this point."); + } } } diff --git a/type_analysis/src/analyzers/signal_declaration_analysis.rs b/type_analysis/src/analyzers/signal_declaration_analysis.rs index aa63f7a60..96e9443c5 100644 --- a/type_analysis/src/analyzers/signal_declaration_analysis.rs +++ b/type_analysis/src/analyzers/signal_declaration_analysis.rs @@ -41,7 +41,7 @@ fn treat_statement( } } InitializationBlock { meta, xtype, .. } => match xtype { - VariableType::Signal(_, _) | VariableType::Component => { + VariableType::Signal(_, _) | VariableType::Component => { if !signal_declaration_allowed { let mut report = Report::error( "Signal or component declaration inside While scope. Signal and component can only be defined in the initial scope or in If scopes with known condition".to_string(), diff --git a/type_analysis/src/analyzers/symbol_analysis.rs b/type_analysis/src/analyzers/symbol_analysis.rs index 1d92ce25e..007a8ed00 100644 --- a/type_analysis/src/analyzers/symbol_analysis.rs +++ b/type_analysis/src/analyzers/symbol_analysis.rs @@ -91,7 +91,11 @@ fn analyze_main(program: &ProgramArchive) -> Result<(), Vec> { &environment, ); - if reports.is_empty() { Ok(()) } else { Err(reports) } + if reports.is_empty() { + Ok(()) + } else { + Err(reports) + } } pub fn analyze_symbols( @@ -227,7 +231,14 @@ fn analyze_statement( Statement::LogCall { args, .. } => { for logarg in args { if let LogArgument::LogExp(arg) = logarg { - analyze_expression(arg, file_id, function_info, template_info, reports, environment); + analyze_expression( + arg, + file_id, + function_info, + template_info, + reports, + environment, + ); } } } @@ -396,15 +407,8 @@ fn analyze_expression( ); } } - Expression::UniformArray{ value, dimension, .. } => { - analyze_expression( - value, - file_id, - function_info, - template_info, - reports, - environment, - ); + Expression::UniformArray { value, dimension, .. } => { + analyze_expression(value, file_id, function_info, template_info, reports, environment); analyze_expression( dimension, file_id, @@ -413,7 +417,7 @@ fn analyze_expression( reports, environment, ); - }, + } _ => {} } } diff --git a/type_analysis/src/analyzers/type_check.rs b/type_analysis/src/analyzers/type_check.rs index 0d3b8901f..3bacb0c52 100644 --- a/type_analysis/src/analyzers/type_check.rs +++ b/type_analysis/src/analyzers/type_check.rs @@ -11,7 +11,11 @@ use std::collections::HashSet; type ArithmeticType = usize; type ComponentInfo = (Option, ArithmeticType); -type TypingEnvironment = CircomEnvironment), ArithmeticType>; +type TypingEnvironment = CircomEnvironment< + ComponentInfo, + (ArithmeticType, std::vec::Vec), + ArithmeticType, +>; type CallRegister = TypeRegister; struct AnalysisInformation { @@ -88,14 +92,13 @@ pub fn type_check(program_archive: &ProgramArchive) -> Result Result bool { - if let Call { id, .. } = initial_expression{ + if let Call { id, .. } = initial_expression { let inputs = program_archive.get_template_data(id).get_inputs(); let mut tag_in_inputs = false; for input in inputs { - if !input.1.1.is_empty(){ + if !input.1 .1.is_empty() { tag_in_inputs = true; break; } } tag_in_inputs + } else { + unreachable!() } - else { unreachable!()} } fn type_statement( @@ -139,8 +143,7 @@ fn type_statement( dim_expression.get_meta(), &mut analysis_information.reports, ); - } - else if dim_type.dim() > 0 { + } else if dim_type.dim() > 0 { add_report( ReportCode::InvalidArraySize(dim_type.dim()), dim_expression.get_meta(), @@ -151,11 +154,17 @@ fn type_statement( match xtype { VariableType::Signal(s_type, tags) => { if let SignalType::Input = s_type { - analysis_information.environment.add_input(name, (dimensions.len(),tags.clone())); + analysis_information + .environment + .add_input(name, (dimensions.len(), tags.clone())); } else if let SignalType::Output = s_type { - analysis_information.environment.add_output(name, (dimensions.len(),tags.clone())); + analysis_information + .environment + .add_output(name, (dimensions.len(), tags.clone())); } else { - analysis_information.environment.add_intermediate(name, (dimensions.len(),tags.clone())); + analysis_information + .environment + .add_intermediate(name, (dimensions.len(), tags.clone())); } } VariableType::Var => { @@ -186,7 +195,8 @@ fn type_statement( return; }; - if analysis_information.environment.has_component(var) && access_information.2.is_some(){ + if analysis_information.environment.has_component(var) && access_information.2.is_some() + { return add_report( ReportCode::OutputTagCannotBeModifiedOutside, meta, @@ -213,8 +223,8 @@ fn type_statement( | (SymbolInformation::Signal(_), AssignOp::AssignSignal) | (SymbolInformation::Var(_), AssignOp::AssignVar) | (SymbolInformation::Component(_), AssignOp::AssignVar) => {} - | (SymbolInformation::Tag, AssignOp::AssignVar) => {} - (SymbolInformation::Signal(_), AssignOp::AssignVar)=>{ + (SymbolInformation::Tag, AssignOp::AssignVar) => {} + (SymbolInformation::Signal(_), AssignOp::AssignVar) => { return add_report( ReportCode::WrongTypesInAssignOperationOperatorSignal, meta, @@ -230,14 +240,14 @@ fn type_statement( } } match symbol_information { - SymbolInformation::Component(possible_template) =>{ - if rhe_type.is_template(){ - if possible_template.is_none(){ + SymbolInformation::Component(possible_template) => { + if rhe_type.is_template() { + if possible_template.is_none() { let (current_template, _) = analysis_information .environment .get_mut_component_or_break(var, file!(), line!()); *current_template = rhe_type.template; - } else{ + } else { let template = possible_template.unwrap(); let r_template = rhe_type.template.unwrap(); if template != r_template { @@ -248,7 +258,7 @@ fn type_statement( ) } } - } else{ + } else { add_report( ReportCode::WrongTypesInAssignOperationTemplate, meta, @@ -256,53 +266,50 @@ fn type_statement( ) } } - SymbolInformation::Signal(dim) =>{ - if rhe_type.is_template(){ + SymbolInformation::Signal(dim) => { + if rhe_type.is_template() { add_report( ReportCode::WrongTypesInAssignOperationExpression, meta, &mut analysis_information.reports, ) - } else if dim != rhe_type.dim(){ + } else if dim != rhe_type.dim() { add_report( ReportCode::WrongTypesInAssignOperationDims(dim, rhe_type.dim()), meta, &mut analysis_information.reports, ) } - } - SymbolInformation::Var(dim) =>{ - if rhe_type.is_template(){ + SymbolInformation::Var(dim) => { + if rhe_type.is_template() { add_report( ReportCode::WrongTypesInAssignOperationExpression, meta, &mut analysis_information.reports, ) - } else if dim != rhe_type.dim(){ + } else if dim != rhe_type.dim() { add_report( - ReportCode::WrongTypesInAssignOperationDims(dim, rhe_type.dim()), + ReportCode::WrongTypesInAssignOperationDims(dim, rhe_type.dim()), meta, &mut analysis_information.reports, ) } - } - SymbolInformation::Tag =>{ - if rhe_type.is_template(){ + SymbolInformation::Tag => { + if rhe_type.is_template() { add_report( ReportCode::WrongTypesInAssignOperationExpression, meta, &mut analysis_information.reports, ) - } else if 0 != rhe_type.dim(){ + } else if 0 != rhe_type.dim() { add_report( ReportCode::WrongTypesInAssignOperationDims(0, rhe_type.dim()), meta, &mut analysis_information.reports, ) } - } } } @@ -343,14 +350,14 @@ fn type_statement( } LogCall { args, meta } => { for arglog in args { - if let LogArgument::LogExp(arg) = arglog{ + if let LogArgument::LogExp(arg) = arglog { let arg_response = type_expression(&arg, program_archive, analysis_information); let arg_type = if let Result::Ok(t) = arg_response { t } else { return; }; - if arg_type.is_template() { + if arg_type.is_template() { add_report( ReportCode::MustBeSingleArithmeticT, meta, @@ -416,13 +423,13 @@ fn type_statement( } else { return; }; - if cond_type.is_template(){ + if cond_type.is_template() { add_report( ReportCode::MustBeSingleArithmeticT, cond.get_meta(), &mut analysis_information.reports, ) - }else if cond_type.dim() > 0 { + } else if cond_type.dim() > 0 { add_report( ReportCode::MustBeSingleArithmetic(cond_type.dim()), cond.get_meta(), @@ -438,13 +445,13 @@ fn type_statement( } else { return; }; - if cond_type.is_template(){ + if cond_type.is_template() { add_report( ReportCode::MustBeSingleArithmeticT, cond.get_meta(), &mut analysis_information.reports, ) - }else if cond_type.dim() > 0 { + } else if cond_type.dim() > 0 { add_report( ReportCode::MustBeSingleArithmetic(cond_type.dim()), cond.get_meta(), @@ -460,7 +467,7 @@ fn type_statement( analysis_information.environment.remove_variable_block(); } MultSubstitution { .. } => unreachable!(), - UnderscoreSubstitution { rhe , ..} => { + UnderscoreSubstitution { rhe, .. } => { let rhe_response = type_expression(rhe, program_archive, analysis_information); let rhe_type = if let Result::Ok(r_type) = rhe_response { r_type @@ -474,7 +481,7 @@ fn type_statement( &mut analysis_information.reports, ); } - }, + } } } fn type_expression( @@ -516,11 +523,7 @@ fn type_expression( UniformArray { meta, value, dimension } => { let value_type = type_expression(value, program_archive, analysis_information)?; if value_type.is_template() { - add_report( - ReportCode::InvalidArrayType, - meta, - &mut analysis_information.reports, - ); + add_report(ReportCode::InvalidArrayType, meta, &mut analysis_information.reports); }; let dim_type = type_expression(dimension, program_archive, analysis_information)?; if dim_type.is_template() { @@ -536,7 +539,7 @@ fn type_expression( &mut analysis_information.reports, ); } - + Result::Ok(FoldedType::arithmetic_type(value_type.dim() + 1)) } InfixOp { lhe, rhe, .. } => { @@ -574,9 +577,9 @@ fn type_expression( Result::Ok(FoldedType::arithmetic_type(0)) } } - ParallelOp {rhe, .. } =>{ + ParallelOp { rhe, .. } => { let rhe_type = type_expression(rhe, program_archive, analysis_information)?; - if rhe_type.is_template() { + if rhe_type.is_template() { Result::Ok(rhe_type) } else { add_report_and_end( @@ -598,14 +601,13 @@ fn type_expression( } else { return Result::Ok(if_true_type); }; - if cond_type.is_template(){ + if cond_type.is_template() { add_report( ReportCode::MustBeSingleArithmeticT, cond.get_meta(), &mut analysis_information.reports, ) - } - else if cond_type.dim() > 0 { + } else if cond_type.dim() > 0 { add_report( ReportCode::MustBeSingleArithmetic(cond_type.dim()), cond.get_meta(), @@ -630,7 +632,7 @@ fn type_expression( Variable { name, access, meta, .. } => { debug_assert!(analysis_information.environment.has_symbol(name)); let access_information = - treat_access( access, meta, program_archive, analysis_information)?; + treat_access(access, meta, program_archive, analysis_information)?; let environment = &analysis_information.environment; let reports = &mut analysis_information.reports; let symbol_information = apply_access_to_symbol( @@ -648,9 +650,7 @@ fn type_expression( SymbolInformation::Var(dim) | SymbolInformation::Signal(dim) => { Result::Ok(FoldedType::arithmetic_type(dim)) } - SymbolInformation::Tag => { - Result::Ok(FoldedType::arithmetic_type(0)) - } + SymbolInformation::Tag => Result::Ok(FoldedType::arithmetic_type(0)), SymbolInformation::Component(possible_template) if possible_template.is_none() => { add_report_and_end(ReportCode::UninitializedSymbolInExpression, meta, reports) } @@ -713,7 +713,9 @@ fn type_expression( let folded_value = returned_type?; Result::Ok(folded_value) } - _ => {unreachable!("Anonymous calls should not be reachable at this point."); } + _ => { + unreachable!("Anonymous calls should not be reachable at this point."); + } } } //************************************************* Statement support ************************************************* @@ -744,14 +746,14 @@ fn treat_access( match access { ArrayAccess(index) => { let index_response = type_expression(&index, program_archive, analysis_information); - - if access_info.2.is_some(){ + + if access_info.2.is_some() { add_report( ReportCode::InvalidArrayAccess(0, 1), index.get_meta(), &mut analysis_information.reports, ); - } else{ + } else { if let Option::Some(signal_info) = &mut access_info.1 { signal_info.1 += 1; } else { @@ -764,8 +766,7 @@ fn treat_access( index.get_meta(), &mut analysis_information.reports, ); - } - else if index_type.dim() > 0 { + } else if index_type.dim() > 0 { add_report( ReportCode::InvalidArraySize(index_type.dim()), index.get_meta(), @@ -776,10 +777,10 @@ fn treat_access( } } ComponentAccess(name) => { - if let Option::Some(_signal_info) = & access_info.1 { - if access_info.2.is_none(){ + if let Option::Some(_signal_info) = &access_info.1 { + if access_info.2.is_none() { access_info.2 = Some(name.clone()) - } else{ + } else { add_report( ReportCode::InvalidSignalTagAccess, meta, @@ -795,7 +796,6 @@ fn treat_access( Result::Ok(access_info) } - enum SymbolInformation { Component(Option), Var(ArithmeticType), @@ -812,32 +812,40 @@ fn apply_access_to_symbol( ) -> Result { let (current_template, mut current_dim, possible_tags) = if environment.has_component(symbol) { let (temp, dim) = environment.get_component_or_break(symbol, file!(), line!()).clone(); - (temp,dim, Vec::new()) + (temp, dim, Vec::new()) } else if environment.has_signal(symbol) { - let(dim, tags) = environment.get_signal_or_break(symbol, file!(), line!()); - (Option::None, *dim, tags.clone()) + let (dim, tags) = environment.get_signal_or_break(symbol, file!(), line!()); + (Option::None, *dim, tags.clone()) } else { let dim = environment.get_variable_or_break(symbol, file!(), line!()); (Option::None, *dim, Vec::new()) }; if access_information.0 > current_dim { - return add_report_and_end(ReportCode::InvalidArrayAccess(current_dim, access_information.0), meta, reports); + return add_report_and_end( + ReportCode::InvalidArrayAccess(current_dim, access_information.0), + meta, + reports, + ); } else { current_dim -= access_information.0 } - // Case signals or tags - if let Option::Some((signal_name, dims_accessed)) = access_information.1{ - if current_template.is_some(){ // we are inside component - - if current_dim != 0{ // only allowed complete accesses to component + // Case signals or tags + if let Option::Some((signal_name, dims_accessed)) = access_information.1 { + if current_template.is_some() { + // we are inside component + + if current_dim != 0 { + // only allowed complete accesses to component return add_report_and_end(ReportCode::InvalidPartialArray, meta, reports); } let template_name = current_template.unwrap(); - let input = program_archive.get_template_data(&template_name).get_input_info(&signal_name); - let output = program_archive.get_template_data(&template_name).get_output_info(&signal_name); + let input = + program_archive.get_template_data(&template_name).get_input_info(&signal_name); + let output = + program_archive.get_template_data(&template_name).get_output_info(&signal_name); let tags; (current_dim, tags) = match (input, output) { (Option::Some((d, tags)), _) | (_, Option::Some((d, tags))) => (*d, tags), @@ -845,41 +853,50 @@ fn apply_access_to_symbol( return add_report_and_end(ReportCode::InvalidSignalAccess, meta, reports); } }; - if access_information.2.is_some(){ // tag of io signal of component - if dims_accessed > 0{ - return add_report_and_end(ReportCode::InvalidTagAccessAfterArray, meta, reports); - } - else if !tags.contains(&access_information.2.unwrap()){ + if access_information.2.is_some() { + // tag of io signal of component + if dims_accessed > 0 { + return add_report_and_end( + ReportCode::InvalidTagAccessAfterArray, + meta, + reports, + ); + } else if !tags.contains(&access_information.2.unwrap()) { return add_report_and_end(ReportCode::InvalidTagAccess, meta, reports); - } else{ + } else { return Result::Ok(SymbolInformation::Tag); } - } else{ // io signal of component + } else { + // io signal of component if dims_accessed > current_dim { - return add_report_and_end(ReportCode::InvalidArrayAccess(current_dim, dims_accessed), meta, reports); + return add_report_and_end( + ReportCode::InvalidArrayAccess(current_dim, dims_accessed), + meta, + reports, + ); } else { return Result::Ok(SymbolInformation::Signal(current_dim - dims_accessed)); - } + } } - } else{ // we are in template - if environment.has_signal(symbol){ - if access_information.0 != 0{ + } else { + // we are in template + if environment.has_signal(symbol) { + if access_information.0 != 0 { add_report_and_end(ReportCode::InvalidTagAccessAfterArray, meta, reports) - } else if dims_accessed > 0{ + } else if dims_accessed > 0 { add_report_and_end( ReportCode::InvalidArrayAccess(0, dims_accessed), meta, reports, ) - } else if !possible_tags.contains(&signal_name){ + } else if !possible_tags.contains(&signal_name) { add_report_and_end(ReportCode::InvalidTagAccess, meta, reports) - } else{ + } else { Result::Ok(SymbolInformation::Tag) } - - } else if environment.has_component(symbol){ + } else if environment.has_component(symbol) { add_report_and_end(ReportCode::UninitializedComponent, meta, reports) - } else{ + } else { add_report_and_end(ReportCode::InvalidSignalTagAccess, meta, reports) } } @@ -894,7 +911,6 @@ fn apply_access_to_symbol( } } - fn type_array_of_expressions( expressions: &[Expression], program_archive: &ProgramArchive, @@ -1006,8 +1022,7 @@ fn add_report(error_code: ReportCode, meta: &Meta, reports: &mut ReportCollectio //TypeCantBeUseAsCondition => "This type can not be used as a condition".to_string(), //BadArrayAccess => "This type can not be used as index".to_string(), EmptyArrayInlineDeclaration => "Empty arrays can not be declared inline".to_string(), - NonHomogeneousArray(dim_1, dim_2) => - format!("All the elements in a array must have the same type.\n Found elements in the array with {} and {} dimensions.", + NonHomogeneousArray(dim_1, dim_2) => format!("All the elements in a array must have the same type.\n Found elements in the array with {} and {} dimensions.", dim_1, dim_2), InvalidArraySize(dim) => { format!("Array indexes and lengths must be single arithmetic expressions.\n Found expression with {} dimensions.", diff --git a/type_analysis/src/analyzers/type_given_function.rs b/type_analysis/src/analyzers/type_given_function.rs index 427d11bcd..294fd8a85 100644 --- a/type_analysis/src/analyzers/type_given_function.rs +++ b/type_analysis/src/analyzers/type_given_function.rs @@ -290,13 +290,11 @@ fn look_for_type_in_expression( function_info, value, ); - if value_type.is_some(){ + if value_type.is_some() { Option::Some(value_type.unwrap() + 1) - } - else{ + } else { None } - } Expression::Call { id, args, .. } => { if explored_functions.contains(id) { @@ -317,6 +315,8 @@ fn look_for_type_in_expression( let has_type = start(id, explored_functions, function_info, ¶ms_types); has_type } - _ => {unreachable!("Anonymous calls should not be reachable at this point."); } + _ => { + unreachable!("Anonymous calls should not be reachable at this point."); + } } } diff --git a/type_analysis/src/analyzers/unknown_known_analysis.rs b/type_analysis/src/analyzers/unknown_known_analysis.rs index 5cb5541f2..f971a68af 100644 --- a/type_analysis/src/analyzers/unknown_known_analysis.rs +++ b/type_analysis/src/analyzers/unknown_known_analysis.rs @@ -77,7 +77,14 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma } environment = exit.environment; } - (constraints_declared, tags_modified, signals_declared, reports, environment, modified_variables) + ( + constraints_declared, + tags_modified, + signals_declared, + reports, + environment, + modified_variables, + ) } let file_id = entry_information.file_id; let mut reports = ReportCollection::new(); @@ -103,19 +110,18 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma } if let VariableType::AnonymousComponent = xtype { // in this case the dimension is ukn - } else{ + } else { for dimension in dimensions { if tag(dimension, &environment) == Unknown { add_report( - ReportCode::UnknownDimension, - dimension.get_meta(), - file_id, - &mut reports, - ); - } + ReportCode::UnknownDimension, + dimension.get_meta(), + file_id, + &mut reports, + ); + } } } - } Substitution { meta, var, access, op, rhe, .. } => { let simplified_elem = simplify_symbol(&environment, var, access); @@ -148,7 +154,7 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma } if access_tag == Unknown { add_report(ReportCode::UnknownTemplate, meta, file_id, &mut reports); - } + } } else if *op == AssignOp::AssignConstraintSignal { constraints_declared = true; if is_non_quadratic(rhe, &environment) { @@ -159,7 +165,7 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma } } } - UnderscoreSubstitution { op, rhe, .. } => { + UnderscoreSubstitution { op, rhe, .. } => { let _expression_tag = tag(rhe, &environment); if *op == AssignOp::AssignConstraintSignal { constraints_declared = true; @@ -167,7 +173,7 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma add_report(ReportCode::NonQuadratic, rhe.get_meta(), file_id, &mut reports); } } - }, + } ConstraintEquality { lhe, rhe, .. } => { constraints_declared = true; if is_non_quadratic(lhe, &environment) { @@ -180,7 +186,7 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma IfThenElse { cond, if_case, else_case, .. } => { let tag_cond = tag(cond, &environment); let new_entry_else_case = - EntryInformation { environment: environment.clone(), file_id}; + EntryInformation { environment: environment.clone(), file_id }; let new_entry_if_case = EntryInformation { environment, file_id }; let if_case_info = analyze(if_case, new_entry_if_case); let else_case_info = if let Option::Some(else_stmt) = else_case { @@ -190,8 +196,8 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma constraints_declared: false, environment: new_entry_else_case.environment, reports: ReportCollection::with_capacity(0), - modified_variables : HashSet::new(), - tags_modified : false, + modified_variables: HashSet::new(), + tags_modified: false, signals_declared: false, } }; @@ -211,14 +217,13 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma Environment::merge(if_case_info.environment, else_case_info.environment, |a, b| { max(a, b) }); - if tag_cond == Unknown{ - for var in &modified_variables{ - if environment.has_variable(var){ + if tag_cond == Unknown { + for var in &modified_variables { + if environment.has_variable(var) { let value = environment.get_mut_variable_or_break(var, file!(), line!()); *value = Unknown; } } - } if tag_cond == Unknown && constraints_declared { add_report( @@ -229,35 +234,27 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma ); } if tag_cond == Unknown && tags_modified { - add_report( - ReportCode::UnreachableTags, - cond.get_meta(), - file_id, - &mut reports, - ); + add_report(ReportCode::UnreachableTags, cond.get_meta(), file_id, &mut reports); } if tag_cond == Unknown && signals_declared { - add_report( - ReportCode::UnreachableSignals, - cond.get_meta(), - file_id, - &mut reports, - ); + add_report(ReportCode::UnreachableSignals, cond.get_meta(), file_id, &mut reports); } } While { cond, stmt, .. } => { let mut entry_info = environment.clone(); - let mut entry = EntryInformation { file_id, environment}; + let mut entry = EntryInformation { file_id, environment }; let mut exit = analyze(stmt, entry); - let mut modified = check_modified(entry_info, &mut exit.environment, &exit.modified_variables); + let mut modified = + check_modified(entry_info, &mut exit.environment, &exit.modified_variables); environment = exit.environment; - while modified{ + while modified { entry_info = environment.clone(); - entry = EntryInformation { file_id, environment}; + entry = EntryInformation { file_id, environment }; exit = analyze(stmt, entry); - modified = check_modified(entry_info, &mut exit.environment, &exit.modified_variables); + modified = + check_modified(entry_info, &mut exit.environment, &exit.modified_variables); environment = exit.environment; - }; + } constraints_declared = exit.constraints_declared; tags_modified = exit.tags_modified; @@ -267,13 +264,13 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma } let tag_out = tag(cond, &environment); - if tag_out == Unknown{ - for var in &exit.modified_variables{ - if environment.has_variable(var){ + if tag_out == Unknown { + for var in &exit.modified_variables { + if environment.has_variable(var) { let value = environment.get_mut_variable_or_break(var, file!(), line!()); *value = Unknown; } - } + } } if constraints_declared && tag_out == Unknown { @@ -285,25 +282,16 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma ); } if tag_out == Unknown && tags_modified { - add_report( - ReportCode::UnreachableTags, - cond.get_meta(), - file_id, - &mut reports, - ); + add_report(ReportCode::UnreachableTags, cond.get_meta(), file_id, &mut reports); } if tag_out == Unknown && signals_declared { - add_report( - ReportCode::UnreachableSignals, - cond.get_meta(), - file_id, - &mut reports, - ); + add_report(ReportCode::UnreachableSignals, cond.get_meta(), file_id, &mut reports); } } Block { stmts, .. } => { environment.add_variable_block(); - let (nc, tags, ns, nr, ne, nm) = iterate_statements(stmts, reports, environment, file_id); + let (nc, tags, ns, nr, ne, nm) = + iterate_statements(stmts, reports, environment, file_id); constraints_declared = nc; reports = nr; environment = ne; @@ -313,7 +301,8 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma signals_declared = ns; } InitializationBlock { initializations, .. } => { - let (nc, tags, ns, nr, ne, nm) = iterate_statements(initializations, reports, environment, file_id); + let (nc, tags, ns, nr, ne, nm) = + iterate_statements(initializations, reports, environment, file_id); constraints_declared = nc; reports = nr; environment = ne; @@ -323,8 +312,13 @@ fn analyze(stmt: &Statement, entry_information: EntryInformation) -> ExitInforma } _ => {} } - ExitInformation { - reports, environment, constraints_declared, modified_variables, tags_modified, signals_declared + ExitInformation { + reports, + environment, + constraints_declared, + modified_variables, + tags_modified, + signals_declared, } } @@ -341,8 +335,8 @@ fn tag(expression: &Expression, environment: &Environment) -> Tag { } else { if environment.has_intermediate(name) && !all_array_are_accesses(access) { Known /* In this case, it is a tag. */ - } else{ - *environment.get_intermediate_or_break(name, file!(), line!()) + } else { + *environment.get_intermediate_or_break(name, file!(), line!()) } }; let mut index = 0; @@ -382,7 +376,9 @@ fn tag(expression: &Expression, environment: &Environment) -> Tag { } PrefixOp { rhe, .. } => tag(rhe, environment), ParallelOp { rhe, .. } => tag(rhe, environment), - _ => {unreachable!("Anonymous calls should not be reachable at this point."); } + _ => { + unreachable!("Anonymous calls should not be reachable at this point."); + } } } // ***************************** Compare two variable states ******************** @@ -391,14 +387,15 @@ fn check_modified( initial_state: Environment, final_state: &mut Environment, modified_variables: &HashSet, -) -> bool{ +) -> bool { let mut modified = false; - for v in modified_variables{ - if initial_state.has_variable(v) && final_state.has_variable(v){ + for v in modified_variables { + if initial_state.has_variable(v) && final_state.has_variable(v) { let t_ini = initial_state.get_variable_or_break(v, file!(), line!()); let t_fin = final_state.get_mut_variable_or_break(v, file!(), line!()); - if *t_ini != *t_fin{ - if *t_fin == Tag::Unknown{ // in other case we can enter in loops + if *t_ini != *t_fin { + if *t_fin == Tag::Unknown { + // in other case we can enter in loops modified = true; } *t_fin = max(*t_ini, *t_fin); @@ -410,7 +407,7 @@ fn check_modified( fn all_array_are_accesses(accesses: &[Access]) -> bool { let mut i = 0; - let mut all_array_accesses = true; + let mut all_array_accesses = true; while i < accesses.len() && all_array_accesses { let aux = accesses.get(i).unwrap(); if let Access::ComponentAccess(_) = aux { @@ -447,7 +444,7 @@ enum Symbol { Signal, Component, Variable, - SignalTag + SignalTag, } fn simplify_symbol(environment: &Environment, name: &str, access: &[Access]) -> Symbol { use Symbol::*; @@ -509,8 +506,10 @@ fn unknown_index(exp: &Expression, environment: &Environment) -> bool { } (false, bucket) } - UniformArray{ value, dimension, .. } => (false, vec![value.as_ref(), dimension.as_ref()]), - _ => {unreachable!("Anonymous calls should not be reachable at this point."); } + UniformArray { value, dimension, .. } => (false, vec![value.as_ref(), dimension.as_ref()]), + _ => { + unreachable!("Anonymous calls should not be reachable at this point."); + } }; let mut has_unknown_index = init; let mut index = 0; diff --git a/type_analysis/src/check_types.rs b/type_analysis/src/check_types.rs index 5cc3c5682..c2bb43a81 100644 --- a/type_analysis/src/check_types.rs +++ b/type_analysis/src/check_types.rs @@ -129,14 +129,15 @@ fn semantic_analyses( ) { for template_name in program_archive.get_template_names().iter() { if let Result::Err(mut unknown_known_report) = - unknown_known_analysis(template_name, program_archive) { - errors.append(&mut unknown_known_report); - } + unknown_known_analysis(template_name, program_archive) + { + errors.append(&mut unknown_known_report); + } if program_archive.get_template_data(template_name).is_custom_gate() { let body = program_archive.get_template_data(template_name).get_body(); match custom_gate_analysis(template_name, body) { Result::Ok(mut custom_gate_report) => warnings.append(&mut custom_gate_report), - Result::Err(mut custom_gate_report) => errors.append(&mut custom_gate_report) + Result::Err(mut custom_gate_report) => errors.append(&mut custom_gate_report), } } } diff --git a/type_analysis/src/decorators/component_type_inference.rs b/type_analysis/src/decorators/component_type_inference.rs index 253d0ef00..0ed4034e9 100644 --- a/type_analysis/src/decorators/component_type_inference.rs +++ b/type_analysis/src/decorators/component_type_inference.rs @@ -47,7 +47,8 @@ fn infer_component_types(stmt: &Statement, templates: &TemplateInfo, data: &mut } } Declaration { xtype, name, .. } - if VariableType::Component == *xtype || VariableType::AnonymousComponent == *xtype =>{ + if VariableType::Component == *xtype || VariableType::AnonymousComponent == *xtype => + { data.components.insert(name.clone()); } Substitution { var, rhe, .. } if data.components.contains(var) => { @@ -70,9 +71,7 @@ fn into_template_inference(expr: &Expression, templates: &TemplateInfo) -> Optio ret } Call { id, .. } if templates.contains_key(id) => Some(id.clone()), - ParallelOp {rhe, ..} =>{ - into_template_inference(rhe, templates) - }, + ParallelOp { rhe, .. } => into_template_inference(rhe, templates), _ => None, } } @@ -99,9 +98,10 @@ fn apply_inference(stmt: &mut Statement, env: &mut Environment) { apply_inference(s, env); } } - Declaration { xtype, name, meta, .. } - if VariableType::Component == *xtype || VariableType::AnonymousComponent == *xtype => { - meta.component_inference = env.remove(name); + Declaration { xtype, name, meta, .. } + if VariableType::Component == *xtype || VariableType::AnonymousComponent == *xtype => + { + meta.component_inference = env.remove(name); } _ => {} } diff --git a/type_analysis/src/decorators/constants_handler.rs b/type_analysis/src/decorators/constants_handler.rs index bbffe78d7..c9a9eb00e 100644 --- a/type_analysis/src/decorators/constants_handler.rs +++ b/type_analysis/src/decorators/constants_handler.rs @@ -224,7 +224,9 @@ fn has_constant_value(expr: &Expression, environment: &Constants) -> bool { Variable { name, .. } => variable(name, environment), ArrayInLine { .. } => array_inline(), UniformArray { .. } => uniform_array(), - _ => {unreachable!("Anonymous calls should not be reachable at this point."); } + _ => { + unreachable!("Anonymous calls should not be reachable at this point."); + } } } @@ -363,10 +365,7 @@ fn expand_substitution( } } -fn expand_underscore_substitution( - rhe: &mut Expression, - environment: &ExpressionHolder, -) { +fn expand_underscore_substitution(rhe: &mut Expression, environment: &ExpressionHolder) { *rhe = expand_expression(rhe.clone(), environment); } @@ -404,7 +403,9 @@ fn expand_expression(expr: Expression, environment: &ExpressionHolder) -> Expres match expr { Number(meta, value) => expand_number(meta, value), ArrayInLine { meta, values } => expand_array(meta, values, environment), - UniformArray { meta, value, dimension} => expand_uniform_array(meta, *value, *dimension, environment), + UniformArray { meta, value, dimension } => { + expand_uniform_array(meta, *value, *dimension, environment) + } Call { id, meta, args } => expand_call(id, meta, args, environment), InfixOp { meta, lhe, rhe, infix_op } => { expand_infix(meta, *lhe, infix_op, *rhe, environment) @@ -415,7 +416,9 @@ fn expand_expression(expr: Expression, environment: &ExpressionHolder) -> Expres expand_inline_switch_op(meta, *cond, *if_true, *if_false, environment) } Variable { meta, name, access } => expand_variable(meta, name, access, environment), - _ => {unreachable!("Anonymous calls should not be reachable at this point."); } + _ => { + unreachable!("Anonymous calls should not be reachable at this point."); + } } } @@ -483,11 +486,7 @@ fn expand_prefix( build_prefix(meta, prefix_op, rhe) } -fn expand_parallel( - meta: Meta, - old_rhe: Expression, - environment: &ExpressionHolder, -) -> Expression { +fn expand_parallel(meta: Meta, old_rhe: Expression, environment: &ExpressionHolder) -> Expression { let rhe = expand_expression(old_rhe, environment); build_parallel_op(meta, rhe) } diff --git a/type_analysis/src/decorators/type_reduction.rs b/type_analysis/src/decorators/type_reduction.rs index 3e42a1027..f23edcfd6 100644 --- a/type_analysis/src/decorators/type_reduction.rs +++ b/type_analysis/src/decorators/type_reduction.rs @@ -39,10 +39,7 @@ fn reduce_types_in_statement(stmt: &mut Statement, environment: &mut Environment IfThenElse { cond, if_case, else_case, .. } => { reduce_types_in_conditional(cond, if_case, else_case, environment) } - LogCall { args, .. } => { - reduce_types_in_log_call(args, environment) - - }, + LogCall { args, .. } => reduce_types_in_log_call(args, environment), Assert { arg, .. } => reduce_types_in_expression(arg, environment), Return { value, .. } => reduce_types_in_expression(value, environment), ConstraintEquality { lhe, rhe, .. } => { @@ -51,11 +48,11 @@ fn reduce_types_in_statement(stmt: &mut Statement, environment: &mut Environment MultSubstitution { .. } => unreachable!(), UnderscoreSubstitution { rhe, .. } => { reduce_types_in_expression(rhe, environment); - }, + } } } -fn reduce_types_in_log_call(args: &mut Vec, environment: &Environment){ +fn reduce_types_in_log_call(args: &mut Vec, environment: &Environment) { for arg in args { if let LogArgument::LogExp(exp) = arg { reduce_types_in_expression(exp, environment); @@ -82,7 +79,9 @@ fn reduce_types_in_expression(expression: &mut Expression, environment: &Environ reduce_types_in_expression(dimension, environment); } Number(..) => {} - _ => {unreachable!("Anonymous calls should not be reachable at this point."); } + _ => { + unreachable!("Anonymous calls should not be reachable at this point."); + } } } @@ -170,7 +169,7 @@ fn reduce_types_in_variable( for acc in access { if let ArrayAccess(exp) = acc { reduce_types_in_expression(exp, environment) - } else if reduction == Signal{ + } else if reduction == Signal { reduction = Tag; } else { reduction = Signal;