lila/src/ast/expr.rs

78 lines
1.8 KiB
Rust

use crate::ast::*;
use crate::typing::Type;
#[derive(Debug, PartialEq)]
pub struct SExpr {
pub expr: Expr,
pub span: Span,
}
#[derive(Debug, PartialEq)]
pub struct BinaryExpression {
pub lhs: Box<SExpr>,
pub op: BinaryOperator,
pub op_span: Span,
pub rhs: Box<SExpr>,
pub typ: Type,
}
#[derive(Debug, PartialEq)]
pub enum Expr {
BinaryExpression(BinaryExpression),
UnaryExpression {
op: UnaryOperator,
inner: Box<SExpr>,
},
Identifier {
name: String,
typ: Type,
},
Call(Box<Call>),
Block(Box<Block>),
/// Last field is either Expr::Block or Expr::IfExpr
IfExpr {
cond: Box<SExpr>,
then_body: Box<Block>,
else_body: Box<SExpr>,
typ: Type,
},
// Literals
UnitLiteral,
BooleanLiteral(bool),
IntegerLiteral(i64),
FloatLiteral(f64),
StringLiteral(String),
}
impl Block {
#[inline]
pub fn ty(&self) -> Type {
// XXX: Cloning may be expensive -> TypeId?
self.typ.clone()
}
}
impl Expr {
pub fn ty(&self) -> Type {
match self {
Expr::BinaryExpression(BinaryExpression { typ, .. }) => typ.clone(),
Expr::UnaryExpression { inner, .. } => inner.ty(), // XXX: problems will arise here
Expr::Identifier { typ, .. } => typ.clone(),
Expr::Call(call) => call.typ.clone(),
Expr::Block(block) => block.typ.clone(),
Expr::IfExpr { typ, .. } => typ.clone(),
Expr::UnitLiteral => Type::Unit,
Expr::BooleanLiteral(_) => Type::Bool,
Expr::IntegerLiteral(_) => Type::Int,
Expr::FloatLiteral(_) => Type::Float,
Expr::StringLiteral(_) => Type::Str,
}
}
}
impl SExpr {
#[inline]
pub fn ty(&self) -> Type {
self.expr.ty()
}
}