Commit 56cac738 authored by Jeff Smits's avatar Jeff Smits

Fixed bug in preprocess/BuildTerm, annos were not put on variables

parent d5049e3c
This diff is collapsed.
module dynamic-rules-test
imports libstratego-lib
signature
constructors
Var : String -> Exp
Int : Int -> Exp
Plus : Exp * Exp -> Exp
Let : List(Decl) * Exp -> Exp
Call : String * List(Exp) -> Exp
Fdec : String * List(String) * Exp -> Decl
Vdec : String * Exp -> Decl
strategies
exp-rename =
rec r({| RenameCall, RenameVar :
try(RenameDeclaration + RenameArgs + RenameCall + RenameVar); all(r)
|})
RenameDeclaration =
Let(list(RenameFdec + RenameVdec), id)
RenameVdec :
Vdec(x, e) -> Vdec(y, e)
where new => y; rules(RenameVar : Var(x) -> Var(y))
RenameFdec :
Fdec(f, xs, e) -> Fdec(g, xs, e)
where new => g; rules(RenameCall : Call(f, es) -> Call(g, es))
RenameArgs :
Fdec(f, xs, e) -> Fdec(f, ys, e)
where <map(new)> xs => ys
; <zip({?(x,y); rules(RenameVar : Var(x) -> Var(y))})> (xs, ys)
my-inline =
rec i({| Inline :
repeat(Subst)
; (Declare; all(i)
<+ {| Subst : Inline; i |}
<+ all(i))
|})
Declare =
Let(list(DeclareFun + DeclareVar), id)
DeclareVar =
?Vdec(x,e);
rules(
Inline : Var(x) -> e
)
DeclareFun =
[email protected](f, _, _);
rules(
Inline :
Call(f,es) -> e
where <exp-rename> fdec => Fdec(_, xs, e)
; <zip({?(x,e); rules(Subst : Var(x) -> e)})> (xs, es)
)
strategies
main =
test-suite(!"dynamic-rules-test",
//test0;
test1//;
//test2;
//test3;
//test4a;
//test4b;
//test5;
//test6
)
test0 =
apply-test(!"test0"
, exp-rename
, !Let([Fdec("f", ["x"], Var("x"))],
Let([Fdec("g", ["x"], Plus(Int(1), Call("f", [Var("x")])))],
Let([Vdec("x", Int(1))],
Call("g", [Var("x")]))))
, !Let([Fdec("a_0",["b_0"],Var("b_0"))],
Let([Fdec("c_0",["d_0"],Plus(Int(1),Call("a_0",[Var("d_0")])))],
Let([Vdec("e_0",Int(1))],
Call("c_0",[Var("e_0")]))))
)
test1 =
apply-test(!"test1"
, my-inline
, !Let([Vdec("x", Int(1))], Call("g", [Var("x")]))
, !Let([Vdec("x", Int(1))], Call("g", [Int(1)]))
)
test2 =
apply-test(!"test2"
, my-inline
, !Let([Fdec("f", ["x"], Var("x"))],
Let([Fdec("g", ["x"], Plus(Int(1), Call("f", [Var("x")])))],
Let([Vdec("x", Int(1))], Call("g", [Var("x")]))))
, !Let([Fdec("f",["x"],Var("x"))],
Let([Fdec("g",["x"],Plus(Int(1),Var("x")))],
Let([Vdec("x",Int(1))],Plus(Int(1),Int(1)))))
)
test3 =
apply-test(!"test3"
, my-inline
, !Let([Fdec("f", ["x"], Plus(Int(1), Var("x")))],
Let([Fdec("g", ["x"], Call("f", [Var("x")]))],
Call("g", [Int(2)])))
, !Let([Fdec("f",["x"],Plus(Int(1),Var("x")))],
Let([Fdec("g",["x"],Plus(Int(1),Var("x")))],
Plus(Int(1),Int(2))))
)
strategies
define-bla =
?(f, g); rules(Bla : f -> g)
override1 =
<define-bla> ("f", "g")
; <Bla> "f" => x
; <define-bla> ("f", "h")
; <Bla> "f" => y
; !(x,y)
test4a =
apply-test(!"test4a"
, override1
, !()
, !("g", "h")
)
override2 =
<define-bla> ("f", "g")
; <Bla> "f" => x
; {| Bla :
<define-bla> ("f", "h")
; <Bla> "f" => y
; <define-bla> ("f", "i")
; <Bla> "f" => z
|}
; <Bla> "f" => a
; !(x,y,z,a)
test4b =
apply-test(!"test4b"
, override2
, !()
, !("g", "h", "i", "g")
)
strategies
UnDeclareFun =
?Fdec(f, _, _)
; rules( NewRule :- Call(f,_) )
test5 =
apply-test(!"test5"
, (UnDeclareFun,id); (id,try(NewRule))
, !(Fdec("f", "i", "g"), Call("f",[]))
, !(Fdec("f", "i", "g"), Call("f",[]))
)
strategies
GenRule1 =
!("a", "b"); ?(x, y); rules(Rule : x -> y)
GenRule2 =
!("a", "b"); ?(x, y); rules(Rule : x -> (y,y))
test6 =
where(GenRule1);
apply-test(!"test6a"
,Rule
,!"a"
,!"b"
);
where(GenRule2);
apply-test(!"test6b"
,Rule
,!"a"
,!("b","b")
)
This diff is collapsed.
module test73
imports libstratego-lib
strategies
test1 = ( rules( a : _ -> 1 ) /~["a"]\ rules( a : _ -> 0 ) ) ; a
test2 = ( rules( b : _ -> 1 ) /~["b"]\ rules( b : _ -> 1 ) ) ; b
test3 = ( rules( c : _ -> 1 ) /c\ rules( c : _ -> 0 ) ) ; c
test4 = ( rules( d : _ -> 1 ) /d\ rules( d : _ -> 1 ) ) ; d
strategies
main =
test-suite(!"intersection with rulenames",
test-it-now
)
test-it-now =
apply-and-fail(!"intersection with rulenames 1",test1,![])
; apply-test(!"intersection with rulenames 2",test2,![],!1)
; apply-and-fail(!"normal intersection 1",test3,![])
; apply-test(!"normal intersection 2",test4,![],!1)
......@@ -3,7 +3,6 @@ use ctree;
use error::{Result, Error};
use factory::{ATermFactory, ATermRef};
use interpreter::Eval;
use std::iter;
use interpreter::to_cons_nil_list;
use aterm::BrokenF32;
......@@ -311,12 +310,20 @@ impl TryFrom<ctree::Term> for BuildTerm {
match value {
I::Var(id) => Ok(O::Var(id)),
I::Anno(term, annos) => {
match *annos {
P::Op(ref c, ref r) if c == "Nil" && r.is_empty() => (*term).try_into(),
_ => {
let pt1 = try_into_box(term)?;
let pt2 = try_into_box(annos)?;
Ok(O::Anno(pt1, pt2))
if let P::Var(_) = *term {
let pt1 = try_into_box(term)?;
let pt2 = try_into_box(annos)?;
Ok(O::Anno(pt1, pt2))
} else {
match *annos {
P::Op(ref c, ref r) if c == "Nil" && r.is_empty() => {
(*term).try_into()
},
_ => {
let pt1 = try_into_box(term)?;
let pt2 = try_into_box(annos)?;
Ok(O::Anno(pt1, pt2))
}
}
}
}
......@@ -355,36 +362,42 @@ impl TryFrom<ctree::PreTerm> for BuildTerm {
impl BuildTerm {
pub fn build<'a>(&self, context: &MutContext<'a>) -> Result<ATermRef> {
self.build_with_annos(context, iter::empty())
self.build_with_annos(context, None)
}
fn build_with_annos<'a, I>(&self, context: &MutContext<'a>, annos: I) -> Result<ATermRef>
where I: IntoIterator<Item = ATermRef>
{
fn build_with_annos<'a>(&self, context: &MutContext<'a>, annos: Option<Vec<ATermRef>>) -> Result<ATermRef> {
use self::BuildTerm::*;
match *self {
Var(ref s) => context.get_term(s),
Var(ref s) => {
use interpreter::b;
if let Some(annos) = annos {
let term = context.get_term(s)?;
Ok(context.factory.with_annos(b(&term).as_inner().term.clone(), annos))
} else {
context.get_term(s)
}
},
Int(i) => {
Ok(context
.factory
.with_annos(context.factory.t_int(i), annos))
.with_annos(context.factory.t_int(i), annos.unwrap_or_default()))
}
Real(BrokenF32(f)) => {
Ok(context
.factory
.with_annos(context.factory.t_real(f), annos))
.with_annos(context.factory.t_real(f), annos.unwrap_or_default()))
}
Str(ref s) => {
Ok(context
.factory
.with_annos(context.factory.t_string(s.clone()), annos))
.with_annos(context.factory.t_string(s.clone()), annos.unwrap_or_default()))
}
Op(ref s, ref t) => {
let t = Self::build_vec(context, t)?;
Ok(context
.factory
.with_annos(context.factory.t_application(s.clone(), t.into_iter()),
annos))
annos.unwrap_or_default()))
}
Explode(ref cons, ref children) => {
use aterm::Term::*;
......@@ -403,7 +416,7 @@ impl BuildTerm {
context
.factory
.t_application(ctree::string_unescape(c), children.iter().cloned());
return Ok(context.factory.with_annos(application, annos));
return Ok(context.factory.with_annos(application, annos.unwrap_or_default()));
}
// According to STR-626 non-string constructor term implosion should fail
// Which the STR/J does when interpreting, but the compiled version just does
......@@ -424,12 +437,12 @@ impl BuildTerm {
// used!
Anno(ref term, ref annos) => {
use interpreter::from_cons_nil_list;
// TODO: specialise annos case of list literal again, but note that's not the only case!
// TODO: Optimisation idea; try specialising the case where annos is a list literal
let annos: ATermRef = (**annos).build(context)?;
if let Ok(annos_vec) = from_cons_nil_list(annos.clone()) {
term.build_with_annos(context, annos_vec)
term.build_with_annos(context, Some(annos_vec))
} else {
term.build_with_annos(context, iter::once(annos))
term.build_with_annos(context, Some(vec![annos]))
}
}
}
......
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