1use crate::calc::context::{Context, Format};
2use crate::calc::undo::Undo;
3use crate::calc::value::{Value, ValueRef};
4use crate::config::Config;
5use crate::core::action;
6use crate::core::action::{Action, Actions};
7use crate::core::count::Count;
8use crate::core::helper::CommandEditor;
9use crate::core::interface::{Directive, Interface, Operation};
10use crate::core::stack::{BracketChars, StackItem, ValueStack};
11use crate::error::{EngineError, MyError, MyResult};
12use crate::util::text::create_padding;
13use fileinput::FileInput;
14use itertools::Itertools;
15use std::cell::RefCell;
16use std::fs::File;
17use std::io::{BufRead, BufReader, Write};
18use std::rc::Rc;
19use std::slice::Iter;
20
21const PAGE_LIMIT: usize = 10;
22
23pub struct Engine<W: Write> {
24 config: Config,
25 editor: CommandEditor,
26 interface: Rc<RefCell<Interface<W>>>,
27 context: Rc<RefCell<Context>>,
28 undos: Vec<Undo>,
29 redos: Vec<Undo>,
30 clip: Option<ValueRef>,
31 dirty: bool,
32 interact: bool,
33 chars: BracketChars,
34}
35
36impl<W: Write> Engine<W> {
38 pub fn new(config: Config, chars: BracketChars) -> MyResult<Self> {
39 let interface = Rc::new(RefCell::new(Interface::build()));
40 let editor = interface.borrow().create_editor()?;
41 let context = Rc::new(RefCell::new(Context::new()));
42 let undos = Vec::new();
43 let redos = Vec::new();
44 let engine = Self {
45 config,
46 editor,
47 interface,
48 context,
49 undos,
50 redos,
51 clip: None,
52 dirty: false,
53 interact: false,
54 chars,
55 };
56 Ok(engine)
57 }
58
59 pub fn parse_input(&mut self, writer: &mut W) -> MyResult<()> {
60 let mut stack = ValueStack::new(Vec::new());
61 if let Some(import) = &self.config.import {
62 let import = vec![String::from(import)];
63 self.import_file(writer, &mut stack, import)?;
64 }
65 if !self.config.values.is_empty() {
66 self.parse_values(writer, &mut stack)?;
67 if !self.config.mock {
68 self.show_simple(writer, &mut stack)?;
69 }
70 } else if !self.config.paths.is_empty() || atty::isnt(atty::Stream::Stdin) || atty::isnt(atty::Stream::Stdout) {
71 let reader = FileInput::new(&self.config.paths);
72 self.parse_files(writer, &mut stack, reader)?;
73 self.show_simple(writer, &mut stack)?;
74 } else {
75 self.parse_loop(writer, &mut stack)?;
76 }
77 Ok(())
78 }
79
80 fn parse_values(
81 &mut self,
82 writer: &mut W,
83 stack: &mut ValueStack,
84 ) -> MyResult<()> {
85 let values = self.config.values.drain(..).collect::<Vec<String>>();
86 if self.config.mock {
87 for (index, value) in values.iter().enumerate() {
88 self.interact = index + 1 == values.len();
89 self.interact_line(writer, stack, &value)?;
90 }
91 } else {
92 for value in values {
93 self.parse_line(writer, stack, &value)?;
94 }
95 }
96 Ok(())
97 }
98
99 fn parse_files(
100 &mut self,
101 writer: &mut W,
102 stack: &mut ValueStack,
103 reader: FileInput,
104 ) -> MyResult<()> {
105 let mut undo = Undo::default();
106 let mut redo = Undo::default();
107 let reader = BufReader::new(reader);
108 for line in reader.lines() {
109 let line = line?;
110 self.parse_inner(writer, stack, &mut undo, &mut redo, &line)?;
111 }
112 self.commit_undo(undo, redo);
113 Ok(())
114 }
115
116 fn parse_loop(
117 &mut self,
118 writer: &mut W,
119 stack: &mut ValueStack,
120 ) -> MyResult<()> {
121 self.interact = true;
122 loop {
123 let line = self.editor.readline("rpn> ")?;
124 self.editor.add_history_entry(&line)?;
125 self.interact_line(writer, stack, &line)?;
126 }
127 }
128
129 fn interact_line(
130 &mut self,
131 writer: &mut W,
132 stack: &mut ValueStack,
133 line: &str,
134 ) -> MyResult<()> {
135 let result = match self.parse_line(writer, stack, line) {
136 Ok(()) => {
137 if self.interact && self.dirty {
138 self.limit_stack(writer, stack, Some(PAGE_LIMIT))?;
139 }
140 Ok(())
141 }
142 Err(MyError::Engine(error)) => {
143 if self.interact {
144 writeln!(writer, " {}", error)?;
145 }
146 Ok(())
147 }
148 Err(error) => {
149 Err(error)
150 }
151 };
152 self.dirty = false;
153 result
154 }
155
156 fn parse_line(
157 &mut self,
158 writer: &mut W,
159 stack: &mut ValueStack,
160 line: &str,
161 ) -> MyResult<()> {
162 let mut undo = Undo::default();
163 let mut redo = Undo::default();
164 self.parse_inner(writer, stack, &mut undo, &mut redo, line)?;
165 self.commit_undo(undo, redo);
166 Ok(())
167 }
168
169 fn parse_inner(
170 &mut self,
171 writer: &mut W,
172 stack: &mut ValueStack,
173 undo: &mut Undo,
174 redo: &mut Undo,
175 line: &str,
176 ) -> MyResult<()> {
177 let mut empty = true;
178 let (line, comment) = Self::split_comment(line);
179 let actions = Actions::new(&self.interface, line.split_ascii_whitespace());
180 for action in actions {
181 let action = match action {
182 Ok((action, keyword)) => self.apply_action(
183 writer,
184 stack,
185 undo,
186 redo,
187 action,
188 Some(keyword),
189 ),
190 Err(error) => Err(error),
191 };
192 if let Err(error) = action {
193 undo.apply_to(stack);
194 return Err(error);
195 }
196 empty = false;
197 }
198 if let Some(comment) = comment {
199 if let Err(error) = self.apply_comment(stack, comment) {
200 undo.apply_to(stack);
201 return Err(error);
202 }
203 empty = false;
204 }
205 self.dirty |= empty;
206 Ok(())
207 }
208
209 fn split_comment(line: &str) -> (&str, Option<&str>) {
210 if let Some(stop) = line.find('#') {
211 let start = stop + 1;
212 let values = line[..stop].trim();
213 let comment = line[start..].trim();
214 let comment = if comment.is_empty() { None } else { Some(comment) };
215 (values, comment)
216 } else {
217 let values = line.trim();
218 (values, None)
219 }
220 }
221
222 fn apply_action(
223 &mut self,
224 writer: &mut W,
225 stack: &mut ValueStack,
226 undo: &mut Undo,
227 redo: &mut Undo,
228 action: Action<W>,
229 keyword: Option<&str>,
230 ) -> MyResult<()> {
231 match action {
232 Action::Operation(operation) => {
233 match operation.as_ref() {
234 Operation::ValueNone(function) => {
235 let result = function()?;
236 stack.push_single(undo, result, keyword);
237 self.dirty = true;
238 }
239 Operation::ValueOne(function) => {
240 let value = stack.pop_single(undo, None)?;
241 let result = function(value)?;
242 stack.push_single(undo, result, keyword);
243 self.dirty = true;
244 }
245 Operation::ValueTwo(function) => {
246 let (value1, value2) = stack.pop_double(undo, None)?;
247 let result = function(value1, value2)?;
248 stack.push_single(undo, result, keyword);
249 self.dirty = true;
250 }
251 Operation::ValueAll(function) => {
252 let (values, _) = stack.pop_series(undo, None);
253 let result = function(values)?;
254 stack.push_single(undo, result, keyword);
255 self.dirty = true;
256 }
257 Operation::SeriesTwo(function) => {
258 let (value1, value2) = stack.pop_double(undo, None)?;
259 let results = function(value1, value2)?;
260 self.dirty |= stack.push_series(undo, results, keyword);
261 }
262 Operation::SeriesThree(function) => {
263 let (value1, value2, value3) = stack.pop_triple(undo, None)?;
264 let results = function(value1, value2, value3)?;
265 self.dirty |= stack.push_series(undo, results, keyword);
266 }
267 Operation::SeriesAll(function) => {
268 let (values, as_series) = stack.pop_series(undo, None);
269 let results = function(values)?;
270 if as_series {
271 self.dirty |= stack.push_series(undo, results, keyword);
272 } else {
273 self.dirty |= stack.push_singles(undo, results, keyword);
274 }
275 }
276 Operation::TimeNow(function) => {
277 let result = function(&self.config.now)?;
278 stack.push_single(undo, result, keyword);
279 self.dirty = true;
280 }
281 Operation::TimeCast(function) => {
282 let value = stack.pop_single(undo, None)?;
283 let result = function(value)?;
284 stack.push_single(undo, result, keyword);
285 self.dirty = true;
286 }
287 Operation::ContextNone(function) => {
288 function(&mut self.context.borrow_mut());
289 self.dirty = true;
290 }
291 Operation::ContextOne(function) => {
292 let value = stack.pop_single(undo, keyword)?;
293 function(&mut self.context.borrow_mut(), value);
294 self.dirty = true;
295 }
296 Operation::EngineNone(function) => {
297 if let Some(dirty) = function(self, writer, stack)? {
298 self.dirty = dirty;
299 }
300 }
301 Operation::EngineUndo(function, _, _) => {
302 if let Some(dirty) = function(self, stack, undo, redo, keyword)? {
303 self.dirty = dirty;
304 }
305 }
306 }
307 }
308 Action::Directive(directive, tokens) => {
309 match directive.as_ref() {
310 Directive::EngineOne(function, _) => {
311 let token = tokens.into_iter().next();
312 self.dirty |= function(self, writer, stack, token)?;
313 }
314 Directive::EngineAll(function, _) => {
315 self.dirty |= function(self, writer, stack, tokens)?;
316 }
317 Directive::EngineApply(function, _) => {
318 self.dirty |= function(self, writer, keyword, stack, undo, redo, tokens)?;
319 }
320 }
321 }
322 Action::Definition(actions) => {
323 for action in actions {
324 self.apply_action(writer, stack, undo, redo, action, None)?;
325 }
326 undo.merge(0, vec![], keyword);
327 }
328 Action::Value(value, dirty) => {
329 stack.push_single(undo, value, keyword);
330 self.dirty |= dirty;
331 }
332 }
333 Ok(())
334 }
335
336 fn apply_comment(
337 &mut self,
338 stack: &ValueStack,
339 comment: &str,
340 ) -> MyResult<()> {
341 let value = stack.peek_single()?;
342 value.borrow_mut().set_comment(comment);
343 self.dirty = true;
344 Ok(())
345 }
346
347 fn commit_undo(
348 &mut self,
349 undo: Undo,
350 redo: Undo,
351 ) {
352 if !undo.is_empty() {
353 self.undos.push(undo);
354 self.redos.clear();
355 } else if !redo.is_empty() {
356 self.redos.push(redo);
357 }
358 }
359
360 pub fn flat_values(
361 &mut self,
362 stack: &mut ValueStack,
363 undo: &mut Undo,
364 redo: &mut Undo,
365 keyword: Option<&str>,
366 ) -> MyResult<Option<bool>> {
367 if stack.items.iter().any(|item| matches!(item, StackItem::Series(_))) {
368 let items = stack.pop_stack(undo, None);
369 redo.clear();
370 stack.push_singles(undo, items, keyword);
371 Ok(Some(true))
372 } else {
373 Ok(None)
374 }
375 }
376
377 pub fn clear_values(
378 &mut self,
379 stack: &mut ValueStack,
380 undo: &mut Undo,
381 redo: &mut Undo,
382 keyword: Option<&str>,
383 ) -> MyResult<Option<bool>> {
384 let items = stack.wrapped_drain(..).collect();
385 undo.merge(0, items, keyword);
386 redo.clear();
387 Ok(Some(true))
388 }
389
390 pub fn pop_value(
391 &mut self,
392 stack: &mut ValueStack,
393 undo: &mut Undo,
394 redo: &mut Undo,
395 keyword: Option<&str>,
396 ) -> MyResult<Option<bool>> {
397 stack.pop_single(undo, keyword)?;
398 redo.clear();
399 Ok(Some(true))
400 }
401
402 pub fn dup_value(
403 &mut self,
404 stack: &mut ValueStack,
405 undo: &mut Undo,
406 redo: &mut Undo,
407 keyword: Option<&str>,
408 ) -> MyResult<Option<bool>> {
409 let value = stack.peek_single()?;
410 let value = Rc::new(RefCell::new(value.borrow().clone()));
411 stack.push_single(undo, value, keyword);
412 redo.clear();
413 Ok(Some(true))
414 }
415
416 pub fn swap_values(
417 &mut self,
418 stack: &mut ValueStack,
419 undo: &mut Undo,
420 redo: &mut Undo,
421 keyword: Option<&str>,
422 ) -> MyResult<Option<bool>> {
423 let (value1, value2) = stack.pop_double(undo, None)?;
424 stack.push_single(undo, value2, None);
425 stack.push_single(undo, value1, keyword);
426 redo.clear();
427 Ok(Some(true))
428 }
429
430 pub fn cut_value(
431 &mut self,
432 stack: &mut ValueStack,
433 undo: &mut Undo,
434 redo: &mut Undo,
435 keyword: Option<&str>,
436 ) -> MyResult<Option<bool>> {
437 let value = stack.pop_single(undo, keyword)?;
438 self.clip = Some(value);
439 redo.clear();
440 Ok(Some(true))
441 }
442
443 pub fn copy_value(
444 &mut self,
445 stack: &mut ValueStack,
446 _undo: &mut Undo,
447 _redo: &mut Undo,
448 _keyword: Option<&str>,
449 ) -> MyResult<Option<bool>> {
450 let value = stack.peek_single()?;
451 let value = Rc::new(RefCell::new(value.borrow().clone()));
452 self.clip = Some(value);
453 Ok(None)
454 }
455
456 pub fn paste_value(
457 &mut self,
458 stack: &mut ValueStack,
459 undo: &mut Undo,
460 redo: &mut Undo,
461 keyword: Option<&str>,
462 ) -> MyResult<Option<bool>> {
463 if let Some(clip) = &self.clip {
464 stack.push_single(undo, Rc::clone(clip), keyword);
465 redo.clear();
466 Ok(Some(true))
467 } else {
468 Err(MyError::from(EngineError::MissingClip))
469 }
470 }
471
472 pub fn import_file(
473 &mut self,
474 writer: &mut W,
475 stack: &mut ValueStack,
476 tokens: Vec<String>,
477 ) -> MyResult<bool> {
478 let reader = FileInput::new(&tokens);
479 self.parse_files(writer, stack, reader)?;
480 Ok(true)
481 }
482
483 pub fn export_file(
484 &mut self,
485 _writer: &mut W,
486 stack: &mut ValueStack,
487 tokens: Vec<String>,
488 ) -> MyResult<bool> {
489 if let Some(path) = tokens.first() {
490 let mut writer = File::create(path)?;
491 let sep = self.context.borrow_mut().swap_sep(false);
492 let result = self.write_simple(&mut writer, stack);
493 self.context.borrow_mut().swap_sep(sep);
494 result?;
495 }
496 Ok(false)
497 }
498
499 pub fn set_variable(
500 &mut self,
501 writer: &mut W,
502 stack: &mut ValueStack,
503 token: Option<String>,
504 ) -> MyResult<bool> {
505 if let Some(token) = token {
506 let value = stack.peek_single()?;
507 if self.interface.borrow_mut().insert_variable(token.clone(), Rc::clone(&value)) {
508 for (value, _) in stack.iter_stack() {
509 Self::unassign_variable(value, &token);
510 }
511 }
512 self.reassign_variable(value, token);
513 self.interface.borrow().adjust_editor(&mut self.editor);
514 Ok(true)
515 } else {
516 let items = self.interface.borrow()
517 .get_variables()
518 .iter()
519 .sorted_by(|(lhs, _), (rhs, _)| String::cmp(lhs, rhs))
520 .map(|(_, value)| Rc::clone(value))
521 .map(|value| StackItem::Single(value))
522 .collect::<Vec<_>>();
523 let mut stack = ValueStack::new(items);
524 self.show_stack(writer, &mut stack)?;
525 Ok(false)
526 }
527 }
528
529 fn unassign_variable(value: ValueRef, token: &str) {
530 let mut inner = value.borrow_mut();
531 if let Some(previous) = &inner.variable {
532 if previous == token {
533 inner.variable = None;
534 }
535 }
536 }
537
538 fn reassign_variable(&mut self, value: ValueRef, token: String) {
539 let mut inner = value.borrow_mut();
540 if let Some(previous) = &inner.variable {
541 if previous != &token {
542 self.interface.borrow_mut().remove_variable(previous);
543 }
544 }
545 inner.variable = Some(token);
546 }
547
548 pub fn define_function(
549 &mut self,
550 writer: &mut W,
551 _stack: &mut ValueStack,
552 tokens: Vec<String>,
553 ) -> MyResult<bool> {
554 let mut tokens = tokens.iter();
555 if let Some(keyword) = tokens.next() {
556 let description = tokens.clone().join(" ");
557 let actions = self.parse_actions(tokens)?;
558 if !actions.is_empty() {
559 let (input, output) = action::fold_actions(&actions);
560 self.interface.borrow_mut().insert_definition(
561 keyword,
562 actions,
563 input,
564 output,
565 description,
566 );
567 } else {
568 self.interface.borrow_mut().remove_definition(keyword);
569 }
570 self.interface.borrow().adjust_editor(&mut self.editor);
571 } else {
572 self.interface.borrow().show_definitions(writer, self.interact)?;
573 }
574 Ok(false)
575 }
576
577 pub fn apply_all(
578 &mut self,
579 writer: &mut W,
580 keyword: Option<&str>,
581 stack: &mut ValueStack,
582 undo: &mut Undo,
583 _redo: &mut Undo,
584 tokens: Vec<String>,
585 ) -> MyResult<bool> {
586 let actions = self.parse_actions(tokens.iter())?;
587 if let (Count::N(1), Count::N(1)) = action::fold_actions(&actions) {
588 let (input_values, as_series) = stack.pop_series(undo, None);
589 let mut output_values = Vec::new();
590 let mut temp_undo = Undo::new(0, vec![], vec![]);
591 let mut temp_redo = Undo::new(0, vec![], vec![]);
592 for value in input_values {
593 let mut temp_stack = ValueStack::new(Vec::new());
594 temp_stack.push_single(&mut temp_undo, value, None);
595 for action in &actions {
596 self.apply_action(
597 writer,
598 &mut temp_stack,
599 &mut temp_undo,
600 &mut temp_redo,
601 action.clone(),
602 None,
603 )?;
604 }
605 let (mut temp_values, _) = temp_stack.pop_series(&mut temp_undo, None);
606 output_values.append(&mut temp_values);
607 }
608 if !output_values.is_empty() {
609 if as_series {
610 stack.push_series(undo, output_values, None);
611 } else {
612 stack.push_singles(undo, output_values, None);
613 }
614 undo.add_tokens(keyword, tokens);
615 Ok(true)
616 } else {
617 Ok(false)
618 }
619 } else {
620 Err(MyError::Engine(EngineError::BadApplyOp))
621 }
622 }
623
624 fn parse_actions(
625 &mut self,
626 tokens: Iter<String>,
627 ) -> MyResult<Vec<Action<W>>> {
628 let tokens = tokens.map(String::as_ref);
629 let actions = Actions::new(&self.interface, tokens);
630 actions
631 .map(|result| result.map(|(x, _)| x))
632 .collect::<MyResult<Vec<Action<W>>>>()
633 }
634
635 pub fn undo_stack(
636 &mut self,
637 stack: &mut ValueStack,
638 undo: &mut Undo,
639 redo: &mut Undo,
640 _keyword: Option<&str>,
641 ) -> MyResult<Option<bool>> {
642 if !undo.is_empty() {
643 self.redos.push(undo.apply_to(stack));
644 redo.clear();
645 Ok(Some(true))
646 } else if let Some(mut undo) = self.undos.pop() {
647 self.redos.push(undo.apply_to(stack));
648 redo.clear();
649 Ok(Some(true))
650 } else {
651 Err(MyError::from(EngineError::MissingUndo))
652 }
653 }
654
655 pub fn redo_stack(
656 &mut self,
657 stack: &mut ValueStack,
658 undo: &mut Undo,
659 redo: &mut Undo,
660 _keyword: Option<&str>,
661 ) -> MyResult<Option<bool>> {
662 if undo.is_empty() {
663 if !redo.is_empty() {
664 self.undos.push(redo.apply_to(stack));
665 return Ok(Some(true));
666 } else if let Some(mut redo) = self.redos.pop() {
667 self.undos.push(redo.apply_to(stack));
668 return Ok(Some(true));
669 }
670 }
671 Err(MyError::from(EngineError::MissingRedo))
672 }
673
674 pub fn show_history(
675 &mut self,
676 writer: &mut W,
677 _stack: &mut ValueStack,
678 ) -> MyResult<Option<bool>> {
679 if self.interact {
680 self.limit_history(writer, PAGE_LIMIT)?;
681 }
682 Ok(Some(false))
683 }
684
685 fn limit_history(&mut self, writer: &mut W, limit: usize) -> MyResult<()> {
686 if self.undos.is_empty() {
687 writeln!(writer, " <==")?;
688 } else {
689 if self.undos.len() > limit {
690 writeln!(writer, " ...")?;
691 }
692 for (index, undo) in self.undos.iter().rev().enumerate().take(limit).rev() {
693 if index == 0 {
694 writeln!(writer, " {} <==", undo)?;
695 } else {
696 writeln!(writer, " {}", undo)?;
697 }
698 }
699 }
700 for redo in self.redos.iter().rev().take(limit) {
701 writeln!(writer, " {}", redo)?;
702 }
703 if self.redos.len() > limit {
704 writeln!(writer, " ...")?;
705 }
706 Ok(())
707 }
708
709 fn show_simple(
710 &mut self,
711 writer: &mut W,
712 stack: &mut ValueStack,
713 ) -> Result<(), MyError> {
714 if self.config.sum {
715 let mut undo = Undo::new(0, vec![], vec![]);
716 let (values, _) = stack.pop_series(&mut undo, None);
717 let result = Value::calc_sum(values)?;
718 stack.push_single(&mut undo, result, None);
719 }
720 if self.config.hex {
721 self.context.borrow_mut().set_hex();
722 }
723 if self.config.sep {
724 self.context.borrow_mut().set_sep();
725 }
726 if let Some(dp) = self.config.dp {
727 self.context.borrow_mut().set_dp_u8(dp);
728 }
729 self.write_simple(writer, stack)?;
730 Ok(())
731 }
732
733 fn write_simple<V: Write>(
734 &mut self,
735 writer: &mut V,
736 stack: &mut ValueStack,
737 ) -> MyResult<()> {
738 self.measure_hexadecimal(stack);
739 let context = self.context.borrow();
740 for (value, _) in stack.iter_stack() {
741 let (integer, fraction, _, _) = value.borrow().to_strings(&context);
742 writeln!(writer, "{}{}", integer, fraction)?;
743 }
744 Ok(())
745 }
746
747 pub fn show_stack(
748 &mut self,
749 writer: &mut W,
750 stack: &mut ValueStack,
751 ) -> MyResult<Option<bool>> {
752 self.limit_stack(writer, stack, None)?;
753 Ok(Some(false))
754 }
755
756 fn limit_stack(
757 &mut self,
758 writer: &mut W,
759 stack: &mut ValueStack,
760 limit: Option<usize>,
761 ) -> MyResult<()> {
762 if self.interact {
763 self.measure_hexadecimal(stack);
764 let context = self.context.borrow();
765 let table = match limit {
766 Some(limit) if limit < stack.total_len() => {
767 writeln!(writer, " ...")?;
771 stack.iter_stack()
772 .rev()
773 .take(limit)
774 .collect::<Vec<_>>()
775 .into_iter()
776 .rev()
777 .map(|(value, style)| (value.borrow().to_strings(&context), style))
778 .collect::<Vec<_>>()
779 }
780 _ => {
781 stack.iter_stack()
782 .map(|(value, style)| (value.borrow().to_strings(&context), style))
783 .collect::<Vec<_>>()
784 }
785 };
786 let integer_width = table.iter()
787 .map(|((x, _, _, _), _)| x.len())
788 .max()
789 .unwrap_or_default();
790 let fraction_width = table.iter()
791 .map(|((_, x, _, _), _)| x.len())
792 .max()
793 .unwrap_or_default();
794 for ((integer, fraction, variable, comment), style) in table {
795 let padding = create_padding(' ', integer_width + 1, integer.len(), 0);
796 let prefix = self.chars.get_prefix(style).unwrap_or(' ');
797 let suffix = self.chars.get_suffix(style);
798 write!(writer, "{}{}{}{}", prefix, padding, integer, fraction)?;
799 if suffix.is_some() || variable.is_some() || comment.is_some() {
800 let padding = create_padding(' ', fraction_width, fraction.len(), 0);
801 write!(writer, "{}", padding)?;
802 }
803 if let Some(suffix) = suffix {
804 write!(writer, " {}", suffix)?;
805 }
806 if let Some(variable) = variable {
807 write!(writer, " = {}", variable)?;
808 }
809 if let Some(comment) = comment {
810 write!(writer, " # {}", comment)?;
811 }
812 writeln!(writer)?;
813 }
814 }
815 Ok(())
816 }
817
818 fn measure_hexadecimal(&mut self, stack: &ValueStack) {
819 let mut context = self.context.borrow_mut();
820 if let Format::Base16(_) = context.format {
821 let chunks = stack.iter_stack()
822 .map(|(value, _)| value.borrow().measure_hexadecimal())
823 .max()
824 .unwrap_or_default();
825 context.format = Format::Base16(chunks);
826 }
827 }
828
829 pub fn show_help(
830 &mut self,
831 writer: &mut W,
832 _stack: &mut ValueStack,
833 ) -> MyResult<Option<bool>> {
834 self.interface.borrow().show_help(writer, self.interact)?;
835 Ok(Some(false))
836 }
837}
838
839#[cfg(test)]
841pub mod tests {
842 use crate::calc::context::Format;
843 use crate::calc::undo::tests::create_undo;
844 use crate::calc::value::tests::parse_value;
845 use crate::config::Config;
846 use crate::core::stack::tests::{parse_item, parse_items, parse_series};
847 use crate::core::stack::{BracketChars, ValueStack};
848 use crate::engine::Engine;
849 use crate::error::MyResult;
850 use crate::util::text::tests::BufferWriter;
851 use pretty_assertions::assert_eq;
852 use std::collections::HashMap;
853 use std::io::Write;
854
855 #[test]
856 fn test_split_comment_finds_first_hash() {
857 assert_eq!(Engine::<BufferWriter>::split_comment("\tone two three\t"), ("one two three", None));
858 assert_eq!(Engine::<BufferWriter>::split_comment("\tone two three #\t"), ("one two three", None));
859 assert_eq!(Engine::<BufferWriter>::split_comment("\tone # two # three\t"), ("one", Some("two # three")));
860 }
861
862 #[test]
865 fn test_create_values_modifies_stack() {
866 let expected_items = parse_items(vec!["1", "2", "3", "4", "5", "6"]);
867 let expected_undos = vec![
868 create_undo(3, vec![], vec!["1", "2", "3"]),
869 create_undo(3, vec![], vec!["4", "5", "6"]),
870 ];
871 let expected_redos = vec![];
872 let mut engine = create_engine();
873 let mut writer = BufferWriter::new();
874 let mut stack = ValueStack::new(Vec::new());
875 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
876 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
877 assert_eq!(stack.items, expected_items);
878 assert_eq!(engine.undos, expected_undos);
879 assert_eq!(engine.redos, expected_redos);
880 assert_eq!(writer.buffer, "");
881 }
882
883 #[test]
884 fn test_comment_modifies_current_line() {
885 let expected_items = vec![
886 parse_item("1"),
887 parse_item("2"),
888 parse_item("3"),
889 parse_item("42 # the answer"),
890 ];
891 let expected_undos = vec![
892 create_undo(2, vec![], vec!["1", "2"]),
893 create_undo(2, vec![], vec!["3", "42"]),
894 ];
895 let expected_redos = vec![];
896 let mut engine = create_engine();
897 let mut writer = BufferWriter::new();
898 let mut stack = ValueStack::new(Vec::new());
899 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2").is_ok());
900 assert!(parse_line(&mut engine, &mut writer, &mut stack, "3 42 # the answer").is_ok());
901 assert_eq!(stack.items, expected_items);
902 assert_eq!(engine.undos, expected_undos);
903 assert_eq!(engine.redos, expected_redos);
904 assert_eq!(writer.buffer, "");
905 }
906
907 #[test]
908 fn test_comment_modifies_previous_line() {
909 let expected_items = vec![
910 parse_item("1"),
911 parse_item("2"),
912 parse_item("3"),
913 parse_item("42 # the answer"),
914 ];
915 let expected_undos = vec![
916 create_undo(4, vec![], vec!["1", "2", "3", "42"]),
917 ];
918 let expected_redos = vec![];
919 let mut engine = create_engine();
920 let mut writer = BufferWriter::new();
921 let mut stack = ValueStack::new(Vec::new());
922 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 42").is_ok());
923 assert!(parse_line(&mut engine, &mut writer, &mut stack, "# the answer").is_ok());
924 assert_eq!(stack.items, expected_items);
925 assert_eq!(engine.undos, expected_undos);
926 assert_eq!(engine.redos, expected_redos);
927 assert_eq!(writer.buffer, "");
928 }
929
930 #[test]
931 fn test_comment_fails_cleanly() {
932 let expected_items = vec![];
933 let expected_undos = vec![];
934 let expected_redos = vec![];
935 let mut engine = create_engine();
936 let mut writer = BufferWriter::new();
937 let mut stack = ValueStack::new(Vec::new());
938 assert!(parse_line(&mut engine, &mut writer, &mut stack, "# the answer").is_err());
939 assert_eq!(stack.items, expected_items);
940 assert_eq!(engine.undos, expected_undos);
941 assert_eq!(engine.redos, expected_redos);
942 assert_eq!(writer.buffer, "Not enough values on stack\n");
943 }
944
945 #[test]
948 fn test_unknown_operation_fails_cleanly() {
949 let expected_items = parse_items(vec!["1", "2", "3"]);
950 let expected_undos = vec![
951 create_undo(3, vec![], vec!["1", "2", "3"]),
952 ];
953 let expected_redos = vec![];
954 let mut engine = create_engine();
955 let mut writer = BufferWriter::new();
956 let mut stack = ValueStack::new(Vec::new());
957 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
958 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 xyz 999").is_err());
959 assert_eq!(stack.items, expected_items);
960 assert_eq!(engine.undos, expected_undos);
961 assert_eq!(engine.redos, expected_redos);
962 assert_eq!(writer.buffer, "Invalid number or keyword: xyz\n");
963 }
964
965 #[test]
968 fn test_nullary_operation_modifies_stack() {
969 let expected_undos = vec![
970 create_undo(1, vec![], vec!["now"]),
971 ];
972 let expected_redos = vec![];
973 let mut engine = create_engine();
974 let mut writer = BufferWriter::new();
975 let mut stack = ValueStack::new(Vec::new());
976 assert!(parse_line(&mut engine, &mut writer, &mut stack, "now").is_ok());
977 assert_eq!(stack.wrapped_len(), 1);
978 assert_eq!(engine.undos, expected_undos);
979 assert_eq!(engine.redos, expected_redos);
980 assert_eq!(writer.buffer, "");
981 }
982
983 #[test]
986 fn test_unary_operation_modifies_stack() {
987 let expected_items = parse_items(vec!["1", "-2"]);
988 let expected_undos = vec![
989 create_undo(3, vec![], vec!["1", "2", "3"]),
990 create_undo(1, vec!["2", "3"], vec!["pop", "neg"]),
991 ];
992 let expected_redos = vec![];
993 let mut engine = create_engine();
994 let mut writer = BufferWriter::new();
995 let mut stack = ValueStack::new(Vec::new());
996 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
997 assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop neg").is_ok());
998 assert_eq!(stack.items, expected_items);
999 assert_eq!(engine.undos, expected_undos);
1000 assert_eq!(engine.redos, expected_redos);
1001 assert_eq!(writer.buffer, "");
1002 }
1003
1004 #[test]
1005 fn test_unary_operation_fails_cleanly() {
1006 let expected_items = parse_items(vec!["1", "2", "3"]);
1007 let expected_undos = vec![
1008 create_undo(3, vec![], vec!["1", "2", "3"]),
1009 ];
1010 let expected_redos = vec![];
1011 let mut engine = create_engine();
1012 let mut writer = BufferWriter::new();
1013 let mut stack = ValueStack::new(Vec::new());
1014 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1015 assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop pop pop neg 999").is_err());
1016 assert_eq!(stack.items, expected_items);
1017 assert_eq!(engine.undos, expected_undos);
1018 assert_eq!(engine.redos, expected_redos);
1019 assert_eq!(writer.buffer, "Not enough values on stack\n");
1020 }
1021
1022 #[test]
1025 fn test_binary_operation_modifies_stack() {
1026 let expected_items = parse_items(vec!["1", "5"]);
1027 let expected_undos = vec![
1028 create_undo(3, vec![], vec!["1", "2", "3"]),
1029 create_undo(1, vec!["2", "3"], vec!["add"]),
1030 ];
1031 let expected_redos = vec![];
1032 let mut engine = create_engine();
1033 let mut writer = BufferWriter::new();
1034 let mut stack = ValueStack::new(Vec::new());
1035 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1036 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1037 assert_eq!(stack.items, expected_items);
1038 assert_eq!(engine.undos, expected_undos);
1039 assert_eq!(engine.redos, expected_redos);
1040 assert_eq!(writer.buffer, "");
1041 }
1042
1043 #[test]
1044 fn test_binary_operation_fails_cleanly() {
1045 let expected_items = parse_items(vec!["1", "2", "3"]);
1046 let expected_undos = vec![
1047 create_undo(3, vec![], vec!["1", "2", "3"]),
1048 ];
1049 let expected_redos = vec![];
1050 let mut engine = create_engine();
1051 let mut writer = BufferWriter::new();
1052 let mut stack = ValueStack::new(Vec::new());
1053 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1054 assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop pop add 999").is_err());
1055 assert_eq!(stack.items, expected_items);
1056 assert_eq!(engine.undos, expected_undos);
1057 assert_eq!(engine.redos, expected_redos);
1058 assert_eq!(writer.buffer, "Not enough values on stack\n");
1059 }
1060
1061 #[test]
1064 fn test_series_to_value_operation_modifies_stack() {
1065 let expected_items = parse_items(vec!["6"]);
1066 let expected_undos = vec![
1067 create_undo(3, vec![], vec!["1", "2", "3"]),
1068 create_undo(1, vec!["1", "2", "3"], vec!["sum"]),
1069 ];
1070 let expected_redos = vec![];
1071 let mut engine = create_engine();
1072 let mut writer = BufferWriter::new();
1073 let mut stack = ValueStack::new(Vec::new());
1074 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1075 assert!(parse_line(&mut engine, &mut writer, &mut stack, "sum").is_ok());
1076 assert_eq!(stack.items, expected_items);
1077 assert_eq!(engine.undos, expected_undos);
1078 assert_eq!(engine.redos, expected_redos);
1079 assert_eq!(writer.buffer, "");
1080 }
1081
1082 #[test]
1083 fn test_binary_to_series_operation_modifies_stack() {
1084 let expected_items = parse_items(vec!["[1 2 3 4 5]"]);
1085 let expected_undos = vec![
1086 create_undo(2, vec![], vec!["1", "5"]),
1087 create_undo(1, vec!["1", "5"], vec!["seq"]),
1088 ];
1089 let expected_redos = vec![];
1090 let mut engine = create_engine();
1091 let mut writer = BufferWriter::new();
1092 let mut stack = ValueStack::new(Vec::new());
1093 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 5").is_ok());
1094 assert!(parse_line(&mut engine, &mut writer, &mut stack, "seq").is_ok());
1095 assert_eq!(stack.items, expected_items);
1096 assert_eq!(engine.undos, expected_undos);
1097 assert_eq!(engine.redos, expected_redos);
1098 assert_eq!(writer.buffer, "");
1099 }
1100
1101 #[test]
1102 fn test_binary_to_series_operation_fails_cleanly() {
1103 let expected_items = parse_items(vec!["1", "5"]);
1104 let expected_undos = vec![
1105 create_undo(2, vec![], vec!["1", "5"]),
1106 ];
1107 let expected_redos = vec![];
1108 let mut engine = create_engine();
1109 let mut writer = BufferWriter::new();
1110 let mut stack = ValueStack::new(Vec::new());
1111 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 5").is_ok());
1112 assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop seq 999").is_err());
1113 assert_eq!(stack.items, expected_items);
1114 assert_eq!(engine.undos, expected_undos);
1115 assert_eq!(engine.redos, expected_redos);
1116 assert_eq!(writer.buffer, "Not enough values on stack\n");
1117 }
1118
1119 #[test]
1120 fn test_series_to_series_operation_modifies_stack() {
1121 let expected_items = parse_items(vec!["5", "4", "3", "2", "1"]);
1122 let expected_undos = vec![
1123 create_undo(5, vec![], vec!["1", "2", "3", "4", "5"]),
1124 create_undo(5, vec!["1", "2", "3", "4", "5"], vec!["rev"]),
1125 ];
1126 let expected_redos = vec![];
1127 let mut engine = create_engine();
1128 let mut writer = BufferWriter::new();
1129 let mut stack = ValueStack::new(Vec::new());
1130 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 4 5").is_ok());
1131 assert!(parse_line(&mut engine, &mut writer, &mut stack, "rev").is_ok());
1132 assert_eq!(stack.items, expected_items);
1133 assert_eq!(engine.undos, expected_undos);
1134 assert_eq!(engine.redos, expected_redos);
1135 assert_eq!(writer.buffer, "");
1136 }
1137
1138 #[test]
1139 fn test_series_to_series_operation_modifies_series() {
1140 let expected_items = parse_items(vec!["1", "2", "[5 4 3]"]);
1141 let expected_undos = vec![
1142 create_undo(3, vec![], vec!["1", "2", "3", "5", "seq"]),
1143 create_undo(1, vec!["[3 4 5]"], vec!["rev"]),
1144 ];
1145 let expected_redos = vec![];
1146 let mut engine = create_engine();
1147 let mut writer = BufferWriter::new();
1148 let mut stack = ValueStack::new(Vec::new());
1149 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 5 seq").is_ok());
1150 assert!(parse_line(&mut engine, &mut writer, &mut stack, "rev").is_ok());
1151 assert_eq!(stack.items, expected_items);
1152 assert_eq!(engine.undos, expected_undos);
1153 assert_eq!(engine.redos, expected_redos);
1154 assert_eq!(writer.buffer, "");
1155 }
1156
1157 #[test]
1160 fn test_apply_unary_operation_modifies_empty() {
1161 let expected_items = vec![];
1162 let expected_undos = vec![];
1163 let expected_redos = vec![];
1164 let mut engine = create_engine();
1165 let mut writer = BufferWriter::new();
1166 let mut stack = ValueStack::new(Vec::new());
1167 assert!(parse_line(&mut engine, &mut writer, &mut stack, "apply 2 pow").is_ok());
1168 assert_eq!(stack.items, expected_items);
1169 assert_eq!(engine.undos, expected_undos);
1170 assert_eq!(engine.redos, expected_redos);
1171 assert_eq!(writer.buffer, "");
1172 }
1173
1174 #[test]
1175 fn test_apply_unary_operation_modifies_stack() {
1176 let expected_items = parse_items(vec!["1", "4", "9", "16", "25", "36"]);
1177 let expected_undos = vec![
1178 create_undo(3, vec![], vec!["1", "2", "5", "seq", "6"]),
1179 create_undo(6, vec!["1", "[2 3 4 5]", "6"], vec!["apply", "2", "pow"]),
1180 ];
1181 let expected_redos = vec![];
1182 let mut engine = create_engine();
1183 let mut writer = BufferWriter::new();
1184 let mut stack = ValueStack::new(Vec::new());
1185 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 5 seq 6").is_ok());
1186 assert!(parse_line(&mut engine, &mut writer, &mut stack, "apply 2 pow").is_ok());
1187 assert_eq!(stack.items, expected_items);
1188 assert_eq!(engine.undos, expected_undos);
1189 assert_eq!(engine.redos, expected_redos);
1190 assert_eq!(writer.buffer, "");
1191 }
1192
1193 #[test]
1194 fn test_apply_unary_operation_modifies_series() {
1195 let expected_items = parse_items(vec!["1", "2", "3", "[16 25 36]"]);
1196 let expected_undos = vec![
1197 create_undo(4, vec![], vec!["1", "2", "3", "4", "6", "seq"]),
1198 create_undo(1, vec!["[4 5 6]"], vec!["apply", "2", "pow"]),
1199 ];
1200 let expected_redos = vec![];
1201 let mut engine = create_engine();
1202 let mut writer = BufferWriter::new();
1203 let mut stack = ValueStack::new(Vec::new());
1204 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 4 6 seq").is_ok());
1205 assert!(parse_line(&mut engine, &mut writer, &mut stack, "apply 2 pow").is_ok());
1206 assert_eq!(stack.items, expected_items);
1207 assert_eq!(engine.undos, expected_undos);
1208 assert_eq!(engine.redos, expected_redos);
1209 assert_eq!(writer.buffer, "");
1210 }
1211
1212 #[test]
1213 fn test_apply_nullary_operation_fails_cleanly() {
1214 let expected_items = vec![];
1215 let expected_undos = vec![];
1216 let expected_redos = vec![];
1217 let mut engine = create_engine();
1218 let mut writer = BufferWriter::new();
1219 let mut stack = ValueStack::new(Vec::new());
1220 assert!(parse_line(&mut engine, &mut writer, &mut stack, "apply now").is_err());
1221 assert_eq!(stack.items, expected_items);
1222 assert_eq!(engine.undos, expected_undos);
1223 assert_eq!(engine.redos, expected_redos);
1224 assert_eq!(writer.buffer, "Unsupported apply operation (must be unary)\n");
1225 }
1226
1227 #[test]
1228 fn test_apply_binary_operation_fails_cleanly() {
1229 let expected_items = vec![];
1230 let expected_undos = vec![];
1231 let expected_redos = vec![];
1232 let mut engine = create_engine();
1233 let mut writer = BufferWriter::new();
1234 let mut stack = ValueStack::new(Vec::new());
1235 assert!(parse_line(&mut engine, &mut writer, &mut stack, "apply add").is_err());
1236 assert_eq!(stack.items, expected_items);
1237 assert_eq!(engine.undos, expected_undos);
1238 assert_eq!(engine.redos, expected_redos);
1239 assert_eq!(writer.buffer, "Unsupported apply operation (must be unary)\n");
1240 }
1241
1242 #[test]
1243 fn test_apply_series_operation_fails_cleanly() {
1244 let expected_items = vec![];
1245 let expected_undos = vec![];
1246 let expected_redos = vec![];
1247 let mut engine = create_engine();
1248 let mut writer = BufferWriter::new();
1249 let mut stack = ValueStack::new(Vec::new());
1250 assert!(parse_line(&mut engine, &mut writer, &mut stack, "apply sum").is_err());
1251 assert_eq!(stack.items, expected_items);
1252 assert_eq!(engine.undos, expected_undos);
1253 assert_eq!(engine.redos, expected_redos);
1254 assert_eq!(writer.buffer, "Unsupported apply operation (must be unary)\n");
1255 }
1256
1257 #[test]
1260 fn test_cast_modifies_current_line() {
1261 let expected_items = vec![
1262 parse_item("1"),
1263 parse_item("2"),
1264 parse_item("3"),
1265 parse_item("5025.678 [delta]"),
1266 ];
1267 let expected_undos = vec![
1268 create_undo(2, vec![], vec!["1", "2"]),
1269 create_undo(2, vec![], vec!["3", "5025.678", "delta"]),
1270 ];
1271 let expected_redos = vec![];
1272 let mut engine = create_engine();
1273 let mut writer = BufferWriter::new();
1274 let mut stack = ValueStack::new(Vec::new());
1275 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2").is_ok());
1276 assert!(parse_line(&mut engine, &mut writer, &mut stack, "3 5025.678 delta").is_ok());
1277 assert_eq!(stack.items, expected_items);
1278 assert_eq!(engine.undos, expected_undos);
1279 assert_eq!(engine.redos, expected_redos);
1280 assert_eq!(writer.buffer, "");
1281 }
1282
1283 #[test]
1284 fn test_cast_modifies_previous_line() {
1285 let expected_items = vec![
1286 parse_item("1"),
1287 parse_item("2"),
1288 parse_item("3"),
1289 parse_item("5025.678 [delta]"),
1290 ];
1291 let expected_undos = vec![
1292 create_undo(4, vec![], vec!["1", "2", "3", "5025.678"]),
1293 create_undo(1, vec!["5025.678"], vec!["delta"]),
1294 ];
1295 let expected_redos = vec![];
1296 let mut engine = create_engine();
1297 let mut writer = BufferWriter::new();
1298 let mut stack = ValueStack::new(Vec::new());
1299 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 5025.678").is_ok());
1300 assert!(parse_line(&mut engine, &mut writer, &mut stack, "delta").is_ok());
1301 assert_eq!(stack.items, expected_items);
1302 assert_eq!(engine.undos, expected_undos);
1303 assert_eq!(engine.redos, expected_redos);
1304 assert_eq!(writer.buffer, "");
1305 }
1306
1307 #[test]
1308 fn test_cast_fails_cleanly() {
1309 let expected_items = vec![];
1310 let expected_undos = vec![];
1311 let expected_redos = vec![];
1312 let mut engine = create_engine();
1313 let mut writer = BufferWriter::new();
1314 let mut stack = ValueStack::new(Vec::new());
1315 assert!(parse_line(&mut engine, &mut writer, &mut stack, "delta").is_err());
1316 assert_eq!(stack.items, expected_items);
1317 assert_eq!(engine.undos, expected_undos);
1318 assert_eq!(engine.redos, expected_redos);
1319 assert_eq!(writer.buffer, "Not enough values on stack\n");
1320 }
1321
1322 #[test]
1325 fn test_flat_operation_leaves_stack_no_series() {
1326 let expected_items = parse_items(vec!["1", "2", "3", "4", "5"]);
1327 let expected_undos = vec![
1328 create_undo(5, vec![], vec!["1", "2", "3", "4", "5"]),
1329 ];
1330 let expected_redos = vec![];
1331 let mut engine = create_engine();
1332 let mut writer = BufferWriter::new();
1333 let mut stack = ValueStack::new(Vec::new());
1334 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 4 5").is_ok());
1335 assert!(parse_line(&mut engine, &mut writer, &mut stack, "flat").is_ok());
1336 assert_eq!(stack.items, expected_items);
1337 assert_eq!(engine.undos, expected_undos);
1338 assert_eq!(engine.redos, expected_redos);
1339 assert_eq!(writer.buffer, "");
1340 }
1341
1342 #[test]
1343 fn test_flat_operation_modifies_stack_with_series() {
1344 let expected_items = parse_items(vec!["1", "2", "3", "4", "5", "6", "7", "8"]);
1345 let expected_undos = vec![
1346 create_undo(5, vec![], vec!["1", "2", "3", "seq", "4", "5", "7", "seq", "8"]),
1347 create_undo(8, vec!["1", "[2 3]", "4", "[5 6 7]", "8"], vec!["flat"]),
1348 ];
1349 let expected_redos = vec![];
1350 let mut engine = create_engine();
1351 let mut writer = BufferWriter::new();
1352 let mut stack = ValueStack::new(Vec::new());
1353 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 seq 4 5 7 seq 8").is_ok());
1354 assert!(parse_line(&mut engine, &mut writer, &mut stack, "flat").is_ok());
1355 assert_eq!(stack.items, expected_items);
1356 assert_eq!(engine.undos, expected_undos);
1357 assert_eq!(engine.redos, expected_redos);
1358 assert_eq!(writer.buffer, "");
1359 }
1360
1361 #[test]
1364 fn test_clear_operation_modifies_stack() {
1365 let expected_items = vec![];
1366 let expected_undos = vec![
1367 create_undo(3, vec![], vec!["1", "2", "3"]),
1368 create_undo(0, vec!["1", "2", "3"], vec!["clear"]),
1369 ];
1370 let expected_redos = vec![];
1371 let mut engine = create_engine();
1372 let mut writer = BufferWriter::new();
1373 let mut stack = ValueStack::new(Vec::new());
1374 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1375 assert!(parse_line(&mut engine, &mut writer, &mut stack, "clear").is_ok());
1376 assert_eq!(stack.items, expected_items);
1377 assert_eq!(engine.undos, expected_undos);
1378 assert_eq!(engine.redos, expected_redos);
1379 assert_eq!(writer.buffer, "");
1380 }
1381
1382 #[test]
1385 fn test_pop_operation_modifies_stack() {
1386 let expected_items = parse_items(vec!["1", "2"]);
1387 let expected_undos = vec![
1388 create_undo(3, vec![], vec!["1", "2", "3"]),
1389 create_undo(0, vec!["3"], vec!["pop"]),
1390 ];
1391 let expected_redos = vec![];
1392 let mut engine = create_engine();
1393 let mut writer = BufferWriter::new();
1394 let mut stack = ValueStack::new(Vec::new());
1395 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1396 assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop").is_ok());
1397 assert_eq!(stack.items, expected_items);
1398 assert_eq!(engine.undos, expected_undos);
1399 assert_eq!(engine.redos, expected_redos);
1400 assert_eq!(writer.buffer, "");
1401 }
1402
1403 #[test]
1404 fn test_pop_operation_fails_cleanly() {
1405 let expected_items = parse_items(vec!["1", "2", "3"]);
1406 let expected_undos = vec![
1407 create_undo(3, vec![], vec!["1", "2", "3"]),
1408 ];
1409 let expected_redos = vec![];
1410 let mut engine = create_engine();
1411 let mut writer = BufferWriter::new();
1412 let mut stack = ValueStack::new(Vec::new());
1413 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1414 assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop pop pop pop 999").is_err());
1415 assert_eq!(stack.items, expected_items);
1416 assert_eq!(engine.undos, expected_undos);
1417 assert_eq!(engine.redos, expected_redos);
1418 assert_eq!(writer.buffer, "Not enough values on stack\n");
1419 }
1420
1421 #[test]
1424 fn test_dup_operation_modifies_stack() {
1425 let expected_items = vec![
1426 parse_item("1"),
1427 parse_item("2"),
1428 parse_item("3 = x # comment"),
1429 parse_item("3 # comment"),
1430 ];
1431 let expected_undos = vec![
1432 create_undo(3, vec![], vec!["1", "2", "3"]),
1433 create_undo(1, vec![], vec!["dup"]),
1434 ];
1435 let expected_redos = vec![];
1436 let mut engine = create_engine();
1437 let mut writer = BufferWriter::new();
1438 let mut stack = ValueStack::new(Vec::new());
1439 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 = x # comment").is_ok());
1440 assert!(parse_line(&mut engine, &mut writer, &mut stack, "dup").is_ok());
1441 assert_eq!(stack.items, expected_items);
1442 assert_eq!(engine.undos, expected_undos);
1443 assert_eq!(engine.redos, expected_redos);
1444 assert_eq!(writer.buffer, "");
1445 }
1446
1447 #[test]
1448 fn test_dup_operation_fails_cleanly() {
1449 let expected_items = vec![
1450 parse_item("1"),
1451 parse_item("2"),
1452 parse_item("3 = x # comment"),
1453 ];
1454 let expected_undos = vec![
1455 create_undo(3, vec![], vec!["1", "2", "3"]),
1456 ];
1457 let expected_redos = vec![];
1458 let mut engine = create_engine();
1459 let mut writer = BufferWriter::new();
1460 let mut stack = ValueStack::new(Vec::new());
1461 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 = x # comment").is_ok());
1462 assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop pop pop dup 999").is_err());
1463 assert_eq!(stack.items, expected_items);
1464 assert_eq!(engine.undos, expected_undos);
1465 assert_eq!(engine.redos, expected_redos);
1466 assert_eq!(writer.buffer, "Not enough values on stack\n");
1467 }
1468
1469 #[test]
1472 fn test_swap_operation_modifies_stack() {
1473 let expected_items = parse_items(vec!["1", "3", "2"]);
1474 let expected_undos = vec![
1475 create_undo(3, vec![], vec!["1", "2", "3"]),
1476 create_undo(2, vec!["2", "3"], vec!["swap"]),
1477 ];
1478 let expected_redos = vec![];
1479 let mut engine = create_engine();
1480 let mut writer = BufferWriter::new();
1481 let mut stack = ValueStack::new(Vec::new());
1482 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1483 assert!(parse_line(&mut engine, &mut writer, &mut stack, "swap").is_ok());
1484 assert_eq!(stack.items, expected_items);
1485 assert_eq!(engine.undos, expected_undos);
1486 assert_eq!(engine.redos, expected_redos);
1487 assert_eq!(writer.buffer, "");
1488 }
1489
1490 #[test]
1491 fn test_swap_operation_fails_cleanly() {
1492 let expected_items = parse_items(vec!["1", "2", "3"]);
1493 let expected_undos = vec![
1494 create_undo(3, vec![], vec!["1", "2", "3"]),
1495 ];
1496 let expected_redos = vec![];
1497 let mut engine = create_engine();
1498 let mut writer = BufferWriter::new();
1499 let mut stack = ValueStack::new(Vec::new());
1500 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1501 assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop pop swap 999").is_err());
1502 assert_eq!(stack.items, expected_items);
1503 assert_eq!(engine.undos, expected_undos);
1504 assert_eq!(engine.redos, expected_redos);
1505 assert_eq!(writer.buffer, "Not enough values on stack\n");
1506 }
1507
1508 #[test]
1511 fn test_cut_operation_copies_value() {
1512 let expected_items = vec![];
1513 let expected_undos = vec![
1514 create_undo(1, vec![], vec!["42"]),
1515 create_undo(0, vec!["42"], vec!["cut"]),
1516 ];
1517 let expected_redos = vec![];
1518 let mut engine = create_engine();
1519 let mut writer = BufferWriter::new();
1520 let mut stack = ValueStack::new(Vec::new());
1521 assert!(parse_line(&mut engine, &mut writer, &mut stack, "42").is_ok());
1522 assert!(parse_line(&mut engine, &mut writer, &mut stack, "cut").is_ok());
1523 assert_eq!(stack.items, expected_items);
1524 assert_eq!(engine.undos, expected_undos);
1525 assert_eq!(engine.redos, expected_redos);
1526 assert_eq!(engine.clip, Some(parse_value("42")));
1527 assert_eq!(writer.buffer, "");
1528 }
1529
1530 #[test]
1531 fn test_cut_operation_fails_cleanly() {
1532 let expected_items = vec![];
1533 let expected_undos = vec![];
1534 let expected_redos = vec![];
1535 let mut engine = create_engine();
1536 let mut writer = BufferWriter::new();
1537 let mut stack = ValueStack::new(Vec::new());
1538 assert!(parse_line(&mut engine, &mut writer, &mut stack, "cut").is_err());
1539 assert_eq!(stack.items, expected_items);
1540 assert_eq!(engine.undos, expected_undos);
1541 assert_eq!(engine.redos, expected_redos);
1542 assert_eq!(engine.clip, None);
1543 assert_eq!(writer.buffer, "Not enough values on stack\n");
1544 }
1545
1546 #[test]
1549 fn test_copy_operation_copies_value() {
1550 let expected_items = parse_items(vec!["42 = x # comment"]);
1551 let expected_undos = vec![
1552 create_undo(1, vec![], vec!["42"]),
1553 ];
1554 let expected_redos = vec![];
1555 let mut engine = create_engine();
1556 let mut writer = BufferWriter::new();
1557 let mut stack = ValueStack::new(Vec::new());
1558 assert!(parse_line(&mut engine, &mut writer, &mut stack, "42 = x # comment").is_ok());
1559 assert!(parse_line(&mut engine, &mut writer, &mut stack, "copy").is_ok());
1560 assert_eq!(stack.items, expected_items);
1561 assert_eq!(engine.undos, expected_undos);
1562 assert_eq!(engine.redos, expected_redos);
1563 assert_eq!(engine.clip, Some(parse_value("42 # comment")));
1564 assert_eq!(writer.buffer, "");
1565 }
1566
1567 #[test]
1568 fn test_copy_operation_fails_cleanly() {
1569 let expected_items = vec![];
1570 let expected_undos = vec![];
1571 let expected_redos = vec![];
1572 let mut engine = create_engine();
1573 let mut writer = BufferWriter::new();
1574 let mut stack = ValueStack::new(Vec::new());
1575 assert!(parse_line(&mut engine, &mut writer, &mut stack, "copy").is_err());
1576 assert_eq!(stack.items, expected_items);
1577 assert_eq!(engine.undos, expected_undos);
1578 assert_eq!(engine.redos, expected_redos);
1579 assert_eq!(engine.clip, None);
1580 assert_eq!(writer.buffer, "Not enough values on stack\n");
1581 }
1582
1583 #[test]
1586 fn test_paste_operation_copies_value() {
1587 let expected_items = parse_items(vec!["42", "42"]);
1588 let expected_undos = vec![
1589 create_undo(1, vec![], vec!["42"]),
1590 create_undo(1, vec![], vec!["paste"]),
1591 ];
1592 let expected_redos = vec![];
1593 let mut engine = create_engine();
1594 let mut writer = BufferWriter::new();
1595 let mut stack = ValueStack::new(Vec::new());
1596 assert!(parse_line(&mut engine, &mut writer, &mut stack, "42").is_ok());
1597 assert!(parse_line(&mut engine, &mut writer, &mut stack, "copy").is_ok());
1598 assert!(parse_line(&mut engine, &mut writer, &mut stack, "paste").is_ok());
1599 assert_eq!(stack.items, expected_items);
1600 assert_eq!(engine.undos, expected_undos);
1601 assert_eq!(engine.redos, expected_redos);
1602 assert_eq!(engine.clip, Some(parse_value("42")));
1603 assert_eq!(writer.buffer, "");
1604 }
1605
1606 #[test]
1607 fn test_paste_operation_fails_cleanly() {
1608 let expected_items = parse_items(vec!["42"]);
1609 let expected_undos = vec![
1610 create_undo(1, vec![], vec!["42"]),
1611 ];
1612 let expected_redos = vec![];
1613 let mut engine = create_engine();
1614 let mut writer = BufferWriter::new();
1615 let mut stack = ValueStack::new(Vec::new());
1616 assert!(parse_line(&mut engine, &mut writer, &mut stack, "42").is_ok());
1617 assert!(parse_line(&mut engine, &mut writer, &mut stack, "paste").is_err());
1618 assert_eq!(stack.items, expected_items);
1619 assert_eq!(engine.undos, expected_undos);
1620 assert_eq!(engine.redos, expected_redos);
1621 assert_eq!(engine.clip, None);
1622 assert_eq!(writer.buffer, "No value on clipboard\n");
1623 }
1624
1625 #[test]
1628 fn test_single_undo_resets_previous_line() {
1629 let expected_items = parse_items(vec!["4", "5", "6"]);
1630 let expected_undos = vec![
1631 create_undo(3, vec![], vec!["4", "5", "6"]),
1632 ];
1633 let expected_redos = vec![
1634 create_undo(2, vec!["11"], vec!["add"]),
1635 ];
1636 let mut engine = create_engine();
1637 let mut writer = BufferWriter::new();
1638 let mut stack = ValueStack::new(Vec::new());
1639 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1640 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1641 assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo").is_ok());
1642 assert_eq!(stack.items, expected_items);
1643 assert_eq!(engine.undos, expected_undos);
1644 assert_eq!(engine.redos, expected_redos);
1645 assert_eq!(writer.buffer, "");
1646 }
1647
1648 #[test]
1649 fn test_double_undo_resets_previous_lines() {
1650 let expected_items = vec![];
1651 let expected_undos = vec![];
1652 let expected_redos = vec![
1653 create_undo(2, vec!["11"], vec!["add"]),
1654 create_undo(0, vec!["4", "5", "6"], vec!["4", "5", "6"]),
1655 ];
1656 let mut engine = create_engine();
1657 let mut writer = BufferWriter::new();
1658 let mut stack = ValueStack::new(Vec::new());
1659 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1660 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1661 assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo").is_ok());
1662 assert_eq!(stack.items, expected_items);
1663 assert_eq!(engine.undos, expected_undos);
1664 assert_eq!(engine.redos, expected_redos);
1665 assert_eq!(writer.buffer, "");
1666 }
1667
1668 #[test]
1669 fn test_single_undo_with_suffix_resets_previous_line() {
1670 let expected_items = parse_items(vec!["4", "30"]);
1671 let expected_undos = vec![
1672 create_undo(3, vec![], vec!["4", "5", "6"]),
1673 create_undo(1, vec!["5", "6"], vec!["mul"]),
1674 ];
1675 let expected_redos = vec![];
1676 let mut engine = create_engine();
1677 let mut writer = BufferWriter::new();
1678 let mut stack = ValueStack::new(Vec::new());
1679 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1680 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1681 assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo mul").is_ok());
1682 assert_eq!(stack.items, expected_items);
1683 assert_eq!(engine.undos, expected_undos);
1684 assert_eq!(engine.redos, expected_redos);
1685 assert_eq!(writer.buffer, "");
1686 }
1687
1688 #[test]
1689 fn test_double_undo_with_suffix_resets_previous_lines() {
1690 let expected_items = parse_items(vec!["1", "6"]);
1691 let expected_undos = vec![
1692 create_undo(3, vec![], vec!["1", "2", "3"]),
1693 create_undo(1, vec!["2", "3"], vec!["mul"]),
1694 ];
1695 let expected_redos = vec![];
1696 let mut engine = create_engine();
1697 let mut writer = BufferWriter::new();
1698 let mut stack = ValueStack::new(Vec::new());
1699 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1700 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1701 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1702 assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo mul").is_ok());
1703 assert_eq!(stack.items, expected_items);
1704 assert_eq!(engine.undos, expected_undos);
1705 assert_eq!(engine.redos, expected_redos);
1706 assert_eq!(writer.buffer, "");
1707 }
1708
1709 #[test]
1710 fn test_single_undo_with_prefix_resets_current_line() {
1711 let expected_items = parse_items(vec!["4", "11"]);
1712 let expected_undos = vec![
1713 create_undo(3, vec![], vec!["4", "5", "6"]),
1714 create_undo(1, vec!["5", "6"], vec!["add"]),
1715 ];
1716 let expected_redos = vec![
1717 create_undo(2, vec!["15"], vec!["add"]),
1718 ];
1719 let mut engine = create_engine();
1720 let mut writer = BufferWriter::new();
1721 let mut stack = ValueStack::new(Vec::new());
1722 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1723 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1724 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add undo").is_ok());
1725 assert_eq!(stack.items, expected_items);
1726 assert_eq!(engine.undos, expected_undos);
1727 assert_eq!(engine.redos, expected_redos);
1728 assert_eq!(writer.buffer, "");
1729 }
1730
1731 #[test]
1732 fn test_double_undo_with_prefix_resets_current_and_previous_lines() {
1733 let expected_items = parse_items(vec!["4", "5", "6"]);
1734 let expected_undos = vec![
1735 create_undo(3, vec![], vec!["4", "5", "6"]),
1736 ];
1737 let expected_redos = vec![
1738 create_undo(2, vec!["15"], vec!["add"]),
1739 create_undo(2, vec!["11"], vec!["add"]),
1740 ];
1741 let mut engine = create_engine();
1742 let mut writer = BufferWriter::new();
1743 let mut stack = ValueStack::new(Vec::new());
1744 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1745 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1746 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add undo undo").is_ok());
1747 assert_eq!(stack.items, expected_items);
1748 assert_eq!(engine.undos, expected_undos);
1749 assert_eq!(engine.redos, expected_redos);
1750 assert_eq!(writer.buffer, "");
1751 }
1752
1753 #[test]
1754 fn test_single_undo_with_prefix_and_suffix_resets_current_line() {
1755 let expected_items = parse_items(vec!["44"]);
1756 let expected_undos = vec![
1757 create_undo(3, vec![], vec!["4", "5", "6"]),
1758 create_undo(1, vec!["5", "6"], vec!["add"]),
1759 create_undo(1, vec!["4", "11"], vec!["mul"]),
1760 ];
1761 let expected_redos = vec![];
1762 let mut engine = create_engine();
1763 let mut writer = BufferWriter::new();
1764 let mut stack = ValueStack::new(Vec::new());
1765 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1766 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1767 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add undo mul").is_ok());
1768 assert_eq!(stack.items, expected_items);
1769 assert_eq!(engine.undos, expected_undos);
1770 assert_eq!(engine.redos, expected_redos);
1771 assert_eq!(writer.buffer, "");
1772 }
1773
1774 #[test]
1775 fn test_double_undo_with_prefix_and_suffix_resets_current_and_previous_lines() {
1776 let expected_items = parse_items(vec!["4", "30"]);
1777 let expected_undos = vec![
1778 create_undo(3, vec![], vec!["4", "5", "6"]),
1779 create_undo(1, vec!["5", "6"], vec!["mul"]),
1780 ];
1781 let expected_redos = vec![];
1782 let mut engine = create_engine();
1783 let mut writer = BufferWriter::new();
1784 let mut stack = ValueStack::new(Vec::new());
1785 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1786 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1787 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add undo undo mul").is_ok());
1788 assert_eq!(stack.items, expected_items);
1789 assert_eq!(engine.undos, expected_undos);
1790 assert_eq!(engine.redos, expected_redos);
1791 assert_eq!(writer.buffer, "");
1792 }
1793
1794 #[test]
1795 fn test_triple_undo_operation_fails_cleanly() {
1796 let expected_items = vec![];
1797 let expected_undos = vec![];
1798 let expected_redos = vec![
1799 create_undo(2, vec!["11"], vec!["add"]),
1800 create_undo(0, vec!["4", "5", "6"], vec!["4", "5", "6"]),
1801 ];
1802 let mut engine = create_engine();
1803 let mut writer = BufferWriter::new();
1804 let mut stack = ValueStack::new(Vec::new());
1805 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1806 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1807 assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo undo").is_err());
1808 assert_eq!(stack.items, expected_items);
1809 assert_eq!(engine.undos, expected_undos);
1810 assert_eq!(engine.redos, expected_redos);
1811 assert_eq!(writer.buffer, "Start of undo history\n");
1812 }
1813
1814 #[test]
1817 fn test_single_redo_operation_modifies_stack() {
1818 let expected_items = parse_items(vec!["4", "11"]);
1819 let expected_undos = vec![
1820 create_undo(3, vec![], vec!["4", "5", "6"]),
1821 create_undo(1, vec!["5", "6"], vec!["add"]),
1822 ];
1823 let expected_redos = vec![
1824 create_undo(2, vec!["15"], vec!["add"]),
1825 ];
1826 let mut engine = create_engine();
1827 let mut writer = BufferWriter::new();
1828 let mut stack = ValueStack::new(Vec::new());
1829 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1830 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1831 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1832 assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo").is_ok());
1833 assert!(parse_line(&mut engine, &mut writer, &mut stack, "redo").is_ok());
1834 assert_eq!(stack.items, expected_items);
1835 assert_eq!(engine.undos, expected_undos);
1836 assert_eq!(engine.redos, expected_redos);
1837 assert_eq!(writer.buffer, "");
1838 }
1839
1840 #[test]
1841 fn test_double_redo_operation_modifies_stack() {
1842 let expected_items = parse_items(vec!["15"]);
1843 let expected_undos = vec![
1844 create_undo(3, vec![], vec!["4", "5", "6"]),
1845 create_undo(1, vec!["5", "6"], vec!["add"]),
1846 create_undo(1, vec!["4", "11"], vec!["add"]),
1847 ];
1848 let expected_redos = vec![];
1849 let mut engine = create_engine();
1850 let mut writer = BufferWriter::new();
1851 let mut stack = ValueStack::new(Vec::new());
1852 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1853 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1854 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1855 assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo").is_ok());
1856 assert!(parse_line(&mut engine, &mut writer, &mut stack, "redo redo").is_ok());
1857 assert_eq!(stack.items, expected_items);
1858 assert_eq!(engine.undos, expected_undos);
1859 assert_eq!(engine.redos, expected_redos);
1860 assert_eq!(writer.buffer, "");
1861 }
1862
1863 #[test]
1864 fn test_single_redo_operation_with_prefix_fails_cleanly() {
1865 let expected_items = parse_items(vec!["4", "5", "6"]);
1866 let expected_undos = vec![
1867 create_undo(3, vec![], vec!["4", "5", "6"]),
1868 ];
1869 let expected_redos = vec![
1870 create_undo(2, vec!["15"], vec!["add"]),
1871 create_undo(2, vec!["11"], vec!["add"]),
1872 ];
1873 let mut engine = create_engine();
1874 let mut writer = BufferWriter::new();
1875 let mut stack = ValueStack::new(Vec::new());
1876 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1877 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1878 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1879 assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo").is_ok());
1880 assert!(parse_line(&mut engine, &mut writer, &mut stack, "mul redo 999").is_err());
1881 assert_eq!(stack.items, expected_items);
1882 assert_eq!(engine.undos, expected_undos);
1883 assert_eq!(engine.redos, expected_redos);
1884 assert_eq!(writer.buffer, "End of undo history\n");
1885 }
1886
1887 #[test]
1888 fn test_triple_redo_operation_fails_cleanly() {
1889 let expected_items = parse_items(vec!["15"]);
1890 let expected_undos = vec![
1891 create_undo(3, vec![], vec!["4", "5", "6"]),
1892 create_undo(1, vec!["5", "6"], vec!["add"]),
1893 create_undo(1, vec!["4", "11"], vec!["add"]),
1894 ];
1895 let expected_redos = vec![];
1896 let mut engine = create_engine();
1897 let mut writer = BufferWriter::new();
1898 let mut stack = ValueStack::new(Vec::new());
1899 assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1900 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1901 assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1902 assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo").is_ok());
1903 assert!(parse_line(&mut engine, &mut writer, &mut stack, "redo redo redo 999").is_err());
1904 assert_eq!(stack.items, expected_items);
1905 assert_eq!(engine.undos, expected_undos);
1906 assert_eq!(engine.redos, expected_redos);
1907 assert_eq!(writer.buffer, "End of undo history\n");
1908 }
1909
1910 #[test]
1913 fn test_variable_not_assigned_by_default() {
1914 let expected_items = vec![
1915 parse_item("1"),
1916 parse_item("2"),
1917 parse_item("3"),
1918 ];
1919 let expected_variables = HashMap::new();
1920 let mut engine = create_engine();
1921 let mut writer = BufferWriter::new();
1922 let mut stack = ValueStack::new(Vec::new());
1923 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1924 assert_eq!(stack.items, expected_items);
1925 assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
1926 }
1927
1928 #[test]
1929 fn test_variable_is_assigned_to_new_entry() {
1930 let expected_items = vec![
1931 parse_item("1"),
1932 parse_item("2 = foo"),
1933 parse_item("3"),
1934 ];
1935 let expected_variables = HashMap::from([
1936 (String::from("foo"), parse_value("2 = foo")),
1937 ]);
1938 let mut engine = create_engine();
1939 let mut writer = BufferWriter::new();
1940 let mut stack = ValueStack::new(Vec::new());
1941 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2").is_ok());
1942 assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_ok());
1943 assert!(parse_line(&mut engine, &mut writer, &mut stack, "3").is_ok());
1944 assert_eq!(stack.items, expected_items);
1945 assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
1946 }
1947
1948 #[test]
1949 fn test_variable_is_reassigned_to_new_entry() {
1950 let expected_items = vec![
1951 parse_item("1"),
1952 parse_item("2"),
1953 parse_item("3 = foo"),
1954 ];
1955 let expected_variables = HashMap::from([
1956 (String::from("foo"), parse_value("3 = foo")),
1957 ]);
1958 let mut engine = create_engine();
1959 let mut writer = BufferWriter::new();
1960 let mut stack = ValueStack::new(Vec::new());
1961 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2").is_ok());
1962 assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_ok());
1963 assert!(parse_line(&mut engine, &mut writer, &mut stack, "3").is_ok());
1964 assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_ok());
1965 assert_eq!(stack.items, expected_items);
1966 assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
1967 }
1968
1969 #[test]
1970 fn test_variable_is_replaced_with_same_name() {
1971 let expected_items = vec![
1972 parse_item("1"),
1973 parse_item("2"),
1974 parse_item("3 = foo"),
1975 ];
1976 let expected_variables = HashMap::from([
1977 (String::from("foo"), parse_value("3 = foo")),
1978 ]);
1979 let mut engine = create_engine();
1980 let mut writer = BufferWriter::new();
1981 let mut stack = ValueStack::new(Vec::new());
1982 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1983 assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_ok());
1984 assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_ok());
1985 assert_eq!(stack.items, expected_items);
1986 assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
1987 }
1988
1989 #[test]
1990 fn test_variable_is_replaced_with_new_name() {
1991 let expected_items = vec![
1992 parse_item("1"),
1993 parse_item("2"),
1994 parse_item("3 = bar"),
1995 ];
1996 let expected_variables = HashMap::from([
1997 (String::from("bar"), parse_value("3 = bar")),
1998 ]);
1999 let mut engine = create_engine();
2000 let mut writer = BufferWriter::new();
2001 let mut stack = ValueStack::new(Vec::new());
2002 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
2003 assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_ok());
2004 assert!(parse_line(&mut engine, &mut writer, &mut stack, "set bar").is_ok());
2005 assert_eq!(stack.items, expected_items);
2006 assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
2007 }
2008
2009 #[test]
2010 fn test_variable_assignment_fails_cleanly() {
2011 let expected_variables = HashMap::new();
2012 let mut engine = create_engine();
2013 let mut writer = BufferWriter::new();
2014 let mut stack = ValueStack::new(Vec::new());
2015 assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_err());
2016 assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
2017 assert_eq!(writer.buffer, "Not enough values on stack\n");
2018 }
2019
2020 #[test]
2021 fn test_variables_are_assigned_on_same_line() {
2022 let expected_items = vec![
2023 parse_item("1 = foo"),
2024 parse_item("2 = bar"),
2025 parse_item("3 = baz"),
2026 ];
2027 let expected_variables = HashMap::from([
2028 (String::from("foo"), parse_value("1 = foo")),
2029 (String::from("bar"), parse_value("2 = bar")),
2030 (String::from("baz"), parse_value("3 = baz")),
2031 ]);
2032 let mut engine = create_engine();
2033 let mut writer = BufferWriter::new();
2034 let mut stack = ValueStack::new(Vec::new());
2035 assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 = foo 2 = bar 3 = baz").is_ok());
2036 assert_eq!(stack.items, expected_items);
2037 assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
2038 }
2039
2040 #[test]
2043 fn test_prints_error_on_invalid_decimal() {
2044 let mut engine = create_engine();
2045 let mut writer = BufferWriter::new();
2046 let mut stack = ValueStack::new(Vec::new());
2047 assert!(parse_line(&mut engine, &mut writer, &mut stack, "xyz").is_err());
2048 assert_eq!(writer.buffer, "Invalid number or keyword: xyz\n");
2049 }
2050
2051 #[test]
2052 fn test_prints_error_on_invalid_hexadecimal() {
2053 let mut engine = create_engine();
2054 let mut writer = BufferWriter::new();
2055 let mut stack = ValueStack::new(Vec::new());
2056 engine.context.borrow_mut().set_hex();
2057 assert!(parse_line(&mut engine, &mut writer, &mut stack, "xyz").is_err());
2058 assert_eq!(writer.buffer, "Invalid number or keyword: xyz\n");
2059 }
2060
2061 #[test]
2062 fn test_shows_history_from_start() {
2063 let expected = "\
2064<==
2065111
2066222
2067333 444 555
2068666 777
2069...
2070";
2071 let mut engine = create_engine();
2072 let mut writer = BufferWriter::new();
2073 engine.redos.insert(0, create_undo(0, vec![], vec!["111"]));
2074 engine.redos.insert(0, create_undo(0, vec![], vec!["222"]));
2075 engine.redos.insert(0, create_undo(0, vec![], vec!["333", "444", "555"]));
2076 engine.redos.insert(0, create_undo(0, vec![], vec!["666", "777"]));
2077 engine.redos.insert(0, create_undo(0, vec![], vec!["888"]));
2078 engine.redos.insert(0, create_undo(0, vec![], vec!["999"]));
2079 assert!(engine.limit_history(&mut writer, 4).is_ok());
2080 assert_eq!(writer.buffer, indent_multiline(expected));
2081 }
2082
2083 #[test]
2084 fn test_shows_history_with_lower_limit() {
2085 let expected = "\
2086...
2087222
2088333 444 555 <==
2089666 777
2090888
2091...
2092";
2093 let mut engine = create_engine();
2094 let mut writer = BufferWriter::new();
2095 engine.undos.push(create_undo(0, vec![], vec!["111"]));
2096 engine.undos.push(create_undo(0, vec![], vec!["222"]));
2097 engine.undos.push(create_undo(0, vec![], vec!["333", "444", "555"]));
2098 engine.redos.insert(0, create_undo(0, vec![], vec!["666", "777"]));
2099 engine.redos.insert(0, create_undo(0, vec![], vec!["888"]));
2100 engine.redos.insert(0, create_undo(0, vec![], vec!["999"]));
2101 assert!(engine.limit_history(&mut writer, 2).is_ok());
2102 assert_eq!(writer.buffer, indent_multiline(expected));
2103 }
2104
2105 #[test]
2106 fn test_shows_history_with_equal_limit() {
2107 let expected = "\
2108111
2109222
2110333 444 555 <==
2111666 777
2112888
2113999
2114";
2115 let mut engine = create_engine();
2116 let mut writer = BufferWriter::new();
2117 engine.undos.push(create_undo(0, vec![], vec!["111"]));
2118 engine.undos.push(create_undo(0, vec![], vec!["222"]));
2119 engine.undos.push(create_undo(0, vec![], vec!["333", "444", "555"]));
2120 engine.redos.insert(0, create_undo(0, vec![], vec!["666", "777"]));
2121 engine.redos.insert(0, create_undo(0, vec![], vec!["888"]));
2122 engine.redos.insert(0, create_undo(0, vec![], vec!["999"]));
2123 assert!(engine.limit_history(&mut writer, 3).is_ok());
2124 assert_eq!(writer.buffer, indent_multiline(expected));
2125 }
2126
2127 #[test]
2128 fn test_shows_history_with_higher_limit() {
2129 let expected = "\
2130111
2131222
2132333 444 555 <==
2133666 777
2134888
2135999
2136";
2137 let mut engine = create_engine();
2138 let mut writer = BufferWriter::new();
2139 engine.undos.push(create_undo(0, vec![], vec!["111"]));
2140 engine.undos.push(create_undo(0, vec![], vec!["222"]));
2141 engine.undos.push(create_undo(0, vec![], vec!["333", "444", "555"]));
2142 engine.redos.insert(0, create_undo(0, vec![], vec!["666", "777"]));
2143 engine.redos.insert(0, create_undo(0, vec![], vec!["888"]));
2144 engine.redos.insert(0, create_undo(0, vec![], vec!["999"]));
2145 assert!(engine.limit_history(&mut writer, 4).is_ok());
2146 assert_eq!(writer.buffer, indent_multiline(expected));
2147 }
2148
2149 #[test]
2150 fn test_shows_history_to_end() {
2151 let expected = "\
2152...
2153333 444 555
2154666 777
2155888
2156999 <==
2157";
2158 let mut engine = create_engine();
2159 let mut writer = BufferWriter::new();
2160 engine.undos.push(create_undo(0, vec![], vec!["111"]));
2161 engine.undos.push(create_undo(0, vec![], vec!["222"]));
2162 engine.undos.push(create_undo(0, vec![], vec!["333", "444", "555"]));
2163 engine.undos.push(create_undo(0, vec![], vec!["666", "777"]));
2164 engine.undos.push(create_undo(0, vec![], vec!["888"]));
2165 engine.undos.push(create_undo(0, vec![], vec!["999"]));
2166 assert!(engine.limit_history(&mut writer, 4).is_ok());
2167 assert_eq!(writer.buffer, indent_multiline(expected));
2168 }
2169
2170 #[test]
2171 fn test_shows_stack_with_no_values() {
2172 let mut engine = create_engine();
2173 let mut writer = BufferWriter::new();
2174 let mut stack = ValueStack::new(Vec::new());
2175 assert!(engine.show_stack(&mut writer, &mut stack).is_ok());
2176 assert_eq!(writer.buffer, "");
2177 }
2178
2179 #[test]
2180 fn test_shows_stack_as_decimal() {
2181 let expected = "\
218299999
218399999 # integer value
218499999 = foo
218599999 = bar # integer value
2186 123.45
2187 123.45 # decimal value
2188 123.45 = baz
2189 123.45 = qux # decimal value
2190 3.142
2191 3.142 # decimal value
2192 3.142 = quux
2193 3.142 = quuux # decimal value
2194";
2195 let mut engine = create_engine();
2196 let mut writer = BufferWriter::new();
2197 let mut stack = ValueStack::new(Vec::new());
2198 stack.wrapped_push(parse_item("99999"));
2199 stack.wrapped_push(parse_item("99999 # integer value"));
2200 stack.wrapped_push(parse_item("99999 = foo"));
2201 stack.wrapped_push(parse_item("99999 = bar # integer value"));
2202 stack.wrapped_push(parse_item("123.45"));
2203 stack.wrapped_push(parse_item("123.45 # decimal value"));
2204 stack.wrapped_push(parse_item("123.45 = baz"));
2205 stack.wrapped_push(parse_item("123.45 = qux # decimal value"));
2206 stack.wrapped_push(parse_item("3.142"));
2207 stack.wrapped_push(parse_item("3.142 # decimal value"));
2208 stack.wrapped_push(parse_item("3.142 = quux"));
2209 stack.wrapped_push(parse_item("3.142 = quuux # decimal value"));
2210 assert!(engine.show_stack(&mut writer, &mut stack).is_ok());
2211 assert_eq!(writer.buffer, indent_multiline(expected));
2212 }
2213
2214 #[test]
2215 fn test_shows_stack_as_single_hexadecimal_no_sep() {
2216 let expected = "\
22170x7fffffff
22180x7fffffff # large value
22190x7fffffff = foo
22200x7fffffff = bar # large value
22210x00000001
22220x00000001 # small value
22230x00000001 = baz
22240x00000001 = qux # small value
2225";
2226 let mut engine = create_engine();
2227 let mut writer = BufferWriter::new();
2228 let mut stack = ValueStack::new(Vec::new());
2229 engine.context.borrow_mut().format = Format::Base16(0);
2230 engine.context.borrow_mut().sep = false;
2231 stack.wrapped_push(parse_item("2147483647"));
2232 stack.wrapped_push(parse_item("2147483647 # large value"));
2233 stack.wrapped_push(parse_item("2147483647 = foo"));
2234 stack.wrapped_push(parse_item("2147483647 = bar # large value"));
2235 stack.wrapped_push(parse_item("1"));
2236 stack.wrapped_push(parse_item("1 # small value"));
2237 stack.wrapped_push(parse_item("1 = baz"));
2238 stack.wrapped_push(parse_item("1 = qux # small value"));
2239 assert!(engine.show_stack(&mut writer, &mut stack).is_ok());
2240 assert_eq!(writer.buffer, indent_multiline(expected));
2241 }
2242
2243 #[test]
2244 fn test_shows_stack_as_double_hexadecimal_with_sep() {
2245 let expected = "\
22460x,00000001,00000000
22470x,00000001,00000000 # large value
22480x,00000001,00000000 = foo
22490x,00000001,00000000 = bar # large value
22500x,00000000,00000001
22510x,00000000,00000001 # small value
22520x,00000000,00000001 = baz
22530x,00000000,00000001 = qux # small value
2254";
2255 let mut engine = create_engine();
2256 let mut writer = BufferWriter::new();
2257 let mut stack = ValueStack::new(Vec::new());
2258 engine.context.borrow_mut().format = Format::Base16(0);
2259 engine.context.borrow_mut().sep = true;
2260 stack.wrapped_push(parse_item("4294967296"));
2261 stack.wrapped_push(parse_item("4294967296 # large value"));
2262 stack.wrapped_push(parse_item("4294967296 = foo"));
2263 stack.wrapped_push(parse_item("4294967296 = bar # large value"));
2264 stack.wrapped_push(parse_item("1"));
2265 stack.wrapped_push(parse_item("1 # small value"));
2266 stack.wrapped_push(parse_item("1 = baz"));
2267 stack.wrapped_push(parse_item("1 = qux # small value"));
2268 assert!(engine.show_stack(&mut writer, &mut stack).is_ok());
2269 assert_eq!(writer.buffer, indent_multiline(expected));
2270 }
2271
2272 #[test]
2273 fn test_shows_stack_with_lower_limit() {
2274 let expected = "\
2275_ ...
2276| 0.25 |
2277[ 0.375 ]
2278( 0.5 )
2279[ 0.625 ]
2280_ 0.75
2281_ 0.875
2282";
2283 let mut engine = create_engine();
2284 let mut writer = BufferWriter::new();
2285 let mut stack = ValueStack::new(Vec::new());
2286 stack.wrapped_push(parse_item("-0.25"));
2287 stack.wrapped_push(parse_item("-0.125"));
2288 stack.wrapped_push(parse_series(vec![
2289 "0",
2290 "0.125",
2291 "0.25",
2292 "0.375",
2293 ]));
2294 stack.wrapped_push(parse_series(vec![
2295 "0.5",
2296 "0.625",
2297 ]));
2298 stack.wrapped_push(parse_item("0.75"));
2299 stack.wrapped_push(parse_item("0.875"));
2300 assert!(engine.limit_stack(&mut writer, &mut stack, Some(6)).is_ok());
2301 assert_eq!(writer.buffer, replace_multiline(expected));
2302 }
2303
2304 #[test]
2305 fn test_shows_stack_with_equal_limit() {
2306 let expected = "\
2307_ -0.25
2308_ -0.125
2309( 0 )
2310| 0.125 |
2311| 0.25 |
2312[ 0.375 ]
2313( 0.5 )
2314[ 0.625 ]
2315_ 0.75
2316_ 0.875
2317";
2318 let mut engine = create_engine();
2319 let mut writer = BufferWriter::new();
2320 let mut stack = ValueStack::new(Vec::new());
2321 stack.wrapped_push(parse_item("-0.25"));
2322 stack.wrapped_push(parse_item("-0.125"));
2323 stack.wrapped_push(parse_series(vec![
2324 "0",
2325 "0.125",
2326 "0.25",
2327 "0.375",
2328 ]));
2329 stack.wrapped_push(parse_series(vec![
2330 "0.5",
2331 "0.625",
2332 ]));
2333 stack.wrapped_push(parse_item("0.75"));
2334 stack.wrapped_push(parse_item("0.875"));
2335 assert!(engine.limit_stack(&mut writer, &mut stack, Some(10)).is_ok());
2336 assert_eq!(writer.buffer, replace_multiline(expected));
2337 }
2338
2339 #[test]
2340 fn test_shows_stack_with_higher_limit() {
2341 let expected = "\
2342_ -0.25
2343_ -0.125
2344( 0 )
2345| 0.125 |
2346| 0.25 |
2347[ 0.375 ]
2348( 0.5 )
2349[ 0.625 ]
2350_ 0.75
2351_ 0.875
2352";
2353 let mut engine = create_engine();
2354 let mut writer = BufferWriter::new();
2355 let mut stack = ValueStack::new(Vec::new());
2356 stack.wrapped_push(parse_item("-0.25"));
2357 stack.wrapped_push(parse_item("-0.125"));
2358 stack.wrapped_push(parse_series(vec![
2359 "0",
2360 "0.125",
2361 "0.25",
2362 "0.375",
2363 ]));
2364 stack.wrapped_push(parse_series(vec![
2365 "0.5",
2366 "0.625",
2367 ]));
2368 stack.wrapped_push(parse_item("0.75"));
2369 stack.wrapped_push(parse_item("0.875"));
2370 assert!(engine.limit_stack(&mut writer, &mut stack, Some(12)).is_ok());
2371 assert_eq!(writer.buffer, replace_multiline(expected));
2372 }
2373
2374 #[test]
2375 fn test_shows_stack_with_no_limit() {
2376 let expected = "\
2377_ -0.25
2378_ -0.125
2379( 0 )
2380| 0.125 |
2381| 0.25 |
2382[ 0.375 ]
2383( 0.5 )
2384[ 0.625 ]
2385_ 0.75
2386_ 0.875
2387";
2388 let mut engine = create_engine();
2389 let mut writer = BufferWriter::new();
2390 let mut stack = ValueStack::new(Vec::new());
2391 stack.wrapped_push(parse_item("-0.25"));
2392 stack.wrapped_push(parse_item("-0.125"));
2393 stack.wrapped_push(parse_series(vec![
2394 "0",
2395 "0.125",
2396 "0.25",
2397 "0.375",
2398 ]));
2399 stack.wrapped_push(parse_series(vec![
2400 "0.5",
2401 "0.625",
2402 ]));
2403 stack.wrapped_push(parse_item("0.75"));
2404 stack.wrapped_push(parse_item("0.875"));
2405 assert!(engine.limit_stack(&mut writer, &mut stack, None).is_ok());
2406 assert_eq!(writer.buffer, replace_multiline(expected));
2407 }
2408
2409 #[test]
2410 fn test_shows_variables_sorted_by_name() {
2411 let expected = "\
24125 = five
24134 = four
24141 = one
24153 = three
24162 = two
2417";
2418 let mut engine = create_engine();
2419 let mut writer = BufferWriter::new();
2420 let mut stack = ValueStack::new(Vec::new());
2421 engine.interface.borrow_mut().insert_variable(String::from("one"), parse_value("1 = one"));
2422 engine.interface.borrow_mut().insert_variable(String::from("two"), parse_value("2 = two"));
2423 engine.interface.borrow_mut().insert_variable(String::from("three"), parse_value("3 = three"));
2424 engine.interface.borrow_mut().insert_variable(String::from("four"), parse_value("4 = four"));
2425 engine.interface.borrow_mut().insert_variable(String::from("five"), parse_value("5 = five"));
2426 assert!(parse_line(&mut engine, &mut writer, &mut stack, "set").is_ok());
2427 assert_eq!(writer.buffer, indent_multiline(expected));
2428 }
2429
2430 fn indent_multiline(lines: &str) -> String {
2431 lines.lines()
2432 .map(|x| format!(" {}\n", x))
2433 .collect::<Vec<String>>()
2434 .join("")
2435 }
2436
2437 fn replace_multiline(lines: &str) -> String {
2438 lines.lines()
2439 .map(|x| x.replace("_", " "))
2440 .map(|x| format!("{}\n", x))
2441 .collect::<Vec<String>>()
2442 .join("")
2443 }
2444
2445 fn create_engine() -> Engine<BufferWriter> {
2446 let config = Config::default();
2447 let chars = BracketChars {
2448 open: ('(', ')'),
2449 middle: ('|', '|'),
2450 close: ('[', ']'),
2451 };
2452 Engine::new(config, chars).unwrap().with_interact(true)
2453 }
2454
2455 fn parse_line(
2456 engine: &mut Engine<BufferWriter>,
2457 writer: &mut BufferWriter,
2458 stack: &mut ValueStack,
2459 line: &str,
2460 ) -> MyResult<()> {
2461 let result = engine.parse_line(writer, stack, line);
2462 if let Err(error) = &result {
2463 writeln!(writer, "{}", error)?;
2464 }
2465 result
2466 }
2467
2468 impl<W: Write> Engine<W> {
2469 pub fn with_interact(mut self, interact: bool) -> Self {
2470 self.interact = interact;
2471 self
2472 }
2473 }
2474}