rpg_compiler/compile/
mod.rs1use 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 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 type_checker.join().expect("Unable to join type-checker thread.");
71 generated
72}
73
74struct ColoredSpinner {
75 handle: SpinnerHandle,
76}
77
78impl ColoredSpinner {
79 fn new(message: String) -> Self {
83 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 pub fn message(&self, message: String) -> Option<String> {
109 self.handle.update(message)
110 }
111
112 pub fn stop(self) {
114 self.handle.close();
115 }
116}