1use super::expression::Expression;
5use super::{Binding, FunctionCall, LetBinding};
6use crate::ast;
7use crate::types::semantic::{ExtendedExpression, SemanticContextInstruction};
8#[cfg(feature = "codec")]
9use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
13#[cfg_attr(
14 feature = "codec",
15 derive(Serialize, Deserialize),
16 serde(tag = "type", content = "content")
17)]
18pub enum Condition {
19 Great,
20 Less,
21 Eq,
22 GreatEq,
23 LessEq,
24 NotEq,
25}
26
27impl From<ast::Condition> for Condition {
28 fn from(value: ast::Condition) -> Self {
29 match value {
30 ast::Condition::Great => Self::Great,
31 ast::Condition::Less => Self::Less,
32 ast::Condition::Eq => Self::Eq,
33 ast::Condition::GreatEq => Self::GreatEq,
34 ast::Condition::LessEq => Self::LessEq,
35 ast::Condition::NotEq => Self::NotEq,
36 }
37 }
38}
39
40#[derive(Debug, Clone, PartialEq, Eq)]
43#[cfg_attr(
44 feature = "codec",
45 derive(Serialize, Deserialize),
46 serde(tag = "type", content = "content")
47)]
48pub enum LogicCondition {
49 And,
50 Or,
51}
52
53impl From<ast::LogicCondition> for LogicCondition {
54 fn from(value: ast::LogicCondition) -> Self {
55 match value {
56 ast::LogicCondition::And => Self::And,
57 ast::LogicCondition::Or => Self::Or,
58 }
59 }
60}
61
62#[derive(Debug, Clone, PartialEq)]
64#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
65pub struct ExpressionCondition {
66 pub left: Expression,
68 pub condition: Condition,
70 pub right: Expression,
72}
73
74impl<I: SemanticContextInstruction, E: ExtendedExpression<I>>
75 From<ast::ExpressionCondition<'_, I, E>> for ExpressionCondition
76{
77 fn from(value: ast::ExpressionCondition<'_, I, E>) -> Self {
78 Self {
79 left: value.left.into(),
80 condition: value.condition.into(),
81 right: value.right.into(),
82 }
83 }
84}
85
86#[derive(Debug, Clone, PartialEq)]
90#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
91pub struct ExpressionLogicCondition {
92 pub left: ExpressionCondition,
94 pub right: Option<(LogicCondition, Box<ExpressionLogicCondition>)>,
96}
97
98impl<I: SemanticContextInstruction, E: ExtendedExpression<I>>
99 From<ast::ExpressionLogicCondition<'_, I, E>> for ExpressionLogicCondition
100{
101 fn from(value: ast::ExpressionLogicCondition<'_, I, E>) -> Self {
102 Self {
103 left: value.left.into(),
104 right: value
105 .right
106 .map(|(v, expr)| (v.into(), Box::new(expr.as_ref().clone().into()))),
107 }
108 }
109}
110
111#[derive(Debug, Clone, PartialEq)]
115#[cfg_attr(
116 feature = "codec",
117 derive(Serialize, Deserialize),
118 serde(tag = "type", content = "content")
119)]
120pub enum IfCondition {
121 Single(Expression),
122 Logic(ExpressionLogicCondition),
123}
124
125impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> From<ast::IfCondition<'_, I, E>>
126 for IfCondition
127{
128 fn from(value: ast::IfCondition<'_, I, E>) -> Self {
129 match value {
130 ast::IfCondition::Single(v) => Self::Single(v.into()),
131 ast::IfCondition::Logic(v) => Self::Logic(v.into()),
132 }
133 }
134}
135
136#[derive(Debug, Clone, PartialEq)]
139#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
140pub struct IfStatement {
141 pub condition: IfCondition,
143 pub body: IfBodyStatements,
145 pub else_statement: Option<IfBodyStatements>,
147 pub else_if_statement: Option<Box<IfStatement>>,
149}
150
151impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> From<ast::IfStatement<'_, I, E>>
152 for IfStatement
153{
154 fn from(value: ast::IfStatement<'_, I, E>) -> Self {
155 Self {
156 condition: value.condition.into(),
157 body: value.body.into(),
158 else_statement: value.else_statement.map(Into::into),
159 else_if_statement: value
160 .else_if_statement
161 .map(|v| Box::new(v.as_ref().clone().into())),
162 }
163 }
164}
165
166#[derive(Debug, Clone, PartialEq)]
170#[cfg_attr(
171 feature = "codec",
172 derive(Serialize, Deserialize),
173 serde(tag = "type", content = "content")
174)]
175pub enum IfBodyStatements {
176 If(Vec<IfBodyStatement>),
177 Loop(Vec<IfLoopBodyStatement>),
178}
179
180impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> From<ast::IfBodyStatements<'_, I, E>>
181 for IfBodyStatements
182{
183 fn from(value: ast::IfBodyStatements<'_, I, E>) -> Self {
184 match value {
185 ast::IfBodyStatements::If(v) => Self::If(v.iter().map(|v| v.clone().into()).collect()),
186 ast::IfBodyStatements::Loop(v) => {
187 Self::Loop(v.iter().map(|v| v.clone().into()).collect())
188 }
189 }
190 }
191}
192
193#[derive(Debug, Clone, PartialEq)]
195#[cfg_attr(
196 feature = "codec",
197 derive(Serialize, Deserialize),
198 serde(tag = "type", content = "content")
199)]
200pub enum LoopBodyStatement {
201 LetBinding(LetBinding),
202 Binding(Binding),
203 FunctionCall(FunctionCall),
204 If(IfStatement),
205 Loop(Vec<LoopBodyStatement>),
206 Return(Expression),
207 Break,
208 Continue,
209}
210
211impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> From<ast::LoopBodyStatement<'_, I, E>>
212 for LoopBodyStatement
213{
214 fn from(value: ast::LoopBodyStatement<'_, I, E>) -> Self {
215 match value {
216 ast::LoopBodyStatement::LetBinding(v) => Self::LetBinding(v.into()),
217 ast::LoopBodyStatement::Binding(v) => Self::Binding(v.into()),
218 ast::LoopBodyStatement::FunctionCall(v) => Self::FunctionCall(v.into()),
219 ast::LoopBodyStatement::If(v) => Self::If(v.into()),
220 ast::LoopBodyStatement::Loop(v) => {
221 Self::Loop(v.iter().map(|v| v.clone().into()).collect())
222 }
223 ast::LoopBodyStatement::Return(v) => Self::Return(v.into()),
224 ast::LoopBodyStatement::Break => Self::Break,
225 ast::LoopBodyStatement::Continue => Self::Continue,
226 }
227 }
228}
229
230#[derive(Debug, Clone, PartialEq)]
232#[cfg_attr(
233 feature = "codec",
234 derive(Serialize, Deserialize),
235 serde(tag = "type", content = "content")
236)]
237pub enum IfBodyStatement {
238 LetBinding(LetBinding),
239 Binding(Binding),
240 FunctionCall(FunctionCall),
241 If(IfStatement),
242 Loop(Vec<LoopBodyStatement>),
243 Return(Expression),
244}
245
246impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> From<ast::IfBodyStatement<'_, I, E>>
247 for IfBodyStatement
248{
249 fn from(value: ast::IfBodyStatement<'_, I, E>) -> Self {
250 match value {
251 ast::IfBodyStatement::LetBinding(v) => Self::LetBinding(v.into()),
252 ast::IfBodyStatement::Binding(v) => Self::Binding(v.into()),
253 ast::IfBodyStatement::FunctionCall(v) => Self::FunctionCall(v.into()),
254 ast::IfBodyStatement::If(v) => Self::If(v.into()),
255 ast::IfBodyStatement::Loop(v) => {
256 Self::Loop(v.iter().map(|v| v.clone().into()).collect())
257 }
258 ast::IfBodyStatement::Return(v) => Self::Return(v.into()),
259 }
260 }
261}
262
263#[derive(Debug, Clone, PartialEq)]
266#[cfg_attr(
267 feature = "codec",
268 derive(Serialize, Deserialize),
269 serde(tag = "type", content = "content")
270)]
271pub enum IfLoopBodyStatement {
272 LetBinding(LetBinding),
273 Binding(Binding),
274 FunctionCall(FunctionCall),
275 If(IfStatement),
276 Loop(Vec<LoopBodyStatement>),
277 Return(Expression),
278 Break,
279 Continue,
280}
281
282impl<I: SemanticContextInstruction, E: ExtendedExpression<I>>
283 From<ast::IfLoopBodyStatement<'_, I, E>> for IfLoopBodyStatement
284{
285 fn from(value: ast::IfLoopBodyStatement<'_, I, E>) -> Self {
286 match value {
287 ast::IfLoopBodyStatement::LetBinding(v) => Self::LetBinding(v.into()),
288 ast::IfLoopBodyStatement::Binding(v) => Self::Binding(v.into()),
289 ast::IfLoopBodyStatement::FunctionCall(v) => Self::FunctionCall(v.into()),
290 ast::IfLoopBodyStatement::If(v) => Self::If(v.into()),
291 ast::IfLoopBodyStatement::Loop(v) => {
292 Self::Loop(v.iter().map(|v| v.clone().into()).collect())
293 }
294 ast::IfLoopBodyStatement::Return(v) => Self::Return(v.into()),
295 ast::IfLoopBodyStatement::Break => Self::Break,
296 ast::IfLoopBodyStatement::Continue => Self::Continue,
297 }
298 }
299}