use crate::targets::*;
use std::cell::Cell;
-use std::rc::Rc;
pub(crate) trait Allocator {
fn new() -> Self;
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,
fn mark_var<'a, Target: CompilationTarget<'a>>(
&mut self,
- var_name: Rc<String>,
+ var_name: Var,
lvl: Level,
cell: &'a Cell<VarReg>,
context: GenContext,
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(),
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)]
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 {
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> {
}
}
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(
ArithTermRef::Var(lvl, cell, name) => {
let r = if lvl == Level::Shallow {
self.marker.mark_non_callable(
- name.clone(),
+ name,
arg,
term_loc,
cell,
use std::cell::Cell;
use std::collections::VecDeque;
-use std::rc::Rc;
#[derive(Debug)]
pub(crate) struct ConjunctInfo<'a> {
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>,
impl DebrayAllocator {
fn mark_var_in_non_callable(
&mut self,
- name: Rc<String>,
+ name: Var,
term_loc: GenContext,
vr: &Cell<VarReg>,
code: &mut Code,
}
#[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)),
pub(crate) fn mark_non_callable(
&mut self,
- name: Rc<String>,
+ name: Var,
arg: usize,
term_loc: GenContext,
vr: &Cell<VarReg>,
}
}
- fn get_var_count(&self, var: &String) -> usize {
+ fn get_var_count(&self, var: &Var) -> usize {
*self.var_count.get(var).unwrap()
}
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,
) {
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>(
#[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));
}
&mut self,
code: &mut Code,
cell: &Cell<VarReg>,
- var: Rc<String>,
+ var: Var,
term_loc: GenContext,
) {
let mut target = Code::new();
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,
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() {
}
}
- 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() {
}
}
- 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;
fn alloc_reg_to_var<'a, Target: CompilationTarget<'a>>(
&mut self,
- var: &String,
+ var: &Var,
lvl: Level,
term_loc: GenContext,
target: &mut Vec<Instruction>,
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() {
fn mark_var<'a, Target: CompilationTarget<'a>>(
&mut self,
- var: Rc<String>,
+ var: Var,
lvl: Level,
cell: &'a Cell<VarReg>,
term_loc: GenContext,
fn mark_reserved_var<'a, Target: CompilationTarget<'a>>(
&mut self,
- var: Rc<String>,
+ var: Var,
lvl: Level,
cell: &'a Cell<VarReg>,
term_loc: GenContext,
use std::cell::Cell;
use std::collections::BTreeSet;
use std::mem::swap;
-use std::rc::Rc;
use std::vec::Vec;
// labeled with chunk numbers.
#[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> {
}
}
- 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);
}
// 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 {
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);
}
}
}
- 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()
}
}
}
- 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()
}
use std::fmt;
use std::ops::AddAssign;
use std::path::PathBuf;
-use std::rc::Rc;
use crate::{is_infix, is_postfix};
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 {
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,
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);
// 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
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 => {
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();
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();
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),
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> {
}
}
-#[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),
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> {
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)),
}
}
}
*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 {
}
}
&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],
}
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("!")));
}
};
}
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))]
}
};
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)));
}
_ => {}
}
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;
}
}
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,
}
}
(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) => {
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)]
}
}
-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>;
use std::convert::TryFrom;
use std::fmt;
use std::ops::{Index, IndexMut};
-use std::rc::Rc;
pub(crate) type Registers = [HeapCellValue; MAX_ARITY + 1];
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));
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,
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!();
use std::cell::Cell;
use std::collections::VecDeque;
use std::convert::TryFrom;
-use std::rc::Rc;
/*
* The preprocessor fabricates if-then-else ( .. -> ... ; ...)
};
if cut_var_found {
- *term = Term::Var(Cell::default(), Rc::new(String::from("!")));
+ *term = Term::Var(Cell::default(), Var::from("!"));
true
} else {
false
}
}
- vars.insert(Rc::new(String::from("!")));
+ vars.insert(Var::from("!"));
vars.into_iter()
.map(|v| Term::Var(Cell::default(), v))
.collect()
}
}
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)) {
use std::num::NonZeroU32;
use std::ops::Sub;
use std::process;
-use std::rc::Rc;
use std::str::FromStr;
use std::sync::Arc;
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();
}
}
+#[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,
// 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 {
use std::cell::Cell;
use std::mem;
-use std::rc::Rc;
#[derive(Debug, Clone, Copy, PartialEq)]
enum TokenType {
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