use crate::front::span::Span;
use crate::ir::BinaryOp;
use std::cmp::PartialEq;
#[derive(Debug)]
pub struct Ast {
pub span: Span,
pub kind: AstKind,
}
pub type AstBox = Box<Ast>;
impl Ast {
pub(in crate::front) fn new_boxed(span: Span, kind: AstKind) -> AstBox {
Box::new(Self { span, kind })
}
}
impl PartialEq for Ast {
fn eq(&self, other: &Self) -> bool {
self.kind == other.kind
}
}
#[derive(Debug, PartialEq)]
pub enum AstKind {
IntType(IntType),
ArrayType(ArrayType),
PointerType(PointerType),
FunType(FunType),
SymbolRef(SymbolRef),
IntVal(IntVal),
UndefVal(UndefVal),
Aggregate(Aggregate),
ZeroInit(ZeroInit),
SymbolDef(SymbolDef),
GlobalDef(GlobalDef),
MemDecl(MemDecl),
GlobalDecl(GlobalDecl),
Load(Load),
Store(Store),
GetPointer(GetPointer),
GetElementPointer(GetElementPointer),
BinaryExpr(BinaryExpr),
Branch(Branch),
Jump(Jump),
FunCall(FunCall),
Return(Return),
FunDef(FunDef),
Block(Block),
FunDecl(FunDecl),
End(End),
Error(Error),
}
#[derive(Debug, PartialEq, Eq)]
pub struct IntType;
impl IntType {
pub fn new_boxed(span: Span) -> AstBox {
Ast::new_boxed(span, AstKind::IntType(Self))
}
}
#[derive(Debug, PartialEq)]
pub struct ArrayType {
pub base: AstBox,
pub len: usize,
}
impl ArrayType {
pub fn new_boxed(span: Span, base: AstBox, len: usize) -> AstBox {
Ast::new_boxed(span, AstKind::ArrayType(Self { base, len }))
}
}
#[derive(Debug, PartialEq)]
pub struct PointerType {
pub base: AstBox,
}
impl PointerType {
pub fn new_boxed(span: Span, base: AstBox) -> AstBox {
Ast::new_boxed(span, AstKind::PointerType(Self { base }))
}
}
#[derive(Debug, PartialEq)]
pub struct FunType {
pub params: Vec<AstBox>,
pub ret: Option<AstBox>,
}
impl FunType {
pub fn new_boxed(span: Span, params: Vec<AstBox>, ret: Option<AstBox>) -> AstBox {
Ast::new_boxed(span, AstKind::FunType(Self { params, ret }))
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct SymbolRef {
pub symbol: String,
}
impl SymbolRef {
pub fn new_boxed(span: Span, symbol: String) -> AstBox {
Ast::new_boxed(span, AstKind::SymbolRef(Self { symbol }))
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct IntVal {
pub value: i32,
}
impl IntVal {
pub fn new_boxed(span: Span, value: i32) -> AstBox {
Ast::new_boxed(span, AstKind::IntVal(Self { value }))
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct UndefVal;
impl UndefVal {
pub fn new_boxed(span: Span) -> AstBox {
Ast::new_boxed(span, AstKind::UndefVal(Self))
}
}
#[derive(Debug, PartialEq)]
pub struct Aggregate {
pub elems: Vec<AstBox>,
}
impl Aggregate {
pub fn new_boxed(span: Span, elems: Vec<AstBox>) -> AstBox {
Ast::new_boxed(span, AstKind::Aggregate(Self { elems }))
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct ZeroInit;
impl ZeroInit {
pub fn new_boxed(span: Span) -> AstBox {
Ast::new_boxed(span, AstKind::ZeroInit(Self))
}
}
#[derive(Debug, PartialEq)]
pub struct SymbolDef {
pub name: String,
pub value: AstBox,
}
impl SymbolDef {
pub fn new_boxed(span: Span, name: String, value: AstBox) -> AstBox {
Ast::new_boxed(span, AstKind::SymbolDef(Self { name, value }))
}
}
#[derive(Debug, PartialEq)]
pub struct GlobalDef {
pub name: String,
pub value: AstBox,
}
impl GlobalDef {
pub fn new_boxed(span: Span, name: String, value: AstBox) -> AstBox {
Ast::new_boxed(span, AstKind::GlobalDef(Self { name, value }))
}
}
#[derive(Debug, PartialEq)]
pub struct MemDecl {
pub ty: AstBox,
}
impl MemDecl {
pub fn new_boxed(span: Span, ty: AstBox) -> AstBox {
Ast::new_boxed(span, AstKind::MemDecl(Self { ty }))
}
}
#[derive(Debug, PartialEq)]
pub struct GlobalDecl {
pub ty: AstBox,
pub init: AstBox,
}
impl GlobalDecl {
pub fn new_boxed(span: Span, ty: AstBox, init: AstBox) -> AstBox {
Ast::new_boxed(span, AstKind::GlobalDecl(Self { ty, init }))
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct Load {
pub symbol: String,
}
impl Load {
pub fn new_boxed(span: Span, symbol: String) -> AstBox {
Ast::new_boxed(span, AstKind::Load(Self { symbol }))
}
}
#[derive(Debug, PartialEq)]
pub struct Store {
pub value: AstBox,
pub symbol: String,
}
impl Store {
pub fn new_boxed(span: Span, value: AstBox, symbol: String) -> AstBox {
Ast::new_boxed(span, AstKind::Store(Self { value, symbol }))
}
}
#[derive(Debug, PartialEq)]
pub struct GetPointer {
pub symbol: String,
pub value: AstBox,
}
impl GetPointer {
pub fn new_boxed(span: Span, symbol: String, value: AstBox) -> AstBox {
Ast::new_boxed(span, AstKind::GetPointer(Self { symbol, value }))
}
}
#[derive(Debug, PartialEq)]
pub struct GetElementPointer {
pub symbol: String,
pub value: AstBox,
}
impl GetElementPointer {
pub fn new_boxed(span: Span, symbol: String, value: AstBox) -> AstBox {
Ast::new_boxed(span, AstKind::GetElementPointer(Self { symbol, value }))
}
}
#[derive(Debug, PartialEq)]
pub struct BinaryExpr {
pub op: BinaryOp,
pub lhs: AstBox,
pub rhs: AstBox,
}
impl BinaryExpr {
pub fn new_boxed(span: Span, op: BinaryOp, lhs: AstBox, rhs: AstBox) -> AstBox {
Ast::new_boxed(span, AstKind::BinaryExpr(Self { op, lhs, rhs }))
}
}
#[derive(Debug, PartialEq)]
pub struct Branch {
pub cond: AstBox,
pub tbb: String,
pub targs: Vec<AstBox>,
pub fbb: String,
pub fargs: Vec<AstBox>,
}
impl Branch {
pub fn new_boxed(
span: Span,
cond: AstBox,
tbb: String,
targs: Vec<AstBox>,
fbb: String,
fargs: Vec<AstBox>,
) -> AstBox {
Ast::new_boxed(
span,
AstKind::Branch(Self {
cond,
tbb,
targs,
fbb,
fargs,
}),
)
}
}
#[derive(Debug, PartialEq)]
pub struct Jump {
pub target: String,
pub args: Vec<AstBox>,
}
impl Jump {
pub fn new_boxed(span: Span, target: String, args: Vec<AstBox>) -> AstBox {
Ast::new_boxed(span, AstKind::Jump(Self { target, args }))
}
}
#[derive(Debug, PartialEq)]
pub struct FunCall {
pub fun: String,
pub args: Vec<AstBox>,
}
impl FunCall {
pub fn new_boxed(span: Span, fun: String, args: Vec<AstBox>) -> AstBox {
Ast::new_boxed(span, AstKind::FunCall(Self { fun, args }))
}
}
#[derive(Debug, PartialEq)]
pub struct Return {
pub value: Option<AstBox>,
}
impl Return {
pub fn new_boxed(span: Span, value: Option<AstBox>) -> AstBox {
Ast::new_boxed(span, AstKind::Return(Self { value }))
}
}
#[derive(Debug, PartialEq)]
pub struct FunDef {
pub name: String,
pub params: Vec<(String, AstBox)>,
pub ret: Option<AstBox>,
pub bbs: Vec<AstBox>,
}
impl FunDef {
pub fn new_boxed(
span: Span,
name: String,
params: Vec<(String, AstBox)>,
ret: Option<AstBox>,
bbs: Vec<AstBox>,
) -> AstBox {
Ast::new_boxed(
span,
AstKind::FunDef(Self {
name,
params,
ret,
bbs,
}),
)
}
}
#[derive(Debug, PartialEq)]
pub struct Block {
pub name: String,
pub params: Vec<(String, AstBox)>,
pub stmts: Vec<AstBox>,
}
impl Block {
pub fn new_boxed(
span: Span,
name: String,
params: Vec<(String, AstBox)>,
stmts: Vec<AstBox>,
) -> AstBox {
Ast::new_boxed(
span,
AstKind::Block(Self {
name,
params,
stmts,
}),
)
}
}
#[derive(Debug, PartialEq)]
pub struct FunDecl {
pub name: String,
pub params: Vec<AstBox>,
pub ret: Option<AstBox>,
}
impl FunDecl {
pub fn new_boxed(span: Span, name: String, params: Vec<AstBox>, ret: Option<AstBox>) -> AstBox {
Ast::new_boxed(span, AstKind::FunDecl(Self { name, params, ret }))
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct End;
impl End {
pub fn new_boxed(span: Span) -> AstBox {
Ast::new_boxed(span, AstKind::End(Self))
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct Error;
impl Error {
pub fn new_boxed(span: Span) -> AstBox {
Ast::new_boxed(span, AstKind::Error(Self))
}
}