change modules when updating code index (re: issue #27)

This commit is contained in:
Mark Thom
2018-04-20 14:03:04 -06:00
parent 09bd087ba5
commit b87d599b14
5 changed files with 59 additions and 39 deletions

View File

@@ -4,7 +4,7 @@ use prolog::num::rational::Ratio;
use prolog::ordered_float::*; use prolog::ordered_float::*;
use prolog::tabled_rc::*; use prolog::tabled_rc::*;
use std::cell::Cell; use std::cell::{Cell, RefCell};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::{BTreeSet, HashMap, VecDeque}; use std::collections::{BTreeSet, HashMap, VecDeque};
use std::fmt; use std::fmt;
@@ -168,7 +168,10 @@ impl Module {
pub fn as_module_code_dir(code_dir: CodeDir) -> ModuleCodeDir { pub fn as_module_code_dir(code_dir: CodeDir) -> ModuleCodeDir {
code_dir.into_iter() code_dir.into_iter()
.map(|(k, code_idx)| (k, ModuleCodeIndex(code_idx.0.get(), code_idx.1))) .map(|(k, code_idx)| {
let (idx, module_name) = code_idx.0.borrow().clone();
(k, ModuleCodeIndex(idx, module_name))
})
.collect() .collect()
} }
@@ -1392,26 +1395,26 @@ pub enum IndexPtr {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct CodeIndex(pub Rc<Cell<IndexPtr>>, pub ClauseName); pub struct CodeIndex(pub Rc<RefCell<(IndexPtr, ClauseName)>>);
#[derive(Clone)] #[derive(Clone)]
pub struct ModuleCodeIndex(pub IndexPtr, pub ClauseName); pub struct ModuleCodeIndex(pub IndexPtr, pub ClauseName);
impl From<ModuleCodeIndex> for CodeIndex { impl From<ModuleCodeIndex> for CodeIndex {
fn from(value: ModuleCodeIndex) -> Self { 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 { impl Default for CodeIndex {
fn default() -> Self { 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 { impl From<(usize, ClauseName)> for CodeIndex {
fn from(value: (usize, ClauseName)) -> Self { 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))))
} }
} }

View File

@@ -115,8 +115,10 @@ impl fmt::Display for CompareTermQT {
impl fmt::Display for ClauseType { impl fmt::Display for ClauseType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
&ClauseType::Named(ref name, ref idx) | &ClauseType::Op(ref name, _, ref idx) => &ClauseType::Named(ref name, ref idx) | &ClauseType::Op(ref name, _, ref idx) => {
write!(f, "{}:{}/{}", idx.1, name, idx.0.get()), let idx = idx.0.borrow();
write!(f, "{}:{}/{}", idx.1, name, idx.0)
},
ref ct => ref ct =>
write!(f, "{}", ct.name()) write!(f, "{}", ct.name())
} }
@@ -465,18 +467,23 @@ pub(crate) trait TLInfo {
struct DeclInfo { name: ClauseName, arity: usize, module_name: ClauseName } struct DeclInfo { name: ClauseName, arity: usize, module_name: ClauseName }
impl TLInfo for DeclInfo { 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) cp: &mut CodeIndex, code_size: usize)
{ {
let (name, arity) = (self.name.clone(), self.arity); let (name, arity) = (self.name.clone(), self.arity);
if entry.0.get() == IndexPtr::Undefined { {
let mut entry = entry.0.borrow_mut();
if entry.0 == IndexPtr::Undefined {
if &name == n1 && arity == a1 { if &name == n1 && arity == a1 {
entry.0.set(IndexPtr::Index(code_size)); entry.0 = IndexPtr::Index(code_size);
} }
} }
entry.1 = self.module_name.clone(); entry.1 = self.module_name.clone();
}
*cp = entry; *cp = entry;
} }
} }
@@ -675,11 +682,10 @@ pub fn compile_listing(wam: &mut Machine, src_str: &str) -> EvalSession
module_name: module_name.clone() }; 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()); .or_insert(CodeIndex::default());
index.0.set(IndexPtr::Index(p)); set_code_index!(idx, IndexPtr::Index(p), module_name);
index.1 = module_name;
} }
decl_info.label_clauses(p, &mut code_dir, &mut decl_code); decl_info.label_clauses(p, &mut code_dir, &mut decl_code);

View File

@@ -235,11 +235,11 @@ pub(crate) trait CallPolicy: Any {
arity: usize, idx: CodeIndex) arity: usize, idx: CodeIndex)
-> CallResult -> CallResult
{ {
match idx.0.get() { match idx.0.borrow().0 {
IndexPtr::Undefined => IndexPtr::Undefined =>
return Err(predicate_existence_error(name, arity, machine_st.heap.h)), return Err(predicate_existence_error(name, arity, machine_st.heap.h)),
IndexPtr::Index(compiled_tl_index) => { 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.cp = machine_st.p.clone() + 1;
machine_st.num_of_args = arity; machine_st.num_of_args = arity;
@@ -255,11 +255,11 @@ pub(crate) trait CallPolicy: Any {
arity: usize, idx: CodeIndex) arity: usize, idx: CodeIndex)
-> CallResult -> CallResult
{ {
match idx.0.get() { match idx.0.borrow().0 {
IndexPtr::Undefined => IndexPtr::Undefined =>
return Err(predicate_existence_error(name, arity, machine_st.heap.h)), return Err(predicate_existence_error(name, arity, machine_st.heap.h)),
IndexPtr::Index(compiled_tl_index) => { 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.num_of_args = arity;
machine_st.b0 = machine_st.b; machine_st.b0 = machine_st.b;

View File

@@ -56,9 +56,7 @@ impl<'a> SubModuleUser for MachineCodeIndex<'a> {
fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex) { 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)) { if let Some(ref mut code_idx) = self.code_dir.get_mut(&(name.clone(), arity)) {
println!("warning: overwriting {}/{}", &name, arity); println!("warning: overwriting {}/{}", &name, arity);
set_code_index!(code_idx, idx.0, idx.1);
code_idx.0.set(idx.0);
code_idx.1 = idx.1;
return; return;
} }
@@ -96,7 +94,11 @@ impl Machine {
let name = name.defrock_brackets(); let name = name.defrock_brackets();
match self.code_dir.get(&(name.clone(), arity)).cloned() { 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)); self.code_dir.remove(&(name.clone(), arity));
// remove or respecify ops. // remove or respecify ops.
@@ -188,10 +190,12 @@ impl Machine {
-> EvalSession -> EvalSession
{ {
match self.code_dir.get(&(name.clone(), arity)) { match self.code_dir.get(&(name.clone(), arity)) {
Some(&CodeIndex (_, ref mod_name)) if mod_name == &clause_name!("builtin") => Some(&CodeIndex (ref idx)) =>
if idx.borrow().1 == clause_name!("builtin") {
return EvalSession::from(EvalError::ImpermissibleEntry(format!("{}/{}", return EvalSession::from(EvalError::ImpermissibleEntry(format!("{}/{}",
name, name,
arity))), arity)))
},
_ => {} _ => {}
}; };
@@ -200,12 +204,10 @@ impl Machine {
self.code.extend(code.into_iter()); self.code.extend(code.into_iter());
self.term_dir.insert((name.clone(), arity), pred); 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")))); .or_insert(CodeIndex::from((offset, clause_name!("user"))));
entry.0.set(IndexPtr::Index(offset)); set_code_index!(idx, IndexPtr::Index(offset), clause_name!("user"));
entry.1 = clause_name!("user");
EvalSession::EntrySuccess EvalSession::EntrySuccess
} }

View File

@@ -774,3 +774,12 @@ macro_rules! return_from_clause {
Ok(()) 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();
}}
}