diff options
author | Aleksey Kladov <[email protected]> | 2018-08-09 15:43:39 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-09 15:43:39 +0100 |
commit | d8b2a5efc0e5de3b0d72f29ccc86185f0827c9d3 (patch) | |
tree | 46f8e8feb046ece8511ac1981f53bfa1762d3af3 /src | |
parent | 36bd28633baf6015b767e9e70d2d53185271db50 (diff) |
Generate AST
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/generated.rs | 54 | ||||
-rw-r--r-- | src/ast/generated.rs.tera | 22 | ||||
-rw-r--r-- | src/ast/mod.rs (renamed from src/ast.rs) | 54 | ||||
-rw-r--r-- | src/grammar.ron | 11 | ||||
-rw-r--r-- | src/lib.rs | 2 |
5 files changed, 103 insertions, 40 deletions
diff --git a/src/ast/generated.rs b/src/ast/generated.rs new file mode 100644 index 000000000..612b04f86 --- /dev/null +++ b/src/ast/generated.rs | |||
@@ -0,0 +1,54 @@ | |||
1 | use std::sync::Arc; | ||
2 | use { | ||
3 | SyntaxNode, SyntaxRoot, TreeRoot, AstNode, | ||
4 | SyntaxKind::*, | ||
5 | }; | ||
6 | |||
7 | |||
8 | #[derive(Debug)] | ||
9 | pub struct File<R: TreeRoot = Arc<SyntaxRoot>> { | ||
10 | syntax: SyntaxNode<R>, | ||
11 | } | ||
12 | |||
13 | impl<R: TreeRoot> AstNode<R> for File<R> { | ||
14 | fn cast(syntax: SyntaxNode<R>) -> Option<Self> { | ||
15 | match syntax.kind() { | ||
16 | FILE => Some(File { syntax }), | ||
17 | _ => None, | ||
18 | } | ||
19 | } | ||
20 | fn syntax(&self) -> &SyntaxNode<R> { &self.syntax } | ||
21 | } | ||
22 | |||
23 | |||
24 | #[derive(Debug)] | ||
25 | pub struct FnItem<R: TreeRoot = Arc<SyntaxRoot>> { | ||
26 | syntax: SyntaxNode<R>, | ||
27 | } | ||
28 | |||
29 | impl<R: TreeRoot> AstNode<R> for FnItem<R> { | ||
30 | fn cast(syntax: SyntaxNode<R>) -> Option<Self> { | ||
31 | match syntax.kind() { | ||
32 | FN_ITEM => Some(FnItem { syntax }), | ||
33 | _ => None, | ||
34 | } | ||
35 | } | ||
36 | fn syntax(&self) -> &SyntaxNode<R> { &self.syntax } | ||
37 | } | ||
38 | |||
39 | |||
40 | #[derive(Debug)] | ||
41 | pub struct Name<R: TreeRoot = Arc<SyntaxRoot>> { | ||
42 | syntax: SyntaxNode<R>, | ||
43 | } | ||
44 | |||
45 | impl<R: TreeRoot> AstNode<R> for Name<R> { | ||
46 | fn cast(syntax: SyntaxNode<R>) -> Option<Self> { | ||
47 | match syntax.kind() { | ||
48 | NAME => Some(Name { syntax }), | ||
49 | _ => None, | ||
50 | } | ||
51 | } | ||
52 | fn syntax(&self) -> &SyntaxNode<R> { &self.syntax } | ||
53 | } | ||
54 | |||
diff --git a/src/ast/generated.rs.tera b/src/ast/generated.rs.tera new file mode 100644 index 000000000..f2559383a --- /dev/null +++ b/src/ast/generated.rs.tera | |||
@@ -0,0 +1,22 @@ | |||
1 | use std::sync::Arc; | ||
2 | use { | ||
3 | SyntaxNode, SyntaxRoot, TreeRoot, AstNode, | ||
4 | SyntaxKind::*, | ||
5 | }; | ||
6 | {% for node in ast %} | ||
7 | {% set Name = node.kind | camel %} | ||
8 | #[derive(Debug)] | ||
9 | pub struct {{ Name }}<R: TreeRoot = Arc<SyntaxRoot>> { | ||
10 | syntax: SyntaxNode<R>, | ||
11 | } | ||
12 | |||
13 | impl<R: TreeRoot> AstNode<R> for {{ Name }}<R> { | ||
14 | fn cast(syntax: SyntaxNode<R>) -> Option<Self> { | ||
15 | match syntax.kind() { | ||
16 | {{ node.kind }} => Some({{ Name }} { syntax }), | ||
17 | _ => None, | ||
18 | } | ||
19 | } | ||
20 | fn syntax(&self) -> &SyntaxNode<R> { &self.syntax } | ||
21 | } | ||
22 | {% endfor %} | ||
diff --git a/src/ast.rs b/src/ast/mod.rs index a595b9324..dc7e006c9 100644 --- a/src/ast.rs +++ b/src/ast/mod.rs | |||
@@ -1,57 +1,41 @@ | |||
1 | mod generated; | ||
2 | |||
1 | use std::sync::Arc; | 3 | use std::sync::Arc; |
2 | use { | 4 | use { |
3 | SyntaxNode, SyntaxRoot, TreeRoot, | 5 | SyntaxNode, SyntaxRoot, TreeRoot, |
4 | SyntaxKind::*, | 6 | SyntaxKind::*, |
5 | }; | 7 | }; |
8 | pub use self::generated::*; | ||
6 | 9 | ||
7 | #[derive(Debug)] | 10 | pub trait AstNode<R: TreeRoot>: Sized { |
8 | pub struct File<R: TreeRoot = Arc<SyntaxRoot>> { | 11 | fn cast(syntax: SyntaxNode<R>) -> Option<Self>; |
9 | syntax: SyntaxNode<R>, | 12 | fn syntax(&self) -> &SyntaxNode<R>; |
10 | } | ||
11 | |||
12 | #[derive(Debug)] | ||
13 | pub struct Function<R: TreeRoot = Arc<SyntaxRoot>> { | ||
14 | syntax: SyntaxNode<R>, | ||
15 | } | 13 | } |
16 | 14 | ||
17 | #[derive(Debug)] | ||
18 | pub struct Name<R: TreeRoot = Arc<SyntaxRoot>> { | ||
19 | syntax: SyntaxNode<R>, | ||
20 | } | ||
21 | |||
22 | |||
23 | impl File<Arc<SyntaxRoot>> { | 15 | impl File<Arc<SyntaxRoot>> { |
24 | pub fn parse(text: &str) -> Self { | 16 | pub fn parse(text: &str) -> Self { |
25 | File { | 17 | File::cast(::parse(text)).unwrap() |
26 | syntax: ::parse(text), | ||
27 | } | ||
28 | } | 18 | } |
29 | } | 19 | } |
30 | 20 | ||
31 | impl<R: TreeRoot> File<R> { | 21 | impl<R: TreeRoot> File<R> { |
32 | pub fn functions<'a>(&'a self) -> impl Iterator<Item = Function<R>> + 'a { | 22 | pub fn functions<'a>(&'a self) -> impl Iterator<Item = FnItem<R>> + 'a { |
33 | self.syntax | 23 | self.syntax() |
34 | .children() | 24 | .children() |
35 | .filter(|node| node.kind() == FN_ITEM) | 25 | .filter_map(FnItem::cast) |
36 | .map(|node| Function { syntax: node }) | ||
37 | } | 26 | } |
38 | } | 27 | } |
39 | 28 | ||
40 | impl<R: TreeRoot> Function<R> { | 29 | impl<R: TreeRoot> FnItem<R> { |
41 | pub fn syntax(&self) -> SyntaxNode<R> { | ||
42 | self.syntax.clone() | ||
43 | } | ||
44 | |||
45 | pub fn name(&self) -> Option<Name<R>> { | 30 | pub fn name(&self) -> Option<Name<R>> { |
46 | self.syntax | 31 | self.syntax() |
47 | .children() | 32 | .children() |
48 | .filter(|node| node.kind() == NAME) | 33 | .filter_map(Name::cast) |
49 | .map(|node| Name { syntax: node }) | ||
50 | .next() | 34 | .next() |
51 | } | 35 | } |
52 | 36 | ||
53 | pub fn has_atom_attr(&self, atom: &str) -> bool { | 37 | pub fn has_atom_attr(&self, atom: &str) -> bool { |
54 | self.syntax | 38 | self.syntax() |
55 | .children() | 39 | .children() |
56 | .filter(|node| node.kind() == ATTR) | 40 | .filter(|node| node.kind() == ATTR) |
57 | .any(|attr| { | 41 | .any(|attr| { |
@@ -81,14 +65,6 @@ impl<R: TreeRoot> Function<R> { | |||
81 | 65 | ||
82 | impl<R: TreeRoot> Name<R> { | 66 | impl<R: TreeRoot> Name<R> { |
83 | pub fn text(&self) -> String { | 67 | pub fn text(&self) -> String { |
84 | self.syntax.text() | 68 | self.syntax().text() |
85 | } | ||
86 | } | ||
87 | |||
88 | |||
89 | |||
90 | impl<R: TreeRoot> File<R> { | ||
91 | pub fn syntax(&self) -> SyntaxNode<R> { | ||
92 | self.syntax.clone() | ||
93 | } | 69 | } |
94 | } | 70 | } |
diff --git a/src/grammar.ron b/src/grammar.ron index 0443dd798..b6a870d84 100644 --- a/src/grammar.ron +++ b/src/grammar.ron | |||
@@ -212,5 +212,16 @@ Grammar( | |||
212 | "PARAM", | 212 | "PARAM", |
213 | "SELF_PARAM", | 213 | "SELF_PARAM", |
214 | "ARG_LIST", | 214 | "ARG_LIST", |
215 | ], | ||
216 | ast: [ | ||
217 | ( | ||
218 | kind: "FILE" | ||
219 | ), | ||
220 | ( | ||
221 | kind: "FN_ITEM" | ||
222 | ), | ||
223 | ( | ||
224 | kind: "NAME" | ||
225 | ), | ||
215 | ] | 226 | ] |
216 | ) | 227 | ) |
diff --git a/src/lib.rs b/src/lib.rs index 91b0c9c55..d1e690bb2 100644 --- a/src/lib.rs +++ b/src/lib.rs | |||
@@ -41,7 +41,7 @@ mod yellow; | |||
41 | pub mod utils; | 41 | pub mod utils; |
42 | 42 | ||
43 | pub use { | 43 | pub use { |
44 | ast::File, | 44 | ast::{AstNode, File}, |
45 | lexer::{tokenize, Token}, | 45 | lexer::{tokenize, Token}, |
46 | syntax_kinds::SyntaxKind, | 46 | syntax_kinds::SyntaxKind, |
47 | text_unit::{TextRange, TextUnit}, | 47 | text_unit::{TextRange, TextUnit}, |