https://svn.lrde.epita.fr/svn/xrm/trunk
Index: ChangeLog from SIGOURE Benoit sigoure.benoit@lrde.epita.fr
Remove debugging messages from prism-desugar.
* src/str/prism-desugar.str: Remove debugging stuff. * tests/prism/range-desugar.pm: New.
src/str/prism-desugar.str | 119 +++++++++++++++++++++++++++++++++++-------- tests/prism/range-desugar.pm | 13 ++++ 2 files changed, 112 insertions(+), 20 deletions(-)
Index: src/str/prism-desugar.str --- src/str/prism-desugar.str (revision 38) +++ src/str/prism-desugar.str (working copy) @@ -21,7 +21,7 @@ RemoveUnconditionnalUpdates <+ AddZero <+ MulOne <+ MulZero <+ DivOne <+ catch-div-by-zero <+ EvalPlus <+ EvalMinus <+ EvalMul <+ EvalDiv - <+ EvalLt <+ EvalLtEq <+ EvalGt <+ EvalGtEq <+ EvalEq <+ EvalNeq + <+ EvalLt <+ EvalLtEq <+ EvalGt <+ EvalGtEq <+ EvalEq <+ EvalNotEq <+ EvalAnd <+ EvalOr <+ EvalMin <+ EvalMax <+ EvalFloor <+ EvalCeil <+ EvalPow <+ EvalMod ) @@ -101,6 +101,15 @@ ** the end of an integer literal make it a Double() and not an Int() [This ** is one of the minor extensions of XRM] */ + +/* +** ## ======== ## +** ## Simplify ## +** ## ======== ## +** +** Simplify arithmetic operations. +*/ + rules
AddZero: @@ -121,6 +130,12 @@ DivOne: |[ e / 1D ]| -> |[ e ]|
+/* +** ## ==================== ## +** ## Constant propagation ## +** ## ==================== ## +*/ + rules
EvalPlus: @@ -147,46 +162,102 @@ EvalGtEq: |[ d1 >= d2 ]| -> <compare(geqR)>(d1, d2)
+/* +** ## ============== ## +** ## Equality tests ## +** ## ============== ## +** +** - Eval constant equality tests (eg: 1=3 -> false) +** - Desugar complex equality tests +** eg: x=1..5,7,10..13 -> (x>=1 & x<=5) | (x=7) | (x>=10 & x<=13) +** This part is a bit complex since we need to handle several cases in +** different ways. +*/ + +strategies + + /** Simple constant equality tests */ EvalSimpleEq: |[ d1 = d2 ]| -> res - where say(!"@@@ EvalSimpleEq");debug - ; <compare(real-eq)>(d1, d2) => res;debug + where <compare(real-eq)>(d1, d2) => res
+ /** Simple equality tests with a range (eg: x=[1..5]) */ EvalSimpleRangeEq: |[ e = e1..e2 ]| -> res - where say(!"@@@ EvalSimpleRangeEq range");debug - ; <DesugarRangeEq(|e)>(Range(e1, e2)) => res;debug + where <DesugarRangeEq(|e)>(Range(e1, e2)) => res
+ /** Complex equality tests (something not in the form of x=exp) */ EvalComplexEq: Eq(e, a*) -> res - where say(!"@@@ EvalComplexEq");<debug>a* - ; !a* - ; map(DesugarRangeEq(|e) <+ \ e2 -> |[ e=e2 ]| );debug + where !a* + ; map(DesugarRangeEq(|e) <+ \ e2 -> |[ e=e2 ]| ) ; foldr(!False(), \ (x, y) -> Or(x, y) ) => res - ; say(!" end of EvalComplexEq:");debug
strategies
- EvalEq = ?a;?Eq(_,_);say(!"@@@ EvalEq starting:");debug;rules(Hello: a); - (?Eq(_, [Eq(_, _)]) <+ EvalSimpleEq <+ EvalSimpleRangeEq <+ (?|[ e = e2 ]| < debug;fail + EvalComplexEq)) + /** Eval/desugar an equality test. + ** 1. Try to see whether it's a simple constant equality test in which + ** case it can be evaluated right away. + ** 2. Try to see whether it's a simple equality test with a range, in + ** which case it can be desugared (and maybe latter evaluated by + ** another pass) + ** 3. a) If 1/ and 2/ failed, and if we have an equality test of the + ** form x = exp, we can't desugar/evaluate it further, so give up. + ** b) If 1/ and 2/ failed but we're not on a simple equality test, + ** try to desugar it further since it's a complex equality test. + */ + EvalEq = + EvalSimpleEq + <+ EvalSimpleRangeEq + <+ (?|[ e = e2 ]| < fail + EvalComplexEq)
rules
+ DesugarRangeEq(|e): + Range(e2, e3) -> |[ e >= e2 & e <= e3]| + +/* +** ## ================= ## +** ## "Not equal" tests ## +** ## ================= ## +** +** Everything works in the exact same way as the above for equality tests. +*/ + +strategies + + EvalSimpleNotEq: + |[ d1 != d2 ]| -> res + where <compare(not(real-eq))>(d1, d2) => res + + EvalSimpleRangeNotEq: + |[ e != e1..e2 ]| -> res + where <DesugarRangeNotEq(|e)>(Range(e1, e2)) => res
- //EvalNeq: - // |[ d1 != d2 ]| -> <compare(not(real-eq))>(d1, d2) - EvalNeq: + EvalComplexNotEq: NotEq(e, a*) -> res - where say(!"@@@ EvalNeq");<not(?[_])>a*;<debug>a* - ; map(DesugarRangeNeq(|e) <+ \ e2 -> |[ e!=e2 ]| );debug - ; foldr(!False(), \ (x, y) -> Or(x, y) ) => res;debug + where !a* + ; map(DesugarRangeNotEq(|e) <+ \ e2 -> |[ e!=e2 ]| ) + ; foldr(!False(), \ (x, y) -> Or(x, y) ) => res
- DesugarRangeEq(|e): - Range(e2, e3) -> |[ e >= e2 & e <= e3]| +strategies
- DesugarRangeNeq(|e): + EvalNotEq = + EvalSimpleNotEq + <+ EvalSimpleRangeNotEq + <+ (?|[ e != e2 ]| < fail + EvalComplexNotEq) + +rules + + DesugarRangeNotEq(|e): Range(e2, e3) -> |[ e < e2 & e > e3]|
+/* +** ## ================= ## +** ## Logical operators ## +** ## ================= ## +*/ + rules
EvalAnd: @@ -211,6 +282,14 @@ EvalOr: |[ false | e ]| -> |[ e ]|
+/* +** ## ============= ## +** ## Eval Builtins ## +** ## ============= ## +** +** Try to evaluate builtin calls. +*/ + rules
EvalMin: Index: tests/prism/range-desugar.pm --- tests/prism/range-desugar.pm (revision 0) +++ tests/prism/range-desugar.pm (revision 0) @@ -0,0 +1,13 @@ +module range + x : [0..42] init 0; + + [] 10=1,10 -> true; + [] 10=1..10 -> true; + [] 10=1,2..11 -> true; + [] 10=1,2..11,12 -> true; + + [] x=1,10 -> true; + [] x=1..10 -> true; + [] x=1,2..11 -> true; + [] x=1,2..11,12 -> true; +endmodule