refactor global consts should no longer allow shadowing

This commit is contained in:
gluaxspeed 2021-08-27 11:42:20 -07:00
parent fed3b1e16a
commit 3b26e61050
6 changed files with 61 additions and 28 deletions

View File

@ -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::<Vec<String>>()
.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);
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();

View File

@ -128,7 +128,7 @@ where
aliases: IndexMap<Identifier, Alias>,
circuits: IndexMap<Identifier, Circuit>,
functions: IndexMap<Identifier, Function>,
global_consts: IndexMap<String, DefinitionStatement>,
global_consts: IndexMap<Vec<Identifier>, DefinitionStatement>,
) -> Result<Program> {
if !empty_imports.is_empty() {
return Err(AstError::injected_programs(empty_imports.len()).into());

View File

@ -33,7 +33,7 @@ pub struct Program {
pub imports: IndexMap<Vec<String>, Program>,
pub aliases: IndexMap<Identifier, Alias>,
pub circuits: IndexMap<Identifier, Circuit>,
pub global_consts: IndexMap<String, DefinitionStatement>,
pub global_consts: IndexMap<Vec<Identifier>, DefinitionStatement>,
pub functions: IndexMap<Identifier, Function>,
}

View File

@ -387,7 +387,7 @@ pub trait ReconstructingReducer {
aliases: IndexMap<Identifier, Alias>,
circuits: IndexMap<Identifier, Circuit>,
functions: IndexMap<Identifier, Function>,
global_consts: IndexMap<String, DefinitionStatement>,
global_consts: IndexMap<Vec<Identifier>, DefinitionStatement>,
) -> Result<Program> {
Ok(Program {
name: program.name.clone(),

View File

@ -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 {

View File

@ -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<Identifier>, DefinitionStatement)> {
let statement = self.parse_definition_statement()?;
let variable_names = statement
.variable_names
.iter()
.map(|variable_name| variable_name.identifier.name.to_string())
.collect::<Vec<String>>()
.join(",");
.map(|variable_name| variable_name.identifier.clone())
.collect::<Vec<Identifier>>();
Ok((variable_names, statement))
}