1use crate::calc::meaning::Meaning;
2use crate::calc::value::{Value, ValueRef};
3use crate::core::count;
4use crate::core::count::Count;
5use crate::core::interface::{Directive, Interface, Operation};
6use crate::error::{EngineError, MyError, MyResult};
7use std::cell::RefCell;
8use std::io::Write;
9use std::rc::Rc;
10
11pub enum Action<W: Write> {
12 Operation(Rc<Operation<W>>),
13 Meaning(Meaning),
14 Directive(Rc<Directive<W>>, Vec<String>),
15 Definition(Vec<Action<W>>),
16 Value(ValueRef, bool),
17}
18
19impl<W: Write> Clone for Action<W> {
20 fn clone(&self) -> Self {
21 match self {
22 Self::Operation(operation) => Self::Operation(Rc::clone(operation)),
23 Self::Meaning(meaning) => Self::Meaning(meaning.clone()),
24 Self::Directive(directive, tokens) => Self::Directive(Rc::clone(directive), tokens.clone()),
25 Self::Definition(actions) => Self::Definition(actions.clone()),
26 Self::Value(value, dirty) => Self::Value(Rc::clone(value), *dirty),
27 }
28 }
29}
30
31pub struct Actions<'a, W: Write, I: Iterator<Item = &'a str>> {
32 interface: Rc<RefCell<Interface<W>>>,
33 tokens: I,
34}
35
36impl<'a, W: Write, I: Iterator<Item = &'a str>> Actions<'a, W, I> {
37 pub fn new(
38 interface: &Rc<RefCell<Interface<W>>>,
39 tokens: I,
40 ) -> Self {
41 let interface = Rc::clone(interface);
42 Self { interface, tokens }
43 }
44}
45
46impl<'a, W: Write, I: Iterator<Item = &'a str>> Iterator for Actions<'a, W, I> {
48 type Item = MyResult<(Action<W>, &'a str)>;
49
50 fn next(&mut self) -> Option<Self::Item> {
51 if let Some(token) = self.tokens.next() {
52 let interface = self.interface.borrow();
53 if let Some(operation) = interface.get_operation(token) {
54 let action = Action::Operation(operation);
55 return Some(Ok((action, token)));
56 } else if let Some(meaning) = interface.get_meaning(token) {
57 let action = Action::Meaning(meaning);
58 return Some(Ok((action, token)));
59 } else if let Some(directive) = interface.get_directive(token) {
60 let mut tokens = Vec::new();
61 if let Directive::EngineOne(_, _) = *directive {
62 if let Some(token) = self.tokens.next() {
63 tokens.push(String::from(token));
64 }
65 } else {
66 while let Some(token) = self.tokens.next() {
67 tokens.push(String::from(token));
68 }
69 }
70 let action = Action::Directive(directive, tokens);
71 return Some(Ok((action, token)));
72 } else if let Some(actions) = interface.get_definition(token) {
73 let action = Action::Definition(actions);
74 return Some(Ok((action, token)));
75 } else if let Some(value) = interface.get_variable(token) {
76 let action = Action::Value(value, true);
77 return Some(Ok((action, token)));
78 } else {
79 match Value::from_string(token) {
80 Ok(value) => {
81 let value = Rc::new(RefCell::new(value));
82 let action = Action::Value(value, false);
83 return Some(Ok((action, token)));
84 }
85 Err(_) => {
86 let error = EngineError::ParseError(String::from(token));
87 return Some(Err(MyError::from(error)));
88 }
89 }
90 }
91 }
92 None
93 }
94}
95
96pub fn fold_actions<W: Write>(actions: &Vec<Action<W>>) -> (Count, Count) {
97 actions.iter().fold((Count::N(0), Count::N(0)), fold_action)
98}
99
100fn fold_action<W: Write>((input, output): (Count, Count), action: &Action<W>) -> (Count, Count) {
101 match action {
102 Action::Operation(operation) => fold_operation(input, output, operation),
103 Action::Meaning(_) => (input, output),
104 Action::Directive(_, _) => (input, output),
105 Action::Definition(actions) => fold_definition(input, output, actions),
106 Action::Value(_, _) => fold_value(input, output),
107 }
108}
109
110fn fold_operation<W: Write>(
111 input: Count,
112 output: Count,
113 operation: &Rc<Operation<W>>,
114) -> (Count, Count) {
115 let (input2, output2) = operation.count_parameters();
116 count::fold_counts(input, output, input2, output2)
117}
118
119fn fold_definition<W: Write>(
120 input: Count,
121 output: Count,
122 actions: &Vec<Action<W>>,
123) -> (Count, Count) {
124 actions.iter().fold((input, output), fold_action)
125}
126
127fn fold_value(input: Count, output: Count) -> (Count, Count) {
128 (input, output + Count::N(1))
129}
130
131#[cfg(test)]
133pub mod tests {
134 use crate::calc::value::tests::create_nan;
135 use crate::core::action::{fold_actions, Action};
136 use crate::core::count::Count;
137 use crate::core::interface::tests::{
138 dummy_binary,
139 dummy_binary_series,
140 dummy_directive,
141 dummy_nullary,
142 dummy_series,
143 dummy_series_series,
144 dummy_unary,
145 };
146 use crate::core::interface::{Completion, Directive, Operation};
147 use crate::util::text::tests::BufferWriter;
148 use std::rc::Rc;
149
150 #[test]
151 fn test_folds_values_only() {
152 let actions: Vec<Action<BufferWriter>> = vec![
153 ];
154 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::N(0)));
155
156 let actions: Vec<Action<BufferWriter>> = vec![
157 Action::Value(create_nan(), false),
158 Action::Value(create_nan(), false),
159 Action::Value(create_nan(), false),
160 ];
161 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::N(3)));
162 }
163
164 #[test]
165 fn test_folds_nullary_operation() {
166 let actions: Vec<Action<BufferWriter>> = vec![
167 Action::Value(create_nan(), false),
168 Action::Value(create_nan(), false),
169 Action::Operation(Rc::new(Operation::ValueNone(dummy_nullary))),
170 ];
171 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::N(3)));
172
173 let actions: Vec<Action<BufferWriter>> = vec![
174 Action::Value(create_nan(), false),
175 Action::Value(create_nan(), false),
176 Action::Operation(Rc::new(Operation::ValueNone(dummy_nullary))),
177 Action::Operation(Rc::new(Operation::ValueNone(dummy_nullary))),
178 ];
179 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::N(4)));
180 }
181
182 #[test]
183 fn test_folds_unary_operation() {
184 let actions: Vec<Action<BufferWriter>> = vec![
185 Action::Value(create_nan(), false),
186 Action::Value(create_nan(), false),
187 Action::Operation(Rc::new(Operation::ValueOne(dummy_unary))),
188 ];
189 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::N(2)));
190
191 let actions: Vec<Action<BufferWriter>> = vec![
192 Action::Value(create_nan(), false),
193 Action::Value(create_nan(), false),
194 Action::Operation(Rc::new(Operation::ValueOne(dummy_unary))),
195 Action::Operation(Rc::new(Operation::ValueOne(dummy_unary))),
196 ];
197 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::N(2)));
198 }
199
200 #[test]
201 fn test_folds_binary_operation() {
202 let actions: Vec<Action<BufferWriter>> = vec![
203 Action::Value(create_nan(), false),
204 Action::Value(create_nan(), false),
205 Action::Operation(Rc::new(Operation::ValueTwo(dummy_binary))),
206 ];
207 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::N(1)));
208
209 let actions: Vec<Action<BufferWriter>> = vec![
210 Action::Value(create_nan(), false),
211 Action::Value(create_nan(), false),
212 Action::Operation(Rc::new(Operation::ValueTwo(dummy_binary))),
213 Action::Operation(Rc::new(Operation::ValueTwo(dummy_binary))),
214 ];
215 std::assert_eq!(fold_actions(&actions), (Count::N(1), Count::N(1)));
216
217 let actions: Vec<Action<BufferWriter>> = vec![
218 Action::Value(create_nan(), false),
219 Action::Value(create_nan(), false),
220 Action::Operation(Rc::new(Operation::ValueTwo(dummy_binary))),
221 Action::Operation(Rc::new(Operation::ValueTwo(dummy_binary))),
222 Action::Operation(Rc::new(Operation::ValueTwo(dummy_binary))),
223 ];
224 std::assert_eq!(fold_actions(&actions), (Count::N(2), Count::N(1)));
225 }
226
227 #[test]
228 fn test_folds_series_to_value_operation() {
229 let actions: Vec<Action<BufferWriter>> = vec![
230 Action::Value(create_nan(), false),
231 Action::Value(create_nan(), false),
232 Action::Operation(Rc::new(Operation::ValueAll(dummy_series))),
233 ];
234 std::assert_eq!(fold_actions(&actions), (Count::All, Count::N(1)));
235
236 let actions: Vec<Action<BufferWriter>> = vec![
237 Action::Value(create_nan(), false),
238 Action::Value(create_nan(), false),
239 Action::Value(create_nan(), false),
240 Action::Operation(Rc::new(Operation::ValueAll(dummy_series))),
241 ];
242 std::assert_eq!(fold_actions(&actions), (Count::All, Count::N(1)));
243
244 let actions: Vec<Action<BufferWriter>> = vec![
245 Action::Value(create_nan(), false),
246 Action::Value(create_nan(), false),
247 Action::Value(create_nan(), false),
248 Action::Value(create_nan(), false),
249 Action::Operation(Rc::new(Operation::ValueAll(dummy_series))),
250 ];
251 std::assert_eq!(fold_actions(&actions), (Count::All, Count::N(1)));
252 }
253
254 #[test]
255 fn test_folds_binary_to_series_operation() {
256 let actions: Vec<Action<BufferWriter>> = vec![
257 Action::Value(create_nan(), false),
258 Action::Value(create_nan(), false),
259 Action::Operation(Rc::new(Operation::SeriesTwo(dummy_binary_series))),
260 ];
261 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::All));
262
263 let actions: Vec<Action<BufferWriter>> = vec![
264 Action::Value(create_nan(), false),
265 Action::Value(create_nan(), false),
266 Action::Operation(Rc::new(Operation::SeriesTwo(dummy_binary_series))),
267 Action::Operation(Rc::new(Operation::SeriesTwo(dummy_binary_series))),
268 ];
269 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::All));
270
271 let actions: Vec<Action<BufferWriter>> = vec![
272 Action::Value(create_nan(), false),
273 Action::Value(create_nan(), false),
274 Action::Operation(Rc::new(Operation::SeriesTwo(dummy_binary_series))),
275 Action::Operation(Rc::new(Operation::SeriesTwo(dummy_binary_series))),
276 Action::Operation(Rc::new(Operation::SeriesTwo(dummy_binary_series))),
277 ];
278 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::All));
279 }
280
281 #[test]
282 fn test_folds_series_to_series_operation() {
283 let actions: Vec<Action<BufferWriter>> = vec![
284 Action::Value(create_nan(), false),
285 Action::Value(create_nan(), false),
286 Action::Operation(Rc::new(Operation::SeriesAll(dummy_series_series))),
287 ];
288 std::assert_eq!(fold_actions(&actions), (Count::All, Count::All));
289 }
290
291 #[test]
292 fn test_folds_directive_as_noop() {
293 let actions: Vec<Action<BufferWriter>> = vec![
294 Action::Value(create_nan(), false),
295 Action::Value(create_nan(), false),
296 Action::Directive(Rc::new(Directive::EngineAll(dummy_directive, Completion::Keyword)), vec![]),
297 ];
298 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::N(2)));
299
300 let actions: Vec<Action<BufferWriter>> = vec![
301 Action::Value(create_nan(), false),
302 Action::Value(create_nan(), false),
303 Action::Directive(Rc::new(Directive::EngineAll(dummy_directive, Completion::Keyword)), vec![]),
304 Action::Directive(Rc::new(Directive::EngineAll(dummy_directive, Completion::Keyword)), vec![]),
305 ];
306 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::N(2)));
307 }
308
309 #[test]
310 fn test_folds_defined_function() {
311 let actions: Vec<Action<BufferWriter>> = vec![
312 Action::Value(create_nan(), false),
313 Action::Value(create_nan(), false),
314 Action::Operation(Rc::new(Operation::ValueNone(dummy_nullary))),
315 Action::Operation(Rc::new(Operation::ValueNone(dummy_nullary))),
316 ];
317 let actions: Vec<Action<BufferWriter>> = vec![
318 Action::Definition(actions),
319 ];
320 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::N(4)));
321
322 let actions: Vec<Action<BufferWriter>> = vec![
323 Action::Value(create_nan(), false),
324 Action::Value(create_nan(), false),
325 Action::Operation(Rc::new(Operation::ValueOne(dummy_unary))),
326 Action::Operation(Rc::new(Operation::ValueOne(dummy_unary))),
327 ];
328 let actions: Vec<Action<BufferWriter>> = vec![
329 Action::Definition(actions),
330 ];
331 std::assert_eq!(fold_actions(&actions), (Count::N(0), Count::N(2)));
332
333 let actions: Vec<Action<BufferWriter>> = vec![
334 Action::Value(create_nan(), false),
335 Action::Value(create_nan(), false),
336 Action::Operation(Rc::new(Operation::ValueTwo(dummy_binary))),
337 Action::Operation(Rc::new(Operation::ValueTwo(dummy_binary))),
338 Action::Operation(Rc::new(Operation::ValueTwo(dummy_binary))),
339 ];
340 let actions: Vec<Action<BufferWriter>> = vec![
341 Action::Definition(actions),
342 ];
343 std::assert_eq!(fold_actions(&actions), (Count::N(2), Count::N(1)));
344
345 let actions: Vec<Action<BufferWriter>> = vec![
346 Action::Value(create_nan(), false),
347 Action::Value(create_nan(), false),
348 Action::Operation(Rc::new(Operation::ValueAll(dummy_series))),
349 ];
350 let actions: Vec<Action<BufferWriter>> = vec![
351 Action::Definition(actions),
352 ];
353 std::assert_eq!(fold_actions(&actions), (Count::All, Count::N(1)));
354 }
355}