refactor: add position tracking to AST, UnaryOp, BinaryOp

This commit is contained in:
Gleb Koval 2025-02-05 02:12:16 +00:00 committed by Barf-Vader
parent bd779931b6
commit 1486296b40

View File

@ -1,6 +1,9 @@
package wacc package wacc
import parsley.generic._ import parsley.Parsley
import parsley.generic.ErrorBridge
import parsley.position._
import parsley.syntax.zipped._
import cats.data.NonEmptyList import cats.data.NonEmptyList
object ast { object ast {
@ -14,80 +17,97 @@ object ast {
sealed trait Expr6 extends Expr5 sealed trait Expr6 extends Expr5
// Atoms // Atoms
case class IntLiter(v: Int) extends Expr6 case class IntLiter(v: Int)(pos: Position) extends Expr6
object IntLiter extends ParserBridge1[Int, IntLiter] object IntLiter extends ParserBridgePos1[Int, IntLiter]
case class BoolLiter(v: Boolean) extends Expr6 case class BoolLiter(v: Boolean)(pos: Position) extends Expr6
object BoolLiter extends ParserBridge1[Boolean, BoolLiter] object BoolLiter extends ParserBridgePos1[Boolean, BoolLiter]
case class CharLiter(v: Char) extends Expr6 case class CharLiter(v: Char)(pos: Position) extends Expr6
object CharLiter extends ParserBridge1[Char, CharLiter] object CharLiter extends ParserBridgePos1[Char, CharLiter]
case class StrLiter(v: String) extends Expr6 case class StrLiter(v: String)(pos: Position) extends Expr6
object StrLiter extends ParserBridge1[String, StrLiter] object StrLiter extends ParserBridgePos1[String, StrLiter]
case object PairLiter extends Expr6 with ParserBridge0[PairLiter.type] case class PairLiter()(pos: Position) extends Expr6
case class Ident(v: String) extends Expr6 with LValue object PairLiter extends Expr6 with ParserBridgePos0[PairLiter]
object Ident extends ParserBridge1[String, Ident] case class Ident(v: String)(pos: Position) extends Expr6 with LValue
case class ArrayElem(name: Ident, indices: NonEmptyList[Expr]) extends Expr6 with LValue object Ident extends ParserBridgePos1[String, Ident]
object ArrayElem extends ParserBridge2[Ident, NonEmptyList[Expr], ArrayElem] case class ArrayElem(name: Ident, indices: NonEmptyList[Expr])(pos: Position)
case class Parens(expr: Expr) extends Expr6 extends Expr6
object Parens extends ParserBridge1[Expr, Parens] with LValue
object ArrayElem extends ParserBridgePos2[Ident, NonEmptyList[Expr], ArrayElem]
case class Parens(expr: Expr)(pos: Position) extends Expr6
object Parens extends ParserBridgePos1[Expr, Parens]
// Unary operators // Unary operators
case class Negate(x: Expr6) extends Expr6 sealed trait UnaryOp extends Expr {
object Negate extends ParserBridge1[Expr6, Negate] val x: Expr
case class Not(x: Expr6) extends Expr6 }
object Not extends ParserBridge1[Expr6, Not] case class Negate(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
case class Len(x: Expr6) extends Expr6 object Negate extends ParserBridgePos1[Expr6, Negate]
object Len extends ParserBridge1[Expr6, Len] case class Not(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
case class Ord(x: Expr6) extends Expr6 object Not extends ParserBridgePos1[Expr6, Not]
object Ord extends ParserBridge1[Expr6, Ord] case class Len(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
case class Chr(x: Expr6) extends Expr6 object Len extends ParserBridgePos1[Expr6, Len]
object Chr extends ParserBridge1[Expr6, Chr] case class Ord(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
object Ord extends ParserBridgePos1[Expr6, Ord]
case class Chr(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
object Chr extends ParserBridgePos1[Expr6, Chr]
// Binary operators // Binary operators
case class Add(x: Expr4, y: Expr5) extends Expr4 sealed trait BinaryOp extends Expr {
object Add extends ParserBridge2[Expr4, Expr5, Add] val x: Expr
case class Sub(x: Expr4, y: Expr5) extends Expr4 val y: Expr
object Sub extends ParserBridge2[Expr4, Expr5, Sub] }
case class Mul(x: Expr5, y: Expr6) extends Expr5 case class Add(x: Expr4, y: Expr5)(pos: Position) extends Expr4 with BinaryOp
object Mul extends ParserBridge2[Expr5, Expr6, Mul] object Add extends ParserBridgePos2[Expr4, Expr5, Add]
case class Div(x: Expr5, y: Expr6) extends Expr5 case class Sub(x: Expr4, y: Expr5)(pos: Position) extends Expr4 with BinaryOp
object Div extends ParserBridge2[Expr5, Expr6, Div] object Sub extends ParserBridgePos2[Expr4, Expr5, Sub]
case class Mod(x: Expr5, y: Expr6) extends Expr5 case class Mul(x: Expr5, y: Expr6)(pos: Position) extends Expr5 with BinaryOp
object Mod extends ParserBridge2[Expr5, Expr6, Mod] object Mul extends ParserBridgePos2[Expr5, Expr6, Mul]
case class Greater(x: Expr4, y: Expr4) extends Expr3 case class Div(x: Expr5, y: Expr6)(pos: Position) extends Expr5 with BinaryOp
object Greater extends ParserBridge2[Expr4, Expr4, Greater] object Div extends ParserBridgePos2[Expr5, Expr6, Div]
case class GreaterEq(x: Expr4, y: Expr4) extends Expr3 case class Mod(x: Expr5, y: Expr6)(pos: Position) extends Expr5 with BinaryOp
object GreaterEq extends ParserBridge2[Expr4, Expr4, GreaterEq] object Mod extends ParserBridgePos2[Expr5, Expr6, Mod]
case class Less(x: Expr4, y: Expr4) extends Expr3 case class Greater(x: Expr4, y: Expr4)(pos: Position) extends Expr3 with BinaryOp
object Less extends ParserBridge2[Expr4, Expr4, Less] object Greater extends ParserBridgePos2[Expr4, Expr4, Greater]
case class LessEq(x: Expr4, y: Expr4) extends Expr3 case class GreaterEq(x: Expr4, y: Expr4)(pos: Position) extends Expr3 with BinaryOp
object LessEq extends ParserBridge2[Expr4, Expr4, LessEq] object GreaterEq extends ParserBridgePos2[Expr4, Expr4, GreaterEq]
case class Eq(x: Expr3, y: Expr3) extends Expr2 case class Less(x: Expr4, y: Expr4)(pos: Position) extends Expr3 with BinaryOp
object Eq extends ParserBridge2[Expr3, Expr3, Eq] object Less extends ParserBridgePos2[Expr4, Expr4, Less]
case class Neq(x: Expr3, y: Expr3) extends Expr2 case class LessEq(x: Expr4, y: Expr4)(pos: Position) extends Expr3 with BinaryOp
object Neq extends ParserBridge2[Expr3, Expr3, Neq] object LessEq extends ParserBridgePos2[Expr4, Expr4, LessEq]
case class And(x: Expr2, y: Expr1) extends Expr1 case class Eq(x: Expr3, y: Expr3)(pos: Position) extends Expr2 with BinaryOp
object And extends ParserBridge2[Expr2, Expr1, And] object Eq extends ParserBridgePos2[Expr3, Expr3, Eq]
case class Or(x: Expr1, y: Expr) extends Expr case class Neq(x: Expr3, y: Expr3)(pos: Position) extends Expr2 with BinaryOp
object Or extends ParserBridge2[Expr1, Expr, Or] object Neq extends ParserBridgePos2[Expr3, Expr3, Neq]
case class And(x: Expr2, y: Expr1)(pos: Position) extends Expr1 with BinaryOp
object And extends ParserBridgePos2[Expr2, Expr1, And]
case class Or(x: Expr1, y: Expr)(pos: Position) extends Expr with BinaryOp
object Or extends ParserBridgePos2[Expr1, Expr, Or]
// Types // Types
sealed trait Type sealed trait Type
sealed trait BaseType extends Type with PairElemType sealed trait BaseType extends Type with PairElemType
case object IntType extends BaseType with ParserBridge0[IntType.type] case class IntType()(pos: Position) extends BaseType
case object BoolType extends BaseType with ParserBridge0[BoolType.type] object IntType extends ParserBridgePos0[IntType]
case object CharType extends BaseType with ParserBridge0[CharType.type] case class BoolType()(pos: Position) extends BaseType
case object StringType extends BaseType with ParserBridge0[StringType.type] object BoolType extends ParserBridgePos0[BoolType]
case class ArrayType(elemType: Type, dimensions: Int) extends Type with PairElemType case class CharType()(pos: Position) extends BaseType
object ArrayType extends ParserBridge2[Type, Int, ArrayType] object CharType extends ParserBridgePos0[CharType]
case class PairType(fst: PairElemType, snd: PairElemType) extends Type case class StringType()(pos: Position) extends BaseType
object PairType extends ParserBridge2[PairElemType, PairElemType, PairType] object StringType extends ParserBridgePos0[StringType]
case class ArrayType(elemType: Type, dimensions: Int)(pos: Position)
extends Type
with PairElemType
object ArrayType extends ParserBridgePos2[Type, Int, ArrayType]
case class PairType(fst: PairElemType, snd: PairElemType)(pos: Position) extends Type
object PairType extends ParserBridgePos2[PairElemType, PairElemType, PairType]
sealed trait PairElemType sealed trait PairElemType
case object UntypedPairType extends PairElemType with ParserBridge0[UntypedPairType.type] case class UntypedPairType()(pos: Position) extends PairElemType
object UntypedPairType extends ParserBridgePos0[UntypedPairType]
// waccadoodledo // waccadoodledo
case class Program(funcs: List[FuncDecl], main: NonEmptyList[Stmt]) case class Program(funcs: List[FuncDecl], main: NonEmptyList[Stmt])(pos: Position)
object Program extends ParserBridge2[List[FuncDecl], NonEmptyList[Stmt], Program] object Program extends ParserBridgePos2[List[FuncDecl], NonEmptyList[Stmt], Program]
// Function Definitions // Function Definitions
case class FuncDecl( case class FuncDecl(
@ -95,49 +115,115 @@ object ast {
name: Ident, name: Ident,
params: List[Param], params: List[Param],
body: NonEmptyList[Stmt] body: NonEmptyList[Stmt]
) )(pos: Position)
object FuncDecl extends ParserBridge4[Type, Ident, List[Param], NonEmptyList[Stmt], FuncDecl] object FuncDecl extends ParserBridgePos4[Type, Ident, List[Param], NonEmptyList[Stmt], FuncDecl]
case class Param(paramType: Type, name: Ident) case class Param(paramType: Type, name: Ident)(pos: Position)
object Param extends ParserBridge2[Type, Ident, Param] object Param extends ParserBridgePos2[Type, Ident, Param]
// Statements // Statements
sealed trait Stmt sealed trait Stmt
case object Skip extends Stmt with ParserBridge0[Skip.type] case class Skip()(pos: Position) extends Stmt
case class VarDecl(varType: Type, name: Ident, value: RValue) extends Stmt object Skip extends ParserBridgePos0[Skip]
object VarDecl extends ParserBridge3[Type, Ident, RValue, VarDecl] case class VarDecl(varType: Type, name: Ident, value: RValue)(pos: Position) extends Stmt
case class Assign(lhs: LValue, value: RValue) extends Stmt object VarDecl extends ParserBridgePos3[Type, Ident, RValue, VarDecl]
object Assign extends ParserBridge2[LValue, RValue, Assign] case class Assign(lhs: LValue, value: RValue)(pos: Position) extends Stmt
case class Read(lhs: LValue) extends Stmt object Assign extends ParserBridgePos2[LValue, RValue, Assign]
object Read extends ParserBridge1[LValue, Read] case class Read(lhs: LValue)(pos: Position) extends Stmt
case class Free(expr: Expr) extends Stmt object Read extends ParserBridgePos1[LValue, Read]
object Free extends ParserBridge1[Expr, Free] case class Free(expr: Expr)(pos: Position) extends Stmt
case class Return(expr: Expr) extends Stmt object Free extends ParserBridgePos1[Expr, Free]
object Return extends ParserBridge1[Expr, Return] case class Return(expr: Expr)(pos: Position) extends Stmt
case class Exit(expr: Expr) extends Stmt object Return extends ParserBridgePos1[Expr, Return]
object Exit extends ParserBridge1[Expr, Exit] case class Exit(expr: Expr)(pos: Position) extends Stmt
case class Print(expr: Expr, newline: Boolean) extends Stmt object Exit extends ParserBridgePos1[Expr, Exit]
object Print extends ParserBridge2[Expr, Boolean, Print] case class Print(expr: Expr, newline: Boolean)(pos: Position) extends Stmt
case class If(cond: Expr, thenStmt: NonEmptyList[Stmt], elseStmt: NonEmptyList[Stmt]) extends Stmt object Print extends ParserBridgePos2[Expr, Boolean, Print]
object If extends ParserBridge3[Expr, NonEmptyList[Stmt], NonEmptyList[Stmt], If] case class If(cond: Expr, thenStmt: NonEmptyList[Stmt], elseStmt: NonEmptyList[Stmt])(
case class While(cond: Expr, body: NonEmptyList[Stmt]) extends Stmt pos: Position
object While extends ParserBridge2[Expr, NonEmptyList[Stmt], While] ) extends Stmt
case class Block(stmt: NonEmptyList[Stmt]) extends Stmt object If extends ParserBridgePos3[Expr, NonEmptyList[Stmt], NonEmptyList[Stmt], If]
object Block extends ParserBridge1[NonEmptyList[Stmt], Block] case class While(cond: Expr, body: NonEmptyList[Stmt])(pos: Position) extends Stmt
object While extends ParserBridgePos2[Expr, NonEmptyList[Stmt], While]
case class Block(stmt: NonEmptyList[Stmt])(pos: Position) extends Stmt
object Block extends ParserBridgePos1[NonEmptyList[Stmt], Block]
sealed trait LValue sealed trait LValue
sealed trait RValue sealed trait RValue
case class ArrayLiter(elems: List[Expr]) extends RValue case class ArrayLiter(elems: List[Expr])(pos: Position) extends RValue
object ArrayLiter extends ParserBridge1[List[Expr], ArrayLiter] object ArrayLiter extends ParserBridgePos1[List[Expr], ArrayLiter]
case class NewPair(fst: Expr, snd: Expr) extends RValue case class NewPair(fst: Expr, snd: Expr)(pos: Position) extends RValue
object NewPair extends ParserBridge2[Expr, Expr, NewPair] object NewPair extends ParserBridgePos2[Expr, Expr, NewPair]
case class Call(name: Ident, args: List[Expr]) extends RValue case class Call(name: Ident, args: List[Expr])(pos: Position) extends RValue
object Call extends ParserBridge2[Ident, List[Expr], Call] object Call extends ParserBridgePos2[Ident, List[Expr], Call]
sealed trait PairElem extends LValue with RValue sealed trait PairElem extends LValue with RValue
case class Fst(elem: LValue) extends PairElem case class Fst(elem: LValue)(pos: Position) extends PairElem
object Fst extends ParserBridge1[LValue, Fst] object Fst extends ParserBridgePos1[LValue, Fst]
case class Snd(elem: LValue) extends PairElem case class Snd(elem: LValue)(pos: Position) extends PairElem
object Snd extends ParserBridge1[LValue, Snd] object Snd extends ParserBridgePos1[LValue, Snd]
// Parser bridges
case class Position(line: Int, column: Int, offset: Int, width: Int)
private def applyCon[A, B](
con: ((Int, Int), Int, Int) => A => B
)(ops: Parsley[A]): Parsley[B] =
(pos, offset, withWidth(ops)).zipped.map { (pos, off, res) =>
con(pos, off, res._2)(res._1)
}
trait ParserSingletonBridgePos[+A] extends ErrorBridge {
protected def con(pos: (Int, Int), offset: Int, width: Int): A
def from(op: Parsley[?]): Parsley[A] = error((pos, offset, withWidth(op)).zipped.map {
(pos, off, res) => con(pos, off, res._2)
})
final def <#(op: Parsley[?]): Parsley[A] = from(op)
}
trait ParserBridgePos0[+A] extends ParserSingletonBridgePos[A] {
def apply()(pos: Position): A
override final def con(pos: (Int, Int), offset: Int, width: Int): A =
apply()(Position(pos._1, pos._2, offset, width))
}
trait ParserBridgePos1[-A, +B] extends ParserSingletonBridgePos[A => B] {
def apply(a: A)(pos: Position): B
def apply(a: Parsley[A]): Parsley[B] = error((pos, offset, withWidth(a)).zipped.map {
(pos, off, res) => con(pos, off, res._2)(res._1)
})
override final def con(pos: (Int, Int), offset: Int, width: Int): A => B =
apply(_)(Position(pos._1, pos._2, offset, width))
}
trait ParserBridgePos2[-A, -B, +C] extends ParserSingletonBridgePos[((A, B)) => C] {
def apply(a: A, b: B)(pos: Position): C
def apply(a: Parsley[A], b: Parsley[B]): Parsley[C] = error(applyCon(con)((a, b).zipped))
override final def con(pos: (Int, Int), offset: Int, width: Int): ((A, B)) => C =
apply(_, _)(Position(pos._1, pos._2, offset, width))
}
trait ParserBridgePos3[-A, -B, -C, +D] extends ParserSingletonBridgePos[((A, B, C)) => D] {
def apply(a: A, b: B, c: C)(pos: Position): D
def apply(a: Parsley[A], b: Parsley[B], c: Parsley[C]): Parsley[D] = error(
applyCon(con)((a, b, c).zipped)
)
override final def con(pos: (Int, Int), offset: Int, width: Int): ((A, B, C)) => D =
apply(_, _, _)(Position(pos._1, pos._2, offset, width))
}
trait ParserBridgePos4[-A, -B, -C, -D, +E] extends ParserSingletonBridgePos[((A, B, C, D)) => E] {
def apply(a: A, b: B, c: C, d: D)(pos: Position): E
def apply(a: Parsley[A], b: Parsley[B], c: Parsley[C], d: Parsley[D]): Parsley[E] = error(
applyCon(con)((a, b, c, d).zipped)
)
override final def con(pos: (Int, Int), offset: Int, width: Int): ((A, B, C, D)) => E =
apply(_, _, _, _)(Position(pos._1, pos._2, offset, width))
}
} }