@@ -4,6 +4,7 @@ use std::cell::RefCell;
44
55use crate :: metta:: * ;
66use crate :: metta:: runner:: * ;
7+ use crate :: space:: module:: ModuleSpace ;
78
89use regex:: Regex ;
910
@@ -56,7 +57,7 @@ impl ModId {
5657pub struct MettaMod {
5758 mod_path : String ,
5859 resource_dir : Option < PathBuf > ,
59- space : DynSpace ,
60+ space : Rc < RefCell < ModuleSpace > > ,
6061 tokenizer : Shared < Tokenizer > ,
6162 imported_deps : Mutex < HashMap < ModId , DynSpace > > ,
6263 loader : Option < Box < dyn ModuleLoader > > ,
@@ -75,6 +76,7 @@ impl MettaMod {
7576 }
7677 }
7778 }
79+ let space = Rc :: new ( RefCell :: new ( ModuleSpace :: new ( space) ) ) ;
7880
7981 let new_mod = Self {
8082 mod_path,
@@ -86,8 +88,8 @@ impl MettaMod {
8688 } ;
8789
8890 // Load the base tokens for the module's new Tokenizer
89- register_runner_tokens ( & mut * new_mod. tokenizer ( ) . borrow_mut ( ) , new_mod. tokenizer ( ) . clone ( ) , & new_mod. space , metta) ;
90- register_common_tokens ( & mut * new_mod. tokenizer ( ) . borrow_mut ( ) , new_mod. tokenizer ( ) . clone ( ) , & new_mod. space , metta) ;
91+ register_runner_tokens ( & mut * new_mod. tokenizer ( ) . borrow_mut ( ) , new_mod. tokenizer ( ) . clone ( ) , & DynSpace :: with_rc ( new_mod. space . clone ( ) ) , metta) ;
92+ register_common_tokens ( & mut * new_mod. tokenizer ( ) . borrow_mut ( ) , new_mod. tokenizer ( ) . clone ( ) , & DynSpace :: with_rc ( new_mod. space . clone ( ) ) , metta) ;
9193
9294 //Load the stdlib unless this module is no_std
9395 if !no_stdlib {
@@ -192,7 +194,7 @@ impl MettaMod {
192194 let ( dep_space, transitive_deps) = mod_ptr. stripped_space ( ) ;
193195
194196 // Add a new Grounded Space atom to the &self space, so we can access the dependent module
195- self . insert_dep ( mod_id, dep_space) ?;
197+ self . insert_dep ( mod_id, DynSpace :: with_rc ( dep_space. clone ( ) ) ) ?;
196198
197199 // Add all the transitive deps from the dependency
198200 if let Some ( transitive_deps) = transitive_deps {
@@ -228,7 +230,7 @@ impl MettaMod {
228230 fn insert_dep ( & self , mod_id : ModId , dep_space : DynSpace ) -> Result < ( ) , String > {
229231 let mut deps_table = self . imported_deps . lock ( ) . unwrap ( ) ;
230232 if !deps_table. contains_key ( & mod_id) {
231- self . add_atom ( Atom :: gnd ( dep_space . clone ( ) ) , false ) . map_err ( |a| a . to_string ( ) ) ? ;
233+ self . space . borrow_mut ( ) . add_dep ( dep_space . clone ( ) ) ;
232234 deps_table. insert ( mod_id, dep_space) ;
233235 }
234236 Ok ( ( ) )
@@ -251,39 +253,9 @@ impl MettaMod {
251253
252254 /// Private function that returns a deep copy of a module's space, with the module's dependency
253255 /// sub-spaces stripped out and returned separately
254- //
255- // HACK. This is a terrible design. It is a stop-gap to get around problems caused by transitive
256- // imports described above, but it has some serious downsides, To name a few:
257- // - It means we must copy every atom in the space for every import
258- // - It only works when the dep module's space is a GroundingSpace
259- fn stripped_space ( & self ) -> ( DynSpace , Option < HashMap < ModId , DynSpace > > ) {
256+ fn stripped_space ( & self ) -> ( Rc < RefCell < ModuleSpace > > , Option < HashMap < ModId , DynSpace > > ) {
260257 let deps_table = self . imported_deps . lock ( ) . unwrap ( ) ;
261- if deps_table. len ( ) == 0 {
262- ( self . space . clone ( ) , None )
263- } else {
264- if let Some ( any_space) = self . space . borrow ( ) . as_any ( ) {
265- if let Some ( dep_g_space) = any_space. downcast_ref :: < GroundingSpace > ( ) {
266-
267- // Do a deep-clone of the dep-space atom-by-atom, because `space.remove()` doesn't recognize
268- // two GroundedAtoms wrapping DynSpaces as being the same, even if the underlying space is
269- let mut new_space = GroundingSpace :: new ( ) ;
270- new_space. set_name ( self . path ( ) . to_string ( ) ) ;
271- for atom in dep_g_space. atom_iter ( ) . unwrap ( ) {
272- if let Some ( sub_space) = atom. as_gnd :: < DynSpace > ( ) {
273- if !deps_table. values ( ) . any ( |space| space == sub_space) {
274- new_space. add ( atom. clone ( ) ) ;
275- }
276- } else {
277- new_space. add ( atom. clone ( ) ) ;
278- }
279- }
280-
281- return ( DynSpace :: new ( new_space) , Some ( deps_table. clone ( ) ) ) ;
282- }
283- }
284- log:: warn!( "import_all_from_dependency: Importing from module based on a non-GroundingSpace is currently unsupported" ) ;
285- ( self . space . clone ( ) , None )
286- }
258+ ( self . space . clone ( ) , Some ( deps_table. clone ( ) ) )
287259 }
288260
289261 /// Returns the full path of a loaded module. For example: "top:parent_mod:this_mod"
@@ -302,8 +274,8 @@ impl MettaMod {
302274 self . loader . as_ref ( ) . and_then ( |loader| loader. pkg_info ( ) )
303275 }
304276
305- pub fn space ( & self ) -> & DynSpace {
306- & self . space
277+ pub fn space ( & self ) -> DynSpace {
278+ DynSpace :: with_rc ( self . space . clone ( ) )
307279 }
308280
309281 pub fn tokenizer ( & self ) -> & Shared < Tokenizer > {
0 commit comments