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
asdasd: *string
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"
export GetStr, multiReturnFunc, Service as S
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
func someFunc(cb: []string -> ()):
ifaces: *string
cb(ifaces)

View File

@ -97,8 +97,10 @@ case class VarModel(name: String, `type`: Type, lambda: Chain[LambdaModel] = Cha
deriveFrom(vv)
}
case Some(vv) => vv // TODO check that lambda is empty, otherwise error
case None => this // Should not happen
case Some(vv) =>
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(".")}"

View File

@ -3,7 +3,7 @@ package aqua.model.func
import aqua.model.ValueModel.varName
import aqua.model.func.raw.*
import aqua.model.{Model, ValueModel, VarModel}
import aqua.types.{ArrayType, ArrowType, ProductType, StreamType, Type}
import aqua.types.*
import cats.Eval
import cats.data.Chain
import cats.free.Cofree
@ -64,6 +64,8 @@ case class FuncCallable(
// Find all duplicates in arguments
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 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
// 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
// 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.data.Chain
import cats.free.Cofree
import cats.instances.tuple.*
import cats.kernel.Semigroup
import cats.syntax.apply.*
import cats.syntax.functor.*
import cats.instances.tuple.*
case class FuncOp(tree: Cofree[Chain, RawTag]) extends Model {
def head: RawTag = tree.head

View File

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

View File

@ -1,11 +1,13 @@
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.semantics.Prog
import aqua.semantics.rules.names.NamesAlgebra
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
class DeclareStreamSem[F[_]](val expr: DeclareStreamExpr[F]) {
@ -18,19 +20,24 @@ class DeclareStreamSem[F[_]](val expr: DeclareStreamExpr[F]) {
T.resolveType(expr.`type`)
.flatMap {
case Some(t: StreamType) =>
N.define(expr.name, t)
N.define(expr.name, t).map(b => Option.when(b)(t))
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)) =>
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) =>
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 =>
Free.pure[Alg, Boolean](false)
Free.pure[Alg, Option[Type]](None)
}
.map {
case true => Model.empty(s"Name `${expr.name.value}` defined successfully")
case false => Model.error(s"Name `${expr.name.value}` not defined")
case Some(streamType) =>
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")
}
)