expr/ast/
program.rs

1use crate::ast::node::Node;
2use crate::Rule;
3use pest::iterators::{Pair, Pairs};
4
5/// A parsed expr program that can be run
6#[derive(Debug, Clone, Default)]
7pub struct Program {
8    pub(crate) lines: Vec<(String, Node)>,
9    pub(crate) expr: Node,
10}
11
12impl<'i> From<Pairs<'i, Rule>> for Program {
13    fn from(pairs: Pairs<'i, Rule>) -> Self {
14        let mut program = Program::default();
15        for pair in pairs {
16            if let Rule::EOI = pair.as_rule() {
17                continue;
18            }
19            let p = Program::from(pair);
20            program.lines.extend(p.lines);
21            program.expr = p.expr;
22        }
23        program
24    }
25}
26
27impl From<Pair<'_, Rule>> for Program {
28    fn from(pair: Pair<'_, Rule>) -> Self {
29        let mut lines = Vec::new();
30        let mut expr = None;
31        match pair.as_rule() {
32            Rule::program => return pair.into_inner().into(),
33            Rule::stmt => {
34                let mut inner = pair.into_inner();
35                let line = inner.next().unwrap().as_str().to_string();
36                let node = Node::from(inner);
37                lines.push((line, node));
38            }
39            Rule::expr => {
40                expr = Some(Node::from(pair.into_inner()));
41            }
42            // means it's a predicate
43            Rule::ident => {
44                expr = Some(Node::Ident(pair.as_str().to_string()));
45            }
46            Rule::EOI => {}
47            rule => unreachable!("Unexpected rule: {rule:?}"),
48        }
49
50        Program {
51            lines,
52            expr: expr.unwrap_or(Node::Value(crate::Value::Nil)),
53        }
54    }
55}