From: Mark Thom Date: Sun, 20 Jan 2019 00:05:29 +0000 (-0700) Subject: clone in situ compiled terms X-Git-Tag: v0.8.110~294 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=ca7e62928b0367f50d58e4fab94e1bb3981819a7;p=scryer-prolog.git clone in situ compiled terms --- diff --git a/src/prolog/codegen.rs b/src/prolog/codegen.rs index 4846c728..66e94f1e 100644 --- a/src/prolog/codegen.rs +++ b/src/prolog/codegen.rs @@ -405,6 +405,46 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator evaluator.eval(term) } + fn compile_is_call(&mut self, terms: &'a Vec>, code: &mut Code, + term_loc: GenContext, use_default_call_policy: bool) + -> Result<(), ParserError> + { + let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?; + code.append(&mut acode); + + Ok(match terms[0].as_ref() { + &Term::Var(ref vr, ref name) => { + let mut target = Vec::new(); + + self.marker.reset_arg(2); + self.marker.mark_var(name.clone(), Level::Shallow, vr, + term_loc, &mut target); + + if !target.is_empty() { + code.push(Line::Query(target)); + } + + if use_default_call_policy { + code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1)))) + } else { + code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1)))) + } + }, + &Term::Constant(_, ref c @ Constant::Number(_)) => { + code.push(query![put_constant!(Level::Shallow, + c.clone(), + temp_v!(1))]); + + if use_default_call_policy { + code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1)))) + } else { + code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1)))) + } + }, + _ => code.push(fail!()) + }) + } + fn compile_seq(&mut self, iter: ChunkedIterator<'a>, conjunct_info: &ConjunctInfo<'a>, code: &mut Code, is_exposed: bool) -> Result<(), ParserError> @@ -441,47 +481,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator }), &QueryTerm::Clause(_, ClauseType::BuiltIn(BuiltInClauseType::Is(..)), ref terms, use_default_call_policy) - => - { - let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?; - code.append(&mut acode); - - match terms[0].as_ref() { - &Term::Var(ref vr, ref name) => { - let mut target = Vec::new(); - - self.marker.reset_arg(2); - self.marker.mark_var(name.clone(), Level::Shallow, vr, - term_loc, &mut target); - - if !target.is_empty() { - code.push(Line::Query(target)); - } - - if use_default_call_policy { - code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1)))); - } else { - code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1)))); - } - }, - &Term::Constant(_, ref c @ Constant::Number(_)) => { - code.push(query![put_constant!(Level::Shallow, - c.clone(), - temp_v!(1))]); - - if use_default_call_policy { - code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1)))); - } else { - code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1)))); - } - }, - _ => { - code.push(fail!()); - } - } - }, - &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => - try!(self.compile_inlined(ct, terms, term_loc, code)), + => self.compile_is_call(terms, code, term_loc, use_default_call_policy)?, + &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) + => self.compile_inlined(ct, terms, term_loc, code)?, _ => { let num_perm_vars = if chunk_num == 0 { conjunct_info.perm_vars() @@ -491,7 +493,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator self.compile_query_line(term, term_loc, code, num_perm_vars, is_exposed); }, - }; + } } self.marker.reset_contents(); @@ -518,7 +520,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator // add a proceed to bookend any trailing cuts. match toc { &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()), - &QueryTerm::Clause(_, ClauseType::Inlined(..), ..) => code.push(proceed!()), + &QueryTerm::Clause(_, ClauseType::Inlined(..), ..) => code.push(proceed!()), _ => {} }; diff --git a/src/prolog/compile.rs b/src/prolog/compile.rs index 89976ffe..6cd23f92 100644 --- a/src/prolog/compile.rs +++ b/src/prolog/compile.rs @@ -250,15 +250,15 @@ impl ListingCompiler { let arity = cl.arity(); cl.name().map(|name| (name, arity)) }).ok_or(SessionError::NamelessEntry)?; - + let non_counted_bt = self.non_counted_bt_preds.contains(&(name.clone(), arity)); - let p = code.len() + wam.code_size(); + let p = code.len() + wam.code_size(); let mut decl_code = compile_relation(&TopLevel::Predicate(decl), non_counted_bt, wam.machine_flags())?; compile_appendix(&mut decl_code, &queue, non_counted_bt, wam.machine_flags())?; - + let idx = code_dir.entry((name, arity)).or_insert(CodeIndex::default()); set_code_index!(idx, IndexPtr::Index(p), self.get_module_name()); @@ -489,7 +489,6 @@ fn setup_indices(wam: &mut Machine, indices: &mut IndexStore) -> Result<(), Sess pub fn compile_user_module(wam: &mut Machine, src: R) -> EvalSession { let mut indices = default_index_store!(wam.indices.atom_tbl.clone()); - try_eval_session!(setup_indices(wam, &mut indices)); - + try_eval_session!(setup_indices(wam, &mut indices)); compile_listing(wam, src, indices) } diff --git a/src/prolog/debray_allocator.rs b/src/prolog/debray_allocator.rs index e94b8fc6..9efb17e6 100644 --- a/src/prolog/debray_allocator.rs +++ b/src/prolog/debray_allocator.rs @@ -231,15 +231,15 @@ impl<'a> Allocator<'a> for DebrayAllocator where Target: CompilationTarget<'a> { let r = cell.get(); - + let r = match lvl { Level::Shallow => { let k = self.arg_c; - + if let GenContext::Last(chunk_num) = term_loc { self.evacuate_arg(chunk_num, target); } - + self.arg_c += 1; RegType::Temp(k) }, @@ -247,7 +247,7 @@ impl<'a> Allocator<'a> for DebrayAllocator _ => r }; - cell.set(r); + cell.set(r); } fn mark_var(&mut self, var: Rc, lvl: Level, cell: &'a Cell, @@ -258,15 +258,14 @@ impl<'a> Allocator<'a> for DebrayAllocator RegType::Temp(0) => { // here, r is temporary *and* unassigned. let o = self.alloc_reg_to_var(&var, lvl, term_loc, target); - cell.set(VarReg::Norm(RegType::Temp(o))); - + (RegType::Temp(o), true) }, RegType::Perm(0) => { let pr = cell.get().norm(); self.record_register(var.clone(), pr); - + (pr, true) }, r => (r, false) diff --git a/src/prolog/fixtures.rs b/src/prolog/fixtures.rs index ffdf8da5..1cbcd713 100644 --- a/src/prolog/fixtures.rs +++ b/src/prolog/fixtures.rs @@ -109,8 +109,8 @@ impl<'a> VariableFixtures<'a> var_count } - pub fn mark_vars_in_chunk(&mut self, iter: Iter, lt_arity: usize, term_loc: GenContext) - where Iter: Iterator> + pub fn mark_vars_in_chunk(&mut self, iter: I, lt_arity: usize, term_loc: GenContext) + where I: Iterator> { let chunk_num = term_loc.chunk_num(); let mut arg_c = 1; diff --git a/src/prolog/instructions.rs b/src/prolog/instructions.rs index 9a84037c..bd5e2f2c 100644 --- a/src/prolog/instructions.rs +++ b/src/prolog/instructions.rs @@ -140,7 +140,7 @@ impl QueryTerm { match self { &mut QueryTerm::Clause(_, _, _, ref mut use_default_cp) => *use_default_cp = true, _ => {} - }; + } } pub fn arity(&self) -> usize { @@ -1140,7 +1140,7 @@ impl Module { { let ge = code_repo.term_dir.entry((clause_name!("goal_expansion"), 2)) .or_insert((Predicate::new(), VecDeque::from(vec![]))); - + (ge.0).0.extend((self.goal_expansions.0).0.iter().cloned()); ge.1.extend(self.goal_expansions.1.iter().cloned()); } diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index 4f35ac65..1260f642 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -1,12 +1,12 @@ :- op(400, yfx, /). -:- module(builtins, [(=)/2, (+)/2, (**)/2, (*)/2, (-)/2, (/)/2, - (/\)/2, (\/)/2, (is)/2, (xor)/2, (div)/2, (//)/2, (rdiv)/2, - (<<)/2, (>>)/2, (mod)/2, (rem)/2, (>)/2, (<)/2, (=\=)/2, - (=:=)/2, (-)/1, (>=)/2, (=<)/2, (,)/2, (->)/2, (;)/2, (=..)/2, - (==)/2, (\==)/2, (@=<)/2, (@>=)/2, (@<)/2, (@>)/2, (=@=)/2, - (\=@=)/2, (:)/2, call_with_inference_limit/3, catch/3, - current_prolog_flag/2, expand_goal/2, expand_term/2, +:- module(builtins, [(=)/2, (+)/1, (+)/2, (**)/2, (*)/2, (-)/1, (-)/2, + (/)/2, (/\)/2, (\/)/2, (is)/2, (xor)/2, (div)/2, (//)/2, + (rdiv)/2, (<<)/2, (>>)/2, (mod)/2, (rem)/2, (>)/2, (<)/2, + (=\=)/2, (=:=)/2, (-)/1, (>=)/2, (=<)/2, (,)/2, (->)/2, (;)/2, + (=..)/2, (==)/2, (\==)/2, (@=<)/2, (@>=)/2, (@<)/2, (@>)/2, + (=@=)/2, (\=@=)/2, (:)/2, call_with_inference_limit/3, + catch/3, current_prolog_flag/2, expand_goal/2, expand_term/2, set_prolog_flag/2, setup_call_cleanup/3, term_variables/2, throw/1, true/0, false/0, write/1, write_canonical/1, writeq/1, write_term/2]). @@ -34,7 +34,7 @@ expand_op_list([Op | OtherOps], Pred, Spec, [(:- op(Pred, Spec, Op)) | OtherResu :- op(500, yfx, [/\, \/, xor]). :- op(400, yfx, [div, //, rdiv]). :- op(400, yfx, [<<, >>, mod, rem]). -:- op(200, fy, -). +:- op(200, fy, [+, -]). % arithmetic comparison operators. :- op(700, xfx, [>, <, =\=, =:=, >=, =<]). diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index e7366ac0..376d588b 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -268,8 +268,7 @@ impl MachineState { } } -fn try_in_situ_lookup(name: ClauseName, arity: usize, indices: &IndexStore) - -> Option +fn try_in_situ_lookup(name: ClauseName, arity: usize, indices: &IndexStore) -> Option { match indices.in_situ_code_dir.get(&(name.clone(), arity)) { Some(p) => Some(*p), diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 3da31e29..cc3e0b06 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -149,14 +149,15 @@ impl CodeRepo { cl.name().map(|name| (name, arity)) }).ok_or(SessionError::NamelessEntry)?; - let p = self.in_situ_code.len(); + let p = self.in_situ_code.len(); in_situ_code_dir.insert((name, arity), p); let mut cg = CodeGenerator::::new(true, flags); - let mut decl_code = cg.compile_predicate(&decl.0)?; - + // clone the decl to avoid the need to wipe its register cells later. + let mut decl_code = cg.compile_predicate(&decl.0.clone())?; + compile_appendix(&mut decl_code, queue, true, flags)?; - + self.in_situ_code.extend(decl_code.into_iter()); Ok(()) } diff --git a/src/prolog/machine/term_expansion.rs b/src/prolog/machine/term_expansion.rs index 19d15760..e6fe4244 100644 --- a/src/prolog/machine/term_expansion.rs +++ b/src/prolog/machine/term_expansion.rs @@ -104,7 +104,7 @@ impl ExpansionAdditionResult { impl<'a, R: Read> Drop for TermStream<'a, R> { fn drop(&mut self) { self.indices.in_situ_code_dir.clear(); - self.code_repo.in_situ_code.clear(); + self.code_repo.in_situ_code.clear(); discard_result!(self.rollback_expansion_code()); } } @@ -322,7 +322,6 @@ impl MachineState { }; output.push_char('.'); - self.reset(); Some(output.result()) } diff --git a/src/prolog/toplevel.rs b/src/prolog/toplevel.rs index eed2c01a..ee1fe25f 100644 --- a/src/prolog/toplevel.rs +++ b/src/prolog/toplevel.rs @@ -487,12 +487,12 @@ impl RelationWorker { fn to_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result { match term { - Term::Constant(r, Constant::Atom(name, fixity)) => + Term::Constant(_, Constant::Atom(name, fixity)) => if name.as_str() == "!" || name.as_str() == "blocked_!" { Ok(QueryTerm::BlockedCut) } else { let ct = indices.get_clause_type(name, 0, fixity); - Ok(QueryTerm::Clause(r, ct, vec![], false)) + Ok(QueryTerm::Clause(Cell::default(), ct, vec![], false)) }, Term::Var(_, ref v) if v.as_str() == "!" => Ok(QueryTerm::UnblockedCut(Cell::default())),