use super::callable::CallableId; use super::types::{ElabData, Type}; use std::fmt::Debug; /// ID of a definition (e.g. variable, block, function) #[derive(Clone, Copy)] pub struct DefId(pub u32); #[derive(Clone, Copy)] pub struct ExprId(pub u32); // more compact Debug impl impl Debug for DefId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "DefId({})", self.0) } } impl Debug for ExprId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "ExprId({})", self.0) } } /// an abstract element that performs some kind of computation on inputs #[derive(Debug, Clone)] pub struct Expr { pub id: ExprId, pub kind: ExprKind, pub typ: Type, } #[derive(Debug, Clone)] pub enum ExprKind { Literal(ElabData), Path(DefId), Call { called: CallableId, args: Vec, genargs: Vec, }, } #[derive(Debug, Clone)] pub struct Signal { pub id: DefId, pub typ: Type, } /// A block of HDL code, e.g. comb block #[derive(Debug, Clone)] pub struct Block { pub signals: Vec, pub expr: Expr, } impl Expr { pub fn with_type(mut self, typ: Type) -> Self { self.typ = typ; self } }