aboutsummaryrefslogtreecommitdiff
path: root/minirust.rs
diff options
context:
space:
mode:
Diffstat (limited to 'minirust.rs')
-rw-r--r--minirust.rs152
1 files changed, 0 insertions, 152 deletions
diff --git a/minirust.rs b/minirust.rs
deleted file mode 100644
index 9baa96039..000000000
--- a/minirust.rs
+++ /dev/null
@@ -1,152 +0,0 @@
1#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
2pub struct NodeKind(u16);
3
4pub struct File {
5 text: String,
6 nodes: Vec<NodeData>,
7}
8
9struct NodeData {
10 kind: NodeKind,
11 range: (u32, u32),
12 parent: Option<u32>,
13 first_child: Option<u32>,
14 next_sibling: Option<u32>,
15}
16
17#[derive(Clone, Copy)]
18pub struct Node<'f> {
19 file: &'f File,
20 idx: u32,
21}
22
23pub struct Children<'f> {
24 next: Option<Node<'f>>,
25}
26
27impl File {
28 pub fn root<'f>(&'f self) -> Node<'f> {
29 assert!(!self.nodes.is_empty());
30 Node { file: self, idx: 0 }
31 }
32}
33
34impl<'f> Node<'f> {
35 pub fn kind(&self) -> NodeKind {
36 self.data().kind
37 }
38
39 pub fn text(&self) -> &'f str {
40 let (start, end) = self.data().range;
41 &self.file.text[start as usize..end as usize]
42 }
43
44 pub fn parent(&self) -> Option<Node<'f>> {
45 self.as_node(self.data().parent)
46 }
47
48 pub fn children(&self) -> Children<'f> {
49 Children { next: self.as_node(self.data().first_child) }
50 }
51
52 fn data(&self) -> &'f NodeData {
53 &self.file.nodes[self.idx as usize]
54 }
55
56 fn as_node(&self, idx: Option<u32>) -> Option<Node<'f>> {
57 idx.map(|idx| Node { file: self.file, idx })
58 }
59}
60
61impl<'f> Iterator for Children<'f> {
62 type Item = Node<'f>;
63
64 fn next(&mut self) -> Option<Node<'f>> {
65 let next = self.next;
66 self.next = next.and_then(|node| node.as_node(node.data().next_sibling));
67 next
68 }
69}
70
71pub const ERROR: NodeKind = NodeKind(0);
72pub const WHITESPACE: NodeKind = NodeKind(1);
73pub const STRUCT_KW: NodeKind = NodeKind(2);
74pub const IDENT: NodeKind = NodeKind(3);
75pub const L_CURLY: NodeKind = NodeKind(4);
76pub const R_CURLY: NodeKind = NodeKind(5);
77pub const COLON: NodeKind = NodeKind(6);
78pub const COMMA: NodeKind = NodeKind(7);
79pub const AMP: NodeKind = NodeKind(8);
80pub const LINE_COMMENT: NodeKind = NodeKind(9);
81pub const FILE: NodeKind = NodeKind(10);
82pub const STRUCT_DEF: NodeKind = NodeKind(11);
83pub const FIELD_DEF: NodeKind = NodeKind(12);
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