Fix incorrect compilation with arguments duplication (#211)

This commit is contained in:
Dima 2021-07-22 12:08:55 +03:00 committed by GitHub
parent c292ce05d7
commit f683a6b3cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 31 deletions

View File

@ -1,11 +1,8 @@
service OpH("op"):
get_str(s: string) -> string
get_arr() -> []string
identity: -> ⊥
service AquaDHT("aqua-dht"):
put_host_value(key: string, value: string, service_id: []string)
func registerKeyPutValue(node_id: string) -> []string:
nodes <- OpH.get_arr()
for n <- nodes par:
on n:
OpH.get_str(node_id)
<- nodes
func putHostValue(key: string, value: string, service_id: ?string):
AquaDHT.put_host_value(key, value, service_id)
func create_client_util(service_id: string):
putHostValue("client-util", service_id, nil)

View File

@ -1,6 +1,6 @@
package aqua.model.func
import aqua.model.func.raw.{AssignmentTag, CallArrowTag, CallServiceTag, FuncOp, RawTag}
import aqua.model.func.raw.{AssignmentTag, CallArrowTag, FuncOp, RawTag}
import aqua.model.{Model, ValueModel, VarModel}
import aqua.types.{ArrowType, Type}
import cats.Eval
@ -47,15 +47,21 @@ case class FuncCallable(
// Collect all arguments: what names are used inside the function, what values are received
val argsFull = args.call(call)
// DataType arguments
val argsToData = argsFull.dataArgs
val argsToDataRaw = argsFull.dataArgs
// Arrow arguments: expected type is Arrow, given by-name
val argsToArrows = argsFull.arrowArgs(arrows)
val argsToArrowsRaw = argsFull.arrowArgs(arrows)
// Find all duplicates in arguments
val argsShouldRename = findNewNames(forbiddenNames, (argsToDataRaw ++ argsToArrowsRaw).keySet)
val argsToData = argsToDataRaw.map { case (k, v) => argsShouldRename.getOrElse(k, k) -> v }
val argsToArrows = argsToArrowsRaw.map { case (k, v) => argsShouldRename.getOrElse(k, k) -> v }
// Going to resolve arrows: collect them all. Names should never collide: it's semantically checked
val allArrows = capturedArrows ++ argsToArrows
// Substitute arguments (referenced by name and optional lambda expressions) with values
val treeWithValues = body.resolveValues(argsToData)
// Also rename all renamed arguments in the body
val treeWithValues = body.rename(argsShouldRename).resolveValues(argsToData)
// Function body on its own defines some values; collect their names
val treeDefines = treeWithValues.definesVarNames.value -- call.exportTo.map(_.name)
@ -63,8 +69,7 @@ case class FuncCallable(
// We have some names in scope (forbiddenNames), can't introduce them again; so find new names
val shouldRename = findNewNames(forbiddenNames, treeDefines)
// If there was a collision, rename exports and usages with new names
val treeRenamed =
if (shouldRename.isEmpty) treeWithValues else treeWithValues.rename(shouldRename)
val treeRenamed = treeWithValues.rename(shouldRename)
// Result could be derived from arguments, or renamed; take care about that
val result = ret.map(_._1).map(_.resolveWith(argsToData)).map {

View File

@ -54,7 +54,10 @@ case class FuncOp(tree: Cofree[Chain, RawTag]) extends Model {
def resolveValues(vals: Map[String, ValueModel]): FuncOp =
FuncOp(tree.map[RawTag](_.mapValues(_.resolveWith(vals))))
def rename(vals: Map[String, String]): FuncOp =
def rename(vals: Map[String, String]): FuncOp = {
if (vals.isEmpty)
this
else
FuncOp(
tree.map[RawTag](op =>
op.mapValues {
@ -70,6 +73,7 @@ case class FuncOp(tree: Cofree[Chain, RawTag]) extends Model {
}
)
)
}
def :+:(prev: FuncOp): FuncOp =
FuncOp.RightAssocSemi.combine(prev, this)