Commit ae6cc107 authored by Jeff Smits's avatar Jeff Smits

Missing a few things, but the basics work! :D

Yes it's mostly untested, I didn't forget to add the test files to this
commit
parent fef1069c
......@@ -2,7 +2,7 @@
name = "strs"
version = "0.1.0"
dependencies = [
"aterm 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"aterm 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt-derive 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -22,7 +22,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "aterm"
version = "0.10.0"
version = "0.11.0"
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)",
......@@ -227,7 +227,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.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b354f3cb915c90375cf371c03408f801e420cbbb3398babcc3965e06f7087c"
"checksum aterm 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4be6658304081c33ce6f15bfb1a6c1cf0589ab87bc95624a9f5ad5a2bda618c6"
"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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf1114886d7cde2d6448517161d7db8d681a9a1c09f7d210f0b0864e48195f6"
......
......@@ -9,6 +9,6 @@ repository = "https://gitlab.com/Apanatshka/strs"
version = "0.1.0"
[dependencies]
aterm = "0.10.0"
aterm = "0.11.0"
structopt = "0.0.3"
structopt-derive = "0.0.3"
......@@ -3,4 +3,4 @@ signature constructors
Nil: Term
Cons: Term * Term -> Term
strategies
main = ?a@[b, c, d*, e*]; !a{}; !a{b}; !a{a,b}; !a{d*}; !a{d*, e*}
main = ?a;?b;?c;?d*;?e*; !a{};!a{b};!a{^"hi"};!a{b,c};!a{d*};!a{c,d*};!a{d*,e*}
Specification([Signature([Constructors([OpDecl("Nil",ConstType(Sort("Term",[])))])]),Strategies([SDefT("main_0_0",[],[],Build(Anno(Int("1"),Op("Nil",[]))))])])
Specification([Signature([Constructors([OpDecl("Nil",ConstType(Sort("Term",[])))])]),Strategies([SDefT("main_0_0",[],[],Build(Anno(Int("1"),Op("Nil",[]))))])])
\ No newline at end of file
......@@ -5,53 +5,88 @@ use std::fmt;
use std::borrow::Borrow;
use std::marker::PhantomData;
use preprocess::SDefT;
use std::cell::RefCell;
#[derive(Debug, Clone)]
pub struct Context<'a, B, F, A>
/// This context is internally mutable in RefCell fields. This is just for convenience as we don't
/// want to pass around the mutable fields separately. But the internal mutability is not a hidden
/// thing without effect, so the name of the context includes `Mut`.
#[derive(Debug)]
pub struct MutContext<'a, B, F, A>
where F: 'a + ATermFactory<'a, B, ATermRef = A>,
A: Borrow<<F as ATermFactory<'a, B>>::ATerm> + Clone,
<F as ATermFactory<'a, B>>::ATerm: Eq,
B: 'a
{
pub stacktracer: StackTracer,
pub stack_tracer: RefCell<StackTracer>,
pub scopes: RefCell<Vec<Scope<A>>>,
pub factory: &'a F,
pub primitives: HashMap<String, Primitive>,
pub scopes: Vec<Scope<A>>,
b: PhantomData<B>,
}
impl<'a, B, F, A> Context<'a, B, F, A>
impl<'a, B, F, A> MutContext<'a, B, F, A>
where F: 'a + ATermFactory<'a, B, ATermRef = A>,
A: Borrow<<F as ATermFactory<'a, B>>::ATerm> + Clone,
<F as ATermFactory<'a, B>>::ATerm: Eq,
B: 'a
{
pub fn new(factory: &'a F, global_scope: Scope<A>) -> Context<'a, B, F, A> {
Context {
stacktracer: StackTracer::default(),
pub fn new(factory: &'a F, global_scope: Scope<A>) -> MutContext<'a, B, F, A> {
MutContext {
stack_tracer: RefCell::new(StackTracer::default()),
factory: factory,
primitives: HashMap::new(),
scopes: vec![global_scope],
scopes: RefCell::new(vec![global_scope]),
b: PhantomData,
}
}
// Should really return a &SDefT, but I can't figure out lifetimes that borrowck will accept :(
pub fn get_strategy(&self, strat_name: &str) -> Result<SDefT> {
self.scopes
.borrow()
.iter()
.rev()
.flat_map(|scope| scope.strategy.get(strat_name))
.cloned()
.cloned() // >:(
.next()
.ok_or(Error::UndefinedStrategy(strat_name.to_owned()))
}
pub fn get_term(&self, strat_name: &str) -> Result<A> {
pub fn get_term(&self, term_name: &str) -> Result<A> {
self.scopes
.borrow()
.iter()
.rev()
.flat_map(|scope| scope.term.get(strat_name))
.flat_map(|scope| scope.term.get(term_name))
.cloned()
.next()
.ok_or(Error::UndefinedVariable(strat_name.to_owned()))
.unwrap_or(None)
.ok_or(Error::UndefinedVariable(term_name.to_owned()))
}
pub fn match_term(&self, term_name: &str, current: &A) -> Result<()> {
match self.get_term(term_name) {
Ok(term) => {
if term.borrow() == current.borrow() {
Ok(())
} else {
Err(Error::StrategyFailed)
}
}
Err(Error::UndefinedVariable(_)) => {
let latest_scope = self.scopes.borrow().len() - 1;
if let Some(_) = self.scopes.borrow_mut()[latest_scope]
.term
.insert(term_name.to_owned(), Some(current.clone())) {
unreachable!(format!("No scope had {}, but we just \
replaced something when we added it?!",
term_name))
} else {
Ok(())
}
}
Err(e) => Err(e),
}
}
}
......@@ -92,7 +127,7 @@ impl fmt::Display for StackTracer {
#[derive(Debug, Default, Clone)]
pub struct Scope<ATerm> {
pub term: HashMap<String, ATerm>,
pub term: HashMap<String, Option<ATerm>>,
pub strategy: HashMap<String, SDefT>,
}
......@@ -102,9 +137,25 @@ impl<ATerm> Scope<ATerm> {
{
Scope {
term: HashMap::default(),
strategy: sdefts.map(|sdeft| (sdeft.c_name(), sdeft)).collect(),
strategy: sdefts.map(|sdeft| (sdeft.name.clone(), sdeft)).collect(),
}
}
pub fn from_fresh_variables<I>(fresh_vars: I) -> Scope<ATerm>
where I: Iterator<Item = String>
{
Scope {
term: {
let mut result = HashMap::with_capacity(fresh_vars.size_hint().0);
// trying to use zip + iter::repeat will require ATerm: Clone, which is unnecessary
for fresh_var in fresh_vars {
result.insert(fresh_var, None);
}
result
},
strategy: HashMap::default(),
}
}
}
pub type Primitive = ();
\ No newline at end of file
pub type Primitive = ();
......@@ -818,7 +818,7 @@ impl<'a, A> TryFrom<&'a A> for PreTerm
}
fn match_string<A, R>(r: &R) -> Result<String, Error>
where A: ATerm<Rec=R>,
where A: ATerm<Rec = R>,
R: Borrow<A>
{
if let a::Term::Application(ref str, ref r) = r.borrow().as_inner().term {
......@@ -830,7 +830,7 @@ fn match_string<A, R>(r: &R) -> Result<String, Error>
}
fn match_strings<A, R>(r: &R) -> Result<Vec<String>, Error>
where A: ATerm<Rec=R>,
where A: ATerm<Rec = R>,
R: Borrow<A>
{
if let a::Term::List(ref r) = r.borrow().as_inner().term {
......@@ -843,7 +843,7 @@ fn match_strings<A, R>(r: &R) -> Result<Vec<String>, Error>
fn match_list<'a, A, R, T>(r: &'a R) -> Result<Vec<T>, Error>
where T: TryFrom<&'a A, Error = Error>,
A: 'a + ATerm<Rec=R>,
A: 'a + ATerm<Rec = R>,
R: Borrow<A>
{
if let a::Term::List(ref r) = r.borrow().as_inner().term {
......@@ -856,7 +856,7 @@ fn match_list<'a, A, R, T>(r: &'a R) -> Result<Vec<T>, Error>
fn match_<'a, A, R, T>(r: &'a R) -> Result<T, Error>
where T: TryFrom<&'a A, Error = Error>,
A: 'a + ATerm<Rec=R>,
A: 'a + ATerm<Rec = R>,
R: Borrow<A>
{
return r.borrow().try_into();
......
This diff is collapsed.
......@@ -73,7 +73,9 @@ fn read_input(path: String) -> io::Result<String> {
Ok(ctree)
}
fn read_aterm(f: &ATermFactory, path: String) -> Result<ATerm> {
fn read_aterm<'a>(f: &ATermFactory,
path: String)
-> Result<<ATermFactory as aterm::ATermFactory<'a, ()>>::ATermRef> {
let file_contents = read_input(path)?;
let (aterm, _) = f.read_ascii(&file_contents)?;
Ok(aterm)
......
This diff is collapsed.
......@@ -5,8 +5,8 @@ use std::result;
use std::error;
use std::fmt;
pub type ATermFactory = aterm::boxed::ATermFactory<()>;
pub type ATerm = aterm::boxed::ATerm<()>;
pub type ATermFactory = aterm::rc::ATermFactory<()>;
pub type ATerm = aterm::rc::ATerm<()>;
pub type Result<T> = result::Result<T, Error>;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment