refactor: add position tracking to AST, UnaryOp, BinaryOp
This commit is contained in:
		| @@ -1,6 +1,9 @@ | ||||
| package wacc | ||||
|  | ||||
| import parsley.generic._ | ||||
| import parsley.Parsley | ||||
| import parsley.generic.ErrorBridge | ||||
| import parsley.position._ | ||||
| import parsley.syntax.zipped._ | ||||
| import cats.data.NonEmptyList | ||||
|  | ||||
| object ast { | ||||
| @@ -14,80 +17,97 @@ object ast { | ||||
|   sealed trait Expr6 extends Expr5 | ||||
|  | ||||
|   // Atoms | ||||
|   case class IntLiter(v: Int) extends Expr6 | ||||
|   object IntLiter extends ParserBridge1[Int, IntLiter] | ||||
|   case class BoolLiter(v: Boolean) extends Expr6 | ||||
|   object BoolLiter extends ParserBridge1[Boolean, BoolLiter] | ||||
|   case class CharLiter(v: Char) extends Expr6 | ||||
|   object CharLiter extends ParserBridge1[Char, CharLiter] | ||||
|   case class StrLiter(v: String) extends Expr6 | ||||
|   object StrLiter extends ParserBridge1[String, StrLiter] | ||||
|   case object PairLiter extends Expr6 with ParserBridge0[PairLiter.type] | ||||
|   case class Ident(v: String) extends Expr6 with LValue | ||||
|   object Ident extends ParserBridge1[String, Ident] | ||||
|   case class ArrayElem(name: Ident, indices: NonEmptyList[Expr]) extends Expr6 with LValue | ||||
|   object ArrayElem extends ParserBridge2[Ident, NonEmptyList[Expr], ArrayElem] | ||||
|   case class Parens(expr: Expr) extends Expr6 | ||||
|   object Parens extends ParserBridge1[Expr, Parens] | ||||
|   case class IntLiter(v: Int)(pos: Position) extends Expr6 | ||||
|   object IntLiter extends ParserBridgePos1[Int, IntLiter] | ||||
|   case class BoolLiter(v: Boolean)(pos: Position) extends Expr6 | ||||
|   object BoolLiter extends ParserBridgePos1[Boolean, BoolLiter] | ||||
|   case class CharLiter(v: Char)(pos: Position) extends Expr6 | ||||
|   object CharLiter extends ParserBridgePos1[Char, CharLiter] | ||||
|   case class StrLiter(v: String)(pos: Position) extends Expr6 | ||||
|   object StrLiter extends ParserBridgePos1[String, StrLiter] | ||||
|   case class PairLiter()(pos: Position) extends Expr6 | ||||
|   object PairLiter extends Expr6 with ParserBridgePos0[PairLiter] | ||||
|   case class Ident(v: String)(pos: Position) extends Expr6 with LValue | ||||
|   object Ident extends ParserBridgePos1[String, Ident] | ||||
|   case class ArrayElem(name: Ident, indices: NonEmptyList[Expr])(pos: Position) | ||||
|       extends Expr6 | ||||
|       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 | ||||
|   case class Negate(x: Expr6) extends Expr6 | ||||
|   object Negate extends ParserBridge1[Expr6, Negate] | ||||
|   case class Not(x: Expr6) extends Expr6 | ||||
|   object Not extends ParserBridge1[Expr6, Not] | ||||
|   case class Len(x: Expr6) extends Expr6 | ||||
|   object Len extends ParserBridge1[Expr6, Len] | ||||
|   case class Ord(x: Expr6) extends Expr6 | ||||
|   object Ord extends ParserBridge1[Expr6, Ord] | ||||
|   case class Chr(x: Expr6) extends Expr6 | ||||
|   object Chr extends ParserBridge1[Expr6, Chr] | ||||
|   sealed trait UnaryOp extends Expr { | ||||
|     val x: Expr | ||||
|   } | ||||
|   case class Negate(x: Expr6)(pos: Position) extends Expr6 with UnaryOp | ||||
|   object Negate extends ParserBridgePos1[Expr6, Negate] | ||||
|   case class Not(x: Expr6)(pos: Position) extends Expr6 with UnaryOp | ||||
|   object Not extends ParserBridgePos1[Expr6, Not] | ||||
|   case class Len(x: Expr6)(pos: Position) extends Expr6 with UnaryOp | ||||
|   object Len extends ParserBridgePos1[Expr6, Len] | ||||
|   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 | ||||
|   case class Add(x: Expr4, y: Expr5) extends Expr4 | ||||
|   object Add extends ParserBridge2[Expr4, Expr5, Add] | ||||
|   case class Sub(x: Expr4, y: Expr5) extends Expr4 | ||||
|   object Sub extends ParserBridge2[Expr4, Expr5, Sub] | ||||
|   case class Mul(x: Expr5, y: Expr6) extends Expr5 | ||||
|   object Mul extends ParserBridge2[Expr5, Expr6, Mul] | ||||
|   case class Div(x: Expr5, y: Expr6) extends Expr5 | ||||
|   object Div extends ParserBridge2[Expr5, Expr6, Div] | ||||
|   case class Mod(x: Expr5, y: Expr6) extends Expr5 | ||||
|   object Mod extends ParserBridge2[Expr5, Expr6, Mod] | ||||
|   case class Greater(x: Expr4, y: Expr4) extends Expr3 | ||||
|   object Greater extends ParserBridge2[Expr4, Expr4, Greater] | ||||
|   case class GreaterEq(x: Expr4, y: Expr4) extends Expr3 | ||||
|   object GreaterEq extends ParserBridge2[Expr4, Expr4, GreaterEq] | ||||
|   case class Less(x: Expr4, y: Expr4) extends Expr3 | ||||
|   object Less extends ParserBridge2[Expr4, Expr4, Less] | ||||
|   case class LessEq(x: Expr4, y: Expr4) extends Expr3 | ||||
|   object LessEq extends ParserBridge2[Expr4, Expr4, LessEq] | ||||
|   case class Eq(x: Expr3, y: Expr3) extends Expr2 | ||||
|   object Eq extends ParserBridge2[Expr3, Expr3, Eq] | ||||
|   case class Neq(x: Expr3, y: Expr3) extends Expr2 | ||||
|   object Neq extends ParserBridge2[Expr3, Expr3, Neq] | ||||
|   case class And(x: Expr2, y: Expr1) extends Expr1 | ||||
|   object And extends ParserBridge2[Expr2, Expr1, And] | ||||
|   case class Or(x: Expr1, y: Expr) extends Expr | ||||
|   object Or extends ParserBridge2[Expr1, Expr, Or] | ||||
|   sealed trait BinaryOp extends Expr { | ||||
|     val x: Expr | ||||
|     val y: Expr | ||||
|   } | ||||
|   case class Add(x: Expr4, y: Expr5)(pos: Position) extends Expr4 with BinaryOp | ||||
|   object Add extends ParserBridgePos2[Expr4, Expr5, Add] | ||||
|   case class Sub(x: Expr4, y: Expr5)(pos: Position) extends Expr4 with BinaryOp | ||||
|   object Sub extends ParserBridgePos2[Expr4, Expr5, Sub] | ||||
|   case class Mul(x: Expr5, y: Expr6)(pos: Position) extends Expr5 with BinaryOp | ||||
|   object Mul extends ParserBridgePos2[Expr5, Expr6, Mul] | ||||
|   case class Div(x: Expr5, y: Expr6)(pos: Position) extends Expr5 with BinaryOp | ||||
|   object Div extends ParserBridgePos2[Expr5, Expr6, Div] | ||||
|   case class Mod(x: Expr5, y: Expr6)(pos: Position) extends Expr5 with BinaryOp | ||||
|   object Mod extends ParserBridgePos2[Expr5, Expr6, Mod] | ||||
|   case class Greater(x: Expr4, y: Expr4)(pos: Position) extends Expr3 with BinaryOp | ||||
|   object Greater extends ParserBridgePos2[Expr4, Expr4, Greater] | ||||
|   case class GreaterEq(x: Expr4, y: Expr4)(pos: Position) extends Expr3 with BinaryOp | ||||
|   object GreaterEq extends ParserBridgePos2[Expr4, Expr4, GreaterEq] | ||||
|   case class Less(x: Expr4, y: Expr4)(pos: Position) extends Expr3 with BinaryOp | ||||
|   object Less extends ParserBridgePos2[Expr4, Expr4, Less] | ||||
|   case class LessEq(x: Expr4, y: Expr4)(pos: Position) extends Expr3 with BinaryOp | ||||
|   object LessEq extends ParserBridgePos2[Expr4, Expr4, LessEq] | ||||
|   case class Eq(x: Expr3, y: Expr3)(pos: Position) extends Expr2 with BinaryOp | ||||
|   object Eq extends ParserBridgePos2[Expr3, Expr3, Eq] | ||||
|   case class Neq(x: Expr3, y: Expr3)(pos: Position) extends Expr2 with BinaryOp | ||||
|   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 | ||||
|   sealed trait Type | ||||
|   sealed trait BaseType extends Type with PairElemType | ||||
|   case object IntType extends BaseType with ParserBridge0[IntType.type] | ||||
|   case object BoolType extends BaseType with ParserBridge0[BoolType.type] | ||||
|   case object CharType extends BaseType with ParserBridge0[CharType.type] | ||||
|   case object StringType extends BaseType with ParserBridge0[StringType.type] | ||||
|   case class ArrayType(elemType: Type, dimensions: Int) extends Type with PairElemType | ||||
|   object ArrayType extends ParserBridge2[Type, Int, ArrayType] | ||||
|   case class PairType(fst: PairElemType, snd: PairElemType) extends Type | ||||
|   object PairType extends ParserBridge2[PairElemType, PairElemType, PairType] | ||||
|   case class IntType()(pos: Position) extends BaseType | ||||
|   object IntType extends ParserBridgePos0[IntType] | ||||
|   case class BoolType()(pos: Position) extends BaseType | ||||
|   object BoolType extends ParserBridgePos0[BoolType] | ||||
|   case class CharType()(pos: Position) extends BaseType | ||||
|   object CharType extends ParserBridgePos0[CharType] | ||||
|   case class StringType()(pos: Position) extends BaseType | ||||
|   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 | ||||
|   case object UntypedPairType extends PairElemType with ParserBridge0[UntypedPairType.type] | ||||
|   case class UntypedPairType()(pos: Position) extends PairElemType | ||||
|   object UntypedPairType extends ParserBridgePos0[UntypedPairType] | ||||
|  | ||||
|   // waccadoodledo | ||||
|   case class Program(funcs: List[FuncDecl], main: NonEmptyList[Stmt]) | ||||
|   object Program extends ParserBridge2[List[FuncDecl], NonEmptyList[Stmt], Program] | ||||
|   case class Program(funcs: List[FuncDecl], main: NonEmptyList[Stmt])(pos: Position) | ||||
|   object Program extends ParserBridgePos2[List[FuncDecl], NonEmptyList[Stmt], Program] | ||||
|  | ||||
|   // Function Definitions | ||||
|   case class FuncDecl( | ||||
| @@ -95,49 +115,115 @@ object ast { | ||||
|       name: Ident, | ||||
|       params: List[Param], | ||||
|       body: NonEmptyList[Stmt] | ||||
|   ) | ||||
|   object FuncDecl extends ParserBridge4[Type, Ident, List[Param], NonEmptyList[Stmt], FuncDecl] | ||||
|   )(pos: Position) | ||||
|   object FuncDecl extends ParserBridgePos4[Type, Ident, List[Param], NonEmptyList[Stmt], FuncDecl] | ||||
|  | ||||
|   case class Param(paramType: Type, name: Ident) | ||||
|   object Param extends ParserBridge2[Type, Ident, Param] | ||||
|   case class Param(paramType: Type, name: Ident)(pos: Position) | ||||
|   object Param extends ParserBridgePos2[Type, Ident, Param] | ||||
|  | ||||
|   // Statements | ||||
|   sealed trait Stmt | ||||
|   case object Skip extends Stmt with ParserBridge0[Skip.type] | ||||
|   case class VarDecl(varType: Type, name: Ident, value: RValue) extends Stmt | ||||
|   object VarDecl extends ParserBridge3[Type, Ident, RValue, VarDecl] | ||||
|   case class Assign(lhs: LValue, value: RValue) extends Stmt | ||||
|   object Assign extends ParserBridge2[LValue, RValue, Assign] | ||||
|   case class Read(lhs: LValue) extends Stmt | ||||
|   object Read extends ParserBridge1[LValue, Read] | ||||
|   case class Free(expr: Expr) extends Stmt | ||||
|   object Free extends ParserBridge1[Expr, Free] | ||||
|   case class Return(expr: Expr) extends Stmt | ||||
|   object Return extends ParserBridge1[Expr, Return] | ||||
|   case class Exit(expr: Expr) extends Stmt | ||||
|   object Exit extends ParserBridge1[Expr, Exit] | ||||
|   case class Print(expr: Expr, newline: Boolean) extends Stmt | ||||
|   object Print extends ParserBridge2[Expr, Boolean, Print] | ||||
|   case class If(cond: Expr, thenStmt: NonEmptyList[Stmt], elseStmt: NonEmptyList[Stmt]) extends Stmt | ||||
|   object If extends ParserBridge3[Expr, NonEmptyList[Stmt], NonEmptyList[Stmt], If] | ||||
|   case class While(cond: Expr, body: NonEmptyList[Stmt]) extends Stmt | ||||
|   object While extends ParserBridge2[Expr, NonEmptyList[Stmt], While] | ||||
|   case class Block(stmt: NonEmptyList[Stmt]) extends Stmt | ||||
|   object Block extends ParserBridge1[NonEmptyList[Stmt], Block] | ||||
|   case class Skip()(pos: Position) extends Stmt | ||||
|   object Skip extends ParserBridgePos0[Skip] | ||||
|   case class VarDecl(varType: Type, name: Ident, value: RValue)(pos: Position) extends Stmt | ||||
|   object VarDecl extends ParserBridgePos3[Type, Ident, RValue, VarDecl] | ||||
|   case class Assign(lhs: LValue, value: RValue)(pos: Position) extends Stmt | ||||
|   object Assign extends ParserBridgePos2[LValue, RValue, Assign] | ||||
|   case class Read(lhs: LValue)(pos: Position) extends Stmt | ||||
|   object Read extends ParserBridgePos1[LValue, Read] | ||||
|   case class Free(expr: Expr)(pos: Position) extends Stmt | ||||
|   object Free extends ParserBridgePos1[Expr, Free] | ||||
|   case class Return(expr: Expr)(pos: Position) extends Stmt | ||||
|   object Return extends ParserBridgePos1[Expr, Return] | ||||
|   case class Exit(expr: Expr)(pos: Position) extends Stmt | ||||
|   object Exit extends ParserBridgePos1[Expr, Exit] | ||||
|   case class Print(expr: Expr, newline: Boolean)(pos: Position) extends Stmt | ||||
|   object Print extends ParserBridgePos2[Expr, Boolean, Print] | ||||
|   case class If(cond: Expr, thenStmt: NonEmptyList[Stmt], elseStmt: NonEmptyList[Stmt])( | ||||
|       pos: Position | ||||
|   ) extends Stmt | ||||
|   object If extends ParserBridgePos3[Expr, NonEmptyList[Stmt], NonEmptyList[Stmt], If] | ||||
|   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 RValue | ||||
|   case class ArrayLiter(elems: List[Expr]) extends RValue | ||||
|   object ArrayLiter extends ParserBridge1[List[Expr], ArrayLiter] | ||||
|   case class NewPair(fst: Expr, snd: Expr) extends RValue | ||||
|   object NewPair extends ParserBridge2[Expr, Expr, NewPair] | ||||
|   case class Call(name: Ident, args: List[Expr]) extends RValue | ||||
|   object Call extends ParserBridge2[Ident, List[Expr], Call] | ||||
|   case class ArrayLiter(elems: List[Expr])(pos: Position) extends RValue | ||||
|   object ArrayLiter extends ParserBridgePos1[List[Expr], ArrayLiter] | ||||
|   case class NewPair(fst: Expr, snd: Expr)(pos: Position) extends RValue | ||||
|   object NewPair extends ParserBridgePos2[Expr, Expr, NewPair] | ||||
|   case class Call(name: Ident, args: List[Expr])(pos: Position) extends RValue | ||||
|   object Call extends ParserBridgePos2[Ident, List[Expr], Call] | ||||
|  | ||||
|   sealed trait PairElem extends LValue with RValue | ||||
|   case class Fst(elem: LValue) extends PairElem | ||||
|   object Fst extends ParserBridge1[LValue, Fst] | ||||
|   case class Snd(elem: LValue) extends PairElem | ||||
|   object Snd extends ParserBridge1[LValue, Snd] | ||||
|   case class Fst(elem: LValue)(pos: Position) extends PairElem | ||||
|   object Fst extends ParserBridgePos1[LValue, Fst] | ||||
|   case class Snd(elem: LValue)(pos: Position) extends PairElem | ||||
|   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)) | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user