use super::{ ast, tok::{Token, TokenKind, Tokens}, }; #[derive(Debug)] pub struct Tree { nodes: Vec, } impl Tree { pub fn new() -> Self { let mut out = Self { nodes: vec![] }; out.register({ let mut node = Node::unregistered(); node.kind = NodeKind::Root; node }); out } pub fn register(&mut self, mut node: Node) -> NodeRef { node.id = self.nodes.len(); let out = NodeRef(node.id); self.nodes.push(node); out } pub fn root(&self) -> NodeRef { NodeRef(0) } pub fn add_child(&mut self, parent: NodeRef, child: NodeRef) { parent.resolve_mut(self).children.push(child); child.resolve_mut(self).parent = Some(parent); } pub fn nth_child( &self, parent: NodeRef, child_index: usize, ) -> Option { parent.resolve(self).children.get(child_index).copied() } pub fn children_of( &self, parent: NodeRef, ) -> impl Iterator { parent.resolve(self).children.iter().copied() } } #[derive(Copy, Clone, Eq, PartialEq, Debug)] struct NodeRef(usize); impl NodeRef { fn resolve<'a>(&self, tree: &'a Tree) -> &'a Node { &tree.nodes[self.0] } fn resolve_mut<'a>(&self, tree: &'a mut Tree) -> &'a mut Node { &mut tree.nodes[self.0] } } #[derive(Default, Debug)] pub struct Node { id: usize, parent: Option, children: Vec, kind: NodeKind, whitespace: Option, token: Option, } impl Node { fn unregistered() -> Self { Self { id: usize::MAX, parent: None, children: vec![], kind: NodeKind::Unknown, whitespace: None, token: None, } } pub fn kind(&self) -> &NodeKind { &self.kind } pub fn token(&self) -> Option<&Token> { self.token.as_ref() } } #[derive(Default, Debug, Eq, PartialEq)] pub enum NodeKind { #[default] Unknown, List, Token, Atom, Root, } pub fn parse(corpus: &str) -> Tree { let mut tree = Tree::new(); let mut tokens = Tokens::new(corpus); while let Some(nr) = parse_one(&mut tree, &mut tokens) { let root = tree.root(); tree.add_child(root, nr); } tree } pub fn parse_one(tree: &mut Tree, tokens: &mut Tokens) -> Option { let tok = tokens.next()?; let (ws, tok) = match tok.kind { TokenKind::Whitespace(_) => (Some(tok), tokens.next()), _ => (None, Some(tok)), }; let mut node = Node::unregistered(); node.whitespace = ws; let tok = match tok { Some(tok) => tok, None => { node.kind = NodeKind::Token; return Some(tree.register(node)); }, }; match &tok.kind { TokenKind::Atom(_) => { node.kind = NodeKind::Atom; }, _ => todo!(), } node.token = Some(tok); Some(tree.register(node)) } #[cfg(test)] mod test { use crate::syn::{ cst::NodeKind, tok::{Atom, TokenKind}, }; use super::parse; #[test] fn atom1() { let tree = parse("32"); let mut children = tree.children_of(tree.root()).map(|n| n.resolve(&tree)); let first = children.next().unwrap().as_atom().unwrap().value(); } }