Skip to main content

microcad_syntax/ast/
statement.rs

1// Copyright © 2026 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4use crate::ast::{Call, Expression, Identifier, ItemExtras, StatementList, Type};
5use crate::Span;
6
7/// A µcad statements
8#[derive(Debug, PartialEq)]
9#[allow(missing_docs)]
10pub enum Statement {
11    Workbench(WorkbenchDefinition),
12    Module(ModuleDefinition),
13    Function(FunctionDefinition),
14    Init(InitDefinition),
15    Use(UseStatement),
16    Return(Return),
17    InnerAttribute(Attribute),
18    Assignment(Assignment),
19    Expression(ExpressionStatement),
20    Comment(Comment),
21    Error(Span),
22}
23
24impl Statement {
25    /// Get the span for the statement
26    pub fn span(&self) -> Span {
27        match self {
28            Statement::Workbench(st) => st.span.clone(),
29            Statement::Module(st) => st.span.clone(),
30            Statement::Function(st) => st.span.clone(),
31            Statement::Init(st) => st.span.clone(),
32            Statement::Use(st) => st.span.clone(),
33            Statement::Return(st) => st.span.clone(),
34            Statement::InnerAttribute(st) => st.span.clone(),
35            Statement::Assignment(st) => st.span.clone(),
36            Statement::Expression(st) => st.span.clone(),
37            Statement::Comment(st) => st.span.clone(),
38            Statement::Error(span) => span.clone(),
39        }
40    }
41}
42
43/// The possible type of workbenches
44#[derive(Debug, PartialEq, Copy, Clone)]
45#[allow(missing_docs)]
46pub enum WorkbenchKind {
47    Sketch,
48    Part,
49    Op,
50}
51
52/// A definition of a workbench
53#[derive(Debug, PartialEq)]
54#[allow(missing_docs)]
55pub struct WorkbenchDefinition {
56    pub span: Span,
57    pub extras: ItemExtras,
58    pub doc: Option<Comment>,
59    pub kind: WorkbenchKind,
60    pub attributes: Vec<Attribute>,
61    pub visibility: Option<Visibility>,
62    pub name: Identifier,
63    pub arguments: ArgumentsDefinition,
64    pub body: StatementList,
65}
66
67/// A definition of a module
68#[derive(Debug, PartialEq)]
69#[allow(missing_docs)]
70pub struct ModuleDefinition {
71    pub span: Span,
72    pub extras: ItemExtras,
73    pub doc: Option<Comment>,
74    pub attributes: Vec<Attribute>,
75    pub visibility: Option<Visibility>,
76    pub name: Identifier,
77    pub body: Option<StatementList>,
78}
79
80/// A definition of a function
81#[derive(Debug, PartialEq)]
82#[allow(missing_docs)]
83pub struct FunctionDefinition {
84    pub span: Span,
85    pub extras: ItemExtras,
86    pub doc: Option<Comment>,
87    pub visibility: Option<Visibility>,
88    pub name: Identifier,
89    pub arguments: ArgumentsDefinition,
90    pub return_type: Option<Type>,
91    pub body: StatementList,
92}
93
94/// An init definition for a workbench
95#[derive(Debug, PartialEq)]
96#[allow(missing_docs)]
97pub struct InitDefinition {
98    pub span: Span,
99    pub keyword_span: Span,
100    pub extras: ItemExtras,
101    pub doc: Option<Comment>,
102    pub arguments: ArgumentsDefinition,
103    pub body: StatementList,
104}
105
106/// A use statement that imports an item from an external library
107#[derive(Debug, PartialEq)]
108#[allow(missing_docs)]
109pub struct UseStatement {
110    pub span: Span,
111    pub extras: ItemExtras,
112    pub visibility: Option<Visibility>,
113    pub name: UseName,
114    pub use_as: Option<Identifier>,
115}
116
117/// The name of the item being imported
118#[derive(Debug, PartialEq)]
119#[allow(missing_docs)]
120pub struct UseName {
121    pub span: Span,
122    pub extras: ItemExtras,
123    pub parts: Vec<UseStatementPart>,
124}
125
126/// The parts a [`UseName`] consists of, separated by `::`
127#[derive(Debug, PartialEq)]
128#[allow(missing_docs)]
129pub enum UseStatementPart {
130    Identifier(Identifier),
131    Glob(Span),
132}
133
134/// A return statement
135#[derive(Debug, PartialEq)]
136#[allow(missing_docs)]
137pub struct Return {
138    pub span: Span,
139    pub extras: ItemExtras,
140    pub value: Option<Expression>,
141}
142
143/// A definition of the arguments of a workbench definition or function definition
144#[derive(Debug, PartialEq)]
145#[allow(missing_docs)]
146pub struct ArgumentsDefinition {
147    pub span: Span,
148    pub extras: ItemExtras,
149    pub arguments: Vec<ArgumentDefinition>,
150}
151
152/// A definition of a single of a workbench definition or function definition
153#[derive(Debug, PartialEq)]
154#[allow(missing_docs)]
155pub struct ArgumentDefinition {
156    pub span: Span,
157    pub extras: ItemExtras,
158    pub name: Identifier,
159    pub ty: Option<Type>,
160    pub default: Option<Expression>,
161}
162
163/// An attribute that can be attached to a statement
164#[derive(Debug, PartialEq)]
165#[allow(missing_docs)]
166pub struct Attribute {
167    pub span: Span,
168    pub is_inner: bool,
169    pub extras: ItemExtras,
170    pub commands: Vec<AttributeCommand>,
171}
172
173/// The contents an an [`Attribute`]
174#[derive(Debug, PartialEq)]
175#[allow(missing_docs)]
176pub enum AttributeCommand {
177    Ident(Identifier),
178    Assignment(Assignment),
179    Call(Call),
180}
181
182/// An optional qualifier that can be part of an [`Assignment`]
183#[derive(Debug, PartialEq)]
184#[allow(missing_docs)]
185pub enum AssignmentQualifier {
186    Const,
187    Prop,
188}
189
190/// An assigment statement
191#[derive(Debug, PartialEq)]
192#[allow(missing_docs)]
193pub struct Assignment {
194    pub span: Span,
195    pub extras: ItemExtras,
196    pub doc: Option<Comment>,
197    pub attributes: Vec<Attribute>,
198    pub visibility: Option<Visibility>,
199    pub qualifier: Option<AssignmentQualifier>,
200    pub name: Identifier,
201    pub ty: Option<Type>,
202    pub value: Box<Expression>,
203}
204
205/// A single- or multi-line comment
206#[derive(Debug, PartialEq)]
207#[allow(missing_docs)]
208pub struct Comment {
209    pub span: Span,
210    pub lines: Vec<String>,
211}
212
213/// An optional visibility modifier that can be art of assigment and module, function and workbench definitions
214#[derive(Debug, PartialEq)]
215#[allow(missing_docs)]
216pub enum Visibility {
217    Public,
218}
219
220/// A statement containing of a bare expression
221#[derive(Debug, PartialEq)]
222#[allow(missing_docs)]
223pub struct ExpressionStatement {
224    pub span: Span,
225    pub extras: ItemExtras,
226    pub attributes: Vec<Attribute>,
227    pub expression: Expression,
228}