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, MetadataKeywordUsage, 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/// Typed payload on accept/send control nodes: `accept name : Type` or `send name : Type`.
87#[derive(Debug, Clone, PartialEq, Eq)]
88pub struct PayloadClause {
89    pub name: String,
90    pub type_name: Option<String>,
91    pub name_span: Span,
92    pub type_span: Option<Span>,
93}
94
95/// Transition accept trigger: typed payload or shorthand expression (`accept StartPressed`).
96#[derive(Debug, Clone, PartialEq, Eq)]
97pub enum TransitionAccept {
98    Payload(PayloadClause),
99    Shorthand(Node<Expression>),
100}
101
102/// Action usage: `action` name `:` type_name (`accept` param_name `:` param_type)? body.
103#[derive(Debug, Clone, PartialEq, Eq)]
104pub struct ActionUsage {
105    pub name: String,
106    pub type_name: String,
107    /// For `action ... accept param : Type` form.
108    pub accept: Option<PayloadClause>,
109    /// For standalone `send param : Type` control-node statements.
110    pub send: Option<PayloadClause>,
111    pub body: ActionUsageBody,
112    /// Span of the usage name (for semantic tokens).
113    pub name_span: Option<Span>,
114    /// Span of the type reference after `:` (for semantic tokens).
115    pub type_ref_span: Option<Span>,
116}
117
118/// Body of an action usage: `;` or `{` ActionUsageBodyElement* `}`.
119#[derive(Debug, Clone, PartialEq, Eq)]
120pub enum ActionUsageBody {
121    Semicolon,
122    Brace {
123        elements: Vec<Node<ActionUsageBodyElement>>,
124    },
125}
126
127/// Element inside an action usage body.
128#[derive(Debug, Clone, PartialEq, Eq)]
129pub enum ActionUsageBodyElement {
130    Error(Node<ParseErrorNode>),
131    Doc(Node<DocComment>),
132    Annotation(Node<Annotation>),
133    InOutDecl(Node<InOutDecl>),
134    RefDecl(Node<RefDecl>),
135    Bind(Node<Bind>),
136    Flow(Node<Flow>),
137    FirstStmt(Node<FirstStmt>),
138    MergeStmt(Node<MergeStmt>),
139    StateUsage(Node<StateUsage>),
140    ActionUsage(Box<Node<ActionUsage>>),
141    Assign(Node<AssignStmt>),
142    ForLoop(Node<ForLoop>),
143    ThenAction(Node<ThenAction>),
144    Decl(Node<ActionBodyDecl>),
145}
146
147/// A minimally-modeled declaration inside an action/behavior body (e.g. `attribute ...;`, `calc ...;`).
148#[derive(Debug, Clone, PartialEq, Eq)]
149pub struct ActionBodyDecl {
150    pub keyword: String,
151    pub text: String,
152}
153
154/// Flow: `flow` from `to` to body.
155#[derive(Debug, Clone, PartialEq, Eq)]
156pub struct Flow {
157    pub from: Node<Expression>,
158    pub to: Node<Expression>,
159    pub body: ConnectBody,
160}
161
162/// Flow definition: `flow def` Identification body.
163#[derive(Debug, Clone, PartialEq, Eq)]
164pub struct FlowDef {
165    pub identification: Identification,
166    pub specializes: Option<String>,
167    pub specializes_span: Option<Span>,
168    pub body: DefinitionBody,
169}
170
171/// Flow usage: `flow` name (`:` type)? [`from` expr `to` expr]? body.
172#[derive(Debug, Clone, PartialEq, Eq)]
173pub struct FlowUsage {
174    pub name: String,
175    pub type_name: Option<String>,
176    pub from: Option<Node<Expression>>,
177    pub to: Option<Node<Expression>>,
178    pub body: DefinitionBody,
179}
180
181/// First/then control flow: `first` expr `then` expr body.
182#[derive(Debug, Clone, PartialEq, Eq)]
183pub struct FirstStmt {
184    pub first: Node<Expression>,
185    pub then: Node<Expression>,
186    pub body: FirstMergeBody,
187}
188
189/// Merge: `merge` expr body.
190#[derive(Debug, Clone, PartialEq, Eq)]
191pub struct MergeStmt {
192    pub merge: Node<Expression>,
193    pub body: FirstMergeBody,
194}
195
196/// Body of first/merge: `;` or `{` ... `}`.
197#[derive(Debug, Clone, PartialEq, Eq)]
198pub enum FirstMergeBody {
199    Semicolon,
200    Brace,
201}
202
203// ---------------------------------------------------------------------------
204// Allocation
205// ---------------------------------------------------------------------------
206
207/// Allocate statement at part usage level: `allocate` from `to` to body.
208#[derive(Debug, Clone, PartialEq, Eq)]
209pub struct Allocate {
210    pub source: Node<Expression>,
211    pub target: Node<Expression>,
212    pub body: ConnectBody,
213}
214
215/// Allocation definition: `allocation def` Identification body.
216#[derive(Debug, Clone, PartialEq, Eq)]
217pub struct AllocationDef {
218    pub identification: Identification,
219    pub specializes: Option<String>,
220    pub specializes_span: Option<Span>,
221    pub body: DefinitionBody,
222}
223
224/// Allocation usage: `allocation` name (`:` type)? [`allocate` source `to` target]? body.
225#[derive(Debug, Clone, PartialEq, Eq)]
226pub struct AllocationUsage {
227    pub name: String,
228    pub type_name: Option<String>,
229    pub source: Option<Node<Expression>>,
230    pub target: Option<Node<Expression>>,
231    pub body: DefinitionBody,
232}
233
234// ---------------------------------------------------------------------------
235// Requirements
236// ---------------------------------------------------------------------------
237
238/// State definition: `state def` Identification body.
239#[derive(Debug, Clone, PartialEq, Eq)]
240pub struct StateDef {
241    pub identification: Identification,
242    pub specializes: Option<String>,
243    pub specializes_span: Option<Span>,
244    pub body: StateDefBody,
245}
246
247#[derive(Debug, Clone, PartialEq, Eq)]
248pub enum StateDefBody {
249    Semicolon,
250    Brace {
251        elements: Vec<Node<StateDefBodyElement>>,
252    },
253}
254
255#[derive(Debug, Clone, PartialEq, Eq)]
256pub enum StateDefBodyElement {
257    Error(Node<ParseErrorNode>),
258    Doc(Node<DocComment>),
259    Annotation(Node<Annotation>),
260    MetadataKeywordUsage(Node<MetadataKeywordUsage>),
261    Other(String),
262    /// `entry` (`;` or body) - entry action.
263    Entry(Node<EntryAction>),
264    /// `then` name `;` - initial state.
265    Then(Node<ThenStmt>),
266    /// `final` / `final state` name `;` - explicit final state.
267    FinalState(Node<FinalState>),
268    /// `ref` name `:` type body ÔÇô reference binding in state.
269    Ref(Node<RefDecl>),
270    RequirementUsage(Node<RequirementUsage>),
271    StateUsage(Node<StateUsage>),
272    Transition(Node<Transition>),
273}
274
275/// Entry action: `entry` (`;` or body).
276#[derive(Debug, Clone, PartialEq, Eq)]
277pub struct EntryAction {
278    /// For `entry action name body` form; None for plain `entry` body.
279    pub action_name: Option<String>,
280    pub body: StateDefBody,
281}
282
283/// Then (initial state): `then` name `;`
284#[derive(Debug, Clone, PartialEq, Eq)]
285pub struct ThenStmt {
286    pub state_name: String,
287    pub name_span: Option<Span>,
288}
289
290/// Final state: `final` name `;` or `final state` name `;`
291#[derive(Debug, Clone, PartialEq, Eq)]
292pub struct FinalState {
293    pub state_name: String,
294    pub name_span: Span,
295}
296
297/// State usage: `state` name (`:` type)? body.
298#[derive(Debug, Clone, PartialEq, Eq)]
299pub struct StateUsage {
300    pub name: String,
301    pub type_name: Option<String>,
302    pub body: StateDefBody,
303}
304
305/// Transition: `transition` name [`first` source [`accept` trigger]] [`if` guard] [`do` effect] `then` target body.
306#[derive(Debug, Clone, PartialEq, Eq)]
307pub struct Transition {
308    pub name: Option<String>,
309    /// If omitted, form is `transition name then target;`.
310    pub source: Option<Node<Expression>>,
311    /// When `first` is present on a transition, the source state is also an initial state.
312    pub is_initial: bool,
313    /// Structured or shorthand accept trigger after `first` source.
314    pub accept: Option<TransitionAccept>,
315    pub guard: Option<Node<Expression>>,
316    pub effect: Option<Node<Expression>>,
317    pub target: Node<Expression>,
318    pub body: ConnectBody,
319}
320
321// ---------------------------------------------------------------------------
322// Constraints & Calculations
323// ---------------------------------------------------------------------------