1use crate::ast::node::Node;
2use crate::Rule;
3use pest::iterators::{Pair, Pairs};
4
5#[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 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}