diff options
Diffstat (limited to 'minirust.rs')
-rw-r--r-- | minirust.rs | 152 |
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)] | ||
2 | pub struct NodeKind(u16); | ||
3 | |||
4 | pub struct File { | ||
5 | text: String, | ||
6 | nodes: Vec<NodeData>, | ||
7 | } | ||
8 | |||
9 | struct 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)] | ||
18 | pub struct Node<'f> { | ||
19 | file: &'f File, | ||
20 | idx: u32, | ||
21 | } | ||
22 | |||
23 | pub struct Children<'f> { | ||
24 | next: Option<Node<'f>>, | ||
25 | } | ||
26 | |||
27 | impl 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 | |||
34 | impl<'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 | |||
61 | impl<'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 | |||
71 | pub const ERROR: NodeKind = NodeKind(0); | ||
72 | pub const WHITESPACE: NodeKind = NodeKind(1); | ||
73 | pub const STRUCT_KW: NodeKind = NodeKind(2); | ||
74 | pub const IDENT: NodeKind = NodeKind(3); | ||
75 | pub const L_CURLY: NodeKind = NodeKind(4); | ||
76 | pub const R_CURLY: NodeKind = NodeKind(5); | ||
77 | pub const COLON: NodeKind = NodeKind(6); | ||
78 | pub const COMMA: NodeKind = NodeKind(7); | ||
79 | pub const AMP: NodeKind = NodeKind(8); | ||
80 | pub const LINE_COMMENT: NodeKind = NodeKind(9); | ||
81 | pub const FILE: NodeKind = NodeKind(10); | ||
82 | pub const STRUCT_DEF: NodeKind = NodeKind(11); | ||
83 | pub const FIELD_DEF: NodeKind = NodeKind(12); | ||
84 | pub const TYPE_REF: NodeKind = NodeKind(13); | ||
85 | |||
86 | |||
87 | pub trait AstNode<'f>: Copy + 'f { | ||
88 | fn new(node: Node<'f>) -> Option<Self>; | ||
89 | fn node(&self) -> Node<'f>; | ||
90 | } | ||
91 | |||
92 | pub fn child_of_kind<'f>(node: Node<'f>, kind: NodeKind) -> Option<Node<'f>> { | ||
93 | node.children().find(|child| child.kind() == kind) | ||
94 | } | ||
95 | |||
96 | pub 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)] | ||
101 | pub struct StructDef<'f>(Node<'f>); | ||
102 | |||
103 | #[derive(Clone, Copy)] | ||
104 | pub struct FieldDef<'f>(Node<'f>); | ||
105 | |||
106 | #[derive(Clone, Copy)] | ||
107 | pub struct TypeRef<'f>(Node<'f>); | ||
108 | |||
109 | pub 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 | |||
118 | impl<'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 | |||
125 | impl<'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 | |||
132 | impl<'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 | |||
139 | impl<'f> NameOwner<'f> for StructDef<'f> {} | ||
140 | impl<'f> NameOwner<'f> for FieldDef<'f> {} | ||
141 | |||
142 | impl<'f> StructDef<'f> { | ||
143 | pub fn fields(&self) -> Box<Iterator<Item=FieldDef<'f>> + 'f> { | ||
144 | ast_children(self.node()) | ||
145 | } | ||
146 | } | ||
147 | |||
148 | impl<'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 | ||