Skip to main content

stack_compiler/
ast.rs

1//! Source-oriented abstract syntax tree.
2
3use crate::diagnostic::{Span, Spanned};
4
5/// A parsed Stack document.
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct Document {
8    /// Authored language version.
9    pub version: Version,
10    /// The document's single diagram.
11    pub diagram: Diagram,
12    /// Span of the complete document.
13    pub span: Span,
14}
15
16/// A `major.minor` language version.
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct Version {
19    /// Authored major number.
20    pub major: u32,
21    /// Authored minor number.
22    pub minor: u32,
23    /// Span of the complete version directive.
24    pub span: Span,
25}
26
27/// The root diagram declaration.
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub struct Diagram {
30    /// Visible diagram title.
31    pub title: Spanned<String>,
32    /// Authored declarations in source order.
33    pub members: Vec<DiagramMember>,
34    /// Span of the complete declaration.
35    pub span: Span,
36}
37
38/// A declaration allowed directly inside a diagram.
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub enum DiagramMember {
41    /// Node declaration.
42    Node(Node),
43    /// Group declaration.
44    Group(Group),
45    /// Edge declaration.
46    Edge(Edge),
47    /// Theme selection.
48    Theme(Theme),
49    /// Layout block.
50    Layout(Layout),
51}
52
53/// A theme selection statement.
54#[derive(Debug, Clone, PartialEq, Eq)]
55pub struct Theme {
56    /// Authored theme identifier.
57    pub identifier: Spanned<String>,
58    /// Span of the complete statement.
59    pub span: Span,
60}
61
62/// A labeled containment group.
63#[derive(Debug, Clone, PartialEq, Eq)]
64pub struct Group {
65    /// Source identifier.
66    pub identifier: Spanned<String>,
67    /// Visible group label.
68    pub label: Spanned<String>,
69    /// Authored group members in source order.
70    pub members: Vec<GroupMember>,
71    /// Span of the complete declaration.
72    pub span: Span,
73}
74
75/// A declaration allowed directly inside a group.
76#[derive(Debug, Clone, PartialEq, Eq)]
77pub enum GroupMember {
78    /// Node declaration.
79    Node(Node),
80    /// Nested group declaration.
81    Group(Group),
82    /// Scoped layout block.
83    Layout(Layout),
84}
85
86/// An architectural node declaration.
87#[derive(Debug, Clone, PartialEq, Eq)]
88pub struct Node {
89    /// Source identifier.
90    pub identifier: Spanned<String>,
91    /// Visible node label.
92    pub label: Spanned<String>,
93    /// Authored properties in source order.
94    pub properties: Vec<NodeProperty>,
95    /// Span of the complete declaration.
96    pub span: Span,
97}
98
99/// A property in a node block.
100#[derive(Debug, Clone, PartialEq, Eq)]
101pub enum NodeProperty {
102    /// Authored node kind.
103    Kind(Spanned<String>),
104    /// Authored theme or namespaced provider icon identifier.
105    Icon(Spanned<String>),
106    /// Authored visible detail.
107    Detail(Spanned<String>),
108}
109
110impl NodeProperty {
111    /// Returns this property's value span.
112    pub fn span(&self) -> Span {
113        match self {
114            Self::Kind(value) | Self::Icon(value) | Self::Detail(value) => value.span,
115        }
116    }
117}
118
119/// An edge declaration between two identifiers.
120#[derive(Debug, Clone, PartialEq, Eq)]
121pub struct Edge {
122    /// Left endpoint reference.
123    pub from: Spanned<String>,
124    /// Authored edge operator.
125    pub operator: Spanned<EdgeOperator>,
126    /// Right endpoint reference.
127    pub to: Spanned<String>,
128    /// Optional visible edge label.
129    pub label: Option<Spanned<String>>,
130    /// Authored edge properties in source order.
131    pub properties: Vec<EdgeProperty>,
132    /// Span of the complete declaration.
133    pub span: Span,
134}
135
136/// Directionality expressed by an edge operator.
137#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
138pub enum EdgeOperator {
139    /// `->`
140    Forward,
141    /// `<->`
142    Bidirectional,
143    /// `--`
144    Association,
145}
146
147/// A property in an edge block.
148#[derive(Debug, Clone, PartialEq, Eq)]
149pub enum EdgeProperty {
150    /// Authored relationship kind.
151    Kind(Spanned<String>),
152}
153
154impl EdgeProperty {
155    /// Returns this property's value span.
156    pub fn span(&self) -> Span {
157        match self {
158            Self::Kind(value) => value.span,
159        }
160    }
161}
162
163/// A scoped collection of layout statements.
164#[derive(Debug, Clone, PartialEq, Eq)]
165pub struct Layout {
166    /// Authored statements in source order.
167    pub statements: Vec<LayoutStatement>,
168    /// Span of the complete block.
169    pub span: Span,
170}
171
172/// A layout constraint or hint.
173#[derive(Debug, Clone, PartialEq, Eq)]
174pub enum LayoutStatement {
175    /// Preferred flow direction.
176    Direction(Spanned<String>),
177    /// Same-rank constraint.
178    RankSame(IdentifierList),
179    /// Relative-order hint.
180    Order(IdentifierList),
181}
182
183impl LayoutStatement {
184    /// Returns the complete statement span.
185    pub fn span(&self) -> Span {
186        match self {
187            Self::Direction(value) => value.span,
188            Self::RankSame(list) | Self::Order(list) => list.span,
189        }
190    }
191}
192
193/// A bracketed list of identifier references.
194#[derive(Debug, Clone, PartialEq, Eq)]
195pub struct IdentifierList {
196    /// Authored identifiers in source order.
197    pub identifiers: Vec<Spanned<String>>,
198    /// Span including the list brackets.
199    pub span: Span,
200}