aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-09 15:43:39 +0100
committerAleksey Kladov <[email protected]>2018-08-09 15:43:39 +0100
commitd8b2a5efc0e5de3b0d72f29ccc86185f0827c9d3 (patch)
tree46f8e8feb046ece8511ac1981f53bfa1762d3af3 /src
parent36bd28633baf6015b767e9e70d2d53185271db50 (diff)
Generate AST
Diffstat (limited to 'src')
-rw-r--r--src/ast/generated.rs54
-rw-r--r--src/ast/generated.rs.tera22
-rw-r--r--src/ast/mod.rs (renamed from src/ast.rs)54
-rw-r--r--src/grammar.ron11
-rw-r--r--src/lib.rs2
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 @@
1use std::sync::Arc;
2use {
3 SyntaxNode, SyntaxRoot, TreeRoot, AstNode,
4 SyntaxKind::*,
5};
6
7
8#[derive(Debug)]
9pub struct File<R: TreeRoot = Arc<SyntaxRoot>> {
10 syntax: SyntaxNode<R>,
11}
12
13impl<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)]
25pub struct FnItem<R: TreeRoot = Arc<SyntaxRoot>> {
26 syntax: SyntaxNode<R>,
27}
28
29impl<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)]
41pub struct Name<R: TreeRoot = Arc<SyntaxRoot>> {
42 syntax: SyntaxNode<R>,
43}
44
45impl<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 @@
1use std::sync::Arc;
2use {
3 SyntaxNode, SyntaxRoot, TreeRoot, AstNode,
4 SyntaxKind::*,
5};
6{% for node in ast %}
7{% set Name = node.kind | camel %}
8#[derive(Debug)]
9pub struct {{ Name }}<R: TreeRoot = Arc<SyntaxRoot>> {
10 syntax: SyntaxNode<R>,
11}
12
13impl<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 @@
1mod generated;
2
1use std::sync::Arc; 3use std::sync::Arc;
2use { 4use {
3 SyntaxNode, SyntaxRoot, TreeRoot, 5 SyntaxNode, SyntaxRoot, TreeRoot,
4 SyntaxKind::*, 6 SyntaxKind::*,
5}; 7};
8pub use self::generated::*;
6 9
7#[derive(Debug)] 10pub trait AstNode<R: TreeRoot>: Sized {
8pub 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)]
13pub struct Function<R: TreeRoot = Arc<SyntaxRoot>> {
14 syntax: SyntaxNode<R>,
15} 13}
16 14
17#[derive(Debug)]
18pub struct Name<R: TreeRoot = Arc<SyntaxRoot>> {
19 syntax: SyntaxNode<R>,
20}
21
22
23impl File<Arc<SyntaxRoot>> { 15impl 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
31impl<R: TreeRoot> File<R> { 21impl<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
40impl<R: TreeRoot> Function<R> { 29impl<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
82impl<R: TreeRoot> Name<R> { 66impl<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
90impl<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;
41pub mod utils; 41pub mod utils;
42 42
43pub use { 43pub 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},