package wacc import parsley.generic._ import cats.data.NonEmptyList object ast { // Expressions sealed trait Expr extends RValue sealed trait Expr1 extends Expr sealed trait Expr2 extends Expr1 sealed trait Expr3 extends Expr2 sealed trait Expr4 extends Expr3 sealed trait Expr5 extends Expr4 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] // 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] // 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] // 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] sealed trait PairElemType case object UntypedPairType extends PairElemType with ParserBridge0[UntypedPairType.type] // waccadoodledo case class Program(funcs: List[FuncDecl], main: NonEmptyList[Stmt]) object Program extends ParserBridge2[List[FuncDecl], NonEmptyList[Stmt], Program] // Function Definitions case class FuncDecl( returnType: Type, name: Ident, params: List[Param], body: NonEmptyList[Stmt] ) object FuncDecl extends ParserBridge4[Type, Ident, List[Param], NonEmptyList[Stmt], FuncDecl] case class Param(paramType: Type, name: Ident) object Param extends ParserBridge2[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] 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] 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] }