diff --git a/asg/src/program/mod.rs b/asg/src/program/mod.rs index c0e94dc561..4cf7b51a88 100644 --- a/asg/src/program/mod.rs +++ b/asg/src/program/mod.rs @@ -242,6 +242,23 @@ impl<'a> Program<'a> { scope.aliases.borrow_mut().insert(name.name.to_string(), asg_alias); } + for (names, global_const) in program.global_consts.iter() { + let gc = <&Statement<'a>>::from_ast(scope, global_const, None)?; + if let Statement::Definition(def) = gc { + let name = names + .iter() + .enumerate() + .map(|(i, name)| { + assert_eq!(name.name, def.variables.get(i).unwrap().borrow().name.name); + name.name.to_string() + }) + .collect::>() + .join(","); + + scope.global_consts.borrow_mut().insert(name, def); + } + } + for (name, circuit) in program.circuits.iter() { assert_eq!(name.name, circuit.circuit_name.name); let asg_circuit = Circuit::init(scope, circuit)?; @@ -264,19 +281,26 @@ impl<'a> Program<'a> { scope.functions.borrow_mut().insert(name.name.to_string(), function); } - for (name, global_const) in program.global_consts.iter() { - global_const - .variable_names - .iter() - .for_each(|variable_name| assert!(name.contains(&variable_name.identifier.name.to_string()))); - let gc = <&Statement<'a>>::from_ast(scope, global_const, None)?; - if let Statement::Definition(gc) = gc { - scope.global_consts.borrow_mut().insert(name.clone(), gc); - } - } - // Load concrete definitions. let mut aliases = IndexMap::new(); + let mut global_consts = IndexMap::new(); + let mut functions = IndexMap::new(); + let mut circuits = IndexMap::new(); + + /* let check_global_shadowing = |name: String, span: &Span| -> Result<()> { + if aliases.contains_key(&name) { + return Err(AsgError::duplicate_alias_definition(name, span).into()); + } else if global_consts.contains_key(&name) { + return Err(AsgError::duplicate_global_const_definition(name, span).into()); + } else if functions.contains_key(&name) { + return Err(AsgError::duplicate_function_definition(name, span).into()); + } else if circuits.contains_key(&name) { + return Err(AsgError::duplicate_circuit_definition(name, span).into()); + } else { + Ok(()) + } + }; */ + for (name, alias) in program.aliases.iter() { assert_eq!(name.name, alias.name.name); let asg_alias = *scope.aliases.borrow().get(name.name.as_ref()).unwrap(); @@ -290,18 +314,21 @@ impl<'a> Program<'a> { aliases.insert(name, asg_alias); } - let mut global_consts = IndexMap::new(); - for (name, global_const) in program.global_consts.iter() { - global_const - .variable_names - .iter() - .for_each(|variable_name| assert!(name.contains(&variable_name.identifier.name.to_string()))); - let asg_global_const = *scope.global_consts.borrow().get(name).unwrap(); + for (names, global_const) in program.global_consts.iter() { + for (identifier, variable) in names.iter().zip(global_const.variable_names.iter()) { + assert_eq!(identifier.name, variable.identifier.name); - global_consts.insert(name.clone(), asg_global_const); + let name = identifier.name.to_string(); + let asg_global_const = *scope.global_consts.borrow().get(&name).unwrap(); + + if global_consts.contains_key(&name) { + return Err(AsgError::duplicate_global_const_definition(name, &global_const.span).into()); + } + + global_consts.insert(name.clone(), asg_global_const); + } } - let mut functions = IndexMap::new(); for (name, function) in program.functions.iter() { assert_eq!(name.name, function.identifier.name); let asg_function = *scope.functions.borrow().get(name.name.as_ref()).unwrap(); @@ -317,7 +344,6 @@ impl<'a> Program<'a> { functions.insert(name, asg_function); } - let mut circuits = IndexMap::new(); for (name, circuit) in program.circuits.iter() { assert_eq!(name.name, circuit.circuit_name.name); let asg_circuit = *scope.circuits.borrow().get(name.name.as_ref()).unwrap(); diff --git a/ast-passes/src/import_resolution/importer.rs b/ast-passes/src/import_resolution/importer.rs index 003dd945f0..118a8a5c43 100644 --- a/ast-passes/src/import_resolution/importer.rs +++ b/ast-passes/src/import_resolution/importer.rs @@ -128,7 +128,7 @@ where aliases: IndexMap, circuits: IndexMap, functions: IndexMap, - global_consts: IndexMap, + global_consts: IndexMap, DefinitionStatement>, ) -> Result { if !empty_imports.is_empty() { return Err(AstError::injected_programs(empty_imports.len()).into()); diff --git a/ast/src/program.rs b/ast/src/program.rs index e666663e96..3c42d14058 100644 --- a/ast/src/program.rs +++ b/ast/src/program.rs @@ -33,7 +33,7 @@ pub struct Program { pub imports: IndexMap, Program>, pub aliases: IndexMap, pub circuits: IndexMap, - pub global_consts: IndexMap, + pub global_consts: IndexMap, DefinitionStatement>, pub functions: IndexMap, } diff --git a/ast/src/reducer/reconstructing_reducer.rs b/ast/src/reducer/reconstructing_reducer.rs index ce3df848a6..671c60ffce 100644 --- a/ast/src/reducer/reconstructing_reducer.rs +++ b/ast/src/reducer/reconstructing_reducer.rs @@ -387,7 +387,7 @@ pub trait ReconstructingReducer { aliases: IndexMap, circuits: IndexMap, functions: IndexMap, - global_consts: IndexMap, + global_consts: IndexMap, DefinitionStatement>, ) -> Result { Ok(Program { name: program.name.clone(), diff --git a/errors/src/asg/asg_errors.rs b/errors/src/asg/asg_errors.rs index e7217461d3..da31092e39 100644 --- a/errors/src/asg/asg_errors.rs +++ b/errors/src/asg/asg_errors.rs @@ -420,6 +420,14 @@ create_errors!( help: None, } + /// For when a user defines an circuit with the same name twice. + @formatted + duplicate_circuit_definition { + args: (name: impl Display), + msg: format!("a circuit named \"{}\" already exists in this scope", name), + help: None, + } + /// For when a user defines a function input with the same name twice. @formatted duplicate_function_input_definition { diff --git a/parser/src/parser/file.rs b/parser/src/parser/file.rs index c28ad28021..993c2200ed 100644 --- a/parser/src/parser/file.rs +++ b/parser/src/parser/file.rs @@ -507,14 +507,13 @@ impl ParserContext { /// Returns an [`(String, DefinitionStatement)`] AST node if the next tokens represent a global /// const definition statement and assignment. /// - pub fn parse_global_const_declaration(&mut self) -> Result<(String, DefinitionStatement)> { + pub fn parse_global_const_declaration(&mut self) -> Result<(Vec, DefinitionStatement)> { let statement = self.parse_definition_statement()?; let variable_names = statement .variable_names .iter() - .map(|variable_name| variable_name.identifier.name.to_string()) - .collect::>() - .join(","); + .map(|variable_name| variable_name.identifier.clone()) + .collect::>(); Ok((variable_names, statement)) }