Skip to content

Commit

Permalink
feat(compiler): Abilities (#731)
Browse files Browse the repository at this point in the history
  • Loading branch information
DieMyst authored Jul 18, 2023
1 parent ca52e25 commit 63a9f42
Show file tree
Hide file tree
Showing 51 changed files with 1,134 additions and 436 deletions.
53 changes: 47 additions & 6 deletions aqua-src/antithesis.aqua
Original file line number Diff line number Diff line change
@@ -1,9 +1,50 @@
module Import3 declares *
aqua Main

export foo_bar
use DECLARE_CONST, decl_bar from "declare.aqua" as Declare

use "export.aqua"
export handleAb

func foo_bar() -> string, string:
z <- FooBars.foo()
<- z, FooBars.DECLARE_CONST2
service SomeService("wed"):
getStr(s: string) -> string

ability SomeAb:
someArrow(s: string) -> string, string
str: string

ability SecondAb:
arrow(s: string) -> string
num: u32

func funcStr(s: string) -> string, string:
strInFunc <- SomeService.getStr(Declare.DECLARE_CONST)
-- SomeService.getStr(s)
<- strInFunc, s

--
-- func diffFunc(s: string) -> string:
-- differentStr <- SomeService.different(s)
-- <- differentStr
--
-- func unit():
-- funcStr("")

-- func bbbbbbb()
--
-- func aaaaaa():
-- closure = (a: string) -> string:
-- <- SomeService.str()

func handleSecAb {SomeAb, SecondAb}() -> string, string:
SomeAb.someArrow("eferfrfrf")
b, c <- SomeAb.someArrow("efre")
<- b, c

func returnAb(s: string) -> SomeAb:
SomeAb = SomeAb(someArrow = funcStr, str = s)
<- SomeAb

func handleAb(fff: string) -> string, string:
SomeAb = returnAb(fff)
SecondAb = SecondAb(arrow = funcStr, num = 12)
d, g <- handleSecAb{SomeAb, SecondAb}()
<- d, g
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ object TypeDefinition {
case t: BoxType => ArrayTypeDef(TypeDefinition(t.element))
case StructType(name, fields) =>
StructTypeDef(name, fields.toSortedMap.view.mapValues(TypeDefinition.apply).toMap)
case AbilityType(name, fieldAndArrows) =>
// TODO: change in union with JS side
StructTypeDef(name, fieldAndArrows.toSortedMap.view.mapValues(TypeDefinition.apply).toMap)
case t: ScalarType => ScalarTypeDef.fromScalar(t)
case t: LiteralType => ScalarTypeDef.fromLiteral(t)
case t: ProductType => ProductTypeDef(t)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package aqua.backend.ts

import aqua.backend.air.FuncAirGen
import aqua.res.FuncRes
import aqua.types.*
import cats.syntax.show.*
Expand Down Expand Up @@ -36,13 +35,14 @@ object TypeScriptCommon {
"[" + pt.toList.map(typeToTs).mkString(", ") + "]"
case st: StructType =>
s"{ ${st.fields.map(typeToTs).toNel.map(kv => kv._1 + ": " + kv._2 + ";").toList.mkString(" ")} }"
case st: AbilityType =>
s"{ ${st.fields.map(typeToTs).toNel.map(kv => kv._1 + ": " + kv._2 + ";").toList.mkString(" ")} }"
case st: ScalarType if ScalarType.number(st) => "number"
case ScalarType.bool => "boolean"
case ScalarType.string => "string"
case lt: LiteralType if lt.oneOf.exists(ScalarType.number) => "number"
case lt: LiteralType if lt.oneOf(ScalarType.bool) => "boolean"
case lt: LiteralType if lt.oneOf(ScalarType.string) => "string"
case _: DataType => "any"
case at: ArrowType => fnDef(at)
}

Expand Down
49 changes: 25 additions & 24 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ lazy val cli = crossProject(JSPlatform, JVMPlatform)
.crossType(CrossType.Pure)
.in(file("cli/cli"))
.enablePlugins(GraalVMNativeImagePlugin)
.settings(commons: _*)
.settings(commons)
.settings(
Compile / mainClass := Some("aqua.AquaCli"),
graalVMNativeImageOptions ++= Seq(
Expand Down Expand Up @@ -92,13 +92,13 @@ lazy val `aqua-run` = crossProject(JSPlatform, JVMPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("aqua-run"))
.settings(commons: _*)
.settings(commons)
.dependsOn(compiler, `backend-air`, `backend-ts`, io, definitions, logging, constants)

lazy val io = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.settings(commons: _*)
.settings(commons)
.settings(
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-effect" % catsEffectV,
Expand All @@ -113,7 +113,7 @@ lazy val `language-server-api` = crossProject(JSPlatform, JVMPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("language-server/language-server-api"))
.settings(commons: _*)
.settings(commons)
.settings(
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-effect" % catsEffectV,
Expand All @@ -135,20 +135,20 @@ lazy val `language-server-apiJS` = `language-server-api`.js
lazy val `js-exports` = project
.in(file("js/js-exports"))
.enablePlugins(ScalaJSPlugin)
.settings(commons: _*)
.settings(commons)
.dependsOn(`backend`.js, definitions.js)

lazy val `js-imports` = project
.in(file("js/js-imports"))
.enablePlugins(ScalaJSPlugin)
.settings(commons: _*)
.settings(commons)
.dependsOn(`js-exports`, transform.js)

lazy val `aqua-api` = crossProject(JSPlatform, JVMPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("api/api"))
.settings(commons: _*)
.settings(commons)
.dependsOn(`aqua-run`, `backend-api`)

lazy val `aqua-apiJS` = `aqua-api`.js
Expand All @@ -175,7 +175,7 @@ lazy val types = crossProject(JVMPlatform, JSPlatform)
lazy val parser = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.settings(commons: _*)
.settings(commons)
.settings(
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-parse" % catsParseV,
Expand All @@ -187,14 +187,14 @@ lazy val parser = crossProject(JVMPlatform, JSPlatform)
lazy val linker = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.settings(commons: _*)
.settings(commons)
.dependsOn(parser)

lazy val tree = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("model/tree"))
.settings(commons: _*)
.settings(commons)
.settings(
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-free" % catsV
Expand All @@ -205,40 +205,41 @@ lazy val raw = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("model/raw"))
.settings(commons: _*)
.settings(commons)
.dependsOn(types, tree)

lazy val model = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.settings(commons: _*)
.settings(commons)
.dependsOn(types, tree, raw)

lazy val res = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("model/res"))
.settings(commons: _*)
.settings(commons)
.dependsOn(model)

lazy val inline = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("model/inline"))
.settings(commons: _*)
.settings(commons)
.dependsOn(raw, model)


lazy val transform = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("model/transform"))
.settings(commons: _*)
.settings(commons)
.dependsOn(model, res, inline, res % "test->test")

lazy val semantics = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.settings(commons: _*)
.settings(commons)
.settings(
libraryDependencies ++= Seq(
"dev.optics" %%% "monocle-core" % monocleV,
Expand All @@ -251,14 +252,14 @@ lazy val compiler = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("compiler"))
.settings(commons: _*)
.settings(commons)
.dependsOn(semantics, linker, backend, transform % "test->test", res % "test->test")

lazy val backend = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("backend"))
.settings(commons: _*)
.settings(commons)
.enablePlugins(BuildInfoPlugin)
.settings(
buildInfoKeys := Seq[BuildInfoKey](version),
Expand All @@ -270,7 +271,7 @@ lazy val definitions = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("backend/definitions"))
.settings(commons: _*)
.settings(commons)
.settings(
libraryDependencies ++= Seq(
"io.circe" %%% "circe-core",
Expand All @@ -284,7 +285,7 @@ lazy val logging = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("utils/logging"))
.settings(commons: _*)
.settings(commons)
.settings(
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-core" % catsV
Expand All @@ -295,7 +296,7 @@ lazy val constants = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("utils/constants"))
.settings(commons: _*)
.settings(commons)
.settings(
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-core" % catsV
Expand All @@ -307,21 +308,21 @@ lazy val `backend-air` = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("backend/air"))
.settings(commons: _*)
.settings(commons)
.dependsOn(backend, transform)

lazy val `backend-api` = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("backend/api"))
.settings(commons: _*)
.settings(commons)
.dependsOn(backend, transform, `backend-air`)

lazy val `backend-ts` = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("backend/ts"))
.settings(commons: _*)
.settings(commons)
.settings(
libraryDependencies ++= Seq(
"io.circe" %%% "circe-core",
Expand Down
37 changes: 37 additions & 0 deletions integration-tests/aqua/examples/abilities.aqua
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
aqua Main

use DECLARE_CONST, decl_bar from "imports_exports/declare.aqua" as Declare

export handleAb, SomeService

service SomeService("wed"):
getStr(s: string) -> string

ability SomeAb:
someArrow(s: string) -> string, string
str: string

ability SecondAb:
arrow(s: string) -> string
num: u32

func funcStr(s: string) -> string, string:
strInFunc <- SomeService.getStr(Declare.DECLARE_CONST)
strInFunc2 <- SomeService.getStr(s)
<- strInFunc, strInFunc2

func handleSecAb {SomeAb, SecondAb}() -> string, string, string, u32:
SomeAb.someArrow("eferfrfrf")
b, c <- SomeAb.someArrow("efre")
d <- SecondAb.arrow(SomeAb.str)
<- b, c, d, SecondAb.num

func returnAb(s: string) -> SomeAb:
SomeAb = SomeAb(someArrow = funcStr, str = s)
<- SomeAb

func handleAb(fff: string) -> string, string, string, u32:
SomeAb = returnAb(fff)
SecondAb = SecondAb(arrow = funcStr, num = 12)
res1, res2, res3, res4 <- handleSecAb{SomeAb, SecondAb}()
<- res1, res2, res3, res4
6 changes: 6 additions & 0 deletions integration-tests/src/__test__/examples.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export const relay2 = config.relays[1]
const relayPeerId2 = relay2.peerId

import log from 'loglevel';
import {abilityCall} from "../examples/abilityCall";
// log.setDefaultLevel("debug")

async function start() {
Expand Down Expand Up @@ -313,6 +314,11 @@ describe('Testing examples', () => {
});
});

it('ability.aqua', async () => {
let result = await abilityCall();
expect(result).toStrictEqual(['declare_const123', "efre123", "declare_const123", 12]);
});

it('functors.aqua LNG-119 bug', async () => {
let result = await bugLng119Call();
expect(result).toEqual([1]);
Expand Down
11 changes: 11 additions & 0 deletions integration-tests/src/examples/abilityCall.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {handleAb, registerSomeService} from "../compiled/examples/abilities";

export async function abilityCall(): Promise<[string, string, string, number]> {
registerSomeService({
getStr: (s: string) => {
return s + "123"
}
})

return await handleAb("some_string")
}
Loading

0 comments on commit 63a9f42

Please sign in to comment.