XRM r99: Handle recursive parametrized formulas separately.

Repository: https://svn.lrde.epita.fr/svn/xrm This didn't fix the bug of infinite recursion on rivf.xrm :( But IMHO it was wrong to handle recursive formulas exactly like non-recursive formulas because we can't inline recursive formulas without evaluating the code as it is inlined... It is still unclear why xrm-front still goes into an infinite recursive on rivf.xrm though... :( ChangeLog: 2006-12-15 SIGOURE Benoit <sigoure.benoit@lrde.epita.fr> Handle recursive parametrized formulas separately. * src/str/check-meta-vars.str: Adjust. * src/str/collect-static-const-decl.str: Collect parametrized formulas separately in different rules. * src/str/eval-meta-code.str: More debugging messages. * src/str/inline.str: Desugar parameters passed to parametrized formulas. * src/str/prism-desugar.str: Call eval-meta-code after inlining a static const definition or a call to a formula. Don't inline recursive parametrized formulas here, it would cause infinite recursion. * src/str/xrm-to-prism.str: Adjust. check-meta-vars.str | 1 + collect-static-const-decl.str | 33 +++++++++++++++++++++++---------- eval-meta-code.str | 23 ++++++++++++++++------- inline.str | 4 ++-- prism-desugar.str | 13 ++++++++++--- xrm-to-prism.str | 2 ++ 6 files changed, 54 insertions(+), 22 deletions(-) Index: src/str/check-meta-vars.str =================================================================== --- src/str/check-meta-vars.str (revision 96) +++ src/str/check-meta-vars.str (working copy) @@ -103,6 +103,7 @@ + ( ( <ExpandFormulas> Identifier(idf) + <ExpandPFormulas> Identifier(idf) + + <ExpandRecPFormulas> Identifier(idf) ) /* if we successfully expanded a formula we need to check * it's made only of meta-vars. */ Index: src/str/xrm-to-prism.str =================================================================== --- src/str/xrm-to-prism.str (revision 96) +++ src/str/xrm-to-prism.str (working copy) @@ -38,6 +38,8 @@ ** expression. ** - ExpandPFormulas: Same as ExpandFormulas but for parameterized ** formulas. +** - ExpandRecPFormulas: Same as ExpandPFormulas but for recursive +** parameterized formulas. ** - RandGenModules: each call to the XRM builtin rand generates a module ** which is stored in this DR. Just before xrm-to-prism finishes, we ** paste these modules at the end of the source code. Index: src/str/inline.str =================================================================== --- src/str/inline.str (revision 96) +++ src/str/inline.str (working copy) @@ -55,7 +55,7 @@ //<topdown(\ x -> y \)> b // => SIGSEGV! // FIXME: Type checking: does y (effective arg) have a compatible // type with x (formal arg)? - ; <topdown(try(?x'; !y))> b + ; <prism-desugar> y => y' + ; <topdown(try(?x'; !y'))> b ; <replace-formal-args>(fname, xs, ys, <id>) => b' - Index: src/str/prism-desugar.str =================================================================== --- src/str/prism-desugar.str (revision 96) +++ src/str/prism-desugar.str (working copy) @@ -64,9 +64,16 @@ */ prism-desugar-first-pass = ?Int(_); IntToDouble - <+ ExpandStaticConsts; prism-desugar-first-pass // We must desugar the - <+ ExpandFormulas; prism-desugar-first-pass // expansed code. - <+ ExpandPFormulas; prism-desugar-first-pass // Ditto. + + /* For the 3 following cases we must desugar the expansed code again. We + * have to run eval-meta-code first in order to evaluate the meta-code as + * we're expansing it (otherwise we might not catch the end of a recursive + * call to a formula for instance...) */ + <+ ExpandStaticConsts; eval-meta-code; prism-desugar-first-pass + <+ ExpandFormulas; eval-meta-code; prism-desugar-first-pass + <+ expand-non-recursive-pformulas; prism-desugar-first-pass + // Note: expand-non-recursive-pformulas calls eval-meta-code. + <+ ConstInt(id, prism-desugar) <+ ConstDouble(id, prism-desugar) <+ ConstBool(id, prism-desugar) Index: src/str/eval-meta-code.str =================================================================== --- src/str/eval-meta-code.str (revision 96) +++ src/str/eval-meta-code.str (working copy) @@ -35,7 +35,7 @@ ** 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 +** sed 's@///@/@g' < eval-meta-code.str > .tmp ** mv .tmp eval-meta-code.str */ module eval-meta-code @@ -47,12 +47,12 @@ strategies eval-meta-code = - eval-meta-if - <+ lazy-eval-and - <+ lazy-eval-or - <+ unroll-meta-for - <+ unroll-meta-forin - <+ (expand-pformulas; eval-meta-code) // try again on expansed code. + (eval-meta-if; id/*say(!" @@@ eval-meta-code: eval-meta-if done")*/) + <+ (lazy-eval-and; id/*say(!" @@@ eval-meta-code: lazy-eval-and done")*/) + <+ (lazy-eval-or; id/*say(!" @@@ eval-meta-code: lazy-eval-or done")*/) + <+ (unroll-meta-for; id/*say(!" @@@ eval-meta-code: unroll-meta-for done")*/) + <+ (unroll-meta-forin; id/*say(!" @@@ eval-meta-code: unroll-meta-forin done")*/) + <+ (expand-pformulas; id/*say(!" @@@ eval-meta-code: expand-pformulas done")*/) // try again on expansed code. <+ all(eval-meta-code) strategies @@ -81,8 +81,11 @@ /** Try also on normal if statements... */ eval-meta-if = ?If(condition, then-part, else-part) + ///*DEBUG*/; say(!" @@@ eval-meta-if[If]: starting:") + ///*DEBUG*/; printf(|" condition = ", condition) ; where(<prism-desugar> condition ; try(LitToBool) => condition-value) + ///*DEBUG*/; printf(|" condition-value = ", condition-value) ; if !condition-value => True() then <eval-meta-code> then-part else @@ -95,21 +98,27 @@ lazy-eval-and = ?|[ e1 & e2 ]| + ///*DEBUG*/; say(!" @@@ lazy-eval-and: starting:") ; <prism-desugar> e1 ; try(LitToBool) => e1' ; if !e1' => False() then !False() + ///*DEBUG*/; say(!" @@@ lazy-eval-and: false") else + ///*DEBUG*/ say(!" @@@ lazy-eval-and: don't know"); fail end lazy-eval-or = ?|[ e1 | e2 ]| + ///*DEBUG*/; say(!" @@@ lazy-eval-or: starting:") ; <prism-desugar> e1 ; try(LitToBool) => e1' ; if !e1' => True() then !True() + ///*DEBUG*/; say(!" @@@ lazy-eval-or: true") else + ///*DEBUG*/ say(!" @@@ lazy-eval-or: don't know"); fail end Index: src/str/collect-static-const-decl.str =================================================================== --- src/str/collect-static-const-decl.str (revision 96) +++ src/str/collect-static-const-decl.str (working copy) @@ -32,11 +32,9 @@ register-static-const(|idf, value, type) = check-identifier-unicity(|idf) - /* NOTE: We omitted ExpandPFormulas in the following attempt to simplify - * the value before storing it in the DR because it will expand the value - * forever if it contains call to recursive parameterized formula. - */ - ; where(<innermost(ExpandStaticConsts + ExpandFormulas)> value => v' + ; where(<innermost(ExpandStaticConsts + + ExpandFormulas + + ExpandPFormulas)> value => v' ; !v'{Type(type)} => v) ; rules(ExpandStaticConsts: idf -> v) @@ -70,20 +68,35 @@ ?PFormulaDef(name@Identifier(fname), args, body) ; check-identifier-unicity(|name) ; <innermost(ExpandStaticConsts + ExpandFormulas)> body => body' - // FIXME: Catch recursive call (error) - ; rules(ExpandPFormulas: + ; if oncetd(?PFormulaCall(name, _)) then + ///*DEBUG*/ printf(|"collect-pformulas: Recursive P-formula: ", fname); + rules(ExpandRecPFormulas: PFormulaCall(name, a*) -> e where <inline-call(|fname, args, a*)> body' => e ) + else + ///*DEBUG*/ printf(|"collect-pformulas: NON Recursive P-formula: ", fname); + rules(ExpandPFormulas: + PFormulaCall(name, a*) -> e + where <inline-call(|fname, args, a*)> body' => e + ) + end ; ![] // we remove the parameterized formula definition strategies + /* Only try to expand non recursive parameterized formulas (eg: for + * partial evaluation) */ + expand-non-recursive-pformulas = + ?PFormulaCall(Identifier(fname), _) + ; ExpandPFormulas + ; eval-meta-code + /** Ensure that a call to a parameterized formula is expanded. Use this ** to catch calls to undefined formulas. */ expand-pformulas = ?PFormulaCall(Identifier(fname), _) - ; (ExpandPFormulas <+ call-to-undefined-pformula(|fname)) + ; ((ExpandPFormulas + ExpandRecPFormulas; /*printf(|"*** After Expand(Rec)?PFormulas ", fname); debug;*/ eval-meta-code) <+ call-to-undefined-pformula(|fname)) call-to-undefined-pformula(|fname) = err-msg(|["invalid call to the undefined parameterized formula `" @@ -102,7 +115,7 @@ ; if <ExpandFormulas> x then cannot-redefine-formula(|x) end - ; if <ExpandPFormulas> x then + ; if <ExpandPFormulas + ExpandRecPFormulas> x then cannot-redefine-parameterized-formula(|x) end ; rules(ExpandFormulas: x -> e) @@ -135,5 +148,5 @@ !idf => Identifier(idf') ; err-msg(|["Cannot redefine `", idf', "': already defined", " as a parameterized formula."]) - ; <debug> (<ExpandPFormulas> idf) + ; <debug> (<ExpandPFormulas + ExpandRecPFormulas> idf) ; <xtc-exit> 2 -- SIGOURE Benoit aka Tsuna (SUSv3 compliant) _____ "On a long enough timeline, the survival rate /EPITA\ Promo 2008.CSI/ACU for everyone drops to zero" -- Jack.
participants (1)
-
SIGOURE Benoit