diff options
author | Griffin Smith <root@gws.fyi> | 2021-03-14T02·57-0500 |
---|---|---|
committer | Griffin Smith <root@gws.fyi> | 2021-03-14T03·07-0500 |
commit | 32a5c0ff0fc58aa6721c1e0ad41950bde2d66744 (patch) | |
tree | ef5dcf5234c2a86607ee2f8f30db73bad016e075 /src/common/env.rs | |
parent | f8beda81fbe8d04883aee71ff4ea078f897c6de4 (diff) |
Add the start of a hindley-milner typechecker
The beginning of a parse-don't-validate-based hindley-milner typechecker, which returns on success an IR where every AST node trivially knows its own type, and using those types to determine LLVM types in codegen.
Diffstat (limited to 'src/common/env.rs')
-rw-r--r-- | src/common/env.rs | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/common/env.rs b/src/common/env.rs index f499323639e3..59a5e46c466f 100644 --- a/src/common/env.rs +++ b/src/common/env.rs @@ -1,19 +1,25 @@ +use std::borrow::Borrow; use std::collections::HashMap; +use std::hash::Hash; use std::mem; -use crate::ast::Ident; - /// A lexical environment #[derive(Debug, PartialEq, Eq)] -pub struct Env<'ast, V>(Vec<HashMap<&'ast Ident<'ast>, V>>); +pub struct Env<K: Eq + Hash, V>(Vec<HashMap<K, V>>); -impl<'ast, V> Default for Env<'ast, V> { +impl<K, V> Default for Env<K, V> +where + K: Eq + Hash, +{ fn default() -> Self { Self::new() } } -impl<'ast, V> Env<'ast, V> { +impl<K, V> Env<K, V> +where + K: Eq + Hash, +{ pub fn new() -> Self { Self(vec![Default::default()]) } @@ -34,11 +40,15 @@ impl<'ast, V> Env<'ast, V> { *self = saved; } - pub fn set(&mut self, k: &'ast Ident<'ast>, v: V) { + pub fn set(&mut self, k: K, v: V) { self.0.last_mut().unwrap().insert(k, v); } - pub fn resolve<'a>(&'a self, k: &'ast Ident<'ast>) -> Option<&'a V> { + pub fn resolve<'a, Q>(&'a self, k: &Q) -> Option<&'a V> + where + K: Borrow<Q>, + Q: Hash + Eq + ?Sized, + { for ctx in self.0.iter().rev() { if let Some(res) = ctx.get(k) { return Some(res); |