pipeline_script/core/
engine.rs

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