feat: implement abstract syntax tree

Merge request lab2425_spring/WACC_37!4

Co-authored-by: Jonny <j.sinteix@gmail.com>
This commit is contained in:
Gleb Koval 2025-02-02 13:37:48 +00:00
commit feac5efb6a
2 changed files with 144 additions and 0 deletions

View File

@ -3,6 +3,7 @@
// dependencies // dependencies
//> using dep com.github.j-mie6::parsley::5.0.0-M10 //> 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.lihaoyi::os-lib::0.11.3
//> using dep com.github.scopt::scopt::4.1.0 //> using dep com.github.scopt::scopt::4.1.0
//> using test.dep org.scalatest::scalatest::3.2.19 //> using test.dep org.scalatest::scalatest::3.2.19

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

@ -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]
}