Commit 2da5aa93 authored by Jeff Smits's avatar Jeff Smits

Use the InternedString type alias

parent c152479b
......@@ -2,7 +2,7 @@
name = "strs"
version = "0.1.0"
dependencies = [
"aterm 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
"aterm 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -29,7 +29,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "aterm"
version = "0.18.1"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -307,7 +307,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
"checksum aterm 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0f2df2694d64af77e71242cfb2e0d421f4b95c0d9c07d0d0d8a1a4c4adbfd3"
"checksum aterm 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1cafec35b5dd56b9cd172b525d8b9bc7b454f7c24739d18b41e92e79c96a6ec8"
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
"checksum clap 2.23.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f57e9b63057a545ad2ecd773ea61e49422ed1b1d63d74d5da5ecaee55b3396cd"
......
......@@ -13,7 +13,7 @@ version = "0.1.0"
phf_codegen = "0.7.21"
[dependencies]
aterm = "0.18.1"
aterm = "0.19.1"
fnv = "1.0.5"
linked-hash-map = "0.4.2"
phf = "0.7.21"
......
......@@ -24,6 +24,8 @@ use try_from::TryInto;
use fnv::{FnvHashSet, FnvHashMap};
use aterm::string_share::InternedString;
use strs::io;
use strs::factory::ATermFactory;
use strs::error::{Error, Result};
......@@ -106,7 +108,7 @@ enum Value<'s> {
UnBound,
MaybeBound,
Bound,
BoundTo(&'s str),
BoundTo(InternedString<'s>),
}
impl<'s> Value<'s> {
......@@ -135,8 +137,8 @@ impl<'s> PartialOrd<Value<'s>> for Value<'s> {
}
}
impl<'a, 's> From<&'a Option<&'s str>> for Value<'s> {
fn from(opt: &'a Option<&'s str>) -> Self {
impl<'a, 's> From<&'a Option<InternedString<'s>>> for Value<'s> {
fn from(opt: &'a Option<InternedString<'s>>) -> Self {
match *opt {
None => Value::Bound,
Some(name) => Value::BoundTo(name),
......@@ -146,8 +148,8 @@ impl<'a, 's> From<&'a Option<&'s str>> for Value<'s> {
#[derive(Debug, Clone, PartialEq, Eq)]
struct Scope<'s> {
strategy: FnvHashMap<&'s str, (::std::result::Result<FnvHashSet<&'s str>, DynamicCall>, usize)>,
term: FnvHashMap<&'s str, Value<'s>>,
strategy: FnvHashMap<InternedString<'s>, (::std::result::Result<FnvHashSet<InternedString<'s>>, DynamicCall>, usize)>,
term: FnvHashMap<InternedString<'s>, Value<'s>>,
is_overlay: bool,
is_unbound_overlay: bool,
}
......@@ -155,8 +157,8 @@ struct Scope<'s> {
impl<'s> Scope<'s> {
fn from_args<I1, I2>(no_of_scopes: usize, sargs: I1, targs: I2) -> Self
where
I1: IntoIterator<Item = &'s str>,
I2: IntoIterator<Item = &'s str>,
I1: IntoIterator<Item = InternedString<'s>>,
I2: IntoIterator<Item = InternedString<'s>>,
{
Scope {
term: targs
......@@ -192,7 +194,7 @@ impl<'s> Scope<'s> {
fn from_fresh_variables<I>(fresh_vars: I) -> Self
where
I: IntoIterator<Item = &'s str>,
I: IntoIterator<Item = InternedString<'s>>,
{
Scope {
term: fresh_vars
......@@ -246,11 +248,11 @@ impl<'s> Scopes<'s> {
self.0.push(Scope::unbound_overlay())
}
fn get_term(&self, term_name: &str) -> Option<Value<'s>> {
fn get_term(&self, term_name: InternedString<'s>) -> Option<Value<'s>> {
let mut found_unbound_overlay = false;
for scope in self.0.iter().rev() {
found_unbound_overlay |= scope.is_unbound_overlay;
if let Some(value) = scope.term.get(term_name) {
if let Some(value) = scope.term.get(&term_name) {
if found_unbound_overlay && *value == Value::UnBound {
return Some(Value::MaybeBound);
} else {
......@@ -261,12 +263,12 @@ impl<'s> Scopes<'s> {
None
}
fn apply_strategy(&mut self, strat_name: &str) {
fn apply_strategy(&mut self, strat_name: InternedString<'s>) {
let (vars, no_of_scopes) = {
let opt = self.0
.iter()
.rev()
.flat_map(|scope| scope.strategy.get(strat_name))
.flat_map(|scope| scope.strategy.get(&strat_name))
.cloned()
.next();
if opt.is_none() {
......@@ -286,7 +288,7 @@ impl<'s> Scopes<'s> {
if offset == None && scope.is_overlay {
offset = Some(n);
}
if scope.term.get(var) == Some(&Value::UnBound) {
if scope.term.get(&var) == Some(&Value::UnBound) {
offset = Some(offset.unwrap_or(n));
break;
}
......@@ -297,9 +299,9 @@ impl<'s> Scopes<'s> {
}
}
fn set_term(&mut self, term_name: &'s str, value: Value<'s>) {
fn set_term(&mut self, term_name: InternedString<'s>, value: Value<'s>) {
for scope in self.0.iter_mut().rev() {
if scope.term.contains_key(term_name) || scope.is_overlay {
if scope.term.contains_key(&term_name) || scope.is_overlay {
scope.term.insert(term_name, value);
return;
}
......@@ -384,7 +386,7 @@ impl<'s> CTreeOptimize for preprocess_ext::Def<'s> {
}
impl<'s> CTreeOptimize for preprocess::Def<'s> {
type Context = (Option<&'s str>, Scopes<'s>);
type Context = (Option<InternedString<'s>>, Scopes<'s>);
fn optimize(mut self, c: &mut Self::Context) -> Self {
// eprintln!("CTreeOptimize::optimize(\"LetDef\", _)");
......@@ -419,7 +421,7 @@ fn conservative_maybe_bind<'s>(scopes: &mut Scopes<'s>) {
fn conservative_maybe_bind2<'s, I>(scopes: &mut Scopes<'s>, affected_names: I)
where
I: IntoIterator<Item=&'s str>,
I: IntoIterator<Item=InternedString<'s>>,
{
for name in affected_names {
if scopes.get_term(name) == Some(Value::UnBound) {
......@@ -430,7 +432,7 @@ where
// Pay attention, this is where the optimizing starts
impl<'s> CTreeOptimize for preprocess::Strategy<'s> {
type Context = (Option<&'s str>, Scopes<'s>);
type Context = (Option<InternedString<'s>>, Scopes<'s>);
fn optimize(self, mut c: &mut Self::Context) -> Self {
use preprocess::Strategy;
......@@ -766,7 +768,7 @@ fn all_vars_bound<'s>(bt: &preprocess::BuildTerm<'s>, m: &Scopes<'s>) -> bool {
}
impl<'s> CTreeOptimize for preprocess::MatchTerm<'s> {
type Context = (Option<&'s str>, Scopes<'s>);
type Context = (Option<InternedString<'s>>, Scopes<'s>);
fn optimize(self, mut c: &mut Self::Context) -> Self {
use preprocess::MatchTerm::*;
......@@ -804,7 +806,7 @@ impl<'s> CTreeOptimize for preprocess::MatchTerm<'s> {
}
impl<'s> CTreeOptimize for preprocess::BuildTerm<'s> {
type Context = (Option<&'s str>, Scopes<'s>);
type Context = (Option<InternedString<'s>>, Scopes<'s>);
fn optimize(self, mut c: &mut Self::Context) -> Self {
use preprocess::BuildTerm::*;
......@@ -838,14 +840,14 @@ struct DynamicCall;
fn match_vars_in_strategy<'s>(
strat: &preprocess::Strategy<'s>,
) -> ::std::result::Result<FnvHashSet<&'s str>, DynamicCall> {
) -> ::std::result::Result<FnvHashSet<InternedString<'s>>, DynamicCall> {
use preprocess::Strategy;
match *strat {
Strategy::Let(_, ref body) => match_vars_in_strategy(body),
// TODO: add vars from Call
Strategy::CallT(_, ref sargs, _) => {
let result = sargs.iter().map(match_vars_in_strategy).collect::<::std::result::Result<Vec<FnvHashSet<&'s str>>, DynamicCall>>()?;
let result = sargs.iter().map(match_vars_in_strategy).collect::<::std::result::Result<Vec<FnvHashSet<InternedString<'s>>>, DynamicCall>>()?;
Ok(result.into_iter().flat_map(|s| s).collect())
},
Strategy::CallDynamic(_, _, _) => Err(DynamicCall),
......@@ -854,7 +856,7 @@ fn match_vars_in_strategy<'s>(
Strategy::Match(ref term) => Ok(match_vars(term)),
Strategy::Build(_) => Ok(FnvHashSet::default()),
Strategy::Scope(ref names, ref body) => {
let name_set: FnvHashSet<&'s str> = names.iter().map(|&s| s).collect();
let name_set: FnvHashSet<InternedString<'s>> = names.iter().map(|&s| s).collect();
match match_vars_in_strategy(body) {
Ok(mut v) => {
v.retain(|n| !name_set.contains(n));
......@@ -864,7 +866,7 @@ fn match_vars_in_strategy<'s>(
}
}
Strategy::Seq(ref strats) => {
let result = strats.iter().map(match_vars_in_strategy).collect::<::std::result::Result<Vec<FnvHashSet<&'s str>>, DynamicCall>>()?;
let result = strats.iter().map(match_vars_in_strategy).collect::<::std::result::Result<Vec<FnvHashSet<InternedString<'s>>>, DynamicCall>>()?;
Ok(result.into_iter().flat_map(|s| s).collect())
},
Strategy::GuardedLChoice(ref pairs, ref s_else) => {
......@@ -873,18 +875,18 @@ fn match_vars_in_strategy<'s>(
.map(|&(ref s_if, ref s_then)| {
let one = match_vars_in_strategy(s_if)?;
let two = match_vars_in_strategy(s_then)?;
Ok(one.union(&two).map(|&s| s).collect::<FnvHashSet<&'s str>>())
Ok(one.union(&two).map(|&s| s).collect::<FnvHashSet<InternedString<'s>>>())
})
.collect::<::std::result::Result<Vec<FnvHashSet<&'s str>>, DynamicCall>>()?;
let pairs_names: FnvHashSet<&'s str> = pairs_names.into_iter().flat_map(|s| s).collect();
.collect::<::std::result::Result<Vec<FnvHashSet<InternedString<'s>>>, DynamicCall>>()?;
let pairs_names: FnvHashSet<InternedString<'s>> = pairs_names.into_iter().flat_map(|s| s).collect();
Ok(pairs_names.union(&match_vars_in_strategy(s_else)?).map(|&s| s).collect())
}
Strategy::ConsMatch(ref map, _) => {
let result = map.values().map(match_vars_in_strategy).collect::<::std::result::Result<Vec<FnvHashSet<&'s str>>, DynamicCall>>()?;
let result = map.values().map(match_vars_in_strategy).collect::<::std::result::Result<Vec<FnvHashSet<InternedString<'s>>>, DynamicCall>>()?;
Ok(result.into_iter().flat_map(|s| s).collect())
},
Strategy::PrimT(_, ref sargs, _) => {
let result = sargs.iter().map(match_vars_in_strategy).collect::<::std::result::Result<Vec<FnvHashSet<&'s str>>, DynamicCall>>()?;
let result = sargs.iter().map(match_vars_in_strategy).collect::<::std::result::Result<Vec<FnvHashSet<InternedString<'s>>>, DynamicCall>>()?;
Ok(result.into_iter().flat_map(|s| s).collect())
},
Strategy::Some(ref s) => match_vars_in_strategy(s),
......@@ -894,7 +896,7 @@ fn match_vars_in_strategy<'s>(
}
}
fn match_vars<'s>(term: &preprocess::MatchTerm<'s>) -> FnvHashSet<&'s str> {
fn match_vars<'s>(term: &preprocess::MatchTerm<'s>) -> FnvHashSet<InternedString<'s>> {
use preprocess::MatchTerm;
let mut result = FnvHashSet::default();
......
......@@ -6,6 +6,8 @@ use primitives::ssl::State;
use fnv::FnvHashMap;
use aterm::string_share::InternedString;
use std::fmt;
use std::borrow::Borrow;
use std::cell::RefCell;
......@@ -38,14 +40,14 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
pub fn call_primitive(
&self,
prim_name: &'f str,
prim_name: InternedString<'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
let prim_ref = self.primitives
.iter()
.flat_map(|prims| prims.get(prim_name))
.flat_map(|prims| prims.get(&*prim_name))
.cloned() // ATermRef should be very cheap to clone
.next()
.ok_or_else(|| Error::UndefinedPrimitive(String::from(prim_name)))?;
......@@ -59,23 +61,23 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
result
}
pub fn get_strategy(&self, strat_name: &str) -> Result<StrategyDef<'d, 'f>> {
pub fn get_strategy(&self, strat_name: InternedString<'f>) -> Result<StrategyDef<'d, 'f>> {
self.scopes
.borrow()
.iter()
.rev()
.flat_map(|scope| scope.strategy.get(strat_name))
.flat_map(|scope| scope.strategy.get(&strat_name))
.cloned() // StrategyDef is fairly cheap to clone
.next()
.ok_or_else(|| Error::UndefinedStrategy(String::from(strat_name)))
}
pub fn get_term(&self, term_name: &str) -> Result<ATermRef<'f>> {
pub fn get_term(&self, term_name: InternedString<'f>) -> Result<ATermRef<'f>> {
Scopes::get_term_option(&self.scopes.borrow(), term_name)
.and_then(|(_, o)| o.ok_or(Error::StrategyFailed))
}
pub fn match_term(&self, term_name: &'f str, current: &ATermRef<'f>) -> Result<()> {
pub fn match_term(&self, term_name: InternedString<'f>, current: &ATermRef<'f>) -> Result<()> {
Scopes::match_term(&mut self.scopes.borrow_mut(), term_name, current)
}
......@@ -161,12 +163,12 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
#[derive(Debug, Default, Clone)]
pub struct StackTracer<'a> {
stack: Vec<&'a str>,
stack: Vec<InternedString<'a>>,
current_depth: usize,
}
impl<'a> StackTracer<'a> {
pub fn push(&mut self, str: &'a str) {
pub fn push(&mut self, str: InternedString<'a>) {
self.stack.truncate(self.current_depth);
self.stack.push(str);
self.current_depth += 1;
......@@ -181,7 +183,7 @@ impl<'a> StackTracer<'a> {
self.current_depth = self.stack.len();
}
pub fn stack(&self) -> ::std::slice::Iter<&'a str> {
pub fn stack(&self) -> ::std::slice::Iter<InternedString<'a>> {
self.stack.iter()
}
}
......@@ -201,16 +203,16 @@ impl<'a> fmt::Display for StackTracer<'a> {
#[derive(Debug, Default, Clone)]
pub struct Scope<'d, 'f: 'd, ATerm> {
pub term: FnvHashMap<&'f str, Option<ATerm>>,
pub strategy: FnvHashMap<&'f str, StrategyDef<'d, 'f>>,
pub term: FnvHashMap<InternedString<'f>, Option<ATerm>>,
pub strategy: FnvHashMap<InternedString<'f>, StrategyDef<'d, 'f>>,
is_overlay: bool,
}
impl<'d, 'f: 'd, ATerm> Scope<'d, 'f, ATerm> {
pub fn new<IA, IS>(terms: IA, defs: IS) -> Self
where
IA: IntoIterator<Item = (&'f str, ATerm)>,
IS: IntoIterator<Item = (&'f str, StrategyDef<'d, 'f>)>,
IA: IntoIterator<Item = (InternedString<'f>, ATerm)>,
IS: IntoIterator<Item = (InternedString<'f>, StrategyDef<'d, 'f>)>,
{
Scope {
term: terms.into_iter().map(|(n, a)| (n, Some(a))).collect(),
......@@ -249,7 +251,7 @@ impl<'d, 'f: 'd, ATerm> Scope<'d, 'f, ATerm> {
pub fn from_fresh_variables<I>(fresh_vars: I) -> Self
where
I: IntoIterator<Item = &'f str>,
I: IntoIterator<Item = InternedString<'f>>,
{
Scope {
term: fresh_vars
......@@ -268,14 +270,14 @@ pub mod Scopes {
pub fn get_term_option<'f>(
scopes: &[Scope<ATermRef<'f>>],
term_name: &str,
term_name: InternedString<'f>,
) -> Result<(usize, Option<ATermRef<'f>>)> {
let mut offset = None;
for (n, scope) in scopes.iter().enumerate().rev() {
if offset == None && scope.is_overlay {
offset = Some(n);
}
if let Some(binding) = scope.term.get(term_name) {
if let Some(binding) = scope.term.get(&term_name) {
let n = offset.unwrap_or(n);
return Ok((n, binding.clone()));
}
......@@ -285,7 +287,7 @@ pub mod Scopes {
pub fn match_term<'d, 'f>(
scopes: &mut Vec<Scope<'d, 'f, ATermRef<'f>>>,
term_name: &'f str,
term_name: InternedString<'f>,
current: &ATermRef<'f>,
) -> Result<()> {
let term = get_term_option(scopes, term_name)?;
......
use aterm::BrokenF32;
use aterm::print::ATermWrite;
use aterm::string_share::InternedString;
use try_from::{TryFrom, TryInto};
......@@ -14,17 +15,17 @@ use factory::Term as FTerm;
/// ModName = {ModNamePart "/"}+
/// ModNamePart = [a-zA-Z\.\_] [a-zA-Z0-9\'\.\-\_]*
/// ```
pub type ModName<'s> = &'s str;
pub type ModName<'s> = InternedString<'s>;
/// `[a-zA-Z\_] [a-zA-Z0-9\'\-\_]*`
pub type Id<'s> = &'s str;
pub type Id<'s> = InternedString<'s>;
/// `[a-z] [a-zA-Z0-9\'\-\_]*`
pub type LCID<'s> = &'s str;
pub type LCID<'s> = InternedString<'s>;
/// `[A-Z] [a-zA-Z0-9\'\-\_]*`
pub type UCID<'s> = &'s str;
pub type UCID<'s> = InternedString<'s>;
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum Module<'s> {
Module(&'s str, Vec<Decl<'s>>),
Module(InternedString<'s>, Vec<Decl<'s>>),
Specification(Vec<Decl<'s>>),
}
......@@ -55,7 +56,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Module<'s> {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"Module" => {
if r.len() == 2 {
let str = match_string(&r[0])?;
......@@ -117,7 +118,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Decl<'s> {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"Imports" => {
if r.len() == 1 {
return match_list(&r[0]).map(Decl::Imports);
......@@ -161,7 +162,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for ImportModName<'s> {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"Import" => {
if r.len() == 1 {
return match_string(&r[0]).map(ImportModName::Import);
......@@ -230,7 +231,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for SDecl<'s> {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"Sorts" => {
if r.len() == 1 {
return match_list(&r[0]).map(SDecl::Sorts);
......@@ -294,7 +295,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Sort<'s> {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"SortVar" => {
if r.len() == 1 {
return match_string(&r[0]).map(Sort::SortVar);
......@@ -345,10 +346,10 @@ impl<'s> ATermWrite for Sort<'s> {
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum OpDecl<'s> {
OpDecl(Id<'s>, Type<'s>),
OpDeclQ(&'s str, Type<'s>),
OpDeclQ(InternedString<'s>, Type<'s>),
OpDeclInj(Type<'s>),
ExtOpDecl(Id<'s>, Type<'s>),
ExtOpDeclQ(&'s str, Type<'s>),
ExtOpDeclQ(InternedString<'s>, Type<'s>),
ExtOpDeclInj(Type<'s>),
}
......@@ -371,7 +372,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for OpDecl<'s> {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"OpDecl" => {
if r.len() == 2 {
let str = match_string(&r[0])?;
......@@ -520,7 +521,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Type<'s> {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"ConstType" => {
if r.len() == 1 {
return match_(&r[0]).map(Type::ConstType);
......@@ -622,7 +623,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Def<'s> {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"SDefT" => {
if r.len() == 4 {
let str = match_string(&r[0])?;
......@@ -750,7 +751,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for StrategyDef<'s> {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"SDefT" => {
if r.len() == 4 {
let str = match_string(&r[0])?;
......@@ -827,7 +828,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Anno {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"Extend" => {
if r.is_empty() {
return Ok(Anno::Extend);
......@@ -910,7 +911,7 @@ pub enum Strategy<'s> {
Scope(Vec<Id<'s>>, Box<Strategy<'s>>),
Seq(Box<Strategy<'s>>, Box<Strategy<'s>>),
GuardedLChoice(Box<Strategy<'s>>, Box<Strategy<'s>>, Box<Strategy<'s>>),
PrimT(&'s str, Vec<Strategy<'s>>, Vec<Term<'s>>),
PrimT(InternedString<'s>, Vec<Strategy<'s>>, Vec<Term<'s>>),
Some(Box<Strategy<'s>>),
One(Box<Strategy<'s>>),
All(Box<Strategy<'s>>),
......@@ -1002,7 +1003,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Strategy<'s> {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"Let" => {
if r.len() == 2 {
let defs = match_list(&r[0])?;
......@@ -1172,7 +1173,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Term<'s> {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"Var" => {
let r = r;
if r.len() == 1 {
......@@ -1209,9 +1210,9 @@ pub enum PreTerm<'s> {
Wld,
Int(i32),
Real(BrokenF32),
Str(&'s str),
Str(InternedString<'s>),
Op(Id<'s>, Vec<Term<'s>>),
OpQ(&'s str, Vec<Term<'s>>),
OpQ(InternedString<'s>, Vec<Term<'s>>),
Explode(Term<'s>, Term<'s>),
As(Var<'s>, Box<PreTerm<'s>>),
}
......@@ -1244,7 +1245,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for PreTerm<'s> {
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let FTerm::Application(c, ref r) = value.term {
match c {
match c.as_ref() {
"Var" => {
let r = r;
if r.len() == 1 {
......@@ -1308,14 +1309,14 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for PreTerm<'s> {
}
}
fn match_string<'s>(r: &ATermRef<'s>) -> Result<&'s str, Error> {
fn match_string<'s>(r: &ATermRef<'s>) -> Result<InternedString<'s>, Error> {
if let FTerm::String(str) = r.term {
return Ok(str);
}
Err(Error::CTreeParse("string"))
}
fn match_strings<'s>(r: &ATermRef<'s>) -> Result<Vec<&'s str>, Error> {
fn match_strings<'s>(r: &ATermRef<'s>) -> Result<Vec<InternedString<'s>>, Error> {
if let FTerm::List(ref r) = r.term {
return r.iter()
.map(|a| match_string(&a))
......@@ -1345,7 +1346,8 @@ where
// This function seems more complicated than necessary... Not sure how to simplify though
// TODO: truncate string when containing unescaped double quote (")
pub fn string_unescape(string: &str) -> String {
pub fn string_unescape<S: AsRef<str>>(string: S) -> String {
let string = string.as_ref();
let mut result = String::with_capacity(string.len() - 2);
// copy marks the next chunk to be copied without special handling
let mut copy = true;
......
use aterm;
use aterm::print::ATermWrite;
use aterm::string_share::StringShare;
use aterm::string_share::{StringShare, InternedString};
use linked_hash_map::LinkedHashMap;
......@@ -193,39 +193,18 @@ impl<'s> Iterator for TermListIterator<'s> {
}
}
#[derive(Debug, Eq, Clone, Hash)]
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum Term<'s, B> {
Int(i32),
Long(i64),
Real(aterm::BrokenF32),
Application(&'s str, Box<[ATermRef<'s>]>),
String(&'s str),
Application(InternedString<'s>, Box<[ATermRef<'s>]>),
String(InternedString<'s>),
List(Rc<TermList<'s>>),
Placeholder(aterm::TermPlaceholder<ATermRef<'s>>, ATermRef<'s>),
Blob(B),
}
// Note that this implementation uses pointer equality on strings, assuming all strings went
// through the factory and were collapsed when equal!
impl<'s, B: PartialEq> PartialEq for Term<'s, B> {
fn eq(&self, other: &Self) -> bool {
use self::Term::*;
use std::ptr;
match (self, other) {
(&Int(l), &Int(r)) => l == r,
(&Long(l), &Long(r)) => l == r,
(&Real(l), &Real(r)) => l == r,
(&Application(lc, ref lch), &Application(rc, ref rch)) => ptr::eq(lc, rc) && lch == rch,
(&String(lc), &String(rc)) => ptr::eq(lc, rc),
(&List(ref l), &List(ref r)) => l == r,
(&Placeholder(_, ref l), &Placeholder(_, ref r)) => l == r,
(&Blob(ref l), &Blob(ref r)) => l == r,
_ => false,
}
}
}
impl<'s, B> ATermWrite for Term<'s, B>
where
B: ATermWrite,
......@@ -239,7 +218,7 @@ where
Real(BrokenF32(r)) => write!(writer, "{}", r),
Application(cons, ref children) => {
// write!(writer, "{:p}#{}", cons, cons)?;
writer.write_str(cons)?;
writer.write_str(cons.as_ref())?;
if !children.is_empty() {
write!(writer, "(")?;
children.to_ascii(writer)?;
......@@ -347,7 +326,7 @@ impl<'s> ATerm<'s> {
}
}
pub fn get_string(&self) -> Option<&'s str> {
pub fn get_string(&self) -> Option<InternedString<'s>> {
use self::Term::*;
match self.term {
String(s) => Some(s),
......@@ -400,7 +379,7 @@ impl<'s> aterm::ATerm<'s> for ATerm<'s> {
}
}
fn get_application(&self) -> Option<(&'s str, &[Self::Rec])> {
fn get_application(&self) -> Option<(InternedString<'s>, &[Self::Rec])> {
match self.term {
Term::Application(c, ref r) => Some((c, r)),
_ => None,
......@@ -492,7 +471,7 @@ impl<'s> ATermFactory {
))
}
pub fn intern_string<S>(&'s self, string: S) -> &'s str
pub fn intern_string<S>(&'s self, string: S) -> InternedString<'s>
where
S: Into<Cow<'s, str>>,
{
......
......@@ -7,6 +7,7 @@ use primitives::Primitives;
use aterm::{ATerm as A, ATermFactory as ATF};
use aterm::BrokenF32;
use aterm::string_share::InternedString;
use ref_eq::ref_eq;
......@@ -76,7 +77,7 @@ pub fn interpret_main<'f>(
factory,
program,
libraries,
"main_0_0",
factory.intern_string("main_0_0"),
factory.list(iter::once(factory.string(String::from("main_0_0")))),
)
}
......@@ -85,7 +86,7 @@ pub fn interpret<'f>(
factory: &'f ATermFactory,
program: ATermRef<'f>,
libraries: Libraries<ATermRef<'f>>,
strategy: &str,
strategy: InternedString<'f>,
input: ATermRef<'f>,
) -> result::Result<ATermRef<'f>, TracedError> {
use context::Scope;
......@@ -231,7 +232,7 @@ impl<'d, 'f: 'd> Eval<'d, 'f> for preprocess::Strategy<'f> {
}
ConsMatch(ref map, ref s_else) => {
let matching_arm = current.get_application().and_then(
|(cons, _)| map.get(cons),
|(cons, _)| map.get(&cons),
);
if let Option::Some(s_match) = matching_arm {
s_match.eval(context, current.clone())
......@@ -331,7 +332,7 @@ fn eval_match<'d, 'f: 'd>(
.and_then(|s2| if s == s2 { Some(()) } else { None })
.ok_or(Error::StrategyFailed)
}
Op(