pipeline_script/core/
engine.rs

1use ariadne::{ColorGenerator, Fmt, Label, Report, ReportKind, Source};
2
3use crate::ast::r#type::Type;
4use crate::compiler::Compiler;
5use crate::context::Context;
6use crate::core::builtin::println;
7use crate::core::error::Error;
8use crate::lexer::Lexer;
9use crate::llvm::builder::lljit::LLJITBuilder;
10use crate::llvm::context::LLVMContext;
11use crate::llvm::value::LLVMValue;
12use crate::parser::Parser;
13use crate::postprocessor::{r#type::TypePostprocessor, run_visitor, DynVisitor, Stage, Visitor};
14use crate::preprocessor::{ImportPreprocessor, Preprocessor};
15use std::collections::HashMap;
16use std::ffi::c_void;
17use std::fs;
18use std::path::{Path, PathBuf};
19
20pub struct Engine {
21    prelude_scripts: Vec<String>,
22    preprocessors: Vec<Box<dyn Preprocessor>>,
23    function_map: HashMap<String, *const c_void>,
24    visitors: Vec<Box<dyn DynVisitor>>,
25    builtin_symbol_types: HashMap<String, Type>,
26    builtin_symbol: HashMap<String, LLVMValue>,
27    // builtin_llvm_functions: HashMap<String, LLVMValue>,
28    pub test_llvm: bool,
29    pub test_llvm_files: Vec<PathBuf>,
30}
31impl Default for Engine {
32    fn default() -> Self {
33        Self {
34            prelude_scripts: vec![],
35            preprocessors: vec![Box::new(ImportPreprocessor)],
36            visitors: vec![],
37            function_map: HashMap::new(),
38            builtin_symbol_types: HashMap::new(),
39            test_llvm: false,
40            test_llvm_files: vec![],
41            builtin_symbol: HashMap::new(),
42        }
43    }
44}
45
46impl Engine {
47    pub fn run_llvm_file(&self, path: impl AsRef<Path>) {
48        let r = fs::read_to_string(path.as_ref()).unwrap();
49        let ctx = LLVMContext::with_mc_jit();
50        let module = ctx.parse_ir(&r).unwrap();
51        let executor = module.create_executor().unwrap();
52        let println_function = module.get_function_ref("println");
53        executor.add_global_mapping(println_function, println as *mut c_void);
54        executor.run_function("$Module.main", &mut []);
55    }
56    pub fn run_file(&mut self, path: impl AsRef<Path>) {
57        let r = fs::read_to_string(path.as_ref()).unwrap();
58        self.run_script(r);
59    }
60    pub fn set_test_llvm(&mut self, test: bool) {
61        self.test_llvm = test;
62    }
63    pub fn add_test_llvm_file(&mut self, path: impl AsRef<Path>) {
64        self.test_llvm_files.push(path.as_ref().to_path_buf());
65    }
66    pub fn register_external_function(&mut self, name: impl Into<String>, f: *const c_void) {
67        self.function_map.insert(name.into(), f);
68    }
69    pub fn register_builtin_symbol_type(&mut self, name: impl Into<String>, ty: Type) {
70        self.builtin_symbol_types.insert(name.into(), ty);
71    }
72    pub fn register_builtin_symbol(&mut self, name: impl Into<String>, value: LLVMValue) {
73        self.builtin_symbol.insert(name.into(), value);
74    }
75    pub fn register_visitor(&mut self, visitor: impl Visitor + 'static) {
76        self.visitors.push(Box::new(visitor));
77    }
78    pub fn register_preprocessor(&mut self, preprocessor: impl Preprocessor + 'static) {
79        self.preprocessors.push(Box::new(preprocessor));
80    }
81    pub fn register_precluded_scripts(&mut self, scripts: &[&str]) {
82        for script in scripts {
83            self.prelude_scripts.push(script.to_string());
84        }
85    }
86    pub fn run_script(&mut self, script: impl AsRef<str>) {
87        let mut s = script.as_ref().to_string();
88        for i in self.prelude_scripts.iter() {
89            s = format!("{}\n{}", i, s)
90        }
91        for preprocessor in &mut self.preprocessors {
92            s = preprocessor.process(&s)
93        }
94        // 分词
95        let lexer = Lexer::from_script("main", &s);
96        // 解析
97        let ctx = Context::background();
98        let ctx = Context::with_module_slot_map(&ctx, Default::default());
99        let mut parser = Parser::new(lexer, &ctx);
100        let module_key = parser
101            .parse(&ctx)
102            .inspect_err(|e| {
103                let mut colors = ColorGenerator::new();
104                match &e {
105                    Error::UnexpectedToken(actual, expect, pos) => Report::build(
106                        ReportKind::Error,
107                        (pos.module_name.as_str(), pos.pos..(pos.pos + pos.span)),
108                    )
109                    .with_message(format!("期待{expect},实际上是{actual}"))
110                    .with_label(
111                        Label::new((pos.module_name.as_str(), pos.pos..(pos.pos + pos.span)))
112                            .with_message(format!("需要 {}", expect.fg(colors.next()))),
113                    )
114                    .finish()
115                    .eprint((pos.module_name.as_str(), &Source::from(&s)))
116                    .unwrap(),
117                    t => {
118                        dbg!(t);
119                    }
120                }
121            })
122            .unwrap();
123        ctx.apply_mut_module(module_key, |module| {
124            for i in self
125                .visitors
126                .iter()
127                .filter(|i| i.stage() == Stage::BeforeTypeInfer)
128            {
129                run_visitor(module, &**i)
130            }
131        });
132        let mut type_preprocessor = TypePostprocessor::new();
133        for (name, ty) in self.builtin_symbol_types.iter() {
134            type_preprocessor.register_builtin_symbol_type(name, ty.clone());
135        }
136
137        let module = type_preprocessor.process(module_key, &ctx);
138        // dbg!(&module);
139        let mut compiler = Compiler::new(module.clone());
140        for (name, value) in self.builtin_symbol.iter() {
141            compiler.register_builtin_symbol(name, value.clone());
142        }
143        ctx.register_module(module);
144        ctx.apply_mut_module(module_key, |module| {
145            for i in self
146                .visitors
147                .iter()
148                .filter(|i| i.stage() == Stage::AfterTypeInfer)
149            {
150                run_visitor(module, &**i)
151            }
152        });
153
154        //编译
155        let llvm_module = compiler.compile(&ctx);
156        let llvm_module = llvm_module.read().unwrap();
157        // llvm_module.verify_with_debug_info();
158        // llvm_module.dump();
159        let jit = LLJITBuilder::new().create_lljit();
160        let safe_module = llvm_module.create_thread_safe_module();
161        match unsafe { jit.add_main_dylib_llvm_ir_module(safe_module) } {
162            Ok(_) => {}
163            Err(e) => {
164                println!("{}", e);
165            }
166        }
167        for (name, f) in &self.function_map {
168            jit.define_main_dylib_symbol(name, *f as u64);
169        }
170        let main = jit.lookup("$Module.main").unwrap();
171        let func: extern "C" fn() = unsafe { std::mem::transmute(main) };
172        func();
173    }
174}