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}