]> Repositorios git - scryer-prolog.git/commitdiff
change modules when updating code index (re: issue #27)
authorMark Thom <[email protected]>
Fri, 20 Apr 2018 20:03:04 +0000 (14:03 -0600)
committerMark Thom <[email protected]>
Fri, 20 Apr 2018 20:03:04 +0000 (14:03 -0600)
src/prolog/ast.rs
src/prolog/io.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/mod.rs
src/prolog/macros.rs

index 47edbdcba476bbce05ffada49d66626d88180685..3bbe7178839a0217336e533b209474b652cbea7b 100644 (file)
@@ -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<Cell<IndexPtr>>, pub ClauseName);
+pub struct CodeIndex(pub Rc<RefCell<(IndexPtr, ClauseName)>>);
 
 #[derive(Clone)]
 pub struct ModuleCodeIndex(pub IndexPtr, pub ClauseName);
 
 impl From<ModuleCodeIndex> 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))))
     }
 }
 
index 9259054fd1f91a7d7cac102b294745709ab44d90..9d12260e940b51155033f390a0efef10a3abb55b 100644 (file)
@@ -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);
index a88aa65fd187ced0b3990b849dbe48d2a7d6d9b1..6c6b6d00258b5e47db3c9fc4dac8d61723b0d4ed 100644 (file)
@@ -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;
index 8c4b977e4ac42b602f380f83d534c1782823ceb3..efce38ce7d1efba4748bcf2c66f6bbe7b2238c55 100644 (file)
@@ -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
     }
 
index 05a5fff942d0fe1600ad638d95175c09eab74b88..7abe2ce0c8b083a599bf77bdd8b565dbc86984f8 100644 (file)
@@ -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();
+    }}
+}