fix: put functions "(" within atomic

This commit is contained in:
Gleb Koval 2025-02-02 00:30:18 +00:00
parent b5a1f2565f
commit 03fdbe01d9
Signed by: cyclane
GPG Key ID: 15E168A8B332382C
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.Parsley.{atomic, many, pure}
import parsley.combinator.{countSome, sepBy} import parsley.combinator.{countSome, sepBy}
import parsley.expr.{precedence, SOps, InfixL, InfixN, InfixR, Prefix, Atoms} import parsley.expr.{precedence, SOps, InfixL, InfixN, InfixR, Prefix, Atoms}
import parsley.errors.combinator._
import parsley.cats.combinator.{sepBy1, some} import parsley.cats.combinator.{sepBy1, some}
import cats.data.NonEmptyList import cats.data.NonEmptyList
@ -75,15 +76,15 @@ object parser {
// Statements // Statements
private lazy val `<program>` = Program( private lazy val `<program>` = Program(
"begin" ~> many(`<func>`), "begin" ~> many(atomic(`<type>` <~> `<ident>` <~ "(") <**> `<partial-func-decl>`),
`<stmt>` <~ "end" `<stmt>` <~ "end"
) )
private lazy val `<func>` = FuncDecl( private lazy val `<partial-func-decl>` =
atomic(`<type>`), (sepBy(`<param>`, ",") <~ ")" <~ "is" <~> `<stmt>`.guardAgainst {
atomic(`<ident>`) <~ "(", case stmts if !stmts.isReturning => Seq("All functions must end in a returning statement")
sepBy(`<param>`, ",") <~ ")" <~ "is", } <~ "end") map { (params, stmt) =>
`<stmt>` (FuncDecl((_: Type), (_: Ident), params, stmt)).tupled
) <~ "end" }
private lazy val `<param>` = Param(`<type>`, `<ident>`) private lazy val `<param>` = Param(`<type>`, `<ident>`)
private lazy val `<stmt>`: Parsley[NonEmptyList[Stmt]] = private lazy val `<stmt>`: Parsley[NonEmptyList[Stmt]] =
sepBy1(`<basic-stmt>`, ";") sepBy1(`<basic-stmt>`, ";")
@ -122,4 +123,14 @@ object parser {
private lazy val `<array-liter>` = ArrayLiter( private lazy val `<array-liter>` = ArrayLiter(
"[" ~> sepBy(`<expr>`, ",") <~ "]" "[" ~> 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
}
}
} }

View File

@ -37,24 +37,24 @@ class ParallelExamplesSpec extends AnyFlatSpec with BeforeAndAfterAll with Paral
Seq( Seq(
// format: off // format: off
// disable formatting to avoid binPack // disable formatting to avoid binPack
"wacc-examples/valid/advanced", // "wacc-examples/valid/advanced",
"wacc-examples/valid/array", // "wacc-examples/valid/array",
"wacc-examples/valid/basic/exit", // "wacc-examples/valid/basic/exit",
"wacc-examples/valid/basic/skip", // "wacc-examples/valid/basic/skip",
"wacc-examples/valid/expressions", // "wacc-examples/valid/expressions",
"wacc-examples/valid/function/nested_functions", // "wacc-examples/valid/function/nested_functions",
"wacc-examples/valid/function/simple_functions", // "wacc-examples/valid/function/simple_functions",
"wacc-examples/valid/if", // "wacc-examples/valid/if",
"wacc-examples/valid/IO/print", // "wacc-examples/valid/IO/print",
"wacc-examples/valid/IO/read", // "wacc-examples/valid/IO/read",
"wacc-examples/valid/IO/IOLoop.wacc", // "wacc-examples/valid/IO/IOLoop.wacc",
"wacc-examples/valid/IO/IOSequence.wacc", // "wacc-examples/valid/IO/IOSequence.wacc",
"wacc-examples/valid/pairs", // "wacc-examples/valid/pairs",
"wacc-examples/valid/runtimeErr", // "wacc-examples/valid/runtimeErr",
"wacc-examples/valid/scope", // "wacc-examples/valid/scope",
"wacc-examples/valid/sequence", // "wacc-examples/valid/sequence",
"wacc-examples/valid/variables", // "wacc-examples/valid/variables",
"wacc-examples/valid/while", // "wacc-examples/valid/while",
// invalid (syntax) // invalid (syntax)
// "wacc-examples/invalid/syntaxErr/array", // "wacc-examples/invalid/syntaxErr/array",
// "wacc-examples/invalid/syntaxErr/basic", // "wacc-examples/invalid/syntaxErr/basic",