use std::sync::Arc;
use super::{LinkName, Node, Operation, Param, Region, SeqPart, Symbol, SymbolName, Term, VarName};
use crate::v0::table::{self, NodeId, TermId, VarId, View};
impl<'a> View<'a, TermId> for Term {
fn view(module: &'a table::Module<'a>, id: TermId) -> Option<Self> {
let term = module.get_term(id)?;
Some(match term {
table::Term::Wildcard => Term::Wildcard,
table::Term::Var(var) => Term::Var(module.view(*var)?),
table::Term::Apply(symbol, terms) => {
let symbol = module.view(*symbol)?;
let terms = module.view(*terms)?;
Term::Apply(symbol, terms)
}
table::Term::Func(region_id) => Term::Func(Arc::new(module.view(*region_id)?)),
table::Term::List(list_parts) => Term::List(module.view(*list_parts)?),
table::Term::Literal(literal) => Term::Literal(literal.clone()),
table::Term::Tuple(tuple_parts) => Term::Tuple(module.view(*tuple_parts)?),
})
}
}
impl<'a> View<'a, NodeId> for Node {
fn view(module: &'a table::Module<'a>, id: NodeId) -> Option<Self> {
let node = module.get_node(id)?;
let operation = match node.operation {
table::Operation::Invalid => Operation::Invalid,
table::Operation::Dfg => Operation::Dfg,
table::Operation::Cfg => Operation::Cfg,
table::Operation::Block => Operation::Block,
table::Operation::DefineFunc(symbol) => {
Operation::DefineFunc(Box::new(module.view(*symbol)?))
}
table::Operation::DeclareFunc(symbol) => {
Operation::DeclareFunc(Box::new(module.view(*symbol)?))
}
table::Operation::Custom(operation) => Operation::Custom(module.view(operation)?),
table::Operation::DefineAlias(symbol, value) => {
let symbol = Box::new(module.view(*symbol)?);
let value = module.view(value)?;
Operation::DefineAlias(symbol, value)
}
table::Operation::DeclareAlias(symbol) => {
Operation::DeclareAlias(Box::new(module.view(*symbol)?))
}
table::Operation::DeclareConstructor(symbol) => {
Operation::DeclareConstructor(Box::new(module.view(*symbol)?))
}
table::Operation::DeclareOperation(symbol) => {
Operation::DeclareOperation(Box::new(module.view(*symbol)?))
}
table::Operation::TailLoop => Operation::TailLoop,
table::Operation::Conditional => Operation::Conditional,
table::Operation::Import { name } => Operation::Import(SymbolName::new(name)),
};
let meta = module.view(node.meta)?;
let signature = module.view(node.signature)?;
let inputs = module.view(node.inputs)?;
let outputs = module.view(node.outputs)?;
let regions = module.view(node.regions)?;
Some(Node {
operation,
inputs,
outputs,
regions,
meta,
signature,
})
}
}
impl<'a> View<'a, table::LinkIndex> for LinkName {
fn view(_module: &'a table::Module<'a>, index: table::LinkIndex) -> Option<Self> {
Some(LinkName::new_index(index))
}
}
impl<'a> View<'a, table::SeqPart> for SeqPart {
fn view(module: &'a table::Module<'a>, part: table::SeqPart) -> Option<Self> {
Some(match part {
table::SeqPart::Item(term_id) => SeqPart::Item(module.view(term_id)?),
table::SeqPart::Splice(term_id) => SeqPart::Splice(module.view(term_id)?),
})
}
}
impl<'a> View<'a, table::Symbol<'a>> for Symbol {
fn view(module: &'a table::Module<'a>, id: table::Symbol<'a>) -> Option<Self> {
let visibility = id.visibility.clone();
let name = SymbolName::new(id.name);
let params = module.view(id.params)?;
let constraints = module.view(id.constraints)?;
let signature = module.view(id.signature)?;
Some(Symbol {
visibility,
name,
params,
constraints,
signature,
})
}
}
impl<'a> View<'a, table::Param<'a>> for Param {
fn view(module: &'a table::Module<'a>, param: table::Param<'a>) -> Option<Self> {
let name = VarName::new(param.name);
let r#type = module.view(param.r#type)?;
Some(Param { name, r#type })
}
}
impl<'a> View<'a, table::RegionId> for Region {
fn view(module: &'a table::Module<'a>, id: table::RegionId) -> Option<Self> {
let region = module.get_region(id)?;
let sources = module.view(region.sources)?;
let targets = module.view(region.targets)?;
let meta = module.view(region.meta)?;
let children = module.view(region.children)?;
let signature = module.view(region.signature)?;
Some(Region {
kind: region.kind,
sources,
targets,
children,
meta,
signature,
})
}
}
impl<'a> View<'a, VarId> for VarName {
fn view(module: &'a table::Module<'a>, id: VarId) -> Option<Self> {
let node = module.get_node(id.0)?;
let symbol = match node.operation {
table::Operation::DefineFunc(symbol) => symbol,
table::Operation::DeclareFunc(symbol) => symbol,
table::Operation::DefineAlias(symbol, _) => symbol,
table::Operation::DeclareAlias(symbol) => symbol,
table::Operation::DeclareConstructor(symbol) => symbol,
table::Operation::DeclareOperation(symbol) => symbol,
_ => return None,
};
let param = &symbol.params[id.1 as usize];
Some(Self(param.name.into()))
}
}
impl<'a> View<'a, NodeId> for SymbolName {
fn view(module: &'a table::Module<'a>, id: NodeId) -> Option<Self> {
let node = module.get_node(id)?;
let name = node.operation.symbol()?;
Some(Self(name.into()))
}
}