1use crate::{
2 ast::{Args, Evaluate, EvaluationResult, Node, Root, Scope},
3 error::Error,
4 lexer::tokenize,
5 tokens::{Operator, Token, TokenList},
6};
7use std::{collections::VecDeque, string::ToString};
8
9type NodeList = Vec<Node>;
10
11pub fn eval(expr: &str, scope: &Scope) -> EvaluationResult {
12 parse_tokens(tokenize(expr, scope)?, scope)?.eval()
13}
14
15pub fn compile<'a>(expr: &'a str, scope: &'a Scope) -> Result<Root<'a>, Error> {
16 parse_tokens(tokenize(expr, scope)?, scope)
17}
18
19fn encounter_func(f: String, operands: &mut NodeList) -> Result<(), Error> {
20 let mut args = Args::with_capacity(2);
21
22 args.push_front(
24 operands
25 .pop()
26 .ok_or(Error::NotEnoughFunctionParams(f.clone()))?,
27 );
28
29 while let Some(last) = operands.pop() {
30 if last.token != Token::Comma {
31 operands.push(last);
32 break;
33 }
34 else {
35 args.push_front(
36 operands
37 .pop()
38 .ok_or(Error::FunctionSyntaxError(f.clone()))?,
39 );
40 }
41 }
42
43 operands.push(Node::new(Token::Function(f), Some(args)));
44 Ok(())
45}
46
47fn right_paren(
48 operators: &mut TokenList,
49 operands: &mut NodeList,
50) -> Result<(), Error> {
51 while let Some(top) = operators.pop() {
52 match top {
53 Token::LeftParenthesis => match operators.last() {
54 Some(Token::Function(_)) => {},
55 _ => break,
56 },
57 Token::Function(f) => encounter_func(f, operands)?,
58 Token::Operator(op) => add_operator(op, operands)?,
59 _ => {},
60 }
61 }
62 Ok(())
63}
64
65fn add_operator(
66 operator: Operator,
67 operands: &mut NodeList,
68) -> Result<(), Error> {
69 let num_operands = operator.num_operands();
70
71 let mut args: VecDeque<Node> =
72 VecDeque::with_capacity(num_operands as usize);
73
74 for _ in 0..num_operands {
75 args.push_front(
76 operands
77 .pop()
78 .ok_or(Error::MissingOperands(operator.to_string()))?,
79 );
80 }
81 operands.push(Node::new(Token::Operator(operator), Some(args)));
82 Ok(())
83}
84
85fn encounter_operator(
86 cur_operator: Operator,
87 operators: &mut TokenList,
88 operands: &mut NodeList,
89) -> Result<(), Error> {
90 while let Some(top) = operators.pop() {
91 match top {
92 Token::Operator(top_operator) => {
93 if top_operator > cur_operator
94 || (top_operator == cur_operator
95 && !cur_operator.is_right_associative())
96 {
97 add_operator(top_operator, operands)?
98 }
99 else {
100 operators.push(Token::Operator(top_operator));
101 break;
102 }
103 },
104 Token::Function(f) => encounter_func(f, operands)?,
105 _ => {
106 operators.push(top);
107 break;
108 },
109 }
110 }
111
112 operators.push(Token::Operator(cur_operator));
113 Ok(())
114}
115
116fn parse_tokens(tokens: TokenList, scope: &Scope) -> Result<Root, Error> {
117 let mut operators: TokenList = Vec::new();
118 let mut operands: NodeList = Vec::new();
119
120 for token in tokens {
121 match token {
122 Token::Number(num) => operands.push(Node {
123 token: Token::Number(num),
124 args: None,
125 }),
126 Token::Variable(var) => operands.push(Node {
127 token: Token::Variable(var),
128 args: None,
129 }),
130 Token::RightParenthesis => {
131 right_paren(&mut operators, &mut operands)?
132 },
133 Token::LeftParenthesis => operators.push(token),
134 Token::Operator(op1) => {
135 encounter_operator(op1, &mut operators, &mut operands)?;
136 },
137 Token::Function(f) => operators.push(Token::Function(f)),
138 Token::Comma => operands.push(Node::new(token, None)),
139 };
140 }
141
142 while let Some(Token::Operator(operator)) = operators.pop() {
143 add_operator(operator, &mut operands)?
144 }
145
146 operands.pop().map_or_else(
148 || Err(Error::EmptyExpression),
149 |node| Ok(Root { node, scope }),
150 )
151}