Commit d6bd79e1 authored by Jeff Smits's avatar Jeff Smits

Still WIP, with these changes strings and constructors should be shared

parent 7581e405
......@@ -121,6 +121,7 @@ fn gen_primitives() {
"indexedSet_destroy",
"indexedSet_put",
"indexedSet_getIndex",
"indexedSet_getElem",
"indexedSet_elements",
"indexedSet_remove",
"indexedSet_reset",
......@@ -306,7 +307,7 @@ fn gen_strc_tests() {
for entry in read_dir("tests/strc_tests").unwrap() {
let path = entry.unwrap().path();
if path.is_file() && Some("ctree".as_ref()) == path.extension() {
// TODO: sanitise file_stem so it's likely to be a valid test name?
// Should we sanitise file_stem so it's likely to be a valid test name?
let test_name = path.file_stem().unwrap().to_str().unwrap().replace(
'-',
"_",
......
......@@ -16,14 +16,14 @@ use std::cell::RefCell;
pub struct MutContext<'d, 'f : 'd> {
pub stack_tracer: RefCell<StackTracer>,
pub scopes: RefCell<Vec<Scope<'d, ATermRef<'f>>>>,
pub factory: &'f ATermFactory<'f>,
pub factory: &'f ATermFactory,
pub primitives: Vec<&'static Primitives>,
pub ssl_state: RefCell<State<'f>>,
}
impl<'d, 'f : 'd> MutContext<'d, 'f> {
pub fn new(
factory: &'f ATermFactory<'f>,
factory: &'f ATermFactory,
scopes: Vec<Scope<'d, ATermRef<'f>>>,
primitives: Vec<&'static Primitives>,
) -> MutContext<'d, 'f> {
......
use aterm as a;
use aterm::BrokenF32;
use try_from::{TryFrom, TryInto};
......@@ -8,6 +7,7 @@ use std::fmt;
use error::Error;
use factory::ATermRef;
use factory::Term as FTerm;
/// ```sdf3
/// ModName = {ModNamePart "/"}+
......@@ -54,7 +54,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Module
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"Module" => {
if r.len() == 2 {
......@@ -117,7 +117,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Decl
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"Imports" => {
if r.len() == 1 {
......@@ -162,7 +162,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for ImportModName
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"Import" => {
if r.len() == 1 {
......@@ -215,7 +215,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for SDecl
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"Sorts" => {
if r.len() == 1 {
......@@ -267,7 +267,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Sort
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"SortVar" => {
if r.len() == 1 {
......@@ -329,7 +329,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for OpDecl
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"OpDecl" => {
if r.len() == 2 {
......@@ -387,7 +387,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for ConstType
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
if let "ConstType" = c.borrow() {
if r.len() == 1 {
return match_(&r[0]).map(ConstType);
......@@ -429,7 +429,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Type
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"ConstType" => {
if r.len() == 1 {
......@@ -513,7 +513,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Def
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"SDefT" => {
if r.len() == 4 {
......@@ -574,7 +574,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for SVar
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
if let "SVar" = c.borrow() {
let r = r;
if r.len() == 1 {
......@@ -643,7 +643,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for StrategyDef
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"SDefT" => {
if r.len() == 4 {
......@@ -721,7 +721,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Anno
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"Extend" => {
if r.is_empty() {
......@@ -760,7 +760,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for VarDec
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
if let "VarDec" = c.borrow() {
if r.len() == 2 {
let str = match_string(&r[0])?;
......@@ -876,7 +876,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Strategy
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"Let" => {
if r.len() == 2 {
......@@ -1011,7 +1011,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Var
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
if let "Var" = c.borrow() {
let r = r;
if r.len() == 1 {
......@@ -1048,7 +1048,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for Term
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"Var" => {
let r = r;
......@@ -1121,7 +1121,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for PreTerm
type Err = Error;
fn try_from(value: &'a ATermRef<'s>) -> Result<Self, Self::Err> {
if let a::rc::Term::Application(c, ref r) = value.term {
if let FTerm::Application(c, ref r) = value.term {
match c {
"Var" => {
let r = r;
......@@ -1187,7 +1187,7 @@ impl<'s, 'a> TryFrom<&'a ATermRef<'s>> for PreTerm
}
fn match_string<'s>(r: &ATermRef<'s>) -> Result<String, Error> {
if let a::rc::Term::Application(ref str, ref r) = r.term {
if let FTerm::Application(ref str, ref r) = r.term {
if r.is_empty() {
return Ok(string_unescape(str));
}
......@@ -1196,21 +1196,21 @@ fn match_string<'s>(r: &ATermRef<'s>) -> Result<String, Error> {
}
fn match_strings<'s>(r: &ATermRef<'s>) -> Result<Vec<String>, Error> {
if let a::rc::Term::List(ref r) = r.term {
return r.into_iter()
.map(match_string)
if let FTerm::List(ref r) = r.term {
return r.iter()
.map(|a| match_string(&a))
.collect::<Result<Vec<String>, Error>>();
}
Err(Error::CTreeParse("list"))
}
fn match_list<'a, 's, T>(r: &'a ATermRef<'s>) -> Result<Vec<T>, Error>
fn match_list<'s, T>(r: &ATermRef<'s>) -> Result<Vec<T>, Error>
where
T: TryFrom<&'a ATermRef<'s>, Err = Error>,
T: for<'a> TryFrom<&'a ATermRef<'s>, Err = Error>,
{
if let a::rc::Term::List(ref r) = r.term {
if let FTerm::List(ref r) = r.term {
return r.iter()
.map(|a| a.try_into())
.map(|a| (&a).try_into())
.collect::<Result<Vec<T>, Error>>();
}
Err(Error::CTreeParse("list"))
......
This diff is collapsed.
use context::{MutContext, StackTracer};
use error::{Result, Error};
use factory::{StrTerm, ATermFactory, ATermRef};
use factory::{ATermFactory, ATermRef};
use preprocess;
use preprocess::{StrategyDef, preprocess};
use primitives::Primitives;
......@@ -68,7 +68,7 @@ impl<A> iter::FromIterator<(A, Option<&'static Primitives>)> for Libraries<A> {
}
pub fn interpret_main<'f>(
factory: &'f ATermFactory<'f>,
factory: &'f ATermFactory,
program: ATermRef<'f>,
libraries: Libraries<ATermRef<'f>>,
) -> result::Result<ATermRef<'f>, TracedError> {
......@@ -82,7 +82,7 @@ pub fn interpret_main<'f>(
}
pub fn interpret<'f>(
factory: &'f ATermFactory<'f>,
factory: &'f ATermFactory,
program: ATermRef<'f>,
libraries: Libraries<ATermRef<'f>>,
strategy: &str,
......@@ -311,7 +311,7 @@ fn eval_match<'d, 'f : 'd>(
let tail = if v.len() > 1 {
context.factory.list(v[1..].iter().cloned())
} else {
context.factory.list(iter::empty())
context.factory.nil()
};
eval_match(context, &children[1], &tail)
}
......@@ -345,7 +345,7 @@ fn eval_match<'d, 'f : 'd>(
)
}
Explode(ref cons, ref children) => {
use aterm::rc::Term::*;
use factory::Term::*;
match current.term {
Application(ref current_cons, ref current_children) => {
let current_cons = &context.factory.string(current_cons.to_owned());
......@@ -355,11 +355,11 @@ fn eval_match<'d, 'f : 'd>(
eval_match(context, children, &current_children)?;
}
List(ref list) => {
eval_match(context, cons, &context.factory.list(iter::empty()))?;
eval_match(context, cons, &context.factory.nil())?;
eval_match(
context,
children,
&context.factory.list(list.clone().to_vec()),
&context.factory.list_term(list.clone()),
)?;
}
Blob(_) |
......@@ -369,9 +369,9 @@ fn eval_match<'d, 'f : 'd>(
explode pattern (#) first argument",
))
}
Int(_) | Long(_) | Real(_) => {
Int(_) | Long(_) | String(_) | Real(_) => {
eval_match(context, cons, current)?;
eval_match(context, children, &context.factory.list(iter::empty()))?;
eval_match(context, children, &context.factory.nil())?;
}
}
Ok(())
......@@ -388,7 +388,7 @@ fn eval_<'d, 'f : 'd, F>(
where
F: Fn(&Box<[ATermRef<'f>]>, &'d preprocess::Strategy, &MutContext<'d, 'f>) -> Result<Box<[ATermRef<'f>]>>
{
use aterm::rc::Term::*;
use factory::Term::*;
use aterm::TermPlaceholder as TP;
let annos = current.get_annotations();
......@@ -397,12 +397,12 @@ where
fun(r, strat, context)
.map(|r| context.factory.application(name.clone(), r.iter().cloned()))
.map(|t| {
context.factory.set_annos(t, annos.into_iter().cloned())
context.factory.with_annos(t, annos.into_iter().cloned())
})
}
List(ref r) => {
fun(r, strat, context).map(|r| context.factory.list(r.iter().cloned())).map(|t| {
context.factory.set_annos(t, annos.into_iter().cloned())
fun(&r.iter().collect::<Vec<_>>().into_boxed_slice(), strat, context).map(|r| context.factory.list(r.iter().cloned())).map(|t| {
context.factory.with_annos(t, annos.into_iter().cloned())
})
}
Placeholder(TP::Application(ref r)) => {
......@@ -410,10 +410,10 @@ where
.map(TP::Application)
.map(|p| context.factory.placeholder(p))
.map(|t| {
context.factory.set_annos(t, annos.into_iter().cloned())
context.factory.with_annos(t, annos.into_iter().cloned())
})
}
Placeholder(_) | Int(_) | Long(_) | Real(_) | Blob(_) => Err(Error::StrategyFailed),
Placeholder(_) | Int(_) | Long(_) | Real(_) | String(_) | Blob(_) => Err(Error::StrategyFailed),
}
}
......
......@@ -21,14 +21,14 @@ pub fn read_input<P: AsRef<Path>>(path: &P) -> io::Result<String> {
Ok(ctree)
}
pub fn read_aterm<'f, P: AsRef<Path>>(f: &'f ATermFactory<'f>, path: &P) -> Result<ATermRef<'f>> {
pub fn read_aterm<'f, P: AsRef<Path>>(f: &'f ATermFactory, path: &P) -> Result<ATermRef<'f>> {
let file_contents = read_input(path)?;
let (aterm, _) = f.read_ascii_string(&file_contents)?;
Ok(aterm)
}
pub fn read_lib<'f>(
f: &'f ATermFactory<'f>,
f: &'f ATermFactory,
str_path: &Path,
path: &str,
) -> Result<(ATermRef<'f>, Option<&'static Primitives>)> {
......
use context::{MutContext, Scope};
use ctree;
use error::{Result, Error};
use factory::{StrTerm, ATermFactory, ATermRef};
use factory::{ATermFactory, ATermRef};
use aterm::BrokenF32;
use aterm::{ATerm as A, ATermFactory as ATF};
......@@ -399,7 +399,7 @@ impl BuildTerm {
Var(ref s) => {
if let Some(annos) = annos {
let term = context.get_term(s)?;
Ok(context.factory.set_annos(
Ok(context.factory.with_annos(
term,
annos,
))
......@@ -408,37 +408,35 @@ impl BuildTerm {
}
}
Int(i) => {
Ok(context.factory.set_annos(
Ok(context.factory.with_annos(
context.factory.int(i),
annos.unwrap_or_default(),
))
}
Real(BrokenF32(f)) => {
Ok(context.factory.set_annos(
Ok(context.factory.with_annos(
context.factory.real(f),
annos.unwrap_or_default(),
))
}
Str(ref s) => {
Ok(context.factory.set_annos(
Ok(context.factory.with_annos(
context.factory.string(s.clone()),
annos.unwrap_or_default(),
))
}
Op(ref s, ref t) => {
use std::iter;
let t = Self::build_vec(context, t)?;
if s == "Cons" && t.len() == 2 {
t[1].get_list().ok_or(Error::StrategyFailed).map(|v| {
context.factory.list(iter::once(t[0].clone()).chain(
v.iter().cloned(),
))
})
if let ::factory::Term::List(ref tail) = t[1].term {
Ok(context.factory.cons(t[0].clone(), tail.clone()))
} else {
Err(Error::StrategyFailed)
}
} else if s == "Nil" && t.is_empty() {
Ok(context.factory.list(iter::empty()))
Ok(context.factory.nil())
} else {
Ok(context.factory.set_annos(
Ok(context.factory.with_annos(
context.factory.application(
s.clone(),
t.into_iter(),
......@@ -462,7 +460,7 @@ impl BuildTerm {
let application =
context.factory.application(s, children.iter().cloned());
Ok(context.factory.set_annos(
Ok(context.factory.with_annos(
application,
annos.unwrap_or_default(),
))
......@@ -503,7 +501,7 @@ impl BuildTerm {
}
#[allow(dead_code)]
pub fn build_static<'f>(&self, f: &'f ATermFactory<'f>) -> Result<ATermRef<'f>> {
pub fn build_static<'f>(&self, f: &'f ATermFactory) -> Result<ATermRef<'f>> {
let dummy_context = MutContext::new(f, Vec::new(), Vec::new());
self.build(&dummy_context).map_err(|e| match e {
Error::UndefinedVariable(_) => Error::CTreeParse(
......
......@@ -157,7 +157,14 @@ pub fn indexedSet_getIndex<'d, 'f: 'd>(
Ok(context.factory.int(result as i32))
}
// TODO: libstratego-lib uses a primitive SSL_indexedSet_getElem, which does not exist in the Java implementation!
pub fn indexedSet_getElem<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: Vec<StrategyDef<'d>>,
targs: Vec<ATermRef<'f>>,
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
unimplemented!("Not available in Java either!")
}
pub fn indexedSet_elements<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
......
use context::MutContext;
use error::{Error, Result};
use factory::{StrTerm, ATermRef};
use factory::ATermRef;
use preprocess::StrategyDef;
use aterm::{ATermFactory as ATF, ATerm as A};
......
use context::MutContext;
use error::{Error, Result};
use factory::{StrTerm, ATermRef};
use factory::ATermRef;
use preprocess::StrategyDef;
use aterm::{ATermFactory as ATF, ATerm as A};
......
use context::MutContext;
use error::{Error, Result};
use factory::{StrTerm, ATermRef};
use factory::ATermRef;
use preprocess::StrategyDef;
use aterm::{ATermFactory as ATF, ATerm as A};
......
use context::MutContext;
use error::{Error, Result};
use factory::{StrTerm, ATermRef};
use factory::ATermRef;
use preprocess::StrategyDef;
use aterm::{ATermFactory as ATF, ATerm as A};
......
use context::MutContext;
use error::{Error, Result};
use factory::{StrTerm, ATermRef};
use factory::ATermRef;
use preprocess::StrategyDef;
use interpreter::eval_sdef;
use aterm::{ATermFactory as ATF, ATerm as A};
use aterm::rc::Term;
use factory::Term;
use aterm::print::ATermWrite;
pub fn get_constructor<'d, 'f: 'd>(
......@@ -14,7 +14,6 @@ pub fn get_constructor<'d, 'f: 'd>(
targs: Vec<ATermRef<'f>>,
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
use std::iter;
if targs.len() < 1 {
return Err(Error::UnknownBehaviour(
"Primitive get_constructor called with wrong argument \
......@@ -26,8 +25,9 @@ pub fn get_constructor<'d, 'f: 'd>(
Term::Long(_) |
Term::Placeholder(_) |
Term::Real(_) => Ok(targs[0].clone()),
Term::List(_) => Ok(context.factory.list(iter::empty())),
Term::Application(ref v, _) => Ok(context.factory.string(v.clone())),
Term::List(_) => Ok(context.factory.nil()),
Term::String(v) |
Term::Application(v, _) => Ok(context.factory.string(v.clone())),
Term::Blob(ref b) => {
let mut str_repr = String::from("BLOB_");
b.to_ascii(&mut str_repr).map_err(|_| Error::StrategyFailed)?;
......@@ -69,7 +69,7 @@ pub fn mkterm<'d, 'f: 'd>(
let s = truncate_at_illegal_chars(s);
targs[1]
.get_list()
.map(|l| context.factory.application(s, l.into_iter().cloned()))
.map(|l| context.factory.application(s, l.into_iter()))
.ok_or(Error::StrategyFailed)
}
})
......@@ -102,14 +102,13 @@ pub fn get_arguments<'d, 'f: 'd>(
targs: Vec<ATermRef<'f>>,
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
use std::iter;
if targs.len() < 1 {
return Err(Error::UnknownBehaviour(
"Primitive get_arguments called with wrong argument \
count",
));
}
let empty_list = context.factory.list(iter::empty());
let empty_list = context.factory.nil();
// filter out strings first as we'll match on application later
targs[0]
.get_int()
......@@ -237,10 +236,6 @@ pub fn preserve_annotations_attachments<'d, 'f: 'd>(
wrong argument count",
));
}
// TODO: Support attachments
let after = eval_sdef(&sargs[0], context, Vec::new(), Vec::new(), current.clone())?;
Ok(context.factory.set_annos(
after,
current.annotations.iter().cloned(),
))
Ok(context.factory.with_annos_attachments(after, current.annotations.iter().cloned(), current.get_attachments()))
}
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