From 72fb1f1a2c9a811839bf4aec6a72af20fff74dc6 Mon Sep 17 00:00:00 2001 From: Sameer Rahmani Date: Thu, 9 Jul 2020 13:52:46 +0100 Subject: [PATCH] Commit the final changes before moving to C++ :( --- src/compiler.rs | 185 ++++++++++++++++++++++++++--------------------- src/main.rs | 4 +- src/namespace.rs | 39 +++++----- 3 files changed, 120 insertions(+), 108 deletions(-) diff --git a/src/compiler.rs b/src/compiler.rs index 672e71e..27ee7d7 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -7,105 +7,122 @@ use crate::namespace::Namespace; use crate::types::Expression; use std::collections::HashMap; -pub fn create_compiler<'a, 'ctx>() -> Compiler<'a, 'ctx> { - let default_ns_name = "user"; - let context = Context::create(); - let builder = context.create_builder(); - let mut namespaces = HashMap::new(); - let user_ns = Namespace::new(&context, default_ns_name); - namespaces.insert(default_ns_name, &user_ns); - let fpm = PassManager::create(&user_ns.module); +// pub fn create_compiler<'ctx>() -> Compiler<'ctx> { +// let default_ns_name = "user"; +// // let builder = context.create_builder(); +// let context = Context::create(); +// //let user_ns = Namespace::new(&context, default_ns_name); +// //namespaces.insert(default_ns_name, &user_ns); +// // let fpm = PassManager::create(&user_ns.module); - fpm.add_instruction_combining_pass(); - fpm.add_reassociate_pass(); - fpm.add_gvn_pass(); - fpm.add_cfg_simplification_pass(); - fpm.add_basic_alias_analysis_pass(); - fpm.add_promote_memory_to_register_pass(); - fpm.add_instruction_combining_pass(); - fpm.add_reassociate_pass(); +// // fpm.add_instruction_combining_pass(); +// // fpm.add_reassociate_pass(); +// // fpm.add_gvn_pass(); +// // fpm.add_cfg_simplification_pass(); +// // fpm.add_basic_alias_analysis_pass(); +// // fpm.add_promote_memory_to_register_pass(); +// // fpm.add_instruction_combining_pass(); +// // fpm.add_reassociate_pass(); - fpm.initialize(); +// // fpm.initialize(); +// //, builder, fpm, namespaces, Some(&default_ns_name) +// //Compiler::new(context) +// let builder = context.create_builder(); +// Compiler { +// builder: builder, +// context: context, +// namespaces: HashMap::new(), +// } +// } - Compiler::new(context, builder, fpm, namespaces, Some(&default_ns_name)) -} - -pub struct Compiler<'a, 'ctx> { +pub struct Compiler<'ctx> { pub context: Context, pub builder: Builder<'ctx>, - /// This hashmap contains all the namespaces that has to be compiled and - /// maps two different keys to the same namespace. Since namespace names - /// can not contain `/` char, the keys of this map are the namespace - /// name and the path to the file containing the namespace. For example: - /// - /// A let's say we have a namespace `abc.xyz`, this namespace will have - /// two entries in this hashmap. One would be the ns name itself which - /// is `abc.xyz` in this case and the otherone would be - /// `/path/to/abc/xyz.srn` file that contains the ns. - pub namespaces: &'a HashMap<&'a str, &'a Namespace<'a, 'ctx>>, - pub fpm: &'a PassManager>, + // /// This hashmap contains all the namespaces that has to be compiled and + // /// maps two different keys to the same namespace. Since namespace names + // /// can not contain `/` char, the keys of this map are the namespace + // /// name and the path to the file containing the namespace. For example: + // /// + // /// A let's say we have a namespace `abc.xyz`, this namespace will have + // /// two entries in this hashmap. One would be the ns name itself which + // /// is `abc.xyz` in this case and the otherone would be + // /// `/path/to/abc/xyz.srn` file that contains the ns. + pub namespaces: HashMap<&'ctx str, Namespace<'ctx>>, + // pub fpm: &'a PassManager>, - current_ns_name: Option<&'a str>, + // current_ns_name: Option<&'a str>, } -impl<'a, 'ctx> Compiler<'a, 'ctx> { - pub fn new( - context: Context, - builder: Builder<'ctx>, - fpm: PassManager>, - namespaces: HashMap<&'a str, &'a Namespace<'a, 'ctx>>, - ns_name: Option<&'a str>, - ) -> Compiler<'a, 'ctx> { +impl<'ctx> Compiler<'ctx> { + pub fn new() -> Compiler<'ctx> { + let default_ns_name = "user"; + // let builder = context.create_builder(); + let context = Context::create(); + //let user_ns = Namespace::new(&context, default_ns_name); + //namespaces.insert(default_ns_name, &user_ns); + // let fpm = PassManager::create(&user_ns.module); + + // fpm.add_instruction_combining_pass(); + // fpm.add_reassociate_pass(); + // fpm.add_gvn_pass(); + // fpm.add_cfg_simplification_pass(); + // fpm.add_basic_alias_analysis_pass(); + // fpm.add_promote_memory_to_register_pass(); + // fpm.add_instruction_combining_pass(); + // fpm.add_reassociate_pass(); + + // fpm.initialize(); + //, builder, fpm, namespaces, Some(&default_ns_name) + //Compiler::new(context) + let builder = context.create_builder(); Compiler { - context: context, - namespaces: &namespaces, - fpm: &fpm, builder: builder, - current_ns_name: ns_name, + context: context, + namespaces: HashMap::new(), } } - #[inline] - pub fn current_ns(&self) -> Option<&'a Namespace<'a, 'ctx>> { - let ns = self.current_ns_name?; - self.namespaces.get(ns).map(|x| *x) - } - - /// Returns the `FunctionValue` representing the function being compiled. - #[inline] - pub fn current_fn(&self) -> FunctionValue<'ctx> { - self.current_ns().unwrap().current_fn() - } - - /// Creates a new stack allocation instruction in the entry block of the function. - // fn create_entry_block_alloca(&self, name: &str) -> PointerValue<'ctx> { - // let builder = self.context.create_builder(); - - // let entry = self.current_fn().get_first_basic_block().unwrap(); - - // match entry.get_first_instruction() { - // Some(first_instr) => builder.position_before(&first_instr), - // None => builder.position_at_end(entry), - // } - - // builder.build_alloca(self.context.f64_type(), name) + // #[inline] + // pub fn current_ns(&self) -> Option<&'a Namespace<'a, 'ctx>> { + // let ns = self.current_ns_name?; + // self.namespaces.get(ns).map(|x| *x) // } - pub fn compile( - &self, - exprs: Vec<&impl Expression<'ctx>>, - ) -> Vec, String>> { - let current_ns = match self.current_ns() { - Some(ns) => ns, - None => panic!("Current namespace is not set."), - }; + // /// Returns the `FunctionValue` representing the function being compiled. + // #[inline] + // pub fn current_fn(&self) -> FunctionValue<'ctx> { + // self.current_ns().unwrap().current_fn() + // } - let mut generated_code = vec![]; + // /// Creates a new stack allocation instruction in the entry block of the function. + // // fn create_entry_block_alloca(&self, name: &str) -> PointerValue<'ctx> { + // // let builder = self.context.create_builder(); - for expr in &exprs { - let code = expr.code_gen(current_ns); - generated_code.push(code); - } + // // let entry = self.current_fn().get_first_basic_block().unwrap(); - generated_code - } + // // match entry.get_first_instruction() { + // // Some(first_instr) => builder.position_before(&first_instr), + // // None => builder.position_at_end(entry), + // // } + + // // builder.build_alloca(self.context.f64_type(), name) + // // } + + // pub fn compile( + // &self, + // exprs: Vec<&impl Expression<'ctx>>, + // ) -> Vec, String>> { + // let current_ns = match self.current_ns() { + // Some(ns) => ns, + // None => panic!("Current namespace is not set."), + // }; + + // let mut generated_code = vec![]; + + // for expr in &exprs { + // let code = expr.code_gen(current_ns); + // generated_code.push(code); + // } + + // generated_code + // } } diff --git a/src/main.rs b/src/main.rs index f79f20d..69f4524 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,12 +13,10 @@ pub mod reader; pub mod scope; pub mod types; -use crate::compiler::create_compiler; - fn main() -> io::Result<()> { let yaml = load_yaml!("cli.yml"); let args = App::from(yaml).get_matches(); - let compiler = create_compiler(); + //let compiler = create_compiler(); if let Some(input) = args.value_of("INPUT") { let mut f = File::open(input)?; diff --git a/src/namespace.rs b/src/namespace.rs index 55564ec..4b0268a 100644 --- a/src/namespace.rs +++ b/src/namespace.rs @@ -3,36 +3,33 @@ use inkwell::context::Context; use inkwell::module::Module; use inkwell::values::FunctionValue; -pub struct Namespace<'a, 'ctx> { +pub struct Namespace<'ctx> { /// Each namespace in serene contains it's own LLVM module. You can /// think of modules as compilation units. Object files if you prefer. /// This way we should be able to hot swap the namespaces. pub module: Module<'ctx>, - - scope: Scope<'a>, - - // The option of the current function being compiled - current_fn_opt: Option>, + scope: Scope<'ctx>, + // // The option of the current function being compiled + // current_fn_opt: Option>, } -impl<'a, 'ctx> Namespace<'a, 'ctx> { - pub fn new(context: &'ctx Context, name: &str) -> Namespace<'a, 'ctx> { - let module = context.create_module(&name); +impl<'ctx> Namespace<'ctx> { + pub fn new(context: &'ctx Context, name: &str) -> Namespace<'ctx> { Namespace { - module: module, + module: context.create_module(&name), scope: Scope::new(None), - current_fn_opt: None, + // current_fn_opt: None, } } - /// Gets a defined function given its name. - #[inline] - pub fn get_function(&self, name: &str) -> Option> { - self.module.get_function(name) - } + // /// Gets a defined function given its name. + // #[inline] + // pub fn get_function(&self, name: &str) -> Option> { + // self.module.get_function(name) + // } - /// Returns the `FunctionValue` representing the function being compiled. - #[inline] - pub fn current_fn(&self) -> FunctionValue<'ctx> { - self.current_fn_opt.unwrap() - } + // /// Returns the `FunctionValue` representing the function being compiled. + // #[inline] + // pub fn current_fn(&self) -> FunctionValue<'ctx> { + // self.current_fn_opt.unwrap() + // } }