Skip to content

Commit 8c97458

Browse files
committed
Begin porting strymonas
1 parent 83cef51 commit 8c97458

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import dotty.tools.dotc.quoted.Toolbox._
2+
import scala.quoted._
3+
4+
trait StagedStreams {
5+
6+
// TODO: remove as it exists in Quoted Lib
7+
sealed trait Var[T] {
8+
def get: Expr[T]
9+
def update(x: Expr[T]): Expr[Unit]
10+
}
11+
12+
object Var {
13+
def apply[T: Type, U](init: Expr[T])(body: Var[T] => Expr[U]): Expr[U] = '{
14+
var x = ~init
15+
~body(
16+
new Var[T] {
17+
def get: Expr[T] = '(x)
18+
def update(e: Expr[T]): Expr[Unit] = '{ x = ~e }
19+
}
20+
)
21+
}
22+
}
23+
24+
type Id[A] = A
25+
26+
trait Producer[A] { self =>
27+
type St
28+
val card: Cardinality
29+
30+
def init(k: St => Expr[Unit]): Expr[Unit]
31+
def step(st: St, k: (A => Expr[Unit])): Expr[Unit]
32+
def hasNext(st: St): Expr[Boolean]
33+
}
34+
35+
trait Cardinality
36+
case object AtMost1 extends Cardinality
37+
case object Many extends Cardinality
38+
39+
trait StagedStream[A]
40+
case class Linear[A](producer: Producer[A]) extends StagedStream[A]
41+
case class Nested[A, B](producer: Producer[A], nestedf: A => StagedStream[B]) extends StagedStream[B]
42+
43+
case class Stream[A](stream: StagedStream[Expr[A]]) {
44+
// def fold[W](z: Expr[W], f: (Expr[W] => Expr[A] => Expr[W])): Expr[W] = ???
45+
46+
// def fold_raw[W](z: Expr[W], update_acc: Expr[W] => Expr[Unit], f: (Expr[W] => Expr[A] => Expr[W])): Expr[Unit] = {
47+
// def consume[A](consumer: A => Expr[Unit], stream: StagedStream[A]): Expr[Unit] = {
48+
// stream match {
49+
// case Linear(producer) => {
50+
// producer.card match {
51+
// case Many =>
52+
// producer.init(sp => '{
53+
// while(~producer.hasNext(sp)) {
54+
// ~producer.step(sp, consumer)
55+
// }
56+
// })
57+
// case AtMost1 =>
58+
// producer.init(sp => '{
59+
// if (~producer.hasNext(sp)) {
60+
// ~producer.step(sp, consumer)
61+
// }
62+
// })
63+
// }
64+
// }
65+
// case Nested(producer, nestedf) => {
66+
// ??? //consume(((a) => consume(consumer, nestedf(a))), Linear[A](producer))
67+
// }
68+
// }
69+
// }
70+
71+
// ??? // consume((a: Expr[A]) => '{ ~update_acc(f(z)(a)) }, stream)
72+
// }
73+
}
74+
75+
object Stream {
76+
def of[A: Type](arr: Expr[Array[A]]): Stream[A] = {
77+
val prod = new Producer[Expr[A]] {
78+
type St = (Var[Int], Var[Int], Expr[Array[A]])
79+
80+
val card = Many
81+
82+
def init(k: St => Expr[Unit]): Expr[Unit] = {
83+
Var('{(~arr).length}) { n =>
84+
Var(0.toExpr){i =>
85+
k((i, n, arr))
86+
}
87+
}
88+
}
89+
90+
def step(st: St, k: (Expr[A] => Expr[Unit])): Expr[Unit] = {
91+
val (i, _, arr) = st
92+
'{
93+
val el = (~arr).apply(~i.get)
94+
~i.update('{ ~i.get + 1 })
95+
~k('(el))
96+
}
97+
}
98+
99+
def hasNext(st: St): Expr[Boolean] = {
100+
val (i, n, _) = st
101+
'{
102+
(~i.get < ~n.get)
103+
}
104+
}
105+
}
106+
107+
Stream(Linear(prod))
108+
}
109+
}
110+
}
111+

0 commit comments

Comments
 (0)