onefig/nodes/
atom.rs

1use flexar::prelude::*;
2use crate::{lexer::Token, errors::SyntaxError, visitor::{VisitValue, DbgValue, ActionTree}};
3use super::{path::Path, list::List, table::Table, expr::Expr};
4
5#[derive(Debug)]
6pub enum Atom {
7    Int(usize),
8    Str(Box<str>),
9    Bool(bool),
10    Path(Node<Path>),
11    List(Box<Node<List>>),
12    Table(Box<Node<Table>>),
13    Expr(Box<Node<Expr>>),
14    Apply(Node<Path>, Box<Node<Atom>>),
15    RawConf(Box<str>),
16}
17
18flexar::parser! {
19    [[Atom] parxt: Token]
20    parse {
21        [expr: Expr::parse] => (Expr(Box::new(expr)));
22        [table: Table::parse] => (Table(Box::new(table)));
23        [list: List::parse] => (List(Box::new(list)));
24        [path: Path::parse_w_error] => {
25            (Apply), [atom: Atom::parse] => (Apply(path, Box::new(atom)));
26        } (else Ok(Self::Path(path)))
27        (Int(x)) => (Int(*x));
28        (Bool(x)) => (Bool(*x));
29        (Str(x)) => (Str(x.clone()));
30        (RawConf(x)) => (RawConf(x.clone()));
31    } else Err(SY004: parxt.current_token());
32}
33
34impl VisitValue for Node<Atom> {
35    fn visit(self, visitor: &mut ActionTree, scope: &[(Position, Box<str>)]) -> (Position, DbgValue) {
36        use Atom as A;
37        use DbgValue::*;
38        (self.position, match self.node {
39            A::Int(x) => Int(x),
40            A::Bool(x) => Bool(x),
41            A::Str(x) => DbgValue::String(x),
42            A::RawConf(x) => Raw(x),
43            
44            A::List(x) => return x.visit(visitor, scope),
45            A::Table(x) => return x.visit(visitor, scope),
46            A::Apply(p, x) => return x.visit(visitor, &super::path::Path::flatten(p)),
47            
48            A::Path(path) => {
49                let path = super::path::Path::flatten(path);
50
51                let mut out = Vec::new();
52                scope.clone_into(&mut out);
53                out.append(&mut path.into_vec());
54
55                Path(out.into_boxed_slice())
56            }
57
58            A::Expr(_) => todo!(), // can't panic as compiler error thrown before
59        })
60    }
61}