kodept-ast 0.4.1

Simple compiler with dependent types support in mind
Documentation
use kodept_core::{ConvertibleToMut, ConvertibleToRef};

use crate::graph::{AnyNode};
use crate::graph::{PermTkn, SyntaxTree};
use crate::graph::tags::ChildTag;
use crate::graph::utils::FromOptVec;
use crate::traits::Identifiable;

pub mod tags {
    pub type ChildTag = u8;

    pub const PRIMARY: ChildTag = 1;
    pub const SECONDARY: ChildTag = 2;
    pub const LEFT: ChildTag = 3;
    pub const RIGHT: ChildTag = 4;

    pub static TAGS_DESC: [&str; 5] = ["", "P", "S", "L", "R"];
}

pub trait HasChildrenMarker<Child, const TAG: ChildTag>: Identifiable {
    type Container: FromOptVec<T = Child>;

    fn get_children<'b>(
        &self,
        tree: &'b SyntaxTree,
        token: &'b PermTkn,
    ) -> ChildrenRef<'b, Self, Child, TAG>
    where
        AnyNode: ConvertibleToRef<Child>,
    {
        Self::Container::unwrap(tree.children_of(self.get_id(), token, TAG))
    }

    fn get_children_mut<'b>(&self, tree: &'b SyntaxTree) -> ChildrenMut<'b, Self, Child, TAG>
    where
        AnyNode: ConvertibleToMut<Child>,
    {
        Self::Container::unwrap_mut(tree.children_of_raw(self.get_id(), TAG))
    }
}

pub type ChildrenRef<'a, T, Child, const TAG: ChildTag> =
    <<T as HasChildrenMarker<Child, TAG>>::Container as FromOptVec>::Ref<'a>;

pub type ChildrenMut<'a, T, Child, const TAG: ChildTag> =
    <<T as HasChildrenMarker<Child, TAG>>::Container as FromOptVec>::Mut<'a>;

pub type ContainerT<T> = <T as FromOptVec>::T;

pub mod macros {
    macro_rules! with_children {
        ($t:ty => {$($vis:vis $name:ident: $c_t:ty as $tag:tt,)*}) => {
            paste::paste! {
            $(
            impl $crate::graph::HasChildrenMarker<$crate::graph::ContainerT<$c_t>, $tag> for $t {
                type Container = $c_t;
            }

            impl $t {
                $vis fn $name<'a>(
                    &self,
                    tree: &'a $crate::graph::SyntaxTree,
                    token: &'a $crate::graph::PermTkn,
                ) -> $crate::graph::ChildrenRef<'a, $t, $crate::graph::ContainerT<$c_t>, $tag> {
                    <Self as $crate::graph::HasChildrenMarker<$crate::graph::ContainerT<$c_t>, $tag>>::get_children(self, tree, token)
                }

                $vis fn [<$name _mut>]<'a>(
                    &self, tree: &'a $crate::graph::SyntaxTree
                ) -> $crate::graph::ChildrenMut<'a, $t, $crate::graph::ContainerT<$c_t>, $tag> {
                    <Self as $crate::graph::HasChildrenMarker<$crate::graph::ContainerT<$c_t>, $tag>>::get_children_mut(self, tree)
                }
            })*
            }
        };
        ($t:ty => {$($vis:vis $name:ident: $c_t:ty,)*}) => {
            $crate::with_children! { $t => {
                $($vis $name: $c_t as 0,)*
            } }
        }
    }
    
    pub(crate) use with_children;
}