change modules when updating code index (re: issue #27)
This commit is contained in:
@@ -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,8 +168,11 @@ 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)| {
|
||||||
.collect()
|
let (idx, module_name) = code_idx.0.borrow().clone();
|
||||||
|
(k, ModuleCodeIndex(idx, module_name))
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SubModuleUser for Module {
|
impl SubModuleUser for Module {
|
||||||
@@ -189,14 +192,14 @@ pub trait SubModuleUser {
|
|||||||
// returns true on successful import.
|
// returns true on successful import.
|
||||||
fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool {
|
fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool {
|
||||||
let name = name.defrock_brackets();
|
let name = name.defrock_brackets();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut insert_op_dir = |fix| {
|
let mut insert_op_dir = |fix| {
|
||||||
if let Some(op_data) = submodule.op_dir.get(&(name.clone(), fix)) {
|
if let Some(op_data) = submodule.op_dir.get(&(name.clone(), fix)) {
|
||||||
self.op_dir().insert((name.clone(), fix), op_data.clone());
|
self.op_dir().insert((name.clone(), fix), op_data.clone());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if arity == 1 {
|
if arity == 1 {
|
||||||
insert_op_dir(Fixity::Pre);
|
insert_op_dir(Fixity::Pre);
|
||||||
insert_op_dir(Fixity::Post);
|
insert_op_dir(Fixity::Post);
|
||||||
@@ -204,7 +207,7 @@ pub trait SubModuleUser {
|
|||||||
insert_op_dir(Fixity::In);
|
insert_op_dir(Fixity::In);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(code_data) = submodule.code_dir.get(&(name.clone(), arity)) {
|
if let Some(code_data) = submodule.code_dir.get(&(name.clone(), arity)) {
|
||||||
self.insert_dir_entry(name, arity, code_data.clone());
|
self.insert_dir_entry(name, arity, code_data.clone());
|
||||||
true
|
true
|
||||||
@@ -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))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
{
|
||||||
if &name == n1 && arity == a1 {
|
let mut entry = entry.0.borrow_mut();
|
||||||
entry.0.set(IndexPtr::Index(code_size));
|
|
||||||
|
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;
|
*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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)) =>
|
||||||
return EvalSession::from(EvalError::ImpermissibleEntry(format!("{}/{}",
|
if idx.borrow().1 == clause_name!("builtin") {
|
||||||
name,
|
return EvalSession::from(EvalError::ImpermissibleEntry(format!("{}/{}",
|
||||||
arity))),
|
name,
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user