Skip to content

Commit

Permalink
fold over map and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
DieMyst committed May 28, 2024
1 parent bca70e4 commit b728af5
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 45 deletions.
24 changes: 13 additions & 11 deletions aqua-src/antithesis.aqua
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
aqua Job declares *

export testContainsFunc
export testForFunc

func testContainsFunc() -> bool, bool, bool, bool, bool:
func testForFunc() -> []string, [][]string:
streamMap: %string
resFirst = streamMap.contains("key one")
streamMap <<- ("key one", "")
resSecond = streamMap.contains("key one")
resThird = streamMap.contains("key one")
streamMap <<- ("key one", "new")
streamMap <<- ("key two", "")
resFourth = streamMap.contains("key one")
resFifth = streamMap.contains("key two")
<- resFirst, resSecond, resThird, resFourth, resFifth
streamMap <<- ("key one", "1")
streamMap <<- ("key one", "2")
streamMap <<- ("key two", "3")

streamKeys: *string
streamValues: *[]string

for kv <- streamMap:
streamKeys <<- kv.key
streamValues <<- kv.value
<- streamKeys, streamValues
25 changes: 23 additions & 2 deletions integration-tests/aqua/examples/streamMap.aqua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
aqua StreamMapTest declares *

export testGetFunc, testGetStreamFunc, testKeysFunc, testContainsFunc
export testGetFunc, testGetStreamFunc, testKeysFunc, testContainsFunc, testForFunc

func testGetFunc() -> []string, []string, []string:
streamMap: %string
Expand Down Expand Up @@ -45,4 +45,25 @@ func testContainsFunc() -> bool, bool, bool, bool, bool:
streamMap <<- (keyTwo, "")
resFourth = streamMap.contains(keyOne)
resFifth = streamMap.contains(keyTwo)
<- resFirst, resSecond, resThird, resFourth, resFifth
<- resFirst, resSecond, resThird, resFourth, resFifth

func testForFunc() -> []string, [][]string:
streamMap: %string
streamMap <<- ("key one", "1")
streamMap <<- ("key one", "2")

streamMap <<- ("key two", "3")
streamMap <<- ("key two", "4")
streamMap <<- ("key two", "5")

streamMap <<- ("key three", "6")

streamMap <<- ("key four", "7")

streamKeys: *string
streamValues: *[]string

for kv <- streamMap:
streamKeys <<- kv.key
streamValues <<- kv.value
<- streamKeys, streamValues
41 changes: 24 additions & 17 deletions integration-tests/src/__test__/examples.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ import {
testGetFuncCall,
testGetStreamFuncCall,
testKeysFuncCall,
testContainsFuncCall
testContainsFuncCall,
testForFuncCall
} from "../examples/streamMapCall.js";
import {
topologyBug205Call,
Expand Down Expand Up @@ -853,30 +854,36 @@ describe("Testing examples", () => {
});

it("streamMap.aqua get function call", async () => {
let [resEmpty, resFirst, resSecond] = await testGetFuncCall();
expect(resEmpty).toEqual([]);
expect(resFirst).toEqual(["first value"]);
expect(resSecond).toEqual(["first value", "second value"]);
});
let [resEmpty, resFirst, resSecond] = await testGetFuncCall();
expect(resEmpty).toEqual([]);
expect(resFirst).toEqual(["first value"]);
expect(resSecond).toEqual(["first value", "second value"]);
});

it("streamMap.aqua get stream function call", async () => {
let [resEmpty, resFirst, resSecond] = await testGetStreamFuncCall();
expect(resEmpty).toEqual([]);
expect(resFirst).toEqual("first value");
expect(resSecond).toEqual("second value");
let [resEmpty, resFirst, resSecond] = await testGetStreamFuncCall();
expect(resEmpty).toEqual([]);
expect(resFirst).toEqual("first value");
expect(resSecond).toEqual("second value");
});

it("streamMap.aqua keys function call", async () => {
let [resEmpty, resFirst, resSecond] = await testKeysFuncCall();
expect(resEmpty).toEqual([]);
expect(resFirst).toEqual(["key one"]);
expect(resSecond).toEqual(["key one", "key two"]);
let [resEmpty, resFirst, resSecond] = await testKeysFuncCall();
expect(resEmpty).toEqual([]);
expect(resFirst).toEqual(["key one"]);
expect(resSecond).toEqual(["key one", "key two"]);
});

it("streamMap.aqua contains function call", async () => {
let res = await testContainsFuncCall();
expect(res).toEqual([false, true, false, true, true]);
});
let res = await testContainsFuncCall();
expect(res).toEqual([false, true, false, true, true]);
});

it("streamMap.aqua call with for over map", async () => {
let [keys, values] = await testForFuncCall();
expect(keys).toEqual(["key one", "key two", "key three", "key four"]);
expect(values).toEqual([["1", "2"], ["3", "4", "5"], ["6"], ["7"]);
});

it("stream.aqua", async () => {
let streamResult = await streamCall();
Expand Down
6 changes: 5 additions & 1 deletion integration-tests/src/examples/streamMapCall.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
testGetFunc, testGetStreamFunc, testKeysFunc, testContainsFunc
testGetFunc, testGetStreamFunc, testKeysFunc, testContainsFunc, testForFunc
} from "../compiled/examples/streamMap.js";

export async function testGetFuncCall() {
Expand All @@ -18,3 +18,7 @@ export async function testContainsFuncCall() {
return testContainsFunc();
}

export async function testForFuncCall() {
return testForFunc();
}

Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ import cats.syntax.option.*

object ApplyStreamMapRawInliner {

private def getIterType(name: String, el: DataType) =
StructType(name, NonEmptyMap.of("key" -> ScalarType.string, "value" -> ArrayType(el)))

private def getStreamFromMapModel(
mapName: String,
mapType: StreamMapType,
Expand All @@ -28,7 +25,7 @@ object ApplyStreamMapRawInliner {
val mapVar = VarModel(mapName, mapType)
val arrayResultType = ArrayType(mapType.element)
val streamVar = VarModel(streamName, StreamType(arrayResultType))
val iter = VarModel(iterName, getIterType("iterName_type", mapType.element))
val iter = VarModel(iterName, mapType.iterType("iterName_type"))
ParModel.wrap(
ForModel(iter.name, mapVar, ForModel.Mode.Never).wrap(
XorModel.wrap(
Expand Down Expand Up @@ -67,7 +64,7 @@ object ApplyStreamMapRawInliner {
val arrayResultType = ArrayType(mapType.element)
val streamVar = VarModel(streamName, StreamType(ScalarType.string))
val canonMap = VarModel(canonName, CanonStreamMapType(arrayResultType))
val iter = VarModel(iterName, getIterType("iterName_type", mapType.element))
val iter = VarModel(iterName, mapType.iterType("iterName_type"))
val result = VarModel(resultName, CanonStreamType(ScalarType.string))
result -> RestrictionModel(streamVar.name, streamVar.`type`).wrap(
CanonicalizeModel(mapVar, CallModel.Export(canonMap)).leaf,
Expand Down
15 changes: 11 additions & 4 deletions semantics/src/main/scala/aqua/semantics/expr/func/ForSem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import aqua.raw.value.ValueRaw
import aqua.semantics.Prog
import aqua.semantics.rules.ValuesAlgebra
import aqua.semantics.rules.abilities.AbilitiesAlgebra
import aqua.semantics.rules.mangler.ManglerAlgebra
import aqua.semantics.rules.names.NamesAlgebra
import aqua.semantics.rules.types.TypesAlgebra
import aqua.types.*
Expand All @@ -26,8 +27,8 @@ class ForSem[S[_]](val expr: ForExpr[S]) extends AnyVal {
def program[F[_]: Monad](using
V: ValuesAlgebra[S, F],
N: NamesAlgebra[S, F],
T: TypesAlgebra[S, F],
A: AbilitiesAlgebra[S, F]
A: AbilitiesAlgebra[S, F],
M: ManglerAlgebra[F]
): Prog[F, Raw] =
Prog
.around(
Expand Down Expand Up @@ -81,12 +82,18 @@ object ForSem {
)(using
V: ValuesAlgebra[S, F],
N: NamesAlgebra[S, F],
T: TypesAlgebra[S, F]
M: ManglerAlgebra[F]
): F[Option[ValueRaw]] = (for {
value <- V.valueToIterable(iterable)
(raw, typ) = value
itemType <- typ match {
case smt: StreamMapType =>
val typeName = "-streamMapIter-"
OptionT.liftF(M.rename(typeName).map(s => smt.iterType(s)))
case _ => OptionT.some(typ.element)
}
_ <- OptionT.liftF(
N.define(item, typ.element)
N.define(item, itemType)
)
} yield raw).value
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import aqua.raw.value.ValueRaw
import aqua.semantics.Prog
import aqua.semantics.rules.ValuesAlgebra
import aqua.semantics.rules.abilities.AbilitiesAlgebra
import aqua.semantics.rules.mangler.ManglerAlgebra
import aqua.semantics.rules.names.NamesAlgebra
import aqua.semantics.rules.types.TypesAlgebra
import aqua.types.{ArrayType, CollectionType, StreamType}
Expand All @@ -26,7 +27,8 @@ class ParSeqSem[S[_]](val expr: ParSeqExpr[S]) extends AnyVal {
V: ValuesAlgebra[S, F],
N: NamesAlgebra[S, F],
T: TypesAlgebra[S, F],
A: AbilitiesAlgebra[S, F]
A: AbilitiesAlgebra[S, F],
M: ManglerAlgebra[F]
): Prog[F, Raw] =
Prog
.around(
Expand All @@ -49,10 +51,7 @@ class ParSeqSem[S[_]](val expr: ParSeqExpr[S]) extends AnyVal {
viaVM: List[ValueRaw],
ops: Raw
)(using
V: ValuesAlgebra[S, F],
N: NamesAlgebra[S, F],
T: TypesAlgebra[S, F],
A: AbilitiesAlgebra[S, F]
V: ValuesAlgebra[S, F]
): F[Raw] =
V.valueToRaw(expr.peerId).map((_, iterableVM, ops)).flatMap {
case (Some(peerId), Some(vm), FuncOp(op)) =>
Expand Down
3 changes: 3 additions & 0 deletions types/src/main/scala/aqua/types/Type.scala
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,9 @@ case class StreamMapType(override val element: DataType) extends MutableStreamTy
"contains" -> ArrowType(ProductType(ScalarType.string :: Nil), ProductType(ScalarType.bool :: Nil))
)

def iterType(name: String) =
StructType(name, NonEmptyMap.of("key" -> ScalarType.string, "value" -> ArrayType(element)))

}

object StreamMapType {
Expand Down

0 comments on commit b728af5

Please sign in to comment.