98 lines
3.0 KiB
Scala
98 lines
3.0 KiB
Scala
package wacc
|
|
|
|
import cats.data.Chain
|
|
|
|
object microWacc {
|
|
import wacc.ast.Position
|
|
import wacc.types._
|
|
|
|
sealed trait CallTarget(val retTy: SemType)
|
|
sealed trait Expr(val ty: SemType)
|
|
sealed trait LValue extends Expr
|
|
|
|
// Atomic expressions
|
|
case class IntLiter(v: Int) extends Expr(KnownType.Int)
|
|
case class BoolLiter(v: Boolean) extends Expr(KnownType.Bool)
|
|
case class CharLiter(v: Char) extends Expr(KnownType.Char)
|
|
case class ArrayLiter(elems: List[Expr])(ty: SemType, val pos: Position) extends Expr(ty)
|
|
case class NullLiter()(ty: SemType) extends Expr(ty)
|
|
case class Ident(name: String, uid: Int)(identTy: SemType)
|
|
extends Expr(identTy)
|
|
with CallTarget(identTy)
|
|
with LValue
|
|
case class ArrayElem(value: LValue, index: Expr)(ty: SemType) extends Expr(ty) with LValue
|
|
|
|
// Operators
|
|
case class UnaryOp(x: Expr, op: UnaryOperator)(ty: SemType) extends Expr(ty)
|
|
enum UnaryOperator {
|
|
case Negate
|
|
case Not
|
|
case Len
|
|
case Ord
|
|
case Chr
|
|
}
|
|
case class BinaryOp(x: Expr, y: Expr, op: BinaryOperator)(ty: SemType) extends Expr(ty)
|
|
enum BinaryOperator {
|
|
case Add
|
|
case Sub
|
|
case Mul
|
|
case Div
|
|
case Mod
|
|
case Greater
|
|
case GreaterEq
|
|
case Less
|
|
case LessEq
|
|
case Eq
|
|
case Neq
|
|
case And
|
|
case Or
|
|
}
|
|
object BinaryOperator {
|
|
def fromAst(op: ast.BinaryOp): BinaryOperator = op match {
|
|
case _: ast.Add => Add
|
|
case _: ast.Sub => Sub
|
|
case _: ast.Mul => Mul
|
|
case _: ast.Div => Div
|
|
case _: ast.Mod => Mod
|
|
case _: ast.Greater => Greater
|
|
case _: ast.GreaterEq => GreaterEq
|
|
case _: ast.Less => Less
|
|
case _: ast.LessEq => LessEq
|
|
case _: ast.Eq => Eq
|
|
case _: ast.Neq => Neq
|
|
case _: ast.And => And
|
|
case _: ast.Or => Or
|
|
}
|
|
}
|
|
|
|
// Statements
|
|
sealed trait Stmt {
|
|
val pos: Position
|
|
}
|
|
|
|
case class Builtin(val name: String)(retTy: SemType) extends CallTarget(retTy) {
|
|
override def toString(): String = name
|
|
}
|
|
object Builtin {
|
|
object Read extends Builtin("read")(?)
|
|
object Printf extends Builtin("printf")(?)
|
|
object Exit extends Builtin("exit")(?)
|
|
object Free extends Builtin("free")(?)
|
|
object Malloc extends Builtin("malloc")(?)
|
|
object PrintCharArray extends Builtin("printCharArray")(?)
|
|
}
|
|
|
|
case class Assign(lhs: LValue, rhs: Expr)(val pos: Position) extends Stmt
|
|
case class If(cond: Expr, thenBranch: Chain[Stmt], elseBranch: Chain[Stmt])(val pos: Position)
|
|
extends Stmt
|
|
case class While(cond: Expr, body: Chain[Stmt])(val pos: Position) extends Stmt
|
|
case class Call(target: CallTarget, args: List[Expr])(val pos: Position)
|
|
extends Stmt
|
|
with Expr(target.retTy)
|
|
case class Return(expr: Expr)(val pos: Position) extends Stmt
|
|
|
|
// Program
|
|
case class FuncDecl(name: Ident, params: List[Ident], body: Chain[Stmt])(val pos: Position)
|
|
case class Program(funcs: Chain[FuncDecl], stmts: Chain[Stmt])(val pos: Position)
|
|
}
|