Rust · 6396 bytes Raw Blame History
1 //! Declaration AST nodes.
2 //!
3 //! Types, attributes, entity declarations, USE statements, IMPLICIT,
4 //! derived type definitions, and legacy declaration forms.
5
6 use super::expr::SpannedExpr;
7 use super::Spanned;
8
9 /// A spanned declaration.
10 pub type SpannedDecl = Spanned<Decl>;
11
12 /// A Fortran declaration.
13 #[derive(Debug, Clone, PartialEq)]
14 #[allow(clippy::enum_variant_names)]
15 pub enum Decl {
16 /// Type declaration: `integer, allocatable :: x(:), y`
17 TypeDecl {
18 type_spec: TypeSpec,
19 attrs: Vec<Attribute>,
20 entities: Vec<EntityDecl>,
21 },
22
23 /// Standalone `PRIVATE` or `PUBLIC` statement that sets the module's
24 /// default access for all subsequent declarations.
25 AccessDefault { access: Attribute },
26
27 /// `PUBLIC :: name1, name2` or `PRIVATE :: assignment(=)` — sets
28 /// access on specific names or generic specs.
29 AccessList {
30 access: Attribute,
31 names: Vec<String>,
32 },
33
34 /// `implicit none` or `implicit none(type, external)`
35 ImplicitNone { external: bool, type_: bool },
36
37 /// `implicit double precision (a-h, o-z)`
38 ImplicitStmt { specs: Vec<ImplicitSpec> },
39
40 /// Derived type definition
41 DerivedTypeDef {
42 name: String,
43 extends: Option<String>,
44 attrs: Vec<TypeAttr>,
45 components: Vec<SpannedDecl>,
46 type_bound_procs: Vec<TypeBoundProc>,
47 final_procs: Vec<String>,
48 },
49
50 /// `use module_name [, only: ...]`
51 UseStmt {
52 module: String,
53 nature: UseNature,
54 renames: Vec<Rename>,
55 only: Option<Vec<OnlyItem>>,
56 },
57
58 /// `parameter (pi = 3.14159, e = 2.71828)`
59 ParameterStmt { pairs: Vec<(String, SpannedExpr)> },
60
61 /// `common /block_name/ x, y, z`
62 CommonBlock {
63 name: Option<String>,
64 vars: Vec<String>,
65 },
66
67 /// `equivalence (a, b), (c, d)`
68 EquivalenceStmt { groups: Vec<Vec<SpannedExpr>> },
69
70 /// `data x /1.0/, y /2.0/`
71 DataStmt { sets: Vec<DataSet> },
72
73 /// `enum, bind(c)`
74 EnumDef {
75 enumerators: Vec<(String, Option<SpannedExpr>)>,
76 },
77
78 /// Standalone attribute statement: `allocatable :: x`, `dimension(10) :: a`
79 AttributeStmt {
80 attr: Attribute,
81 entities: Vec<String>,
82 },
83 }
84
85 // ---- Type specifiers ----
86
87 /// Fortran type specifier.
88 #[derive(Debug, Clone, PartialEq)]
89 pub enum TypeSpec {
90 Integer(Option<KindSelector>),
91 Real(Option<KindSelector>),
92 DoublePrecision,
93 Complex(Option<KindSelector>),
94 DoubleComplex,
95 Logical(Option<KindSelector>),
96 Character(Option<CharSelector>),
97 /// `type(my_type)` — derived type reference
98 Type(String),
99 /// `class(my_type)` — polymorphic
100 Class(String),
101 /// `class(*)` — unlimited polymorphic
102 ClassStar,
103 /// `type(*)` — assumed type
104 TypeStar,
105 }
106
107 /// Kind selector: `(4)`, `(kind=4)`, `*4`
108 #[derive(Debug, Clone, PartialEq)]
109 pub enum KindSelector {
110 Expr(SpannedExpr),
111 Star(SpannedExpr), // *4 (old-style)
112 }
113
114 /// Character selector: `(10)`, `(len=10, kind=1)`, `*10`
115 #[derive(Debug, Clone, PartialEq)]
116 pub struct CharSelector {
117 pub len: Option<LenSpec>,
118 pub kind: Option<SpannedExpr>,
119 }
120
121 /// Character length specification.
122 #[derive(Debug, Clone, PartialEq)]
123 pub enum LenSpec {
124 Expr(SpannedExpr),
125 Star, // len=* (assumed length)
126 Colon, // len=: (deferred length)
127 }
128
129 // ---- Attributes ----
130
131 /// Declaration attribute.
132 #[derive(Debug, Clone, PartialEq)]
133 pub enum Attribute {
134 Dimension(Vec<ArraySpec>),
135 Allocatable,
136 Pointer,
137 Target,
138 Intent(Intent),
139 Optional,
140 Save,
141 Parameter,
142 Value,
143 Volatile,
144 Asynchronous,
145 Protected,
146 Contiguous,
147 External,
148 Intrinsic,
149 Bind(Option<String>), // bind(c, name="cfunc")
150 Public,
151 Private,
152 }
153
154 /// Intent specification.
155 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
156 pub enum Intent {
157 In,
158 Out,
159 InOut,
160 }
161
162 /// Array specification for dimension attribute.
163 #[derive(Debug, Clone, PartialEq)]
164 pub enum ArraySpec {
165 /// `(10)` or `(1:10)` — explicit bounds
166 Explicit {
167 lower: Option<SpannedExpr>,
168 upper: SpannedExpr,
169 },
170 /// `(:)` — assumed shape (for dummy arguments)
171 AssumedShape { lower: Option<SpannedExpr> },
172 /// `(*)` — assumed size (last dimension only)
173 AssumedSize { lower: Option<SpannedExpr> },
174 /// `(:)` with allocatable/pointer — deferred shape
175 Deferred,
176 /// `(..)` — assumed rank (F2018)
177 AssumedRank,
178 }
179
180 // ---- Entity declarations ----
181
182 /// An entity in a type declaration: `x`, `x = 0`, `x(:,:)`, `ptr => null()`
183 #[derive(Debug, Clone, PartialEq)]
184 pub struct EntityDecl {
185 pub name: String,
186 pub array_spec: Option<Vec<ArraySpec>>,
187 pub char_len: Option<LenSpec>, // character entity-specific length
188 pub init: Option<SpannedExpr>, // = expr
189 pub ptr_init: Option<SpannedExpr>, // => expr
190 }
191
192 // ---- Derived type parts ----
193
194 /// Derived type attribute.
195 #[derive(Debug, Clone, PartialEq)]
196 pub enum TypeAttr {
197 Public,
198 Private,
199 Abstract,
200 Bind(Option<String>),
201 Extends(String),
202 }
203
204 /// Type-bound procedure.
205 #[derive(Debug, Clone, PartialEq)]
206 pub struct TypeBoundProc {
207 pub name: String,
208 pub interface: Option<String>, // procedure(iface) :: name
209 pub binding: Option<String>, // procedure :: name => binding
210 pub bindings: Vec<String>, // generic :: name => specific_a, specific_b
211 pub attrs: Vec<String>, // pass, nopass, deferred, etc.
212 pub is_generic: bool,
213 }
214
215 // ---- USE statement parts ----
216
217 /// USE module nature.
218 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
219 pub enum UseNature {
220 Normal,
221 Intrinsic,
222 NonIntrinsic,
223 }
224
225 /// USE rename: `local => remote`
226 #[derive(Debug, Clone, PartialEq)]
227 pub struct Rename {
228 pub local: String,
229 pub remote: String,
230 }
231
232 /// USE ONLY item.
233 #[derive(Debug, Clone, PartialEq)]
234 pub enum OnlyItem {
235 Name(String),
236 Rename(Rename),
237 Generic(String),
238 }
239
240 // ---- IMPLICIT parts ----
241
242 /// Implicit type specification: `double precision (a-h, o-z)`
243 #[derive(Debug, Clone, PartialEq)]
244 pub struct ImplicitSpec {
245 pub type_spec: TypeSpec,
246 pub ranges: Vec<(char, char)>,
247 }
248
249 // ---- DATA statement parts ----
250
251 /// A data set: `x /1.0/` or `(a(i), i=1,10) /10*0.0/`
252 #[derive(Debug, Clone, PartialEq)]
253 pub struct DataSet {
254 pub objects: Vec<SpannedExpr>,
255 pub values: Vec<SpannedExpr>,
256 }
257