mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 22:50:18 +00:00
Imports/exports fixes (#258)
* Fix for export in headerless file * Ability arrow resolution bugfix * Trying to reproduce a bug * Allow dots in module declaration
This commit is contained in:
parent
bc461457da
commit
3e7b11db10
16
aqua-src/export.aqua
Normal file
16
aqua-src/export.aqua
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
module Export.Test declares foobar, foo, bar
|
||||||
|
|
||||||
|
func bar() -> string:
|
||||||
|
<- " I am MyFooBar bar"
|
||||||
|
|
||||||
|
func foo() -> string:
|
||||||
|
<- "I am MyFooBar foo"
|
||||||
|
|
||||||
|
func foobar() -> []string:
|
||||||
|
res: *string
|
||||||
|
res <- foo()
|
||||||
|
res <- bar()
|
||||||
|
<- res
|
||||||
|
|
||||||
|
service ExpSrv:
|
||||||
|
baz()
|
3
aqua-src/gen/OneMore.aqua
Normal file
3
aqua-src/gen/OneMore.aqua
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
service OneMore:
|
||||||
|
more_call()
|
||||||
|
consume(s: string)
|
23
aqua-src/import.aqua
Normal file
23
aqua-src/import.aqua
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
-- import.aqua
|
||||||
|
module Import.Test
|
||||||
|
import foobar from "export.aqua"
|
||||||
|
|
||||||
|
use foo as f from "export.aqua" as Exp
|
||||||
|
|
||||||
|
use "export.aqua"
|
||||||
|
|
||||||
|
import "gen/OneMore.aqua"
|
||||||
|
|
||||||
|
import OneMore as OM from "gen/OneMore.aqua"
|
||||||
|
|
||||||
|
export foo_wrapper as wrap, foobar as barfoo
|
||||||
|
|
||||||
|
func foo_wrapper() -> string:
|
||||||
|
z <- Exp.f()
|
||||||
|
q <- Export.Test.bar()
|
||||||
|
OneMore "hello"
|
||||||
|
OneMore.more_call()
|
||||||
|
OM "ohmygod"
|
||||||
|
OM.more_call()
|
||||||
|
OM.consume(q)
|
||||||
|
<- z
|
@ -17,7 +17,7 @@ val declineV = "2.1.0"
|
|||||||
name := "aqua-hll"
|
name := "aqua-hll"
|
||||||
|
|
||||||
val commons = Seq(
|
val commons = Seq(
|
||||||
baseAquaVersion := "0.2.0",
|
baseAquaVersion := "0.2.1",
|
||||||
version := baseAquaVersion.value + "-" + sys.env.getOrElse("BUILD_NUMBER", "SNAPSHOT"),
|
version := baseAquaVersion.value + "-" + sys.env.getOrElse("BUILD_NUMBER", "SNAPSHOT"),
|
||||||
scalaVersion := dottyVersion,
|
scalaVersion := dottyVersion,
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
|
@ -5,6 +5,7 @@ import aqua.model.func.{ArgsCall, FuncCallable, FuncModel}
|
|||||||
import aqua.types.{StructType, Type}
|
import aqua.types.{StructType, Type}
|
||||||
import cats.Monoid
|
import cats.Monoid
|
||||||
import cats.data.NonEmptyMap
|
import cats.data.NonEmptyMap
|
||||||
|
import cats.kernel.Semigroup
|
||||||
import cats.syntax.functor.*
|
import cats.syntax.functor.*
|
||||||
import cats.syntax.monoid.*
|
import cats.syntax.monoid.*
|
||||||
import scribe.Logging
|
import scribe.Logging
|
||||||
@ -150,37 +151,34 @@ object AquaContext extends Logging {
|
|||||||
)
|
)
|
||||||
|
|
||||||
def fromScriptModel(sm: ScriptModel, init: AquaContext)(implicit
|
def fromScriptModel(sm: ScriptModel, init: AquaContext)(implicit
|
||||||
aqum: Monoid[AquaContext]
|
aqum: Semigroup[AquaContext]
|
||||||
): AquaContext =
|
): AquaContext =
|
||||||
sm.models
|
sm.models
|
||||||
.foldLeft((init, Monoid.empty[AquaContext])) {
|
.foldLeft((init, blank)) {
|
||||||
case ((ctx, exportContext), c: ConstantModel) =>
|
case ((ctx, exportContext), c: ConstantModel) =>
|
||||||
val add =
|
val add =
|
||||||
Monoid
|
blank
|
||||||
.empty[AquaContext]
|
|
||||||
.copy(values =
|
.copy(values =
|
||||||
if (c.allowOverrides && ctx.values.contains(c.name)) ctx.values
|
if (c.allowOverrides && ctx.values.contains(c.name)) Map.empty
|
||||||
else ctx.values.updated(c.name, c.value.resolveWith(ctx.values))
|
else Map(c.name -> c.value.resolveWith(ctx.values))
|
||||||
)
|
)
|
||||||
(ctx |+| add, exportContext |+| add)
|
(ctx |+| add, exportContext |+| add)
|
||||||
case ((ctx, exportContext), func: FuncModel) =>
|
case ((ctx, exportContext), func: FuncModel) =>
|
||||||
val fr = func.capture(ctx.allFuncs(), ctx.allValues())
|
val fr = func.capture(ctx.allFuncs(), ctx.allValues())
|
||||||
val add =
|
val add =
|
||||||
Monoid.empty[AquaContext].copy(funcs = ctx.funcs.updated(func.name, fr))
|
blank.copy(funcs = Map(func.name -> fr))
|
||||||
(ctx |+| add, exportContext |+| add)
|
(ctx |+| add, exportContext |+| add)
|
||||||
case ((ctx, exportContext), t: TypeModel) =>
|
case ((ctx, exportContext), t: TypeModel) =>
|
||||||
val add =
|
val add =
|
||||||
Monoid.empty[AquaContext].copy(types = ctx.types.updated(t.name, t.`type`))
|
blank.copy(types = Map(t.name -> t.`type`))
|
||||||
(ctx |+| add, exportContext |+| add)
|
(ctx |+| add, exportContext |+| add)
|
||||||
case ((ctx, exportContext), m: ServiceModel) =>
|
case ((ctx, exportContext), m: ServiceModel) =>
|
||||||
val add =
|
val add =
|
||||||
Monoid
|
blank
|
||||||
.empty[AquaContext]
|
|
||||||
.copy(
|
.copy(
|
||||||
abilities = m.defaultId.fold(ctx.abilities)(id =>
|
abilities =
|
||||||
ctx.abilities.updated(m.name, fromServiceModel(m, id))
|
m.defaultId.fold(Map.empty)(id => Map(m.name -> fromServiceModel(m, id))),
|
||||||
),
|
services = Map(m.name -> m)
|
||||||
services = ctx.services.updated(m.name, m)
|
|
||||||
)
|
)
|
||||||
(ctx |+| add, exportContext |+| add)
|
(ctx |+| add, exportContext |+| add)
|
||||||
case (ce, _) => ce
|
case (ce, _) => ce
|
||||||
|
@ -40,7 +40,7 @@ object ModuleExpr extends HeaderExpr.Leaf {
|
|||||||
nameOrAbList[F].map(Left(_)) | `star`.lift.map(Token.lift(_)).map(Right(_))
|
nameOrAbList[F].map(Left(_)) | `star`.lift.map(Token.lift(_)).map(Right(_))
|
||||||
|
|
||||||
override def p[F[_]: LiftParser: Comonad]: Parser[ModuleExpr[F]] =
|
override def p[F[_]: LiftParser: Comonad]: Parser[ModuleExpr[F]] =
|
||||||
(`module` *> ` ` *> Ability.ab[F] ~
|
(`module` *> ` ` *> Ability.dotted[F] ~
|
||||||
(` declares ` *> nameOrAbListOrAll[F]).?).map {
|
(` declares ` *> nameOrAbListOrAll[F]).?).map {
|
||||||
case (name, None) =>
|
case (name, None) =>
|
||||||
ModuleExpr(name, None, Nil, Nil)
|
ModuleExpr(name, None, Nil, Nil)
|
||||||
|
@ -13,11 +13,16 @@ import cats.syntax.semigroup.*
|
|||||||
import cats.instances.list.*
|
import cats.instances.list.*
|
||||||
import cats.instances.option.*
|
import cats.instances.option.*
|
||||||
import cats.free.Cofree
|
import cats.free.Cofree
|
||||||
|
import cats.kernel.Semigroup
|
||||||
|
|
||||||
case class HeaderSem[S[_]](
|
case class HeaderSem[S[_]](
|
||||||
initCtx: AquaContext,
|
initCtx: AquaContext,
|
||||||
finCtx: AquaContext => ValidatedNec[SemanticError[S], AquaContext]
|
finInitCtx: (AquaContext, AquaContext) => ValidatedNec[SemanticError[S], AquaContext]
|
||||||
)
|
) {
|
||||||
|
|
||||||
|
def finCtx: AquaContext => ValidatedNec[SemanticError[S], AquaContext] =
|
||||||
|
finInitCtx(_, initCtx)
|
||||||
|
}
|
||||||
|
|
||||||
object HeaderSem {
|
object HeaderSem {
|
||||||
type Res[S[_]] = ValidatedNec[SemanticError[S], HeaderSem[S]]
|
type Res[S[_]] = ValidatedNec[SemanticError[S], HeaderSem[S]]
|
||||||
@ -27,12 +32,12 @@ object HeaderSem {
|
|||||||
acm: Monoid[AquaContext]
|
acm: Monoid[AquaContext]
|
||||||
): Monoid[HeaderSem[S]] =
|
): Monoid[HeaderSem[S]] =
|
||||||
new Monoid[HeaderSem[S]] {
|
new Monoid[HeaderSem[S]] {
|
||||||
override def empty: HeaderSem[S] = HeaderSem(acm.empty, validNec(_))
|
override def empty: HeaderSem[S] = HeaderSem(acm.empty, (c, _) => validNec(c))
|
||||||
|
|
||||||
override def combine(a: HeaderSem[S], b: HeaderSem[S]): HeaderSem[S] =
|
override def combine(a: HeaderSem[S], b: HeaderSem[S]): HeaderSem[S] =
|
||||||
HeaderSem(
|
HeaderSem(
|
||||||
a.initCtx |+| b.initCtx,
|
a.initCtx |+| b.initCtx,
|
||||||
a.finCtx.andThen(_.andThen(b.finCtx))
|
(c, i) => a.finInitCtx(c, i).andThen(b.finInitCtx(_, i))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +74,7 @@ object HeaderSem {
|
|||||||
.getOrElse(
|
.getOrElse(
|
||||||
error(
|
error(
|
||||||
n,
|
n,
|
||||||
s"Imported file declares [${ctx.declares.mkString(", ")}], no ${n.value} declared. Try adding `declares *` to that file."
|
s"Imported file `declares ${ctx.declares.mkString(", ")}`, no ${n.value} declared. Try adding `declares ${n.value}` to that file."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -80,7 +85,7 @@ object HeaderSem {
|
|||||||
.getOrElse(
|
.getOrElse(
|
||||||
error(
|
error(
|
||||||
n,
|
n,
|
||||||
s"Imported file declares [${ctx.declares.mkString(", ")}], no ${n.value} declared. Try adding `declares *` to that file."
|
s"Imported file `declares ${ctx.declares.mkString(", ")}`, no ${n.value} declared. Try adding `declares ${n.value}` to that file."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -112,7 +117,7 @@ object HeaderSem {
|
|||||||
module = Some(name.value),
|
module = Some(name.value),
|
||||||
declares = shouldDeclare
|
declares = shouldDeclare
|
||||||
),
|
),
|
||||||
ctx =>
|
(ctx, _) =>
|
||||||
// When file is handled, check that all the declarations exists
|
// When file is handled, check that all the declarations exists
|
||||||
if (declareAll.nonEmpty)
|
if (declareAll.nonEmpty)
|
||||||
validNec(
|
validNec(
|
||||||
@ -144,25 +149,25 @@ object HeaderSem {
|
|||||||
|
|
||||||
case f @ ImportExpr(_) =>
|
case f @ ImportExpr(_) =>
|
||||||
// Import everything from a file
|
// Import everything from a file
|
||||||
resolve(f).map(fc => HeaderSem[S](fc, validNec(_)))
|
resolve(f).map(fc => HeaderSem[S](fc, (c, _) => validNec(c)))
|
||||||
case f @ ImportFromExpr(_, _) =>
|
case f @ ImportFromExpr(_, _) =>
|
||||||
// Import, map declarations
|
// Import, map declarations
|
||||||
resolve(f)
|
resolve(f)
|
||||||
.andThen(getFrom(f, _))
|
.andThen(getFrom(f, _))
|
||||||
.map(ctx => HeaderSem[S](ctx, validNec(_)))
|
.map(ctx => HeaderSem[S](ctx, (c, _) => validNec(c)))
|
||||||
|
|
||||||
case f @ UseExpr(_, asModule) =>
|
case f @ UseExpr(_, asModule) =>
|
||||||
// Import, move into a module scope
|
// Import, move into a module scope
|
||||||
resolve(f)
|
resolve(f)
|
||||||
.andThen(toModule(_, f.token, asModule))
|
.andThen(toModule(_, f.token, asModule))
|
||||||
.map(fc => HeaderSem[S](fc, validNec(_)))
|
.map(fc => HeaderSem[S](fc, (c, _) => validNec(c)))
|
||||||
|
|
||||||
case f @ UseFromExpr(_, _, asModule) =>
|
case f @ UseFromExpr(_, _, asModule) =>
|
||||||
// Import, cherry-pick declarations, move to a module scope
|
// Import, cherry-pick declarations, move to a module scope
|
||||||
resolve(f)
|
resolve(f)
|
||||||
.andThen(getFrom(f, _))
|
.andThen(getFrom(f, _))
|
||||||
.andThen(toModule(_, f.token, Some(asModule)))
|
.andThen(toModule(_, f.token, Some(asModule)))
|
||||||
.map(fc => HeaderSem[S](fc, validNec(_)))
|
.map(fc => HeaderSem[S](fc, (c, _) => validNec(c)))
|
||||||
|
|
||||||
case ExportExpr(pubs) =>
|
case ExportExpr(pubs) =>
|
||||||
// Save exports, finally handle them
|
// Save exports, finally handle them
|
||||||
@ -170,12 +175,12 @@ object HeaderSem {
|
|||||||
HeaderSem[S](
|
HeaderSem[S](
|
||||||
// Nothing there
|
// Nothing there
|
||||||
acm.empty,
|
acm.empty,
|
||||||
ctx =>
|
(ctx, initCtx) =>
|
||||||
pubs
|
pubs
|
||||||
.map(
|
.map(
|
||||||
_.fold(
|
_.fold(
|
||||||
{ case (n, rn) =>
|
{ case (n, rn) =>
|
||||||
ctx
|
(initCtx |+| ctx)
|
||||||
.pick(n.value, rn.map(_.value), declared = false)
|
.pick(n.value, rn.map(_.value), declared = false)
|
||||||
.map(validNec)
|
.map(validNec)
|
||||||
.getOrElse(
|
.getOrElse(
|
||||||
@ -183,7 +188,7 @@ object HeaderSem {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{ case (n, rn) =>
|
{ case (n, rn) =>
|
||||||
ctx
|
(initCtx |+| ctx)
|
||||||
.pick(n.value, rn.map(_.value), declared = false)
|
.pick(n.value, rn.map(_.value), declared = false)
|
||||||
.map(validNec)
|
.map(validNec)
|
||||||
.getOrElse(
|
.getOrElse(
|
||||||
@ -198,11 +203,11 @@ object HeaderSem {
|
|||||||
)
|
)
|
||||||
|
|
||||||
case HeadExpr(token) =>
|
case HeadExpr(token) =>
|
||||||
// Old file exports everything
|
// Old file exports everything that it declares
|
||||||
validNec(HeaderSem[S](acm.empty, ctx => validNec(ctx.copy(exports = Some(ctx)))))
|
validNec(HeaderSem[S](acm.empty, (ctx, _) => validNec(ctx.copy(exports = Some(ctx)))))
|
||||||
|
|
||||||
case f: FilenameExpr[S] =>
|
case f: FilenameExpr[S] =>
|
||||||
resolve(f).map(fc => HeaderSem[S](fc, validNec(_)))
|
resolve(f).map(fc => HeaderSem[S](fc, (c, _) => validNec(c)))
|
||||||
}
|
}
|
||||||
|
|
||||||
Cofree
|
Cofree
|
||||||
|
@ -62,7 +62,7 @@ class AbilitiesInterpreter[F[_], X](implicit
|
|||||||
s"Ability is found, but arrow is undefined, available: ${abCtx.funcs.keys.toList
|
s"Ability is found, but arrow is undefined, available: ${abCtx.funcs.keys.toList
|
||||||
.mkString(", ")}"
|
.mkString(", ")}"
|
||||||
).as(Option.empty[ArrowType])
|
).as(Option.empty[ArrowType])
|
||||||
)(a => State.pure(Some(a)))
|
)(fn => State.pure(Some(fn.arrowType)))
|
||||||
case None =>
|
case None =>
|
||||||
report(ga.name, "Ability with this name is undefined").as(Option.empty[ArrowType])
|
report(ga.name, "Ability with this name is undefined").as(Option.empty[ArrowType])
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,9 @@ case class ArrowType(domain: ProductType, codomain: ProductType) extends Type {
|
|||||||
s"$domain -> $codomain"
|
s"$domain -> $codomain"
|
||||||
}
|
}
|
||||||
|
|
||||||
case class StreamType(element: Type) extends BoxType
|
case class StreamType(element: Type) extends BoxType {
|
||||||
|
override def toString: String = s"*$element"
|
||||||
|
}
|
||||||
|
|
||||||
object Type {
|
object Type {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user