1 use winnow::prelude::*;
2 
3 mod parser;
4 mod parser_ast;
5 mod parser_lexer;
6 
main() -> Result<(), lexopt::Error>7 fn main() -> Result<(), lexopt::Error> {
8     let args = Args::parse()?;
9 
10     let input = args.input.as_deref().unwrap_or("1 + 1");
11     if let Err(err) = calc(input, args.implementation) {
12         println!("FAILED");
13         println!("{}", err);
14     }
15 
16     Ok(())
17 }
18 
calc( input: &str, imp: Impl, ) -> Result<(), winnow::error::ParseError<&str, winnow::error::ContextError>>19 fn calc(
20     input: &str,
21     imp: Impl,
22 ) -> Result<(), winnow::error::ParseError<&str, winnow::error::ContextError>> {
23     println!("{} =", input);
24     match imp {
25         Impl::Eval => {
26             let result = parser::expr.parse(input)?;
27             println!("  {}", result);
28         }
29         Impl::Ast => {
30             let result = parser_ast::expr.parse(input)?;
31             println!("  {:#?}={}", result, result.eval());
32         }
33         Impl::Lexer => {
34             let tokens = parser_lexer::lex.parse(input)?;
35             println!("  {:#?}", tokens);
36             let result = parser_lexer::expr.parse(tokens.as_slice()).unwrap();
37             println!("  {:#?}={}", result, result.eval());
38         }
39     }
40     Ok(())
41 }
42 
43 #[derive(Default)]
44 struct Args {
45     input: Option<String>,
46     implementation: Impl,
47 }
48 
49 enum Impl {
50     Eval,
51     Ast,
52     Lexer,
53 }
54 
55 impl Default for Impl {
default() -> Self56     fn default() -> Self {
57         Self::Eval
58     }
59 }
60 
61 impl Args {
parse() -> Result<Self, lexopt::Error>62     fn parse() -> Result<Self, lexopt::Error> {
63         use lexopt::prelude::*;
64 
65         let mut res = Args::default();
66 
67         let mut args = lexopt::Parser::from_env();
68         while let Some(arg) = args.next()? {
69             match arg {
70                 Long("impl") => {
71                     res.implementation = args.value()?.parse_with(|s| match s {
72                         "eval" => Ok(Impl::Eval),
73                         "ast" => Ok(Impl::Ast),
74                         "lexer" => Ok(Impl::Lexer),
75                         _ => Err("expected `eval`, `ast`"),
76                     })?;
77                 }
78                 Value(input) => {
79                     res.input = Some(input.string()?);
80                 }
81                 _ => return Err(arg.unexpected()),
82             }
83         }
84         Ok(res)
85     }
86 }
87