https://svn.lrde.epita.fr/svn/xrm/trunk
Index: ChangeLog
from SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr>
Improve desugarisation, fix concrete syntax.
* src/str/xrm-front.str: Remove empty line.
* src/str/prism-desugar.meta: New.
* src/str/Makefile.am: Update header.
* src/str/prism-desugar.str: Use concrete syntax. Improve
and simplify desugarisation. Extend to doubles.
* src/str/reals.str: New.
* src/syn/xrm/Makefile.am: Add parse table generation for concrete
syntax.
* src/syn/prism/Makefile.am: Likewise.
* src/syn/prism/PRISM-MetaVars.sdf: Fix meta-vars.
* src/syn/prism/PRISM-Identifier.sdf: Fix restrictions.
str/Makefile.am | 4 -
str/prism-desugar.meta | 1
str/prism-desugar.str | 111 ++++++++++++++++++++---------------------
str/reals.str | 27 +++++++++
str/xrm-front.str | 1
syn/prism/Makefile.am | 5 +
syn/prism/PRISM-Identifier.sdf | 4 +
syn/prism/PRISM-MetaVars.sdf | 7 +-
syn/xrm/Makefile.am | 5 +
9 files changed, 98 insertions(+), 67 deletions(-)
Index: src/str/xrm-front.str
--- src/str/xrm-front.str (revision 23)
+++ src/str/xrm-front.str (working copy)
@@ -113,7 +113,6 @@
must-desugar =
<get-config> "desugar" => "yes"
-
/**
* Documentation
*/
Index: src/str/prism-desugar.meta
--- src/str/prism-desugar.meta (revision 0)
+++ src/str/prism-desugar.meta (revision 0)
@@ -0,0 +1 @@
+Meta([Syntax("StrategoXRM")])
Index: src/str/Makefile.am
--- src/str/Makefile.am (revision 23)
+++ src/str/Makefile.am (working copy)
@@ -1,11 +1,11 @@
##
-## Makefile.am for xrm in /home/tsuna/work/xrm/trunk/src
+## Makefile.am for xrm in /home/tsuna/work/xrm/trunk/src/str
##
## Made by SIGOURE Benoit
## Mail <sigoure.benoit(a)lrde.epita.fr>
##
## Started on Thu Apr 27 17:59:35 2006 SIGOURE Benoit
-## Last update Fri May 12 16:55:22 2006 SIGOURE Benoit
+## Last update Thu May 18 16:49:50 2006 SIGOURE Benoit
##
include $(top_srcdir)/config/Transformers.mk
Index: src/str/prism-desugar.str
--- src/str/prism-desugar.str (revision 23)
+++ src/str/prism-desugar.str (working copy)
@@ -1,15 +1,48 @@
module prism-desugar
-imports PRISM
+imports
+ PRISM
+ reals
strategies
+ /**
+ ** 1. First convert all literal ints to doubles. This makes the
+ ** simplifications easier to write since there is less cases to
+ ** address (eg: int + int, int + double, double + int,
+ ** double + double etc.).
+ ** 2. Desugar the AST
+ ** 3. Convert the doubles which are round numbers back to ints.
+ ** Simplify doubles (round them up and remove trailing zeros)
+ */
prism-desugar =
- innermost(
+ topdown(try(IntToDouble))
+ ; innermost(
RemoveUnconditionnalUpdates
- <+ AddZero <+ MulOne <+ MulZero <+ DivOne <+ warn-div-by-zero
+ <+ AddZero <+ MulOne <+ MulZero <+ DivOne <+ catch-div-by-zero
<+ EvalPlus <+ EvalMinus <+ EvalMul <+ EvalDiv
<+ EvalLt <+ EvalLtEq <+ EvalGt <+ EvalGtEq <+ EvalEq <+ EvalNeq
)
+ ; topdown(try(SimplifyDoubles <+ TruncateDouble))
+
+rules
+
+ IntToDouble: Int(i) -> Double(i)
+
+ // Transform a round (or almost round) Double into an Int.
+ SimplifyDoubles:
+ Double(d) -> Int(i) // eg: Double("41.9999999999999") ->
Int("42")
+ where !d // "41.9999999999999"
+ ; string-to-real // 4.199999999999990e+01
+ ; real-to-string(|6) // "42.000000"
+ ; split-at-dot // ("42", "000000")
+ ; (?i, ?decimals) // i="42", decimals="000000"
+ // strcmp(decimals, "000000") == 0 ? id : fail
+ ; <strcmp> (<explode-string> decimals, <explode-string>
"000000") => 0
+
+ // Round real numbers up to 6 digits and remove trailing zeros
+ TruncateDouble:
+ Double(d) -> Double(d')
+ where <rtrim-chars(?'0')> (<real-to-string(|6)>
(<string-to-real> d)) => d'
rules
@@ -30,89 +63,55 @@
// 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")
+ catch-div-by-zero =
+ ?|[ e / 0 ]|; fatal-err-msg(|"Division by zero detected")
rules
AddZero:
- Plus(e, Int("0")) -> e
+ |[ e + 0 ]| -> |[ e ]|
AddZero:
- Plus(Int("0"), e) -> e
+ |[ 0 + e ]| -> |[ e ]|
MulOne:
- Mul(e, Int("1")) -> e
+ |[ e * 1 ]| -> |[ e ]|
MulOne:
- Mul(Int("1"), e) -> e
+ |[ 1 * e ]| -> |[ e ]|
MulZero:
- Mul(e, Int("0")) -> Int("0")
+ |[ e * 0 ]| -> |[ 0 ]|
MulZero:
- Mul(Int("0"), e) -> Int("0")
+ |[ 0 * e ]| -> |[ 0 ]|
DivOne:
- Div(e, Int("1")) -> e
+ |[ e / 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))
+ |[ d1 + d2 ]| -> |[ r ]| where <addR>(d1, d2) => r
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))
+ |[ d1 - d2 ]| -> |[ r ]| where <subtR>(d1, d2) => r
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))
+ |[ d1 * d2 ]| -> |[ r ]| where <mulR>(d1, d2) => r
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:
+ |[ d1 / d2 ]| -> |[ r ]| where <divR>(d1, d2) => r
EvalLt:
- Lt(Int(i), Int(j)) -> <compare(ltS)>(i, j)
+ |[ d1 < d2 ]| -> <compare(ltR)>(d1, d2)
EvalLtEq:
- LtEq(Int(i), Int(j)) -> <compare(leqS)>(i, j)
+ |[ d1 <= d2 ]| -> <compare(leqR)>(d1, d2)
EvalGt:
- Gt(Int(i), Int(j)) -> <compare(gtS)>(i, j)
+ |[ d1 > d2 ]| -> <compare(gtR)>(d1, d2)
EvalGtEq:
- GtEq(Int(i), Int(j)) -> <compare(geqS)>(i, j)
+ |[ d1 >= d2 ]| -> <compare(geqR)>(d1, d2)
EvalEq:
- Eq(Int(i), Int(j)) -> <compare(eq)>(i, j)
+ |[ d1 = d2 ]| -> <compare(real-eq)>(d1, d2)
EvalNeq:
- NotEq(Int(i), Int(j)) -> <compare(not(eq))>(i, j)
+ |[ d1 != d2 ]| -> <compare(not(real-eq))>(d1, d2)
Index: src/str/reals.str
--- src/str/reals.str (revision 0)
+++ src/str/reals.str (revision 0)
@@ -0,0 +1,27 @@
+module reals
+
+strategies
+
+ // for some reason the following rules are only defined for integers
+ // in the stratego-lib. Here is their equivalant for reals.
+ addR = (string-to-real, string-to-real); addr; real-to-string
+ subtR = (string-to-real, string-to-real); subtr; real-to-string
+ mulR = (string-to-real, string-to-real); mulr; real-to-string
+ divR = (string-to-real, string-to-real); divr; real-to-string
+ gtR = where((string-to-real, string-to-real); gtr)
+ geqR = where((string-to-real, string-to-real); ?(x,x) <+ gtr)
+ ltR = where((string-to-real, string-to-real); not(?(x,x) <+ gtr))
+ leqR = where((string-to-real, string-to-real); not(gtr))
+
+ /**
+ ** tests whether two reals are equal
+ ** => tests if there difference is less than 10^-7
+ ** operates on the input term (a, b)
+ ** eg: <real-eq> ("0.42", "0.43") -> fail
+ */
+ real-eq =
+ (string-to-real, string-to-real)
+ ; subtr
+ ; abs => difference
+ ; <not(gtr)>(difference, 0.0000001)
+
Index: src/syn/xrm/Makefile.am
--- src/syn/xrm/Makefile.am (revision 23)
+++ src/syn/xrm/Makefile.am (working copy)
@@ -5,7 +5,7 @@
## Mail <sigoure.benoit(a)lrde.epita.fr>
##
## Started on Thu Apr 27 17:40:41 2006 SIGOURE Benoit
-## Last update Fri May 12 16:57:54 2006 SIGOURE Benoit
+## Last update Thu May 18 16:53:05 2006 SIGOURE Benoit
##
include $(top_srcdir)/config/Transformers.mk
@@ -28,7 +28,8 @@
XRM.str \
XRM-StartSymbols.tbl \
XRM-Prefixed.def \
- StrategoXRM.def
+ StrategoXRM.def \
+ StrategoXRM.tbl
pkgdata_DATA = $(pkgdata_DATA_built)
sdfdata_DATA = $(pkgdata_DATA_built)
Index: src/syn/prism/PRISM-MetaVars.sdf
--- src/syn/prism/PRISM-MetaVars.sdf (revision 23)
+++ src/syn/prism/PRISM-MetaVars.sdf (working copy)
@@ -1,9 +1,10 @@
module PRISM-MetaVars
exports
variables
- [ijkln][0-9]* -> Int {prefer}
- [xyzfgh][0-9]* -> Identifier {prefer}
- [xyzfgh][0-9]* "'" -> IdentifierPrime {prefer}
+ [ijkln][0-9]* -> LInt {prefer}
+ [dr][0-9]* -> LDouble {prefer}
+ [xyzfgh][0-9]* -> ID {prefer}
+%% [xyzfgh][0-9]* "'" -> IdentifierPrime {prefer}
[e][0-9]* -> Expression {prefer}
"a"[0-9]* "*" -> {Identifier ","}+ {prefer}
[m][0-9]* -> Module {prefer}
Index: src/syn/prism/PRISM-Identifier.sdf
--- src/syn/prism/PRISM-Identifier.sdf (revision 23)
+++ src/syn/prism/PRISM-Identifier.sdf (working copy)
@@ -31,7 +31,9 @@
Keyword -> ID {reject}
lexical restrictions
- Identifier -/- [A-Za-z0-9\_]
+ ID -/- [A-Za-z0-9\_]
+
+ context-free restrictions
IdentifierPrime -/- [A-Za-z0-9\_]%% "'"
%% FIXME ^^^
%% causes an error oO
Index: src/syn/prism/Makefile.am
--- src/syn/prism/Makefile.am (revision 23)
+++ src/syn/prism/Makefile.am (working copy)
@@ -5,7 +5,7 @@
## Mail <sigoure.benoit(a)lrde.epita.fr>
##
## Started on Thu Apr 27 17:40:41 2006 SIGOURE Benoit
-## Last update Fri May 12 16:52:04 2006 SIGOURE Benoit
+## Last update Thu May 18 16:52:52 2006 SIGOURE Benoit
##
include $(top_srcdir)/config/Transformers.mk
@@ -26,7 +26,8 @@
PRISM.str \
PRISM-StartSymbols.tbl \
PRISM-Prefixed.def \
- StrategoPRISM.def
+ StrategoPRISM.def \
+ StrategoPRISM.tbl
pkgdata_DATA = $(pkgdata_DATA_built)
sdfdata_DATA = $(pkgdata_DATA_built)