diff --git a/aqua-src/demo.aqua b/aqua-src/demo.aqua index bf4991a2..f70ca00d 100644 --- a/aqua-src/demo.aqua +++ b/aqua-src/demo.aqua @@ -2,13 +2,20 @@ import "builtin.aqua" service OpH("op"): puk(s: string) -> string + pek(s: string, -- trgtr + c: string) -> string -func a(b: string) -> string: +func a( -- ferkjn + b: string, -- fr + c: string, -- asdf + g: string + ) -> string: -- rgtr try: f = "world" OpH "planet" - OpH.puk("TRY THIS") + OpH.pek("TRY THIS", -- gtrg + c) catch err: OpH.puk(err.msg) <- f diff --git a/parser/src/main/scala/aqua/parser/expr/CallArrowExpr.scala b/parser/src/main/scala/aqua/parser/expr/CallArrowExpr.scala index e13ca5cb..31634cf0 100644 --- a/parser/src/main/scala/aqua/parser/expr/CallArrowExpr.scala +++ b/parser/src/main/scala/aqua/parser/expr/CallArrowExpr.scala @@ -20,7 +20,7 @@ object CallArrowExpr extends Expr.Leaf { ((Name.p[F] <* ` <- `).backtrack.?.with1 ~ ((Ability.ab[F] <* `.`).?.with1 ~ Name.p[F] ~ - comma0(Value.`value`[F]).between(`(`, `)`))).map { + comma0(Value.`value`[F].surroundedBy(`/s*`)).between(`(` <* `/s*`, `/s*` *> `)`))).map { case (variable, ((ability, funcName), args)) => CallArrowExpr(variable, ability, funcName, args) } diff --git a/parser/src/main/scala/aqua/parser/expr/FuncExpr.scala b/parser/src/main/scala/aqua/parser/expr/FuncExpr.scala index f5c74563..cefea854 100644 --- a/parser/src/main/scala/aqua/parser/expr/FuncExpr.scala +++ b/parser/src/main/scala/aqua/parser/expr/FuncExpr.scala @@ -34,10 +34,10 @@ object FuncExpr extends Expr.AndIndented { Nil override def p[F[_]: LiftParser: Comonad]: Parser[FuncExpr[F]] = - ((`func` *> ` ` *> Name.p[F]) ~ comma0(Arg.p) - .between(`(`, `)`) ~ (` -> ` *> DataTypeToken.`datatypedef`).?).map { - case ((name, args), ret) => - FuncExpr(name, args, ret, None) + ((`func` *> ` ` *> Name.p[F]) + ~ comma0(Arg.p.surroundedBy(`/s*`)).between(`(` <* `/s*`, `/s*` *> `)`) + ~ (` -> ` *> DataTypeToken.`datatypedef`).?).map { case ((name, args), ret) => + FuncExpr(name, args, ret, None) } override def ast[F[_]: LiftParser: Comonad](): Parser[ValidatedNec[ParserError[F], Ast.Tree[F]]] = diff --git a/parser/src/main/scala/aqua/parser/lexer/Token.scala b/parser/src/main/scala/aqua/parser/lexer/Token.scala index 3284dfbe..58aaed0d 100644 --- a/parser/src/main/scala/aqua/parser/lexer/Token.scala +++ b/parser/src/main/scala/aqua/parser/lexer/Token.scala @@ -72,6 +72,7 @@ object Token { val ` = ` : P[Unit] = P.string("=").surroundedBy(` `.?) val `?` : P[Unit] = P.string("?") val `<-` : P[Unit] = P.string("<-") + val `/s*` : P0[Any] = ` \n+` | ` *` case class LiftToken[F[_]: Functor, A](point: F[A]) extends Token[F] { override def as[T](v: T): F[T] = Functor[F].as(point, v) diff --git a/parser/src/main/scala/aqua/parser/lexer/TypeToken.scala b/parser/src/main/scala/aqua/parser/lexer/TypeToken.scala index d3e41bf1..ec94d6e3 100644 --- a/parser/src/main/scala/aqua/parser/lexer/TypeToken.scala +++ b/parser/src/main/scala/aqua/parser/lexer/TypeToken.scala @@ -6,8 +6,8 @@ import aqua.parser.lift.LiftParser._ import aqua.types.ScalarType import cats.Comonad import cats.parse.{Parser => P} -import cats.syntax.functor._ import cats.syntax.comonad._ +import cats.syntax.functor._ sealed trait TypeToken[F[_]] extends Token[F] sealed trait DataTypeToken[F[_]] extends TypeToken[F] @@ -93,7 +93,9 @@ object ArrowTypeToken { } def `arrowWithNames`[F[_]: LiftParser: Comonad]: P[ArrowTypeToken[F]] = - ((`(`.lift ~ comma0(Name.p[F] *> ` : ` *> DataTypeToken.`datatypedef`) <* `)`) ~ + (((`(`.lift <* `/s*`) ~ comma0( + (Name.p[F] *> ` : ` *> DataTypeToken.`datatypedef`).surroundedBy(`/s*`) + ) <* (`/s*` *> `)`)) ~ (` -> ` *> DataTypeToken.`datatypedef`).?).map { case ((point, args), res) => ArrowTypeToken(point, args, res) } diff --git a/parser/src/test/scala/aqua/parser/FuncExprSpec.scala b/parser/src/test/scala/aqua/parser/FuncExprSpec.scala index 5b4f1b86..51ca4b19 100644 --- a/parser/src/test/scala/aqua/parser/FuncExprSpec.scala +++ b/parser/src/test/scala/aqua/parser/FuncExprSpec.scala @@ -116,6 +116,14 @@ class FuncExprSpec extends AnyFlatSpec with Matchers with AquaSpec { parser[Id]().parseAll(script).value.toEither shouldBe Symbol("left") } + "function with multiline definitions" should "parse without error" in { + val script = + """func tryGen(a: string, + | b: string)""".stripMargin + + FuncExpr.p[Id].parseAll(script) shouldBe Symbol("right") + } + "function with root expression without children" should "parse with error" in { val script = """func tryGen() -> bool: