Projects
Threads by month
- ----- 2025 -----
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
May 2006
- 10 participants
- 53 discussions
>>> "SIGOURE" == SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr> writes:
> + , Summary("Transforms an eXtended Reactive Module source file in a
> + PRISM-equivalant abstract syntax tree (default) or source
Equivalent.
Other than that, nice patch!
2
1
>>> "SIGOURE" == SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr> writes:
> AddZero:
> - Plus(e, Int("0")) -> e
> + |[ e + 0 ]| -> |[ e ]|
Cool !
> 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
Très cool.
> 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.
equivalent. Emacs dispose de correction orthographique des chaînes et
des commentaires, je suppose de vim aussi.
> + 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))
Pourquoi des where dans la seconde partie ?
> + /**
> + ** 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
> + */
Ce sont des commentaires xDoc ça ?
2
1
https://svn.lrde.epita.fr/svn/xrm/trunk
Index: ChangeLog
from SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr>
Clean up the code and add more tests.
* src/str/xrm-to-prism.str: Big chunks moved to ...
* src/str/check-meta-vars.str: this and...
* src/str/desugar-array-accesses.str: this and...
* src/str/eval-meta-code.str: this.
* src/str/ice.str: New.
* src/str/prism-desugar.str: Change some comments.
* tests/test-pp-prism.sh.in: Add more tests.
* tests/test-parse-xrm.sh.in: Ditto.
* tests/test-parse-prism.sh.in: Ditto.
* tests/test-pp-xrm.sh.in: Ditto.
src/str/check-meta-vars.str | 60 ++++++++++
src/str/desugar-array-accesses.str | 66 +++++++++++
src/str/eval-meta-code.str | 113 ++++++++++++++++++
src/str/ice.str | 22 +++
src/str/prism-desugar.str | 8 -
src/str/xrm-to-prism.str | 222 ++-----------------------------------
tests/test-parse-prism.sh.in | 2
tests/test-parse-xrm.sh.in | 2
tests/test-pp-prism.sh.in | 2
tests/test-pp-xrm.sh.in | 2
10 files changed, 282 insertions(+), 217 deletions(-)
Index: src/str/check-meta-vars.str
--- src/str/check-meta-vars.str (revision 0)
+++ src/str/check-meta-vars.str (revision 0)
@@ -0,0 +1,60 @@
+/*
+** This sub-module is used to check that meta-vars are correctly used
+** throughout the program. This implies:
+** - checking that they have been defined when they're used
+** - checking that they are not redefined in the same scope
+** - checking that some expressions are only using meta-variables to
+** ensure that they are statically evaluable. (eg: array subscripts,
+** meta-if conditions)
+*/
+module check-meta-vars
+
+strategies
+
+ check-meta-vars =
+ check-meta-for
+ <+ check-meta-if
+ <+ ArrayAccess(id, check-all-identifers-are-meta-vars)
+ <+ ArrayAccessPrime(id, check-all-identifers-are-meta-vars)
+ <+ all(check-meta-vars)
+
+ check-meta-for =
+ ?MetaFor(new-meta-var, from, to, step, body)
+ ; where({| MetaVars:
+ <add-meta-var> new-meta-var
+ ; <check-all-identifers-are-meta-vars> from
+ ; <check-all-identifers-are-meta-vars> to
+ ; <check-all-identifers-are-meta-vars> step
+ ; <check-meta-vars> body
+ |})
+
+ check-meta-if =
+ ?MetaIf(condition, then-part, else-part)
+ ; where(
+ <check-all-identifers-are-meta-vars> condition
+ ; <check-meta-vars> then-part
+ ; <check-meta-vars> else-part
+ )
+
+ check-all-identifers-are-meta-vars =
+ (?Identifier(_); check-meta-var-declared)
+ <+ all(check-all-identifers-are-meta-vars)
+
+ add-meta-var =
+ check-meta-var-unicity
+ ; ?meta-var
+ ; rules(MetaVars: meta-var)
+
+ check-meta-var-declared =
+ ?Identifier(idf)
+ ; if not(<MetaVars> Identifier(idf)) then
+ err-msg(|<concat-strings>["undeclared meta-var: ", idf])
+ ; <xtc-exit> 2
+ end
+
+ check-meta-var-unicity =
+ ?Identifier(idf)
+ ; if <MetaVars> Identifier(idf) then
+ err-msg(|<concat-strings>["meta-var already defined: ", idf])
+ ; <xtc-exit> 2
+ end
Index: src/str/desugar-array-accesses.str
--- src/str/desugar-array-accesses.str (revision 0)
+++ src/str/desugar-array-accesses.str (revision 0)
@@ -0,0 +1,66 @@
+module desugar-array-accesses
+
+rules
+
+ /**
+ ** Transform an array access into an identifier (eg: x[i] -> x_i)
+ */
+ remove-array-accesses:
+ ArrayAccess(Identifier(idf), access-list) -> Identifier(idf')
+ where flatten-access-list(|idf, access-list) => idf'
+
+ remove-array-accesses:
+ ArrayAccessPrime(Identifier(idf), access-list) -> IdentifierPrime(idf')
+ where flatten-access-list(|idf, access-list) => idf'
+
+strategies
+
+ /**
+ ** @internal
+ ** Transform an access list (in array accesses) into a flat variable name
+ ** eg: flatten-access-list(|"x", [Int("1"), Int("2")]) -> "x_1_2"
+ ** NOTE: The access list can contain expressions as long as it possible to
+ ** evaluate them down to a constant positive Int() value.
+ **
+ ** @param idf String
+ ** @param access-list List of Int()
+ */
+ flatten-access-list(|idf, access-list) =
+ /* eval meta expressions in the access-list
+ * eg: Plus(Int("1"), Int("2")) -> Int("3") */
+ <prism-desugar> access-list
+
+ /* Now the access must only contain a list of Int: [Int("1"), Int("2"), ..]
+ * So we can remove the Int() constructor. */
+ ; map(\ Int(i) -> i \ <+ invalid-array-access)
+
+ /* Now we have a list of strings such as: ["1", "2", ...]
+ * Check that the list only contains positive integers as strings */
+ ; try(map(string-to-int; neg; invalid-array-access))
+
+ /* Insert underscores between each integer */
+ ; separate-by(|"_")
+
+ /* Produce the final identifier: eg: idf_1_2 */
+ ; <concat-strings> [idf, "_" | <id>]
+
+ /**
+ ** @internal
+ ** Report invalid array accesses.
+ */
+ invalid-array-access =
+ if ?Identifier(i) then
+ ice(|"invalid-array-access", <concat-strings>["internal compiler error: ",
+ "undeclared meta-variable: ", i,
+ " (should have been detected earlier!)"])
+ else
+ if (is-int; neg) then
+ err-msg(|"error: negative array subscript detected:")
+ ; debug
+ ; <xtc-exit> 2
+ else
+ err-msg(|"error: non constant term in array access:")
+ ; debug
+ ; <xtc-exit> 2
+ end
+ end
Index: src/str/xrm-to-prism.str
--- src/str/xrm-to-prism.str (revision 28)
+++ src/str/xrm-to-prism.str (working copy)
@@ -1,7 +1,14 @@
+/*
+** This sub-module does the real work of the front-end. It transforms the
+** program into a valid PRISM AST.
+*/
module xrm-to-prism
imports
XRM
prism-desugar
+ desugar-array-accesses
+ check-meta-vars
+ eval-meta-code
strategies
@@ -34,6 +41,7 @@
xrm-to-prism-desugar:
|[ e1 << e2 ]| -> |[ e1 * func(pow, 2, e2) ]|
+ // if the step is not specified, it is implicitely set to 1
xrm-to-prism-desugar:
MetaFor(identifier, from, to, body)
-> MetaFor(identifier, from, to, Int("1"), body)
@@ -43,74 +51,10 @@
//|[ if e then s* end ]| -> |[ if e then s* else end ]|
MetaIf(e, m*) -> MetaIf(e, m*, [])
-rules
-
- /**
- ** Transform an array access into an identifier (eg: x[i] -> x_i)
- */
- remove-array-accesses:
- ArrayAccess(Identifier(idf), access-list) -> Identifier(idf')
- where flatten-access-list(|idf, access-list) => idf'
-
- remove-array-accesses:
- ArrayAccessPrime(Identifier(idf), access-list) -> IdentifierPrime(idf')
- where flatten-access-list(|idf, access-list) => idf'
-
strategies
/**
- ** @internal
- ** Transform an access list (in array accesses) into a flat variable name
- ** eg: flatten-access-list(|"x", [Int("1"), Int("2")]) -> "x_1_2"
- ** NOTE: The access list can contain expressions as long as it possible to
- ** evaluate them down to a constant positive Int() value.
- **
- ** @param idf String
- ** @param access-list List of Int()
- */
- flatten-access-list(|idf, access-list) =
- /* eval meta expressions in the access-list
- * eg: Plus(Int("1"), Int("2")) -> Int("3") */
- <prism-desugar> access-list
-
- /* Now the access must only contain a list of Int: [Int("1"), Int("2"), ..]
- * So we can remove the Int() constructor. */
- ; map(\ Int(i) -> i \ <+ invalid-array-access)
-
- /* Now we have a list of strings such as: ["1", "2", ...]
- * Check that the list only contains positive integers as strings */
- ; try(map(string-to-int; neg; invalid-array-access))
-
- /* Insert underscores between each integer */
- ; separate-by(|"_")
-
- /* Produce the final identifier: eg: idf_1_2 */
- ; <concat-strings> [idf, "_" | <id>]
-
- /**
- ** @internal
- ** Report invalid array accesses.
- */
- invalid-array-access =
- if ?Identifier(i) then
- fatal-err-msg(|<concat-strings>["internal compiler error: ",
- "undeclared meta-variable: ", i,
- " (should have been detected earlier!)"])
- else
- if (is-int; neg) then
- err-msg(|"error: negative array subscript detected:")
- ; debug
- ; <xtc-exit> 2
- else
- err-msg(|"error: non constant term in array access:")
- ; debug
- ; <xtc-exit> 2
- end
- end
-
-strategies
-
- /** Re-order modules so that the declarations are separated from the
+ ** Re-order modules so that the declarations are separated from the
** commands, as required by the original PRISM grammar.
*/
reorder-module-contents =
@@ -119,9 +63,9 @@
Module(id, map(add-command <+ add-declaration))
; where(
bagof-DeclarationList
- ; reverse
- ; ?dec-list
- ; bagof-CommandList
+ ; reverse /* We reverse the result of bagof-* */
+ ; ?dec-list /* because it yields the dynamic */
+ ; bagof-CommandList /* rules' content in reverse order */
; reverse
; ?cmd-list
)
@@ -138,145 +82,3 @@
add-declaration =
?current-term
; rules(DeclarationList:+ _ -> current-term)
-
-strategies
-
- check-meta-vars =
- check-meta-for
- <+ check-meta-if
- <+ ArrayAccess(id, check-all-identifers-are-meta-vars)
- <+ ArrayAccessPrime(id, check-all-identifers-are-meta-vars)
- <+ all(check-meta-vars)
-
- check-meta-for =
- ?MetaFor(new-meta-var, from, to, step, body)
- ; where({| MetaVars:
- <add-meta-var> new-meta-var
- ; <check-all-identifers-are-meta-vars> from
- ; <check-all-identifers-are-meta-vars> to
- ; <check-all-identifers-are-meta-vars> step
- ; <check-meta-vars> body
- |})
-
- check-meta-if =
- ?MetaIf(condition, then-part, else-part)
- ; where(
- <check-all-identifers-are-meta-vars> condition
- ; <check-meta-vars> then-part
- ; <check-meta-vars> else-part
- )
-
- check-all-identifers-are-meta-vars =
- (?Identifier(_); check-meta-var-declared)
- <+ all(check-all-identifers-are-meta-vars)
-
- add-meta-var =
- check-meta-var-unicity
- ; ?meta-var
- ; rules(MetaVars: meta-var)
-
- check-meta-var-declared =
- ?Identifier(idf)
- ; if not(<MetaVars> Identifier(idf)) then
- err-msg(|<concat-strings>["undeclared meta-var: ", idf])
- ; <xtc-exit> 2
- end
-
- check-meta-var-unicity =
- ?Identifier(idf)
- ; if <MetaVars> Identifier(idf) then
- err-msg(|<concat-strings>["meta-var already defined: ", idf])
- ; <xtc-exit> 2
- end
-
-strategies
-
- eval-meta-code =
- eval-meta-if
- <+ unroll-meta-loops
- <+ all(eval-meta-code)
-
-strategies
-
- eval-meta-if =
- ?MetaIf(condition, then-part, else-part)
- /*DEBUG*/; say(!" @@@ eval-meta-if: starting:")
- /*DEBUG*/; printf(|" condition = ", condition)
- ; where(<prism-desugar> condition => condition-value)
- /*DEBUG*/; printf(|" condition-value = ", condition-value)
- ; if !condition-value => True() then
- <eval-meta-code> then-part
- else
- if !condition-value => False() then
- <eval-meta-code> else-part
- else
- fatal-err-msg(|"internal compiler error in eval-meta-if")
- end
- end
-
-strategies
-
- unroll-meta-loops =
- ?MetaFor(meta-var, Int(from), Int(to), Int(step), body)
- ; where(check-loop-validity(|meta-var, from, to))
- ; {| MetaCode:
- /*DEBUG*/say(!" @@@ unroll-meta-loops: starting:")
- /*DEBUG*/; printf(|" meta-var = ", meta-var)
- /*DEBUG*/; printf(|" from = ", from)
- /*DEBUG*/; printf(|" to = ", to)
- ; where(<check-meta-var-unicity> meta-var)
- ; for-loop(gen-meta-code | from, to, step, [])
- /*DEBUG*/; say(!" ~~~ unroll-meta-loops: before bagof-MetaModule")
- /*DEBUG*/; debug
- ; bagof-MetaCode
- ; reverse
- /*DEBUG*/; say(!" ~~~ unroll-meta-loops: after bagof-MetaModule")
- /*DEBUG*/; debug
- |}
-
- check-loop-validity(|meta-var, from, to) =
- if <gtS>(from, to) then
- !meta-var => Identifier(idf)
- ; err-msg(|<concat-strings>["bad `for' loop on the meta-var ",
- idf, " starts at ", from,
- " which is less than ", to])
- ; <xtc-exit> 2
- end
-
-strategies
-
- gen-meta-code(|i, args) =
- /*DEBUG*/say(!" ### gen-meta-code starting"); debug;
- (?MetaFor(meta-var, _, _, _, body) <+ fatal-err-msg(|"ICE!"))
- /*DEBUG*/; say(!" >>> gen-meta-code -- start -- current term >>>")
- /*DEBUG*/; debug
- /*DEBUG*/; say(!" >>> gen-meta-code -- start -- iterator >>>")
- /*DEBUG*/; printf(|" meta-var = ", meta-var)
- /*DEBUG*/; printf(|" i = ", i)
- /*DEBUG*/; say(!" <<< gen-meta-code -- propagating meta-var's value <<< ")
- ; !body
- ; topdown(try(?meta-var; !Int(i)))
- /*DEBUG*/; debug
- /*DEBUG*/; say(!" ~~~ gen-meta-code: now recursing")
- ; eval-meta-code => generated-code
- ; rules(MetaCode:+ _ -> generated-code)
- /*DEBUG*/; say(!" ~~~ gen-meta-code: recursion finished, final result:")
- /*DEBUG*/; debug
- /*DEBUG*/; say(!" <<<<<<<<<<<<<<<<< gen-meta-code <<<<<<<<<<<<<<<<< ")
-
-strategies
- /*DEBUG*/printf(|str, term) = where(<fprintnl> (stderr, [str, term]))
-
- /**
- * for-loop(s | low, up, step, data)
- * <=> in C:
- * for(i = low; i <= up; i += step)
- * s(|i, data)
- */
- for-loop(s : Int * a * List(a) -> a | low, up, step, data) =
- /*DEBUG*/where(say(!"--- for-loop ---"); printf(|" i = ", low)
- /*DEBUG*/ ; printf(|" up = ", up); printf(|" step = ", step));
- if <leqS>(low, up) then
- where(s(|low, data))
- ; for-loop(s | <addS>(low, step), up, step, data)
- end
Index: src/str/ice.str
--- src/str/ice.str (revision 0)
+++ src/str/ice.str (revision 0)
@@ -0,0 +1,22 @@
+/*
+** Handle internal errors (things that should not happen)
+*/
+module ice
+
+strategies
+
+ ice(|calling-strategy-name) = ice(|calling-strategy-name, "unknown reason")
+
+ /** Reports an ICE and exit 42 */
+ ice(|calling-strategy-name, reason) =
+ log(|Critical(), <concat-strings>["internal compiler error in strategy ",
+ calling-strategy-name, ": ", reason])
+ ; <xtc-exit> 42
+
+ ice(|calling-strategy-name, reason, term) =
+ // FIXME: if has-annotation ...
+ log(|Critical(), <concat-strings>["internal compiler error in strategy ",
+ calling-strategy-name, ": ", reason])
+ ; !term
+ ; debug
+ ; <xtc-exit> 42
Index: src/str/prism-desugar.str
--- src/str/prism-desugar.str (revision 28)
+++ src/str/prism-desugar.str (working copy)
@@ -29,7 +29,7 @@
IntToDouble: Int(i) -> Double(i)
- // Transform a round (or almost round) Double into an Int.
+ /** Transforms a round (or almost round) Double into an Int. */
SimplifyDoubles:
Double(d) -> Int(i) // eg: Double("41.9999999999999") -> Int("42")
where !d // "41.9999999999999"
@@ -40,7 +40,7 @@
// strcmp(decimals, "000000") == 0 ? id : fail
; !decimals => "000000"
- // Round real numbers up to 6 digits and remove trailing zeros
+ /** 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'
@@ -48,6 +48,7 @@
rules
/**
+ ** Remove conditionnal updates.
** [] guard -> unconditionnal-update-list;
** is rewritten as:
** [] guard -> 1:(unconditionnal-update-list);
@@ -61,9 +62,10 @@
*/
strategies
- // used by the rules below to evaluate constant comparisons
+ /** @internal used by the rules below to evaluate constant comparisons */
compare(s) = if s then !True() else !False() end
+ /** @internal report divisions by zero detected during constant exp eval */
catch-div-by-zero =
?|[ e / 0D ]|
; err-msg(|"Division by zero detected:")
Index: src/str/eval-meta-code.str
--- src/str/eval-meta-code.str (revision 0)
+++ src/str/eval-meta-code.str (revision 0)
@@ -0,0 +1,113 @@
+/**
+** This sub-module does all the meta-code evaluation and generation.
+** XRM modules can contain meta for loops as well as meta if statements
+** which have to evaluated and transformed in PRISM source code.
+**
+** NOTE: This is a tricky part so debugging stuff have been kept and
+** commented out instead of being deleted. Hopefully this will make
+** debugging easier. This might also make the code easier to understand.
+** Sorry if it makes the source a bit overloaded with comments.
+**
+** If you want to enable debugging simply use:
+** sed 's@///\*@/*@g' < eval-meta-code.str > .tmp
+** mv .tmp eval-meta-code.str
+*/
+module eval-meta-code
+imports ice
+
+strategies
+
+ eval-meta-code =
+ eval-meta-if
+ <+ unroll-meta-loops
+ <+ all(eval-meta-code)
+
+strategies
+
+ eval-meta-if =
+ ?MetaIf(condition, then-part, else-part)
+ ///*DEBUG*/; say(!" @@@ eval-meta-if: starting:")
+ ///*DEBUG*/; printf(|" condition = ", condition)
+ ; where(<prism-desugar> condition => condition-value)
+ ///*DEBUG*/; printf(|" condition-value = ", condition-value)
+ ; if !condition-value => True() then
+ <eval-meta-code> then-part
+ else
+ if !condition-value => False() then
+ <eval-meta-code> else-part
+ else
+ ice(|"eval-meta-code", <concat-strings> [
+ "the conditionnal test of a meta if could ",
+ "not be reduced to a single value (True or",
+ " False), this should have been detected ",
+ "earlier"],
+ condition)
+ end
+ end
+
+strategies
+
+ unroll-meta-loops =
+ ?MetaFor(meta-var, Int(from), Int(to), Int(step), body)
+ ; where(check-loop-validity(|meta-var, from, to))
+ ; {| MetaCode:
+ ///*DEBUG*/say(!" @@@ unroll-meta-loops: starting:")
+ ///*DEBUG*/; printf(|" meta-var = ", meta-var)
+ ///*DEBUG*/; printf(|" from = ", from)
+ ///*DEBUG*/; printf(|" to = ", to);
+ where(<check-meta-var-unicity> meta-var)
+ ; for-loop(gen-meta-code | from, to, step, [])
+ ///*DEBUG*/; say(!" ~~~ unroll-meta-loops: before bagof-MetaModule")
+ ///*DEBUG*/; debug
+ ; bagof-MetaCode
+ ; reverse
+ ///*DEBUG*/; say(!" ~~~ unroll-meta-loops: after bagof-MetaModule")
+ ///*DEBUG*/; debug
+ |}
+
+ check-loop-validity(|meta-var, from, to) =
+ if <gtS>(from, to) then
+ !meta-var => Identifier(idf)
+ ; err-msg(|<concat-strings>["bad `for' loop on the meta-var ",
+ idf, " starts at ", from,
+ " which is less than ", to])
+ ; <xtc-exit> 2
+ end
+
+strategies
+
+ gen-meta-code(|i, args) =
+ ///*DEBUG*/say(!" ### gen-meta-code starting"); debug;
+ (?MetaFor(meta-var, _, _, _, body) <+ fatal-err-msg(|"ICE!"))
+ ///*DEBUG*/; say(!" >>> gen-meta-code -- start -- current term >>>")
+ ///*DEBUG*/; debug
+ ///*DEBUG*/; say(!" >>> gen-meta-code -- start -- iterator >>>")
+ ///*DEBUG*/; printf(|" meta-var = ", meta-var)
+ ///*DEBUG*/; printf(|" i = ", i)
+ ///*DEBUG*/; say(!" <<< gen-meta-code -- propagating meta-var's value <<< ")
+ ; !body
+ ; topdown(try(?meta-var; !Int(i)))
+ ///*DEBUG*/; debug
+ ///*DEBUG*/; say(!" ~~~ gen-meta-code: now recursing")
+ ; eval-meta-code => generated-code
+ ; rules(MetaCode:+ _ -> generated-code)
+ ///*DEBUG*/; say(!" ~~~ gen-meta-code: recursion finished, final result:")
+ ///*DEBUG*/; debug
+ ///*DEBUG*/; say(!" <<<<<<<<<<<<<<<<< gen-meta-code <<<<<<<<<<<<<<<<< ")
+
+strategies
+ ///*DEBUG*/printf(|str, term) = where(<fprintnl> (stderr, [str, term]))
+
+ /**
+ * for-loop(s | low, up, step, data)
+ * <=> in C:
+ * for(i = low; i <= up; i += step)
+ * s(|i, data)
+ */
+ for-loop(s : Int * a * List(a) -> a | low, up, step, data) =
+ ///*DEBUG*/where(say(!"--- for-loop ---"); printf(|" i = ", low)
+ ///*DEBUG*/ ; printf(|" up = ", up); printf(|" step = ", step));
+ if <leqS>(low, up) then
+ where(s(|low, data))
+ ; for-loop(s | <addS>(low, step), up, step, data)
+ end
Index: tests/test-pp-prism.sh.in
--- tests/test-pp-prism.sh.in (revision 28)
+++ tests/test-pp-prism.sh.in (working copy)
@@ -20,7 +20,7 @@
outdir="`pwd`"
cd ..
-for file in `find "@srcdir@" -name '*.pm' | sort`; do
+for file in `find "@srcdir@" -name '*.pm' -o -name '*.nm' -o -name '*.sm' | sort`; do
basefile="`basename $file`"
bfile="`echo \"$basefile\" | sed 's/\.pm$//'`"
Index: tests/test-parse-xrm.sh.in
--- tests/test-parse-xrm.sh.in (revision 28)
+++ tests/test-parse-xrm.sh.in (working copy)
@@ -11,7 +11,7 @@
test_cnt=0
test_pass=0
-for file in `find "@srcdir@" -name '*.pm' -o -name '*.xpm' | sort`; do
+for file in `find "@srcdir@" -name '*.pm' -o -name '*.nm' -o -name '*.sm' -o -name '*.xpm' | sort`; do
echo @ECHO_N@ " Parsing `basename $file` ... "
"@top_builddir@/src/tools/parse-xrm" -i "$file" -o /dev/null
if [ $? -eq 0 ]; then
Index: tests/test-parse-prism.sh.in
--- tests/test-parse-prism.sh.in (revision 28)
+++ tests/test-parse-prism.sh.in (working copy)
@@ -11,7 +11,7 @@
test_cnt=0
test_pass=0
-for file in `find "@srcdir@" -name '*.pm' | sort`; do
+for file in `find "@srcdir@" -name '*.pm' -o -name '*.nm' -o -name '*.sm' | sort`; do
echo @ECHO_N@ " Parsing `basename $file` ... "
"@top_builddir@/src/tools/parse-prism" -i "$file" -o /dev/null
if [ $? -eq 0 ]; then
Index: tests/test-pp-xrm.sh.in
--- tests/test-pp-xrm.sh.in (revision 28)
+++ tests/test-pp-xrm.sh.in (working copy)
@@ -20,7 +20,7 @@
outdir="`pwd`"
cd ..
-for file in `find "@srcdir@" -name '*.pm' -o -name '*.xpm' | sort`; do
+for file in `find "@srcdir@" -name '*.pm' -o -name '*.nm' -o -name '*.sm' -o -name '*.xpm' | sort`; do
basefile="`basename $file`"
bfile="`echo \"$basefile\" | sed 's/\.x\?pm$//'`"
1
0
https://svn.lrde.epita.fr/svn/xrm/trunk
Index: ChangeLog
from SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr>
Simplify XRM's grammar.
The constructors for meta for loops and meta ifs had each two
different names depending whether they were found at top-level or
inside modules. This turned out to be a bad idea because it was
completely unecessary and made transformations harder (because
multiple different cases had to be addressed where a single one could
be enough).
From now on we also stop saying "static" for loops or "static" if
because "meta" seems more appropriate to qualify them and it sounds
better (buzzword inside! :P)
* src/lib/xrm/pp/xrm-staticif.str: Rename as...
* src/lib/xrm/pp/xrm-meta-if.str: This.
* src/lib/xrm/pp/xrm-staticfor.str: Rename as...
* src/lib/xrm/pp/xrm-meta-for.str: This. Allow for loops to have an
empty body.
* src/lib/xrm/pp/xrm-staticfor.meta: Rename as...
* src/lib/xrm/pp/xrm-meta-for.meta: This.
* src/lib/xrm/pp/xrm-staticif.meta: Rename as...
* src/lib/xrm/pp/xrm-meta-if.meta: This.
* src/lib/xrm/pp/xrm-to-abox.str: Update imports accordingly.
* src/str/xrm-front.str: Correct a typo.
* src/str/xrm-to-prism.str: Simplify the rules according to the above
grammar changes + s/static/meta/g
* src/syn/xrm/XRM-StaticIf.sdf: Rename as...
* src/syn/xrm/XRM-MetaIf.sdf: This.
* src/syn/xrm/XRM-StaticFor.sdf: Rename as...
* src/syn/xrm/XRM-MetaFor.sdf: This.
* src/syn/xrm/XRM-Main.sdf: Update imports accordingly.
* src/syn/xrm/StrategoXRM.sdf: Ditto + fix meta-vars.
* tests/xrm/inner-static-if.xpm: Reduce the number of iterations to
reduce the time needed to run make test and make the output more
human readable.
* tests/xrm/inner-static-for-step.xpm,
* tests/xrm/outer-static-if.xpm,
* tests/xrm/outer-static-for-step.xpm,
* tests/xrm/static-if.xpm,
* tests/xrm/inner-static-for.xpm,
* tests/xrm/static-for-step.xpm,
* tests/xrm/outer-static-for.xpm,
* tests/xrm/static-for.xpm: Ditto.
src/lib/xrm/pp/xrm-meta-for.str | 41 +++++++-----------------------
src/lib/xrm/pp/xrm-meta-if.str | 19 ++-----------
src/lib/xrm/pp/xrm-to-abox.str | 4 +-
src/str/xrm-front.str | 2 -
src/str/xrm-to-prism.str | 49 +++++++++++++-----------------------
src/syn/xrm/StrategoXRM.sdf | 13 +++++----
src/syn/xrm/XRM-Main.sdf | 4 +-
src/syn/xrm/XRM-MetaFor.sdf | 24 ++++++++---------
src/syn/xrm/XRM-MetaIf.sdf | 13 +++++----
tests/xrm/inner-static-for-step.xpm | 2 -
tests/xrm/inner-static-for.xpm | 2 -
tests/xrm/inner-static-if.xpm | 4 +-
tests/xrm/outer-static-for-step.xpm | 2 -
tests/xrm/outer-static-for.xpm | 2 -
tests/xrm/outer-static-if.xpm | 4 +-
tests/xrm/static-for-step.xpm | 4 +-
tests/xrm/static-for.xpm | 4 +-
tests/xrm/static-if.xpm | 8 ++---
18 files changed, 80 insertions(+), 121 deletions(-)
Index: src/lib/xrm/pp/xrm-to-abox.str
--- src/lib/xrm/pp/xrm-to-abox.str (revision 27)
+++ src/lib/xrm/pp/xrm-to-abox.str (working copy)
@@ -21,8 +21,8 @@
xrm-parenthesize
xrm-expression
xrm-module
- xrm-staticfor
- xrm-staticif
+ xrm-meta-for
+ xrm-meta-if
xrm-arrays
strategies
Index: src/lib/xrm/pp/xrm-meta-for.str
--- src/lib/xrm/pp/xrm-meta-for.str (revision 27)
+++ src/lib/xrm/pp/xrm-meta-for.str (working copy)
@@ -1,11 +1,13 @@
-module xrm-staticfor
+module xrm-meta-for
rules
- // "for" Identifier "from" Int "to" Int "do" ModulesFileSection+ "end"
- // -> OuterStaticFor
+ // "for" Identifier "from" Int "to" Int "do" ModulesFileSection* "end"
+ // -> MetaFor
+ // "for" Identifier "from" Int "to" Int "do" DeclarationOrCommand* "end"
+ // -> MetaFor
prism-to-box:
- OuterStaticFor(idf, for-from, for-to, mfs-list)
+ MetaFor(idf, for-from, for-to, mfs-list)
-> box |[ V[ V is=2 [
H hs=1 [ KW["for"] ~idf
KW["from"] ~for-from
@@ -15,39 +17,16 @@
] ]|
// "for" Identifier "from" Int "to" Int "step" Int "do"
- // ModulesFileSection+ "end" -> OuterStaticFor
- prism-to-box:
- OuterStaticFor(idf, for-from, for-to, for-step, mfs-list)
- -> box |[ V[ V is=2 [
- H hs=1 [ KW["for"] ~idf
- KW["from"] ~for-from
- KW["to"] ~for-to
- KW["step"] ~for-step KW["do"] ]
- ~*mfs-list // in the innermost V box
- ] KW["end"] // in the outermost V box
- ] ]|
-
- // "for" Identifier "from" Int "to" Int "do" DeclarationOrCommand+ "end"
- // -> InnerStaticFor
- prism-to-box:
- InnerStaticFor(idf, for-from, for-to, dec-or-cmd-list)
- -> box |[ V[ V is=2 [
- H hs=1 [ KW["for"] ~idf
- KW["from"] ~for-from
- KW["to"] ~for-to KW["do"] ]
- ~*dec-or-cmd-list // in the innermost V box
- ] KW["end"] // in the outermost V box
- ] ]|
-
+ // ModulesFileSection* "end" -> MetaFor
// "for" Identifier "from" Int "to" Int "step" Int "do"
- // DeclarationOrCommand+ "end" -> InnerStaticFor
+ // DeclarationOrCommand* "end" -> MetaFor
prism-to-box:
- InnerStaticFor(idf, for-from, for-to, for-step, dec-or-cmd-list)
+ MetaFor(idf, for-from, for-to, for-step, mfs-list)
-> box |[ V[ V is=2 [
H hs=1 [ KW["for"] ~idf
KW["from"] ~for-from
KW["to"] ~for-to
KW["step"] ~for-step KW["do"] ]
- ~*dec-or-cmd-list // in the innermost V box
+ ~*mfs-list // in the innermost V box
] KW["end"] // in the outermost V box
] ]|
Index: src/lib/xrm/pp/xrm-meta-if.str
--- src/lib/xrm/pp/xrm-meta-if.str (revision 27)
+++ src/lib/xrm/pp/xrm-meta-if.str (working copy)
@@ -1,28 +1,15 @@
-module xrm-staticif
+module xrm-meta-if
rules
prism-to-box:
- OuterStaticIf(condition, then-part)
+ MetaIf(condition, then-part)
-> V[ V is=2 [ H hs=1 [ KW["if"] ~condition KW["then"] ]
~*then-part ]
KW["end"]]
prism-to-box:
- OuterStaticIf(condition, then-part, else-part)
- -> V[ V is=2 [ H hs=1 [ KW["if"] ~condition KW["then"] ]
- ~*then-part ]
- V is=2 [ KW["else"] ~*else-part ]
- KW["end"]]
-
- prism-to-box:
- InnerStaticIf(condition, then-part)
- -> V[ V is=2 [ H hs=1 [ KW["if"] ~condition KW["then"] ]
- ~*then-part ]
- KW["end"]]
-
- prism-to-box:
- InnerStaticIf(condition, then-part, else-part)
+ MetaIf(condition, then-part, else-part)
-> V[ V is=2 [ H hs=1 [ KW["if"] ~condition KW["then"] ]
~*then-part ]
V is=2 [ KW["else"] ~*else-part ]
Index: src/str/xrm-front.str
--- src/str/xrm-front.str (revision 27)
+++ src/str/xrm-front.str (working copy)
@@ -142,7 +142,7 @@
<tool-doc>
[ Usage("xrm-front [OPTIONS]")
, Summary("Transforms an eXtended Reactive Module source file in a
- PRISM-equivalant abstract syntax tree (default) or source
+ PRISM-equivalent abstract syntax tree (default) or source
code. (see option -P)")
, OptionUsage()
, AutoReportBugs()
Index: src/str/xrm-to-prism.str
--- src/str/xrm-to-prism.str (revision 27)
+++ src/str/xrm-to-prism.str (working copy)
@@ -13,7 +13,7 @@
* and that they are not redefined twice in the same scope */
; check-meta-vars
- /* unroll static loops, eval static if */
+ /* unroll meta loops, eval meta if */
; eval-meta-code
/* flatten nested lists */
@@ -35,20 +35,13 @@
|[ e1 << e2 ]| -> |[ e1 * func(pow, 2, e2) ]|
xrm-to-prism-desugar:
- OuterStaticFor(identifier, from, to, body)
- -> OuterStaticFor(identifier, from, to, Int("1"), body)
-
- xrm-to-prism-desugar:
- InnerStaticFor(identifier, from, to, body)
- -> InnerStaticFor(identifier, from, to, Int("1"), body)
+ MetaFor(identifier, from, to, body)
+ -> MetaFor(identifier, from, to, Int("1"), body)
xrm-to-prism-desugar:
//|[ if e then m* end ]| -> |[ if e then m* else end ]|
- OuterStaticIf(e, m*) -> OuterStaticIf(e, m*, [])
-
- xrm-to-prism-desugar:
//|[ if e then s* end ]| -> |[ if e then s* else end ]|
- InnerStaticIf(e, s*) -> InnerStaticIf(e, s*, [])
+ MetaIf(e, m*) -> MetaIf(e, m*, [])
rules
@@ -76,7 +69,7 @@
** @param access-list List of Int()
*/
flatten-access-list(|idf, access-list) =
- /* eval static expressions in the access-list
+ /* eval meta expressions in the access-list
* eg: Plus(Int("1"), Int("2")) -> Int("3") */
<prism-desugar> access-list
@@ -149,15 +142,14 @@
strategies
check-meta-vars =
- check-static-for
- <+ check-static-if
+ check-meta-for
+ <+ check-meta-if
<+ ArrayAccess(id, check-all-identifers-are-meta-vars)
<+ ArrayAccessPrime(id, check-all-identifers-are-meta-vars)
<+ all(check-meta-vars)
- check-static-for =
- (?OuterStaticFor(new-meta-var, from, to, step, body)
- <+ ?InnerStaticFor(new-meta-var, from, to, step, body))
+ check-meta-for =
+ ?MetaFor(new-meta-var, from, to, step, body)
; where({| MetaVars:
<add-meta-var> new-meta-var
; <check-all-identifers-are-meta-vars> from
@@ -166,9 +158,8 @@
; <check-meta-vars> body
|})
- check-static-if =
- (?OuterStaticIf(condition, then-part, else-part)
- <+ ?InnerStaticIf(condition, then-part, else-part))
+ check-meta-if =
+ ?MetaIf(condition, then-part, else-part)
; where(
<check-all-identifers-are-meta-vars> condition
; <check-meta-vars> then-part
@@ -202,14 +193,13 @@
eval-meta-code =
eval-meta-if
- <+ unroll-static-loops
+ <+ unroll-meta-loops
<+ all(eval-meta-code)
strategies
eval-meta-if =
- (?OuterStaticIf(condition, then-part, else-part)
- <+ ?InnerStaticIf(condition, then-part, else-part))
+ ?MetaIf(condition, then-part, else-part)
/*DEBUG*/; say(!" @@@ eval-meta-if: starting:")
/*DEBUG*/; printf(|" condition = ", condition)
; where(<prism-desugar> condition => condition-value)
@@ -226,22 +216,21 @@
strategies
- unroll-static-loops =
- (?OuterStaticFor(meta-var, Int(from), Int(to), Int(step), body)
- <+ ?InnerStaticFor(meta-var, Int(from), Int(to), Int(step), body))
+ unroll-meta-loops =
+ ?MetaFor(meta-var, Int(from), Int(to), Int(step), body)
; where(check-loop-validity(|meta-var, from, to))
; {| MetaCode:
- /*DEBUG*/say(!" @@@ unroll-static-loops: starting:")
+ /*DEBUG*/say(!" @@@ unroll-meta-loops: starting:")
/*DEBUG*/; printf(|" meta-var = ", meta-var)
/*DEBUG*/; printf(|" from = ", from)
/*DEBUG*/; printf(|" to = ", to)
; where(<check-meta-var-unicity> meta-var)
; for-loop(gen-meta-code | from, to, step, [])
- /*DEBUG*/; say(!" ~~~ unroll-static-loops: before bagof-MetaModule")
+ /*DEBUG*/; say(!" ~~~ unroll-meta-loops: before bagof-MetaModule")
/*DEBUG*/; debug
; bagof-MetaCode
; reverse
- /*DEBUG*/; say(!" ~~~ unroll-static-loops: after bagof-MetaModule")
+ /*DEBUG*/; say(!" ~~~ unroll-meta-loops: after bagof-MetaModule")
/*DEBUG*/; debug
|}
@@ -258,7 +247,7 @@
gen-meta-code(|i, args) =
/*DEBUG*/say(!" ### gen-meta-code starting"); debug;
- (?for-kind#([meta-var, _, _, _, body]) <+ fatal-err-msg(|"ICE!"))
+ (?MetaFor(meta-var, _, _, _, body) <+ fatal-err-msg(|"ICE!"))
/*DEBUG*/; say(!" >>> gen-meta-code -- start -- current term >>>")
/*DEBUG*/; debug
/*DEBUG*/; say(!" >>> gen-meta-code -- start -- iterator >>>")
Index: src/syn/xrm/XRM-MetaIf.sdf
--- src/syn/xrm/XRM-MetaIf.sdf (revision 27)
+++ src/syn/xrm/XRM-MetaIf.sdf (working copy)
@@ -1,10 +1,10 @@
-module XRM-StaticIf
+module XRM-MetaIf
imports
PRISM-to-XRM
XRM-Module
exports
- %% EBNF Grammar: Static if-then-else
+ %% EBNF Grammar: Meta if-then-else
%% (* if-then-else at top-level *)
%% ModulesFileSection ::=
%% "if" Expression "then" ModulesFileSection {ModulesFileSection} "end"
@@ -14,6 +14,7 @@
%% ModulesFileSection {ModulesFileSection}
%% "end"
%%
+ %% (* if-then-else inside modules *)
%% DeclarationOrCommand ::=
%% "if" Expression "then" DeclarationOrCommand {DeclarationOrCommand} "end"
%% | "if" Expression "then"
@@ -25,23 +26,23 @@
context-free syntax
%% if-then at top-level
"if" Expression "then" ModulesFileSection* "end"
- -> ModulesFileSection {cons("OuterStaticIf")}
+ -> ModulesFileSection {cons("MetaIf")}
%% if-then-else at top-level
"if" Expression "then"
ModulesFileSection*
"else"
ModulesFileSection*
- "end" -> ModulesFileSection {cons("OuterStaticIf")}
+ "end" -> ModulesFileSection {cons("MetaIf")}
context-free syntax
%% if-then within modules
"if" Expression "then" DeclarationOrCommand* "end"
- -> DeclarationOrCommand {cons("InnerStaticIf")}
+ -> DeclarationOrCommand {cons("MetaIf")}
%% if-then-else within modules
"if" Expression "then"
DeclarationOrCommand*
"else"
DeclarationOrCommand*
- "end" -> DeclarationOrCommand {cons("InnerStaticIf")}
+ "end" -> DeclarationOrCommand {cons("MetaIf")}
Index: src/syn/xrm/StrategoXRM.sdf
--- src/syn/xrm/StrategoXRM.sdf (revision 27)
+++ src/syn/xrm/StrategoXRM.sdf (working copy)
@@ -6,6 +6,8 @@
PRISM-MetaCongruences
XRM-MetaVars
XRM-MetaCongruences
+ XRM-MetaFor
+ XRM-MetaIf
exports
context-free start-symbols StrategoModule
@@ -17,13 +19,14 @@
"|[" Expression "]|" -> StrategoTerm {prefer,cons("ToTerm")}
"|[" Declaration "]|" -> StrategoTerm {prefer,cons("ToTerm")}
"|[" Command "]|" -> StrategoTerm {prefer,cons("ToTerm")}
- "|[" OuterStaticFor "]|" -> StrategoTerm {prefer,cons("ToTerm")}
- "|[" InnerStaticFor "]|" -> StrategoTerm {prefer,cons("ToTerm")}
+ "|[" MetaFor "]|" -> StrategoTerm {prefer,cons("ToTerm")}
+ "|[" MetaIf "]|" -> StrategoTerm {prefer,cons("ToTerm")}
context-free syntax
"~" StrategoTerm -> Expression {prefer,cons("FromTerm")}
- "~id:" StrategoTerm -> Identifier {prefer,cons("FromTerm")}
+ "~id:" StrategoTerm -> ID {prefer,cons("FromTerm")}
+ %% FIXME: the following rule is b0rken
"~id':" StrategoTerm -> IdentifierPrime {prefer,cons("FromTerm")}
- "~int:" StrategoTerm -> Int {prefer,cons("FromTerm")}
- "~double:" StrategoTerm -> Double {prefer,cons("FromTerm")}
+ "~int:" StrategoTerm -> LInt {prefer,cons("FromTerm")}
+ "~double:" StrategoTerm -> LDouble {prefer,cons("FromTerm")}
Index: src/syn/xrm/XRM-Main.sdf
--- src/syn/xrm/XRM-Main.sdf (revision 27)
+++ src/syn/xrm/XRM-Main.sdf (working copy)
@@ -3,8 +3,8 @@
PRISM-to-XRM
XRM-Module
XRM-Expression
- XRM-StaticFor
- XRM-StaticIf
+ XRM-MetaFor
+ XRM-MetaIf
XRM-Literals
XRM-Declaration
XRM-Update
Index: src/syn/xrm/XRM-MetaFor.sdf
--- src/syn/xrm/XRM-MetaFor.sdf (revision 27)
+++ src/syn/xrm/XRM-MetaFor.sdf (working copy)
@@ -1,33 +1,33 @@
-module XRM-StaticFor
+module XRM-MetaFor
imports
PRISM-to-XRM
XRM-Module
exports
- %% EBNF Grammar: Static For Loops
- %% (* Static For loops at the top level *)
+ %% EBNF Grammar: Meta For Loops
+ %% (* Meta For loops at the top level *)
%% ModulesFileSection ::=
%% "for" Identifier "from" Int "to" Int ["step" Int] "do"
%% {ModulesFileSection} "end"
%%
- %% (* Static For loops inside modules *)
+ %% (* Meta For loops inside modules *)
%% DeclarationOrCommand ::=
%% "for" Identifier "from" Int "to" Int ["step" Int] "do"
%% {DeclarationOrCommand} "end"
context-free syntax
- %% OuterStaticFor can be found only at top-level
+ %% This MetaFor can be found only at top-level
%% So we can see it as a ModulesFileSection
- "for" Identifier "from" Int "to" Int "do" ModulesFileSection+ "end"
- -> ModulesFileSection {cons("OuterStaticFor")}
+ "for" Identifier "from" Int "to" Int "do" ModulesFileSection* "end"
+ -> ModulesFileSection {cons("MetaFor")}
"for" Identifier "from" Int "to" Int "step" Int "do"
- ModulesFileSection+ "end" -> ModulesFileSection {cons("OuterStaticFor")}
+ ModulesFileSection* "end" -> ModulesFileSection {cons("MetaFor")}
- %% InnerStaticFor can be found only inside Modules
+ %% This MetaFor can be found only inside Modules
%% So we can see it as a DeclarationOrCommand
- "for" Identifier "from" Int "to" Int "do" DeclarationOrCommand+ "end"
- -> DeclarationOrCommand {cons("InnerStaticFor")}
+ "for" Identifier "from" Int "to" Int "do" DeclarationOrCommand* "end"
+ -> DeclarationOrCommand {cons("MetaFor")}
"for" Identifier "from" Int "to" Int "step" Int "do"
- DeclarationOrCommand+ "end" -> DeclarationOrCommand {cons("InnerStaticFor")}
+ DeclarationOrCommand* "end" -> DeclarationOrCommand {cons("MetaFor")}
Index: tests/xrm/inner-static-if.xpm
--- tests/xrm/inner-static-if.xpm (revision 27)
+++ tests/xrm/inner-static-if.xpm (working copy)
@@ -1,8 +1,8 @@
probabilistic
module dummy
- for i from 0 to 42 do
- if i=0 | i=42 then
+ for i from 0 to 4 do
+ if i=0 | i=4 then
x[i] : [0..2];
else
x[i] : [0..1];
Index: tests/xrm/inner-static-for-step.xpm
--- tests/xrm/inner-static-for-step.xpm (revision 27)
+++ tests/xrm/inner-static-for-step.xpm (working copy)
@@ -1,7 +1,7 @@
probabilistic
module dummy
- for i from 0 to 42 step 2 do
+ for i from 0 to 4 step 2 do
x[i] : [0..1];
[] x[i]=0 -> x[i]'=1;
end
Index: tests/xrm/outer-static-if.xpm
--- tests/xrm/outer-static-if.xpm (revision 27)
+++ tests/xrm/outer-static-if.xpm (working copy)
@@ -1,7 +1,7 @@
probabilistic
-for i from 0 to 42 do
- if i<1 & i>41 then
+for i from 0 to 4 do
+ if i<1 | i>2 then
module dummy[i]
x[i] : [0..1];
[] x[i]=0 -> x[i]'=1;
Index: tests/xrm/outer-static-for-step.xpm
--- tests/xrm/outer-static-for-step.xpm (revision 27)
+++ tests/xrm/outer-static-for-step.xpm (working copy)
@@ -1,6 +1,6 @@
probabilistic
-for i from 0 to 42 step 2 do
+for i from 0 to 4 step 2 do
module dummy[i]
x[i] : [0..1];
[] x[i]=0 -> x[i]'=1;
Index: tests/xrm/static-if.xpm
--- tests/xrm/static-if.xpm (revision 27)
+++ tests/xrm/static-if.xpm (working copy)
@@ -1,10 +1,10 @@
probabilistic
-for i from 0 to 42 do
- if i<1 & i>41 then
+for i from 0 to 4 do
+ if i<1 | i>=3 then
module dummy[i]
- for j from 0 to 42 do
- if i=0 | i=42 then
+ for j from 6 to 10 do
+ if i=0 | i+j=7 then
x[i][j] : [0..2];
else
x[i][j] : [0..1];
Index: tests/xrm/inner-static-for.xpm
--- tests/xrm/inner-static-for.xpm (revision 27)
+++ tests/xrm/inner-static-for.xpm (working copy)
@@ -1,7 +1,7 @@
probabilistic
module dummy
- for i from 0 to 42 do
+ for i from 0 to 4 do
x[i] : [0..1];
[] x[i]=0 -> x[i]'=1;
end
Index: tests/xrm/static-for-step.xpm
--- tests/xrm/static-for-step.xpm (revision 27)
+++ tests/xrm/static-for-step.xpm (working copy)
@@ -1,8 +1,8 @@
probabilistic
-for i from 0 to 42 step 2 do
+for i from 0 to 4 step 2 do
module dummy[i]
- for j from 0 to 42 step 2 do
+ for j from 6 to 10 step 2 do
x[i][j] : [0..1];
[] x[i][j]=0 -> x[i][j]'=1;
end
Index: tests/xrm/outer-static-for.xpm
--- tests/xrm/outer-static-for.xpm (revision 27)
+++ tests/xrm/outer-static-for.xpm (working copy)
@@ -1,6 +1,6 @@
probabilistic
-for i from 0 to 42 do
+for i from 0 to 4 do
module dummy[i]
x[i] : [0..1];
[] x[i]=0 -> x[i]'=1;
Index: tests/xrm/static-for.xpm
--- tests/xrm/static-for.xpm (revision 27)
+++ tests/xrm/static-for.xpm (working copy)
@@ -1,8 +1,8 @@
probabilistic
-for i from 0 to 42 do
+for i from 0 to 4 do
module dummy[i]
- for j from 0 to 42 do
+ for j from 6 to 10 do
x[i][j] : [0..1];
[] x[i][j]=0 -> x[i][j]'=1;
end
1
0
>>> "SIGOURE" == SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr> writes:
> Add meta code evaluation [debug version].
> This is the first working version with complete meta code evaluation.
> For loops and Ifs are evaluated at the meta-level and code is
> generated by xrm-front accordingly.
> /!\ This version contains debugging messages to be removed.
> The code also needs to be cleaned up and re-organized a bit.
> The first Release Candidate is on its way! \o/
Sincères félicitations !
1
0
https://svn.lrde.epita.fr/svn/xrm/trunk
Index: ChangeLog
from SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr>
Add meta code evaluation [debug version].
This is the first working version with complete meta code evaluation.
For loops and Ifs are evaluated at the meta-level and code is
generated by xrm-front accordingly.
/!\ This version contains debugging messages to be removed.
The code also needs to be cleaned up and re-organized a bit.
The first Release Candidate is on its way! \o/
* src/lib/xrm/pp/xrm-module.str: Remove MetaModule boxing.
* src/lib/xrm/pp/xrm-expression.str: Remove PreIncr and PreDecr boxing.
* src/lib/xrm/pp/xrm-arrays.str: Add ArrayAccessPrime boxing.
* src/str/xrm-front.str: Add a FIXME. To be removed very soon.
* src/str/xrm-to-prism.str: Add meta code evaluation.
* src/str/prism-desugar.str: Add some FIXMEs and some new constant
expression evaluation.
* src/syn/xrm/XRM-Arrays.sdf: Add ArrayAccessPrime (eg: x[i]').
* src/syn/xrm/XRM-StartSymbols.sdf: Remove IdentifierPrime (useless).
* src/syn/prism/PRISM-StartSymbols.sdf: Ditto.
* src/syn/xrm/XRM-StaticIf.sdf: The then-part and else-part of an If
may now be empty.
* src/syn/xrm/StrategoXRM.sdf: Add static fors.
* src/syn/xrm/XRM-Literals.sdf: Add a comment about SDF kernel syntax.
* src/syn/xrm/XRM-MetaVars.sdf: Add new meta-vars for XRM.
* src/syn/xrm/XRM-Update.sdf: New. Add updates using ArrayAccessPrime.
* src/syn/xrm/XRM-Main.sdf: Import XRM-Declaration and XRM-Update.
* src/syn/xrm/XRM-Declaration.sdf: New. Add declarations of
ArrayAccessPrime. (eg: declarations for variables named x[i])
* src/syn/xrm/XRM-Module.sdf: Change the MetaModule constructor in
Module. The new constructor was useless.
* src/syn/xrm/XRM-Expression.sdf: Remove PreIncr and PreDecr (eg: ++x
and --x). This was wrong and useless and used only for testing.
* tests/xrm/inner-static-if.xpm: Remove the FIXME.
* tests/xrm/inner-static-for-step.xpm: Ditto.
* tests/xrm/outer-static-if.xpm: Ditto.
* tests/xrm/outer-static-for-step.xpm: Ditto.
* tests/xrm/static-if.xpm: Ditto.
* tests/xrm/inner-static-for.xpm: Ditto.
* tests/xrm/static-for-step.xpm: Ditto.
* tests/xrm/outer-static-for.xpm: Ditto.
* tests/xrm/simple_01.xpm: Ditto.
* tests/xrm/static-for.xpm: Ditto.
src/lib/xrm/pp/xrm-arrays.str | 6
src/lib/xrm/pp/xrm-expression.str | 6
src/lib/xrm/pp/xrm-module.str | 8 -
src/str/prism-desugar.str | 47 +++++-
src/str/xrm-front.str | 2
src/str/xrm-to-prism.str | 268 +++++++++++++++++++++++++++++++++--
src/syn/prism/PRISM-StartSymbols.sdf | 1
src/syn/xrm/StrategoXRM.sdf | 2
src/syn/xrm/XRM-Arrays.sdf | 9 +
src/syn/xrm/XRM-Declaration.sdf | 22 ++
src/syn/xrm/XRM-Expression.sdf | 20 --
src/syn/xrm/XRM-Literals.sdf | 2
src/syn/xrm/XRM-Main.sdf | 2
src/syn/xrm/XRM-MetaVars.sdf | 4
src/syn/xrm/XRM-Module.sdf | 2
src/syn/xrm/XRM-StartSymbols.sdf | 1
src/syn/xrm/XRM-StaticIf.sdf | 12 -
src/syn/xrm/XRM-Update.sdf | 22 ++
tests/xrm/inner-static-for-step.xpm | 6
tests/xrm/inner-static-for.xpm | 6
tests/xrm/inner-static-if.xpm | 8 -
tests/xrm/outer-static-for-step.xpm | 4
tests/xrm/outer-static-for.xpm | 4
tests/xrm/outer-static-if.xpm | 8 -
tests/xrm/simple_01.xpm | 3
tests/xrm/static-for-step.xpm | 8 -
tests/xrm/static-for.xpm | 8 -
tests/xrm/static-if.xpm | 14 -
28 files changed, 408 insertions(+), 97 deletions(-)
Index: src/lib/xrm/pp/xrm-module.str
--- src/lib/xrm/pp/xrm-module.str (revision 26)
+++ src/lib/xrm/pp/xrm-module.str (working copy)
@@ -10,11 +10,3 @@
]
KW["endmodule"]
] ]|
-
- prism-to-box:
- MetaModule(array-access, dec-or-cmd-list)
- -> box |[ V[ V is=2 [ H hs=1 [KW["module"] ~array-access ]
- ~*dec-or-cmd-list
- ]
- KW["endmodule"]
- ] ]|
Index: src/lib/xrm/pp/xrm-expression.str
--- src/lib/xrm/pp/xrm-expression.str (revision 26)
+++ src/lib/xrm/pp/xrm-expression.str (working copy)
@@ -3,12 +3,6 @@
rules
prism-to-box:
- PreIncr(exp) -> H hs=0 [ MATH["++"] ~exp ]
-
- prism-to-box:
- PreDecr(exp) -> H hs=0 [ MATH["--"] ~exp ]
-
- prism-to-box:
RightShift(lhs, rhs) -> H hs=1 [~lhs MATH[">>"] ~rhs]
prism-to-box:
Index: src/lib/xrm/pp/xrm-arrays.str
--- src/lib/xrm/pp/xrm-arrays.str (revision 26)
+++ src/lib/xrm/pp/xrm-arrays.str (working copy)
@@ -7,3 +7,9 @@
ArrayAccess(idf, subscripts) -> H hs=0 [ ~idf ~*subscripts-impl ]
where
<mapconcat(\ x -> [S("["), x, S("]")] \)> subscripts => subscripts-impl
+
+ // Identifier ArraySubscript+ "'" -> ArrayAccessPrime
+ prism-to-box:
+ ArrayAccessPrime(idf, subscripts) -> H hs=0 [ ~idf ~*subscripts-impl "'" ]
+ where
+ <mapconcat(\ x -> [S("["), x, S("]")] \)> subscripts => subscripts-impl
Index: src/str/xrm-front.str
--- src/str/xrm-front.str (revision 26)
+++ src/str/xrm-front.str (working copy)
@@ -23,7 +23,7 @@
; xtc-transform(!"parse-xrm", // parse input (returns a FILE)
!["-b", "--preserve-positions" | <pass-verbose>()])
; read-from // read parsed input
- ; strip-annos
+ ; /*FIXME*/strip-annos // FIXME: remove this line!!!!!!!!!!!!!!!!!!!!!!!!!!
; xrm-front-pipeline // transformations
; if not(must-keep-attributes) then strip-annos end
; if <get-config> "-b" then
Index: src/str/xrm-to-prism.str
--- src/str/xrm-to-prism.str (revision 26)
+++ src/str/xrm-to-prism.str (working copy)
@@ -1,55 +1,293 @@
module xrm-to-prism
-imports XRM
+imports
+ XRM
+ prism-desugar
strategies
xrm-to-prism =
+ /* remove XRM sugar, normalize some nodes */
topdown(try(xrm-to-prism-desugar))
- ; id // unroll static for loops here
- ; topdown(try(reorder-module-contents))
+
+ /* Check that meta vars are always defined in the current scope when used
+ * and that they are not redefined twice in the same scope */
+ ; check-meta-vars
+
+ /* unroll static loops, eval static if */
+ ; eval-meta-code
+
+ /* flatten nested lists */
+ ; ModulesFile(id, flatten-list)
+ ; ModulesFile(id, map(try(Module(id, flatten-list))))
+
+ /* remove array accesses: x[i] -> x_i */
+ ; topdown(try(remove-array-accesses))
+
+ /* re-order modules so that all declarations appear before commands */
+ ; ModulesFile(id, map(try(reorder-module-contents)))
rules
xrm-to-prism-desugar:
- // PreIncr(exp) -> Eq(exp, [Plus(exp, Int("1"))])
- |[ ++e ]| -> |[ e = e + 1 ]|
+ |[ e1 >> e2 ]| -> |[ e1 / func(pow, 2, e2) ]|
+
+ xrm-to-prism-desugar:
+ |[ e1 << e2 ]| -> |[ e1 * func(pow, 2, e2) ]|
xrm-to-prism-desugar:
- // PreDecr(exp) -> Eq(exp, [Minus(exp, Int("1"))])
- |[ --e ]| -> |[ e = e - 1 ]|
+ OuterStaticFor(identifier, from, to, body)
+ -> OuterStaticFor(identifier, from, to, Int("1"), body)
xrm-to-prism-desugar:
- // RightShift(lhs, rhs) -> Div(lhs, rhs)
- |[ e1 >> e2 ]| -> |[ e1 / func(pow, 2, e2) ]|
+ InnerStaticFor(identifier, from, to, body)
+ -> InnerStaticFor(identifier, from, to, Int("1"), body)
xrm-to-prism-desugar:
- // LeftShift(lhs, rhs) -> Div(lhs, rhs)
- |[ e1 << e2 ]| -> |[ e1 * func(pow, 2, e2) ]|
+ //|[ if e then m* end ]| -> |[ if e then m* else end ]|
+ OuterStaticIf(e, m*) -> OuterStaticIf(e, m*, [])
+
+ xrm-to-prism-desugar:
+ //|[ if e then s* end ]| -> |[ if e then s* else end ]|
+ InnerStaticIf(e, s*) -> InnerStaticIf(e, s*, [])
+
+rules
+
+ /**
+ ** Transform an array access into an identifier (eg: x[i] -> x_i)
+ */
+ remove-array-accesses:
+ ArrayAccess(Identifier(idf), access-list) -> Identifier(idf')
+ where flatten-access-list(|idf, access-list) => idf'
+
+ remove-array-accesses:
+ ArrayAccessPrime(Identifier(idf), access-list) -> IdentifierPrime(idf')
+ where flatten-access-list(|idf, access-list) => idf'
+
+strategies
+
+ /**
+ ** @internal
+ ** Transform an access list (in array accesses) into a flat variable name
+ ** eg: flatten-access-list(|"x", [Int("1"), Int("2")]) -> "x_1_2"
+ ** NOTE: The access list can contain expressions as long as it possible to
+ ** evaluate them down to a constant positive Int() value.
+ **
+ ** @param idf String
+ ** @param access-list List of Int()
+ */
+ flatten-access-list(|idf, access-list) =
+ /* eval static expressions in the access-list
+ * eg: Plus(Int("1"), Int("2")) -> Int("3") */
+ <prism-desugar> access-list
+
+ /* Now the access must only contain a list of Int: [Int("1"), Int("2"), ..]
+ * So we can remove the Int() constructor. */
+ ; map(\ Int(i) -> i \ <+ invalid-array-access)
+
+ /* Now we have a list of strings such as: ["1", "2", ...]
+ * Check that the list only contains positive integers as strings */
+ ; try(map(string-to-int; neg; invalid-array-access))
+
+ /* Insert underscores between each integer */
+ ; separate-by(|"_")
+
+ /* Produce the final identifier: eg: idf_1_2 */
+ ; <concat-strings> [idf, "_" | <id>]
+
+ /**
+ ** @internal
+ ** Report invalid array accesses.
+ */
+ invalid-array-access =
+ if ?Identifier(i) then
+ fatal-err-msg(|<concat-strings>["internal compiler error: ",
+ "undeclared meta-variable: ", i,
+ " (should have been detected earlier!)"])
+ else
+ if (is-int; neg) then
+ err-msg(|"error: negative array subscript detected:")
+ ; debug
+ ; <xtc-exit> 2
+ else
+ err-msg(|"error: non constant term in array access:")
+ ; debug
+ ; <xtc-exit> 2
+ end
+ end
strategies
- // re-order modules so that the declarations are separated from the
- // commands, as required by the original PRISM grammar
+ /** Re-order modules so that the declarations are separated from the
+ ** commands, as required by the original PRISM grammar.
+ */
reorder-module-contents =
?Module(name, _)
; {| DeclarationList, CommandList:
Module(id, map(add-command <+ add-declaration))
; where(
bagof-DeclarationList
+ ; reverse
; ?dec-list
; bagof-CommandList
+ ; reverse
; ?cmd-list
)
|}
; !Module(name, dec-list, cmd-list)
- // if the current term is a Command, add it in the CommandList DR
+ /** if the current term is a Command, add it in the CommandList DR */
add-command =
?Command(_, _, _)
; ?current-term
; rules(CommandList:+ _ -> current-term)
- // if the current term is not a Command, add it in the DeclarationList DR
+ /** if the current term is not a Command, add it in the DeclarationList DR */
add-declaration =
?current-term
; rules(DeclarationList:+ _ -> current-term)
+
+strategies
+
+ check-meta-vars =
+ check-static-for
+ <+ check-static-if
+ <+ ArrayAccess(id, check-all-identifers-are-meta-vars)
+ <+ ArrayAccessPrime(id, check-all-identifers-are-meta-vars)
+ <+ all(check-meta-vars)
+
+ check-static-for =
+ (?OuterStaticFor(new-meta-var, from, to, step, body)
+ <+ ?InnerStaticFor(new-meta-var, from, to, step, body))
+ ; where({| MetaVars:
+ <add-meta-var> new-meta-var
+ ; <check-all-identifers-are-meta-vars> from
+ ; <check-all-identifers-are-meta-vars> to
+ ; <check-all-identifers-are-meta-vars> step
+ ; <check-meta-vars> body
+ |})
+
+ check-static-if =
+ (?OuterStaticIf(condition, then-part, else-part)
+ <+ ?InnerStaticIf(condition, then-part, else-part))
+ ; where(
+ <check-all-identifers-are-meta-vars> condition
+ ; <check-meta-vars> then-part
+ ; <check-meta-vars> else-part
+ )
+
+ check-all-identifers-are-meta-vars =
+ (?Identifier(_); check-meta-var-declared)
+ <+ all(check-all-identifers-are-meta-vars)
+
+ add-meta-var =
+ check-meta-var-unicity
+ ; ?meta-var
+ ; rules(MetaVars: meta-var)
+
+ check-meta-var-declared =
+ ?Identifier(idf)
+ ; if not(<MetaVars> Identifier(idf)) then
+ err-msg(|<concat-strings>["undeclared meta-var: ", idf])
+ ; <xtc-exit> 2
+ end
+
+ check-meta-var-unicity =
+ ?Identifier(idf)
+ ; if <MetaVars> Identifier(idf) then
+ err-msg(|<concat-strings>["meta-var already defined: ", idf])
+ ; <xtc-exit> 2
+ end
+
+strategies
+
+ eval-meta-code =
+ eval-meta-if
+ <+ unroll-static-loops
+ <+ all(eval-meta-code)
+
+strategies
+
+ eval-meta-if =
+ (?OuterStaticIf(condition, then-part, else-part)
+ <+ ?InnerStaticIf(condition, then-part, else-part))
+ /*DEBUG*/; say(!" @@@ eval-meta-if: starting:")
+ /*DEBUG*/; printf(|" condition = ", condition)
+ ; where(<prism-desugar> condition => condition-value)
+ /*DEBUG*/; printf(|" condition-value = ", condition-value)
+ ; if !condition-value => True() then
+ <eval-meta-code> then-part
+ else
+ if !condition-value => False() then
+ <eval-meta-code> else-part
+ else
+ fatal-err-msg(|"internal compiler error in eval-meta-if")
+ end
+ end
+
+strategies
+
+ unroll-static-loops =
+ (?OuterStaticFor(meta-var, Int(from), Int(to), Int(step), body)
+ <+ ?InnerStaticFor(meta-var, Int(from), Int(to), Int(step), body))
+ ; where(check-loop-validity(|meta-var, from, to))
+ ; {| MetaCode:
+ /*DEBUG*/say(!" @@@ unroll-static-loops: starting:")
+ /*DEBUG*/; printf(|" meta-var = ", meta-var)
+ /*DEBUG*/; printf(|" from = ", from)
+ /*DEBUG*/; printf(|" to = ", to)
+ ; where(<check-meta-var-unicity> meta-var)
+ ; for-loop(gen-meta-code | from, to, step, [])
+ /*DEBUG*/; say(!" ~~~ unroll-static-loops: before bagof-MetaModule")
+ /*DEBUG*/; debug
+ ; bagof-MetaCode
+ ; reverse
+ /*DEBUG*/; say(!" ~~~ unroll-static-loops: after bagof-MetaModule")
+ /*DEBUG*/; debug
+ |}
+
+ check-loop-validity(|meta-var, from, to) =
+ if <gtS>(from, to) then
+ !meta-var => Identifier(idf)
+ ; err-msg(|<concat-strings>["bad `for' loop on the meta-var ",
+ idf, " starts at ", from,
+ " which is less than ", to])
+ ; <xtc-exit> 2
+ end
+
+strategies
+
+ gen-meta-code(|i, args) =
+ /*DEBUG*/say(!" ### gen-meta-code starting"); debug;
+ (?for-kind#([meta-var, _, _, _, body]) <+ fatal-err-msg(|"ICE!"))
+ /*DEBUG*/; say(!" >>> gen-meta-code -- start -- current term >>>")
+ /*DEBUG*/; debug
+ /*DEBUG*/; say(!" >>> gen-meta-code -- start -- iterator >>>")
+ /*DEBUG*/; printf(|" meta-var = ", meta-var)
+ /*DEBUG*/; printf(|" i = ", i)
+ /*DEBUG*/; say(!" <<< gen-meta-code -- propagating meta-var's value <<< ")
+ ; !body
+ ; topdown(try(?meta-var; !Int(i)))
+ /*DEBUG*/; debug
+ /*DEBUG*/; say(!" ~~~ gen-meta-code: now recursing")
+ ; eval-meta-code => generated-code
+ ; rules(MetaCode:+ _ -> generated-code)
+ /*DEBUG*/; say(!" ~~~ gen-meta-code: recursion finished, final result:")
+ /*DEBUG*/; debug
+ /*DEBUG*/; say(!" <<<<<<<<<<<<<<<<< gen-meta-code <<<<<<<<<<<<<<<<< ")
+
+strategies
+ /*DEBUG*/printf(|str, term) = where(<fprintnl> (stderr, [str, term]))
+
+ /**
+ * for-loop(s | low, up, step, data)
+ * <=> in C:
+ * for(i = low; i <= up; i += step)
+ * s(|i, data)
+ */
+ for-loop(s : Int * a * List(a) -> a | low, up, step, data) =
+ /*DEBUG*/where(say(!"--- for-loop ---"); printf(|" i = ", low)
+ /*DEBUG*/ ; printf(|" up = ", up); printf(|" step = ", step));
+ if <leqS>(low, up) then
+ where(s(|low, data))
+ ; for-loop(s | <addS>(low, step), up, step, data)
+ end
Index: src/str/prism-desugar.str
--- src/str/prism-desugar.str (revision 26)
+++ src/str/prism-desugar.str (working copy)
@@ -21,6 +21,7 @@
<+ AddZero <+ MulOne <+ MulZero <+ DivOne <+ catch-div-by-zero
<+ EvalPlus <+ EvalMinus <+ EvalMul <+ EvalDiv
<+ EvalLt <+ EvalLtEq <+ EvalGt <+ EvalGtEq <+ EvalEq <+ EvalNeq
+ <+ EvalAnd <+ EvalOr
)
; topdown(try(SimplifyDoubles <+ TruncateDouble))
@@ -37,7 +38,7 @@
; 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
+ ; !decimals => "000000"
// Round real numbers up to 6 digits and remove trailing zeros
TruncateDouble:
@@ -64,8 +65,16 @@
compare(s) = if s then !True() else !False() end
catch-div-by-zero =
- ?|[ e / 0D ]|; debug; fatal-err-msg(|"Division by zero detected")
+ ?|[ e / 0D ]|
+ ; err-msg(|"Division by zero detected:")
+ ; debug
+ ; <xtc-exit> 3
+/**
+** Remember: we are working exclusively with Double! The trailing 'D' at
+** the end of an integer literal make it a Double() and not an Int() [This
+** is one of the minor extensions of XRM]
+*/
rules
AddZero:
@@ -86,6 +95,8 @@
DivOne:
|[ e / 1D ]| -> |[ e ]|
+rules
+
EvalPlus:
|[ d1 + d2 ]| -> |[ r ]| where <addR>(d1, d2) => r
@@ -110,8 +121,40 @@
EvalGtEq:
|[ d1 >= d2 ]| -> <compare(geqR)>(d1, d2)
+ /* FIXME: The following rules could be generalized
+ We need to check whether d1 appears in the list at the RHS */
EvalEq:
|[ d1 = d2 ]| -> <compare(real-eq)>(d1, d2)
+ /* FIXME: Same thing as EvalEq */
EvalNeq:
|[ d1 != d2 ]| -> <compare(not(real-eq))>(d1, d2)
+
+rules
+/* FIXME: Can we optimize this in a single rule?
+ Since the optimization would decrease readability,
+ is it worth it?
+ eg:
+ EvalAnd:
+ And(x, y) -> True() where x => True(); y => True()
+ EvalAnd:
+ And(x, y) -> False() where x => False() + y => False()
+*/
+
+ EvalAnd:
+ |[ true & true ]| -> |[ true ]|
+ EvalAnd:
+ |[ true & false ]| -> |[ false ]|
+ EvalAnd:
+ |[ false & true ]| -> |[ false ]|
+ EvalAnd:
+ |[ false & false ]| -> |[ false ]|
+
+ EvalOr:
+ |[ true | true ]| -> |[ true ]|
+ EvalOr:
+ |[ true | false ]| -> |[ true ]|
+ EvalOr:
+ |[ false | true ]| -> |[ true ]|
+ EvalOr:
+ |[ false | false ]| -> |[ false ]|
Index: src/syn/xrm/XRM-Arrays.sdf
--- src/syn/xrm/XRM-Arrays.sdf (revision 26)
+++ src/syn/xrm/XRM-Arrays.sdf (working copy)
@@ -7,13 +7,20 @@
%% ArrayAccess ::= Identifier ArraySubscript {ArraySubscript}
%%
%% ArraySubscript ::= "[" Identifier "]"
+ %%
+ %% ArrayAccessPrime ::= Identifier ArraySubscript+ "'"
sorts ArrayAccess ArraySubscript
context-free syntax
Identifier ArraySubscript+ -> ArrayAccess {cons("ArrayAccess")}
- "[" Identifier "]" -> ArraySubscript {bracket}
+ "[" Expression "]" -> ArraySubscript {bracket}
%% Note: why use bracket here?
%% This is a work around. In SDF, if a production contains literals,
%% a constructor is required. With brackets, we specify that literals
%% are allowed there, however this does not create a node in the AST.
+
+ sorts ArrayAccessPrime
+ context-free syntax
+ Identifier ArraySubscript+ "'"
+ -> ArrayAccessPrime {cons("ArrayAccessPrime")}
Index: src/syn/xrm/XRM-StartSymbols.sdf
--- src/syn/xrm/XRM-StartSymbols.sdf (revision 26)
+++ src/syn/xrm/XRM-StartSymbols.sdf (working copy)
@@ -14,7 +14,6 @@
Expression
Updates
Identifier
- IdentifierPrime
SystemComp
RewardStruct
ModulesFileSection
Index: src/syn/xrm/XRM-StaticIf.sdf
--- src/syn/xrm/XRM-StaticIf.sdf (revision 26)
+++ src/syn/xrm/XRM-StaticIf.sdf (working copy)
@@ -24,24 +24,24 @@
context-free syntax
%% if-then at top-level
- "if" Expression "then" ModulesFileSection+ "end"
+ "if" Expression "then" ModulesFileSection* "end"
-> ModulesFileSection {cons("OuterStaticIf")}
%% if-then-else at top-level
"if" Expression "then"
- ModulesFileSection+
+ ModulesFileSection*
"else"
- ModulesFileSection+
+ ModulesFileSection*
"end" -> ModulesFileSection {cons("OuterStaticIf")}
context-free syntax
%% if-then within modules
- "if" Expression "then" DeclarationOrCommand+ "end"
+ "if" Expression "then" DeclarationOrCommand* "end"
-> DeclarationOrCommand {cons("InnerStaticIf")}
%% if-then-else within modules
"if" Expression "then"
- DeclarationOrCommand+
+ DeclarationOrCommand*
"else"
- DeclarationOrCommand+
+ DeclarationOrCommand*
"end" -> DeclarationOrCommand {cons("InnerStaticIf")}
Index: src/syn/xrm/StrategoXRM.sdf
--- src/syn/xrm/StrategoXRM.sdf (revision 26)
+++ src/syn/xrm/StrategoXRM.sdf (working copy)
@@ -17,6 +17,8 @@
"|[" Expression "]|" -> StrategoTerm {prefer,cons("ToTerm")}
"|[" Declaration "]|" -> StrategoTerm {prefer,cons("ToTerm")}
"|[" Command "]|" -> StrategoTerm {prefer,cons("ToTerm")}
+ "|[" OuterStaticFor "]|" -> StrategoTerm {prefer,cons("ToTerm")}
+ "|[" InnerStaticFor "]|" -> StrategoTerm {prefer,cons("ToTerm")}
context-free syntax
Index: src/syn/xrm/XRM-Literals.sdf
--- src/syn/xrm/XRM-Literals.sdf (revision 26)
+++ src/syn/xrm/XRM-Literals.sdf (working copy)
@@ -2,6 +2,8 @@
imports PRISM-to-XRM
exports
+ %% NOTES: This block is a simple "syntax" block and contains SDF kernel
+ %% syntax. In fact everything is
syntax
<LInt-LEX> "d" -> <LDouble-CF> {bracket}
<LInt-LEX> "D" -> <LDouble-CF> {bracket}
Index: src/syn/xrm/XRM-MetaVars.sdf
--- src/syn/xrm/XRM-MetaVars.sdf (revision 26)
+++ src/syn/xrm/XRM-MetaVars.sdf (working copy)
@@ -1 +1,5 @@
module XRM-MetaVars
+exports
+ variables
+ [s][0-9]* -> DeclarationOrCommand {prefer}
+ "s"[0-9]* "*" -> DeclarationOrCommand+ {prefer}
Index: src/syn/xrm/XRM-Update.sdf
--- src/syn/xrm/XRM-Update.sdf (revision 0)
+++ src/syn/xrm/XRM-Update.sdf (revision 0)
@@ -0,0 +1,22 @@
+module XRM-Update
+imports
+ PRISM-to-XRM
+ XRM-Arrays
+exports
+
+ %% EBNF Grammar: Extended Update Elements
+ %% UpdateElement ::= "(" ArrayAccessPrime "=" Expression ")"
+ %% (* The following form is kept for backwards compat. *)
+ %% | ArrayAccessPrime "=" Expression
+
+
+ sorts UpdateElement
+ context-free syntax
+ "(" ArrayAccessPrime "=" Expression ")"
+ -> UpdateElement {cons("UpdateElement")}
+
+ %% NOTE: Officially this form is NOT supported but it is still supported
+ %% for backwards compatibility. This form introduces an ambiguity
+ %% because the `+' between the elements can be bound to the
+ %% Expression or can be a separator between two elements.
+ ArrayAccessPrime "=" Expression -> UpdateElement {cons("UpdateElement")}
Index: src/syn/xrm/XRM-Main.sdf
--- src/syn/xrm/XRM-Main.sdf (revision 26)
+++ src/syn/xrm/XRM-Main.sdf (working copy)
@@ -6,3 +6,5 @@
XRM-StaticFor
XRM-StaticIf
XRM-Literals
+ XRM-Declaration
+ XRM-Update
Index: src/syn/xrm/XRM-Declaration.sdf
--- src/syn/xrm/XRM-Declaration.sdf (revision 0)
+++ src/syn/xrm/XRM-Declaration.sdf (revision 0)
@@ -0,0 +1,22 @@
+module XRM-Declaration
+imports
+ PRISM-to-XRM
+ XRM-Arrays
+exports
+
+ %% EBNF Grammar: Extended Variable declarations
+ %% Declaration ::= ArrayAccess ":" "[" Expression .. Expression "]" ";"
+ %% | ArrayAccess ":" "[" Expression .. Expression "]" "init" Expression ";"
+ %% | ArrayAccess ":" "bool" ";"
+ %% | ArrayAccess ":" "bool" "init" Expression ";"
+
+ context-free syntax
+ ArrayAccess ":" "[" Expression ".." Expression "]" ";"
+ -> Declaration {cons("IntDecNoInit")}
+ ArrayAccess ":" "[" Expression ".." Expression "]" "init" Expression ";"
+ -> Declaration {cons("IntDec")}
+
+
+ ArrayAccess ":" "bool" ";" -> Declaration {cons("BoolDecNoInit")}
+ ArrayAccess ":" "bool" "init" Expression ";"
+ -> Declaration {cons("BoolDec")}
Index: src/syn/xrm/XRM-Module.sdf
--- src/syn/xrm/XRM-Module.sdf (revision 26)
+++ src/syn/xrm/XRM-Module.sdf (working copy)
@@ -15,4 +15,4 @@
context-free syntax
"module" ArrayAccess DeclarationOrCommand* "endmodule"
- -> Module {cons("MetaModule")}
+ -> Module {cons("Module")}
Index: src/syn/xrm/XRM-Expression.sdf
--- src/syn/xrm/XRM-Expression.sdf (revision 26)
+++ src/syn/xrm/XRM-Expression.sdf (working copy)
@@ -3,16 +3,19 @@
PRISM-to-XRM
exports
+ %% EBNF Grammar: Extended Expressions
+ %% Expression ::=
+ %% ArrayAccess
+ %% | Expression "<<" Expression
+ %% | Expression ">>" Expression
+
context-free syntax
- "++" Expression -> Expression {cons("PreIncr")}
- "--" Expression -> Expression {cons("PreDecr")}
+ ArrayAccess -> Expression
Expression ">>" Expression -> Expression {left,cons("RightShift")}
Expression "<<" Expression -> Expression {left,cons("LeftShift")}
context-free priorities
{
- "++" Expression -> Expression
- "--" Expression -> Expression
"+" Expression -> Expression
"-" Expression -> Expression
}
@@ -24,12 +27,3 @@
Expression "*" Expression -> Expression
Expression "/" Expression -> Expression
}
-
- %% We need to add a lexical restriction so that when we have ++x it is
- %% indeed understood as ++x and not +(+x)
- %% This is due to the fact that sglr doesn't try to find the longuest match
- %% So we need tell it to see whether there is another + (or -) after a
- %% first + (or -)
- lexical restrictions
- "+" -/- [\+]
- "-" -/- [\-]
Index: src/syn/prism/PRISM-Declaration.sdf
Index: src/syn/prism/PRISM-StartSymbols.sdf
--- src/syn/prism/PRISM-StartSymbols.sdf (revision 26)
+++ src/syn/prism/PRISM-StartSymbols.sdf (working copy)
@@ -14,7 +14,6 @@
Expression
Updates
Identifier
- IdentifierPrime
SystemComp
RewardStruct
ModulesFileSection
Index: tests/xrm/inner-static-if.xpm
--- tests/xrm/inner-static-if.xpm (revision 26)
+++ tests/xrm/inner-static-if.xpm (working copy)
@@ -2,13 +2,11 @@
module dummy
for i from 0 to 42 do
- // FIXME: x here shall be replaced with x[i]
- // but this is not supported ATM
if i=0 | i=42 then
- x : [0..2];
+ x[i] : [0..2];
else
- x : [0..1];
+ x[i] : [0..1];
end
- [] x=0 -> x'=1;
+ [] x[i]=0 -> x[i]'=1;
end
endmodule
Index: tests/xrm/inner-static-for-step.xpm
--- tests/xrm/inner-static-for-step.xpm (revision 26)
+++ tests/xrm/inner-static-for-step.xpm (working copy)
@@ -2,9 +2,7 @@
module dummy
for i from 0 to 42 step 2 do
- // FIXME: x here shall be replaced with x[i]
- // but this is not supported ATM
- x : [0..1];
- [] x=0 -> x'=1;
+ x[i] : [0..1];
+ [] x[i]=0 -> x[i]'=1;
end
endmodule
Index: tests/xrm/outer-static-if.xpm
--- tests/xrm/outer-static-if.xpm (revision 26)
+++ tests/xrm/outer-static-if.xpm (working copy)
@@ -3,13 +3,13 @@
for i from 0 to 42 do
if i<1 & i>41 then
module dummy[i]
- x : [0..1];
- [] x=0 -> x'=1;
+ x[i] : [0..1];
+ [] x[i]=0 -> x[i]'=1;
endmodule
else
module dummy[i]
- x : [0..2];
- [] x=1 -> x'=2;
+ x[i] : [0..2];
+ [] x[i]=1 -> x[i]'=2;
endmodule
end
end
Index: tests/xrm/outer-static-for-step.xpm
--- tests/xrm/outer-static-for-step.xpm (revision 26)
+++ tests/xrm/outer-static-for-step.xpm (working copy)
@@ -2,7 +2,7 @@
for i from 0 to 42 step 2 do
module dummy[i]
- x : [0..1];
- [] x=0 -> x'=1;
+ x[i] : [0..1];
+ [] x[i]=0 -> x[i]'=1;
endmodule
end
Index: tests/xrm/static-if.xpm
--- tests/xrm/static-if.xpm (revision 26)
+++ tests/xrm/static-if.xpm (working copy)
@@ -3,21 +3,19 @@
for i from 0 to 42 do
if i<1 & i>41 then
module dummy[i]
- for i from 0 to 42 do
- // FIXME: x here shall be replaced with x[i]
- // but this is not supported ATM
+ for j from 0 to 42 do
if i=0 | i=42 then
- x : [0..2];
+ x[i][j] : [0..2];
else
- x : [0..1];
+ x[i][j] : [0..1];
end
- [] x=0 -> x'=1;
+ [] x[i][j]=0 -> x[i][j]'=1;
end
endmodule
else
module dummyelse[i]
- y : [0..1];
- [] y=0 -> y'=1;
+ y[i] : [0..1];
+ [] y[i]=0 -> y[i]'=1;
endmodule
end
end
Index: tests/xrm/inner-static-for.xpm
--- tests/xrm/inner-static-for.xpm (revision 26)
+++ tests/xrm/inner-static-for.xpm (working copy)
@@ -2,9 +2,7 @@
module dummy
for i from 0 to 42 do
- // FIXME: x here shall be replaced with x[i]
- // but this is not supported ATM
- x : [0..1];
- [] x=0 -> x'=1;
+ x[i] : [0..1];
+ [] x[i]=0 -> x[i]'=1;
end
endmodule
Index: tests/xrm/static-for-step.xpm
--- tests/xrm/static-for-step.xpm (revision 26)
+++ tests/xrm/static-for-step.xpm (working copy)
@@ -2,11 +2,9 @@
for i from 0 to 42 step 2 do
module dummy[i]
- for i from 0 to 42 step 2 do
- // FIXME: x here shall be replaced with x[i]
- // but this is not supported ATM
- x : [0..1];
- [] x=0 -> x'=1;
+ for j from 0 to 42 step 2 do
+ x[i][j] : [0..1];
+ [] x[i][j]=0 -> x[i][j]'=1;
end
endmodule
end
Index: tests/xrm/outer-static-for.xpm
--- tests/xrm/outer-static-for.xpm (revision 26)
+++ tests/xrm/outer-static-for.xpm (working copy)
@@ -2,7 +2,7 @@
for i from 0 to 42 do
module dummy[i]
- x : [0..1];
- [] x=0 -> x'=1;
+ x[i] : [0..1];
+ [] x[i]=0 -> x[i]'=1;
endmodule
end
Index: tests/xrm/simple_01.xpm
--- tests/xrm/simple_01.xpm (revision 26)
+++ tests/xrm/simple_01.xpm (working copy)
@@ -4,7 +4,4 @@
[] x=1 -> (x'=x/x>>2+x);
[] x=2 -> (x'=x+x<<3/x);
- [] (x=42) -> (x'=++x);
- [] ++x=4 -> true; // x=3
- [] --x=4 -> true; // x=5
endmodule
Index: tests/xrm/static-for.xpm
--- tests/xrm/static-for.xpm (revision 26)
+++ tests/xrm/static-for.xpm (working copy)
@@ -2,11 +2,9 @@
for i from 0 to 42 do
module dummy[i]
- for i from 0 to 42 do
- // FIXME: x here shall be replaced with x[i]
- // but this is not supported ATM
- x : [0..1];
- [] x=0 -> x'=1;
+ for j from 0 to 42 do
+ x[i][j] : [0..1];
+ [] x[i][j]=0 -> x[i][j]'=1;
end
endmodule
end
1
0
https://svn.lrde.epita.fr/svn/xrm/trunk
Index: ChangeLog
from SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr>
Add MetaModules and some other extensions.
* src/tools/parse-xrm.str: Factorize some code in common with
parse-prism in parser-common.str. Improve use of addPosInfo.
* src/tools/parse-prism.str: Likewise.
* src/tools/parser-common.str: New.
* src/lib/xrm/pp/xrm-module.str: Add MetaModule boxing.
* src/lib/xrm/pp/xrm-to-abox.str: Import xrm-arrays.
* src/lib/xrm/pp/xrm-arrays.meta: New.
* src/lib/xrm/pp/xrm-arrays.str: New.
* src/str/xrm-front.str: Use parse-xrm instead of receiving ATerms on
stdin. Use addPosInfo by default.
* src/str/prism-desugar.str: Update literals used in concrete syntax.
* src/syn/xrm/XRM-Arrays.sdf: New.
* src/syn/xrm/XRM-StaticIf.sdf: Add EBNF grammar in comments.
* src/syn/xrm/XRM-Literals.sdf: New.
* src/syn/xrm/XRM-Main.sdf: Import XRM-Literals.
* src/syn/xrm/XRM-Module.sdf: Add MetaModule.
* src/syn/prism/PRISM-MetaVars.sdf: Add a FIXME.
* src/syn/prism/StrategoPRISM.sdf: Add a FIXME. Fix meta-escapes.
* tests/xrm/outer-static-if.xpm: Update test case.
* tests/xrm/outer-static-for-step.xpm,
* tests/xrm/static-if.xpm,
* tests/xrm/static-for-step.xpm,
* tests/xrm/outer-static-for.xpm,
* tests/xrm/static-for.xpm,
* tests/test-xrm-front.sh.in: Adapt to xrm-front changes.
src/lib/xrm/pp/xrm-arrays.meta | 1
src/lib/xrm/pp/xrm-arrays.str | 9 ++++
src/lib/xrm/pp/xrm-module.str | 8 +++
src/lib/xrm/pp/xrm-to-abox.str | 1
src/str/prism-desugar.str | 16 +++----
src/str/xrm-front.str | 29 +++++++++++-
src/syn/prism/PRISM-MetaVars.sdf | 3 -
src/syn/prism/StrategoPRISM.sdf | 7 +--
src/syn/xrm/XRM-Arrays.sdf | 19 ++++++++
src/syn/xrm/XRM-Literals.sdf | 12 +++++
src/syn/xrm/XRM-Main.sdf | 1
src/syn/xrm/XRM-Module.sdf | 9 ++++
src/syn/xrm/XRM-StaticIf.sdf | 18 ++++++++
src/tools/parse-prism.str | 81 ++----------------------------------
src/tools/parse-xrm.str | 81 ++----------------------------------
src/tools/parser-common.str | 77 ++++++++++++++++++++++++++++++++++
tests/test-xrm-front.sh.in | 12 -----
tests/xrm/outer-static-for-step.xpm | 5 --
tests/xrm/outer-static-for.xpm | 5 --
tests/xrm/outer-static-if.xpm | 7 ---
tests/xrm/static-for-step.xpm | 5 --
tests/xrm/static-for.xpm | 5 --
tests/xrm/static-if.xpm | 7 ---
23 files changed, 214 insertions(+), 204 deletions(-)
Index: src/tools/parse-xrm.str
--- src/tools/parse-xrm.str (revision 25)
+++ src/tools/parse-xrm.str (working copy)
@@ -4,6 +4,7 @@
imports
liblib
tool-doc
+ parser-common
strategies
main-parse-xrm =
@@ -11,7 +12,7 @@
xtc-io-wrap(
parse-xrm-options
, parse-xrm-usage
- , parse-xrm-about
+ , parser-about
, !["sglr", "implode-asfix", "XRM.tbl", "pp-aterm"]
, parse-xrm
)
@@ -25,18 +26,13 @@
strategies
parse-xrm =
- xtc-sglr-no-heuristics(get-parse-table, get-start-symbol)
+ where(?FILE(input-file-name) + !"stdin" => input-file-name)
+ ; xtc-sglr-no-heuristics(get-parse-table, get-start-symbol)
; if must-preserve-comments then
xtc-transform(!"asfix-anno-comments", pass-verbose)
end
- /*
- ** -p is supposed to be the original path of the file, used in the
- ** position representation. The input of addPosInfo is an asfix file,
- ** which is not the original source file. The -p option is almost
- ** never used by addPosInfo but it's a "mandatory option"
- */
; if must-preserve-positions then
- xtc-transform(!"addPosInfo", !["-p", "DummyFileName"
+ xtc-transform(!"addPosInfo", !["-p", input-file-name
| <pass-verbose>()])
end
; xtc-implode-asfix
@@ -44,18 +40,6 @@
xtc-transform(!"pp-aterm", pass-verbose)
end
- /* sglr options:
- ** -fi: heuristic: injection count
- ** -fe: heuristic: eagerness
- ** -2: use AsFix2 output format
- ** -A: ambiguities are treated as errors
- ** -p <file>: parse table to use
- ** -s <symbol>: start symbol to use
- */
- xtc-sglr-no-heuristics(tbl, sort) =
- xtc-transform(!"sglr", !["-fi", "-fe", "-2A", "-p", <tbl; xtc-find> (),
- "-s", <sort> () | <pass-v-verbose> ()])
-
strategies
symbol-option =
@@ -72,50 +56,6 @@
<get-config> "start-symbol" <+ !"ModulesFile"
strategies
-
- preserve-comments-option =
- Option("--preserve-comments"
- , <set-preserve-comments> "yes"
- , !HelpString("--preserve-comments", "Preserve source code
- comments as annotations of the abstract syntax tree. [off]")
- )
-
- set-preserve-comments =
- <set-config> ("preserve-comments", <id>)
-
- must-preserve-comments =
- <get-config> "preserve-comments" => "yes"
-
-strategies
-
- preserve-positions-option =
- Option("--preserve-positions"
- , <set-preserve-positions> "yes"
- , !HelpString("--preserve-positions", "Preserve source code positions in
- the input file as annotations of the abstract syntax tree.
- [off]")
- )
-
- set-preserve-positions =
- <set-config> ("preserve-positions", <id>)
-
- must-preserve-positions =
- <get-config> "preserve-positions" => "yes"
-
-strategies
- pp-aterm-option =
- Option("-A" + "--pp-aterm"
- , <set-pp-aterm> "yes"
- , !HelpString("-A | --pp-aterm", "Pretty print output with pp-aterm")
- )
-
- set-pp-aterm =
- <set-config> ("pp-aterm", <id>)
-
- must-pp-aterm =
- <get-config> "pp-aterm" => "yes"
-
-strategies
/*
** We use two parse tables for performances. One of them (XRM.tbl) has a
** single start symbol (ModulesFile) and the other (XRM-StartSymbols) has
@@ -145,14 +85,3 @@
, OptionUsage()
, AutoReportBugs()
]
-
- parse-xrm-about =
- <tool-doc>
- [ AutoProgram()
- , Author(Person("SIGOURE Benoit", "sigoure.benoit(a)lrde.epita.fr"))
- , GNU_GPL("2006", "SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr>")
- , Config([
- DefaultXTCRepository()
- , CurrentXTCRepository()
- ])
- ]
Index: src/tools/parse-prism.str
--- src/tools/parse-prism.str (revision 25)
+++ src/tools/parse-prism.str (working copy)
@@ -4,6 +4,7 @@
imports
liblib
tool-doc
+ parser-common
strategies
main-parse-prism =
@@ -11,7 +12,7 @@
xtc-io-wrap(
parse-prism-options
, parse-prism-usage
- , parse-prism-about
+ , parser-about
, !["sglr", "implode-asfix", "PRISM.tbl", "pp-aterm"]
, parse-prism
)
@@ -25,18 +26,13 @@
strategies
parse-prism =
- xtc-sglr-no-heuristics(get-parse-table, get-start-symbol)
+ where(?FILE(input-file-name) + !"stdin" => input-file-name)
+ ; xtc-sglr-no-heuristics(get-parse-table, get-start-symbol)
; if must-preserve-comments then
xtc-transform(!"asfix-anno-comments", pass-verbose)
end
- /*
- ** -p is supposed to be the original path of the file, used in the
- ** position representation. The input of addPosInfo is an asfix file,
- ** which is not the original source file. The -p option is almost
- ** never used by addPosInfo but it's a "mandatory option"
- */
; if must-preserve-positions then
- xtc-transform(!"addPosInfo", !["-p", "DummyFileName"
+ xtc-transform(!"addPosInfo", !["-p", input-file-name
| <pass-verbose>()])
end
; xtc-implode-asfix
@@ -44,18 +40,6 @@
xtc-transform(!"pp-aterm", pass-verbose)
end
- /* sglr options:
- ** -fi: heuristic: injection count
- ** -fe: heuristic: eagerness
- ** -2: use AsFix2 output format
- ** -A: ambiguities are treated as errors
- ** -p <file>: parse table to use
- ** -s <symbol>: start symbol to use
- */
- xtc-sglr-no-heuristics(tbl, sort) =
- xtc-transform(!"sglr", !["-fi", "-fe", "-2A", "-p", <tbl; xtc-find> (),
- "-s", <sort> () | <pass-v-verbose> ()])
-
strategies
symbol-option =
@@ -72,50 +56,6 @@
<get-config> "start-symbol" <+ !"ModulesFile"
strategies
-
- preserve-comments-option =
- Option("--preserve-comments"
- , <set-preserve-comments> "yes"
- , !HelpString("--preserve-comments", "Preserve source code
- comments as annotations of the abstract syntax tree. [off]")
- )
-
- set-preserve-comments =
- <set-config> ("preserve-comments", <id>)
-
- must-preserve-comments =
- <get-config> "preserve-comments" => "yes"
-
-strategies
-
- preserve-positions-option =
- Option("--preserve-positions"
- , <set-preserve-positions> "yes"
- , !HelpString("--preserve-positions", "Preserve source code positions in
- the input file as annotations of the abstract syntax tree.
- [off]")
- )
-
- set-preserve-positions =
- <set-config> ("preserve-positions", <id>)
-
- must-preserve-positions =
- <get-config> "preserve-positions" => "yes"
-
-strategies
- pp-aterm-option =
- Option("-A" + "--pp-aterm"
- , <set-pp-aterm> "yes"
- , !HelpString("-A | --pp-aterm", "Pretty print output with pp-aterm")
- )
-
- set-pp-aterm =
- <set-config> ("pp-aterm", <id>)
-
- must-pp-aterm =
- <get-config> "pp-aterm" => "yes"
-
-strategies
/*
** We use two parse tables for performances. One of them (PRISM.tbl) has a
** single start symbol (ModulesFile) and the other (PRISM-StartSymbols) has
@@ -145,14 +85,3 @@
, OptionUsage()
, AutoReportBugs()
]
-
- parse-prism-about =
- <tool-doc>
- [ AutoProgram()
- , Author(Person("SIGOURE Benoit", "sigoure.benoit(a)lrde.epita.fr"))
- , GNU_GPL("2006", "SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr>")
- , Config([
- DefaultXTCRepository()
- , CurrentXTCRepository()
- ])
- ]
Index: src/tools/parser-common.str
--- src/tools/parser-common.str (revision 0)
+++ src/tools/parser-common.str (revision 0)
@@ -0,0 +1,77 @@
+// used by parse-prism and parse-xrm to factorize common strategies
+
+module parser-common
+
+strategies
+
+ /* sglr options:
+ ** -fi: heuristic: injection count
+ ** -fe: heuristic: eagerness
+ ** -2: use AsFix2 output format
+ ** -A: ambiguities are treated as errors
+ ** -p <file>: parse table to use
+ ** -s <symbol>: start symbol to use
+ */
+ xtc-sglr-no-heuristics(tbl, sort) =
+ xtc-transform(!"sglr", !["-fi", "-fe", "-2A", "-p", <tbl; xtc-find> (),
+ "-s", <sort> () | <pass-v-verbose> ()])
+
+strategies
+
+ preserve-comments-option =
+ Option("--preserve-comments"
+ , <set-preserve-comments> "yes"
+ , !HelpString("--preserve-comments", "Preserve source code
+ comments as annotations of the abstract syntax tree. [off]")
+ )
+
+ set-preserve-comments =
+ <set-config> ("preserve-comments", <id>)
+
+ must-preserve-comments =
+ <get-config> "preserve-comments" => "yes"
+
+strategies
+
+ preserve-positions-option =
+ Option("--preserve-positions"
+ , <set-preserve-positions> "yes"
+ , !HelpString("--preserve-positions", "Preserve source code positions in
+ the input file as annotations of the abstract syntax tree.
+ [off]")
+ )
+
+ set-preserve-positions =
+ <set-config> ("preserve-positions", <id>)
+
+ must-preserve-positions =
+ <get-config> "preserve-positions" => "yes"
+
+strategies
+ pp-aterm-option =
+ Option("-A" + "--pp-aterm"
+ , <set-pp-aterm> "yes"
+ , !HelpString("-A | --pp-aterm", "Pretty print output with pp-aterm")
+ )
+
+ set-pp-aterm =
+ <set-config> ("pp-aterm", <id>)
+
+ must-pp-aterm =
+ <get-config> "pp-aterm" => "yes"
+
+/**
+ * Documentation
+ */
+strategies
+
+ parser-about =
+ <tool-doc>
+ [ AutoProgram()
+ , Author(Person("SIGOURE Benoit", "sigoure.benoit(a)lrde.epita.fr"))
+ , GNU_GPL("2006", "SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr>")
+ , Config([
+ DefaultXTCRepository()
+ , CurrentXTCRepository()
+ ])
+ ]
Index: src/lib/xrm/pp/xrm-module.str
--- src/lib/xrm/pp/xrm-module.str (revision 25)
+++ src/lib/xrm/pp/xrm-module.str (working copy)
@@ -10,3 +10,11 @@
]
KW["endmodule"]
] ]|
+
+ prism-to-box:
+ MetaModule(array-access, dec-or-cmd-list)
+ -> box |[ V[ V is=2 [ H hs=1 [KW["module"] ~array-access ]
+ ~*dec-or-cmd-list
+ ]
+ KW["endmodule"]
+ ] ]|
Index: src/lib/xrm/pp/xrm-to-abox.str
--- src/lib/xrm/pp/xrm-to-abox.str (revision 25)
+++ src/lib/xrm/pp/xrm-to-abox.str (working copy)
@@ -23,6 +23,7 @@
xrm-module
xrm-staticfor
xrm-staticif
+ xrm-arrays
strategies
Index: src/lib/xrm/pp/xrm-arrays.meta
--- src/lib/xrm/pp/xrm-arrays.meta (revision 0)
+++ src/lib/xrm/pp/xrm-arrays.meta (revision 0)
@@ -0,0 +1 @@
+Meta([Syntax("Stratego-Box")])
Index: src/lib/xrm/pp/xrm-arrays.str
--- src/lib/xrm/pp/xrm-arrays.str (revision 0)
+++ src/lib/xrm/pp/xrm-arrays.str (revision 0)
@@ -0,0 +1,9 @@
+module xrm-arrays
+
+rules
+
+ // Identifier ArraySubscript+ -> ArrayAccess
+ prism-to-box:
+ ArrayAccess(idf, subscripts) -> H hs=0 [ ~idf ~*subscripts-impl ]
+ where
+ <mapconcat(\ x -> [S("["), x, S("]")] \)> subscripts => subscripts-impl
Index: src/str/xrm-front.str
--- src/str/xrm-front.str (revision 25)
+++ src/str/xrm-front.str (working copy)
@@ -14,14 +14,18 @@
xrm-front-options
, xrm-front-usage
, xrm-front-about
- , !["pp-prism", "pp-aterm"]
+ , !["parse-xrm", "pp-prism", "pp-aterm"]
, main-wrapped
)
main-wrapped =
check-options
- ; read-from
+ ; xtc-transform(!"parse-xrm", // parse input (returns a FILE)
+ !["-b", "--preserve-positions" | <pass-verbose>()])
+ ; read-from // read parsed input
+ ; strip-annos
; xrm-front-pipeline // transformations
+ ; if not(must-keep-attributes) then strip-annos end
; if <get-config> "-b" then
write-to // output binary ATerms
else
@@ -51,6 +55,7 @@
xrm-front-options =
pp-prism-option
+ pp-aterm-option
+ + keep-attributes-option
+ desugar-option
// check the options are consistent
@@ -72,6 +77,21 @@
strategies
+ keep-attributes-option =
+ Option("-K" + "--keep-attributes"
+ , <set-keep-attributes> "yes"
+ , !HelpString("-K | --keep-attributes", "Don't remove attributes when
+ printing ATerms (this includes positions)")
+ )
+
+ set-keep-attributes =
+ <set-config> ("keep-attributes", <id>)
+
+ must-keep-attributes =
+ <get-config> "keep-attributes" => "yes"
+
+strategies
+
pp-prism-option =
Option("-P" + "--pp-prism"
, <set-pp-prism> "yes"
@@ -121,8 +141,9 @@
xrm-front-usage =
<tool-doc>
[ Usage("xrm-front [OPTIONS]")
- , Summary("Transforms an eXtended Reactive Module abstract syntax
- tree in ATerm format to a PRISM-equivalant abstract syntax tree.")
+ , Summary("Transforms an eXtended Reactive Module source file in a
+ PRISM-equivalant abstract syntax tree (default) or source
+ code. (see option -P)")
, OptionUsage()
, AutoReportBugs()
]
Index: src/str/prism-desugar.str
--- src/str/prism-desugar.str (revision 25)
+++ src/str/prism-desugar.str (working copy)
@@ -64,27 +64,27 @@
compare(s) = if s then !True() else !False() end
catch-div-by-zero =
- ?|[ e / 0 ]|; fatal-err-msg(|"Division by zero detected")
+ ?|[ e / 0D ]|; debug; fatal-err-msg(|"Division by zero detected")
rules
AddZero:
- |[ e + 0 ]| -> |[ e ]|
+ |[ e + 0D ]| -> |[ e ]|
AddZero:
- |[ 0 + e ]| -> |[ e ]|
+ |[ 0D + e ]| -> |[ e ]|
MulOne:
- |[ e * 1 ]| -> |[ e ]|
+ |[ e * 1D ]| -> |[ e ]|
MulOne:
- |[ 1 * e ]| -> |[ e ]|
+ |[ 1D * e ]| -> |[ e ]|
MulZero:
- |[ e * 0 ]| -> |[ 0 ]|
+ |[ e * 0D ]| -> |[ 0D ]|
MulZero:
- |[ 0 * e ]| -> |[ 0 ]|
+ |[ 0D * e ]| -> |[ 0D ]|
DivOne:
- |[ e / 1 ]| -> |[ e ]|
+ |[ e / 1D ]| -> |[ e ]|
EvalPlus:
|[ d1 + d2 ]| -> |[ r ]| where <addR>(d1, d2) => r
Index: src/syn/xrm/XRM-Arrays.sdf
--- src/syn/xrm/XRM-Arrays.sdf (revision 0)
+++ src/syn/xrm/XRM-Arrays.sdf (revision 0)
@@ -0,0 +1,19 @@
+module XRM-Arrays
+imports
+ PRISM-to-XRM
+exports
+
+ %% EBNF Grammar: Arrays
+ %% ArrayAccess ::= Identifier ArraySubscript {ArraySubscript}
+ %%
+ %% ArraySubscript ::= "[" Identifier "]"
+
+ sorts ArrayAccess ArraySubscript
+ context-free syntax
+ Identifier ArraySubscript+ -> ArrayAccess {cons("ArrayAccess")}
+ "[" Identifier "]" -> ArraySubscript {bracket}
+
+ %% Note: why use bracket here?
+ %% This is a work around. In SDF, if a production contains literals,
+ %% a constructor is required. With brackets, we specify that literals
+ %% are allowed there, however this does not create a node in the AST.
Index: src/syn/xrm/XRM-StaticIf.sdf
--- src/syn/xrm/XRM-StaticIf.sdf (revision 25)
+++ src/syn/xrm/XRM-StaticIf.sdf (working copy)
@@ -4,6 +4,24 @@
XRM-Module
exports
+ %% EBNF Grammar: Static if-then-else
+ %% (* if-then-else at top-level *)
+ %% ModulesFileSection ::=
+ %% "if" Expression "then" ModulesFileSection {ModulesFileSection} "end"
+ %% | "if" Expression "then"
+ %% ModulesFileSection {ModulesFileSection}
+ %% "else"
+ %% ModulesFileSection {ModulesFileSection}
+ %% "end"
+ %%
+ %% DeclarationOrCommand ::=
+ %% "if" Expression "then" DeclarationOrCommand {DeclarationOrCommand} "end"
+ %% | "if" Expression "then"
+ %% DeclarationOrCommand {DeclarationOrCommand}
+ %% "else"
+ %% DeclarationOrCommand {DeclarationOrCommand}
+ %% "end"
+
context-free syntax
%% if-then at top-level
"if" Expression "then" ModulesFileSection+ "end"
Index: src/syn/xrm/XRM-Literals.sdf
--- src/syn/xrm/XRM-Literals.sdf (revision 0)
+++ src/syn/xrm/XRM-Literals.sdf (revision 0)
@@ -0,0 +1,12 @@
+module XRM-Literals
+imports PRISM-to-XRM
+exports
+
+ syntax
+ <LInt-LEX> "d" -> <LDouble-CF> {bracket}
+ <LInt-LEX> "D" -> <LDouble-CF> {bracket}
+ <LInt-LEX> "f" -> <LDouble-CF> {bracket}
+ <LInt-LEX> "F" -> <LDouble-CF> {bracket}
+
+ lexical restrictions
+ LDouble -/- [dDfF]
Index: src/syn/xrm/XRM-Main.sdf
--- src/syn/xrm/XRM-Main.sdf (revision 25)
+++ src/syn/xrm/XRM-Main.sdf (working copy)
@@ -5,3 +5,4 @@
XRM-Expression
XRM-StaticFor
XRM-StaticIf
+ XRM-Literals
Index: src/syn/xrm/XRM-Module.sdf
--- src/syn/xrm/XRM-Module.sdf (revision 25)
+++ src/syn/xrm/XRM-Module.sdf (working copy)
@@ -1,9 +1,18 @@
module XRM-Module
imports
PRISM-to-XRM
+ XRM-Arrays
exports
+ %% EBNF Grammar: eXtended Modules
+ %% DeclarationOrCommand ::= Declaration | Command
+ %% Module ::= "module" ArrayAccess Declaration* Command* "endmodule"
+
sorts DeclarationOrCommand
context-free syntax
Declaration -> DeclarationOrCommand
Command -> DeclarationOrCommand
+
+ context-free syntax
+ "module" ArrayAccess DeclarationOrCommand* "endmodule"
+ -> Module {cons("MetaModule")}
Index: src/syn/prism/PRISM-MetaVars.sdf
--- src/syn/prism/PRISM-MetaVars.sdf (revision 25)
+++ src/syn/prism/PRISM-MetaVars.sdf (working copy)
@@ -4,7 +4,8 @@
[ijkln][0-9]* -> LInt {prefer}
[dr][0-9]* -> LDouble {prefer}
[xyzfgh][0-9]* -> ID {prefer}
-%% [xyzfgh][0-9]* "'" -> IdentifierPrime {prefer}
+ %% FIXME: The following doesn't work
+ [xyzfgh][0-9]* "'" -> IdentifierPrime {prefer}
[e][0-9]* -> Expression {prefer}
"a"[0-9]* "*" -> {Identifier ","}+ {prefer}
[m][0-9]* -> Module {prefer}
Index: src/syn/prism/StrategoPRISM.sdf
--- src/syn/prism/StrategoPRISM.sdf (revision 25)
+++ src/syn/prism/StrategoPRISM.sdf (working copy)
@@ -19,7 +19,8 @@
context-free syntax
"~" StrategoTerm -> Expression {prefer,cons("FromTerm")}
- "~id:" StrategoTerm -> Identifier {prefer,cons("FromTerm")}
+ "~id:" StrategoTerm -> ID {prefer,cons("FromTerm")}
+ %% FIXME: The following doesn't work
"~id':" StrategoTerm -> IdentifierPrime {prefer,cons("FromTerm")}
- "~int:" StrategoTerm -> Int {prefer,cons("FromTerm")}
- "~double:" StrategoTerm -> Double {prefer,cons("FromTerm")}
+ "~int:" StrategoTerm -> LInt {prefer,cons("FromTerm")}
+ "~double:" StrategoTerm -> LDouble {prefer,cons("FromTerm")}
Index: tests/xrm/outer-static-if.xpm
--- tests/xrm/outer-static-if.xpm (revision 25)
+++ tests/xrm/outer-static-if.xpm (working copy)
@@ -1,16 +1,13 @@
probabilistic
for i from 0 to 42 do
- // FIXME: the following line shall be:
- //module dummy[i]
- // but this is not supported ATM
if i<1 & i>41 then
- module dummy
+ module dummy[i]
x : [0..1];
[] x=0 -> x'=1;
endmodule
else
- module dummy
+ module dummy[i]
x : [0..2];
[] x=1 -> x'=2;
endmodule
Index: tests/xrm/outer-static-for-step.xpm
--- tests/xrm/outer-static-for-step.xpm (revision 25)
+++ tests/xrm/outer-static-for-step.xpm (working copy)
@@ -1,10 +1,7 @@
probabilistic
for i from 0 to 42 step 2 do
- // FIXME: the following line shall be:
- //module dummy[i]
- // but this is not supported ATM
- module dummy
+ module dummy[i]
x : [0..1];
[] x=0 -> x'=1;
endmodule
Index: tests/xrm/static-if.xpm
--- tests/xrm/static-if.xpm (revision 25)
+++ tests/xrm/static-if.xpm (working copy)
@@ -1,11 +1,8 @@
probabilistic
for i from 0 to 42 do
- // FIXME: the following line shall be:
- //module dummy[i]
- // but this is not supported ATM
if i<1 & i>41 then
- module dummy
+ module dummy[i]
for i from 0 to 42 do
// FIXME: x here shall be replaced with x[i]
// but this is not supported ATM
@@ -18,7 +15,7 @@
end
endmodule
else
- module dummyelse
+ module dummyelse[i]
y : [0..1];
[] y=0 -> y'=1;
endmodule
Index: tests/xrm/static-for-step.xpm
--- tests/xrm/static-for-step.xpm (revision 25)
+++ tests/xrm/static-for-step.xpm (working copy)
@@ -1,10 +1,7 @@
probabilistic
for i from 0 to 42 step 2 do
- // FIXME: the following line shall be:
- //module dummy[i]
- // but this is not supported ATM
- module dummy
+ module dummy[i]
for i from 0 to 42 step 2 do
// FIXME: x here shall be replaced with x[i]
// but this is not supported ATM
Index: tests/xrm/outer-static-for.xpm
--- tests/xrm/outer-static-for.xpm (revision 25)
+++ tests/xrm/outer-static-for.xpm (working copy)
@@ -1,10 +1,7 @@
probabilistic
for i from 0 to 42 do
- // FIXME: the following line shall be:
- //module dummy[i]
- // but this is not supported ATM
- module dummy
+ module dummy[i]
x : [0..1];
[] x=0 -> x'=1;
endmodule
Index: tests/xrm/static-for.xpm
--- tests/xrm/static-for.xpm (revision 25)
+++ tests/xrm/static-for.xpm (working copy)
@@ -1,10 +1,7 @@
probabilistic
for i from 0 to 42 do
- // FIXME: the following line shall be:
- //module dummy[i]
- // but this is not supported ATM
- module dummy
+ module dummy[i]
for i from 0 to 42 do
// FIXME: x here shall be replaced with x[i]
// but this is not supported ATM
Index: tests/test-xrm-front.sh.in
--- tests/test-xrm-front.sh.in (revision 25)
+++ tests/test-xrm-front.sh.in (working copy)
@@ -27,17 +27,9 @@
echo ">>> Starting the test for $basefile"
test_cnt=$((test_cnt + 1))
- echo @ECHO_N@ " Parsing $basefile ... "
- "@top_builddir@/src/tools/parse-xrm" -i "$file" -o "$outdir/$bfile.xpm.aterm"
- if [ $? -ne 0 ]; then
- echo 'FAILED, continuing with the next test...'
- continue
- fi
- echo 'OK, no ambiguities found'
-
echo @ECHO_N@ " Converting $basefile into standard PRISM AST ... "
"@top_builddir@/src/str/xrm-front" \
- -i "$outdir/$bfile.xpm.aterm" -o "$outdir/$bfile.pm.aterm"
+ -i "$file" -o "$outdir/$bfile.pm.aterm"
if [ $? -ne 0 ]; then
echo 'FAILED, continuing with the next test...'
continue
@@ -46,7 +38,7 @@
echo @ECHO_N@ " Converting $basefile into standard PRISM code ... "
"@top_builddir@/src/str/xrm-front" -P \
- -i "$outdir/$bfile.xpm.aterm" -o "$outdir/$bfile.pm"
+ -i "$file" -o "$outdir/$bfile.pm"
if [ $? -ne 0 ]; then
echo 'FAILED, continuing with the next test...'
continue
1
0
https://svn.lrde.epita.fr/svn/xrm/trunk
Index: ChangeLog
from SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr>
Extend real-eq.
* src/str/xrm-to-prism.str: Optimize traversals.
* src/str/reals.str: Extend real-eq.
reals.str | 11 ++++++-----
xrm-to-prism.str | 9 ++-------
2 files changed, 8 insertions(+), 12 deletions(-)
Index: src/str/xrm-to-prism.str
--- src/str/xrm-to-prism.str (revision 24)
+++ src/str/xrm-to-prism.str (working copy)
@@ -4,7 +4,7 @@
strategies
xrm-to-prism =
- topdown(repeat(xrm-to-prism-desugar))
+ topdown(try(xrm-to-prism-desugar))
; id // unroll static for loops here
; topdown(try(reorder-module-contents))
@@ -33,7 +33,7 @@
reorder-module-contents =
?Module(name, _)
; {| DeclarationList, CommandList:
- Module(id, map(try(fetch-module-content)))
+ Module(id, map(add-command <+ add-declaration))
; where(
bagof-DeclarationList
; ?dec-list
@@ -43,11 +43,6 @@
|}
; !Module(name, dec-list, cmd-list)
- // we're inside a Module(_, content)
- // each element is either a Command(_, _, _) or a declaration
- fetch-module-content =
- add-command <+ add-declaration
-
// if the current term is a Command, add it in the CommandList DR
add-command =
?Command(_, _, _)
Index: src/str/reals.str
--- src/str/reals.str (revision 24)
+++ src/str/reals.str (working copy)
@@ -3,7 +3,7 @@
strategies
// for some reason the following rules are only defined for integers
- // in the stratego-lib. Here is their equivalant for reals.
+ // in the stratego-lib. Here is their equivalent 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
@@ -15,13 +15,14 @@
/**
** tests whether two reals are equal
- ** => tests if there difference is less than 10^-7
+ ** => tests if there difference is less than the precision given in parameter
** operates on the input term (a, b)
- ** eg: <real-eq> ("0.42", "0.43") -> fail
+ ** eg: <real-eq(|0.00001)> ("0.42", "0.43") -> fail
*/
- real-eq =
+ real-eq(|precision) =
(string-to-real, string-to-real)
; subtr
; abs => difference
- ; <not(gtr)>(difference, 0.0000001)
+ ; <not(gtr)>(difference, precision)
+ real-eq = real-eq(|0.0000001)
1
0
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)
1
0

16 May '06
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)
1
0