kodept_ast/node/
block_level.rs

1use std::fmt::Debug;
2
3use derive_more::{IsVariant};
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7use kodept_core::structure::rlt;
8use kodept_core::structure::rlt::BlockLevelNode;
9use kodept_core::structure::span::CodeHolder;
10
11use crate::graph::NodeId;
12use crate::graph::{Identity, SyntaxTreeBuilder};
13use crate::traits::{Linker, PopulateTree};
14use crate::{node, BodyFnDecl, Exprs, Operation, Type, node_sub_enum};
15
16node_sub_enum! {
17    #[derive(Debug, PartialEq)]
18    #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
19    pub enum BlockLevel {
20        Fn(BodyFnDecl),
21        InitVar(InitVar),
22        Op(forward Operation),
23        Block(Exprs)
24    }
25}
26
27node_sub_enum! {
28    #[derive(Debug, PartialEq)]
29    #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
30    pub enum Body {
31        Block(Exprs),
32        Simple(forward BlockLevel)
33    }
34}
35
36node! {
37    #[derive(Debug, PartialEq)]
38    #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
39    pub struct VarDecl {
40        pub kind: VariableKind,
41        pub name: String,;
42        pub assigned_type: Option<Type>,
43    }
44}
45
46node! {
47    #[derive(Debug, PartialEq)]
48    #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
49    pub struct InitVar {
50        ;
51        pub variable: Identity<VarDecl>,
52        pub expr: Identity<Operation>,
53    }
54}
55
56#[derive(Debug, PartialEq, Clone, IsVariant)]
57#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
58pub enum VariableKind {
59    Immutable,
60    Mutable,
61}
62
63impl PopulateTree for rlt::Body {
64    type Output = Body;
65
66    fn convert(
67        &self,
68        builder: &mut SyntaxTreeBuilder,
69        context: &mut (impl Linker + CodeHolder),
70    ) -> NodeId<Self::Output> {
71        match self {
72            rlt::Body::Block(x) => x.convert(builder, context).cast(),
73            rlt::Body::Simplified { expression, .. } => expression.convert(builder, context).cast(),
74        }
75    }
76}
77
78impl PopulateTree for BlockLevelNode {
79    type Output = BlockLevel;
80
81    fn convert(
82        &self,
83        builder: &mut SyntaxTreeBuilder,
84        context: &mut (impl Linker + CodeHolder),
85    ) -> NodeId<Self::Output> {
86        match self {
87            BlockLevelNode::InitVar(x) => x.convert(builder, context).cast(),
88            BlockLevelNode::Block(x) => x.convert(builder, context).cast(),
89            BlockLevelNode::Function(x) => x.convert(builder, context).cast(),
90            BlockLevelNode::Operation(x) => x.convert(builder, context).cast(),
91        }
92    }
93}
94
95impl PopulateTree for rlt::InitializedVariable {
96    type Output = InitVar;
97
98    fn convert(
99        &self,
100        builder: &mut SyntaxTreeBuilder,
101        context: &mut (impl Linker + CodeHolder),
102    ) -> NodeId<Self::Output> {
103        builder
104            .add_node(InitVar::uninit())
105            .with_children_from([&self.expression], context)
106            .with_children_from([&self.variable], context)
107            .with_rlt(context, self)
108            .id()
109    }
110}
111
112impl PopulateTree for rlt::Variable {
113    type Output = VarDecl;
114
115    fn convert(
116        &self,
117        builder: &mut SyntaxTreeBuilder,
118        context: &mut (impl Linker + CodeHolder),
119    ) -> NodeId<Self::Output> {
120        let (kind, name, ty) = match self {
121            rlt::Variable::Immutable {
122                id, assigned_type, ..
123            } => (VariableKind::Immutable, id, assigned_type),
124            rlt::Variable::Mutable {
125                id, assigned_type, ..
126            } => (VariableKind::Mutable, id, assigned_type),
127        };
128        builder
129            .add_node(VarDecl::uninit(
130                kind,
131                context.get_chunk_located(name).to_string(),
132            ))
133            .with_children_from(ty.as_ref().map(|x| &x.1), context)
134            .with_rlt(context, self)
135            .id()
136    }
137}