fix: put functions "(" within atomic

This commit is contained in:
2025-02-02 00:30:18 +00:00
parent b5a1f2565f
commit 03fdbe01d9
2 changed files with 36 additions and 25 deletions

View File

@@ -5,6 +5,7 @@ import parsley.Parsley
import parsley.Parsley.{atomic, many, pure}
import parsley.combinator.{countSome, sepBy}
import parsley.expr.{precedence, SOps, InfixL, InfixN, InfixR, Prefix, Atoms}
import parsley.errors.combinator._
import parsley.cats.combinator.{sepBy1, some}
import cats.data.NonEmptyList
@@ -75,15 +76,15 @@ object parser {
// Statements
private lazy val `<program>` = Program(
"begin" ~> many(`<func>`),
"begin" ~> many(atomic(`<type>` <~> `<ident>` <~ "(") <**> `<partial-func-decl>`),
`<stmt>` <~ "end"
)
private lazy val `<func>` = FuncDecl(
atomic(`<type>`),
atomic(`<ident>`) <~ "(",
sepBy(`<param>`, ",") <~ ")" <~ "is",
`<stmt>`
) <~ "end"
private lazy val `<partial-func-decl>` =
(sepBy(`<param>`, ",") <~ ")" <~ "is" <~> `<stmt>`.guardAgainst {
case stmts if !stmts.isReturning => Seq("All functions must end in a returning statement")
} <~ "end") map { (params, stmt) =>
(FuncDecl((_: Type), (_: Ident), params, stmt)).tupled
}
private lazy val `<param>` = Param(`<type>`, `<ident>`)
private lazy val `<stmt>`: Parsley[NonEmptyList[Stmt]] =
sepBy1(`<basic-stmt>`, ";")
@@ -122,4 +123,14 @@ object parser {
private lazy val `<array-liter>` = ArrayLiter(
"[" ~> sepBy(`<expr>`, ",") <~ "]"
)
extension (stmts: NonEmptyList[Stmt]) {
def isReturning: Boolean = stmts.last match {
case Return(_) | Exit(_) => true
case If(_, thenStmt, elseStmt) => thenStmt.isReturning && elseStmt.isReturning
case While(_, body) => body.isReturning
case Block(body) => body.isReturning
case _ => false
}
}
}