Skip to content

Commit 7a91ec4

Browse files
Merge pull request #28 from elevate-lang/count-rules
2 parents b17ab09 + 97a8592 commit 7a91ec4

File tree

3 files changed

+61
-40
lines changed

3 files changed

+61
-40
lines changed

macros/src/main/scala/elevate/macros/RuleMacro.scala

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -18,38 +18,46 @@ object RuleMacro {
1818
class Impl(val c: blackbox.Context) {
1919
import c.universe._
2020

21-
def rule(annottees: c.Expr[Any]*): c.Expr[Any] = {
21+
def strategy(annottees: c.Expr[Any]*): c.Expr[Any] =
22+
generic({ r: Tree => r }, annottees)
23+
24+
def rule(annottees: c.Expr[Any]*): c.Expr[Any] =
25+
generic({ r: Tree => q"elevate.core.countApplications { $r }" }, annottees)
26+
27+
def generic(wrapResult: Tree => Tree, annottees: Seq[c.Expr[Any]]): c.Expr[Any] = {
2228
annottees.map(_.tree) match {
2329
case (cdef: DefDef) :: Nil =>
24-
c.Expr(fromDefDef(cdef))
30+
c.Expr(fromDefDef(wrapResult)(cdef))
2531
case (cdef: DefDef) :: (md: ModuleDef) :: Nil =>
26-
c.Expr(q"{${fromDefDef(cdef)}; $md}")
32+
c.Expr(q"{${fromDefDef(wrapResult)(cdef)}; $md}")
2733
case _ => c.abort(c.enclosingPosition, "expected a method definition")
2834
}
2935
}
3036

31-
def fromDefDef: DefDef => Tree = {
37+
def fromDefDef(wrapResult: Tree => Tree): DefDef => Tree = {
3238
case q"def ${name: TermName}[..$tparams]: Strategy[..$resTypes] = { case ..$cases }"
3339
if resTypes.length == 1 =>
3440

3541
val resType = resTypes.head.asInstanceOf[Tree]
3642
if (tparams.isEmpty) {
43+
val r = q"""e_internal match {
44+
case ..${addDefaultCase(cases.asInstanceOf[List[CaseDef]], q"elevate.core.Failure($name)")}
45+
}"""
3746
makeRuleObject(name, resType,
3847
q"""
39-
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = e_internal match {
40-
case ..${addDefaultCase(cases.asInstanceOf[List[CaseDef]], q"elevate.core.Failure($name)")}
41-
}"""
48+
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = ${wrapResult(r)}"""
4249
)
4350
} else {
44-
makeRuleClass(name, tparams.asInstanceOf[List[TypeDef]], resType, List(List()))(makeClass =>
45-
q"""
46-
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = e_internal match {
51+
makeRuleClass(name, tparams.asInstanceOf[List[TypeDef]], resType, List(List())) { makeClass =>
52+
val r = q"""e_internal match {
4753
case ..${addDefaultCase(cases.asInstanceOf[List[CaseDef]], q"elevate.core.Failure($makeClass)")}
48-
}
54+
}"""
55+
q"""
56+
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = ${wrapResult(r)}
4957

5058
..${makeToString(name)}
5159
"""
52-
)
60+
}
5361
}
5462

5563
case q"def ${name: TermName}[..$tparams]: Strategy[..$resTypes] = (..$es) => $body"
@@ -58,22 +66,24 @@ object RuleMacro {
5866
val resType = resTypes.head.asInstanceOf[Tree]
5967
val e = es.head.asInstanceOf[ValDef]
6068
if (tparams.isEmpty) {
69+
val r = q"""((${e.name} : $resType) => {
70+
val res_internal: elevate.core.RewriteResult[$resType] = $body
71+
res_internal
72+
}).apply(e_internal)"""
6173
makeRuleObject(name, resType,
6274
q"""
63-
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = {
64-
((${e.name} : $resType) => {
65-
val res_internal: elevate.core.RewriteResult[$resType] = $body
66-
res_internal
67-
}).apply(e_internal)
68-
}""")
75+
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = ${wrapResult(r)}
76+
""")
6977
} else {
78+
val r = q"""{
79+
((${e.name} : $resType) => {
80+
val res_internal: elevate.core.RewriteResult[$resType] = $body
81+
res_internal
82+
}).apply(e_internal)
83+
}"""
7084
makeRuleClass(name, tparams.asInstanceOf[List[TypeDef]], resType, List(List()))(_ =>
7185
q"""
72-
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] =
73-
((${e.name} : $resType) => {
74-
val res_internal: elevate.core.RewriteResult[$resType] = $body
75-
res_internal
76-
}).apply(e_internal)
86+
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = ${wrapResult(r)}
7787

7888
..${makeToString(name)}
7989
"""
@@ -84,17 +94,16 @@ object RuleMacro {
8494
if resTypes.length == 1 =>
8595

8696
val resType = resTypes.head.asInstanceOf[Tree]
97+
val r = q"""($body).apply(e_internal)"""
8798
if (tparams.isEmpty) {
8899
makeRuleObject(name, resType,
89100
q"""
90-
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = {
91-
($body).apply(e_internal)
92-
}""")
101+
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = ${wrapResult(r)}
102+
""")
93103
} else {
94104
makeRuleClass(name, tparams.asInstanceOf[List[TypeDef]], resType, List(List()))(_ =>
95105
q"""
96-
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] =
97-
($body).apply(e_internal)
106+
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = ${wrapResult(r)}
98107

99108
..${makeToString(name)}
100109
"""
@@ -108,29 +117,31 @@ object RuleMacro {
108117

109118
val params = paramLists.asInstanceOf[List[List[ValDef]]]
110119
val resType = resTypes.head.asInstanceOf[Tree]
111-
makeRuleClass(name, tparams.asInstanceOf[List[TypeDef]], resType, params)(makeClass =>
112-
q"""
113-
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = e_internal match {
120+
makeRuleClass(name, tparams.asInstanceOf[List[TypeDef]], resType, params) { makeClass =>
121+
val r = q"""e_internal match {
114122
case ..${addDefaultCase(cases.asInstanceOf[List[CaseDef]], q"elevate.core.Failure($makeClass)")}
115-
}
123+
}"""
124+
q"""
125+
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = ${wrapResult(r)}
116126

117127
..${makeToString(name, params)}
118128
"""
119-
)
129+
}
120130

121131
case q"def ${name: TermName}[..$tparams](...$paramLists): Strategy[..$resTypes] = (..$es) => $body"
122132
if /*paramLists.length == 1 &&*/ resTypes.length == 1 && es.length == 1 =>
123133

124134
val params = paramLists.asInstanceOf[List[List[ValDef]]]
125135
val resType = resTypes.head.asInstanceOf[Tree]
126136
val e = es.head.asInstanceOf[ValDef]
127-
makeRuleClass(name, tparams.asInstanceOf[List[TypeDef]], resType, params)(_ =>
128-
q"""
129-
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] =
137+
val r = q"""
130138
((${e.name} : $resType) => {
131139
val res_internal: elevate.core.RewriteResult[$resType] = $body
132140
res_internal
133-
}).apply(e_internal)
141+
}).apply(e_internal)"""
142+
makeRuleClass(name, tparams.asInstanceOf[List[TypeDef]], resType, params)(_ =>
143+
q"""
144+
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = ${wrapResult(r)}
134145

135146
..${makeToString(name, params)}
136147
"""
@@ -142,10 +153,10 @@ object RuleMacro {
142153

143154
val params = paramLists.asInstanceOf[List[List[ValDef]]]
144155
val resType = resTypes.head.asInstanceOf[Tree]
156+
val r = q"""($body).apply(e_internal)"""
145157
makeRuleClass(name, tparams.asInstanceOf[List[TypeDef]], resType, params)(_ =>
146158
q"""
147-
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] =
148-
($body).apply(e_internal)
159+
override def apply(e_internal: $resType): elevate.core.RewriteResult[$resType] = ${wrapResult(r)}
149160

150161
..${makeToString(name, params)}
151162
"""

macros/src/main/scala/elevate/macros/StrategyMacro.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ object StrategyMacro {
1010
// noinspection ScalaUnusedSymbol
1111
@compileTimeOnly("strategy macro")
1212
class strategy(doc: String = "") extends StaticAnnotation {
13-
def macroTransform(annottees: Any*): Any = macro Impl.rule
13+
def macroTransform(annottees: Any*): Any = macro Impl.strategy
1414
}
1515
}

src/main/scala/elevate/core/package.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ import elevate.core.strategies.basic._
55
import scala.language.implicitConversions
66

77
package object core {
8+
var applyCount = 0L
9+
def countApplications[P](s: Strategy[P]): Strategy[P] = {
10+
p => countApplications(s(p))
11+
}
12+
def countApplications[P](r: RewriteResult[P]): RewriteResult[P] = {
13+
if (r.isInstanceOf[Success[P]]) {
14+
applyCount += 1
15+
}
16+
r
17+
}
818

919
type Strategy[P] = P => RewriteResult[P]
1020

0 commit comments

Comments
 (0)