aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2017-12-22 14:34:42 +0000
committerAleksey Kladov <[email protected]>2017-12-22 14:38:00 +0000
commit7a6361b219a4ff53aa0d0ffc402921eaa67230c8 (patch)
treea9cadbb7818eb0815f9d1c4a65e45d97dc3289ee
parent9726ecdc99a35467af4aa9f375821805d55e4869 (diff)
Hash out ast structure
-rw-r--r--minirust.rs73
-rw-r--r--rfc.md4
2 files changed, 72 insertions, 5 deletions
diff --git a/minirust.rs b/minirust.rs
index 009892ca9..9baa96039 100644
--- a/minirust.rs
+++ b/minirust.rs
@@ -1,3 +1,4 @@
1#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
1pub struct NodeKind(u16); 2pub struct NodeKind(u16);
2 3
3pub struct File { 4pub struct File {
@@ -67,8 +68,6 @@ impl<'f> Iterator for Children<'f> {
67 } 68 }
68} 69}
69 70
70
71
72pub const ERROR: NodeKind = NodeKind(0); 71pub const ERROR: NodeKind = NodeKind(0);
73pub const WHITESPACE: NodeKind = NodeKind(1); 72pub const WHITESPACE: NodeKind = NodeKind(1);
74pub const STRUCT_KW: NodeKind = NodeKind(2); 73pub const STRUCT_KW: NodeKind = NodeKind(2);
@@ -82,4 +81,72 @@ pub const LINE_COMMENT: NodeKind = NodeKind(9);
82pub const FILE: NodeKind = NodeKind(10); 81pub const FILE: NodeKind = NodeKind(10);
83pub const STRUCT_DEF: NodeKind = NodeKind(11); 82pub const STRUCT_DEF: NodeKind = NodeKind(11);
84pub const FIELD_DEF: NodeKind = NodeKind(12); 83pub const FIELD_DEF: NodeKind = NodeKind(12);
85pub const TYPE: NodeKind = NodeKind(13); 84pub const TYPE_REF: NodeKind = NodeKind(13);
85
86
87pub trait AstNode<'f>: Copy + 'f {
88 fn new(node: Node<'f>) -> Option<Self>;
89 fn node(&self) -> Node<'f>;
90}
91
92pub fn child_of_kind<'f>(node: Node<'f>, kind: NodeKind) -> Option<Node<'f>> {
93 node.children().find(|child| child.kind() == kind)
94}
95
96pub fn ast_children<'f, A: AstNode<'f>>(node: Node<'f>) -> Box<Iterator<Item=A> + 'f> {
97 Box::new(node.children().filter_map(A::new))
98}
99
100#[derive(Clone, Copy)]
101pub struct StructDef<'f>(Node<'f>);
102
103#[derive(Clone, Copy)]
104pub struct FieldDef<'f>(Node<'f>);
105
106#[derive(Clone, Copy)]
107pub struct TypeRef<'f>(Node<'f>);
108
109pub trait NameOwner<'f>: AstNode<'f> {
110 fn name_ident(&self) -> Node<'f> {
111 child_of_kind(self.node(), IDENT).unwrap()
112 }
113
114 fn name(&self) -> &'f str { self.name_ident().text() }
115}
116
117
118impl<'f> AstNode<'f> for StructDef<'f> {
119 fn new(node: Node<'f>) -> Option<Self> {
120 if node.kind() == STRUCT_DEF { Some(StructDef(node)) } else { None }
121 }
122 fn node(&self) -> Node<'f> { self.0 }
123}
124
125impl<'f> AstNode<'f> for FieldDef<'f> {
126 fn new(node: Node<'f>) -> Option<Self> {
127 if node.kind() == FIELD_DEF { Some(FieldDef(node)) } else { None }
128 }
129 fn node(&self) -> Node<'f> { self.0 }
130}
131
132impl<'f> AstNode<'f> for TypeRef<'f> {
133 fn new(node: Node<'f>) -> Option<Self> {
134 if node.kind() == TYPE_REF { Some(TypeRef(node)) } else { None }
135 }
136 fn node(&self) -> Node<'f> { self.0 }
137}
138
139impl<'f> NameOwner<'f> for StructDef<'f> {}
140impl<'f> NameOwner<'f> for FieldDef<'f> {}
141
142impl<'f> StructDef<'f> {
143 pub fn fields(&self) -> Box<Iterator<Item=FieldDef<'f>> + 'f> {
144 ast_children(self.node())
145 }
146}
147
148impl<'f> FieldDef<'f> {
149 pub fn type_ref(&self) -> Option<TypeRef<'f>> {
150 ast_children(self.node()).next()
151 }
152} \ No newline at end of file
diff --git a/rfc.md b/rfc.md
index dfba7cb2c..6cc3e1a79 100644
--- a/rfc.md
+++ b/rfc.md
@@ -150,7 +150,7 @@ FILE
150 IDENT 150 IDENT
151 COLON 151 COLON
152 WHITESPACE 152 WHITESPACE
153 TYPE 153 TYPE_REF
154 IDENT 154 IDENT
155 COMMA 155 COMMA
156 WHITESPACE 156 WHITESPACE
@@ -180,7 +180,7 @@ Note several features of the tree:
180 180
181* The non-documenting comment is correctly attached to the following 181* The non-documenting comment is correctly attached to the following
182 field. 182 field.
183 183
184 184
185 185
186# Drawbacks 186# Drawbacks