Rust · 3229 bytes Raw Blame History
1 //! Program unit AST nodes.
2 //!
3 //! Top-level compilation units: programs, modules, submodules,
4 //! subroutines, functions, block data, and interface blocks.
5
6 use super::decl::{SpannedDecl, TypeSpec};
7 use super::stmt::SpannedStmt;
8 use super::Spanned;
9
10 /// A spanned program unit.
11 pub type SpannedUnit = Spanned<ProgramUnit>;
12
13 /// A Fortran program unit — the top-level organizational structure.
14 #[derive(Debug, Clone, PartialEq)]
15 #[allow(clippy::large_enum_variant)]
16 pub enum ProgramUnit {
17 Program {
18 name: Option<String>,
19 uses: Vec<SpannedDecl>,
20 imports: Vec<ImportStmt>,
21 implicit: Vec<SpannedDecl>,
22 decls: Vec<SpannedDecl>,
23 body: Vec<SpannedStmt>,
24 contains: Vec<SpannedUnit>,
25 },
26
27 Module {
28 name: String,
29 uses: Vec<SpannedDecl>,
30 imports: Vec<ImportStmt>,
31 implicit: Vec<SpannedDecl>,
32 decls: Vec<SpannedDecl>,
33 contains: Vec<SpannedUnit>,
34 },
35
36 Submodule {
37 parent: String,
38 ancestor: Option<String>,
39 name: String,
40 uses: Vec<SpannedDecl>,
41 decls: Vec<SpannedDecl>,
42 contains: Vec<SpannedUnit>,
43 },
44
45 Subroutine {
46 name: String,
47 args: Vec<DummyArg>,
48 bind: Option<BindInfo>,
49 prefix: Vec<Prefix>,
50 uses: Vec<SpannedDecl>,
51 imports: Vec<ImportStmt>,
52 implicit: Vec<SpannedDecl>,
53 decls: Vec<SpannedDecl>,
54 body: Vec<SpannedStmt>,
55 contains: Vec<SpannedUnit>,
56 },
57
58 Function {
59 name: String,
60 args: Vec<DummyArg>,
61 result: Option<String>,
62 return_type: Option<TypeSpec>,
63 bind: Option<BindInfo>,
64 prefix: Vec<Prefix>,
65 uses: Vec<SpannedDecl>,
66 imports: Vec<ImportStmt>,
67 implicit: Vec<SpannedDecl>,
68 decls: Vec<SpannedDecl>,
69 body: Vec<SpannedStmt>,
70 contains: Vec<SpannedUnit>,
71 },
72
73 BlockData {
74 name: Option<String>,
75 uses: Vec<SpannedDecl>,
76 decls: Vec<SpannedDecl>,
77 },
78
79 /// An interface block (explicit, generic, abstract).
80 InterfaceBlock {
81 name: Option<String>,
82 is_abstract: bool,
83 bodies: Vec<InterfaceBody>,
84 },
85 }
86
87 /// Subprogram prefix.
88 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
89 pub enum Prefix {
90 Pure,
91 Impure,
92 Elemental,
93 Recursive,
94 NonRecursive,
95 Module,
96 }
97
98 /// A dummy argument in a subprogram.
99 #[derive(Debug, Clone, PartialEq)]
100 pub enum DummyArg {
101 Name(String),
102 Star, // alternate return: *
103 }
104
105 /// BIND(C) specification.
106 #[derive(Debug, Clone, PartialEq)]
107 pub struct BindInfo {
108 pub name: Option<String>, // BIND(C, NAME="cname") — None if just BIND(C)
109 }
110
111 /// Body of an interface block — either a subprogram interface or a module procedure name.
112 #[derive(Debug, Clone, PartialEq)]
113 #[allow(clippy::large_enum_variant)]
114 pub enum InterfaceBody {
115 Subprogram(SpannedUnit),
116 ModuleProcedure(Vec<String>),
117 }
118
119 /// IMPORT statement.
120 #[derive(Debug, Clone, PartialEq)]
121 pub enum ImportStmt {
122 Default(Vec<String>), // import :: name1, name2
123 All, // import, all
124 None, // import, none
125 Only(Vec<String>), // import, only: name1, name2
126 }
127