From b9c9de522256f7ec2b56fd8c5e0348153fbb53b0 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 4 Oct 2022 09:24:37 -0600 Subject: [PATCH] add classifications and occurrence counting --- src/allocator.rs | 11 ++-- src/arithmetic.rs | 11 ++-- src/codegen.rs | 19 +++--- src/debray_allocator.rs | 25 ++++---- src/fixtures.rs | 21 +++---- src/forms.rs | 5 +- src/heap_print.rs | 24 ++++--- src/iterators.rs | 110 ++++++++++++++------------------- src/machine/loader.rs | 4 +- src/machine/machine_indices.rs | 5 +- src/machine/machine_state.rs | 13 ++-- src/machine/preprocessor.rs | 7 +-- src/machine/system_calls.rs | 3 +- src/parser/ast.rs | 40 +++++++++++- src/parser/parser.rs | 3 +- 15 files changed, 153 insertions(+), 148 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index 5be3aae1..76bdfb53 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -8,7 +8,6 @@ use crate::machine::machine_indices::*; use crate::targets::*; use std::cell::Cell; -use std::rc::Rc; pub(crate) trait Allocator { fn new() -> Self; @@ -30,7 +29,7 @@ pub(crate) trait Allocator { fn mark_reserved_var<'a, Target: CompilationTarget<'a>>( &mut self, - var_name: Rc, + var_name: Var, lvl: Level, cell: &'a Cell, term_loc: GenContext, @@ -41,7 +40,7 @@ pub(crate) trait Allocator { fn mark_var<'a, Target: CompilationTarget<'a>>( &mut self, - var_name: Rc, + var_name: Var, lvl: Level, cell: &'a Cell, context: GenContext, @@ -88,17 +87,17 @@ pub(crate) trait Allocator { perm_vs } - fn get(&self, var: Rc) -> RegType { + fn get(&self, var: Var) -> RegType { self.bindings() .get(&var) .map_or(temp_v!(0), |v| v.as_reg_type()) } - fn is_unbound(&self, var: Rc) -> bool { + fn is_unbound(&self, var: Var) -> bool { self.get(var).reg_num() == 0 } - fn record_register(&mut self, var: Rc, r: RegType) { + fn record_register(&mut self, var: Var, r: RegType) { match self.bindings_mut().get_mut(&var).unwrap() { &mut VarData::Temp(_, ref mut s, _) => *s = r.reg_num(), &mut VarData::Perm(ref mut s) => *s = r.reg_num(), diff --git a/src/arithmetic.rs b/src/arithmetic.rs index fcfd9599..94974a51 100644 --- a/src/arithmetic.rs +++ b/src/arithmetic.rs @@ -22,7 +22,6 @@ use std::convert::TryFrom; use std::f64; use std::num::FpCategory; use std::ops::Div; -use std::rc::Rc; use std::vec::Vec; #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -74,7 +73,7 @@ impl<'a> ArithInstructionIterator<'a> { 2, )) } - Term::Var(cell, var) => TermIterState::Var(Level::Shallow, cell, RcMutPtr::new(var)), + Term::Var(cell, var) => TermIterState::Var(Level::Shallow, cell, VarPtr::from(var)), }; Ok(ArithInstructionIterator { @@ -87,7 +86,7 @@ impl<'a> ArithInstructionIterator<'a> { pub(crate) enum ArithTermRef<'a> { Literal(&'a Literal), Op(Atom, usize), // name, arity. - Var(Level, &'a Cell, Rc), + Var(Level, &'a Cell, Var), } impl<'a> Iterator for ArithInstructionIterator<'a> { @@ -115,8 +114,8 @@ impl<'a> Iterator for ArithInstructionIterator<'a> { } } TermIterState::Literal(_, _, c) => return Some(Ok(ArithTermRef::Literal(c))), - TermIterState::Var(lvl, cell, var) => { - return Some(Ok(ArithTermRef::Var(lvl, cell, var.owned()))); + TermIterState::Var(lvl, cell, var_ref) => { + return Some(Ok(ArithTermRef::Var(lvl, cell, Var::from(var_ref)))); } _ => { return Some(Err(ArithmeticError::NonEvaluableFunctor( @@ -317,7 +316,7 @@ impl<'a> ArithmeticEvaluator<'a> { ArithTermRef::Var(lvl, cell, name) => { let r = if lvl == Level::Shallow { self.marker.mark_non_callable( - name.clone(), + name, arg, term_loc, cell, diff --git a/src/codegen.rs b/src/codegen.rs index 1aea58d2..a3fdc99b 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -20,7 +20,6 @@ use indexmap::{IndexMap, IndexSet}; use std::cell::Cell; use std::collections::VecDeque; -use std::rc::Rc; #[derive(Debug)] pub(crate) struct ConjunctInfo<'a> { @@ -170,7 +169,7 @@ impl CodeGenSettings { pub(crate) struct CodeGenerator<'a> { pub(crate) atom_tbl: &'a mut AtomTable, marker: DebrayAllocator, - pub(crate) var_count: IndexMap, usize>, + pub(crate) var_count: IndexMap, settings: CodeGenSettings, pub(crate) skeleton: PredicateSkeleton, pub(crate) jmp_by_locs: Vec, @@ -180,7 +179,7 @@ pub(crate) struct CodeGenerator<'a> { impl DebrayAllocator { fn mark_var_in_non_callable( &mut self, - name: Rc, + name: Var, term_loc: GenContext, vr: &Cell, code: &mut Code, @@ -190,7 +189,7 @@ impl DebrayAllocator { } #[inline(always)] - pub(crate) fn get_binding(&self, name: &String) -> Option { + pub(crate) fn get_binding(&self, name: &Var) -> Option { match self.bindings().get(name) { Some(&VarData::Temp(_, t, _)) if t != 0 => Some(RegType::Temp(t)), Some(&VarData::Perm(p)) if p != 0 => Some(RegType::Perm(p)), @@ -200,7 +199,7 @@ impl DebrayAllocator { pub(crate) fn mark_non_callable( &mut self, - name: Rc, + name: Var, arg: usize, term_loc: GenContext, vr: &Cell, @@ -299,7 +298,7 @@ impl<'b> CodeGenerator<'b> { } } - fn get_var_count(&self, var: &String) -> usize { + fn get_var_count(&self, var: &Var) -> usize { *self.var_count.get(var).unwrap() } @@ -320,7 +319,7 @@ impl<'b> CodeGenerator<'b> { fn deep_var_instr<'a, Target: crate::targets::CompilationTarget<'a>>( &mut self, cell: &'a Cell, - var: &Rc, + var: &Var, term_loc: GenContext, target: &mut Code, ) { @@ -429,7 +428,7 @@ impl<'b> CodeGenerator<'b> { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); target.push(Target::to_pstr(lvl, atom, cell.get(), false)); } - TermRef::Var(lvl @ Level::Shallow, cell, ref var) if var.as_str() == "!" => { + TermRef::Var(lvl @ Level::Shallow, cell, var) if var.as_str() == Some("!") => { if self.marker.is_unbound(var.clone()) { if term_loc != GenContext::Head { self.marker.mark_reserved_var::( @@ -835,7 +834,7 @@ impl<'b> CodeGenerator<'b> { #[inline] fn compile_unblocked_cut(&mut self, code: &mut Code, cell: &Cell) { - let r = self.marker.get(Rc::new(String::from("!"))); + let r = self.marker.get(Var::from("!")); cell.set(VarReg::Norm(r)); code.push(instr!("$set_cp", cell.get().norm(), 0)); } @@ -844,7 +843,7 @@ impl<'b> CodeGenerator<'b> { &mut self, code: &mut Code, cell: &Cell, - var: Rc, + var: Var, term_loc: GenContext, ) { let mut target = Code::new(); diff --git a/src/debray_allocator.rs b/src/debray_allocator.rs index e9cc73c7..73645929 100644 --- a/src/debray_allocator.rs +++ b/src/debray_allocator.rs @@ -14,28 +14,27 @@ use fxhash::FxBuildHasher; use std::cell::Cell; use std::collections::BTreeSet; -use std::rc::Rc; #[derive(Debug)] pub(crate) struct DebrayAllocator { - bindings: IndexMap, VarData, FxBuildHasher>, + bindings: IndexMap, arg_c: usize, temp_lb: usize, arity: usize, // 0 if not at head. - contents: IndexMap, FxBuildHasher>, + contents: IndexMap, in_use: BTreeSet, free_list: Vec, } impl DebrayAllocator { - fn is_curr_arg_distinct_from(&self, var: &String) -> bool { + fn is_curr_arg_distinct_from(&self, var: &Var) -> bool { match self.contents.get(&self.arg_c) { - Some(t_var) if **t_var != *var => true, + Some(t_var) if *t_var != *var => true, _ => false, } } - fn occurs_shallowly_in_head(&self, var: &String, r: usize) -> bool { + fn occurs_shallowly_in_head(&self, var: &Var, r: usize) -> bool { match self.bindings.get(var).unwrap() { &VarData::Temp(_, _, ref tvd) => tvd.use_set.contains(&(GenContext::Head, r)), _ => false, @@ -48,7 +47,7 @@ impl DebrayAllocator { in_use_range || self.in_use.contains(&r) } - fn alloc_with_cr(&self, var: &String) -> usize { + fn alloc_with_cr(&self, var: &Var) -> usize { match self.bindings.get(var) { Some(&VarData::Temp(_, _, ref tvd)) => { for &(_, reg) in tvd.use_set.iter() { @@ -74,7 +73,7 @@ impl DebrayAllocator { } } - fn alloc_with_ca(&self, var: &String) -> usize { + fn alloc_with_ca(&self, var: &Var) -> usize { match self.bindings.get(var) { Some(&VarData::Temp(_, _, ref tvd)) => { for &(_, reg) in tvd.use_set.iter() { @@ -102,7 +101,7 @@ impl DebrayAllocator { } } - fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Rc, usize)> { + fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Var, usize)> { // we want to allocate a register to the k^{th} parameter, par_k. // par_k may not be a temporary variable. let k = self.arg_c; @@ -154,7 +153,7 @@ impl DebrayAllocator { fn alloc_reg_to_var<'a, Target: CompilationTarget<'a>>( &mut self, - var: &String, + var: &Var, lvl: Level, term_loc: GenContext, target: &mut Vec, @@ -202,7 +201,7 @@ impl DebrayAllocator { final_index } - fn in_place(&self, var: &String, term_loc: GenContext, r: RegType, k: usize) -> bool { + fn in_place(&self, var: &Var, term_loc: GenContext, r: RegType, k: usize) -> bool { match term_loc { GenContext::Head if !r.is_perm() => r.reg_num() == k, _ => match self.bindings().get(var).unwrap() { @@ -293,7 +292,7 @@ impl Allocator for DebrayAllocator { fn mark_var<'a, Target: CompilationTarget<'a>>( &mut self, - var: Rc, + var: Var, lvl: Level, cell: &'a Cell, term_loc: GenContext, @@ -321,7 +320,7 @@ impl Allocator for DebrayAllocator { fn mark_reserved_var<'a, Target: CompilationTarget<'a>>( &mut self, - var: Rc, + var: Var, lvl: Level, cell: &'a Cell, term_loc: GenContext, diff --git a/src/fixtures.rs b/src/fixtures.rs index 65340da0..1433b092 100644 --- a/src/fixtures.rs +++ b/src/fixtures.rs @@ -9,7 +9,6 @@ use indexmap::{IndexMap, IndexSet}; use std::cell::Cell; use std::collections::BTreeSet; use std::mem::swap; -use std::rc::Rc; use std::vec::Vec; // labeled with chunk numbers. @@ -84,8 +83,8 @@ type VariableFixture<'a> = (VarStatus, Vec<&'a Cell>); #[derive(Debug)] pub(crate) struct VariableFixtures<'a> { - perm_vars: IndexMap, VariableFixture<'a>>, - last_chunk_temp_vars: IndexSet>, + perm_vars: IndexMap>, + last_chunk_temp_vars: IndexSet, } impl<'a> VariableFixtures<'a> { @@ -96,11 +95,11 @@ impl<'a> VariableFixtures<'a> { } } - pub(crate) fn insert(&mut self, var: Rc, vs: VariableFixture<'a>) { + pub(crate) fn insert(&mut self, var: Var, vs: VariableFixture<'a>) { self.perm_vars.insert(var, vs); } - pub(crate) fn insert_last_chunk_temp_var(&mut self, var: Rc) { + pub(crate) fn insert_last_chunk_temp_var(&mut self, var: Var) { self.last_chunk_temp_vars.insert(var); } @@ -115,7 +114,7 @@ impl<'a> VariableFixtures<'a> { // Compute the conflict set of u. // 1. - let mut use_sets: IndexMap, OccurrenceSet> = IndexMap::new(); + let mut use_sets: IndexMap = IndexMap::new(); for (var, &mut (ref mut var_status, _)) in self.iter_mut() { if let &mut VarStatus::Temp(_, ref mut var_data) = var_status { @@ -132,7 +131,7 @@ impl<'a> VariableFixtures<'a> { if let GenContext::Last(cn_u) = term_loc { for (ref t, &mut (ref mut var_status, _)) in self.iter_mut() { if let &mut VarStatus::Temp(cn_t, ref mut t_data) = var_status { - if cn_u == cn_t && *u != ***t { + if cn_u == cn_t && u != **t { if !t_data.uses_reg(reg) { t_data.no_use_set.insert(reg); } @@ -153,11 +152,11 @@ impl<'a> VariableFixtures<'a> { } } - fn get_mut(&mut self, u: Rc) -> Option<&mut VariableFixture<'a>> { + fn get_mut(&mut self, u: Var) -> Option<&mut VariableFixture<'a>> { self.perm_vars.get_mut(&u) } - fn iter_mut(&mut self) -> indexmap::map::IterMut, VariableFixture<'a>> { + fn iter_mut(&mut self) -> indexmap::map::IterMut> { self.perm_vars.iter_mut() } @@ -218,11 +217,11 @@ impl<'a> VariableFixtures<'a> { } } - pub(crate) fn into_iter(self) -> indexmap::map::IntoIter, VariableFixture<'a>> { + pub(crate) fn into_iter(self) -> indexmap::map::IntoIter> { self.perm_vars.into_iter() } - fn values(&self) -> indexmap::map::Values, VariableFixture<'a>> { + fn values(&self) -> indexmap::map::Values> { self.perm_vars.values() } diff --git a/src/forms.rs b/src/forms.rs index 1c014587..9db69581 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -21,7 +21,6 @@ use std::convert::TryFrom; use std::fmt; use std::ops::AddAssign; use std::path::PathBuf; -use std::rc::Rc; use crate::{is_infix, is_postfix}; @@ -85,8 +84,8 @@ pub enum QueryTerm { Clause(Cell, ClauseType, Vec, CallPolicy), BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q. UnblockedCut(Cell), - GetLevelAndUnify(Cell, Rc), - Jump(JumpStub), + GetLevelAndUnify(Cell, Var), + Jump(JumpStub), // SOON: Branch(Vec), } impl QueryTerm { diff --git a/src/heap_print.rs b/src/heap_print.rs index 54f52cd6..d09211d1 100644 --- a/src/heap_print.rs +++ b/src/heap_print.rs @@ -472,7 +472,7 @@ pub struct HCPrinter<'a, Outputter> { state_stack: Vec, toplevel_spec: Option, last_item_idx: usize, - pub var_names: IndexMap>, + pub var_names: IndexMap, pub numbervars_offset: Integer, pub numbervars: bool, pub quoted: bool, @@ -803,7 +803,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { if let Some(var) = self.var_names.get(&addr) { read_heap_cell!(addr, (HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => { - return Some(format!("{}", var.as_str())); + return Some(var.to_string()); } _ => { self.iter.push_stack(h); @@ -847,10 +847,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { // short-circuits handle_heap_term. // self.iter.pop_stack(); - let var_str = var.as_str(); + let var_str = var.to_string(); - push_space_if_amb!(self, var_str, { - append_str!(self, var_str); + push_space_if_amb!(self, &var_str, { + append_str!(self, &var_str); }); None @@ -862,8 +862,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { Some(var) => { // If the term is bound to a named variable, // print the variable's name to output. - push_space_if_amb!(self, &var, { - append_str!(self, &var); + let var_str = var.to_string(); + + push_space_if_amb!(self, &var_str, { + append_str!(self, &var_str); }); } None => { @@ -1715,9 +1717,7 @@ mod tests { heap_loc_as_cell!(0) ); - printer - .var_names - .insert(list_loc_as_cell!(1), Rc::new("L".to_string())); + printer.var_names.insert(list_loc_as_cell!(1), Var::from("L")); let output = printer.print(); @@ -1778,9 +1778,7 @@ mod tests { heap_loc_as_cell!(0) ); - printer - .var_names - .insert(list_loc_as_cell!(1), Rc::new("L".to_string())); + printer.var_names.insert(list_loc_as_cell!(1), Var::from("L")); let output = printer.print(); diff --git a/src/iterators.rs b/src/iterators.rs index 6bf92a5f..ac87a451 100644 --- a/src/iterators.rs +++ b/src/iterators.rs @@ -7,11 +7,40 @@ use std::cell::Cell; use std::collections::VecDeque; use std::fmt; use std::fmt::Debug; -use std::hash::{Hash, Hasher}; +use std::hash::{Hash}; use std::iter::*; -use std::rc::Rc; use std::vec::Vec; +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub(crate) struct VarPtr { + ptr: std::ptr::NonNull, +} + +impl From<&Var> for VarPtr { + #[inline] + fn from(value: &Var) -> VarPtr { + unsafe { + VarPtr { ptr: std::ptr::NonNull::new_unchecked(value as *const _ as *mut _) } + } + } +} + +impl From for Var { + #[inline] + fn from(value: VarPtr) -> Var { + unsafe { + (*value.ptr.as_ptr()).clone() + } + } +} + +impl VarPtr { + pub(crate) fn set(&mut self, value: Var) { + unsafe { *self.ptr.as_mut() = value; } + } +} + + #[derive(Debug, Clone)] pub(crate) enum TermRef<'a> { AnonVar(Level), @@ -20,7 +49,7 @@ pub(crate) enum TermRef<'a> { Clause(Level, &'a Cell, Atom, &'a Vec), PartialString(Level, &'a Cell, &'a String, &'a Box), CompleteString(Level, &'a Cell, Atom), - Var(Level, &'a Cell, Rc), + Var(Level, &'a Cell, Var), } impl<'a> TermRef<'a> { @@ -37,58 +66,6 @@ impl<'a> TermRef<'a> { } } -#[derive(Clone, Debug)] -pub(crate) struct RcMutPtr { - owned: Rc, - ptr: *mut Rc, -} - -impl RcMutPtr { - #[inline] - pub(crate) fn new(rc: &Rc) -> Self { - Self { owned: rc.clone(), ptr: rc as *const _ as *mut _ } - } - - #[inline] - pub(crate) fn owned(&self) -> Rc { - self.owned.clone() - } - - #[inline] - pub(crate) fn set(&mut self, var_b_marker: &Rc) { - self.owned = var_b_marker.clone(); - - unsafe { - if !self.ptr.is_null() { - *self.ptr = self.owned.clone(); - } - } - } -} - -impl From for RcMutPtr { - #[inline] - fn from(value: T) -> RcMutPtr { - let owned = Rc::new(value); - RcMutPtr { owned, ptr: std::ptr::null_mut() } - } -} - -impl PartialEq for RcMutPtr { - fn eq(&self, rhs: &Self) -> bool { - &self.owned == &rhs.owned - } -} - -impl Eq for RcMutPtr {} - -impl Hash for RcMutPtr { - #[inline(always)] - fn hash(&self, hasher: &mut H) { - self.owned.hash(hasher) - } -} - #[derive(Debug)] pub(crate) enum TermIterState<'a> { AnonVar(Level), @@ -99,7 +76,8 @@ pub(crate) enum TermIterState<'a> { InitialPartialString(Level, &'a Cell, &'a String, &'a Box), FinalPartialString(Level, &'a Cell, &'a String, &'a Box), CompleteString(Level, &'a Cell, Atom), - Var(Level, &'a Cell, RcMutPtr), + UnblockedCut(Level, &'a Cell), + Var(Level, &'a Cell, VarPtr), } impl<'a> TermIterState<'a> { @@ -119,7 +97,7 @@ impl<'a> TermIterState<'a> { Term::CompleteString(cell, atom) => { TermIterState::CompleteString(lvl, cell, *atom) } - Term::Var(cell, var) => TermIterState::Var(lvl, cell, RcMutPtr::new(var)), + Term::Var(cell, var) => TermIterState::Var(lvl, cell, VarPtr::from(var)), } } } @@ -160,7 +138,7 @@ impl<'a> QueryIterator<'a> { *name, terms, ), - Term::Var(cell, var) => TermIterState::Var(Level::Root, cell, RcMutPtr::new(var)), + Term::Var(cell, var) => TermIterState::Var(Level::Root, cell, VarPtr::from(var)), }; QueryIterator { @@ -183,13 +161,14 @@ impl<'a> QueryIterator<'a> { } } &QueryTerm::UnblockedCut(ref cell) => { - let state = TermIterState::Var(Level::Root, cell, RcMutPtr::from("!".to_string())); + let state = TermIterState::UnblockedCut(Level::Root, cell); + QueryIterator { state_stack: vec![state], } } &QueryTerm::GetLevelAndUnify(ref cell, ref var) => { - let state = TermIterState::Var(Level::Root, cell, RcMutPtr::new(var)); + let state = TermIterState::Var(Level::Root, cell, VarPtr::from(var)); QueryIterator { state_stack: vec![state], } @@ -267,7 +246,10 @@ impl<'a> Iterator for QueryIterator<'a> { return Some(TermRef::Literal(lvl, cell, constant)); } TermIterState::Var(lvl, cell, var) => { - return Some(TermRef::Var(lvl, cell, var.owned())); + return Some(TermRef::Var(lvl, cell, Var::from(var))); + } + TermIterState::UnblockedCut(lvl, cell) => { + return Some(TermRef::Var(lvl, cell, Var::from("!"))); } }; } @@ -333,7 +315,7 @@ impl<'a> FactIterator<'a> { vec![TermIterState::Literal(Level::Root, cell, constant)] } Term::Var(cell, var) => { - vec![TermIterState::Var(Level::Root, cell, RcMutPtr::new(var))] + vec![TermIterState::Var(Level::Root, cell, VarPtr::from(var))] } }; @@ -380,7 +362,7 @@ impl<'a> Iterator for FactIterator<'a> { return Some(TermRef::Literal(lvl, cell, constant)) } TermIterState::Var(lvl, cell, var) => { - return Some(TermRef::Var(lvl, cell, var.owned())); + return Some(TermRef::Var(lvl, cell, Var::from(var))); } _ => {} } @@ -420,7 +402,7 @@ impl<'a> ChunkedTerm<'a> { fn contains_cut_var<'a, Iter: Iterator>(terms: Iter) -> bool { for term in terms { if let &Term::Var(_, ref var) = term { - if var.as_str() == "!" { + if var.as_str() == Some("!") { return true; } } diff --git a/src/machine/loader.rs b/src/machine/loader.rs index f268c0f7..bb093a0e 100644 --- a/src/machine/loader.rs +++ b/src/machine/loader.rs @@ -21,7 +21,6 @@ use std::convert::TryFrom; use std::fmt; use std::mem; use std::ops::{Deref, DerefMut}; -use std::rc::Rc; /* * The loader compiles Prolog terms read from a TermStream instance, @@ -1429,8 +1428,7 @@ impl MachineState { } } (HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar, h) => { - let offset_string = format!("_{}", h); - term_stack.push(Term::Var(Cell::default(), Rc::new(offset_string))); + term_stack.push(Term::Var(Cell::default(), Var::Generated(h))); } (HeapCellValueTag::Cons | HeapCellValueTag::CStr | HeapCellValueTag::Fixnum | HeapCellValueTag::Char | HeapCellValueTag::F64) => { diff --git a/src/machine/machine_indices.rs b/src/machine/machine_indices.rs index 11a9d6e8..3f49e1ce 100644 --- a/src/machine/machine_indices.rs +++ b/src/machine/machine_indices.rs @@ -16,7 +16,6 @@ use modular_bitfield::specifiers::*; use std::cmp::Ordering; use std::collections::BTreeSet; use std::ops::{Deref, DerefMut}; -use std::rc::Rc; use crate::types::*; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -228,8 +227,8 @@ impl CodeIndex { } } -pub(crate) type HeapVarDict = IndexMap, HeapCellValue, FxBuildHasher>; -pub(crate) type AllocVarDict = IndexMap, VarData, FxBuildHasher>; +pub(crate) type HeapVarDict = IndexMap; +pub(crate) type AllocVarDict = IndexMap; pub(crate) type GlobalVarDir = IndexMap), FxBuildHasher>; diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index bdaf048c..6d0de7d9 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -21,7 +21,6 @@ use indexmap::IndexMap; use std::convert::TryFrom; use std::fmt; use std::ops::{Index, IndexMut}; -use std::rc::Rc; pub(crate) type Registers = [HeapCellValue; MAX_ARITY + 1]; @@ -501,13 +500,13 @@ impl MachineState { pub fn read_term(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult { fn push_var_eq_functors<'a>( heap: &mut Heap, - iter: impl Iterator, &'a HeapCellValue)>, + iter: impl Iterator, atom_tbl: &mut AtomTable, ) -> Vec { let mut list_of_var_eqs = vec![]; for (var, binding) in iter { - let var_atom = atom_tbl.build_with(&var); + let var_atom = atom_tbl.build_with(&var.to_string()); let h = heap.len(); heap.push(atom_as_cell!(atom!("="), 2)); @@ -673,7 +672,7 @@ impl MachineState { let printer = match self.try_from_list(self.registers[6], stub_gen) { Ok(addrs) => { - let mut var_names: IndexMap> = IndexMap::new(); + let mut var_names: IndexMap = IndexMap::new(); for addr in addrs { read_heap_cell!(addr, @@ -691,18 +690,18 @@ impl MachineState { read_heap_cell!(atom, (HeapCellValueTag::Char, c) => { - var_names.insert(var, Rc::new(c.to_string())); + var_names.insert(var, Var::from(c.to_string())); } (HeapCellValueTag::Atom, (name, _arity)) => { debug_assert_eq!(_arity, 0); - var_names.insert(var, Rc::new(name.as_str().to_owned())); + var_names.insert(var, Var::from(name.as_str())); } (HeapCellValueTag::Str, s) => { let (name, arity) = cell_as_atom_cell!(self.heap[s]) .get_name_and_arity(); debug_assert_eq!(arity, 0); - var_names.insert(var, Rc::new(name.as_str().to_owned())); + var_names.insert(var, Var::from(name.as_str())); } _ => { unreachable!(); diff --git a/src/machine/preprocessor.rs b/src/machine/preprocessor.rs index 7f0cc264..d2c33b06 100644 --- a/src/machine/preprocessor.rs +++ b/src/machine/preprocessor.rs @@ -12,7 +12,6 @@ use indexmap::IndexSet; use std::cell::Cell; use std::collections::VecDeque; use std::convert::TryFrom; -use std::rc::Rc; /* * The preprocessor fabricates if-then-else ( .. -> ... ; ...) @@ -373,7 +372,7 @@ fn mark_cut_variable(term: &mut Term) -> bool { }; if cut_var_found { - *term = Term::Var(Cell::default(), Rc::new(String::from("!"))); + *term = Term::Var(Cell::default(), Var::from("!")); true } else { false @@ -656,7 +655,7 @@ fn compute_head(term: &Term) -> Vec { } } - vars.insert(Rc::new(String::from("!"))); + vars.insert(Var::from("!")); vars.into_iter() .map(|v| Term::Var(Cell::default(), v)) .collect() @@ -767,7 +766,7 @@ impl Preprocessor { } } Term::Literal(_, Literal::Char('!')) => Ok(QueryTerm::BlockedCut), - Term::Var(_, ref v) if v.as_str() == "!" => { + Term::Var(_, ref v) if v.as_str() == Some("!") => { Ok(QueryTerm::UnblockedCut(Cell::default())) } Term::Clause(r, name, mut terms) => match (name, source_arity(&terms)) { diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index e457a611..d26468da 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -51,7 +51,6 @@ use std::net::{TcpListener, TcpStream, SocketAddr, ToSocketAddrs}; use std::num::NonZeroU32; use std::ops::Sub; use std::process; -use std::rc::Rc; use std::str::FromStr; use std::sync::Arc; @@ -1410,7 +1409,7 @@ impl Machine { let vars: Vec<_> = vars .union(&result.supp_vars) // difference + union does not cancel. - .map(|v| Term::Var(Cell::default(), Rc::new(format!("_{}", v.get_value())))) + .map(|v| Term::Var(Cell::default(), Var::Generated(v.get_value()))) .collect(); let helper_clause_loc = self.code.len(); diff --git a/src/parser/ast.rs b/src/parser/ast.rs index cf7bf946..78bd55b4 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -572,6 +572,44 @@ impl Literal { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum Var { + Generated(usize), + Named(Rc), +} + +impl From for Var { + #[inline(always)] + fn from(value: String) -> Var { + Var::Named(Rc::new(value)) + } +} + +impl From<&str> for Var { + #[inline(always)] + fn from(value: &str) -> Var { + Var::Named(Rc::new(value.to_owned())) + } +} + +impl Var { + #[inline(always)] + pub fn as_str(&self) -> Option<&str> { + match self { + Var::Generated(_) => None, + Var::Named(value) => Some(&value), + } + } + + #[inline(always)] + pub fn to_string(&self) -> String { + match self { + Var::Generated(n) => format!("_{}", n), + Var::Named(value) => value.to_string(), + } + } +} + #[derive(Debug, Clone)] pub enum Term { AnonVar, @@ -582,7 +620,7 @@ pub enum Term { // other PartialString variants in as_partial_string. PartialString(Cell, String, Box), CompleteString(Cell, Atom), - Var(Cell, Rc), + Var(Cell, Var), } impl Term { diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 74f1b930..ce633b94 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -8,7 +8,6 @@ use crate::parser::rug::ops::NegAssign; use std::cell::Cell; use std::mem; -use std::rc::Rc; #[derive(Debug, Clone, Copy, PartialEq)] enum TokenType { @@ -427,7 +426,7 @@ impl<'a, R: CharRead> Parser<'a, R> { if v.trim() == "_" { self.terms.push(Term::AnonVar); } else { - self.terms.push(Term::Var(Cell::default(), Rc::new(v))); + self.terms.push(Term::Var(Cell::default(), Var::from(v))); } TokenType::Term -- 2.54.0