kodept_ast/node/
top_level.rs

1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3
4use kodept_core::structure::rlt::{Enum, Struct, TopLevelNode};
5use kodept_core::structure::span::CodeHolder;
6
7use crate::graph::NodeId;
8use crate::graph::{SyntaxTreeBuilder};
9use crate::traits::Linker;
10use crate::traits::PopulateTree;
11use crate::{node, BodyFnDecl, TyName, TyParam, node_sub_enum};
12
13#[derive(Debug, PartialEq, Clone)]
14#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
15pub enum EnumKind {
16    Stack,
17    Heap,
18}
19
20node_sub_enum! {
21    #[derive(Debug, PartialEq)]
22    #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
23    pub enum TopLevel {
24        Enum(EnumDecl),
25        Struct(StructDecl),
26        Fn(BodyFnDecl)
27    }
28}
29
30node! {
31    #[derive(Debug, PartialEq)]
32    #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
33    pub struct StructDecl {
34        pub name: String,;
35        pub parameters: Vec<TyParam>,
36        pub contents: Vec<BodyFnDecl>,
37    }
38}
39
40node! {
41    #[derive(Debug, PartialEq)]
42    #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
43    pub struct EnumDecl {
44        pub kind: EnumKind,
45        pub name: String,;
46        pub contents: Vec<TyName>,
47    }
48}
49
50impl PopulateTree for Struct {
51    type Output = StructDecl;
52
53    fn convert(
54        &self,
55        builder: &mut SyntaxTreeBuilder,
56        context: &mut (impl Linker + CodeHolder),
57    ) -> NodeId<Self::Output> {
58        let node = StructDecl::uninit(context.get_chunk_located(&self.id).to_string());
59        builder
60            .add_node(node)
61            .with_children_from(self.body.iter().flat_map(|x| x.inner.as_ref()), context)
62            .with_children_from(
63                self.parameters.iter().flat_map(|x| x.inner.as_ref()),
64                context,
65            )
66            .with_rlt(context, self)
67            .id()
68    }
69}
70
71impl PopulateTree for Enum {
72    type Output = EnumDecl;
73
74    fn convert(
75        &self,
76        builder: &mut SyntaxTreeBuilder,
77        context: &mut (impl Linker + CodeHolder),
78    ) -> NodeId<Self::Output> {
79        let (kind, name, rest) = match self {
80            Enum::Stack { id, contents, .. } => (EnumKind::Stack, id, contents),
81            Enum::Heap { id, contents, .. } => (EnumKind::Heap, id, contents),
82        };
83        let node = EnumDecl::uninit(kind, context.get_chunk_located(name).to_string());
84        builder
85            .add_node(node)
86            .with_children_from(
87                rest.as_ref()
88                    .map_or([].as_slice(), |x| x.inner.iter().as_slice()),
89                context,
90            )
91            .with_rlt(context, self)
92            .id()
93    }
94}
95
96impl PopulateTree for TopLevelNode {
97    type Output = TopLevel;
98
99    fn convert(
100        &self,
101        builder: &mut SyntaxTreeBuilder,
102        context: &mut (impl Linker + CodeHolder),
103    ) -> NodeId<Self::Output> {
104        match self {
105            TopLevelNode::Enum(x) => x.convert(builder, context).cast(),
106            TopLevelNode::Struct(x) => x.convert(builder, context).cast(),
107            TopLevelNode::BodiedFunction(x) => x.convert(builder, context).cast(),
108        }
109    }
110}