1mod cst_print;
2mod parser_print;
3mod print;
4
5use std::sync::LazyLock;
6use std::sync::Mutex;
7pub struct GlobalConfig {
8 pub indent_size: usize,
9}
10impl Default for GlobalConfig {
11 fn default() -> Self {
12 Self { indent_size: 4 }
13 }
14}
15pub static GLOBAL_DATA: LazyLock<Mutex<GlobalConfig>> =
16 LazyLock::new(|| Mutex::new(GlobalConfig::default()));
17
18pub use cst_print::pretty_print as pretty_print_cst;
20pub use parser_print::pretty_print;
22
23use clap::Parser;
24use mimium_lang::utils::error::report;
25use std::fs;
26use std::path::PathBuf;
27
28#[derive(Parser, Debug)]
29#[command(author, version, about, long_about = None)]
30pub struct Args {
31 #[clap(value_parser)]
33 file: Option<PathBuf>,
34 #[arg(long, default_value = "80")]
36 width: usize,
37 #[arg(long, default_value = "4")]
39 indent_size: usize,
40 #[arg(long)]
42 ast: bool,
43}
44
45pub fn lib_main() {
46 let args = Args::parse();
47
48 if let Ok(mut gdata) = GLOBAL_DATA.try_lock() {
49 gdata.indent_size = args.indent_size;
50 }
51
52 let file_path = args.file;
53 let code = match file_path.as_ref() {
54 Some(path) => fs::read_to_string(path).expect("Unable to read file"),
55 None => {
56 use std::io::Read;
57 let mut buf = String::new();
58 eprintln!("No file specified. Reading from stdin...");
59 std::io::stdin()
60 .read_to_string(&mut buf)
61 .expect("Unable to read from stdin");
62 buf
63 }
64 };
65
66 let res = if args.ast {
67 pretty_print(code.as_str(), &file_path, args.width)
68 } else {
69 pretty_print_cst(code.as_str(), &file_path, args.width)
70 };
71
72 match res {
73 Ok(rendered) => {
74 println!("{rendered}");
75 }
76 Err(errs) => {
77 report(code.as_str(), file_path.unwrap_or_default(), &errs);
78 }
79 }
80}