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;
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 {
// 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);
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
}
#[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))))
}
}
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())
}
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;
}
}
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);
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;
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;
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;
}
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.
-> 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)))
+ },
_ => {}
};
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
}
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();
+ }}
+}