feat: imports and parallelised renamer #40

Merged
gk1623 merged 14 commits from imports into master 2025-03-13 23:10:38 +00:00
26 changed files with 442 additions and 88 deletions
Showing only changes of commit 6904aa37e4 - Show all commits

View File

@@ -69,7 +69,8 @@ val outputOpt: Opts[Option[Path]] =
.orNone .orNone
def frontend( def frontend(
contents: String, file: File contents: String,
file: File
): Either[NonEmptyList[Error], microWacc.Program] = ): Either[NonEmptyList[Error], microWacc.Program] =
parser.parse(contents) match { parser.parse(contents) match {
case Failure(msg) => Left(NonEmptyList.one(Error.SyntaxError(msg))) case Failure(msg) => Left(NonEmptyList.one(Error.SyntaxError(msg)))

View File

@@ -134,7 +134,8 @@ object ast {
extends Type extends Type
with PairElemType with PairElemType
object ArrayType extends ParserBridgePos2Chain[Int, Type, ArrayType] { object ArrayType extends ParserBridgePos2Chain[Int, Type, ArrayType] {
def apply(dimensions: Int, elemType: Type)(pos: Position): ArrayType = ArrayType(elemType, dimensions)(pos) def apply(dimensions: Int, elemType: Type)(pos: Position): ArrayType =
ArrayType(elemType, dimensions)(pos)
} }
case class PairType(fst: PairElemType, snd: PairElemType)(val pos: Position) extends Type case class PairType(fst: PairElemType, snd: PairElemType)(val pos: Position) extends Type
object PairType extends ParserBridgePos2[PairElemType, PairElemType, PairType] object PairType extends ParserBridgePos2[PairElemType, PairElemType, PairType]
@@ -171,9 +172,12 @@ object ast {
object FuncDecl object FuncDecl
extends ParserBridgePos2Chain[ extends ParserBridgePos2Chain[
(List[Param], NonEmptyList[Stmt]), (List[Param], NonEmptyList[Stmt]),
((Type, Ident)), FuncDecl ((Type, Ident)),
FuncDecl
] { ] {
def apply(paramsBody: (List[Param], NonEmptyList[Stmt]), retTyName: (Type, Ident))(pos: Position): FuncDecl = def apply(paramsBody: (List[Param], NonEmptyList[Stmt]), retTyName: (Type, Ident))(
pos: Position
): FuncDecl =
new FuncDecl(retTyName._1, retTyName._2, paramsBody._1, paramsBody._2)(pos) new FuncDecl(retTyName._1, retTyName._2, paramsBody._1, paramsBody._2)(pos)
} }
@@ -261,15 +265,19 @@ object ast {
a => file => this.apply(a(file))(Position(pos._1, pos._2, file)) a => file => this.apply(a(file))(Position(pos._1, pos._2, file))
} }
trait ParserBridgePos2Chain[-A, -B, +C] extends ParserSingletonBridgePos[(File => A) => (File => B) => File => C] { trait ParserBridgePos2Chain[-A, -B, +C]
extends ParserSingletonBridgePos[(File => A) => (File => B) => File => C] {
def apply(a: A, b: B)(pos: Position): C def apply(a: A, b: B)(pos: Position): C
def apply(a: Parsley[File =>A]): Parsley[(File => B) => File => C] = error(ap1(pos.map(con), a)) def apply(a: Parsley[File => A]): Parsley[(File => B) => File => C] = error(
ap1(pos.map(con), a)
)
override final def con(pos: (Int, Int)): (File => A) => (File => B) => File => C = override final def con(pos: (Int, Int)): (File => A) => (File => B) => File => C =
a => b => file => this.apply(a(file), b(file))(Position(pos._1, pos._2, file)) a => b => file => this.apply(a(file), b(file))(Position(pos._1, pos._2, file))
} }
trait ParserBridgePos2[-A, -B, +C] extends ParserSingletonBridgePos[(File => A, File => B) => File => C] { trait ParserBridgePos2[-A, -B, +C]
extends ParserSingletonBridgePos[(File => A, File => B) => File => C] {
def apply(a: A, b: B)(pos: Position): C def apply(a: A, b: B)(pos: Position): C
def apply(a: Parsley[File => A], b: => Parsley[File => B]): Parsley[File => C] = error( def apply(a: Parsley[File => A], b: => Parsley[File => B]): Parsley[File => C] = error(
ap2(pos.map(con), a, b) ap2(pos.map(con), a, b)
@@ -279,9 +287,14 @@ object ast {
(a, b) => file => this.apply(a(file), b(file))(Position(pos._1, pos._2, file)) (a, b) => file => this.apply(a(file), b(file))(Position(pos._1, pos._2, file))
} }
trait ParserBridgePos3[-A, -B, -C, +D] extends ParserSingletonBridgePos[(File => A, File => B, File => C) => File => D] { trait ParserBridgePos3[-A, -B, -C, +D]
extends ParserSingletonBridgePos[(File => A, File => B, File => C) => File => D] {
def apply(a: A, b: B, c: C)(pos: Position): D def apply(a: A, b: B, c: C)(pos: Position): D
def apply(a: Parsley[File => A], b: => Parsley[File => B], c: => Parsley[File => C]): Parsley[File => D] = error( def apply(
a: Parsley[File => A],
b: => Parsley[File => B],
c: => Parsley[File => C]
): Parsley[File => D] = error(
ap3(pos.map(con), a, b, c) ap3(pos.map(con), a, b, c)
) )

View File

@@ -161,11 +161,15 @@ object parser {
) )
private lazy val `<program>` = Program( private lazy val `<program>` = Program(
"begin" ~> ( "begin" ~> (
fList(many( fList(
fPair(atomic( many(
fPair(
atomic(
`<type>`.label("function declaration") <~> `<ident>` <~ "(" `<type>`.label("function declaration") <~> `<ident>` <~ "("
)) <**> `<partial-func-decl>` )
).label("function declaration")) | ) <**> `<partial-func-decl>`
).label("function declaration")
) |
atomic(`<ident>` <~ "(").verifiedExplain("function declaration is missing return type") atomic(`<ident>` <~ "(").verifiedExplain("function declaration is missing return type")
), ),
`<stmt>`.label( `<stmt>`.label(
@@ -174,18 +178,23 @@ object parser {
) )
private lazy val `<partial-func-decl>` = private lazy val `<partial-func-decl>` =
FuncDecl( FuncDecl(
fPair((fList(sepBy(`<param>`, ",")) <~ ")" <~ "is") <~> fPair(
(fList(sepBy(`<param>`, ",")) <~ ")" <~ "is") <~>
(`<stmt>`.guardAgainst { (`<stmt>`.guardAgainst {
// TODO: passing in an arbitrary file works but is ugly // TODO: passing in an arbitrary file works but is ugly
case stmts if !(stmts(File("."))).isReturning => Seq("all functions must end in a returning statement") case stmts if !(stmts(File("."))).isReturning =>
} <~ "end")) Seq("all functions must end in a returning statement")
} <~ "end")
)
) )
private lazy val `<param>` = Param(`<type>`, `<ident>`) private lazy val `<param>` = Param(`<type>`, `<ident>`)
private lazy val `<stmt>`: FParsley[NonEmptyList[Stmt]] = private lazy val `<stmt>`: FParsley[NonEmptyList[Stmt]] =
fNonEmptyList(( fNonEmptyList(
(
`<basic-stmt>`.label("main program body"), `<basic-stmt>`.label("main program body"),
(many(";" ~> `<basic-stmt>`.label("statement after ';'"))) </> Nil (many(";" ~> `<basic-stmt>`.label("statement after ';'"))) </> Nil
).zipped(NonEmptyList.apply)) ).zipped(NonEmptyList.apply)
)
private lazy val `<basic-stmt>` = private lazy val `<basic-stmt>` =
(Skip from "skip") (Skip from "skip")