fix: added error messages for functions missing type, and late function decls
This commit is contained in:
parent
b3ecae5dbb
commit
a65cc01815
@ -33,7 +33,7 @@ val errConfig = new ErrorConfig {
|
||||
"false" -> Label("boolean literal"),
|
||||
"true" -> Label("boolean literal"),
|
||||
"=" -> Label("assignment"),
|
||||
"[" -> Label("array index")
|
||||
"[" -> Label("array index"),
|
||||
)
|
||||
}
|
||||
object lexer {
|
||||
@ -85,9 +85,10 @@ object lexer {
|
||||
val errTokens = Seq(
|
||||
lexer.nonlexeme.names.identifier.map(v => s"identifier $v"),
|
||||
lexer.nonlexeme.integer.decimal32[Int].map(n => s"integer $n"),
|
||||
lexer.nonlexeme.character.ascii.map(c => s"character literal \'$c\'"),
|
||||
(lexer.nonlexeme.character.ascii).map(c => s"character literal \'$c\'"),
|
||||
lexer.nonlexeme.string.ascii.map(s => s"string literal \"$s\""),
|
||||
character.whitespace.map(_ => "")
|
||||
// lexer.nonlexeme.symbol("()").as("function call, bruh use keyword 'call' to call functions"),
|
||||
character.whitespace.map(_ => ""),
|
||||
) ++ desc.symbolDesc.hardKeywords.map { k =>
|
||||
lexer.nonlexeme.symbol(k).as(s"keyword $k")
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ import cats.data.NonEmptyList
|
||||
import parsley.errors.DefaultErrorBuilder
|
||||
import parsley.errors.ErrorBuilder
|
||||
import parsley.errors.tokenextractors.LexToken
|
||||
import parsley.errors.patterns.VerifiedErrors
|
||||
import parsley.character.char
|
||||
|
||||
object parser {
|
||||
import lexer.implicits.implicitSymbol
|
||||
@ -48,6 +50,10 @@ object parser {
|
||||
case Expr
|
||||
case Pair
|
||||
|
||||
val _parensCheck =
|
||||
char('(').verifiedExplain("use keyword 'call' to call functions")
|
||||
|
||||
|
||||
implicit val builder: ErrorBuilder[String] = new DefaultErrorBuilder with LexToken {
|
||||
def tokens = errTokens
|
||||
}
|
||||
@ -66,8 +72,8 @@ object parser {
|
||||
GreaterEq from ">="
|
||||
) +:
|
||||
SOps(InfixL)(
|
||||
(Add from "+").label("binary operator"),
|
||||
(Sub from "-").label("binary operator")
|
||||
((Add from "+").label("binary operator") | _parensCheck),
|
||||
((Sub from "-").label("binary operator") | _parensCheck)
|
||||
) +:
|
||||
SOps(InfixL)(Mul from "*", Div from "/", Mod from "%") +:
|
||||
SOps(Prefix)(
|
||||
@ -117,15 +123,15 @@ object parser {
|
||||
// Statements
|
||||
private lazy val `<program>` = Program(
|
||||
"begin" ~> many(
|
||||
atomic(`<type>`.label("function declaration") <~> `<ident>` <~ "(") <**> `<partial-func-decl>`
|
||||
atomic((`<type>`.label("function declaration") <~> `<ident>` <~ "(")) <**> `<partial-func-decl>`
|
||||
).label("function declaration"),
|
||||
`<stmt>`.label("main program body") <~ "end"
|
||||
((`<ident>` <~ "(")*> fail("function is missing return type") | `<stmt>`.label("main program body")) <~ "end"
|
||||
)
|
||||
private lazy val `<partial-func-decl>` =
|
||||
FuncDecl(
|
||||
sepBy(`<param>`, ",") <~ ")" <~ "is",
|
||||
sepBy(`<param>`, ",") <~ ")".label("parenthesis") <~ "is",
|
||||
`<stmt>`.guardAgainst {
|
||||
case stmts if !stmts.isReturning => Seq("All functions must end in a returning statement")
|
||||
case stmts if !stmts.isReturning => Seq("all functions must end in a returning statement")
|
||||
} <~ "end"
|
||||
)
|
||||
private lazy val `<param>` = Param(`<type>`, `<ident>`)
|
||||
@ -150,8 +156,8 @@ object parser {
|
||||
)
|
||||
| While("while" ~> `<expr>`.labelWithType(LabelType.Expr) <~ "do", `<stmt>` <~ "done")
|
||||
| Block("begin" ~> `<stmt>` <~ "end")
|
||||
| VarDecl(`<type>`, `<ident>` <~ "=", `<rvalue>`.label("valid initial value for variable"))
|
||||
// TODO: Can we inline the name of the variable in the message
|
||||
| VarDecl(`<type>`, `<ident>` <~ "=".explain("functions must be defined on top of the main block"),
|
||||
`<rvalue>`.label("valid initial value for variable"))
|
||||
| Assign(`<lvalue>` <~ "=", `<rvalue>`)
|
||||
private lazy val `<lvalue>`: Parsley[LValue] =
|
||||
`<pair-elem>` | `<ident-or-array-elem>`
|
||||
|
Loading…
x
Reference in New Issue
Block a user