From: Mark Thom Date: Fri, 20 Apr 2018 20:03:04 +0000 (-0600) Subject: change modules when updating code index (re: issue #27) X-Git-Tag: v0.8.110~487 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=b87d599b14c7c362c092a65d4e91fa16167c90b1;p=scryer-prolog.git change modules when updating code index (re: issue #27) --- diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index 47edbdcb..3bbe7178 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -4,7 +4,7 @@ use prolog::num::rational::Ratio; use prolog::ordered_float::*; use prolog::tabled_rc::*; -use std::cell::Cell; +use std::cell::{Cell, RefCell}; use std::cmp::Ordering; use std::collections::{BTreeSet, HashMap, VecDeque}; use std::fmt; @@ -168,8 +168,11 @@ impl Module { pub fn as_module_code_dir(code_dir: CodeDir) -> ModuleCodeDir { code_dir.into_iter() - .map(|(k, code_idx)| (k, ModuleCodeIndex(code_idx.0.get(), code_idx.1))) - .collect() + .map(|(k, code_idx)| { + let (idx, module_name) = code_idx.0.borrow().clone(); + (k, ModuleCodeIndex(idx, module_name)) + }) + .collect() } impl SubModuleUser for Module { @@ -189,14 +192,14 @@ pub trait SubModuleUser { // returns true on successful import. fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool { let name = name.defrock_brackets(); - + { let mut insert_op_dir = |fix| { if let Some(op_data) = submodule.op_dir.get(&(name.clone(), fix)) { self.op_dir().insert((name.clone(), fix), op_data.clone()); } }; - + if arity == 1 { insert_op_dir(Fixity::Pre); insert_op_dir(Fixity::Post); @@ -204,7 +207,7 @@ pub trait SubModuleUser { insert_op_dir(Fixity::In); } } - + if let Some(code_data) = submodule.code_dir.get(&(name.clone(), arity)) { self.insert_dir_entry(name, arity, code_data.clone()); true @@ -1392,26 +1395,26 @@ pub enum IndexPtr { } #[derive(Clone)] -pub struct CodeIndex(pub Rc>, pub ClauseName); +pub struct CodeIndex(pub Rc>); #[derive(Clone)] pub struct ModuleCodeIndex(pub IndexPtr, pub ClauseName); impl From for CodeIndex { fn from(value: ModuleCodeIndex) -> Self { - CodeIndex(Rc::new(Cell::new(value.0)), value.1.clone()) + CodeIndex(Rc::new(RefCell::new((value.0, value.1.clone())))) } } impl Default for CodeIndex { fn default() -> Self { - CodeIndex(Rc::new(Cell::new(IndexPtr::Undefined)), clause_name!("")) + CodeIndex(Rc::new(RefCell::new((IndexPtr::Undefined, clause_name!(""))))) } } impl From<(usize, ClauseName)> for CodeIndex { fn from(value: (usize, ClauseName)) -> Self { - CodeIndex(Rc::new(Cell::new(IndexPtr::Index(value.0))), value.1) + CodeIndex(Rc::new(RefCell::new((IndexPtr::Index(value.0), value.1)))) } } diff --git a/src/prolog/io.rs b/src/prolog/io.rs index 9259054f..9d12260e 100644 --- a/src/prolog/io.rs +++ b/src/prolog/io.rs @@ -115,8 +115,10 @@ impl fmt::Display for CompareTermQT { impl fmt::Display for ClauseType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &ClauseType::Named(ref name, ref idx) | &ClauseType::Op(ref name, _, ref idx) => - write!(f, "{}:{}/{}", idx.1, name, idx.0.get()), + &ClauseType::Named(ref name, ref idx) | &ClauseType::Op(ref name, _, ref idx) => { + let idx = idx.0.borrow(); + write!(f, "{}:{}/{}", idx.1, name, idx.0) + }, ref ct => write!(f, "{}", ct.name()) } @@ -465,18 +467,23 @@ pub(crate) trait TLInfo { struct DeclInfo { name: ClauseName, arity: usize, module_name: ClauseName } impl TLInfo for DeclInfo { - fn update_entry_index(&self, n1: &ClauseName, a1: usize, mut entry: CodeIndex, + fn update_entry_index(&self, n1: &ClauseName, a1: usize, entry: CodeIndex, cp: &mut CodeIndex, code_size: usize) { let (name, arity) = (self.name.clone(), self.arity); - - if entry.0.get() == IndexPtr::Undefined { - if &name == n1 && arity == a1 { - entry.0.set(IndexPtr::Index(code_size)); + + { + let mut entry = entry.0.borrow_mut(); + + if entry.0 == IndexPtr::Undefined { + if &name == n1 && arity == a1 { + entry.0 = IndexPtr::Index(code_size); + } } - } - entry.1 = self.module_name.clone(); + entry.1 = self.module_name.clone(); + } + *cp = entry; } } @@ -675,11 +682,10 @@ pub fn compile_listing(wam: &mut Machine, src_str: &str) -> EvalSession module_name: module_name.clone() }; { - let index = code_dir.entry((decl_info.name.clone(), decl_info.arity)) + let idx = code_dir.entry((decl_info.name.clone(), decl_info.arity)) .or_insert(CodeIndex::default()); - - index.0.set(IndexPtr::Index(p)); - index.1 = module_name; + + set_code_index!(idx, IndexPtr::Index(p), module_name); } decl_info.label_clauses(p, &mut code_dir, &mut decl_code); diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index a88aa65f..6c6b6d00 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -235,11 +235,11 @@ pub(crate) trait CallPolicy: Any { arity: usize, idx: CodeIndex) -> CallResult { - match idx.0.get() { + match idx.0.borrow().0 { IndexPtr::Undefined => return Err(predicate_existence_error(name, arity, machine_st.heap.h)), IndexPtr::Index(compiled_tl_index) => { - let module_name = idx.1; + let module_name = idx.0.borrow().1.clone(); machine_st.cp = machine_st.p.clone() + 1; machine_st.num_of_args = arity; @@ -255,11 +255,11 @@ pub(crate) trait CallPolicy: Any { arity: usize, idx: CodeIndex) -> CallResult { - match idx.0.get() { + match idx.0.borrow().0 { IndexPtr::Undefined => return Err(predicate_existence_error(name, arity, machine_st.heap.h)), IndexPtr::Index(compiled_tl_index) => { - let module_name = idx.1; + let module_name = idx.0.borrow().1.clone(); machine_st.num_of_args = arity; machine_st.b0 = machine_st.b; diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 8c4b977e..efce38ce 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -56,9 +56,7 @@ impl<'a> SubModuleUser for MachineCodeIndex<'a> { fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex) { if let Some(ref mut code_idx) = self.code_dir.get_mut(&(name.clone(), arity)) { println!("warning: overwriting {}/{}", &name, arity); - - code_idx.0.set(idx.0); - code_idx.1 = idx.1; + set_code_index!(code_idx, idx.0, idx.1); return; } @@ -96,7 +94,11 @@ impl Machine { let name = name.defrock_brackets(); match self.code_dir.get(&(name.clone(), arity)).cloned() { - Some(CodeIndex (_, ref mod_name)) if mod_name == &module_name => { + Some(CodeIndex (ref code_idx)) => { + if &code_idx.borrow().1 != &module_name { + continue; + } + self.code_dir.remove(&(name.clone(), arity)); // remove or respecify ops. @@ -188,10 +190,12 @@ impl Machine { -> EvalSession { match self.code_dir.get(&(name.clone(), arity)) { - Some(&CodeIndex (_, ref mod_name)) if mod_name == &clause_name!("builtin") => - return EvalSession::from(EvalError::ImpermissibleEntry(format!("{}/{}", - name, - arity))), + Some(&CodeIndex (ref idx)) => + if idx.borrow().1 == clause_name!("builtin") { + return EvalSession::from(EvalError::ImpermissibleEntry(format!("{}/{}", + name, + arity))) + }, _ => {} }; @@ -200,12 +204,10 @@ impl Machine { self.code.extend(code.into_iter()); self.term_dir.insert((name.clone(), arity), pred); - let entry = self.code_dir.entry((name, arity)) + let idx = self.code_dir.entry((name, arity)) .or_insert(CodeIndex::from((offset, clause_name!("user")))); - entry.0.set(IndexPtr::Index(offset)); - entry.1 = clause_name!("user"); - + set_code_index!(idx, IndexPtr::Index(offset), clause_name!("user")); EvalSession::EntrySuccess } diff --git a/src/prolog/macros.rs b/src/prolog/macros.rs index 05a5fff9..7abe2ce0 100644 --- a/src/prolog/macros.rs +++ b/src/prolog/macros.rs @@ -774,3 +774,12 @@ macro_rules! return_from_clause { Ok(()) }} } + +macro_rules! set_code_index { + ($idx:expr, $ip:expr, $mod_name:expr) => {{ + let mut idx = $idx.0.borrow_mut(); + + idx.0 = $ip; + idx.1 = $mod_name.clone(); + }} +}