https://svn.lrde.epita.fr/svn/xrm/trunk
Index: ChangeLog
from SIGOURE Benoit <sigoure.benoit(a)lrde.epita.fr>
Add meta-if at Expression level.
So basically, it is now possible to have a meta-if statement everywhere
we can find an Expression. /!\ NOTE: meta-if statements at Expression
level are restricted to one single expressions in the then-part and
else-part. eg:
if some-condition then
exp1
exp2
end
is *invalid* at Expression level because neither the base language
nor the extended language provide real statements/sequences of
expressions.
Other improvements: PRISM-If statements (cond ? then-part : else-part)
are now evaluated by prism-desugar when possible. It is also possible
to reduce the condition of a meta-if statement down to a simple
Int(_) or Double(_). If that Int(_) or Double(_) is zero, the
condition will evaluate as False() otherwise True() [like in C].
NOTE: for Double(_) all tests are performed with a precision of 10^-7
in other words if 0.000000001 then ... else /*executed*/ end will be
false.
* src/str/prism-desugar.str: Add EvalIf and LitToBool.
* src/str/eval-meta-code.str: Allow if statements to evaluate as
integer/real. In this case the behavior is the same as in C: 0 means
false and all the other values mean true.
* src/str/xrm-front.str: Change a debug message to be a notice.
* src/syn/xrm/XRM-Arrays.sdf: Use XRMRange for array subscripts.
* src/syn/xrm/XRM-MetaIf.sdf: Add meta-if at the Expression level.
Correct EBNF grammar.
* src/syn/xrm/XRM-MetaFor.sdf: Remove trailing whitespaces.
* src/syn/xrm/XRM-Expression.sdf: Add XRMRange. This basically just a
simple range but it has a different priority in the grammar than
the original Range from the base grammar. It is used for array
subscripts. Actually XRMRange might not be a wise name for this
sorts.
* tests/xrm/desugar-if.xpm: New.
* tests/xrm/if-exp.xpm: New.
* tests/xrm/cond-array-access.xpm: New.
* tests/xrm/priorities-exp-array-subscript.xpm: New.
src/str/eval-meta-code.str | 4 +-
src/str/prism-desugar.str | 46 +++++++++++++++++++++++++++
src/str/xrm-front.str | 3 -
src/syn/xrm/XRM-Arrays.sdf | 16 ++++-----
src/syn/xrm/XRM-Expression.sdf | 27 +++++++++++++++
src/syn/xrm/XRM-MetaIf.sdf | 44 ++++++++++++++++++++++---
tests/xrm/cond-array-access.xpm | 4 ++
tests/xrm/desugar-if.xpm | 15 ++++++++
tests/xrm/if-exp.xpm | 7 ++++
tests/xrm/priorities-exp-array-subscript.xpm | 9 +++++
10 files changed, 158 insertions(+), 17 deletions(-)
Index: src/str/prism-desugar.str
--- src/str/prism-desugar.str (revision 52)
+++ src/str/prism-desugar.str (working copy)
@@ -27,6 +27,7 @@
<+ EvalAnd <+ EvalOr
<+ EvalMin <+ EvalMax <+ EvalFloor <+ EvalCeil <+ EvalPow <+
EvalMod
<+ (EvalStaticRand; IntToDouble)
+ <+ EvalIf
)
; topdown(try(SimplifyDoubles <+ TruncateDouble))
@@ -305,6 +306,28 @@
/*
** ## ============= ##
+** ## If statements ##
+** ## ============= ##
+*/
+
+rules
+
+ EvalIf:
+ |[ true ? e1 : e2 ]| -> |[ e1 ]|
+
+ EvalIf:
+ |[ false ? e1 : e2 ]| -> |[ e2 ]|
+
+ EvalIf:
+ |[ d ? e1 : e2 ]| -> |[ e1 ]|
+ where <not(compare(real-eq))>(d, 0)
+
+ EvalIf:
+ |[ d ? e1 : e2 ]| -> |[ e2 ]|
+ where <compare(real-eq)>(d, 0)
+
+/*
+** ## ============= ##
** ## Eval Builtins ##
** ## ============= ##
**
@@ -348,3 +371,26 @@
else
<modS> (i, j) => r
end
+
+/*
+** ## =========== ##
+** ## Misc. stuff ##
+** ## =========== ##
+*/
+
+rules
+
+ LitToBool:
+ |[ 0 ]| -> |[ false ]|
+
+ LitToBool:
+ |[ i ]| -> |[ true ]|
+ where <not(eq)>(i, "0")
+
+ LitToBool:
+ |[ d ]| -> |[ false ]|
+ where <compare(real-eq)>(d, 0)
+
+ LitToBool:
+ |[ d ]| -> |[ true ]|
+ where <not(compare(real-eq))>(d, 0)
Index: src/str/eval-meta-code.str
--- src/str/eval-meta-code.str (revision 52)
+++ src/str/eval-meta-code.str (working copy)
@@ -23,6 +23,7 @@
imports
ice
signatures
+ prism-desugar
strategies
@@ -38,7 +39,8 @@
?MetaIf(condition, then-part, else-part)
///*DEBUG*/; say(!" @@@ eval-meta-if: starting:")
///*DEBUG*/; printf(|" condition = ", condition)
- ; where(<prism-desugar> condition => condition-value)
+ ; where(<prism-desugar> condition
+ ; try(LitToBool) => condition-value)
///*DEBUG*/; printf(|" condition-value = ", condition-value)
; if !condition-value => True() then
<eval-meta-code> then-part
Index: src/str/xrm-front.str
--- src/str/xrm-front.str (revision 52)
+++ src/str/xrm-front.str (working copy)
@@ -42,10 +42,9 @@
notice-msg(|"transformation pipeline starting")
; where(<set-random-seed> (<time>))
; xrm-to-prism
- ; dbg(|"xrm-to-prism finished")
; if must-desugar then
prism-desugar
- ; dbg(|"prism-desugar finished")
+ ; notice-msg(|"prism-desugar finished")
end
/** list of available options for xrm-front */
Index: src/syn/xrm/XRM-Arrays.sdf
--- src/syn/xrm/XRM-Arrays.sdf (revision 52)
+++ src/syn/xrm/XRM-Arrays.sdf (working copy)
@@ -6,21 +6,21 @@
%% EBNF Grammar: Arrays
%% ArrayAccess ::=
- %% Identifier "[" Range {"," Range} "]"
- %% | ArrayAccess "[" Range {"," Range} "]"
+ %% Identifier "[" XRMRange {"," XRMRange} "]"
+ %% | ArrayAccess "[" XRMRange {"," XRMRange} "]"
%%
%% ArrayAccessPrime ::=
- %% Identifier "[" Range {"," Range} "]"
"'"
- %% | ArrayAccess "[" Range {"," Range} "]"
"'"
+ %% Identifier "[" XRMRange {"," XRMRange} "]"
"'"
+ %% | ArrayAccess "[" XRMRange {"," XRMRange} "]"
"'"
sorts ArrayAccess
context-free syntax
- Identifier "[" {Range ","}+ "]" -> ArrayAccess
{cons("ArrayAccess")}
- ArrayAccess "[" {Range ","}+ "]" -> ArrayAccess
{cons("ArrayAccess")}
+ Identifier "[" {XRMRange ","}+ "]" -> ArrayAccess
{cons("ArrayAccess")}
+ ArrayAccess "[" {XRMRange ","}+ "]" -> ArrayAccess
{cons("ArrayAccess")}
sorts ArrayAccessPrime
context-free syntax
- ArrayAccess "[" {Range ","}+ "]" "'"
+ ArrayAccess "[" {XRMRange ","}+ "]" "'"
-> ArrayAccessPrime {cons("ArrayAccessPrime")}
- Identifier "[" {Range ","}+ "]" "'"
+ Identifier "[" {XRMRange ","}+ "]" "'"
-> ArrayAccessPrime {cons("ArrayAccessPrime")}
Index: src/syn/xrm/XRM-MetaIf.sdf
--- src/syn/xrm/XRM-MetaIf.sdf (revision 52)
+++ src/syn/xrm/XRM-MetaIf.sdf (working copy)
@@ -7,23 +7,37 @@
%% EBNF Grammar: Meta if-then-else
%% (* if-then-else at top-level *)
%% ModulesFileSection ::=
- %% "if" Expression "then" ModulesFileSection
{ModulesFileSection} "end"
+ %% "if" Expression "then" {ModulesFileSection} "end"
%% | "if" Expression "then"
- %% ModulesFileSection {ModulesFileSection}
+ %% {ModulesFileSection}
%% "else"
- %% ModulesFileSection {ModulesFileSection}
+ %% {ModulesFileSection}
%% "end"
%%
%% (* if-then-else inside modules *)
%% DeclarationOrCommand ::=
- %% "if" Expression "then" DeclarationOrCommand
{DeclarationOrCommand} "end"
+ %% "if" Expression "then" {DeclarationOrCommand}
"end"
%% | "if" Expression "then"
- %% DeclarationOrCommand {DeclarationOrCommand}
+ %% {DeclarationOrCommand}
%% "else"
- %% DeclarationOrCommand {DeclarationOrCommand}
+ %% {DeclarationOrCommand}
+ %% "end"
+ %%
+ %% (* if-then-else inside expressions *)
+ %% (* NOTE: it's not possible to have more than 1 exp in the then-part
+ %% * and else-part of the meta-if statements for expression. This is
+ %% * because the current base and extended language don't have real
+ %% * statements nor sequences of expressions. *)
+ %% Expression ::=
+ %% "if" Expression "then" Expression "end"
+ %% | "if" Expression "then"
+ %% Expression
+ %% "else"
+ %% Expression
%% "end"
context-free syntax
+
%% if-then at top-level
"if" Expression "then" ModulesFileSection* "end"
-> ModulesFileSection {cons("MetaIf")}
@@ -36,6 +50,7 @@
"end" -> ModulesFileSection {cons("MetaIf")}
context-free syntax
+
%% if-then within modules
"if" Expression "then" DeclarationOrCommand* "end"
-> DeclarationOrCommand {cons("MetaIf")}
@@ -46,3 +61,20 @@
"else"
DeclarationOrCommand*
"end" -> DeclarationOrCommand {cons("MetaIf")}
+
+ %% NOTE: it's not possible to have more than 1 exp in the then-part
+ %% and else-part of the meta-if statements for expression. This is
+ %% because the current base and extended language don't have real
+ %% statements nor sequences of expressions.
+ context-free syntax
+
+ %% if-then within expressions
+ "if" Expression "then" Expression "end"
+ -> Expression {cons("MetaIf")}
+
+ %% if-then-else within expressions
+ "if" Expression "then"
+ Expression
+ "else"
+ Expression
+ "end" -> Expression {cons("MetaIf")}
Index: src/syn/xrm/XRM-MetaFor.sdf
Index: src/syn/xrm/XRM-Expression.sdf
--- src/syn/xrm/XRM-Expression.sdf (revision 52)
+++ src/syn/xrm/XRM-Expression.sdf (working copy)
@@ -18,6 +18,9 @@
%% (* builtin functions calls using the "func" notation *)
%% | "func" "(" "rand" ","
Expression {"," Expression} ")"
%% | "func" "(" "static_rand" ","
Expression {"," Expression} ")"
+ %%
+ %% (* Ranges in XRM with different priority (for array accesses) *)
+ %% XRMRange ::= Expression | Expression ".." Expression
context-free syntax
ArrayAccess -> Expression
@@ -39,6 +42,12 @@
"func" "(" "static_rand" "," {Expression
","}+ ")"
-> Expression {cons("StaticRand")}
+ %% Ranges in XRM with different priority (for array accesses)
+ sorts XRMRange
+ context-free syntax
+ Expression -> XRMRange
+ Expression ".." Expression -> XRMRange {cons("Range")}
+
%% NOTE: remember: priorities are transitive in SDF.
%% The following priorities are marked either with "inherited" or
"new".
%% The former means that these priorities are inherited from the base
@@ -71,3 +80,21 @@
{ %% inherited
Expression -> Range
}
+ > { %% inherited
+ "!" Expression -> Expression
+ }
+ > {left: %% inherited
+ Expression "&" Expression -> Expression
+ }
+ > {left: %% inherited
+ Expression "|" Expression -> Expression
+ }
+ > { %% inherited
+ Expression "?" Expression ":" Expression -> Expression
+ }
+ > {non-assoc: %% new
+ Expression ".." Expression -> XRMRange
+ }
+ > { %% new
+ Expression -> XRMRange
+ }
Index: tests/xrm/desugar-if.xpm
--- tests/xrm/desugar-if.xpm (revision 0)
+++ tests/xrm/desugar-if.xpm (revision 0)
@@ -0,0 +1,15 @@
+if 0=1?0:2 then
+ const int success1 = 1;
+ if 0=1?0:2 then
+ const int success2 = 1;
+ if false?0:0 then
+ const int fail1 = 1;
+ else
+ const int success3 = 1;
+ end
+ else
+ const int fail2 = 1;
+ end
+else
+ const int fail3 = 1;
+end
Index: tests/xrm/if-exp.xpm
--- tests/xrm/if-exp.xpm (revision 0)
+++ tests/xrm/if-exp.xpm (revision 0)
@@ -0,0 +1,7 @@
+const int N = 3;
+const int success = 1;
+
+module test
+ x : [if true then 0 end..if false then 0 else 42 end];
+ [] x=0 -> x'=if 42 then success else -1 end;
+endmodule
Index: tests/xrm/cond-array-access.xpm
--- tests/xrm/cond-array-access.xpm (revision 0)
+++ tests/xrm/cond-array-access.xpm (revision 0)
@@ -0,0 +1,4 @@
+module test
+ x[4] : [0..42] init 0;
+ [] x[-1<0?0:-1]=0 -> true;
+endmodule
Index: tests/xrm/priorities-exp-array-subscript.xpm
--- tests/xrm/priorities-exp-array-subscript.xpm (revision 0)
+++ tests/xrm/priorities-exp-array-subscript.xpm (revision 0)
@@ -0,0 +1,9 @@
+module test
+ x[3] : bool init false;
+ y : bool init true;
+ x[4] : [0..42] init 0;
+
+ //[] true -> x[1|1]'=true;
+ [] x[true?2:3]=0 -> true;
+ [] true -> x[0..1&1]'=true;
+endmodule