feat: initial ast implementation

This commit is contained in:
Jonny 2025-01-31 17:54:30 +00:00 committed by Gleb Koval
parent 78ef878fb2
commit 49ebf2f7d0

165
src/main/wacc/ast.scala Normal file
View File

@ -0,0 +1,165 @@
package wacc
import parsley.generic._
// TODO - Note that I have opted for object Add extends ParserBridge2[Expr5, Expr6, Add] instead of object Add extends ParserBridge2[Expr5, Expr6, Expr5]
// Reason: Better type safety / pattern matching ? We can change this at any time.
// For consistency in case objects you may see I extended the parser bridge pattern with ".type"
// Personally I am not a fan
// TODO - Obviously layout issues, could follow Haskell interlude style
object ast {
// Expressions
sealed trait Expr
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
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]
// TODO: with LValue questionable (see LValue BNF)
case class Ident(v: String) extends Expr6 with LValue
object Ident extends ParserBridge1[String, Ident]
case class ArrayElem(name: String, indices: List[Expr])
extends Expr6
with LValue
object ArrayElem extends ParserBridge2[String, List[Expr], ArrayElem]
case class UnaryOper(op: UnaryOperator, expr: Expr6) extends Expr6
object UnaryOper extends ParserBridge2[UnaryOperator, Expr6, UnaryOper]
// R values
sealed trait RValue
case class ArrayLiter(elems: List[Expr]) extends Expr6 with RValue
object ArrayLiter extends ParserBridge1[List[Expr], ArrayLiter]
case class NewPair(fst: Expr, snd: Expr) extends Expr6 with RValue
object NewPair extends ParserBridge2[Expr, Expr, NewPair]
case class Call(name: String, args: List[Expr]) extends Expr6 with RValue
object Call extends ParserBridge2[String, List[Expr], Call]
// Operators
sealed trait UnaryOperator
case object Negate extends UnaryOperator with ParserBridge0[Negate.type]
case object Not extends UnaryOperator with ParserBridge0[Not.type]
case object Len extends UnaryOperator with ParserBridge0[Len.type]
case object Ord extends UnaryOperator with ParserBridge0[Ord.type]
case object Chr extends UnaryOperator with ParserBridge0[Chr.type]
sealed trait BinaryOperator
case class Add(x: Expr5, y: Expr6) extends Expr5
object Add extends ParserBridge2[Expr5, Expr6, Add]
case class Sub(x: Expr5, y: Expr6) extends Expr5
object Sub extends ParserBridge2[Expr5, Expr6, Sub]
case class Mul(x: Expr6, y: Expr6) extends Expr6
object Mul extends ParserBridge2[Expr6, Expr6, Mul]
case class Div(x: Expr6, y: Expr6) extends Expr6
object Div extends ParserBridge2[Expr6, Expr6, Div]
case class Mod(x: Expr6, y: Expr6) extends Expr6
object Mod extends ParserBridge2[Expr6, 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: Expr4, y: Expr4) extends Expr3
object Eq extends ParserBridge2[Expr4, Expr4, Eq]
case class Neq(x: Expr4, y: Expr4) extends Expr3
object Neq extends ParserBridge2[Expr4, Expr4, Neq]
case class And(x: Expr2, y: Expr2) extends Expr2
object And extends ParserBridge2[Expr2, Expr2, And]
case class Or(x: Expr1, y: Expr1) extends Expr1
object Or extends ParserBridge2[Expr1, Expr1, Or]
// Statements
sealed trait Stmt
case object Skip extends Stmt with ParserBridge0[Skip.type]
case class VarDecl(varType: Type, name: String, expr: Expr) extends Stmt
object VarDecl extends ParserBridge3[Type, String, Expr, VarDecl]
case class Assign(lhs: LValue, expr: Expr) extends Stmt
object Assign extends ParserBridge2[LValue, Expr, 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: Stmt, elseStmt: Stmt) extends Stmt
object If extends ParserBridge3[Expr, Stmt, Stmt, If]
case class While(cond: Expr, body: Stmt) extends Stmt
object While extends ParserBridge2[Expr, Stmt, While]
case class SeqStmt(stmt1: Stmt, stmt2: Stmt) extends Stmt
object SeqStmt extends ParserBridge2[Stmt, Stmt, SeqStmt]
// LValues
sealed trait LValue
// Pair Elements
sealed trait PairElem extends LValue
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]
// Function Defns
case class FuncDecl(
returnType: Type,
name: String,
params: List[Param],
body: Stmt
)
object FuncDecl
extends ParserBridge4[Type, String, List[Param], Stmt, FuncDecl]
case class Param(paramType: Type, name: String)
object Param extends ParserBridge2[Type, String, Param]
// waccadoodledo
case class Program(funcs: List[FuncDecl], main: Stmt)
object Program extends ParserBridge2[List[FuncDecl], Stmt, Program]
// Types
sealed trait Type
case object IntType extends Type with ParserBridge0[IntType.type]
case object BoolType extends Type with ParserBridge0[BoolType.type]
case object CharType extends Type with ParserBridge0[CharType.type]
case object StringType extends Type with ParserBridge0[StringType.type]
case class ArrayType(elemType: Type) extends Type
object ArrayType extends ParserBridge1[Type, ArrayType]
case class PairType(fst: PairElemType, snd: PairElemType) extends Type
object PairType extends ParserBridge2[PairElemType, PairElemType, PairType]
sealed trait PairElemType
case object PairBaseType
extends PairElemType
with ParserBridge0[PairBaseType.type]
case class PairArrayType(baseType: Type) extends PairElemType
object PairArrayType extends ParserBridge1[Type, PairArrayType]
}