1use std::{collections::VecDeque, error::Error};
7
8use argparse::{ArgumentParser, Store, StoreTrue};
9
10mod error;
11mod lexer;
12mod parser;
13mod token;
14
15use parser::Parser;
16use token::TokenInfo;
17
18fn main() -> Result<(), Box<dyn Error>> {
31 let mut input_file = std::path::PathBuf::new();
32 let mut verbose: bool = false;
33
34 {
35 let mut arg_parser: ArgumentParser = ArgumentParser::new();
36 arg_parser.set_description("Parse your Anillo file");
37 arg_parser
38 .refer(&mut input_file)
39 .add_argument("input", Store, "anillo file to parse")
40 .required();
41 arg_parser.refer(&mut verbose).add_option(
42 &["--verbose"],
43 StoreTrue,
44 "Print in progress Lexer, parser, and AST state",
45 );
46
47 arg_parser.parse_args_or_exit();
48 }
49
50 if let Some(ext) = input_file.extension()
51 && let Some(ext_str) = ext.to_str()
52 && ext_str == "ani"
53 {
54 println!("Parsing input: {}", input_file.display());
55 } else {
56 eprintln!(
57 "Not an anillo file ending in '.ani': {}",
58 input_file.display()
59 );
60 return Err(Box::new(std::io::Error::new(
61 std::io::ErrorKind::NotFound,
62 "Not an anillo file ending in '.ani'",
63 )));
64 }
65
66 let mut lexer = lexer::Lexer::new(&input_file)?;
67 let tokens: VecDeque<TokenInfo> = lexer.tokenize()?;
68 let mut parser = Parser::new(tokens);
69
70 if verbose {
71 println!(
72 "********************************************************************************"
73 );
74 println!("Starting token buffer:");
75 dbg!(&parser);
76 println!(
77 "********************************************************************************"
78 );
79 }
80
81 let ast = parser.run(verbose)?;
82
83 if verbose {
84 println!(
85 "********************************************************************************"
86 );
87 println!("Final AST:");
88 dbg!(&ast);
89 println!(
90 "********************************************************************************"
91 );
92 }
93
94 ast.verify()?;
95 println!("{} passed verification!", input_file.display());
96
97 Ok(())
98}