onefig/nodes/
path.rs

1use flexar::prelude::*;
2use crate::{lexer::Token, errors::SyntaxError};
3use super::ident::Ident;
4
5#[derive(Debug, Clone)]
6pub enum Path {
7    Head(Box<str>, Box<Node<Path>>),
8    Tail(Box<str>),
9}
10
11impl Path {
12    pub fn flatten(mut this: Node<Path>) -> Box<[(Position, Box<str>)]> {
13        let mut out = Vec::new();
14        loop {
15            match this.node {
16                Path::Tail(x) => { out.push((this.position, x)); break },
17                Path::Head(x, y) => {
18                    out.push((this.position, x));
19                    this = *y;
20                }
21            }
22        }
23
24        out.into_boxed_slice()
25    }
26}
27
28flexar::parser! {
29    [[Path] parxt: Token]
30    parse {
31        [head: Ident::parse] => {
32            (Dot) => {
33                [tail: Self::parse] => (Head(head.node.0, Box::new(tail)));
34            } (else Err(SY006: parxt.current_token()))
35        } (else Ok(Self::Tail(head.node.0)))
36    } else Err(SY005: parxt.current_token());
37
38    parse_w_error {
39        (Ident(head)) => {
40            (Dot) => {
41                [tail: Self::parse] => (Head(head.clone(), Box::new(tail)));
42            } (else Err(SY006: parxt.current_token()))
43        } (else Ok(Self::Tail(head.clone())))
44    } else Err(SY009: parxt.current_token(), parxt.current_token());
45
46    path_ident {
47        (Ident(x)) => (Tail(x.clone()));
48        (Str(x)) => (Tail(x.clone()));
49        (Int(x)) => (Tail(x.to_string().into_boxed_str()));
50        (Bool(x)) => (Tail(x.to_string().into_boxed_str()));
51    } else Err(SY009: parxt.current_token(), parxt.current_token());
52}