From: Mark Thom Date: Mon, 1 May 2017 20:22:32 +0000 (-0600) Subject: refine *_void emission" X-Git-Tag: v0.8.110~736 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=9687878219a74c856df281a600904263d0e7f0f4;p=scryer-prolog.git refine *_void emission" --- diff --git a/src/prolog/codegen.rs b/src/prolog/codegen.rs index d08307d5..1dbbb439 100644 --- a/src/prolog/codegen.rs +++ b/src/prolog/codegen.rs @@ -96,30 +96,17 @@ impl<'a> CodeGenerator<'a> { Target::clause_arg_to_instr(cell.get()) } - fn flatten_void_instrs(target: Vec) -> Vec + fn add_or_increment_void_instr(target: &mut Vec) where Target: CompilationTarget<'a> - { - let mut compressed_target = Vec::new(); - let mut void_count = 0; - - for term in target.into_iter() { - if Target::is_void_instr(&term) { - void_count += 1; - } else { - if void_count > 0 { - compressed_target.push(Target::to_void(void_count)); - void_count = 0; - } - - compressed_target.push(term); + { + if let Some(ref mut instr) = target.last_mut() { + if Target::is_void_instr(&*instr) { + Target::incr_void_instr(instr); + return; } } - if void_count > 0 { - compressed_target.push(Target::to_void(void_count)); - } - - compressed_target + target.push(Target::to_void(1)); } fn subterm_to_instr(&mut self, @@ -133,7 +120,7 @@ impl<'a> CodeGenerator<'a> { &Term::AnonVar if is_exposed => self.marker.mark_anon_var(Level::Deep, target), &Term::AnonVar => - target.push(Target::to_void(1)), + Self::add_or_increment_void_instr(target), &Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _) => { let instr = self.non_var_subterm(Level::Deep, term_loc, cell, target); target.push(instr); @@ -144,7 +131,7 @@ impl<'a> CodeGenerator<'a> { if is_exposed || self.get_var_count(var) > 1 { self.marker.mark_var(var, Level::Deep, cell, term_loc, target); } else { - target.push(Target::to_void(1)); + Self::add_or_increment_void_instr(target); } }; } @@ -195,7 +182,7 @@ impl<'a> CodeGenerator<'a> { }; } - Self::flatten_void_instrs(target) + target } fn collect_var_data(&mut self, iter: ChunkedIterator<'a>) -> (VariableFixtures<'a>, bool) diff --git a/src/prolog/targets.rs b/src/prolog/targets.rs index 002bcbf1..1bcfeb83 100644 --- a/src/prolog/targets.rs +++ b/src/prolog/targets.rs @@ -9,9 +9,10 @@ pub trait CompilationTarget<'a> { fn to_constant(Level, Constant, RegType) -> Self; fn to_list(Level, RegType) -> Self; fn to_structure(Level, Atom, usize, RegType) -> Self; + fn to_void(usize) -> Self; - fn is_void_instr(&self) -> bool; + fn incr_void_instr(&mut self); fn constant_subterm(Constant) -> Self; @@ -56,6 +57,13 @@ impl<'a> CompilationTarget<'a> for FactInstruction { } } + fn incr_void_instr(&mut self) { + match self { + &mut FactInstruction::UnifyVoid(ref mut incr) => *incr += 1, + _ => {} + } + } + fn constant_subterm(constant: Constant) -> Self { FactInstruction::UnifyConstant(constant) } @@ -114,6 +122,13 @@ impl<'a> CompilationTarget<'a> for QueryInstruction { _ => false } } + + fn incr_void_instr(&mut self) { + match self { + &mut QueryInstruction::SetVoid(ref mut incr) => *incr += 1, + _ => {} + } + } fn constant_subterm(constant: Constant) -> Self { QueryInstruction::SetConstant(constant)