diff --git a/project.scala b/project.scala index 7a42a9c..e6fb151 100644 --- a/project.scala +++ b/project.scala @@ -3,6 +3,7 @@ // dependencies //> using dep com.github.j-mie6::parsley::5.0.0-M10 +//> using dep com.github.j-mie6::parsley-cats::1.3.0 //> using dep com.lihaoyi::os-lib::0.11.3 //> using dep com.github.scopt::scopt::4.1.0 //> using test.dep org.scalatest::scalatest::3.2.19 diff --git a/src/main/wacc/ast.scala b/src/main/wacc/ast.scala new file mode 100644 index 0000000..c6e743e --- /dev/null +++ b/src/main/wacc/ast.scala @@ -0,0 +1,143 @@ +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] +}