Pass stream arguments to callbacks properly (#350)

* add DeclareStreamTag

* some fixes

* fix

* intersect argsToRename and streamToRename to fix excess renaming

Co-authored-by: dmitry <dmitry@fluence.one>
This commit is contained in:
Dima 2021-11-02 12:26:00 +03:00 committed by GitHub
parent 5dd4ea6b0f
commit 73f46c6897
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 38 additions and 44 deletions

View File

@ -12,4 +12,4 @@ func invalid_append() -> *string:
str: *string str: *string
asdasd: *string asdasd: *string
GetStr.retStr(stream, nil) GetStr.retStr(stream, nil)
<- streem <- stream

View File

@ -1,31 +1,7 @@
module Ret module Ret declares *
import Service from "service" export someFunc
use "error.aqua" func someFunc(cb: []string -> ()):
export GetStr, multiReturnFunc, Service as S ifaces: *string
cb(ifaces)
service GetStr("multiret-test"):
retStr: string -> string
service GetNum("multiret-num"):
retNum: -> u8
const SOME_NUM = 5
const SOME_STR = "some-str"
func tupleFunc() -> string, u8:
str <- GetStr.retStr(SOME_STR)
n <- GetNum.retNum()
Err.Peer.is_connected("Connected?")
<- str, n
func multiReturnFunc(somethingToReturn: []u8, smthOption: ?string) -> []string, u8, string, []u8, ?string, u8:
res: *string
res <- GetStr.retStr(SOME_STR)
try:
res <- GetStr.retStr("random-str")
catch e:
GetStr.retStr(e.msg)
res, tNum <- tupleFunc()
<- res, 5, SOME_STR, somethingToReturn, smthOption, tNum

View File

@ -97,8 +97,10 @@ case class VarModel(name: String, `type`: Type, lambda: Chain[LambdaModel] = Cha
deriveFrom(vv) deriveFrom(vv)
} }
case Some(vv) => vv // TODO check that lambda is empty, otherwise error case Some(vv) =>
case None => this // Should not happen vv // TODO check that lambda is empty, otherwise error
case None =>
this // Should not happen
} }
override def toString(): String = s"var{$name: " + `type` + s"}.${lambda.toList.mkString(".")}" override def toString(): String = s"var{$name: " + `type` + s"}.${lambda.toList.mkString(".")}"

View File

@ -3,7 +3,7 @@ package aqua.model.func
import aqua.model.ValueModel.varName import aqua.model.ValueModel.varName
import aqua.model.func.raw.* import aqua.model.func.raw.*
import aqua.model.{Model, ValueModel, VarModel} import aqua.model.{Model, ValueModel, VarModel}
import aqua.types.{ArrayType, ArrowType, ProductType, StreamType, Type} import aqua.types.*
import cats.Eval import cats.Eval
import cats.data.Chain import cats.data.Chain
import cats.free.Cofree import cats.free.Cofree
@ -64,6 +64,8 @@ case class FuncCallable(
// Find all duplicates in arguments // Find all duplicates in arguments
val argsShouldRename = findNewNames(forbiddenNames, (argsToDataRaw ++ argsToArrowsRaw).keySet) val argsShouldRename = findNewNames(forbiddenNames, (argsToDataRaw ++ argsToArrowsRaw).keySet)
// we shoudln't rename arguments that will be renamed by 'streamToRename'
.filter{case (k, _) => !streamToRename.contains(k)}
val argsToData = argsToDataRaw.map { case (k, v) => argsShouldRename.getOrElse(k, k) -> v } val argsToData = argsToDataRaw.map { case (k, v) => argsShouldRename.getOrElse(k, k) -> v }
val argsToArrows = argsToArrowsRaw.map { case (k, v) => argsShouldRename.getOrElse(k, k) -> v } val argsToArrows = argsToArrowsRaw.map { case (k, v) => argsShouldRename.getOrElse(k, k) -> v }
@ -72,7 +74,8 @@ case class FuncCallable(
// Substitute arguments (referenced by name and optional lambda expressions) with values // Substitute arguments (referenced by name and optional lambda expressions) with values
// Also rename all renamed arguments in the body // Also rename all renamed arguments in the body
val treeWithValues = body.rename(argsShouldRename ++ streamToRename).resolveValues(argsToData) val treeWithValues =
body.rename(argsShouldRename).resolveValues(argsToData).rename(streamToRename)
// Function body on its own defines some values; collect their names // Function body on its own defines some values; collect their names
// except stream arguments. They should be already renamed // except stream arguments. They should be already renamed

View File

@ -5,10 +5,10 @@ import aqua.model.{Model, ValueModel, VarModel}
import cats.Eval import cats.Eval
import cats.data.Chain import cats.data.Chain
import cats.free.Cofree import cats.free.Cofree
import cats.instances.tuple.*
import cats.kernel.Semigroup import cats.kernel.Semigroup
import cats.syntax.apply.* import cats.syntax.apply.*
import cats.syntax.functor.* import cats.syntax.functor.*
import cats.instances.tuple.*
case class FuncOp(tree: Cofree[Chain, RawTag]) extends Model { case class FuncOp(tree: Cofree[Chain, RawTag]) extends Model {
def head: RawTag = tree.head def head: RawTag = tree.head

View File

@ -34,6 +34,8 @@ sealed trait RawTag {
) )
case AssignmentTag(value, assignTo) => case AssignmentTag(value, assignTo) =>
AssignmentTag(f(value), assignTo) AssignmentTag(f(value), assignTo)
case DeclareStreamTag(value) =>
DeclareStreamTag(f(value))
case AbilityIdTag(value, ability) => case AbilityIdTag(value, ability) =>
AbilityIdTag(f(value), ability) AbilityIdTag(f(value), ability)
case _ => this case _ => this
@ -74,6 +76,10 @@ case class CallArrowTag(
call: Call call: Call
) extends RawTag ) extends RawTag
case class DeclareStreamTag(
value: ValueModel
) extends NoExecTag
case class AssignmentTag( case class AssignmentTag(
value: ValueModel, value: ValueModel,
assignTo: String assignTo: String

View File

@ -1,11 +1,13 @@
package aqua.semantics.expr package aqua.semantics.expr
import aqua.model.Model import aqua.model.func.raw.{DeclareStreamTag, FuncOp}
import aqua.model.{Model, VarModel}
import aqua.parser.expr.DeclareStreamExpr import aqua.parser.expr.DeclareStreamExpr
import aqua.semantics.Prog import aqua.semantics.Prog
import aqua.semantics.rules.names.NamesAlgebra import aqua.semantics.rules.names.NamesAlgebra
import aqua.semantics.rules.types.TypesAlgebra import aqua.semantics.rules.types.TypesAlgebra
import aqua.types.{ArrayType, OptionType, StreamType} import aqua.types.{ArrayType, OptionType, StreamType, Type}
import cats.data.Chain
import cats.free.Free import cats.free.Free
class DeclareStreamSem[F[_]](val expr: DeclareStreamExpr[F]) { class DeclareStreamSem[F[_]](val expr: DeclareStreamExpr[F]) {
@ -18,19 +20,24 @@ class DeclareStreamSem[F[_]](val expr: DeclareStreamExpr[F]) {
T.resolveType(expr.`type`) T.resolveType(expr.`type`)
.flatMap { .flatMap {
case Some(t: StreamType) => case Some(t: StreamType) =>
N.define(expr.name, t) N.define(expr.name, t).map(b => Option.when(b)(t))
case Some(t: OptionType) => case Some(t: OptionType) =>
N.define(expr.name, StreamType(t.element)) val streamType = StreamType(t.element)
N.define(expr.name, streamType).map(b => Option.when(b)(streamType))
case Some(at @ ArrayType(t)) => case Some(at @ ArrayType(t)) =>
T.ensureTypeMatches(expr.`type`, StreamType(t), at) val streamType = StreamType(t)
T.ensureTypeMatches(expr.`type`, streamType, at).map(b => Option.when(b)(streamType))
case Some(t) => case Some(t) =>
T.ensureTypeMatches(expr.`type`, StreamType(t), t) val streamType = StreamType(t)
T.ensureTypeMatches(expr.`type`, streamType, t).map(b => Option.when(b)(streamType))
case None => case None =>
Free.pure[Alg, Boolean](false) Free.pure[Alg, Option[Type]](None)
} }
.map { .map {
case true => Model.empty(s"Name `${expr.name.value}` defined successfully") case Some(streamType) =>
case false => Model.error(s"Name `${expr.name.value}` not defined") val valueModel = VarModel(expr.name.value, streamType, Chain.empty)
FuncOp.leaf(DeclareStreamTag(valueModel)): Model
case None => Model.error(s"Name `${expr.name.value}` not defined")
} }
) )