]> Repositorios git - scryer-prolog.git/commitdiff
copy terms to global variable blackboard, fix attribute_goals//1
authorMark Thom <[email protected]>
Wed, 9 Oct 2019 20:11:31 +0000 (14:11 -0600)
committerMark Thom <[email protected]>
Wed, 9 Oct 2019 20:11:31 +0000 (14:11 -0600)
12 files changed:
Cargo.toml
src/prolog/lib/atts.pl
src/prolog/lib/non_iso.pl
src/prolog/machine/compile.rs
src/prolog/machine/copier.rs
src/prolog/machine/machine_indices.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs
src/prolog/machine/project_attributes.pl
src/prolog/machine/system_calls.rs
src/prolog/machine/toplevel.rs

index b4cd90df1fd4d79a7c948e5774b58aa77d36c71e..e1f0ef68e23f68e3fa7ac72247db01407034efca 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "scryer-prolog"
-version = "0.8.104"
+version = "0.8.105"
 authors = ["Mark Thom <[email protected]>"]
 build = "build.rs"
 repository = "https://github.com/mthom/scryer-prolog"
index 2e355d5645c12fc3e08c8caa957e472a2cb7d048..eba35d2f70d72f1d11161d7d578e265714ac47f2 100644 (file)
    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)]
index 9d4367fbb674928dcf7274e3e2264e61c8581691..14accf43b08b6241f4e6bb91101ee5e611a8e060 100644 (file)
@@ -12,7 +12,9 @@ forall(Generate, Test) :-
 
 %% (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) :-
index f2d3083baab52f42f362182429b7f85155662380..4ed2d5028bf7c85a15371b3af09325aec41ec298 100644 (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]
index 4fd58f633c8323812d006d335c2cf2c188014582..577f999249cded55a97bc827909181cf4c269c24 100644 (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> {
index e311a50de1b520654a37bcade86c0eba370f9730..a18ea6ec2f00fa9f76cb575caebf7a6ab0ab8916 100644 (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>,
index a6e1da203721e5223ccfe5165f0d1561294bf329..05ced12ad481fbbde1adc0cd5f971b8b3263d047 100644 (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> {
index e7abc19b66bbf992538b221fb273d5185f0d9533..e20a2d9d07a7256066070e2f8fd54b2c0b3e009d 100644 (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() {
index 35c1d6e2c6149123fadfdaaf2c85f71276e8b702..d5ae71ec6be181a350c9582bc83c9825b8ff5efb 100644 (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;
index 2e77a31176ec4adbf7ed4d615bd0f3ec4d788a2c..084d60b8ca210339a17e77f45dd46c6db806b7f0 100644 (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).
 
index 91afb24869431d8a35f7db1c013771d503ef8a95..ca2ac0d5c8e5a499395eb38ccca47b0bb43fcde9 100644 (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 => {
index 281531156477f416ca9242e6322a95eed97608f9..12d153cc027cc6dff412945859b660ee6ad7fc51 100644 (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);
-                }
-            }
 
+        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(
@@ -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)
     }