mirror of
https://github.com/unisonweb/unison.git
synced 2024-11-14 16:28:34 +03:00
thread env through with StackDecode TC
This commit is contained in:
parent
ddac74edb8
commit
e05752740c
@ -11,47 +11,51 @@ import org.unisonweb.util.{Sequence, Stream, Text}
|
||||
|
||||
/* Sketch of convenience functions for constructing builtin functions. */
|
||||
object Builtins {
|
||||
def env =
|
||||
type Env = (Array[U], Array[B], StackPtr, Result)
|
||||
def _env: Env =
|
||||
(new Array[U](1024), new Array[B](1024), StackPtr.empty, Result())
|
||||
|
||||
type StreamRepr = Env => Stream[Value]
|
||||
// Stream.empty : Stream a
|
||||
val Stream_empty =
|
||||
c0z("Stream.empty", Stream.empty[Value])
|
||||
|
||||
c0z("Stream.empty", (_: Env) => Stream.empty[Value])
|
||||
|
||||
// Stream.fromInt64 : Int64 -> Stream Int64
|
||||
val Stream_fromInt64 =
|
||||
fp_z("Stream.from-int64", "n", Stream.fromInt64)
|
||||
fp_z("Stream.from-int64", "n", (u: U) => (_: Env) => Stream.fromInt64(u))
|
||||
|
||||
// Stream.fromUInt64 : UInt64 -> Stream UInt64
|
||||
val Stream_fromUInt64 =
|
||||
fp_z("Stream.from-uint64", "n", Stream.fromUInt64)
|
||||
fp_z("Stream.from-uint64", "n", (u: U) => (_: Env) => Stream.fromUInt64(u))
|
||||
|
||||
// Stream.cons : a -> Stream a -> Stream a
|
||||
val Stream_cons =
|
||||
fpp_z("Stream.cons", "v", "stream",
|
||||
(v: Value, stream: Stream[Value]) => v :: stream)
|
||||
(v: Value, stream: StreamRepr) => (env: Env) => v :: stream(env))
|
||||
|
||||
val Stream_take =
|
||||
flp_z("Stream.take", "n", "stream",
|
||||
(n, s: Stream[Value]) => s.take(n))
|
||||
(n, s: StreamRepr) => (env: Env) => s(env).take(n))
|
||||
|
||||
val Stream_drop =
|
||||
flp_z("Stream.drop", "n", "stream",
|
||||
(n, s: Stream[Value]) => s.drop(n))
|
||||
(n, s: StreamRepr) => (env: Env) => s(env).drop(n))
|
||||
|
||||
// Stream.map : (a -> b) -> Stream a -> Stream b
|
||||
val Stream_map =
|
||||
fpp_z("Stream.map", "f", "stream",
|
||||
(f: Value, s: Stream[Value]) =>
|
||||
s.map(UnisonToScala.toUnboxed1(f.asInstanceOf[Lambda])(env)))
|
||||
(f: Value, s: StreamRepr) =>
|
||||
(env: Env) =>
|
||||
s(env).map(UnisonToScala.toUnboxed1(f.asInstanceOf[Lambda])(env)))
|
||||
|
||||
// Stream.foldLeft : b -> (b -> a -> b) -> Stream a -> b
|
||||
val Stream_foldLeft =
|
||||
fppp_p("Stream.fold-left", "acc", "f", "stream",
|
||||
(acc: Value, f: Value, s: Stream[Value]) =>
|
||||
fpps_p("Stream.fold-left", "acc", "f", "stream",
|
||||
(acc: Value, f: Value, s: Stream[Value]) => {
|
||||
val env = _env
|
||||
s.foldLeft(acc)(
|
||||
UnisonToScala.toUnboxed2(f.asInstanceOf[Lambda])(env))
|
||||
}
|
||||
)
|
||||
|
||||
abstract class FPPP_P[A,B,C,D] { def apply(a: A, b: B, c: C): D }
|
||||
@ -78,6 +82,30 @@ object Builtins {
|
||||
name -> Return(lambda)
|
||||
}
|
||||
|
||||
abstract class FPPS_P[A,B,C,D] { def apply(a: A, b: B, c: C): D }
|
||||
def fpps_p[A,B,C,D](name: Name, arg1: Name, arg2: Name, arg3: Name,
|
||||
f: FPPS_P[A,B,C,D])
|
||||
(implicit
|
||||
A: Decode[A],
|
||||
B: Decode[B],
|
||||
C: StackDecode[C],
|
||||
D: Encode[D]): (Name, Computation) = {
|
||||
val body: Computation =
|
||||
(r,rec,top,stackU,x1,x0,stackB,x1b,x0b) => {
|
||||
val x2 = top.u(stackU, 2)
|
||||
val x2b = top.b(stackB, 2)
|
||||
D.encode(r, f(
|
||||
A.decode(x2, x2b),
|
||||
B.decode(x1, x1b),
|
||||
C.stackDecode(x0, x0b)((stackU, stackB, top, r))
|
||||
))
|
||||
}
|
||||
val decompiled = Term.Id(name)
|
||||
val lambda =
|
||||
new Value.Lambda.ClosureForming(List(arg1, arg2, arg3), body, decompiled)
|
||||
name -> Return(lambda)
|
||||
}
|
||||
|
||||
val streamBuiltins = Map(
|
||||
Stream_empty,
|
||||
Stream_fromInt64,
|
||||
@ -650,6 +678,16 @@ object Builtins {
|
||||
b.toValue.asInstanceOf[External].get.asInstanceOf[A]
|
||||
}
|
||||
|
||||
trait StackDecode[+T] {
|
||||
def stackDecode(u: U, b: B): Env => T
|
||||
}
|
||||
object StackDecode {
|
||||
implicit def stackDecodeStream: StackDecode[Stream[Value]] =
|
||||
(_, b) =>
|
||||
b.asInstanceOf[External]
|
||||
.get.asInstanceOf[StreamRepr]
|
||||
}
|
||||
|
||||
/** Encode a scala type `A` in `Result => U` form. */
|
||||
trait Encode[-A] { def encode(r: Result, a: A): U }
|
||||
object Encode {
|
||||
|
@ -1,13 +1,22 @@
|
||||
package org.unisonweb.util
|
||||
|
||||
import org.unisonweb.Builtins.env
|
||||
import org.unisonweb.EasyTest._
|
||||
import org.unisonweb.Term.Term
|
||||
import org.unisonweb._
|
||||
import org.unisonweb.util.Unboxed.F1.{D_B, L_B, L_L, L_P}
|
||||
import org.unisonweb.util.Unboxed.F2.{DD_D, LD_L, LL_L}
|
||||
import org.unisonweb.util.Unboxed.Unboxed
|
||||
|
||||
object StreamTests {
|
||||
implicit class SourceRunner(private val s: String) extends AnyVal {
|
||||
def runPipes(implicit t: EasyTest.Env): Term =
|
||||
Bootstrap.normalizedFromText(
|
||||
s"""a |> f = f a
|
||||
|$s
|
||||
""".stripMargin
|
||||
).fold(fail(_), identity)
|
||||
}
|
||||
|
||||
val tests = suite("stream")(
|
||||
suite("native")(
|
||||
test("take/drop") { implicit T =>
|
||||
@ -143,52 +152,62 @@ object StreamTests {
|
||||
}
|
||||
),
|
||||
{
|
||||
val incU = UnisonToScala.toUnboxed1(Builtins.Int64_inc)
|
||||
val plusU = UnisonToScala.toUnboxed2(Builtins.Int64_add)
|
||||
val evenU = UnisonToScala.toUnboxed1(Builtins.Int64_isEven)
|
||||
import Term.Syntax._
|
||||
|
||||
suite("unison") (
|
||||
test("take/drop") { implicit T =>
|
||||
equal(
|
||||
Stream.iterate(0)(incU(env)).take(5).drop(3).reduce(0)(plusU(env)),
|
||||
equal[Term](
|
||||
s"""Stream.iterate +0 Int64.inc
|
||||
| |> Stream.take 5
|
||||
| |> Stream.drop 3
|
||||
| |> Stream.reduce 0 (+)
|
||||
""".stripMargin.runPipes,
|
||||
scala.Stream.from(0).take(5).drop(3).sum
|
||||
)
|
||||
},
|
||||
test("map") { implicit T =>
|
||||
equal[List[Long]](
|
||||
Stream.fromInt64(0).take(10).map(incU(env)).toSequence[Long].toList,
|
||||
scala.Stream.from(0).take(10).map(_ + 1l).toList
|
||||
equal[Term](
|
||||
s"""Stream.fromInt64 +0
|
||||
| |> Stream.take 10
|
||||
| |> Stream.map Int64.inc
|
||||
| |> Stream.toSequence
|
||||
""".stripMargin.runPipes,
|
||||
Term.Sequence(Sequence(
|
||||
scala.Stream.from(0)
|
||||
.take(10)
|
||||
.map(i => (i + 1l): Term).toList: _*
|
||||
))
|
||||
)
|
||||
},
|
||||
test("filter") { implicit T =>
|
||||
equal[List[Long]](
|
||||
Stream.iterate(0)(incU(env)).take(10000).filter(evenU(env))
|
||||
.toSequence[Long].toList,
|
||||
scala.Stream.from(0).map(_.toLong).take(10000).filter(_ % 2 == 0).toList
|
||||
)
|
||||
},
|
||||
test("foldLeft Int64_add") { implicit T =>
|
||||
val plusU = UnisonToScala.toUnboxed2(Builtins.Int64_add)
|
||||
equal(
|
||||
Stream.fromInt64(0).take(10000).foldLeft(Value(0))(plusU(env)),
|
||||
Value((0 until 10000).sum)
|
||||
)
|
||||
},
|
||||
test("scanLeft Int64_add") { implicit T =>
|
||||
val int64add = UnisonToScala.toUnboxed2(Builtins.Int64_add)(env)
|
||||
equal(
|
||||
Stream.fromInt64(1).take(10000).scanLeft(Value(0))(int64add).reduce(Value(0))(int64add),
|
||||
Value(scala.Stream.from(1).take(10000).scanLeft(0l)(_+_).sum)
|
||||
)
|
||||
},
|
||||
test("iterate Int64_inc, reduce Int64_add") { implicit T =>
|
||||
val incU = UnisonToScala.toUnboxed1(Builtins.Int64_inc)
|
||||
val plusU = UnisonToScala.toUnboxed2(Builtins.Int64_add)
|
||||
equal[Value](
|
||||
Stream.iterate(0l)(incU(env)).take(10).reduce(zero = Value(0))(plusU(env)),
|
||||
Value((scala.Stream.from(0).take(10)).sum)
|
||||
)
|
||||
}
|
||||
// test("filter") { implicit T =>
|
||||
// equal[List[Long]](
|
||||
// Stream.iterate(0)(incU(env)).take(10000).filter(evenU(env))
|
||||
// .toSequence[Long].toList,
|
||||
// scala.Stream.from(0).map(_.toLong).take(10000).filter(_ % 2 == 0).toList
|
||||
// )
|
||||
// },
|
||||
// test("foldLeft Int64_add") { implicit T =>
|
||||
// val plusU = UnisonToScala.toUnboxed2(Builtins.Int64_add)
|
||||
// equal(
|
||||
// Stream.fromInt64(0).take(10000).foldLeft(Value(0))(plusU(env)),
|
||||
// Value((0 until 10000).sum)
|
||||
// )
|
||||
// },
|
||||
// test("scanLeft Int64_add") { implicit T =>
|
||||
// val int64add = UnisonToScala.toUnboxed2(Builtins.Int64_add)(env)
|
||||
// equal(
|
||||
// Stream.fromInt64(1).take(10000).scanLeft(Value(0))(int64add).reduce(Value(0))(int64add),
|
||||
// Value(scala.Stream.from(1).take(10000).scanLeft(0l)(_+_).sum)
|
||||
// )
|
||||
// },
|
||||
// test("iterate Int64_inc, reduce Int64_add") { implicit T =>
|
||||
// val incU = UnisonToScala.toUnboxed1(Builtins.Int64_inc)
|
||||
// val plusU = UnisonToScala.toUnboxed2(Builtins.Int64_add)
|
||||
// equal[Value](
|
||||
// Stream.iterate(0l)(incU(env)).take(10).reduce(zero = Value(0))(plusU(env)),
|
||||
// Value((scala.Stream.from(0).take(10)).sum)
|
||||
// )
|
||||
// }
|
||||
)
|
||||
}
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user