pipeline_script/core/
engine.rs1use 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 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 let lexer = Lexer::from_script("main", &s);
96 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 let mut compiler = Compiler::new(module.clone());
139 for (name, value) in self.builtin_symbol.iter() {
140 compiler.register_builtin_symbol(name, value.clone());
141 }
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 let llvm_module = compiler.compile(&ctx);
156 let llvm_module = llvm_module.read().unwrap();
157 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}