erl_ast/ast/
form.rs

1//! Module Declarations and Forms
2//!
3//! See: [6.1 Module Declarations and Forms](http://erlang.org/doc/apps/erts/absform.html#id86691)
4use ast;
5use ast::clause;
6use ast::common;
7use ast::expr;
8use ast::ty;
9use eetf;
10
11#[derive(Debug, Clone)]
12pub enum Form {
13    Module(ModuleAttr),
14    Behaviour(BehaviourAttr),
15    Export(ExportAttr),
16    Import(ImportAttr),
17    ExportType(ExportTypeAttr),
18    Compile(CompileOptionsAttr),
19    File(FileAttr),
20    Record(RecordDecl),
21    Type(TypeDecl),
22    Spec(FunSpec),
23    Attr(WildAttr),
24    Fun(FunDecl),
25    Eof(Eof),
26}
27impl_from!(Form::Module(ModuleAttr));
28impl_from!(Form::Behaviour(BehaviourAttr));
29impl_from!(Form::Export(ExportAttr));
30impl_from!(Form::Import(ImportAttr));
31impl_from!(Form::ExportType(ExportTypeAttr));
32impl_from!(Form::Compile(CompileOptionsAttr));
33impl_from!(Form::File(FileAttr));
34impl_from!(Form::Record(RecordDecl));
35impl_from!(Form::Type(TypeDecl));
36impl_from!(Form::Spec(FunSpec));
37impl_from!(Form::Attr(WildAttr));
38impl_from!(Form::Fun(FunDecl));
39impl_from!(Form::Eof(Eof));
40impl ast::Node for Form {
41    fn line(&self) -> ast::LineNum {
42        match *self {
43            Form::Module(ref x) => x.line(),
44            Form::Behaviour(ref x) => x.line(),
45            Form::Export(ref x) => x.line(),
46            Form::Import(ref x) => x.line(),
47            Form::ExportType(ref x) => x.line(),
48            Form::Compile(ref x) => x.line(),
49            Form::File(ref x) => x.line(),
50            Form::Record(ref x) => x.line(),
51            Form::Type(ref x) => x.line(),
52            Form::Spec(ref x) => x.line(),
53            Form::Attr(ref x) => x.line(),
54            Form::Fun(ref x) => x.line(),
55            Form::Eof(ref x) => x.line(),
56        }
57    }
58}
59
60#[derive(Debug, Clone)]
61pub struct Eof {
62    pub line: ast::LineNum,
63}
64impl_node!(Eof);
65impl Eof {
66    pub fn new(line: ast::LineNum) -> Self {
67        Eof { line }
68    }
69}
70
71#[derive(Debug, Clone)]
72pub struct ModuleAttr {
73    pub line: ast::LineNum,
74    pub name: String,
75}
76impl_node!(ModuleAttr);
77impl ModuleAttr {
78    pub fn new(line: ast::LineNum, name: String) -> Self {
79        ModuleAttr { line, name }
80    }
81}
82
83#[derive(Debug, Clone)]
84pub struct BehaviourAttr {
85    pub line: ast::LineNum,
86    pub is_british: bool,
87    pub name: String,
88}
89impl_node!(BehaviourAttr);
90impl BehaviourAttr {
91    pub fn new(line: ast::LineNum, name: String) -> Self {
92        BehaviourAttr {
93            line,
94            name,
95            is_british: true,
96        }
97    }
98    pub fn british(mut self, is_british: bool) -> Self {
99        self.is_british = is_british;
100        self
101    }
102}
103
104#[derive(Debug, Clone)]
105pub struct ExportAttr {
106    pub line: ast::LineNum,
107    pub funs: Vec<Export>,
108}
109impl_node!(ExportAttr);
110impl ExportAttr {
111    pub fn new(line: ast::LineNum, funs: Vec<Export>) -> Self {
112        ExportAttr { line, funs }
113    }
114}
115
116#[derive(Debug, Clone)]
117pub struct ImportAttr {
118    pub line: ast::LineNum,
119    pub module: String,
120    pub funs: Vec<Import>,
121}
122impl_node!(ImportAttr);
123impl ImportAttr {
124    pub fn new(line: ast::LineNum, module: String, funs: Vec<Import>) -> Self {
125        ImportAttr { line, module, funs }
126    }
127}
128
129#[derive(Debug, Clone)]
130pub struct ExportTypeAttr {
131    pub line: ast::LineNum,
132    pub types: Vec<ExportType>,
133}
134impl_node!(ExportTypeAttr);
135impl ExportTypeAttr {
136    pub fn new(line: ast::LineNum, types: Vec<ExportType>) -> Self {
137        ExportTypeAttr { line, types }
138    }
139}
140
141#[derive(Debug, Clone)]
142pub struct CompileOptionsAttr {
143    pub line: ast::LineNum,
144    pub options: eetf::Term,
145}
146impl_node!(CompileOptionsAttr);
147impl CompileOptionsAttr {
148    pub fn new(line: ast::LineNum, options: eetf::Term) -> Self {
149        CompileOptionsAttr { line, options }
150    }
151}
152
153#[derive(Debug, Clone)]
154pub struct FileAttr {
155    pub line: ast::LineNum,
156    pub original_file: String,
157    pub original_line: ast::LineNum,
158}
159impl_node!(FileAttr);
160impl FileAttr {
161    pub fn new(line: ast::LineNum, original_file: String, original_line: ast::LineNum) -> Self {
162        FileAttr {
163            line,
164            original_file,
165            original_line,
166        }
167    }
168}
169
170#[derive(Debug, Clone)]
171pub struct RecordDecl {
172    pub line: ast::LineNum,
173    pub name: String,
174    pub fields: Vec<RecordFieldDecl>,
175}
176impl_node!(RecordDecl);
177impl RecordDecl {
178    pub fn new(line: ast::LineNum, name: String, fields: Vec<RecordFieldDecl>) -> Self {
179        RecordDecl { line, name, fields }
180    }
181}
182
183#[derive(Debug, Clone)]
184pub struct TypeDecl {
185    pub line: ast::LineNum,
186    pub is_opaque: bool,
187    pub name: String,
188    pub vars: Vec<common::Var>,
189    pub ty: ty::Type,
190}
191impl_node!(TypeDecl);
192impl TypeDecl {
193    pub fn new(line: ast::LineNum, name: String, vars: Vec<common::Var>, ty: ty::Type) -> Self {
194        TypeDecl {
195            line,
196            name,
197            vars,
198            ty,
199            is_opaque: false,
200        }
201    }
202    pub fn opaque(mut self, is_opaque: bool) -> Self {
203        self.is_opaque = is_opaque;
204        self
205    }
206}
207
208#[derive(Debug, Clone)]
209pub struct FunSpec {
210    pub line: ast::LineNum,
211    pub module: Option<String>,
212    pub name: String,
213    pub types: Vec<ty::Fun>,
214    pub is_callback: bool,
215}
216impl_node!(FunSpec);
217impl FunSpec {
218    pub fn new(line: ast::LineNum, name: String, types: Vec<ty::Fun>) -> Self {
219        FunSpec {
220            line,
221            module: None,
222            name,
223            types,
224            is_callback: false,
225        }
226    }
227    pub fn module(mut self, module: String) -> Self {
228        self.module = Some(module);
229        self
230    }
231    pub fn callback(mut self, is_callback: bool) -> Self {
232        self.is_callback = is_callback;
233        self
234    }
235}
236
237#[derive(Debug, Clone)]
238pub struct WildAttr {
239    pub line: ast::LineNum,
240    pub name: String,
241    pub value: eetf::Term,
242}
243impl_node!(WildAttr);
244impl WildAttr {
245    pub fn new(line: ast::LineNum, name: String, value: eetf::Term) -> Self {
246        WildAttr { line, name, value }
247    }
248}
249
250#[derive(Debug, Clone)]
251pub struct FunDecl {
252    pub line: ast::LineNum,
253    pub name: String,
254    pub clauses: Vec<clause::Clause>,
255}
256impl_node!(FunDecl);
257impl FunDecl {
258    pub fn new(line: ast::LineNum, name: String, clauses: Vec<clause::Clause>) -> Self {
259        FunDecl {
260            line,
261            name,
262            clauses,
263        }
264    }
265}
266
267#[derive(Debug, Clone)]
268pub struct RecordFieldDecl {
269    pub line: ast::LineNum,
270    pub name: String,
271    pub ty: ty::Type,
272    pub default_value: expr::Expression,
273}
274impl_node!(RecordFieldDecl);
275impl RecordFieldDecl {
276    pub fn new(line: ast::LineNum, name: String) -> Self {
277        RecordFieldDecl {
278            line,
279            name,
280            ty: ty::Type::any(line),
281            default_value: expr::Expression::atom(line, "undefined".to_string()),
282        }
283    }
284    pub fn typ(mut self, ty: ty::Type) -> Self {
285        self.ty = ty;
286        self
287    }
288    pub fn default_value(mut self, value: expr::Expression) -> Self {
289        self.default_value = value;
290        self
291    }
292}
293
294#[derive(Debug, Clone)]
295pub struct Export {
296    pub fun: String,
297    pub arity: ast::Arity,
298}
299impl Export {
300    pub fn new(fun: String, arity: ast::Arity) -> Self {
301        Export { fun, arity }
302    }
303}
304
305#[derive(Debug, Clone)]
306pub struct Import {
307    pub fun: String,
308    pub arity: ast::Arity,
309}
310impl Import {
311    pub fn new(fun: String, arity: ast::Arity) -> Self {
312        Import { fun, arity }
313    }
314}
315
316#[derive(Debug, Clone)]
317pub struct ExportType {
318    pub typ: String,
319    pub arity: ast::Arity,
320}
321impl ExportType {
322    pub fn new(typ: String, arity: ast::Arity) -> Self {
323        ExportType { typ, arity }
324    }
325}