kodept_ast/node/
top_level.rs1#[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}