Files
WACC_37/src/main/wacc/ast.scala

229 lines
10 KiB
Scala

package wacc
import parsley.Parsley
import parsley.generic.ErrorBridge
import parsley.ap._
import parsley.position._
import parsley.syntax.zipped._
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)(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 ParserBridgePos0[PairLiter]
case class Ident(v: String, var uid: Int = -1)(pos: Position) extends Expr6 with LValue
object Ident extends ParserBridgePos1[String, Ident] {
def apply(v: String)(pos: Position): Ident = new Ident(v)(pos)
}
case class ArrayElem(name: Ident, indices: NonEmptyList[Expr])(pos: Position)
extends Expr6
with LValue
object ArrayElem extends ParserBridgePos1[NonEmptyList[Expr], Ident => ArrayElem] {
def apply(a: NonEmptyList[Expr])(pos: Position): Ident => ArrayElem =
name => ArrayElem(name, a)(pos)
}
case class Parens(expr: Expr)(pos: Position) extends Expr6
object Parens extends ParserBridgePos1[Expr, Parens]
// Unary operators
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
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 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 ParserBridgePos1[Int, Type => ArrayType] {
def apply(a: Int)(pos: Position): Type => ArrayType = elemType => ArrayType(elemType, a)(pos)
}
case class PairType(fst: PairElemType, snd: PairElemType)(pos: Position) extends Type
object PairType extends ParserBridgePos2[PairElemType, PairElemType, PairType]
sealed trait PairElemType
case class UntypedPairType()(pos: Position) extends PairElemType
object UntypedPairType extends ParserBridgePos0[UntypedPairType]
// waccadoodledo
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(
returnType: Type,
name: Ident,
params: List[Param],
body: NonEmptyList[Stmt]
)(pos: Position)
object FuncDecl
extends ParserBridgePos2[
List[Param],
NonEmptyList[Stmt],
((Type, Ident)) => FuncDecl
] {
def apply(params: List[Param], body: NonEmptyList[Stmt])(
pos: Position
): ((Type, Ident)) => FuncDecl =
(returnType, name) => FuncDecl(returnType, name, params, body)(pos)
}
case class Param(paramType: Type, name: Ident)(pos: Position)
object Param extends ParserBridgePos2[Type, Ident, Param]
// Statements
sealed trait Stmt
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])(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)(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)
trait ParserSingletonBridgePos[+A] extends ErrorBridge {
protected def con(pos: (Int, Int), offset: Int): A
infix def from(op: Parsley[?]): Parsley[A] = error((pos, offset).zipped(con) <~ op)
final def <#(op: Parsley[?]): Parsley[A] = this from op
}
trait ParserBridgePos0[+A] extends ParserSingletonBridgePos[A] {
def apply()(pos: Position): A
override final def con(pos: (Int, Int), offset: Int): A =
apply()(Position(pos._1, pos._2, offset))
}
trait ParserBridgePos1[-A, +B] extends ParserSingletonBridgePos[A => B] {
def apply(a: A)(pos: Position): B
def apply(a: Parsley[A]): Parsley[B] = error(ap1((pos, offset).zipped(con), a))
override final def con(pos: (Int, Int), offset: Int): A => B =
this.apply(_)(Position(pos._1, pos._2, offset))
}
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(
ap2((pos, offset).zipped(con), a, b)
)
override final def con(pos: (Int, Int), offset: Int): (A, B) => C =
apply(_, _)(Position(pos._1, pos._2, offset))
}
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(
ap3((pos, offset).zipped(con), a, b, c)
)
override final def con(pos: (Int, Int), offset: Int): (A, B, C) => D =
apply(_, _, _)(Position(pos._1, pos._2, offset))
}
}