Skip to main content

sysml_v2_parser/ast/
behavior.rs

1use super::common::{ConnectBody, DocComment, Identification, ParseErrorNode};
2use super::requirement::RequirementUsage;
3use super::structure::{Annotation, Bind, DefinitionBody, Perform, RefDecl};
4use crate::ast::core::{Expression, Node, Span};
5
6/// Action definition: `action def` Identification body (in/out params).
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct ActionDef {
9    pub identification: Identification,
10    pub specializes: Option<String>,
11    pub specializes_span: Option<Span>,
12    pub body: ActionDefBody,
13}
14
15/// Body of an action definition: `;` or `{` ActionDefBodyElement* `}`.
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub enum ActionDefBody {
18    Semicolon,
19    Brace {
20        elements: Vec<Node<ActionDefBodyElement>>,
21    },
22}
23
24/// Element inside an action definition body.
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub enum ActionDefBodyElement {
27    Error(Node<ParseErrorNode>),
28    InOutDecl(Node<InOutDecl>),
29    Doc(Node<DocComment>),
30    Annotation(Node<Annotation>),
31    RefDecl(Node<RefDecl>),
32    Perform(Node<Perform>),
33    Bind(Node<Bind>),
34    Flow(Node<Flow>),
35    FirstStmt(Node<FirstStmt>),
36    MergeStmt(Node<MergeStmt>),
37    StateUsage(Node<StateUsage>),
38    ActionUsage(Box<Node<ActionUsage>>),
39    Assign(Node<AssignStmt>),
40    ForLoop(Node<ForLoop>),
41    ThenAction(Node<ThenAction>),
42    Decl(Node<ActionBodyDecl>),
43}
44
45/// Assignment statement (SysML v2 AssignmentNode/AssignmentActionUsage).
46///
47/// Examples:
48/// - `assign x := y;`
49/// - `then assign position := dynamics.x_out;`
50#[derive(Debug, Clone, PartialEq, Eq)]
51pub struct AssignStmt {
52    pub is_then: bool,
53    pub lhs: String,
54    pub rhs: String,
55}
56
57/// For-loop node (SysML v2 ForLoopNode) - modeled minimally.
58#[derive(Debug, Clone, PartialEq, Eq)]
59pub struct ForLoop {
60    pub var: String,
61    pub range: String,
62    pub body: ActionDefBody,
63}
64
65/// Succession to an action usage: `then action ...`.
66#[derive(Debug, Clone, PartialEq, Eq)]
67pub struct ThenAction {
68    pub action: Node<ActionUsage>,
69}
70
71/// In/out parameter in action def: `in` name `:` type `;` or `out` name `:` type `;`.
72#[derive(Debug, Clone, PartialEq, Eq)]
73pub struct InOutDecl {
74    pub direction: InOut,
75    pub name: String,
76    pub type_name: String,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq)]
80pub enum InOut {
81    In,
82    Out,
83    InOut,
84}
85
86/// Action usage: `action` name `:` type_name (`accept` param_name `:` param_type)? body.
87#[derive(Debug, Clone, PartialEq, Eq)]
88pub struct ActionUsage {
89    pub name: String,
90    pub type_name: String,
91    /// For accept form: (param_name, param_type).
92    pub accept: Option<(String, String)>,
93    pub body: ActionUsageBody,
94    /// Span of the usage name (for semantic tokens).
95    pub name_span: Option<Span>,
96    /// Span of the type reference after `:` (for semantic tokens).
97    pub type_ref_span: Option<Span>,
98}
99
100/// Body of an action usage: `;` or `{` ActionUsageBodyElement* `}`.
101#[derive(Debug, Clone, PartialEq, Eq)]
102pub enum ActionUsageBody {
103    Semicolon,
104    Brace {
105        elements: Vec<Node<ActionUsageBodyElement>>,
106    },
107}
108
109/// Element inside an action usage body.
110#[derive(Debug, Clone, PartialEq, Eq)]
111pub enum ActionUsageBodyElement {
112    Error(Node<ParseErrorNode>),
113    Doc(Node<DocComment>),
114    Annotation(Node<Annotation>),
115    InOutDecl(Node<InOutDecl>),
116    RefDecl(Node<RefDecl>),
117    Bind(Node<Bind>),
118    Flow(Node<Flow>),
119    FirstStmt(Node<FirstStmt>),
120    MergeStmt(Node<MergeStmt>),
121    StateUsage(Node<StateUsage>),
122    ActionUsage(Box<Node<ActionUsage>>),
123    Assign(Node<AssignStmt>),
124    ForLoop(Node<ForLoop>),
125    ThenAction(Node<ThenAction>),
126    Decl(Node<ActionBodyDecl>),
127}
128
129/// A minimally-modeled declaration inside an action/behavior body (e.g. `attribute ...;`, `calc ...;`).
130#[derive(Debug, Clone, PartialEq, Eq)]
131pub struct ActionBodyDecl {
132    pub keyword: String,
133    pub text: String,
134}
135
136/// Flow: `flow` from `to` to body.
137#[derive(Debug, Clone, PartialEq, Eq)]
138pub struct Flow {
139    pub from: Node<Expression>,
140    pub to: Node<Expression>,
141    pub body: ConnectBody,
142}
143
144/// Flow definition: `flow def` Identification body.
145#[derive(Debug, Clone, PartialEq, Eq)]
146pub struct FlowDef {
147    pub identification: Identification,
148    pub specializes: Option<String>,
149    pub specializes_span: Option<Span>,
150    pub body: DefinitionBody,
151}
152
153/// Flow usage: `flow` name (`:` type)? [`from` expr `to` expr]? body.
154#[derive(Debug, Clone, PartialEq, Eq)]
155pub struct FlowUsage {
156    pub name: String,
157    pub type_name: Option<String>,
158    pub from: Option<Node<Expression>>,
159    pub to: Option<Node<Expression>>,
160    pub body: DefinitionBody,
161}
162
163/// First/then control flow: `first` expr `then` expr body.
164#[derive(Debug, Clone, PartialEq, Eq)]
165pub struct FirstStmt {
166    pub first: Node<Expression>,
167    pub then: Node<Expression>,
168    pub body: FirstMergeBody,
169}
170
171/// Merge: `merge` expr body.
172#[derive(Debug, Clone, PartialEq, Eq)]
173pub struct MergeStmt {
174    pub merge: Node<Expression>,
175    pub body: FirstMergeBody,
176}
177
178/// Body of first/merge: `;` or `{` ... `}`.
179#[derive(Debug, Clone, PartialEq, Eq)]
180pub enum FirstMergeBody {
181    Semicolon,
182    Brace,
183}
184
185// ---------------------------------------------------------------------------
186// Allocation
187// ---------------------------------------------------------------------------
188
189/// Allocate statement at part usage level: `allocate` from `to` to body.
190#[derive(Debug, Clone, PartialEq, Eq)]
191pub struct Allocate {
192    pub source: Node<Expression>,
193    pub target: Node<Expression>,
194    pub body: ConnectBody,
195}
196
197/// Allocation definition: `allocation def` Identification body.
198#[derive(Debug, Clone, PartialEq, Eq)]
199pub struct AllocationDef {
200    pub identification: Identification,
201    pub specializes: Option<String>,
202    pub specializes_span: Option<Span>,
203    pub body: DefinitionBody,
204}
205
206/// Allocation usage: `allocation` name (`:` type)? [`allocate` source `to` target]? body.
207#[derive(Debug, Clone, PartialEq, Eq)]
208pub struct AllocationUsage {
209    pub name: String,
210    pub type_name: Option<String>,
211    pub source: Option<Node<Expression>>,
212    pub target: Option<Node<Expression>>,
213    pub body: DefinitionBody,
214}
215
216// ---------------------------------------------------------------------------
217// Requirements
218// ---------------------------------------------------------------------------
219
220/// State definition: `state def` Identification body.
221#[derive(Debug, Clone, PartialEq, Eq)]
222pub struct StateDef {
223    pub identification: Identification,
224    pub specializes: Option<String>,
225    pub specializes_span: Option<Span>,
226    pub body: StateDefBody,
227}
228
229#[derive(Debug, Clone, PartialEq, Eq)]
230pub enum StateDefBody {
231    Semicolon,
232    Brace {
233        elements: Vec<Node<StateDefBodyElement>>,
234    },
235}
236
237#[derive(Debug, Clone, PartialEq, Eq)]
238pub enum StateDefBodyElement {
239    Error(Node<ParseErrorNode>),
240    Doc(Node<DocComment>),
241    Annotation(Node<Annotation>),
242    Other(String),
243    /// `entry` (`;` or body) - entry action.
244    Entry(Node<EntryAction>),
245    /// `then` name `;` - initial state.
246    Then(Node<ThenStmt>),
247    /// `ref` name `:` type body ÔÇô reference binding in state.
248    Ref(Node<RefDecl>),
249    RequirementUsage(Node<RequirementUsage>),
250    StateUsage(Node<StateUsage>),
251    Transition(Node<Transition>),
252}
253
254/// Entry action: `entry` (`;` or body).
255#[derive(Debug, Clone, PartialEq, Eq)]
256pub struct EntryAction {
257    /// For `entry action name body` form; None for plain `entry` body.
258    pub action_name: Option<String>,
259    pub body: StateDefBody,
260}
261
262/// Then (initial state): `then` name `;`
263#[derive(Debug, Clone, PartialEq, Eq)]
264pub struct ThenStmt {
265    pub state_name: String,
266}
267
268/// State usage: `state` name (`:` type)? body.
269#[derive(Debug, Clone, PartialEq, Eq)]
270pub struct StateUsage {
271    pub name: String,
272    pub type_name: Option<String>,
273    pub body: StateDefBody,
274}
275
276/// Transition: `transition` name [`first` source] [`if` guard] [`do` effect] `then` target body.
277#[derive(Debug, Clone, PartialEq, Eq)]
278pub struct Transition {
279    pub name: Option<String>,
280    /// If omitted, form is `transition name then target;`.
281    pub source: Option<Node<Expression>>,
282    pub guard: Option<Node<Expression>>,
283    pub effect: Option<Node<Expression>>,
284    pub target: Node<Expression>,
285    pub body: ConnectBody,
286}
287
288// ---------------------------------------------------------------------------
289// Constraints & Calculations
290// ---------------------------------------------------------------------------