reload files properly (re: #213)

This commit is contained in:
Mark Thom
2019-10-26 01:34:41 -06:00
parent e9c1556c32
commit a358431d30
6 changed files with 80 additions and 85 deletions

View File

@@ -338,6 +338,7 @@ pub struct Module {
pub user_term_expansions: (Predicate, VecDeque<TopLevel>), // term expansions inherited from the user scope. pub user_term_expansions: (Predicate, VecDeque<TopLevel>), // term expansions inherited from the user scope.
pub user_goal_expansions: (Predicate, VecDeque<TopLevel>), // same for goal_expansions. pub user_goal_expansions: (Predicate, VecDeque<TopLevel>), // same for goal_expansions.
pub inserted_expansions: bool, // has the module been successfully inserted into toplevel?? pub inserted_expansions: bool, // has the module been successfully inserted into toplevel??
pub is_impromptu_module: bool,
} }
#[derive(Clone, PartialEq, Eq)] #[derive(Clone, PartialEq, Eq)]

View File

@@ -62,7 +62,7 @@ fn load_module<R: Read>(
stream: ParsingStream<R>, stream: ParsingStream<R>,
suppress_warnings: bool, suppress_warnings: bool,
listing_src: ClauseName, listing_src: ClauseName,
) -> Result<Option<ClauseName>, SessionError> { ) -> Result<ClauseName, SessionError> {
// follow the operation of compile_user_module, but before // follow the operation of compile_user_module, but before
// compiling, check that a module is declared in the file. if not, // compiling, check that a module is declared in the file. if not,
// throw an exception. // throw an exception.
@@ -72,15 +72,24 @@ fn load_module<R: Read>(
let mut compiler = ListingCompiler::new( let mut compiler = ListingCompiler::new(
&wam.code_repo, &wam.code_repo,
suppress_warnings, suppress_warnings,
listing_src, listing_src.clone(),
); );
let results = compiler.gather_items(wam, stream, &mut indices); let results = compiler.gather_items(wam, stream, &mut indices);
let module_name = if let Some(ref module) = &compiler.module { let module_name = if let Some(ref module) = &compiler.module {
Some(module.module_decl.name.clone()) module.module_decl.name.clone()
} else { } else {
None // this impromptu definition (namely, its exports) will be filled out later.
let module_decl = ModuleDecl { name: listing_src, exports: vec![] };
let mut module = Module::new(module_decl, wam.indices.atom_tbl.clone());
let module_name = module.module_decl.name.clone();
module.is_impromptu_module = true;
compiler.module = Some(module);
module_name
}; };
results.and_then(|results| compile_work_impl(&mut compiler, wam, indices, results)) results.and_then(|results| compile_work_impl(&mut compiler, wam, indices, results))
@@ -97,7 +106,7 @@ fn load_module_from_file(
wam: &mut Machine, wam: &mut Machine,
filename: &str, filename: &str,
suppress_warnings: bool, suppress_warnings: bool,
) -> Result<Option<ClauseName>, SessionError> { ) -> Result<ClauseName, SessionError> {
let path = fix_filename(wam.indices.atom_tbl.clone(), filename)?; let path = fix_filename(wam.indices.atom_tbl.clone(), filename)?;
let filename = clause_name!(path.to_string_lossy().to_string(), wam.indices.atom_tbl); let filename = clause_name!(path.to_string_lossy().to_string(), wam.indices.atom_tbl);
@@ -491,12 +500,9 @@ pub struct ListingCompiler {
listing_src: ClauseName // a file? a module? listing_src: ClauseName // a file? a module?
} }
fn add_toplevel_code(wam: &mut Machine, code: Code, mut indices: IndexStore) { fn add_toplevel_code(wam: &mut Machine, code: Code, indices: IndexStore) {
let code_dir = mem::replace(&mut indices.code_dir, CodeDir::new()); wam.add_batched_code(code, indices.code_dir);
let op_dir = mem::replace(&mut indices.op_dir, OpDir::new()); wam.add_batched_ops(indices.op_dir);
wam.add_batched_code(code, code_dir);
wam.add_batched_ops(op_dir);
} }
#[inline] #[inline]
@@ -543,9 +549,8 @@ fn load_library(
) -> Result<ClauseName, SessionError> { ) -> Result<ClauseName, SessionError> {
match LIBRARIES.borrow().get(name.as_str()) { match LIBRARIES.borrow().get(name.as_str()) {
Some(code) => { Some(code) => {
let module_name = load_module(wam, parsing_stream(code.as_bytes()), load_module(wam, parsing_stream(code.as_bytes()),
suppress_warnings, name.clone())?; suppress_warnings, name.clone())
module_name.ok_or(SessionError::NoModuleDeclaration(name))
} }
None => Err(SessionError::ModuleNotFound) None => Err(SessionError::ModuleNotFound)
} }
@@ -848,17 +853,11 @@ impl ListingCompiler {
} }
Declaration::UseModule(ModuleSource::File(filename)) => { Declaration::UseModule(ModuleSource::File(filename)) => {
let name = load_module_from_file(wam, filename.as_str(), true)?; let name = load_module_from_file(wam, filename.as_str(), true)?;
if let Some(name) = name {
self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices) self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices)
} else {
Ok(())
}
} }
Declaration::UseQualifiedModule(ModuleSource::File(filename), exports) => { Declaration::UseQualifiedModule(ModuleSource::File(filename), exports) => {
let name = load_module_from_file(wam, filename.as_str(), true)?; let name = load_module_from_file(wam, filename.as_str(), true)?;
if let Some(name) = name {
self.use_qualified_module( self.use_qualified_module(
name, name,
&mut wam.code_repo, &mut wam.code_repo,
@@ -867,9 +866,6 @@ impl ListingCompiler {
&mut wam.indices, &mut wam.indices,
indices, indices,
) )
} else {
Ok(())
}
} }
Declaration::ModuleInitialization(query_terms, queue) => { Declaration::ModuleInitialization(query_terms, queue) => {
self.initialization_goals.0.extend(query_terms.into_iter()); self.initialization_goals.0.extend(query_terms.into_iter());
@@ -996,6 +992,7 @@ fn compile_work_impl(
&mut indices.code_dir, &mut indices.code_dir,
0 0
)?; )?;
let toplvl_code = compiler.generate_code( let toplvl_code = compiler.generate_code(
results.toplevel_results, results.toplevel_results,
wam, wam,
@@ -1004,16 +1001,24 @@ fn compile_work_impl(
)?; )?;
if let Some(ref mut module) = &mut compiler.module { if let Some(ref mut module) = &mut compiler.module {
if !module.is_impromptu_module {
module.user_term_expansions = results.addition_results.take_term_expansions(); module.user_term_expansions = results.addition_results.take_term_expansions();
module.user_goal_expansions = results.addition_results.take_goal_expansions(); module.user_goal_expansions = results.addition_results.take_goal_expansions();
} }
}
let flags = wam.machine_flags(); let flags = wam.machine_flags();
wam.code_repo.compile_hook(CompileTimeHook::UserTermExpansion, flags)?; wam.code_repo.compile_hook(CompileTimeHook::UserTermExpansion, flags)?;
wam.code_repo.compile_hook(CompileTimeHook::UserGoalExpansion, flags)?; wam.code_repo.compile_hook(CompileTimeHook::UserGoalExpansion, flags)?;
if let Some(module) = compiler.module.take() { if let Some(mut module) = compiler.module.take() {
if module.is_impromptu_module {
module.module_decl.exports = indices.code_dir.keys().cloned()
.filter(|(name, _)| name.owning_module().as_str() != "builtins")
.collect();
}
let mut clause_code_generator = let mut clause_code_generator =
ClauseCodeGenerator::new(module_code.len() + toplvl_code.len(), ClauseCodeGenerator::new(module_code.len() + toplvl_code.len(),
module.module_decl.name.clone()); module.module_decl.name.clone());
@@ -1021,6 +1026,10 @@ fn compile_work_impl(
wam.check_toplevel_code(&results.toplevel_indices)?; wam.check_toplevel_code(&results.toplevel_indices)?;
clause_code_generator.generate_clause_code(&results.dynamic_clause_map, wam)?; clause_code_generator.generate_clause_code(&results.dynamic_clause_map, wam)?;
if let Some(ref module) = wam.indices.modules.swap_remove(&module.module_decl.name) {
wam.indices.remove_module(clause_name!("user"), module);
}
add_module_code(wam, module, module_code, indices); add_module_code(wam, module, module_code, indices);
add_toplevel_code(wam, toplvl_code, results.toplevel_indices); add_toplevel_code(wam, toplvl_code, results.toplevel_indices);

View File

@@ -143,9 +143,6 @@ impl MachineError {
"private_procedure", "private_procedure",
clause_name!("module_does_not_exist"), clause_name!("module_does_not_exist"),
), ),
SessionError::NoModuleDeclaration(name) => {
Self::existence_error(h, ExistenceError::Module(name))
}
SessionError::OpIsInfixAndPostFix(op) => { SessionError::OpIsInfixAndPostFix(op) => {
Self::permission_error(PermissionError::Create, "operator", op) Self::permission_error(PermissionError::Create, "operator", op)
} }
@@ -538,7 +535,6 @@ pub enum SessionError {
ModuleDoesNotContainExport, ModuleDoesNotContainExport,
ModuleNotFound, ModuleNotFound,
NamelessEntry, NamelessEntry,
NoModuleDeclaration(ClauseName),
OpIsInfixAndPostFix(ClauseName), OpIsInfixAndPostFix(ClauseName),
ParserError(ParserError), ParserError(ParserError),
UserPrompt, UserPrompt,

View File

@@ -128,7 +128,7 @@ impl SubModuleUser for IndexStore {
fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: CodeIndex) { fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: CodeIndex) {
if let Some(ref code_idx) = self.code_dir.get(&(name.clone(), arity)) { if let Some(ref code_idx) = self.code_dir.get(&(name.clone(), arity)) {
if !code_idx.is_undefined() { if !code_idx.is_undefined() {
println!("warning: overwriting {}/{}", &name, arity); println!("Warning: overwriting {}/{}", &name, arity);
} }
let (p, module_name) = idx.0.borrow().clone(); let (p, module_name) = idx.0.borrow().clone();
@@ -444,28 +444,22 @@ impl Machine {
let load_result = match to_src(name) { let load_result = match to_src(name) {
ModuleSource::Library(name) => ModuleSource::Library(name) =>
if !self.indices.modules.contains_key(&name) { if !self.indices.modules.contains_key(&name) {
load_library(self, name, false).map(Some) load_library(self, name, false)
} else { } else {
Ok(Some(name)) Ok(name)
}, },
ModuleSource::File(name) => ModuleSource::File(name) =>
load_module_from_file(self, name.as_str(), false) load_module_from_file(self, name.as_str(), false)
}; };
let result = load_result.and_then(|name| let result = load_result.and_then(|name| {
if let Some(name) = name { let module = self.indices.take_module(name.clone()).unwrap();
let module = self.indices.take_module(name).unwrap();
// remove previous exports.
self.indices.remove_module(clause_name!("user"), &module);
self.indices.use_module(&mut self.code_repo, self.machine_st.flags, self.indices.use_module(&mut self.code_repo, self.machine_st.flags,
&module)?; &module)?;
Ok(self.indices.insert_module(module)) Ok(self.indices.insert_module(module))
} else { });
Ok(())
}
);
self.code_repo.cached_query = cached_query; self.code_repo.cached_query = cached_query;
@@ -490,31 +484,28 @@ impl Machine {
let load_result = match to_src(name) { let load_result = match to_src(name) {
ModuleSource::Library(name) => ModuleSource::Library(name) =>
if !self.indices.modules.contains_key(&name) { if let Some(module) = self.indices.take_module(name.clone()) {
load_library(self, name, false).map(Some) self.indices.remove_module(clause_name!("user"), &module);
self.indices.modules.insert(name.clone(), module);
Ok(name)
} else { } else {
Ok(Some(name)) load_library(self, name, false)
}, },
ModuleSource::File(name) => ModuleSource::File(name) =>
load_module_from_file(self, name.as_str(), false) load_module_from_file(self, name.as_str(), false)
}; };
let result = load_result.and_then(|name| let result = load_result.and_then(|name| {
if let Some(name) = name { let module = self.indices.take_module(name.clone()).unwrap();
let module = self.indices.take_module(name).unwrap();
// remove previous exports.
self.indices.remove_module(clause_name!("user"), &module);
self.indices.use_qualified_module(&mut self.code_repo, self.indices.use_qualified_module(&mut self.code_repo,
self.machine_st.flags, self.machine_st.flags,
&module, &module,
&exports)?; &exports)?;
Ok(self.indices.insert_module(module)) Ok(self.indices.insert_module(module))
} else { });
Ok(())
}
);
self.code_repo.cached_query = cached_query; self.code_repo.cached_query = cached_query;

View File

@@ -22,6 +22,7 @@ impl Module {
code_dir: CodeDir::new(), code_dir: CodeDir::new(),
op_dir: default_op_dir(), op_dir: default_op_dir(),
inserted_expansions: false, inserted_expansions: false,
is_impromptu_module: false,
} }
} }
@@ -162,7 +163,7 @@ pub trait SubModuleUser {
self.insert_dir_entry(name, arity, code_data.clone()); self.insert_dir_entry(name, arity, code_data.clone());
true true
} else { } else {
found_op found_op || submodule.is_impromptu_module
} }
} }

View File

@@ -268,9 +268,6 @@ impl fmt::Display for SessionError {
&SessionError::ModuleDoesNotContainExport => { &SessionError::ModuleDoesNotContainExport => {
write!(f, "module does not contain claimed export.") write!(f, "module does not contain claimed export.")
} }
&SessionError::NoModuleDeclaration(ref name) => {
write!(f, "file {}.pl lacks an expected module declaration.", name)
}
&SessionError::OpIsInfixAndPostFix(_) => { &SessionError::OpIsInfixAndPostFix(_) => {
write!(f, "cannot define an op to be both postfix and infix.") write!(f, "cannot define an op to be both postfix and infix.")
} }