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!(), })
60 }
61}