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