feat: imports parser
This commit is contained in:
@@ -72,7 +72,7 @@ def frontend(
|
||||
): Either[NonEmptyList[Error], microWacc.Program] =
|
||||
parser.parse(contents) match {
|
||||
case Failure(msg) => Left(NonEmptyList.one(Error.SyntaxError(msg)))
|
||||
case Success(prog) =>
|
||||
case Success(ast.PartialProgram(_, prog)) =>
|
||||
given errors: mutable.Builder[Error, List[Error]] = List.newBuilder
|
||||
|
||||
val (names, funcs) = renamer.rename(prog)
|
||||
|
||||
@@ -131,6 +131,18 @@ object ast {
|
||||
|
||||
/* ============================ PROGRAM STRUCTURE ============================ */
|
||||
|
||||
case class ImportedFunc(sourceName: Ident, importName: Ident)(val pos: Position)
|
||||
object ImportedFunc extends ParserBridgePos2[Ident, Option[Ident], ImportedFunc] {
|
||||
def apply(a: Ident, b: Option[Ident])(pos: Position): ImportedFunc =
|
||||
new ImportedFunc(a, b.getOrElse(a))(pos)
|
||||
}
|
||||
|
||||
case class Import(source: StrLiter, funcs: NonEmptyList[ImportedFunc])(val pos: Position)
|
||||
object Import extends ParserBridgePos2[StrLiter, NonEmptyList[ImportedFunc], Import]
|
||||
|
||||
case class PartialProgram(imports: List[Import], self: Program)(val pos: Position)
|
||||
object PartialProgram extends ParserBridgePos2[List[Import], Program, PartialProgram]
|
||||
|
||||
case class Program(funcs: List[FuncDecl], main: NonEmptyList[Stmt])(val pos: Position)
|
||||
object Program extends ParserBridgePos2[List[FuncDecl], NonEmptyList[Stmt], Program]
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@ package wacc
|
||||
import parsley.Result
|
||||
import parsley.Parsley
|
||||
import parsley.Parsley.{atomic, many, notFollowedBy, pure, unit}
|
||||
import parsley.combinator.{countSome, sepBy}
|
||||
import parsley.combinator.{countSome, sepBy, option}
|
||||
import parsley.expr.{precedence, SOps, InfixL, InfixN, InfixR, Prefix, Atoms}
|
||||
import parsley.errors.combinator._
|
||||
import parsley.errors.patterns.VerifiedErrors
|
||||
import parsley.syntax.zipped._
|
||||
import parsley.cats.combinator.{some}
|
||||
import parsley.cats.combinator.{some, sepBy1}
|
||||
import cats.data.NonEmptyList
|
||||
import parsley.errors.DefaultErrorBuilder
|
||||
import parsley.errors.ErrorBuilder
|
||||
@@ -52,8 +52,8 @@ object parser {
|
||||
implicit val builder: ErrorBuilder[String] = new DefaultErrorBuilder with LexToken {
|
||||
def tokens = errTokens
|
||||
}
|
||||
def parse(input: String): Result[String, Program] = parser.parse(input)
|
||||
private val parser = lexer.fully(`<program>`)
|
||||
def parse(input: String): Result[String, PartialProgram] = parser.parse(input)
|
||||
private val parser = lexer.fully(`<partial-program>`)
|
||||
|
||||
// Expressions
|
||||
private lazy val `<expr>`: Parsley[Expr] = precedence {
|
||||
@@ -87,11 +87,12 @@ object parser {
|
||||
IntLiter(integer).label("integer literal"),
|
||||
BoolLiter(("true" as true) | ("false" as false)).label("boolean literal"),
|
||||
CharLiter(charLit).label("character literal"),
|
||||
StrLiter(stringLit).label("string literal"),
|
||||
`<str-liter>`.label("string literal"),
|
||||
PairLiter from "null",
|
||||
`<ident-or-array-elem>`,
|
||||
Parens("(" ~> `<expr>` <~ ")")
|
||||
)
|
||||
private val `<str-liter>` = StrLiter(stringLit)
|
||||
private val `<ident>` =
|
||||
Ident(ident) | some("*" | "&").verifiedExplain("pointer operators are not allowed")
|
||||
private lazy val `<ident-or-array-elem>` =
|
||||
@@ -127,6 +128,19 @@ object parser {
|
||||
invalid syntax check, this only happens at most once per program so this is not a major
|
||||
concern.
|
||||
*/
|
||||
private lazy val `<partial-program>` = PartialProgram(
|
||||
many(`<import>`),
|
||||
`<program>`
|
||||
)
|
||||
private lazy val `<import>` = Import(
|
||||
"import" ~> `<import-filename>`,
|
||||
"(" ~> sepBy1(`<imported-func>`, ",") <~ ")"
|
||||
)
|
||||
private lazy val `<import-filename>` = `<str-liter>`.label("import file name")
|
||||
private lazy val `<imported-func>` = ImportedFunc(
|
||||
`<ident>`.label("imported function name"),
|
||||
option("as" ~> `<ident>`).label("imported function alias")
|
||||
)
|
||||
private lazy val `<program>` = Program(
|
||||
"begin" ~> (
|
||||
many(
|
||||
|
||||
Reference in New Issue
Block a user