From 7a6361b219a4ff53aa0d0ffc402921eaa67230c8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 22 Dec 2017 17:34:42 +0300 Subject: Hash out ast structure --- minirust.rs | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- rfc.md | 4 ++-- 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 @@ +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct NodeKind(u16); pub struct File { @@ -67,8 +68,6 @@ impl<'f> Iterator for Children<'f> { } } - - pub const ERROR: NodeKind = NodeKind(0); pub const WHITESPACE: NodeKind = NodeKind(1); pub const STRUCT_KW: NodeKind = NodeKind(2); @@ -82,4 +81,72 @@ pub const LINE_COMMENT: NodeKind = NodeKind(9); pub const FILE: NodeKind = NodeKind(10); pub const STRUCT_DEF: NodeKind = NodeKind(11); pub const FIELD_DEF: NodeKind = NodeKind(12); -pub const TYPE: NodeKind = NodeKind(13); +pub const TYPE_REF: NodeKind = NodeKind(13); + + +pub trait AstNode<'f>: Copy + 'f { + fn new(node: Node<'f>) -> Option; + fn node(&self) -> Node<'f>; +} + +pub fn child_of_kind<'f>(node: Node<'f>, kind: NodeKind) -> Option> { + node.children().find(|child| child.kind() == kind) +} + +pub fn ast_children<'f, A: AstNode<'f>>(node: Node<'f>) -> Box + 'f> { + Box::new(node.children().filter_map(A::new)) +} + +#[derive(Clone, Copy)] +pub struct StructDef<'f>(Node<'f>); + +#[derive(Clone, Copy)] +pub struct FieldDef<'f>(Node<'f>); + +#[derive(Clone, Copy)] +pub struct TypeRef<'f>(Node<'f>); + +pub trait NameOwner<'f>: AstNode<'f> { + fn name_ident(&self) -> Node<'f> { + child_of_kind(self.node(), IDENT).unwrap() + } + + fn name(&self) -> &'f str { self.name_ident().text() } +} + + +impl<'f> AstNode<'f> for StructDef<'f> { + fn new(node: Node<'f>) -> Option { + if node.kind() == STRUCT_DEF { Some(StructDef(node)) } else { None } + } + fn node(&self) -> Node<'f> { self.0 } +} + +impl<'f> AstNode<'f> for FieldDef<'f> { + fn new(node: Node<'f>) -> Option { + if node.kind() == FIELD_DEF { Some(FieldDef(node)) } else { None } + } + fn node(&self) -> Node<'f> { self.0 } +} + +impl<'f> AstNode<'f> for TypeRef<'f> { + fn new(node: Node<'f>) -> Option { + if node.kind() == TYPE_REF { Some(TypeRef(node)) } else { None } + } + fn node(&self) -> Node<'f> { self.0 } +} + +impl<'f> NameOwner<'f> for StructDef<'f> {} +impl<'f> NameOwner<'f> for FieldDef<'f> {} + +impl<'f> StructDef<'f> { + pub fn fields(&self) -> Box> + 'f> { + ast_children(self.node()) + } +} + +impl<'f> FieldDef<'f> { + pub fn type_ref(&self) -> Option> { + ast_children(self.node()).next() + } +} \ 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 IDENT COLON WHITESPACE - TYPE + TYPE_REF IDENT COMMA WHITESPACE @@ -180,7 +180,7 @@ Note several features of the tree: * The non-documenting comment is correctly attached to the following field. - + # Drawbacks -- cgit v1.2.3