diff options
Diffstat (limited to 'src/semantic')
-rw-r--r-- | src/semantic/environment.rs | 33 | ||||
-rw-r--r-- | src/semantic/mod.rs | 3 | ||||
-rw-r--r-- | src/semantic/translate.rs | 39 | ||||
-rw-r--r-- | src/semantic/types.rs | 7 |
4 files changed, 82 insertions, 0 deletions
diff --git a/src/semantic/environment.rs b/src/semantic/environment.rs new file mode 100644 index 0000000..fab16b3 --- /dev/null +++ b/src/semantic/environment.rs @@ -0,0 +1,33 @@ +use std::collections::HashMap; +use std::hash::Hash; + +pub struct Environment<'a, T: 'a, U: 'a> { + pub parent: Option<&'a Environment<'a, T, U>>, + pub bindings: HashMap<T, U>, +} + +impl<'a, T: 'a, U: 'a> Environment<'a, T, U> + where T: Eq + Hash { + pub fn new(parent: Option<&'a Environment<'a, T, U>>) -> Environment<'a, T, U> { + Environment { + parent: parent, + bindings: HashMap::new(), + } + } + + pub fn add_binding(&mut self, key: T, value: U) { + self.bindings.insert(key, value); + } + + pub fn lookup(&self, key: &T) -> Option<&U> { + if let Some(v) = self.bindings.get(key) { + Some(v) + } + else if let Some(p) = self.parent { + p.lookup(key) + } + else { + None + } + } +} diff --git a/src/semantic/mod.rs b/src/semantic/mod.rs new file mode 100644 index 0000000..433a196 --- /dev/null +++ b/src/semantic/mod.rs @@ -0,0 +1,3 @@ +pub mod environment; +pub mod translate; +pub mod types; diff --git a/src/semantic/translate.rs b/src/semantic/translate.rs new file mode 100644 index 0000000..7bcd646 --- /dev/null +++ b/src/semantic/translate.rs @@ -0,0 +1,39 @@ +use ::ast::{self, WithLocation}; +use super::environment; +use super::types::Ty; + +#[derive(Debug)] +pub enum TypeError { + Unimplemented, +} + +type TypeEnvironment<'a> = environment::Environment<'a, String, Ty>; +pub type Result = ::std::result::Result<Ty, WithLocation<TypeError>>; + +pub fn translate(program: &ast::Program) -> Result { + trans_exp(TypeEnvironment::new(None), &*program.0) +} + +fn trans_exp<'a>(venv: TypeEnvironment<'a>, exp: &WithLocation<ast::Expression>) -> Result { + use ast::Expression::*; + + match &exp.value { + &Let(ref decls, ref body) => { + Err(WithLocation::new(TypeError::Unimplemented, exp.start, exp.end)) + }, + &UnaryOp(ref op, ref operand) => { + Err(WithLocation::new(TypeError::Unimplemented, exp.start, exp.end)) + }, + &BinOp(ref op, ref left, ref right) => { + Err(WithLocation::new(TypeError::Unimplemented, exp.start, exp.end)) + }, + &Number(_) => Ok(Ty::Int), + &String(_) => Ok(Ty::String), + &Name(ref name) => { + Err(WithLocation::new(TypeError::Unimplemented, exp.start, exp.end)) + }, + &Nil => { + Err(WithLocation::new(TypeError::Unimplemented, exp.start, exp.end)) + }, + } +} diff --git a/src/semantic/types.rs b/src/semantic/types.rs new file mode 100644 index 0000000..2d76387 --- /dev/null +++ b/src/semantic/types.rs @@ -0,0 +1,7 @@ +#[derive(Debug)] +pub enum Ty { + Int, + String, + Nil, + Unit, +} |