https://svn.lrde.epita.fr/svn/xrm/trunk
Index: ChangeLog
from SIGOURE Benoit <sigoure.benoit(a)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