Skip to content

Commit 78ec221

Browse files
committed
WIP Add fix
1 parent 46c05d7 commit 78ec221

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

tests/run-macros/quote-matcher-symantics-3/quoted_1.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ object Macros {
4646
'{ $sym.lam((x: R[Int]) => ${delegate for Env = envWith(x0, 'x) given env; lift(body)}).asInstanceOf[R[T]] }
4747
case '{ ($x0: Boolean) => $body: Any } =>
4848
'{ $sym.lam((x: R[Boolean]) => ${delegate for Env = envWith(x0, 'x) given env; lift(body)}).asInstanceOf[R[T]] }
49+
case '{ ($x0: Int => Int) => $body: Any } =>
50+
'{ $sym.lam((x: R[Int => Int]) => ${delegate for Env = envWith(x0, 'x) given env; lift(body)}).asInstanceOf[R[T]] }
51+
52+
case '{ Symantics.fix[$t, $u]($f) } =>
53+
'{ $sym.fix[$t, $u]((x: R[$t => $u]) => $sym.app(${lift(f)}, x)).asInstanceOf[R[T]] }
4954

5055
case Bind(FromEnv(expr)) => expr.asInstanceOf[Expr[R[T]]]
5156

@@ -67,13 +72,14 @@ trait Symantics {
6772
def bool(x: Boolean): Repr[Boolean]
6873
def lam[A, B](f: Repr[A] => Repr[B]): Repr[A => B]
6974
def app[A, B](f: Repr[A => B], arg: Repr[A]): Repr[B]
70-
def fix[A](f: Repr[A] => Repr[A]): Repr[A]
75+
// def fix[A]: (Repr[A] => Repr[A]) => Repr[A]
76+
def fix[A, B]: (Repr[A => B] => Repr[A => B]) => Repr[A => B]
7177
def add(x: Repr[Int], y: Repr[Int]): Repr[Int]
7278
def mult(x: Repr[Int], y: Repr[Int]): Repr[Int]
7379
def leq(x: Repr[Int], y: Repr[Int]): Repr[Boolean]
74-
def ifThenElse[A](cond: Repr[Boolean], thenp: Repr[A], elsep: Repr[A]): Repr[A]
80+
def ifThenElse[A](cond: Repr[Boolean], thenp: => Repr[A], elsep: => Repr[A]): Repr[A]
7581
}
7682

7783
object Symantics {
78-
def fix[A](f: A => A): A = throw new Exception("Must be used inside of `lift`")
84+
def fix[A, B](f: (A => B) => (A => B)): A => B = throw new Exception("Must be used inside of `lift`")
7985
}

tests/run-macros/quote-matcher-symantics-3/quoted_2.scala

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ object Test {
3434
// println(lift(new Show)(((f: Int => Int) => f(4))((x: Int) => x)))
3535
// println(lift(new Eval)(((f: Int => Int) => f(4))((x: Int) => x)))
3636

37+
println(lift(new Show)(((x: Int) => Symantics.fix((self: Int => Int) => ((n: Int) => if (n <= 0) 1 else x * self(n + (-1)) )))(3)(25)))
38+
println(lift(new Eval)(((x: Int) => Symantics.fix((self: Int => Int) => ((n: Int) => if (n <= 0) 1 else x * self(n + (-1)) )))(3)(5)))
39+
40+
3741

3842
}
3943

@@ -49,11 +53,11 @@ class Show extends Symantics {
4953
s"(arg$i => ${f(s"arg$i")})"
5054
}
5155
def app[A, B](f: Repr[A => B], arg: Repr[A]): Repr[B] = s"$f($arg)"
52-
def fix[A](f: Repr[A] => Repr[A]): Repr[A] = ???
56+
def fix[A, B]: (Repr[A => B] => Repr[A => B]) => Repr[A => B] = f => f("FIX")
5357
def add(x: Repr[Int], y: Repr[Int]): Repr[Int] = s"$x + $y"
5458
def mult(x: Repr[Int], y: Repr[Int]): Repr[Int] = s"($x) * ($y)"
5559
def leq(x: Repr[Int], y: Repr[Int]): Repr[Boolean] = s"$x <= $y"
56-
def ifThenElse[A](cond: Repr[Boolean], thenp: Repr[A], elsep: Repr[A]): Repr[A] = s"if ($cond) $thenp else $elsep"
60+
def ifThenElse[A](cond: Repr[Boolean], thenp: => Repr[A], elsep: => Repr[A]): Repr[A] = s"if ($cond) $thenp else $elsep"
5761

5862
private[this] var idx: Int = 0
5963
private def nextIndex(): Int = {
@@ -68,9 +72,13 @@ class Eval extends Symantics {
6872
def bool(x: Boolean): Repr[Boolean] = x
6973
def lam[A, B](f: Repr[A] => Repr[B]): Repr[A => B] = f
7074
def app[A, B](f: Repr[A => B], arg: Repr[A]): Repr[B] = f(arg)
71-
def fix[A](f: Repr[A] => Repr[A]): Repr[A] = ???
75+
def fix[A, B]: (Repr[A => B] => Repr[A => B]) => Repr[A => B] = f => {
76+
def self(n: A): B = f(self)(n)
77+
self
78+
}
7279
def add(x: Repr[Int], y: Repr[Int]): Repr[Int] = x + y
7380
def mult(x: Repr[Int], y: Repr[Int]): Repr[Int] = x * y
7481
def leq(x: Repr[Int], y: Repr[Int]): Repr[Boolean] = x <= y
75-
def ifThenElse[A](cond: Repr[Boolean], thenp: Repr[A], elsep: Repr[A]): Repr[A] = if (cond) thenp else thenp
82+
def ifThenElse[A](cond: Repr[Boolean], thenp: => Repr[A], elsep: => Repr[A]): Repr[A] = if (cond) thenp else thenp
83+
7684
}

0 commit comments

Comments
 (0)