give dynamic predicates a better respect for module bounds
This commit is contained in:
@@ -6,8 +6,27 @@ use prolog::machine::compile::*;
|
||||
use prolog::machine::machine_errors::*;
|
||||
use prolog::num::ToPrimitive;
|
||||
|
||||
use std::io::Read;
|
||||
|
||||
impl Machine {
|
||||
fn get_predicate_key(&self, name: RegType, arity: RegType) -> PredicateKey {
|
||||
pub(super)
|
||||
fn atom_tbl_of(&self, name: &ClauseName) -> TabledData<Atom> {
|
||||
match name {
|
||||
&ClauseName::User(ref rc) => rc.table.clone(),
|
||||
_ => self.indices.atom_tbl()
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_into_machine<R: Read>(&mut self, src: R, name: ClauseName) -> EvalSession
|
||||
{
|
||||
match name.owning_module().as_str() {
|
||||
"user" => compile_user_module(self, src),
|
||||
_ => compile_into_module(self, src, name)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_predicate_key(&self, name: RegType, arity: RegType) -> PredicateKey
|
||||
{
|
||||
let name = self.machine_st[name].clone();
|
||||
let arity = self.machine_st[arity].clone();
|
||||
|
||||
@@ -25,12 +44,10 @@ impl Machine {
|
||||
(name, arity)
|
||||
}
|
||||
|
||||
fn print_new_dynamic_clause(&self, addrs: VecDeque<Addr>, name: RegType, arity: RegType)
|
||||
fn print_new_dynamic_clause(&self, addrs: VecDeque<Addr>, name: ClauseName, arity: usize)
|
||||
-> String
|
||||
{
|
||||
let mut output = PrinterOutputter::new();
|
||||
let (name, arity) = self.get_predicate_key(name, arity);
|
||||
|
||||
output.append(format!(":- dynamic({}/{}). ", name.as_str(), arity).as_str());
|
||||
|
||||
for addr in addrs {
|
||||
@@ -56,18 +73,19 @@ impl Machine {
|
||||
self.indices.dynamic_code_dir.remove(&(name, arity));
|
||||
}
|
||||
|
||||
fn handle_eval_result_from_dynamic_compile(&mut self, pred_str: String, src: ClauseName)
|
||||
fn handle_eval_result_from_dynamic_compile(&mut self, pred_str: String, name: ClauseName,
|
||||
src: ClauseName)
|
||||
{
|
||||
let machine_st = mem::replace(&mut self.machine_st, MachineState::new());
|
||||
let result = compile_user_module(self, pred_str.as_bytes());
|
||||
|
||||
let result = self.compile_into_machine(pred_str.as_bytes(), name);
|
||||
self.machine_st = machine_st;
|
||||
|
||||
if let EvalSession::Error(err) = result {
|
||||
let h = self.machine_st.heap.h;
|
||||
let stub = MachineError::functor_stub(src, 1);
|
||||
let err = MachineError::session_error(h, err);
|
||||
let err = self.machine_st.error_form(err, stub);
|
||||
let err = self.machine_st.error_form(err, stub);
|
||||
|
||||
self.machine_st.throw_exception(err);
|
||||
}
|
||||
@@ -75,6 +93,8 @@ impl Machine {
|
||||
|
||||
fn recompile_dynamic_predicate(&mut self, place: DynamicAssertPlace)
|
||||
{
|
||||
let (name, arity) = self.get_predicate_key(temp_v!(3), temp_v!(4));
|
||||
|
||||
let stub = MachineError::functor_stub(place.predicate_name(), 1);
|
||||
let pred_str = match self.machine_st.try_from_list(temp_v!(2), stub) {
|
||||
Ok(addrs) => {
|
||||
@@ -82,16 +102,17 @@ impl Machine {
|
||||
let added_clause = self.machine_st[temp_v!(1)].clone();
|
||||
|
||||
place.push_to_queue(&mut addrs, added_clause);
|
||||
self.print_new_dynamic_clause(addrs, temp_v!(3), temp_v!(4))
|
||||
self.print_new_dynamic_clause(addrs, name.clone(), arity)
|
||||
},
|
||||
Err(err) =>
|
||||
return self.machine_st.throw_exception(err)
|
||||
};
|
||||
|
||||
self.handle_eval_result_from_dynamic_compile(pred_str, place.predicate_name());
|
||||
self.handle_eval_result_from_dynamic_compile(pred_str, name, place.predicate_name());
|
||||
}
|
||||
|
||||
fn retract_from_dynamic_predicate(&mut self) {
|
||||
fn retract_from_dynamic_predicate(&mut self)
|
||||
{
|
||||
let index = self.machine_st[temp_v!(3)].clone();
|
||||
let index = match self.machine_st.store(self.machine_st.deref(index)) {
|
||||
Addr::Con(Constant::Number(Number::Integer(n))) => n.to_usize().unwrap(),
|
||||
@@ -99,6 +120,8 @@ impl Machine {
|
||||
};
|
||||
|
||||
let stub = MachineError::functor_stub(clause_name!("retract"), 1);
|
||||
let (name, arity) = self.get_predicate_key(temp_v!(1), temp_v!(2));
|
||||
|
||||
let pred_str = match self.machine_st.try_from_list(temp_v!(4), stub) {
|
||||
Ok(addrs) => {
|
||||
let mut addrs = VecDeque::from(addrs);
|
||||
@@ -109,13 +132,13 @@ impl Machine {
|
||||
return;
|
||||
}
|
||||
|
||||
self.print_new_dynamic_clause(addrs, temp_v!(1), temp_v!(2))
|
||||
self.print_new_dynamic_clause(addrs, name.clone(), arity)
|
||||
},
|
||||
Err(err) =>
|
||||
return self.machine_st.throw_exception(err)
|
||||
};
|
||||
|
||||
self.handle_eval_result_from_dynamic_compile(pred_str, clause_name!("retract"));
|
||||
self.handle_eval_result_from_dynamic_compile(pred_str, name, clause_name!("retract"));
|
||||
}
|
||||
|
||||
pub(super)
|
||||
|
||||
Reference in New Issue
Block a user