Skip to main content

mist_api/
transpiler.rs

1/* 1:1 */
2use std::fs;
3/* 2:1 */
4use std::path::Path;
5/* 3:1 */
6use std::path::PathBuf;
7/* 4:1 */
8use std::process;
9/* 5:1 */
10use std::time;
11/* 6:1 */
12use std::env;
13/* 8:1 */
14use mist_parser::error;
15/* 9:1 */
16use crate::modules;
17/* 11:1 */
18pub fn build(force: bool) -> PathBuf {
19    /* 12:5 */
20    let start = time::Instant::now();
21    /* 14:5 */
22    let root = env::current_dir().expect("Unable to find project root");
23    /* 16:5 */
24    let src: PathBuf = root.join("src");
25    /* 17:5 */
26    let out: PathBuf = root.join(".mist/src");
27    /* 19:5 */
28    let master = modules::master_package(src.join("main.mist"), out.join("main.rs"));
29    /* 21:5 */
30    master.transpile(&out);
31    /* 23:5 */
32    let elapsed = start.elapsed();
33    /* 25:5 */
34    println!(
35        "\x1b[32m\nTranspile successful\x1b[0m in \x1b[34m{:.2?}\x1b[0m",
36        elapsed
37    );
38    /* 30:5 */
39    root
40} /* 33:1 */
41impl modules::Module {
42    /* 34:5 */
43    fn transpile(self: &Self, parent_dir: &PathBuf) -> String {
44        /* 35:9 */
45        let dir: PathBuf = self.output_dir(&parent_dir);
46        /* 36:9 */
47        let output_file: PathBuf = self.output_path(&parent_dir);
48        /* 38:9 */
49        let _ = fs::create_dir_all(&dir);
50        /* 40:9 */
51        let mut output: String = String::new();
52        /* 42:9 */
53        for child in &self.children {
54            /* 43:13 */
55            output.push_str(&child.transpile(&dir));
56        }
57        /* 46:9 */
58        if self.path.is_dir() {
59            /* 47:13 */
60            let res = fs::write(&output_file, output);
61            /* 49:13 */
62            if res.is_err() {
63                /* 50:17 */
64                eprintln!(
65                    "error: failed to write output {}\n  {}",
66                    output_file.display(),
67                    res.unwrap_err(),
68                );
69                /* 56:17 */
70                process::exit(1);
71            }
72        } else {
73            /* 59:13 */
74            transpile_file(&self.path, &output_file, &output);
75        }
76        /* 62:9 */
77        format!("pub mod {};\n", self.name)
78    }
79}
80/* 66:1 */
81fn transpile_file(path: &PathBuf, output_file: &PathBuf, mod_decl: &str) -> () {
82    /* 67:5 */
83    let source: String = match fs::read_to_string(path) {
84        /* 68:9 */
85        Ok(s) => s, /* 69:9 */
86
87        Err(e) => {
88            /* 70:13 */
89            eprintln!("error: failed to read file {}\n  {}", path.display(), e);
90            /* 72:13 */
91            process::exit(1);
92        }
93    };
94    /* 76:5 */
95    let mut gc = mist_codegen::RustCodegen::new();
96    /* 78:5 */
97    let output: String = gc.generate(match mist_parser::parse(&source) {
98        /* 79:9 */
99        Ok(ast) => ast, /* 80:9 */
100
101        Err(e) => {
102            /* 81:13 */
103            match e {
104                /* 82:17 */
105                error::ParseError::Ast(e) => {
106                    /* 83:21 */
107                    let start_pos = e.span.start_pos().line_col();
108                    /* 85:21 */
109                    let span = e.span.as_str();
110                    /* 87:21 */
111                    eprintln!(
112                        "\n{}:{}:{}\n \x1b[31mError\x1b[0m: {}\n\t{}{}\t{}",
113                        path.as_os_str().display(),
114                        start_pos.0,
115                        start_pos.1,
116                        e.error_message,
117                        span,
118                        if span.ends_with("\n") { "" } else { "\n" },
119                        "^".repeat(span.trim().len()),
120                    );
121                    /* 98:21 */
122                    process::exit(1);
123                } /* 101:17 */
124
125                error::ParseError::PreAst(e) => {
126                    /* 102:21 */
127                    eprintln!("error: parse failed in {}\n{}", path.display(), e);
128                    /* 104:21 */
129                    process::exit(1);
130                }
131            }
132        }
133    });
134    /* 110:5 */
135    let res = fs::write(&output_file, format!("{mod_decl}{output}"));
136    /* 112:5 */
137    if res.is_err() {
138        /* 113:9 */
139        eprintln!(
140            "error: failed to write output {}\n  {}",
141            output_file.display(),
142            res.unwrap_err(),
143        );
144        /* 119:9 */
145        process::exit(1);
146    }
147}