https://svn.lrde.epita.fr/svn/xrm/trunk
Index: ChangeLog
from SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr>
Add constant folding / constant expression evaluation.
* src/str/prism-desugar.str: Here.
prism-desugar.str | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 107 insertions(+), 5 deletions(-)
Index: src/str/prism-desugar.str
--- src/str/prism-desugar.str (revision 22)
+++ src/str/prism-desugar.str (working copy)
@@ -4,13 +4,115 @@
strategies
prism-desugar =
- topdown(repeat(PrismDesugar))
+ innermost(
+ RemoveUnconditionnalUpdates
+ <+ AddZero <+ MulOne <+ MulZero <+ DivOne <+ warn-div-by-zero
+ <+ EvalPlus <+ EvalMinus <+ EvalMul <+ EvalDiv
+ <+ EvalLt <+ EvalLtEq <+ EvalGt <+ EvalGtEq <+ EvalEq <+ EvalNeq
+ )
rules
- PrismDesugar:
- // [] guard -> unconditionnal-update-list;
- // is rewritten as:
- // [] guard -> 1:(unconditionnal-update-list);
+ /**
+ ** [] guard -> unconditionnal-update-list;
+ ** is rewritten as:
+ ** [] guard -> 1:(unconditionnal-update-list);
+ */
+ RemoveUnconditionnalUpdates:
AlwaysUpdate(UpdateList(update-elements))
-> ProbUpdateList([ProbUpdate(Int("1"), UpdateList(update-elements))])
+
+/**
+** Constant folding / Constant expression evaluation
+*/
+strategies
+
+ // used by the rules below to evaluate constant comparisons
+ compare(s) = if s then !True() else !False() end
+
+ // for some reason the following rules are only defined for integers
+ // in the stratego-lib. Here is their equivalant for reals.
+ // NOTE: We only keep 6 digits after the period
+ addR = (string-to-real, string-to-real); addr; real-to-string(|6)
+ subtR = (string-to-real, string-to-real); subtr; real-to-string(|6)
+ mulR = (string-to-real, string-to-real); mulr; real-to-string(|6)
+ divR = (string-to-real, string-to-real); divr; real-to-string(|6)
+
+ warn-div-by-zero =
+ ?Div(e, Int("0")); fatal-err-msg(|"Division by zero")
+
+rules
+
+ AddZero:
+ Plus(e, Int("0")) -> e
+ AddZero:
+ Plus(Int("0"), e) -> e
+
+ MulOne:
+ Mul(e, Int("1")) -> e
+ MulOne:
+ Mul(Int("1"), e) -> e
+
+ MulZero:
+ Mul(e, Int("0")) -> Int("0")
+ MulZero:
+ Mul(Int("0"), e) -> Int("0")
+
+ DivOne:
+ Div(e, Int("1")) -> e
+
+ EvalPlus:
+ Plus(Int(i), Int(j)) -> Int(<addS>(i, j))
+ EvalPlus:
+ Plus(Double(i), Int(j)) -> Double(<addR>(i, j))
+ EvalPlus:
+ Plus(Int(i), Double(j)) -> Double(<addR>(i, j))
+ EvalPlus:
+ Plus(Double(i), Double(j)) -> Double(<addR>(i, j))
+
+ EvalMinus:
+ Minus(Int(i), Int(j)) -> Int(<subtS>(i, j))
+ EvalMinus:
+ Minus(Double(i), Int(j)) -> Double(<subtR>(i, j))
+ EvalMinus:
+ Minus(Int(i), Double(j)) -> Double(<subtR>(i, j))
+ EvalMinus:
+ Minus(Double(i), Double(j)) -> Double(<subtR>(i, j))
+
+ EvalMul:
+ Mul(Int(i), Int(j)) -> Int(<mulS>(i, j))
+ EvalMul:
+ Mul(Double(i), Int(j)) -> Double(<mulR>(i, j))
+ EvalMul:
+ Mul(Int(i), Double(j)) -> Double(<mulR>(i, j))
+ EvalMul:
+ Mul(Double(i), Double(j)) -> Double(<mulR>(i, j))
+
+ EvalDiv:
+ Div(Int(i), Int(j)) -> Double(<divR>(i, j))
+ EvalDiv:
+ Div(Double(i), Int(j)) -> Double(<divR>(i, j))
+ EvalDiv:
+ Div(Int(i), Double(j)) -> Double(<divR>(i, j))
+ EvalDiv:
+ Div(Double(i), Double(j)) -> Double(<divR>(i, j))
+
+ // FIXME: considere adding the Double's in the following:
+
+ EvalLt:
+ Lt(Int(i), Int(j)) -> <compare(ltS)>(i, j)
+
+ EvalLtEq:
+ LtEq(Int(i), Int(j)) -> <compare(leqS)>(i, j)
+
+ EvalGt:
+ Gt(Int(i), Int(j)) -> <compare(gtS)>(i, j)
+
+ EvalGtEq:
+ GtEq(Int(i), Int(j)) -> <compare(geqS)>(i, j)
+
+ EvalEq:
+ Eq(Int(i), Int(j)) -> <compare(eq)>(i, j)
+
+ EvalNeq:
+ NotEq(Int(i), Int(j)) -> <compare(not(eq))>(i, j)