in midst of refactor

This commit is contained in:
2024-04-29 21:46:42 +02:00
parent ed0d64d52e
commit aa3f7e99ab
221 changed files with 5431 additions and 685 deletions

View File

@@ -0,0 +1,79 @@
//! Components to build in-memory module trees that in Orchid. These modules
//! can only contain constants and other modules.
use std::fmt;
use dyn_clone::{clone_box, DynClone};
use orchid_api::expr::Expr;
use trait_set::trait_set;
use super::tpl;
use super::traits::{Gen, GenClause};
use crate::combine::Combine;
use crate::host::AtomHand;
use crate::tree::{ModEntry, ModMember, TreeConflict};
trait_set! {
trait TreeLeaf = Gen<Expr, [Expr; 0]> + DynClone + Send;
}
/// A leaf in the [ConstTree]
pub struct GenConst(Box<dyn TreeLeaf>);
impl GenConst {
fn c(data: impl GenClause + Send + Clone + 'static) -> Self { Self(Box::new(data)) }
}
impl fmt::Debug for GenConst {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.0) }
}
impl Clone for GenConst {
fn clone(&self) -> Self { Self(clone_box(&*self.0)) }
}
/// Error condition when constant trees that define the the same constant are
/// merged. Produced during system loading if multiple modules define the
/// same constant
#[derive(Debug, Clone)]
pub struct ConflictingConsts;
impl Combine for GenConst {
type Error = ConflictingConsts;
fn combine(self, _: Self) -> Result<Self, Self::Error> { Err(ConflictingConsts) }
}
/// A lightweight module tree that can be built declaratively by hand to
/// describe libraries of external functions in Rust. It implements [Combine]
/// for merging libraries.
pub type ConstTree = ModEntry<GenConst, (), ()>;
/// Describe a constant
#[must_use]
pub fn leaf(value: impl GenClause + Clone + Send + 'static) -> ConstTree {
ModEntry::wrap(ModMember::Item(GenConst::c(value)))
}
/// Describe a constant which appears in [ConstTree::tree].
///
/// The unarray tricks rustfmt into keeping this call as a single line even if
/// it chooses to break the argument into a block.
pub fn ent<K: AsRef<str>>(
key: K,
[g]: [impl GenClause + Clone + Send + 'static; 1],
) -> (K, ConstTree) {
(key, leaf(g))
}
/// Describe an [Atomic]
#[must_use]
pub fn atom_leaf(atom: AtomHand) -> ConstTree { leaf(tpl::SysAtom(atom)) }
/// Describe an [Atomic] which appears as an entry in a [ConstTree::tree]
///
/// The unarray is used to trick rustfmt into breaking the atom into a block
/// without breaking this call into a block
#[must_use]
pub fn atom_ent<K: AsRef<str>>(key: K, [atom]: [AtomHand; 1]) -> (K, ConstTree) {
(key, atom_leaf(atom))
}
/// Errors produced duriung the merger of constant trees
pub type ConstCombineErr = TreeConflict<GenConst, (), ()>;