From 37290f661b0091b1667d549b99fa33ec3e21234f Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Tue, 30 Jul 2024 18:37:50 -0300 Subject: [PATCH 1/2] Substitute imported type names --- src/imports/book.rs | 115 +++++++++++++++++- .../import_system/import_type.bend | 7 ++ .../import_system/lib/MyOption.bend | 12 ++ .../import_system__import_type.bend.snap | 5 + 4 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 tests/golden_tests/import_system/import_type.bend create mode 100644 tests/golden_tests/import_system/lib/MyOption.bend create mode 100644 tests/snapshots/import_system__import_type.bend.snap diff --git a/src/imports/book.rs b/src/imports/book.rs index 767aca194..a5985c7b6 100644 --- a/src/imports/book.rs +++ b/src/imports/book.rs @@ -114,6 +114,7 @@ impl ParseBook { let main_imports = main_imports.unwrap_or(&self.import_ctx.map); let mut local_imports = BindMap::new(); + let mut adt_imports = BindMap::new(); // Collect local imports binds, starting with `__` if not imported by the main book. 'outer: for (bind, src) in self.import_ctx.map.binds.iter().rev() { @@ -128,7 +129,6 @@ impl ParseBook { // Checks if the bind is an loaded ADT name, // If so, add the constructors binds as `bind/ctr` instead. - // As ADTs names are not used in the syntax, we don't bind their names. for pkg in self.import_ctx.sources() { if let Some(book) = pkgs.loaded_adts.get(pkg) { if let Some(ctrs) = book.get(&nam) { @@ -138,6 +138,8 @@ impl ParseBook { let bind = Name::new(format!("{}{}", bind, ctr_name)); local_imports.insert(bind, ctr.clone()); } + // Add a mapping of the ADT name + adt_imports.insert(bind.clone(), nam.clone()); continue 'outer; } } @@ -149,6 +151,7 @@ impl ParseBook { for (_, def) in self.local_defs_mut() { def.apply_binds(true, &local_imports); + def.apply_types(&adt_imports); } } @@ -306,6 +309,8 @@ trait Def { /// and if there are possible constructor names on it, rename rule patterns. fn apply_binds(&mut self, maybe_constructor: bool, binds: &BindMap); + fn apply_types(&mut self, types: &BindMap); + fn source(&self) -> &Source; fn source_mut(&mut self) -> &mut Source; fn name_mut(&mut self) -> &mut Name; @@ -332,6 +337,22 @@ impl Def for Definition { } } + fn apply_types(&mut self, types: &BindMap) { + fn apply_type(bod: &mut Term, types: &BindMap) { + if let Term::With { typ, .. } = bod { + if let Some(alias) = types.get(typ).cloned() { + *typ = alias; + } + } + for child in bod.children_mut() { + apply_type(child, types); + } + } + for rule in self.rules.iter_mut() { + apply_type(&mut rule.body, types); + } + } + fn source(&self) -> &Source { &self.source } @@ -351,6 +372,84 @@ impl Def for imp::Definition { self.body = bod.fold_uses(binds.iter().rev()); } + fn apply_types(&mut self, types: &BindMap) { + fn rename_with_types(bod: &mut Stmt, types: &BindMap) { + match bod { + Stmt::With { typ, bod, nxt } => { + if let Some(alias) = types.get(typ).cloned() { + *typ = alias + } + rename_with_types(bod, types); + if let Some(nxt) = nxt { + rename_with_types(nxt, types); + } + } + Stmt::Assign { nxt, .. } => { + if let Some(nxt) = nxt { + rename_with_types(nxt, types); + } + } + Stmt::InPlace { nxt, .. } => { + rename_with_types(nxt, types); + } + Stmt::If { then, otherwise, nxt, .. } => { + rename_with_types(then, types); + rename_with_types(otherwise, types); + if let Some(nxt) = nxt { + rename_with_types(nxt, types); + } + } + Stmt::Match { arms, nxt, .. } => { + for arm in arms { + rename_with_types(&mut arm.rgt, types); + } + if let Some(nxt) = nxt { + rename_with_types(nxt, types); + } + } + Stmt::Switch { arms, nxt, .. } => { + for arm in arms { + rename_with_types(arm, types); + } + if let Some(nxt) = nxt { + rename_with_types(nxt, types); + } + } + Stmt::Bend { step, base, nxt, .. } => { + rename_with_types(step, types); + rename_with_types(base, types); + if let Some(nxt) = nxt { + rename_with_types(nxt, types); + } + } + Stmt::Fold { arms, nxt, .. } => { + for arm in arms { + rename_with_types(&mut arm.rgt, types); + } + if let Some(nxt) = nxt { + rename_with_types(nxt, types); + } + } + Stmt::Ask { nxt, .. } => { + rename_with_types(nxt, types); + } + Stmt::Return { .. } => {} + Stmt::Open { nxt, .. } => { + rename_with_types(nxt, types); + } + Stmt::Use { nxt, .. } => { + rename_with_types(nxt, types); + } + Stmt::LocalDef { def, nxt } => { + def.apply_types(types); + rename_with_types(nxt, types); + } + Stmt::Err => {} + } + } + rename_with_types(&mut self.body, types); + } + fn source(&self) -> &Source { &self.source } @@ -368,6 +467,8 @@ impl Def for HvmDefinition { /// Do nothing, can not apply binds to a HvmDefinition. fn apply_binds(&mut self, _maybe_constructor: bool, _binds: &BindMap) {} + fn apply_types(&mut self, _types: &BindMap) {} + fn source(&self) -> &Source { &self.source } @@ -379,6 +480,18 @@ impl Def for HvmDefinition { fn name_mut(&mut self) -> &mut Name { &mut self.name } + + fn canonicalize_name(&mut self, src: &Name, main_imports: &ImportsMap, binds: &mut BindMap) { + let def_name = self.name_mut(); + let mut new_name = Name::new(std::format!("{}/{}", src, def_name)); + + if !main_imports.contains_source(&new_name) { + new_name = Name::new(std::format!("__{}", new_name)); + } + + binds.insert(def_name.clone(), new_name.clone()); + *def_name = new_name; + } } impl Term { diff --git a/tests/golden_tests/import_system/import_type.bend b/tests/golden_tests/import_system/import_type.bend new file mode 100644 index 000000000..f2908c28d --- /dev/null +++ b/tests/golden_tests/import_system/import_type.bend @@ -0,0 +1,7 @@ +from lib/MyOption import (MyOption, MyOption/bind, MyOption/wrap) + +def main(): + with MyOption: + a <- MyOption/Some(1) + b <- MyOption/Some(2) + return wrap((a, b)) diff --git a/tests/golden_tests/import_system/lib/MyOption.bend b/tests/golden_tests/import_system/lib/MyOption.bend new file mode 100644 index 000000000..c87f17000 --- /dev/null +++ b/tests/golden_tests/import_system/lib/MyOption.bend @@ -0,0 +1,12 @@ +type MyOption = (Some val) | (None) + +def MyOption/bind(val, nxt): + match val: + case MyOption/Some: + nxt = undefer(nxt) + return nxt(val.val) + case MyOption/None: + return MyOption/None + +def MyOption/wrap(val): + return MyOption/Some(val) diff --git a/tests/snapshots/import_system__import_type.bend.snap b/tests/snapshots/import_system__import_type.bend.snap new file mode 100644 index 000000000..93a3178f0 --- /dev/null +++ b/tests/snapshots/import_system__import_type.bend.snap @@ -0,0 +1,5 @@ +--- +source: tests/golden_tests.rs +input_file: tests/golden_tests/import_system/import_type.bend +--- +λa (a lib/MyOption/MyOption/Some/tag (1, 2)) From fc7db0eaf185057f0b9aae7e6343ecdda1bc97ab Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Tue, 30 Jul 2024 18:41:14 -0300 Subject: [PATCH 2/2] Rename function --- src/imports/book.rs | 50 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/imports/book.rs b/src/imports/book.rs index a5985c7b6..08296daad 100644 --- a/src/imports/book.rs +++ b/src/imports/book.rs @@ -338,18 +338,18 @@ impl Def for Definition { } fn apply_types(&mut self, types: &BindMap) { - fn apply_type(bod: &mut Term, types: &BindMap) { + fn rename_with_type(bod: &mut Term, types: &BindMap) { if let Term::With { typ, .. } = bod { if let Some(alias) = types.get(typ).cloned() { *typ = alias; } } for child in bod.children_mut() { - apply_type(child, types); + rename_with_type(child, types); } } for rule in self.rules.iter_mut() { - apply_type(&mut rule.body, types); + rename_with_type(&mut rule.body, types); } } @@ -373,81 +373,81 @@ impl Def for imp::Definition { } fn apply_types(&mut self, types: &BindMap) { - fn rename_with_types(bod: &mut Stmt, types: &BindMap) { + fn rename_with_type(bod: &mut Stmt, types: &BindMap) { match bod { Stmt::With { typ, bod, nxt } => { if let Some(alias) = types.get(typ).cloned() { *typ = alias } - rename_with_types(bod, types); + rename_with_type(bod, types); if let Some(nxt) = nxt { - rename_with_types(nxt, types); + rename_with_type(nxt, types); } } Stmt::Assign { nxt, .. } => { if let Some(nxt) = nxt { - rename_with_types(nxt, types); + rename_with_type(nxt, types); } } Stmt::InPlace { nxt, .. } => { - rename_with_types(nxt, types); + rename_with_type(nxt, types); } Stmt::If { then, otherwise, nxt, .. } => { - rename_with_types(then, types); - rename_with_types(otherwise, types); + rename_with_type(then, types); + rename_with_type(otherwise, types); if let Some(nxt) = nxt { - rename_with_types(nxt, types); + rename_with_type(nxt, types); } } Stmt::Match { arms, nxt, .. } => { for arm in arms { - rename_with_types(&mut arm.rgt, types); + rename_with_type(&mut arm.rgt, types); } if let Some(nxt) = nxt { - rename_with_types(nxt, types); + rename_with_type(nxt, types); } } Stmt::Switch { arms, nxt, .. } => { for arm in arms { - rename_with_types(arm, types); + rename_with_type(arm, types); } if let Some(nxt) = nxt { - rename_with_types(nxt, types); + rename_with_type(nxt, types); } } Stmt::Bend { step, base, nxt, .. } => { - rename_with_types(step, types); - rename_with_types(base, types); + rename_with_type(step, types); + rename_with_type(base, types); if let Some(nxt) = nxt { - rename_with_types(nxt, types); + rename_with_type(nxt, types); } } Stmt::Fold { arms, nxt, .. } => { for arm in arms { - rename_with_types(&mut arm.rgt, types); + rename_with_type(&mut arm.rgt, types); } if let Some(nxt) = nxt { - rename_with_types(nxt, types); + rename_with_type(nxt, types); } } Stmt::Ask { nxt, .. } => { - rename_with_types(nxt, types); + rename_with_type(nxt, types); } Stmt::Return { .. } => {} Stmt::Open { nxt, .. } => { - rename_with_types(nxt, types); + rename_with_type(nxt, types); } Stmt::Use { nxt, .. } => { - rename_with_types(nxt, types); + rename_with_type(nxt, types); } Stmt::LocalDef { def, nxt } => { def.apply_types(types); - rename_with_types(nxt, types); + rename_with_type(nxt, types); } Stmt::Err => {} } } - rename_with_types(&mut self.body, types); + rename_with_type(&mut self.body, types); } fn source(&self) -> &Source {