push to stream as a result of inner function only if stream is declared in outer function

This commit is contained in:
DieMyst 2022-10-19 19:07:08 +03:00
parent 2e558dbf80
commit 2b99cba0d1
4 changed files with 23 additions and 3 deletions

View File

@ -26,7 +26,8 @@ object ArrowInliner extends Logging {
// Apply a callable function, get its fully resolved body & optional value, if any
private def inline[S: Mangler: Arrows: Exports](
fn: FuncArrow,
call: CallModel
call: CallModel,
outsideDeclaredStreams: Map[String, ValueModel]
): State[S, (OpModel.Tree, List[ValueModel])] =
// Function's internal variables will not be available outside, hence the scope
Exports[S].scope(
@ -53,6 +54,9 @@ object ArrowInliner extends Logging {
// Fix the return values
(ops, rets) = (call.exportTo zip resolvedResult)
.map[(List[OpModel.Tree], ValueModel)] {
case (CallModel.Export(n, StreamType(_)), (res@VarModel(_, StreamType(_), _), resDesugar))
if !outsideDeclaredStreams.contains(n) =>
resDesugar.toList -> res
case (CallModel.Export(exp, st @ StreamType(_)), (res, resDesugar)) =>
// pass nested function results to a stream
(resDesugar.toList :+ PushToStreamModel(
@ -169,10 +173,16 @@ object ArrowInliner extends Logging {
for {
passArrows <- Arrows[S].pickArrows(call.arrowArgNames)
exports <- Exports[S].exports
declaredStreams = exports.filter {
case (_, VarModel(_, StreamType(_), _)) => true
case _ => false
}
av <- Arrows[S].scope(
for {
_ <- Arrows[S].resolved(passArrows)
av <- ArrowInliner.inline(arrow, call)
av <- ArrowInliner.inline(arrow, call, declaredStreams)
} yield av
)
(appliedOp, value) = av

View File

@ -209,6 +209,15 @@ object TagInliner extends Logging {
case _: ParGroupTag => pure(ParModel)
case XorTag | XorTag.LeftBiased =>
pure(XorModel)
case DeclareStreamTag(value) =>
value match
case VarRaw(name, _) =>
for {
cd <- valueToModel(value)
_ <- Exports[S].resolved(name, cd._1)
} yield None -> cd._2
case _ => none
case _: NoExecTag => none
case _ =>
logger.warn(s"Tag $tag must have been eliminated at this point")

View File

@ -172,7 +172,7 @@ object CallArrowRawTag {
case class DeclareStreamTag(
value: ValueRaw
) extends NoExecTag {
) extends RawTag {
override def mapValues(f: ValueRaw => ValueRaw): RawTag =
DeclareStreamTag(value.map(f))

View File

@ -87,6 +87,7 @@ class ArrowSem[S[_]](val expr: ArrowExpr[S]) extends AnyVal {
val (body, retValuesFix) = localStreams.foldLeft((m, retValues)) {
case ((b, rs), (n, st)) =>
if (derivedFromNames(n))
// TODO: what if this stream will be unused. create ticket
RestrictionTag(n, isStream = true).wrap(
SeqTag.wrap(
b :: CanonicalizeTag(