use std::sync::Arc;
use bumpalo::Bump;
use super::table::{self};
use super::{LinkName, Literal, RegionKind, SymbolName, VarName, Visibility};
mod parse;
mod print;
#[cfg(feature = "pyo3")]
mod python;
mod resolve;
mod view;
pub use parse::ParseError;
pub use resolve::ResolveError;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Package {
pub modules: Vec<Module>,
}
impl Package {
pub fn resolve<'a>(
&'a self,
bump: &'a Bump,
) -> Result<table::Package<'a>, resolve::ResolveError> {
let modules = self
.modules
.iter()
.map(|module| module.resolve(bump))
.collect::<Result<_, _>>()?;
Ok(table::Package { modules })
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Module {
pub root: Region,
}
impl Module {
pub fn resolve<'a>(
&'a self,
bump: &'a Bump,
) -> Result<table::Module<'a>, resolve::ResolveError> {
let mut ctx = resolve::Context::new(bump);
ctx.resolve_module(self)?;
Ok(ctx.finish())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Node {
pub operation: Operation,
pub inputs: Box<[LinkName]>,
pub outputs: Box<[LinkName]>,
pub regions: Box<[Region]>,
pub meta: Box<[Term]>,
pub signature: Option<Term>,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum Operation {
#[default]
Invalid,
Dfg,
Cfg,
Block,
DefineFunc(Box<Symbol>),
DeclareFunc(Box<Symbol>),
Custom(Term),
DefineAlias(Box<Symbol>, Term),
DeclareAlias(Box<Symbol>),
TailLoop,
Conditional,
DeclareConstructor(Box<Symbol>),
DeclareOperation(Box<Symbol>),
Import(SymbolName),
}
impl Operation {
#[must_use]
pub fn symbol_name(&self) -> Option<&SymbolName> {
if let Operation::Import(symbol_name) = self {
Some(symbol_name)
} else {
Some(&self.symbol()?.name)
}
}
#[must_use]
pub fn symbol(&self) -> Option<&Symbol> {
match self {
Operation::DefineFunc(symbol)
| Operation::DeclareFunc(symbol)
| Operation::DefineAlias(symbol, _)
| Operation::DeclareAlias(symbol)
| Operation::DeclareConstructor(symbol)
| Operation::DeclareOperation(symbol) => Some(symbol),
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Symbol {
pub visibility: Option<Visibility>,
pub name: SymbolName,
pub params: Box<[Param]>,
pub constraints: Box<[Term]>,
pub signature: Term,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Param {
pub name: VarName,
pub r#type: Term,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Region {
pub kind: RegionKind,
pub sources: Box<[LinkName]>,
pub targets: Box<[LinkName]>,
pub children: Box<[Node]>,
pub meta: Box<[Term]>,
pub signature: Option<Term>,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum Term {
#[default]
Wildcard,
Var(VarName),
Apply(SymbolName, Arc<[Term]>),
List(Arc<[SeqPart]>),
Literal(Literal),
Tuple(Arc<[SeqPart]>),
Func(Arc<Region>),
}
impl From<Literal> for Term {
fn from(value: Literal) -> Self {
Self::Literal(value)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SeqPart {
Item(Term),
Splice(Term),
}