kodept_ast/node/
block_level.rs1use 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}