diff --git a/src/compiler.rs b/src/compiler.rs index cf6fea7..3cc5901 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -64,7 +64,7 @@ pub struct Compiler<'ctx> { // /// 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>, + //pub fpm: &'a PassManager>, // current_ns_name: Option<&'a str>, } diff --git a/src/namespace.rs b/src/namespace.rs index ddf73c0..d149d04 100644 --- a/src/namespace.rs +++ b/src/namespace.rs @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -use crate::scope::Scope; +//use crate::scope::Scope; use inkwell::context::Context; use inkwell::module::Module; use inkwell::values::FunctionValue; @@ -24,28 +24,29 @@ pub struct Namespace<'ctx> { /// 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<'ctx>, - // // 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<'ctx> Namespace<'ctx> { pub fn new(context: &'ctx Context, name: &str) -> Namespace<'ctx> { Namespace { module: context.create_module(&name), - scope: Scope::new(None), - // current_fn_opt: None, + //scope: Scope::new(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) - // } + /// Get 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() - // } + /// Return the `FunctionValue` representing the function being compiled. + #[inline] + pub fn current_fn(&self) -> FunctionValue<'ctx> { + self.current_fn_opt.unwrap() + } } diff --git a/src/scope.rs b/src/scope.rs index a7e0d81..b71a00a 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -17,6 +17,9 @@ use inkwell::values::PointerValue; use std::collections::HashMap; +/// Scopes in **Serene** are simply represented by hashmaps. Each +/// Scope optionally has a parent scope that lookups fallback to +/// if the lookup key is missing from the current scope. pub struct Scope<'a> { parent: Option>>, symbol_table: HashMap>, @@ -35,8 +38,18 @@ impl<'a> Scope<'a> { } } + /// Lookup the given `key` in the scope and if it is not in the current + /// scope look it up in the `parent` scope. pub fn lookup(&self, key: &str) -> Option { - self.symbol_table.get(key).map(|x| *x) + let v = self.symbol_table.get(key); + + if let None = v { + return match &self.parent { + Some(x) => x.lookup(key), + None => None, + }; + } + v.map(|x| *x) } pub fn insert(&mut self, key: &str, val: PointerValue<'a>) {