use crate::ast::{BinOp, Literal, Spanned};
use crate::ir::hir::{BuiltinCtor, BuiltinIntrinsic};
use crate::ir::{BuiltinId, CtorId, FnId, TypeId};
use super::program::LocalId;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MirLocal {
pub slot: LocalId,
pub last_use: bool,
pub name: String,
}
impl MirLocal {
pub fn at(slot: LocalId) -> Self {
Self {
slot,
last_use: false,
name: String::new(),
}
}
}
impl std::fmt::Display for MirLocal {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.last_use {
write!(f, "{}*", self.slot)
} else {
write!(f, "{}", self.slot)
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MirCtor {
User(CtorId),
Builtin(BuiltinCtor),
}
#[derive(Debug, Clone)]
pub enum MirExpr {
Literal(Spanned<Literal>),
Local(Spanned<MirLocal>),
Let(Spanned<MirLet>),
Call(Spanned<MirCall>),
TailCall(Spanned<MirTailCall>),
BinOp(Spanned<MirBinOp>),
Neg(Box<Spanned<MirExpr>>),
Match(Spanned<MirMatch>),
Construct(Spanned<MirConstruct>),
RecordCreate(Spanned<MirRecordCreate>),
RecordUpdate(Spanned<MirRecordUpdate>),
Project(Spanned<MirProject>),
IfThenElse(Spanned<MirIfThenElse>),
Try(Box<Spanned<MirExpr>>),
List(Vec<Spanned<MirExpr>>),
Tuple(Vec<Spanned<MirExpr>>),
MapLiteral(Vec<(Spanned<MirExpr>, Spanned<MirExpr>)>),
InterpolatedStr(Vec<MirStrPart>),
IndependentProduct(Spanned<MirIndependentProduct>),
Return(Box<Spanned<MirExpr>>),
FnValue(String),
Box(std::boxed::Box<Spanned<MirExpr>>),
Unbox(std::boxed::Box<Spanned<MirExpr>>),
}
#[derive(Debug, Clone)]
pub struct MirLet {
pub binding: LocalId,
pub binding_name: String,
pub value: Box<Spanned<MirExpr>>,
pub body: Box<Spanned<MirExpr>>,
}
#[derive(Debug, Clone)]
pub struct MirCall {
pub callee: MirCallee,
pub args: Vec<Spanned<MirExpr>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MirCallee {
Fn(FnId),
Builtin(BuiltinId),
Intrinsic(BuiltinIntrinsic),
LocalSlot {
slot: u16,
name: String,
last_use: bool,
},
}
#[derive(Debug, Clone)]
pub struct MirTailCall {
pub target: FnId,
pub args: Vec<Spanned<MirExpr>>,
}
#[derive(Debug, Clone)]
pub struct MirBinOp {
pub op: BinOp,
pub lhs: Box<Spanned<MirExpr>>,
pub rhs: Box<Spanned<MirExpr>>,
}
#[derive(Debug, Clone)]
pub struct MirMatch {
pub subject: Box<Spanned<MirExpr>>,
pub arms: Vec<MirMatchArm>,
}
#[derive(Debug, Clone)]
pub struct MirIfThenElse {
pub cond: Box<Spanned<MirExpr>>,
pub then_branch: Box<Spanned<MirExpr>>,
pub else_branch: Box<Spanned<MirExpr>>,
}
#[derive(Debug, Clone)]
pub struct MirMatchArm {
pub pattern: MirPattern,
pub body: Spanned<MirExpr>,
}
#[derive(Debug, Clone)]
pub enum MirPattern {
Wildcard,
Literal(Literal),
Bind(LocalId, String),
EmptyList,
Cons {
head: LocalId,
head_name: String,
tail: LocalId,
tail_name: String,
},
Tuple(Vec<MirPattern>),
Ctor {
ctor: MirCtor,
bindings: Vec<LocalId>,
binding_names: Vec<String>,
},
}
#[derive(Debug, Clone)]
pub struct MirConstruct {
pub ctor: MirCtor,
pub args: Vec<Spanned<MirExpr>>,
}
#[derive(Debug, Clone)]
pub struct MirRecordCreate {
pub type_id: Option<TypeId>,
pub type_name: String,
pub fields: Vec<MirRecordField>,
}
#[derive(Debug, Clone)]
pub struct MirRecordUpdate {
pub base: Box<Spanned<MirExpr>>,
pub type_id: Option<TypeId>,
pub type_name: String,
pub updates: Vec<MirRecordField>,
}
#[derive(Debug, Clone)]
pub struct MirRecordField {
pub name: String,
pub value: Spanned<MirExpr>,
}
#[derive(Debug, Clone)]
pub struct MirProject {
pub base: Box<Spanned<MirExpr>>,
pub field: String,
}
#[derive(Debug, Clone)]
pub struct MirIndependentProduct {
pub items: Vec<Spanned<MirExpr>>,
pub unwrap_results: bool,
}
#[derive(Debug, Clone)]
pub enum MirStrPart {
Literal(String),
Expr(Spanned<MirExpr>),
}
#[derive(Debug, Clone)]
pub struct MirEffectAnnotation {
pub name: String,
}