]> Repositorios git - scryer-prolog.git/commitdiff
add classifications and occurrence counting
authorMark Thom <[email protected]>
Tue, 4 Oct 2022 15:24:37 +0000 (09:24 -0600)
committerMark <[email protected]>
Fri, 23 Jun 2023 19:54:46 +0000 (13:54 -0600)
15 files changed:
src/allocator.rs
src/arithmetic.rs
src/codegen.rs
src/debray_allocator.rs
src/fixtures.rs
src/forms.rs
src/heap_print.rs
src/iterators.rs
src/machine/loader.rs
src/machine/machine_indices.rs
src/machine/machine_state.rs
src/machine/preprocessor.rs
src/machine/system_calls.rs
src/parser/ast.rs
src/parser/parser.rs

index 5be3aae1be848664d4a1e88025f2a9d237d9e19d..76bdfb53e34eb59927cd54874e5504874994350f 100644 (file)
@@ -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<String>,
+        var_name: Var,
         lvl: Level,
         cell: &'a Cell<VarReg>,
         term_loc: GenContext,
@@ -41,7 +40,7 @@ pub(crate) trait Allocator {
 
     fn mark_var<'a, Target: CompilationTarget<'a>>(
         &mut self,
-        var_name: Rc<String>,
+        var_name: Var,
         lvl: Level,
         cell: &'a Cell<VarReg>,
         context: GenContext,
@@ -88,17 +87,17 @@ pub(crate) trait Allocator {
         perm_vs
     }
 
-    fn get(&self, var: Rc<String>) -> 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<String>) -> bool {
+    fn is_unbound(&self, var: Var) -> bool {
         self.get(var).reg_num() == 0
     }
 
-    fn record_register(&mut self, var: Rc<String>, 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(),
index fcfd95990a7f60194be0d69b9615a4687b4594cd..94974a5104f1f3546a009fb887e065ea6b37fb1f 100644 (file)
@@ -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<VarReg>, Rc<String>),
+    Var(Level, &'a Cell<VarReg>, 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,
index 1aea58d2b8f23887cf7ccfa6869e4681e534ea00..a3fdc99b98d226a034e74898a3dfb2daa920a2a9 100644 (file)
@@ -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<Rc<String>, usize>,
+    pub(crate) var_count: IndexMap<Var, usize>,
     settings: CodeGenSettings,
     pub(crate) skeleton: PredicateSkeleton,
     pub(crate) jmp_by_locs: Vec<usize>,
@@ -180,7 +179,7 @@ pub(crate) struct CodeGenerator<'a> {
 impl DebrayAllocator {
     fn mark_var_in_non_callable(
         &mut self,
-        name: Rc<String>,
+        name: Var,
         term_loc: GenContext,
         vr: &Cell<VarReg>,
         code: &mut Code,
@@ -190,7 +189,7 @@ impl DebrayAllocator {
     }
 
     #[inline(always)]
-    pub(crate) fn get_binding(&self, name: &String) -> Option<RegType> {
+    pub(crate) fn get_binding(&self, name: &Var) -> Option<RegType> {
         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<String>,
+        name: Var,
         arg: usize,
         term_loc: GenContext,
         vr: &Cell<VarReg>,
@@ -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<VarReg>,
-        var: &Rc<String>,
+        var: &Var,
         term_loc: GenContext,
         target: &mut Code,
     ) {
@@ -429,7 +428,7 @@ impl<'b> CodeGenerator<'b> {
                     self.marker.mark_non_var::<Target>(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::<Target>(
@@ -835,7 +834,7 @@ impl<'b> CodeGenerator<'b> {
 
     #[inline]
     fn compile_unblocked_cut(&mut self, code: &mut Code, cell: &Cell<VarReg>) {
-        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<VarReg>,
-        var: Rc<String>,
+        var: Var,
         term_loc: GenContext,
     ) {
         let mut target = Code::new();
index e9cc73c7293a11c2e7d0fccc96fd65a96083602c..73645929275eaf8045e8e9a7fe941e38ef31a729 100644 (file)
@@ -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<Rc<String>, VarData, FxBuildHasher>,
+    bindings: IndexMap<Var, VarData, FxBuildHasher>,
     arg_c: usize,
     temp_lb: usize,
     arity: usize, // 0 if not at head.
-    contents: IndexMap<usize, Rc<String>, FxBuildHasher>,
+    contents: IndexMap<usize, Var, FxBuildHasher>,
     in_use: BTreeSet<usize>,
     free_list: Vec<usize>,
 }
 
 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<String>, 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<Instruction>,
@@ -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<String>,
+        var: Var,
         lvl: Level,
         cell: &'a Cell<VarReg>,
         term_loc: GenContext,
@@ -321,7 +320,7 @@ impl Allocator for DebrayAllocator {
 
     fn mark_reserved_var<'a, Target: CompilationTarget<'a>>(
         &mut self,
-        var: Rc<String>,
+        var: Var,
         lvl: Level,
         cell: &'a Cell<VarReg>,
         term_loc: GenContext,
index 65340da09a51c92fcd645fd4dcbfdd576b31b74b..1433b092e590b8fed6c36539af799de9c45c4e63 100644 (file)
@@ -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<VarReg>>);
 
 #[derive(Debug)]
 pub(crate) struct VariableFixtures<'a> {
-    perm_vars: IndexMap<Rc<String>, VariableFixture<'a>>,
-    last_chunk_temp_vars: IndexSet<Rc<String>>,
+    perm_vars: IndexMap<Var, VariableFixture<'a>>,
+    last_chunk_temp_vars: IndexSet<Var>,
 }
 
 impl<'a> VariableFixtures<'a> {
@@ -96,11 +95,11 @@ impl<'a> VariableFixtures<'a> {
         }
     }
 
-    pub(crate) fn insert(&mut self, var: Rc<String>, 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<String>) {
+    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<Rc<String>, OccurrenceSet> = IndexMap::new();
+        let mut use_sets: IndexMap<Var, OccurrenceSet> = 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<String>) -> 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<Rc<String>, VariableFixture<'a>> {
+    fn iter_mut(&mut self) -> indexmap::map::IterMut<Var, VariableFixture<'a>> {
         self.perm_vars.iter_mut()
     }
 
@@ -218,11 +217,11 @@ impl<'a> VariableFixtures<'a> {
         }
     }
 
-    pub(crate) fn into_iter(self) -> indexmap::map::IntoIter<Rc<String>, VariableFixture<'a>> {
+    pub(crate) fn into_iter(self) -> indexmap::map::IntoIter<Var, VariableFixture<'a>> {
         self.perm_vars.into_iter()
     }
 
-    fn values(&self) -> indexmap::map::Values<Rc<String>, VariableFixture<'a>> {
+    fn values(&self) -> indexmap::map::Values<Var, VariableFixture<'a>> {
         self.perm_vars.values()
     }
 
index 1c014587b8aa45d63650b72889a1ef2ffd0bcb6c..9db69581903bd7ba465c399007511f8f4d92e798 100644 (file)
@@ -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<RegType>, ClauseType, Vec<Term>, CallPolicy),
     BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q.
     UnblockedCut(Cell<VarReg>),
-    GetLevelAndUnify(Cell<VarReg>, Rc<String>),
-    Jump(JumpStub),
+    GetLevelAndUnify(Cell<VarReg>, Var),
+    Jump(JumpStub), // SOON: Branch(Vec<QueryTerm>),
 }
 
 impl QueryTerm {
index 54f52cd6cf7cd0b29e76c5c883ad9dc5e3c29495..d09211d14845b6b3d32301ab55a8f94dec55e09c 100644 (file)
@@ -472,7 +472,7 @@ pub struct HCPrinter<'a, Outputter> {
     state_stack: Vec<TokenOrRedirect>,
     toplevel_spec: Option<DirectedOp>,
     last_item_idx: usize,
-    pub var_names: IndexMap<HeapCellValue, Rc<String>>,
+    pub var_names: IndexMap<HeapCellValue, Var>,
     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();
 
index 6bf92a5f3b08ba202ead3cf64aaed19aeb7e8a3a..ac87a451417e36ab45b9a4a077f98eac492f3795 100644 (file)
@@ -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<Var>,
+}
+
+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<VarPtr> 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<RegType>, Atom, &'a Vec<Term>),
     PartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
     CompleteString(Level, &'a Cell<RegType>, Atom),
-    Var(Level, &'a Cell<VarReg>, Rc<String>),
+    Var(Level, &'a Cell<VarReg>, Var),
 }
 
 impl<'a> TermRef<'a> {
@@ -37,58 +66,6 @@ impl<'a> TermRef<'a> {
     }
 }
 
-#[derive(Clone, Debug)]
-pub(crate) struct RcMutPtr<T: Debug> {
-    owned: Rc<T>,
-    ptr: *mut Rc<T>,
-}
-
-impl<T: Debug> RcMutPtr<T> {
-    #[inline]
-    pub(crate) fn new(rc: &Rc<T>) -> Self {
-        Self { owned: rc.clone(), ptr: rc as *const _ as *mut _ }
-    }
-
-    #[inline]
-    pub(crate) fn owned(&self) -> Rc<T> {
-        self.owned.clone()
-    }
-
-    #[inline]
-    pub(crate) fn set(&mut self, var_b_marker: &Rc<T>) {
-        self.owned = var_b_marker.clone();
-
-        unsafe {
-            if !self.ptr.is_null() {
-                *self.ptr = self.owned.clone();
-            }
-        }
-    }
-}
-
-impl<T: Debug> From<T> for RcMutPtr<T> {
-    #[inline]
-    fn from(value: T) -> RcMutPtr<T> {
-        let owned = Rc::new(value);
-        RcMutPtr { owned, ptr: std::ptr::null_mut() }
-    }
-}
-
-impl<T: Debug + PartialEq> PartialEq for RcMutPtr<T> {
-    fn eq(&self, rhs: &Self) -> bool {
-        &self.owned == &rhs.owned
-    }
-}
-
-impl<T: Debug + Eq> Eq for RcMutPtr<T> {}
-
-impl<T: Debug + Hash> Hash for RcMutPtr<T> {
-    #[inline(always)]
-    fn hash<H: Hasher>(&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<RegType>, &'a String, &'a Box<Term>),
     FinalPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
     CompleteString(Level, &'a Cell<RegType>, Atom),
-    Var(Level, &'a Cell<VarReg>, RcMutPtr<String>),
+    UnblockedCut(Level, &'a Cell<VarReg>),
+    Var(Level, &'a Cell<VarReg>, 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<Item = &'a Term>>(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;
             }
         }
index f268c0f72529ee4bab7147f21852d1764c4b83f8..bb093a0e979984927e2f3c9d9b034ec31da4076f 100644 (file)
@@ -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) => {
index 11a9d6e808a8db231f3ced97b1a9c4ec975f3bfa..3f49e1ce6107e09f12db2102dae070e3098e33f0 100644 (file)
@@ -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<Rc<String>, HeapCellValue, FxBuildHasher>;
-pub(crate) type AllocVarDict = IndexMap<Rc<String>, VarData, FxBuildHasher>;
+pub(crate) type HeapVarDict = IndexMap<Var, HeapCellValue, FxBuildHasher>;
+pub(crate) type AllocVarDict = IndexMap<Var, VarData, FxBuildHasher>;
 
 pub(crate) type GlobalVarDir = IndexMap<Atom, (Ball, Option<HeapCellValue>), FxBuildHasher>;
 
index bdaf048c76e7412df362beb74fcabe27356f591e..6d0de7d9af18c2a159f3f5b79a6ea9a33801b195 100644 (file)
@@ -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<Item = (&'a Rc<String>, &'a HeapCellValue)>,
+            iter: impl Iterator<Item = (&'a Var, &'a HeapCellValue)>,
             atom_tbl: &mut AtomTable,
         ) -> Vec<HeapCellValue> {
             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<HeapCellValue, Rc<String>> = IndexMap::new();
+                let mut var_names: IndexMap<HeapCellValue, Var> = 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!();
index 7f0cc2649671fc01e56575fa2d3c65f70a050bf2..d2c33b06319a4dde9dda620341c44f5c76cd4b52 100644 (file)
@@ -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<Term> {
         }
     }
 
-    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)) {
index e457a611cafeb0cbe1e1b2046bf649556354cfde..d26468daa9341980a9d3d007964fdf18d3255334 100644 (file)
@@ -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();
index cf7bf94623968a4d7f7d4c3bdb40a7cb90dba5d5..78bd55b4d9b6bf1dfaa6dba039affbc9530c8591 100644 (file)
@@ -572,6 +572,44 @@ impl Literal {
     }
 }
 
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum Var {
+    Generated(usize),
+    Named(Rc<String>),
+}
+
+impl From<String> 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<RegType>, String, Box<Term>),
     CompleteString(Cell<RegType>, Atom),
-    Var(Cell<VarReg>, Rc<String>),
+    Var(Cell<VarReg>, Var),
 }
 
 impl Term {
index 74f1b930eb3fa618471ada12638fd28c4362305c..ce633b9448a52208cb2cce2daef486572e5fd77f 100644 (file)
@@ -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