plc_ast/
control_statements.rs1use serde::{Deserialize, Serialize};
2use std::fmt::Debug;
3
4use plc_source::source_location::SourceLocation;
5
6use crate::ast::AstNode;
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9#[serde(bound(deserialize = "'de: 'static"))]
10pub struct IfStatement {
11 pub blocks: Vec<ConditionalBlock>,
12 pub else_block: Vec<AstNode>,
13 pub end_location: SourceLocation,
14}
15
16#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
17#[serde(bound(deserialize = "'de: 'static"))]
18pub struct ForLoopStatement {
19 pub counter: Box<AstNode>,
20 pub start: Box<AstNode>,
21 pub end: Box<AstNode>,
22 pub by_step: Option<Box<AstNode>>,
23 pub body: Vec<AstNode>,
24 pub end_location: SourceLocation,
25}
26
27#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
28#[serde(bound(deserialize = "'de: 'static"))]
29pub struct LoopStatement {
31 pub condition: Box<AstNode>,
32 pub body: Vec<AstNode>,
33 pub end_location: SourceLocation,
34}
35
36#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
37#[serde(bound(deserialize = "'de: 'static"))]
38pub struct CaseStatement {
39 pub selector: Box<AstNode>,
40 pub case_blocks: Vec<ConditionalBlock>,
41 pub else_block: Vec<AstNode>,
42 pub end_location: SourceLocation,
43}
44
45#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
46#[serde(bound(deserialize = "'de: 'static"))]
47pub enum AstControlStatement {
48 If(IfStatement),
49 ForLoop(ForLoopStatement),
50 WhileLoop(LoopStatement),
51 RepeatLoop(LoopStatement),
52 Case(CaseStatement),
53}
54
55#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
56#[serde(bound(deserialize = "'de: 'static"))]
57pub struct ConditionalBlock {
58 pub condition: Box<AstNode>,
59 pub body: Vec<AstNode>,
60}
61
62#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
63#[serde(bound(deserialize = "'de: 'static"))]
64pub struct ReturnStatement {
65 pub condition: Option<Box<AstNode>>,
68}
69
70impl ForLoopStatement {
71 pub fn get_conditionals(&self) -> Vec<&AstNode> {
72 let mut conditionals = Vec::new();
73
74 conditionals.push(self.counter.as_ref());
75 conditionals.push(self.start.as_ref());
76 conditionals.push(self.end.as_ref());
77 if let Some(ref step) = self.by_step {
78 conditionals.push(step);
79 }
80
81 conditionals
82 }
83}