Skip to main content

oak_fsharp/ast/
mod.rs

1#![doc = include_str!("readme.md")]
2
3use core::range::Range;
4
5/// The root node of an F# program
6#[derive(Debug, Clone, PartialEq)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct FSharpRoot {
9    /// Items in the compilation unit
10    pub items: Vec<Item>,
11}
12
13/// Top-level items in an F# program
14#[derive(Debug, Clone, PartialEq)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub enum Item {
17    /// Namespace declaration
18    Namespace(NamespaceDeclaration),
19    /// Module declaration
20    Module(ModuleDeclaration),
21    /// Open directive (open)
22    Open(OpenDirective),
23    /// Binding (let)
24    Binding(Binding),
25    /// Type definition (type)
26    Type(TypeDefinition),
27    /// Class definition (type ... = class)
28    Class(ClassDefinition),
29    /// Interface definition (type ... = interface)
30    Interface(InterfaceDefinition),
31    /// Exception definition (exception)
32    Exception(ExceptionDefinition),
33}
34
35/// Namespace declaration
36#[derive(Debug, Clone, PartialEq)]
37#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
38pub struct NamespaceDeclaration {
39    /// Namespace name
40    pub name: String,
41    /// Members
42    pub items: Vec<Item>,
43    /// Source span
44    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
45    pub span: Range<usize>,
46}
47
48/// Module declaration
49#[derive(Debug, Clone, PartialEq)]
50#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
51pub struct ModuleDeclaration {
52    /// Module name
53    pub name: String,
54    /// Whether it is a top-level module
55    pub is_top_level: bool,
56    /// Whether it is a nested module
57    pub is_nested: bool,
58    /// Members
59    pub items: Vec<Item>,
60    /// Source span
61    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
62    pub span: Range<usize>,
63}
64
65/// Open directive (open)
66#[derive(Debug, Clone, PartialEq)]
67#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
68pub struct OpenDirective {
69    /// Import path
70    pub path: String,
71    /// Source span
72    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
73    pub span: Range<usize>,
74}
75
76/// Binding (let)
77#[derive(Debug, Clone, PartialEq)]
78#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
79pub struct Binding {
80    /// Binding name
81    pub name: String,
82    /// Whether it is a recursive binding (rec)
83    pub is_rec: bool,
84    /// Whether it is mutable (mutable)
85    pub is_mutable: bool,
86    /// Parameter list
87    pub parameters: Vec<Parameter>,
88    /// Type annotation
89    pub type_annotation: Option<String>,
90    /// Bound expression
91    pub expression: Expression,
92    /// Source span
93    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
94    pub span: Range<usize>,
95}
96
97/// Parameter
98#[derive(Debug, Clone, PartialEq)]
99#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
100pub struct Parameter {
101    /// Parameter name
102    pub name: String,
103    /// Type annotation
104    pub type_annotation: Option<String>,
105}
106
107/// Type definition
108#[derive(Debug, Clone, PartialEq)]
109#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
110pub struct TypeDefinition {
111    /// Type name
112    pub name: String,
113    /// Type parameters
114    pub type_parameters: Vec<String>,
115    /// Type body
116    pub body: TypeBody,
117    /// Source span
118    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
119    pub span: Range<usize>,
120}
121
122/// Type body
123#[derive(Debug, Clone, PartialEq)]
124#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
125pub enum TypeBody {
126    /// Record type
127    Record(Vec<RecordField>),
128    /// Union type
129    Union(Vec<UnionCase>),
130    /// Alias
131    Alias(String),
132    /// Struct
133    Struct(Vec<RecordField>),
134}
135
136/// Record field
137#[derive(Debug, Clone, PartialEq)]
138#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
139pub struct RecordField {
140    /// Field name
141    pub name: String,
142    /// Field type
143    pub field_type: String,
144}
145
146/// Union case
147#[derive(Debug, Clone, PartialEq)]
148#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
149pub struct UnionCase {
150    /// Case name
151    pub name: String,
152    /// Case fields
153    pub fields: Vec<RecordField>,
154}
155
156/// Class definition
157#[derive(Debug, Clone, PartialEq)]
158#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
159pub struct ClassDefinition {
160    /// Class name
161    pub name: String,
162    /// Type parameters
163    pub type_parameters: Vec<String>,
164    /// Base class
165    pub base_class: Option<String>,
166    /// Interfaces
167    pub interfaces: Vec<String>,
168    /// Members
169    pub members: Vec<ClassMember>,
170    /// Source span
171    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
172    pub span: Range<usize>,
173}
174
175/// Class member
176#[derive(Debug, Clone, PartialEq)]
177#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
178pub enum ClassMember {
179    /// Constructor
180    Constructor(Constructor),
181    /// Method
182    Method(Method),
183    /// Property
184    Property(Property),
185    /// Field
186    Field(Field),
187}
188
189/// Constructor
190#[derive(Debug, Clone, PartialEq)]
191#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
192pub struct Constructor {
193    /// Parameters
194    pub parameters: Vec<Parameter>,
195    /// Body
196    pub body: Expression,
197}
198
199/// Method
200#[derive(Debug, Clone, PartialEq)]
201#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
202pub struct Method {
203    /// Method name
204    pub name: String,
205    /// Parameters
206    pub parameters: Vec<Parameter>,
207    /// Return type
208    pub return_type: Option<String>,
209    /// Body
210    pub body: Expression,
211}
212
213/// Property
214#[derive(Debug, Clone, PartialEq)]
215#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
216pub struct Property {
217    /// Property name
218    pub name: String,
219    /// Property type
220    pub property_type: String,
221    /// Getter
222    pub getter: Option<Expression>,
223    /// Setter
224    pub setter: Option<Expression>,
225}
226
227/// Field
228#[derive(Debug, Clone, PartialEq)]
229#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
230pub struct Field {
231    /// Field name
232    pub name: String,
233    /// Field type
234    pub field_type: String,
235    /// Initial value
236    pub initial_value: Option<Expression>,
237}
238
239/// Interface definition
240#[derive(Debug, Clone, PartialEq)]
241#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
242pub struct InterfaceDefinition {
243    /// Interface name
244    pub name: String,
245    /// Type parameters
246    pub type_parameters: Vec<String>,
247    /// Base interfaces
248    pub base_interfaces: Vec<String>,
249    /// Members
250    pub members: Vec<InterfaceMember>,
251    /// Source span
252    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
253    pub span: Range<usize>,
254}
255
256/// Interface member
257#[derive(Debug, Clone, PartialEq)]
258#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
259pub enum InterfaceMember {
260    /// Method signature
261    MethodSignature(Method),
262    /// Property signature
263    PropertySignature(Property),
264}
265
266/// Exception definition
267#[derive(Debug, Clone, PartialEq)]
268#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
269pub struct ExceptionDefinition {
270    /// Exception name
271    pub name: String,
272    /// Fields
273    pub fields: Vec<RecordField>,
274    /// Source span
275    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
276    pub span: Range<usize>,
277}
278
279/// F# expression
280#[derive(Debug, Clone, PartialEq)]
281#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
282pub enum Expression {
283    /// Literal
284    Literal(Literal),
285    /// Identifier
286    Identifier(String),
287    /// If expression
288    If {
289        /// Condition expression
290        condition: Box<Expression>,
291        /// Then branch
292        then_branch: Box<Expression>,
293        /// Else branch
294        else_branch: Option<Box<Expression>>,
295    },
296    /// Match expression
297    Match {
298        /// Expression to match
299        expression: Box<Expression>,
300        /// Match cases
301        cases: Vec<MatchCase>,
302    },
303    /// Lambda expression
304    Lambda {
305        /// Parameters
306        parameters: Vec<Parameter>,
307        /// Body
308        body: Box<Expression>,
309    },
310    /// Function application
311    Application {
312        /// Function
313        function: Box<Expression>,
314        /// Argument
315        argument: Box<Expression>,
316    },
317    /// Binary expression
318    Binary {
319        /// Left operand
320        left: Box<Expression>,
321        /// Operator
322        op: String,
323        /// Right operand
324        right: Box<Expression>,
325    },
326    /// Unary expression
327    Unary {
328        /// Operator
329        op: String,
330        /// Operand
331        operand: Box<Expression>,
332    },
333    /// Let expression
334    Let {
335        /// Bindings
336        bindings: Vec<Binding>,
337        /// Body
338        body: Box<Expression>,
339    },
340    /// Pipe forward operator (|>)
341    PipeForward {
342        /// Expression
343        expression: Box<Expression>,
344        /// Function
345        function: Box<Expression>,
346    },
347    /// Pipe backward operator (<|)
348    PipeBackward {
349        /// Function
350        function: Box<Expression>,
351        /// Expression
352        expression: Box<Expression>,
353    },
354    /// Tuple
355    Tuple(Vec<Expression>),
356    /// List
357    List(Vec<Expression>),
358    /// Array
359    Array(Vec<Expression>),
360    /// Record expression
361    Record {
362        /// Type name
363        type_name: Option<String>,
364        /// Fields
365        fields: Vec<(String, Expression)>,
366    },
367    /// Union case expression
368    UnionCase {
369        /// Case name
370        case_name: String,
371        /// Arguments
372        arguments: Vec<Expression>,
373    },
374    /// Sequential expressions
375    Sequential(Vec<Expression>),
376    /// Parenthesized expression
377    Parenthesized(Box<Expression>),
378    /// Async expression
379    Async(Box<Expression>),
380    /// Computation expression
381    Computation {
382        /// Builder name
383        builder: String,
384        /// Body
385        body: Vec<ComputationItem>,
386    },
387}
388
389/// Literal
390#[derive(Debug, Clone, PartialEq)]
391#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
392pub enum Literal {
393    /// Integer
394    Integer(i64),
395    /// Float
396    Float(f64),
397    /// String
398    String(String),
399    /// Char
400    Char(char),
401    /// Boolean
402    Boolean(bool),
403    /// Unit
404    Unit,
405}
406
407/// Match case
408#[derive(Debug, Clone, PartialEq)]
409#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
410pub struct MatchCase {
411    /// Pattern
412    pub pattern: Pattern,
413    /// Guard
414    pub guard: Option<Expression>,
415    /// Body
416    pub body: Expression,
417}
418
419/// Pattern
420#[derive(Debug, Clone, PartialEq)]
421#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
422pub enum Pattern {
423    /// Wildcard (_)
424    Wildcard,
425    /// Identifier
426    Identifier(String),
427    /// Literal
428    Literal(Literal),
429    /// Tuple pattern
430    Tuple(Vec<Pattern>),
431    /// List pattern
432    List(Vec<Pattern>),
433    /// Union case pattern
434    UnionCase {
435        /// Case name
436        case_name: String,
437        /// Patterns
438        patterns: Vec<Pattern>,
439    },
440    /// Record pattern
441    Record(Vec<String>),
442    /// As pattern
443    As {
444        /// Pattern
445        pattern: Box<Pattern>,
446        /// Identifier
447        identifier: String,
448    },
449    /// Or pattern
450    Or(Box<Pattern>, Box<Pattern>),
451}
452
453/// Computation item
454#[derive(Debug, Clone, PartialEq)]
455#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
456pub enum ComputationItem {
457    /// Let binding
458    Let(Binding),
459    /// Yield
460    Yield(Expression),
461    /// Return
462    Return(Expression),
463    /// Expression
464    Expression(Expression),
465    /// Custom operation
466    CustomOperation {
467        /// Operation name
468        name: String,
469        /// Arguments
470        arguments: Vec<Expression>,
471    },
472}