mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-12 09:45:32 +00:00
Fix incorrect compilation with arguments duplication (#211)
This commit is contained in:
parent
c292ce05d7
commit
f683a6b3cf
@ -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)
|
@ -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 {
|
||||
|
@ -54,22 +54,26 @@ 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 =
|
||||
FuncOp(
|
||||
tree.map[RawTag](op =>
|
||||
op.mapValues {
|
||||
case v: VarModel if vals.contains(v.name) => v.copy(name = vals(v.name))
|
||||
case v => v
|
||||
} match {
|
||||
case c: CallArrowTag => c.copy(call = c.call.mapExport(n => vals.getOrElse(n, n)))
|
||||
case c: CallServiceTag => c.copy(call = c.call.mapExport(n => vals.getOrElse(n, n)))
|
||||
case a: AssignmentTag => a.copy(assignTo = vals.getOrElse(a.assignTo, a.assignTo))
|
||||
case t: ForTag if vals.contains(t.item) => t.copy(item = vals(t.item))
|
||||
case t: NextTag if vals.contains(t.item) => t.copy(item = vals(t.item))
|
||||
case t => t
|
||||
}
|
||||
def rename(vals: Map[String, String]): FuncOp = {
|
||||
if (vals.isEmpty)
|
||||
this
|
||||
else
|
||||
FuncOp(
|
||||
tree.map[RawTag](op =>
|
||||
op.mapValues {
|
||||
case v: VarModel if vals.contains(v.name) => v.copy(name = vals(v.name))
|
||||
case v => v
|
||||
} match {
|
||||
case c: CallArrowTag => c.copy(call = c.call.mapExport(n => vals.getOrElse(n, n)))
|
||||
case c: CallServiceTag => c.copy(call = c.call.mapExport(n => vals.getOrElse(n, n)))
|
||||
case a: AssignmentTag => a.copy(assignTo = vals.getOrElse(a.assignTo, a.assignTo))
|
||||
case t: ForTag if vals.contains(t.item) => t.copy(item = vals(t.item))
|
||||
case t: NextTag if vals.contains(t.item) => t.copy(item = vals(t.item))
|
||||
case t => t
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
def :+:(prev: FuncOp): FuncOp =
|
||||
FuncOp.RightAssocSemi.combine(prev, this)
|
||||
|
Loading…
Reference in New Issue
Block a user