rpg_compiler/compile/
mod.rs

1use std::{fs, thread};
2use std::cmp::max;
3use std::sync::Arc;
4use std::time::Duration;
5use simple_colors::Color;
6use spinner::{SpinnerBuilder, SpinnerHandle};
7use spinners::utils::spinner_data::SpinnerData;
8use crate::{Parser, rm_comments, Tokenizer};
9use crate::generator::Generator;
10use crate::type_checker::TypeChecker;
11use crate::user_output::CompileError;
12
13pub fn compile(file: &str) -> String {
14    let sp = ColoredSpinner::new("Reading input...".to_string());
15    let code = fs::read_to_string(file).expect_compile_error(&format!("{file} could not be found."));
16    let code = rm_comments(&code);
17    let code = code.trim();
18    sp.stop(); println!();
19    let sp = ColoredSpinner::new("Tokenizing...".to_string());
20    let mut tokens = Tokenizer::new(&code).tokenize();
21    sp.stop(); println!();
22    let sp = ColoredSpinner::new("Parsing...".to_string());
23    let parsed = Parser::new(&mut tokens).parse();
24    let parsed = Arc::new(parsed);
25    sp.stop(); println!();
26    let thread_parsed = parsed.clone();
27    let type_checker = thread::spawn(move || {
28        TypeChecker::new(&thread_parsed).check_types();
29    });
30    let sp = ColoredSpinner::new("Generating...".to_string());
31    let generated = Generator::new(&parsed).generate();
32    sp.stop(); println!();
33    type_checker.join().expect("Unable to join type-checker thread.");
34    generated
35}
36
37pub struct Config {
38    pub max_char: usize,
39    pub verbose: bool
40}
41
42pub unsafe fn compile_with_config(file: &str, conf: Config) -> String {
43    let sp = ColoredSpinner::new("Reading input...".to_string());
44    let max_char = conf.max_char;
45    let verbose = conf.verbose;
46    if max_char > 10 { println!("Cheater :(") }
47    crate::generator::MAX_CHAR = max_char;
48    crate::user_output::VERBOSE = verbose;
49    let code = fs::read_to_string(file).expect_compile_error(&format!("{file} could not be found."));
50    let code = rm_comments(&code);
51    let code = code.trim();
52    sp.stop(); println!();
53    let sp = ColoredSpinner::new("Tokenizing...".to_string());
54    let mut tokens = Tokenizer::new(&code).tokenize();
55    sp.stop(); println!();
56    let sp = ColoredSpinner::new("Parsing...".to_string());
57    let parsed = Parser::new(&mut tokens).parse();
58    let parsed = Arc::new(parsed);
59    sp.stop(); println!();
60    // if let Some(handler) = &handler { &handler.stop_parsing; }
61    // TODO: pb for type checker
62    let thread_parsed = parsed.clone();
63    let type_checker = thread::spawn(move || {
64        TypeChecker::new(&thread_parsed).check_types();
65    });
66    let sp = ColoredSpinner::new("Generating...".to_string());
67    let generated = Generator::new(&parsed).generate();
68    sp.stop(); println!();
69    // if let Some(handler) = &handler { &handler.stop_generating; }
70    type_checker.join().expect("Unable to join type-checker thread.");
71    generated
72}
73
74struct ColoredSpinner {
75    handle: SpinnerHandle,
76}
77
78impl ColoredSpinner {
79    /// Create a new spinner along with a message
80    ///
81    /// Returns a spinner
82    fn new(message: String) -> Self {
83        // Dots3
84        let spinner_data = SpinnerData {frames: vec![
85            "\x1b[34m⠋\x1b[0m",
86            "\x1b[34m⠙\x1b[0m",
87            "\x1b[34m⠚\x1b[0m",
88            "\x1b[34m⠞\x1b[0m",
89            "\x1b[34m⠖\x1b[0m",
90            "\x1b[34m⠦\x1b[0m",
91            "\x1b[34m⠴\x1b[0m",
92            "\x1b[34m⠲\x1b[0m",
93            "\x1b[34m⠳\x1b[0m",
94            "\x1b[34m⠓\x1b[0m"
95        ], interval: 80};
96        
97        let handle = SpinnerBuilder::new(message)
98            .spinner(spinner_data.frames.clone())
99            .step(Duration::from_millis(spinner_data.interval.into()))
100            .start();
101        
102        ColoredSpinner { handle }
103    }
104    
105    /// Update spinner's message
106    ///
107    /// Returns the String that is put in in case the sender could not send.
108    pub fn message(&self, message: String) -> Option<String> {
109        self.handle.update(message)
110    }
111    
112    /// Stop the spinner
113    pub fn stop(self) {
114        self.handle.close();
115    }
116}