Actually just three programming languages in a trenchcoat
1use super::*;
2use crate::{Parser, Spanned};
3use source_span::Span;
4use trilogy_scanner::{Token, TokenType};
5
6/// An export declaration item.
7///
8/// ```trilogy
9/// export something, something_else
10/// ```
11#[derive(Clone, Debug, PrettyPrintSExpr)]
12pub struct ExportDefinition {
13 pub export: Token,
14 pub names: Vec<Identifier>,
15 span: Span,
16}
17
18impl Spanned for ExportDefinition {
19 fn span(&self) -> Span {
20 self.span
21 }
22}
23
24impl ExportDefinition {
25 pub(crate) fn parse(parser: &mut Parser) -> SyntaxResult<Self> {
26 let export = parser.expect(TokenType::KwExport).unwrap();
27 let mut names = vec![];
28 while {
29 names.push(Identifier::parse(parser)?);
30 parser.expect(TokenType::OpComma).is_ok()
31 } {}
32
33 let span = match names.last() {
34 None => export.span,
35 Some(name) => export.span.union(name.span()),
36 };
37
38 Ok(Self {
39 export,
40 names,
41 span,
42 })
43 }
44}
45
46#[cfg(test)]
47mod test {
48 use super::*;
49
50 test_parse!(export_single: "export x" => ExportDefinition::parse => "(ExportDefinition _ [_])");
51 test_parse!(export_many: "export x, y, z" => ExportDefinition::parse => "(ExportDefinition _ [_ _ _])");
52 test_parse_error!(export_not_ident: "export x y" => ExportDefinition::parse);
53 test_parse_error!(export_none: "export" => ExportDefinition::parse);
54}