78 lines
1.8 KiB
Rust
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()
|
|
}
|
|
}
|