mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 22:50:18 +00:00
FuncSem WIP
This commit is contained in:
parent
b45c61f5c8
commit
d0d4db7bf5
@ -20,6 +20,94 @@ import scala.collection.immutable.Queue
|
||||
class FuncSem[F[_]](val expr: FuncExpr[F]) extends AnyVal {
|
||||
import expr._
|
||||
|
||||
def before[Alg[_]](implicit
|
||||
T: TypesAlgebra[F, Alg],
|
||||
N: NamesAlgebra[F, Alg],
|
||||
V: ValuesAlgebra[F, Alg],
|
||||
P: PeerIdAlgebra[F, Alg],
|
||||
A: AbilitiesAlgebra[F, Alg]
|
||||
): Free[Alg, ArrowType] =
|
||||
A.beginScope(name) >> Applicative[Free[Alg, *]]
|
||||
.product(
|
||||
// Collect argument types, define local variables
|
||||
args
|
||||
.foldLeft(
|
||||
// Begin scope -- for mangling
|
||||
N.beginScope(name).as[Queue[Type]](Queue.empty)
|
||||
) {
|
||||
case (f, Arg(argName, argType)) =>
|
||||
// Resolve arg type, remember it
|
||||
f.flatMap(acc =>
|
||||
T.resolveType(argType).flatMap {
|
||||
case Some(t: ArrowType) =>
|
||||
N.defineArrow(argName, ArrowGen.arg(argName.value, t), isRoot = false).as(acc.enqueue(t))
|
||||
case Some(t) =>
|
||||
N.define(argName, t).as(acc.enqueue(t))
|
||||
case None =>
|
||||
Free.pure(acc)
|
||||
}
|
||||
)
|
||||
}
|
||||
.map(_.toList),
|
||||
// Resolve return type
|
||||
ret.fold(Free.pure[Alg, Option[Type]](None))(T.resolveType(_))
|
||||
)
|
||||
.map(argsAndRes => ArrowType(argsAndRes._1, argsAndRes._2))
|
||||
|
||||
def after[Alg](funcArrow: ArrowType, bodyGen: Gen)(implicit
|
||||
T: TypesAlgebra[F, Alg],
|
||||
N: NamesAlgebra[F, Alg],
|
||||
V: ValuesAlgebra[F, Alg],
|
||||
P: PeerIdAlgebra[F, Alg],
|
||||
A: AbilitiesAlgebra[F, Alg]
|
||||
): Free[Alg, Gen] =
|
||||
// Check return value type
|
||||
((funcArrow.res, retValue) match {
|
||||
case (Some(t), Some(v)) =>
|
||||
V.resolveType(v).flatMap {
|
||||
case Some(vt) => T.ensureTypeMatches(v, t, vt).void
|
||||
case None => Free.pure[Alg, Unit](())
|
||||
}
|
||||
case _ =>
|
||||
Free.pure[Alg, Unit](())
|
||||
|
||||
// Erase arguments and internal variables
|
||||
}) >> A.endScope() >> N.endScope() >> (bodyGen match {
|
||||
case bg: AirGen if ret.isDefined == retValue.isDefined =>
|
||||
val argNames = args.map(_.name.value)
|
||||
N.defineArrow(
|
||||
name,
|
||||
ArrowGen.func(funcArrow, argNames, retValue.map(ArrowGen.valueToData), FuncBodyGen(bg)),
|
||||
isRoot = true
|
||||
) as FuncGen(
|
||||
name.value,
|
||||
Eval.later {
|
||||
bg.generate(
|
||||
AirContext(
|
||||
data = argNames
|
||||
.zip(funcArrow.args)
|
||||
.collect { //TODO preload these variables
|
||||
case (an, _: DataType) =>
|
||||
an -> DataView.Variable(an)
|
||||
}
|
||||
.toMap,
|
||||
arrows = argNames
|
||||
.zip(funcArrow.args)
|
||||
.collect {
|
||||
case (an, _: ArrowType) =>
|
||||
an -> new ArrowGen.SrvCallableOnPeer(InitPeerId, DataView.StringScalar("callback"), an)
|
||||
}
|
||||
.toMap,
|
||||
vars = argNames.toSet
|
||||
)
|
||||
)
|
||||
._2
|
||||
},
|
||||
FuncBodyGen(bg)
|
||||
)
|
||||
case _ => Gen.noop.lift
|
||||
})
|
||||
|
||||
def program[Alg[_]](implicit
|
||||
T: TypesAlgebra[F, Alg],
|
||||
N: NamesAlgebra[F, Alg],
|
||||
@ -28,79 +116,8 @@ class FuncSem[F[_]](val expr: FuncExpr[F]) extends AnyVal {
|
||||
A: AbilitiesAlgebra[F, Alg]
|
||||
): Prog[Alg, Gen] =
|
||||
Prog.around(
|
||||
A.beginScope(name) >> Applicative[Free[Alg, *]]
|
||||
.product(
|
||||
// Collect argument types, define local variables
|
||||
args
|
||||
.foldLeft(
|
||||
// Begin scope -- for mangling
|
||||
N.beginScope(name).as[Queue[Type]](Queue.empty)
|
||||
) {
|
||||
case (f, Arg(argName, argType)) =>
|
||||
// Resolve arg type, remember it
|
||||
f.flatMap(acc =>
|
||||
T.resolveType(argType).flatMap {
|
||||
case Some(t: ArrowType) =>
|
||||
N.defineArrow(argName, ArrowGen.arg(argName.value, t), isRoot = false).as(acc.enqueue(t))
|
||||
case Some(t) =>
|
||||
N.define(argName, t).as(acc.enqueue(t))
|
||||
case None =>
|
||||
Free.pure(acc)
|
||||
}
|
||||
)
|
||||
}
|
||||
.map(_.toList),
|
||||
// Resolve return type
|
||||
ret.fold(Free.pure[Alg, Option[Type]](None))(T.resolveType(_))
|
||||
)
|
||||
.map(argsAndRes => ArrowType(argsAndRes._1, argsAndRes._2)),
|
||||
(funcArrow: ArrowType, bodyGen: Gen) =>
|
||||
// Check return value type
|
||||
((funcArrow.res, retValue) match {
|
||||
case (Some(t), Some(v)) =>
|
||||
V.resolveType(v).flatMap {
|
||||
case Some(vt) => T.ensureTypeMatches(v, t, vt).void
|
||||
case None => Free.pure[Alg, Unit](())
|
||||
}
|
||||
case _ =>
|
||||
Free.pure[Alg, Unit](())
|
||||
})
|
||||
// Erase arguments and internal variables
|
||||
>> A.endScope() >> N.endScope() >> (bodyGen match {
|
||||
case bg: AirGen if ret.isDefined == retValue.isDefined =>
|
||||
val argNames = args.map(_.name.value)
|
||||
N.defineArrow(
|
||||
name,
|
||||
ArrowGen.func(funcArrow, argNames, retValue.map(ArrowGen.valueToData), FuncBodyGen(bg)),
|
||||
isRoot = true
|
||||
) as FuncGen(
|
||||
name.value,
|
||||
Eval.later {
|
||||
bg.generate(
|
||||
AirContext(
|
||||
data = argNames
|
||||
.zip(funcArrow.args)
|
||||
.collect { //TODO preload these variables
|
||||
case (an, _: DataType) =>
|
||||
an -> DataView.Variable(an)
|
||||
}
|
||||
.toMap,
|
||||
arrows = argNames
|
||||
.zip(funcArrow.args)
|
||||
.collect {
|
||||
case (an, _: ArrowType) =>
|
||||
an -> new ArrowGen.SrvCallableOnPeer(InitPeerId, DataView.StringScalar("callback"), an)
|
||||
}
|
||||
.toMap,
|
||||
vars = argNames.toSet
|
||||
)
|
||||
)
|
||||
._2
|
||||
},
|
||||
FuncBodyGen(bg)
|
||||
)
|
||||
case _ => Gen.noop.lift
|
||||
})
|
||||
before[Alg],
|
||||
after[Alg]
|
||||
)
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user