copy terms to global variable blackboard, fix attribute_goals//1

This commit is contained in:
Mark Thom
2019-10-09 14:11:31 -06:00
parent 3409db010f
commit f898b98b06
12 changed files with 113 additions and 76 deletions

View File

@@ -1070,14 +1070,19 @@ pub fn compile_special_form<R: Read>(
wam: &mut Machine,
src: ParsingStream<R>,
listing_src: ClauseName,
) -> Result<Code, SessionError> {
) -> Result<usize, SessionError> {
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
setup_indices(wam, clause_name!("builtins"), &mut indices)?;
let mut compiler = ListingCompiler::new(&wam.code_repo, true, listing_src);
let results = compiler.gather_items(wam, src, &mut indices)?;
compiler.generate_code(results.worker_results, wam, &mut indices.code_dir, 0)
let code = compiler.generate_code(results.worker_results, wam, &mut indices.code_dir, 0)?;
let p = wam.code_repo.code.len();
add_toplevel_code(wam, code, indices);
Ok(p)
}
#[inline]

View File

@@ -15,7 +15,7 @@ pub(crate) trait CopierTarget: IndexMut<usize, Output = HeapCellValue> {
pub(crate) fn copy_term<T: CopierTarget>(target: T, addr: Addr) {
let mut copy_term_state = CopyTermState::new(target);
copy_term_state.copy_term_impl(addr);
copy_term_state.copy_term_impl(addr);
}
struct CopyTermState<T: CopierTarget> {

View File

@@ -4,6 +4,7 @@ use prolog_parser::tabled_rc::*;
use prolog::clause_types::*;
use prolog::fixtures::*;
use prolog::forms::*;
use prolog::machine::Ball;
use indexmap::IndexMap;
@@ -454,7 +455,7 @@ pub type InSituCodeDir = IndexMap<PredicateKey, usize>;
// key type: module name, predicate indicator.
pub type DynamicCodeDir = IndexMap<(ClauseName, ClauseName, usize), DynamicPredicateInfo>;
pub type GlobalVarDir = IndexMap<ClauseName, Addr>;
pub type GlobalVarDir = IndexMap<ClauseName, Ball>;
pub struct IndexStore {
pub(super) atom_tbl: TabledData<Atom>,

View File

@@ -21,7 +21,7 @@ use std::io::{stdout, Write};
use std::mem;
use std::ops::{Index, IndexMut};
pub(super) struct Ball {
pub struct Ball {
pub(super) boundary: usize, // ball.0
pub(super) stub: MachineStub, // ball.1
}
@@ -48,6 +48,22 @@ impl Ball {
stub: mem::replace(&mut self.stub, vec![]),
}
}
pub(super) fn copy_and_align(&self, h: usize) -> MachineStub {
let diff = self.boundary as i64 - h as i64;
let mut stub = vec![];
for index in 0..self.stub.len() {
let heap_value = self.stub[index].clone();
stub.push(match heap_value {
HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
_ => heap_value,
});
}
stub
}
}
pub(super) struct CopyTerm<'a> {

View File

@@ -173,7 +173,7 @@ impl MachineState {
}
_ => {
self.push_attr_var_binding(h, addr.clone());
self.heap[h] = HeapCellValue::Addr(addr);
self.heap[h] = HeapCellValue::Addr(addr);
self.trail(TrailRef::Ref(Ref::AttrVar(h)));
}
}
@@ -201,7 +201,8 @@ impl MachineState {
self.heap[h] = HeapCellValue::Addr(t1);
self.trail(TrailRef::Ref(Ref::HeapCell(h)));
}
Some(Ref::AttrVar(h)) => return self.bind_attr_var(h, t1),
Some(Ref::AttrVar(h)) =>
self.bind_attr_var(h, t1),
None => {}
}
}
@@ -2091,26 +2092,6 @@ impl MachineState {
self.fail = true;
}
fn heap_ball_boundary_diff(&self) -> i64 {
self.ball.boundary as i64 - self.heap.h as i64
}
pub(super) fn copy_and_align_ball(&self) -> MachineStub {
let diff = self.heap_ball_boundary_diff();
let mut stub = vec![];
for index in 0..self.ball.stub.len() {
let heap_value = self.ball.stub[index].clone();
stub.push(match heap_value {
HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
_ => heap_value,
});
}
stub
}
pub(crate) fn is_cyclic_term(&self, addr: Addr) -> bool {
let mut seen = IndexSet::new();
let mut fail = false;
@@ -2264,7 +2245,8 @@ impl MachineState {
}
// returns true on failure.
pub(super) fn eq_test(&self, a1: Addr, a2: Addr) -> bool {
pub(super)
fn eq_test(&self, a1: Addr, a2: Addr) -> bool {
let mut iter = self.zipped_acyclic_pre_order_iter(a1, a2);
while let Some((v1, v2)) = iter.next() {

View File

@@ -179,18 +179,16 @@ impl Machine {
match compile_special_form(self, parsing_stream(VERIFY_ATTRS.as_bytes()), verify_attrs_src)
{
Ok(code) => {
self.machine_st.attr_var_init.verify_attrs_loc = self.code_repo.code.len();
self.code_repo.code.extend(code.into_iter());
Ok(p) => {
self.machine_st.attr_var_init.verify_attrs_loc = p;
}
Err(_) => panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS"),
}
match compile_special_form(self, parsing_stream(PROJECT_ATTRS.as_bytes()), project_attrs_src)
{
Ok(code) => {
self.machine_st.attr_var_init.project_attrs_loc = self.code_repo.code.len();
self.code_repo.code.extend(code.into_iter());
Ok(p) => {
self.machine_st.attr_var_init.project_attrs_loc = p;
}
Err(e) => panic!("Machine::compile_special_forms() failed at PROJECT_ATTRS: {}", e),
}
@@ -602,7 +600,9 @@ impl Machine {
self.machine_st.absorb_snapshot(snapshot);
self.machine_st.ball = ball;
let stub = self.machine_st.copy_and_align_ball();
let h = self.machine_st.heap.h;
let stub = self.machine_st.ball.copy_and_align(h);
self.machine_st.throw_exception(stub);
return;

View File

@@ -15,16 +15,20 @@ enqueue_goals(Goals0) :-
enqueue_goals(Goals).
enqueue_goals(_).
'$print_exception'(E) :-
write_term('caught: ', [quoted(false)]),
writeq(E),
nl.
'$print_project_attributes_exception'(Module, E) :-
( E = error(evaluation_error((Module:project_attributes)/2), project_attributes/2) ->
true
; write_term('caught: ', [quoted(false)]),
writeq(E),
nl
).
call_project_attributes([], _, _).
call_project_attributes([Module|Modules], QueryVars, AttrVars) :-
( catch(Module:project_attributes(QueryVars, AttrVars),
E, %error(evaluation_error((Module:project_attributes)/2), project_attributes/2),
'$print_exception'(E)) -> true
E,
'$print_project_attributes_exception'(Module, E))
-> true
; true
),
call_project_attributes(Modules, QueryVars, AttrVars).
@@ -35,12 +39,25 @@ call_attribute_goals([Module | Modules], AttrVars) :-
enqueue_goals(Goals),
call_attribute_goals(Modules, AttrVars).
'$print_attribute_goals_exception'(Module, E) :-
( E = error(evaluation_error((Module:attribute_goals)/3), attribute_goals/3)
-> true
; write_term('caught: ', [quoted(false)]),
writeq(E),
nl
).
call_goals([], _, []).
call_goals([AttrVar|AttrVars], Module, Goals) :-
( catch(Module:attribute_goals(AttrVar, Goals, RGoals),
E, %error(evaluation_error((Module:attribute_goals)/3), attribute_goals/3),
('$print_exception'(E), atts:'$default_attr_list'(Module, AttrVar, Goals, RGoals))) -> true
; true
( catch(( Module:attribute_goals(AttrVar, Goals, RGoals0),
atts:'$default_attr_list'(Module, AttrVar, RGoals0, RGoals)
),
E,
( '$print_attribute_goals_exception'(Module, E),
atts:'$default_attr_list'(Module, AttrVar, Goals, RGoals)
))
-> true
; atts:'$default_attr_list'(Module, AttrVar, Goals, RGoals)
),
call_goals(AttrVars, Module, RGoals).

View File

@@ -840,8 +840,14 @@ impl MachineState {
let addr = self[temp_v!(2)].clone();
match indices.global_variables.get(&key).cloned() {
Some(sought_addr) => self.unify(addr, sought_addr),
match indices.global_variables.get(&key) {
Some(ref ball) => {
let h = self.heap.h;
let stub = ball.copy_and_align(h);
self.heap.extend(stub.into_iter());
self.unify(addr, Addr::HeapCell(h));
}
None => self.fail = true,
};
}
@@ -1671,7 +1677,7 @@ impl MachineState {
let h = self.heap.h;
if self.ball.stub.len() > 0 {
let stub = self.copy_and_align_ball();
let stub = self.ball.copy_and_align(h);
self.heap.append(stub);
} else {
self.fail = true;
@@ -1759,9 +1765,16 @@ impl MachineState {
_ => unreachable!(),
};
let value = self[temp_v!(2)].clone();
indices.global_variables.insert(key, value);
let value = self[temp_v!(2)].clone();
let mut ball = Ball::new();
ball.boundary = self.heap.h;
copy_term(
CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut ball.stub),
value,
);
indices.global_variables.insert(key, ball);
}
&SystemClauseType::Succeed => {}
&SystemClauseType::TermVariables => {

View File

@@ -713,25 +713,9 @@ impl RelationWorker {
let mut query_terms = vec![];
let mut work_queue = VecDeque::from(terms);
let mut machine_st = MachineState::new();
while let Some(term) = work_queue.pop_front() {
let mut term = *term;
if let Term::Clause(cell, name, terms, op_spec) = term {
if name.as_str() == "," {
let term = Term::Clause(cell, name, terms, op_spec);
let mut subterms = unfold_by_str(term, ",");
while let Some(subterm) = subterms.pop() {
work_queue.push_front(Box::new(subterm));
}
continue;
} else {
term = Term::Clause(cell, name, terms, op_spec);
}
}
let term = *term;
let op_dir = op_dir(&indices.index_src);
let mut expanded_terms = indices.term_stream.expand_goals(
@@ -739,14 +723,29 @@ impl RelationWorker {
op_dir.as_ref(),
VecDeque::from(vec![term])
)?;
while let Some(term) = expanded_terms.pop() {
work_queue.push_front(Box::new(term));
}
if let Some(term) = work_queue.pop_front() {
if let Some(term) = work_queue.pop_front() {
let mut term = *term;
if let Term::Clause(cell, name, terms, op_spec) = term {
if name.as_str() == "," {
let term = Term::Clause(cell, name, terms, op_spec);
let mut subterms = unfold_by_str(term, ",");
while let Some(subterm) = subterms.pop() {
work_queue.push_front(Box::new(subterm));
}
continue;
} else {
term = Term::Clause(cell, name, terms, op_spec);
}
}
if !blocks_cuts {
mark_cut_variable(&mut term);
}
@@ -754,7 +753,7 @@ impl RelationWorker {
query_terms.push(self.pre_query_term(indices, term)?);
}
}
Ok(query_terms)
}