mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 14:40:17 +00:00
fix(compiler): Multiple closures in one function [LNG-262] (#941)
This commit is contained in:
parent
fcdb5b0fef
commit
45ca7bbf3e
@ -1,34 +1,35 @@
|
||||
aqua A
|
||||
|
||||
export test
|
||||
export bugLNG260
|
||||
|
||||
ability InnerAb:
|
||||
arrow() -> i8, i8
|
||||
func create(a: i8) -> -> i8:
|
||||
closureArrow = () -> i8:
|
||||
<- a
|
||||
<- closureArrow
|
||||
|
||||
ability TestAb:
|
||||
inner: InnerAb
|
||||
func test() -> i8, i8:
|
||||
arr1 <- create(1)
|
||||
arr2 <- create(2)
|
||||
<- arr1(), arr2()
|
||||
|
||||
-- func create(a: i8, b: i8) -> TestAb:
|
||||
-- arrow = () -> i8, i8:
|
||||
-- <- a, b
|
||||
-- <- TestAb(inner = InnerAb(arrow = arrow))
|
||||
--
|
||||
-- func test() -> i8, i8, i8, i8, i8, i8:
|
||||
-- Ab <- create(1, 2)
|
||||
-- ab <- create(3, 4)
|
||||
-- AB <- create(5, 6)
|
||||
-- res1, res2 <- ab.inner.arrow()
|
||||
-- res3, res4 <- Ab.inner.arrow()
|
||||
-- res5, res6 <- AB.inner.arrow()
|
||||
-- <- res1, res2, res3, res4, res5, res6
|
||||
func cmp(a: i32, b: i32, pred: i8 -> bool) -> bool:
|
||||
result: ?bool
|
||||
|
||||
func create(a: i8, b: i8) -> i8 -> i8, i8:
|
||||
arrow = (c: i8) -> i8, i8:
|
||||
<- a, b
|
||||
<- arrow
|
||||
if a < b:
|
||||
result <- pred(-1)
|
||||
else:
|
||||
if a == b:
|
||||
result <- pred(0)
|
||||
else:
|
||||
result <- pred(1)
|
||||
|
||||
func test() -> i8, i8, i8, i8, i8, i8:
|
||||
Ab <- create(1, 2)
|
||||
ab <- create(3, 4)
|
||||
AB <- create(5, 6)
|
||||
<- res1, res2, res3, res4, res5, res6
|
||||
<- result!
|
||||
|
||||
func gt(a: i32, b: i32) -> bool:
|
||||
pred = (ord: i8) -> bool:
|
||||
<- ord > 0
|
||||
|
||||
<- cmp(a, b, pred)
|
||||
|
||||
func bugLNG260(a: i32, b: i32) -> bool:
|
||||
<- gt(a, b)
|
@ -2,7 +2,7 @@ aqua Main
|
||||
|
||||
use DECLARE_CONST, decl_bar from "imports_exports/declare.aqua" as Declare
|
||||
|
||||
export handleAb, SomeService, bug214, checkAbCalls, bugLNG258_1, bugLNG258_2, bugLNG258_3
|
||||
export handleAb, SomeService, bug214, checkAbCalls, bugLNG258_1, bugLNG258_2, bugLNG258_3, multipleAbilityWithClosure
|
||||
|
||||
service SomeService("wed"):
|
||||
getStr(s: string) -> string
|
||||
@ -114,4 +114,18 @@ func bugLNG258_3() -> i8, i8:
|
||||
res1, res2 <- aB.inner.arrow()
|
||||
<- res1, res2
|
||||
|
||||
ability TestAbWithClosure:
|
||||
arrow: -> i8
|
||||
|
||||
func createAb(a: i8) -> TestAbWithClosure:
|
||||
closureArrow = () -> i8:
|
||||
<- a
|
||||
ab = TestAbWithClosure(arrow = closureArrow)
|
||||
<- ab
|
||||
|
||||
func multipleAbilityWithClosure() -> i8, i8:
|
||||
ab <- createAb(1)
|
||||
ab2 <- createAb(2)
|
||||
<- ab.arrow(), ab2.arrow()
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@ module Closure declares *
|
||||
|
||||
import "@fluencelabs/aqua-lib/builtin.aqua"
|
||||
|
||||
export LocalSrv, closureIn, closureOut, closureBig, closureOut2, lng58Bug
|
||||
export LocalSrv, closureIn, closureOut, closureBig, closureOut2, lng58Bug, multipleClosuresBugLNG262
|
||||
|
||||
service MyOp("op"):
|
||||
identity(s: string) -> string
|
||||
@ -70,4 +70,14 @@ func lng58Bug() -> string:
|
||||
|
||||
waiting()
|
||||
|
||||
<- status!
|
||||
<- status!
|
||||
|
||||
func create(a: i8) -> -> i8:
|
||||
closureArrow = () -> i8:
|
||||
<- a
|
||||
<- closureArrow
|
||||
|
||||
func multipleClosuresBugLNG262() -> i8, i8:
|
||||
arr1 <- create(1)
|
||||
arr2 <- create(2)
|
||||
<- arr1(), arr2()
|
@ -33,7 +33,7 @@ import {
|
||||
import {
|
||||
abilityCall,
|
||||
complexAbilityCall,
|
||||
checkAbCallsCall, bugLNG258Call1, bugLNG258Call2, bugLNG258Call3,
|
||||
checkAbCallsCall, bugLNG258Call1, bugLNG258Call2, bugLNG258Call3, multipleAbilityWithClosureCall,
|
||||
} from "../examples/abilityCall.js";
|
||||
import {
|
||||
nilLengthCall,
|
||||
@ -104,7 +104,7 @@ import { multiReturnCall } from "../examples/multiReturnCall.js";
|
||||
import { declareCall } from "../examples/declareCall.js";
|
||||
import { genOptions, genOptionsEmptyString } from "../examples/optionsCall.js";
|
||||
import { lng193BugCall } from "../examples/closureReturnRename.js";
|
||||
import { closuresCall } from "../examples/closures.js";
|
||||
import {closuresCall, multipleClosuresLNG262BugCall} from "../examples/closures.js";
|
||||
import { closureArrowCaptureCall } from "../examples/closureArrowCapture.js";
|
||||
import {
|
||||
bugLNG63_2Call,
|
||||
@ -533,7 +533,7 @@ describe("Testing examples", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("ability.aqua", async () => {
|
||||
it("abilities.aqua", async () => {
|
||||
let result = await abilityCall();
|
||||
expect(result).toStrictEqual([
|
||||
"declare_const123",
|
||||
@ -543,17 +543,17 @@ describe("Testing examples", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("ability.aqua complex", async () => {
|
||||
it("abilities.aqua complex", async () => {
|
||||
let result = await complexAbilityCall();
|
||||
expect(result).toStrictEqual([false, true]);
|
||||
});
|
||||
|
||||
it("ability.aqua ability calls", async () => {
|
||||
it("abilities.aqua ability calls", async () => {
|
||||
let result = await checkAbCallsCall();
|
||||
expect(result).toStrictEqual([true, false, true]);
|
||||
});
|
||||
|
||||
it("ability.aqua bug LNG-258", async () => {
|
||||
it("abilities.aqua bug LNG-258", async () => {
|
||||
let result1 = await bugLNG258Call1();
|
||||
expect(result1).toStrictEqual([1, 2]);
|
||||
|
||||
@ -564,6 +564,11 @@ describe("Testing examples", () => {
|
||||
expect(result3).toStrictEqual([5, 6]);
|
||||
});
|
||||
|
||||
it("abilities.aqua multiple abilities with closures", async () => {
|
||||
let result1 = await multipleAbilityWithClosureCall();
|
||||
expect(result1).toStrictEqual([1, 2]);
|
||||
});
|
||||
|
||||
it("functors.aqua LNG-119 bug", async () => {
|
||||
let result = await bugLng119Call();
|
||||
expect(result).toEqual([1]);
|
||||
@ -949,6 +954,11 @@ describe("Testing examples", () => {
|
||||
expect(closuresResult).toEqual(["in", res1, res1, res2]);
|
||||
}, 20000);
|
||||
|
||||
it("closures.aqua bug LNG-262", async () => {
|
||||
let result = await multipleClosuresLNG262BugCall();
|
||||
expect(result).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
it("closureArrowCapture.aqua", async () => {
|
||||
let result = await closureArrowCaptureCall("input");
|
||||
expect(result).toEqual("call: ".repeat(4) + "input");
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
bugLNG258_1,
|
||||
bugLNG258_2,
|
||||
bugLNG258_3,
|
||||
multipleAbilityWithClosure
|
||||
} from "../compiled/examples/abilities";
|
||||
|
||||
export async function abilityCall(): Promise<[string, string, string, number]> {
|
||||
@ -37,3 +38,7 @@ export async function bugLNG258Call2(): Promise<[number, number]> {
|
||||
export async function bugLNG258Call3(): Promise<[number, number]> {
|
||||
return await bugLNG258_3();
|
||||
}
|
||||
|
||||
export async function multipleAbilityWithClosureCall(): Promise<[number, number]> {
|
||||
return await multipleAbilityWithClosure()
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
registerLocalSrv,
|
||||
closureOut2,
|
||||
lng58Bug,
|
||||
multipleClosuresBugLNG262
|
||||
} from "../compiled/examples/closures.js";
|
||||
import { config } from "../config.js";
|
||||
|
||||
@ -32,3 +33,7 @@ export async function closuresCall(): Promise<
|
||||
export async function lng58CBugCall(): Promise<string> {
|
||||
return lng58Bug();
|
||||
}
|
||||
|
||||
export async function multipleClosuresLNG262BugCall(): Promise<[number, number]> {
|
||||
return multipleClosuresBugLNG262();
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ object ArrowInliner extends Logging {
|
||||
) if !outsideStreamNames.contains(n) =>
|
||||
resDesugar.toList -> res
|
||||
case (
|
||||
cexp @ CallModel.Export(exp, st @ StreamType(_)),
|
||||
cexp @ CallModel.Export(_, StreamType(_)),
|
||||
(res, resDesugar)
|
||||
) =>
|
||||
// pass nested function results to a stream
|
||||
|
@ -1,13 +1,13 @@
|
||||
package aqua.model.inline
|
||||
|
||||
import aqua.model.*
|
||||
import aqua.model.MetaModel.CallArrowModel
|
||||
import aqua.model.inline.state.InliningState
|
||||
import aqua.raw.ops.*
|
||||
import aqua.raw.value.*
|
||||
import aqua.types.*
|
||||
import aqua.raw.value.{CallArrowRaw, ValueRaw}
|
||||
import aqua.raw.arrow.{ArrowRaw, FuncRaw}
|
||||
|
||||
import cats.Eval
|
||||
import cats.syntax.show.*
|
||||
import cats.syntax.option.*
|
||||
@ -520,6 +520,137 @@ class ArrowInlinerSpec extends AnyFlatSpec with Matchers with Inside {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* func return(a: i8) -> -> i8:
|
||||
* closure = () -> i8:
|
||||
* <- a
|
||||
* <- closure
|
||||
*
|
||||
* func test() -> i8, i8:
|
||||
* closure <- return(1)
|
||||
* closure2 <- return(2)
|
||||
* <- closure(), closure2()
|
||||
*/
|
||||
it should "correct renaming on multiple closures from same function" in {
|
||||
val resType = ScalarType.i8
|
||||
val resVar = VarRaw("a", resType)
|
||||
|
||||
val closureType = ArrowType(
|
||||
ProductType(Nil),
|
||||
ProductType(resType :: Nil)
|
||||
)
|
||||
|
||||
val innerClosure = VarRaw("closureArrow", closureType)
|
||||
val closureFunc = FuncRaw(
|
||||
innerClosure.name,
|
||||
ArrowRaw(
|
||||
closureType,
|
||||
List(resVar),
|
||||
ReturnTag(NonEmptyList.one(resVar)).leaf
|
||||
)
|
||||
)
|
||||
|
||||
val returnFunc = FuncArrow(
|
||||
"return",
|
||||
SeqTag.wrap(
|
||||
ClosureTag(
|
||||
closureFunc,
|
||||
detach = false
|
||||
).leaf,
|
||||
ReturnTag(
|
||||
NonEmptyList.one(innerClosure)
|
||||
).leaf
|
||||
),
|
||||
ArrowType(
|
||||
ProductType.labelled((resVar.name, ScalarType.i8) :: Nil),
|
||||
ProductType(closureType :: Nil)
|
||||
),
|
||||
List(innerClosure),
|
||||
Map.empty,
|
||||
Map.empty,
|
||||
None
|
||||
)
|
||||
|
||||
val closureVar = VarRaw("closure", closureType)
|
||||
val closureVar2 = VarRaw("closure2", closureType)
|
||||
|
||||
val res1 = VarRaw("res1", ScalarType.i8)
|
||||
val res2 = VarRaw("res2", ScalarType.i8)
|
||||
|
||||
val testFunc = FuncArrow(
|
||||
"test",
|
||||
SeqTag.wrap(
|
||||
CallArrowRawTag
|
||||
.func(
|
||||
returnFunc.funcName,
|
||||
Call(LiteralRaw.number(1) :: Nil, Call.Export(closureVar.name, closureType) :: Nil)
|
||||
)
|
||||
.leaf,
|
||||
CallArrowRawTag
|
||||
.func(
|
||||
returnFunc.funcName,
|
||||
Call(LiteralRaw.number(2) :: Nil, Call.Export(closureVar2.name, closureType) :: Nil)
|
||||
)
|
||||
.leaf,
|
||||
CallArrowRawTag
|
||||
.func(
|
||||
closureVar.name,
|
||||
Call(Nil, Call.Export(res1.name, res1.baseType) :: Nil)
|
||||
)
|
||||
.leaf,
|
||||
CallArrowRawTag
|
||||
.func(
|
||||
closureVar2.name,
|
||||
Call(Nil, Call.Export(res2.name, res2.baseType) :: Nil)
|
||||
)
|
||||
.leaf,
|
||||
CallArrowRawTag
|
||||
.service(LiteralRaw.quote("Srv"), "callSrv", Call(res1 :: res2 :: Nil, Nil))
|
||||
.leaf
|
||||
),
|
||||
ArrowType(
|
||||
ProductType(Nil),
|
||||
ProductType(Nil)
|
||||
),
|
||||
Nil,
|
||||
Map(returnFunc.funcName -> returnFunc),
|
||||
Map.empty,
|
||||
None
|
||||
)
|
||||
|
||||
println("testFunc: ")
|
||||
println(testFunc.body.show)
|
||||
|
||||
val model = ArrowInliner
|
||||
.callArrow[InliningState](testFunc, CallModel(Nil, Nil))
|
||||
.runA(InliningState())
|
||||
.value
|
||||
|
||||
model.tailForced
|
||||
|
||||
model.equalsOrShowDiff(
|
||||
SeqModel.wrap(
|
||||
CallArrowModel("return").wrap(
|
||||
CaptureTopologyModel("closureArrow").leaf
|
||||
),
|
||||
CallArrowModel("return").wrap(
|
||||
CaptureTopologyModel("closureArrow-0").leaf
|
||||
),
|
||||
CallArrowModel("closureArrow").wrap(
|
||||
ApplyTopologyModel("closureArrow").wrap(EmptyModel.leaf)
|
||||
),
|
||||
CallArrowModel("closureArrow-0").wrap(
|
||||
ApplyTopologyModel("closureArrow-0").wrap(EmptyModel.leaf)
|
||||
),
|
||||
CallServiceModel(
|
||||
LiteralModel.quote("Srv"),
|
||||
"callSrv",
|
||||
CallModel(LiteralModel.number(1) :: LiteralModel.number(2) :: Nil, Nil)
|
||||
).leaf
|
||||
)
|
||||
) should be(true)
|
||||
}
|
||||
|
||||
/*
|
||||
func stream-callback(cb: string -> ()):
|
||||
records: *string
|
||||
@ -1652,7 +1783,7 @@ class ArrowInlinerSpec extends AnyFlatSpec with Matchers with Inside {
|
||||
val mainFunc = FuncArrow(
|
||||
funcName = "main",
|
||||
body = mainBody,
|
||||
arrowType = ArrowType(ProductType(Nil), ProductType(Nil)),
|
||||
arrowType = mainType,
|
||||
ret = Nil,
|
||||
capturedArrows = Map(testName -> testFunc),
|
||||
capturedValues = Map.empty,
|
||||
|
@ -290,13 +290,17 @@ case class ClosureTag(
|
||||
override def usesVarNames: Set[String] = Set.empty
|
||||
|
||||
override def renameExports(map: Map[String, String]): RawTag =
|
||||
copy(func = func.copy(name = map.getOrElse(func.name, func.name)))
|
||||
copy(func =
|
||||
func.copy(
|
||||
name = map.getOrElse(func.name, func.name)
|
||||
)
|
||||
)
|
||||
|
||||
override def mapValues(f: ValueRaw => ValueRaw): RawTag =
|
||||
copy(
|
||||
func.copy(arrow =
|
||||
func.arrow.copy(
|
||||
ret = func.arrow.ret.map(_.mapValues(f)),
|
||||
ret = func.arrow.ret.map(_.map(f)),
|
||||
body = func.arrow.body.map(_.mapValues(f))
|
||||
)
|
||||
)
|
||||
|
@ -10,8 +10,10 @@ import aqua.semantics.rules.ValuesAlgebra
|
||||
import aqua.semantics.rules.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.rules.definitions.DefinitionsAlgebra
|
||||
import aqua.semantics.rules.locations.LocationsAlgebra
|
||||
import aqua.semantics.rules.mangler.ManglerAlgebra
|
||||
import aqua.semantics.rules.names.NamesAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
|
||||
import cats.Monad
|
||||
|
||||
object ExprSem {
|
||||
@ -24,7 +26,8 @@ object ExprSem {
|
||||
T: TypesAlgebra[S, G],
|
||||
V: ValuesAlgebra[S, G],
|
||||
D: DefinitionsAlgebra[S, G],
|
||||
L: LocationsAlgebra[S, G]
|
||||
L: LocationsAlgebra[S, G],
|
||||
M: ManglerAlgebra[G]
|
||||
): Prog[G, Raw] =
|
||||
expr match {
|
||||
case expr: ServiceIdExpr[S] => new ServiceIdSem(expr).program[G]
|
||||
|
@ -276,7 +276,8 @@ object RawSemantics extends Logging {
|
||||
T: TypesAlgebra[S, G],
|
||||
D: DefinitionsAlgebra[S, G],
|
||||
L: LocationsAlgebra[S, G],
|
||||
E: ReportAlgebra[S, G]
|
||||
E: ReportAlgebra[S, G],
|
||||
M: ManglerAlgebra[G]
|
||||
): (Expr[S], Chain[G[RawWithToken[S]]]) => Eval[G[RawWithToken[S]]] = (expr, inners) =>
|
||||
Eval later ExprSem
|
||||
.getProg[S, G](expr)
|
||||
|
@ -1,33 +1,27 @@
|
||||
package aqua.semantics.expr.func
|
||||
|
||||
import aqua.parser.expr.FuncExpr
|
||||
import aqua.parser.expr.func.ArrowExpr
|
||||
import aqua.parser.lexer.{Arg, DataTypeToken}
|
||||
import aqua.raw.Raw
|
||||
import aqua.raw.arrow.ArrowRaw
|
||||
import aqua.raw.ops.{SeqTag, *}
|
||||
import aqua.raw.ops.*
|
||||
import aqua.raw.value.*
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.rules.ValuesAlgebra
|
||||
import aqua.semantics.rules.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.rules.locations.LocationsAlgebra
|
||||
import aqua.semantics.rules.mangler.ManglerAlgebra
|
||||
import aqua.semantics.rules.names.NamesAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
import aqua.types.*
|
||||
|
||||
import cats.Eval
|
||||
import cats.data.{Chain, NonEmptyList}
|
||||
import cats.free.{Cofree, Free}
|
||||
import cats.data.OptionT
|
||||
import cats.syntax.show.*
|
||||
import cats.Monad
|
||||
import cats.data.Chain
|
||||
import cats.free.Cofree
|
||||
import cats.syntax.applicative.*
|
||||
import cats.syntax.apply.*
|
||||
import cats.syntax.foldable.*
|
||||
import cats.syntax.bifunctor.*
|
||||
import cats.syntax.flatMap.*
|
||||
import cats.syntax.foldable.*
|
||||
import cats.syntax.functor.*
|
||||
import cats.syntax.traverse.*
|
||||
import cats.{Applicative, Monad}
|
||||
|
||||
class ArrowSem[S[_]](val expr: ArrowExpr[S]) extends AnyVal {
|
||||
|
||||
@ -35,9 +29,7 @@ class ArrowSem[S[_]](val expr: ArrowExpr[S]) extends AnyVal {
|
||||
|
||||
def before[Alg[_]: Monad](implicit
|
||||
T: TypesAlgebra[S, Alg],
|
||||
N: NamesAlgebra[S, Alg],
|
||||
A: AbilitiesAlgebra[S, Alg],
|
||||
L: LocationsAlgebra[S, Alg]
|
||||
N: NamesAlgebra[S, Alg]
|
||||
): Alg[ArrowType] = for {
|
||||
arrowType <- T.beginArrowScope(arrowTypeExpr)
|
||||
// Create local variables
|
||||
@ -57,13 +49,11 @@ class ArrowSem[S[_]](val expr: ArrowExpr[S]) extends AnyVal {
|
||||
)(using
|
||||
T: TypesAlgebra[S, Alg],
|
||||
N: NamesAlgebra[S, Alg],
|
||||
A: AbilitiesAlgebra[S, Alg],
|
||||
L: LocationsAlgebra[S, Alg]
|
||||
M: ManglerAlgebra[Alg]
|
||||
): Alg[Raw] = for {
|
||||
streamsInScope <- N.streamsDefinedWithinScope()
|
||||
retValues <- T.endArrowScope(expr.arrowTypeExpr)
|
||||
retValuesDerivedFrom <- N.getDerivedFrom(retValues.map(_.varNames))
|
||||
res = bodyGen match {
|
||||
res <- bodyGen match {
|
||||
case FuncOp(bodyModel) =>
|
||||
// TODO: wrap with local on...via...
|
||||
val retsAndArgs = retValues zip funcArrow.codomain.toList
|
||||
@ -77,51 +67,63 @@ class ArrowSem[S[_]](val expr: ArrowExpr[S]) extends AnyVal {
|
||||
val localStreams = streamsInScope -- dataArgsNames -- streamsThatReturnAsStreams
|
||||
|
||||
// process stream that returns as not streams and all Apply*Raw
|
||||
val (bodyRets, retVals) = retsAndArgs.mapWithIndex {
|
||||
case ((v @ VarRaw(_, StreamType(_)), StreamType(_)), _) =>
|
||||
(Chain.empty, v)
|
||||
retsAndArgs.traverse {
|
||||
case (v @ VarRaw(_, StreamType(_)), StreamType(_)) =>
|
||||
(Chain.empty, v).pure[Alg]
|
||||
// canonicalize and change return value
|
||||
case ((VarRaw(streamName, streamType @ StreamType(streamElement)), _), idx) =>
|
||||
val canonReturnVar = VarRaw(s"-$streamName-fix-$idx", CanonStreamType(streamElement))
|
||||
val returnVar = VarRaw(s"-$streamName-flat-$idx", ArrayType(streamElement))
|
||||
val body = Chain(
|
||||
CanonicalizeTag(
|
||||
VarRaw(streamName, streamType),
|
||||
Call.Export(canonReturnVar.name, canonReturnVar.`type`)
|
||||
).leaf,
|
||||
FlattenTag(
|
||||
canonReturnVar,
|
||||
returnVar.name
|
||||
).leaf
|
||||
)
|
||||
case (VarRaw(streamName, streamType @ StreamType(streamElement)), _) =>
|
||||
for {
|
||||
canonName <- M.rename(s"-$streamName-fix")
|
||||
returnVarName <- M.rename(s"-$streamName-flat")
|
||||
} yield {
|
||||
val canonReturnVar = VarRaw(canonName, CanonStreamType(streamElement))
|
||||
val returnVar = VarRaw(returnVarName, ArrayType(streamElement))
|
||||
val body = Chain(
|
||||
CanonicalizeTag(
|
||||
VarRaw(streamName, streamType),
|
||||
Call.Export(canonReturnVar.name, canonReturnVar.`type`)
|
||||
).leaf,
|
||||
FlattenTag(
|
||||
canonReturnVar,
|
||||
returnVar.name
|
||||
).leaf
|
||||
)
|
||||
|
||||
(body, returnVar)
|
||||
}
|
||||
|
||||
(body, returnVar)
|
||||
// assign and change return value for all `Apply*Raw`
|
||||
case ((v: ValueRaw.ApplyRaw, _), idx) =>
|
||||
val assignedReturnVar = VarRaw(s"-return-fix-$idx", v.`type`)
|
||||
val body = Chain.one(
|
||||
AssignmentTag(
|
||||
v,
|
||||
assignedReturnVar.name
|
||||
).leaf
|
||||
)
|
||||
case (v: ValueRaw.ApplyRaw, _) =>
|
||||
for {
|
||||
assignedReturnName <- M.rename(s"-return-fix")
|
||||
} yield {
|
||||
val assignedReturnVar = VarRaw(assignedReturnName, v.`type`)
|
||||
|
||||
(body, assignedReturnVar)
|
||||
case ((v, _), _) => (Chain.empty, v)
|
||||
}.unzip.leftMap(_.combineAll)
|
||||
val body = Chain.one(
|
||||
AssignmentTag(
|
||||
v,
|
||||
assignedReturnVar.name
|
||||
).leaf
|
||||
)
|
||||
|
||||
val bodyModified = SeqTag.wrap(
|
||||
bodyModel +: bodyRets
|
||||
)
|
||||
(body, assignedReturnVar)
|
||||
}
|
||||
|
||||
// wrap streams with restrictions
|
||||
val bodyWithRestrictions = localStreams.foldLeft(bodyModified) {
|
||||
case (bm, (streamName, streamType)) =>
|
||||
RestrictionTag(streamName, streamType).wrap(bm)
|
||||
case (v, _) => (Chain.empty, v).pure[Alg]
|
||||
}.map(_.unzip.leftMap(_.combineAll)).map { case (bodyRets, retVals) =>
|
||||
val bodyModified = SeqTag.wrap(
|
||||
bodyModel +: bodyRets
|
||||
)
|
||||
|
||||
// wrap streams with restrictions
|
||||
val bodyWithRestrictions =
|
||||
localStreams.foldLeft(bodyModified) { case (bm, (streamName, streamType)) =>
|
||||
RestrictionTag(streamName, streamType).wrap(bm)
|
||||
}
|
||||
ArrowRaw(funcArrow, retVals, bodyWithRestrictions)
|
||||
}
|
||||
|
||||
ArrowRaw(funcArrow, retVals, bodyWithRestrictions)
|
||||
case _ => Raw.error("Invalid arrow body")
|
||||
case _ => Raw.error("Invalid arrow body").pure[Alg]
|
||||
}
|
||||
} yield res
|
||||
|
||||
@ -129,7 +131,8 @@ class ArrowSem[S[_]](val expr: ArrowExpr[S]) extends AnyVal {
|
||||
T: TypesAlgebra[S, Alg],
|
||||
N: NamesAlgebra[S, Alg],
|
||||
A: AbilitiesAlgebra[S, Alg],
|
||||
L: LocationsAlgebra[S, Alg]
|
||||
L: LocationsAlgebra[S, Alg],
|
||||
M: ManglerAlgebra[Alg]
|
||||
): Prog[Alg, Raw] =
|
||||
Prog
|
||||
.around(
|
||||
|
Loading…
Reference in New Issue
Block a user