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(a)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.