[package]
name = "scryer-prolog"
-version = "0.8.104"
+version = "0.8.105"
build = "build.rs"
repository = "https://github.com/mthom/scryer-prolog"
of a particular module, as a list of terms of the form
Module:put_atts(V, ListOfAtts). */
'$default_attr_list'(Module, V) -->
- { Module:get_atts(V, Attributes) },
- '$default_attr_list'(Attributes, Module, V).
+ ( { Module:get_atts(V, Attributes) } ->
+ '$default_attr_list'(Attributes, Module, V)
+ ; []
+ ).
'$default_attr_list'([PG | PGs], Module, AttrVar) -->
( { '$module_of'(Module, PG) } -> [Module:put_atts(AttrVar, PG)]
%% (non-)backtrackable global variables.
-bb_put(Key, Value) :- atom(Key), !, '$store_global_var'(Key, Value).
+bb_put(Key, Value) :- atom(Key),
+ !,
+ '$store_global_var'(Key, Value).
bb_put(Key, _) :- throw(error(type_error(atom, Key), bb_put/2)).
bb_b_put(Key, NewValue) :-
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]
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> {
use prolog::clause_types::*;
use prolog::fixtures::*;
use prolog::forms::*;
+use prolog::machine::Ball;
use indexmap::IndexMap;
// 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>,
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
}
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> {
}
_ => {
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)));
}
}
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 => {}
}
}
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;
}
// 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() {
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),
}
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;
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).
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).
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,
};
}
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;
_ => 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 => {
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);
- }
- }
+ while let Some(term) = work_queue.pop_front() {
+ let term = *term;
let op_dir = op_dir(&indices.index_src);
let mut expanded_terms = indices.term_stream.expand_goals(
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);
}
query_terms.push(self.pre_query_term(indices, term)?);
}
}
-
+
Ok(query_terms)
}