diff options
-rw-r--r-- | src/main.rs | 4 | ||||
-rw-r--r-- | src/semantic/analysis.rs | 61 | ||||
-rw-r--r-- | src/semantic/ir.rs | 3 | ||||
-rw-r--r-- | src/semantic/translate.rs | 27 |
4 files changed, 71 insertions, 24 deletions
diff --git a/src/main.rs b/src/main.rs index 0579fc8..a8114ac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ fn main() { let stdin = io::stdin(); let mut handle = stdin.lock(); loop { + let mut translate = semantic::translate::Translate::new(); let mut input = String::new(); print!("taiga> "); io::stdout().flush().unwrap(); @@ -21,7 +22,8 @@ fn main() { let program = taiga::parse_Program(&input); println!("{:?}", program); if let Ok(program) = program { - println!("{:?}", semantic::analysis::translate(&program)); + let result = semantic::analysis::translate(&mut translate, &program); + println!("{:?}", result); } } else { diff --git a/src/semantic/analysis.rs b/src/semantic/analysis.rs index 21a9eb8..edc229f 100644 --- a/src/semantic/analysis.rs +++ b/src/semantic/analysis.rs @@ -5,6 +5,7 @@ use ::ast::{self, WithLocation}; use super::environment; +use super::translate::{self, Translate}; use super::types::{self, Ty}; #[derive(Debug)] @@ -22,14 +23,15 @@ pub enum TypeError { } type TypeEnvironment<'a> = environment::Environment<'a, String, Ty>; -pub type Result = ::std::result::Result<Ty, WithLocation<TypeError>>; +pub type Result<T> = ::std::result::Result<T, WithLocation<TypeError>>; -pub fn translate(program: &ast::Program) -> Result { +pub fn translate(translate: &mut Translate, program: &ast::Program) + -> Result<(translate::Expression, Ty)> { let mut venv = TypeEnvironment::new(None); let mut tenv = TypeEnvironment::new(None); tenv.add_binding("int".into(), Ty::Int); tenv.add_binding("string".into(), Ty::String); - trans_exp(&mut venv, &mut tenv, &*program.0) + trans_exp(translate, &mut venv, &mut tenv, &*program.0) } macro_rules! err { @@ -41,7 +43,7 @@ macro_rules! err { fn trans_ty<'a>( venv: &mut TypeEnvironment<'a>, tenv: &mut TypeEnvironment<'a>, - ty: &WithLocation<ast::Ty>) -> Result { + ty: &WithLocation<ast::Ty>) -> Result<Ty> { match ty.value { ast::Ty::Name(ref name) => { tenv.lookup(&name) @@ -64,9 +66,10 @@ fn trans_ty<'a>( } fn trans_decl<'a>( + tr: &mut Translate, venv: &mut TypeEnvironment<'a>, tenv: &mut TypeEnvironment<'a>, - decl: &WithLocation<ast::Declaration>) -> Result { + decl: &WithLocation<ast::Declaration>) -> Result<Ty> { match decl.declaration { ast::DeclarationBody::Fun { ref ty, ref params, ref body } => { let declared_ty = if let &Some(ref ty) = ty { @@ -82,7 +85,8 @@ fn trans_decl<'a>( new_venv.add_binding(param.name.value.clone(), arg_ty); } - let body_ty = trans_exp(&mut new_venv, &mut new_tenv, &*body)?; + let (body_exp, body_ty) = + trans_exp(tr, &mut new_venv, &mut new_tenv, &*body)?; if let Some(decl_ty) = declared_ty { if &decl_ty.value != &body_ty { @@ -99,7 +103,8 @@ fn trans_decl<'a>( trans_ty(venv, tenv, ty) } ast::DeclarationBody::Var { ref ty, ref value } => { - let actual_ty = trans_exp(venv, tenv, &value)?; + let (var_exp, actual_ty) = + trans_exp(tr, venv, tenv, &value)?; if let &Some(ref ty) = ty { let decl_ty = trans_ty(venv, tenv, &ty)?; if decl_ty != actual_ty { @@ -115,9 +120,11 @@ fn trans_decl<'a>( } fn trans_exp<'a>( + tr: &mut Translate, venv: &mut TypeEnvironment<'a>, tenv: &mut TypeEnvironment<'a>, - exp: &WithLocation<ast::Expression>) -> Result { + exp: &WithLocation<ast::Expression>) + -> Result<(translate::Expression, Ty)> { use ast::Expression::*; match &exp.value { @@ -125,7 +132,7 @@ fn trans_exp<'a>( let mut new_venv = TypeEnvironment::new(Some(venv)); let mut new_tenv = TypeEnvironment::new(Some(tenv)); for decl in decls.iter() { - let decl_ty = trans_decl(&mut new_venv, &mut new_tenv, decl)?; + let decl_ty = trans_decl(tr, &mut new_venv, &mut new_tenv, decl)?; match decl.declaration { ast::DeclarationBody::Fun { .. } | ast::DeclarationBody::Var { .. } => { new_venv.add_binding(decl.name.clone(), decl_ty); @@ -135,12 +142,12 @@ fn trans_exp<'a>( } } } - trans_exp(&mut new_venv, &mut new_tenv, &*body) + trans_exp(tr, &mut new_venv, &mut new_tenv, &*body) }, &Call(ref name, ref args) => { let mut arg_types = vec![]; for arg in args { - arg_types.push(trans_exp(venv, tenv, arg)?); + arg_types.push(trans_exp(tr, venv, tenv, arg)?); } let fun_ty = venv.lookup(name) @@ -154,7 +161,7 @@ fn trans_exp<'a>( actual: arg_types.len(), }); } - for (i, (provided_ty, expected_ty)) in + for (i, (&(_, ref provided_ty), expected_ty)) in arg_types.iter().zip(expected_args).enumerate() { if provided_ty != expected_ty { return err!(args[i], TypeError::Mismatch { @@ -163,12 +170,15 @@ fn trans_exp<'a>( }) } } - Ok((**result).clone()) + err!(exp, TypeError::Unimplemented) + // Ok((**result).clone()) }, otherwise => { err!(exp, TypeError::Mismatch { // TODO: better way to handle this - expected: Ty::Function(arg_types, Box::new(Ty::Nil)), + expected: Ty::Function( + arg_types.into_iter().map(|v| v.1).collect(), + Box::new(Ty::Nil)), actual: otherwise.clone(), }) } @@ -176,12 +186,13 @@ fn trans_exp<'a>( }, &UnaryOp(ref op, ref operand) => { use ast::UnaryOp::*; - let operand_ty = trans_exp(venv, tenv, operand)?; + let (operand_exp, operand_ty) = trans_exp(tr, venv, tenv, operand)?; match op { &Neg | &Pos => { match operand_ty { Ty::Int => { - Ok(Ty::Int) + err!(exp, TypeError::Unimplemented) + // Ok(Ty::Int) } other => { err!(operand, TypeError::Mismatch { @@ -198,16 +209,18 @@ fn trans_exp<'a>( }, &BinOp(ref op, ref left, ref right) => { use ast::BinOp::*; - let left_ty = trans_exp(venv, tenv, left)?; - let right_ty = trans_exp(venv, tenv, right)?; + let (left_exp, left_ty) = trans_exp(tr, venv, tenv, left)?; + let (right_exp, right_ty) = trans_exp(tr, venv, tenv, right)?; match op { &Add => { match (left_ty, right_ty) { (Ty::Int, Ty::Int) => { - Ok(Ty::Int) + err!(exp, TypeError::Unimplemented) + // Ok(Ty::Int) } (Ty::String, Ty::String) => { - Ok(Ty::String) + err!(exp, TypeError::Unimplemented) + // Ok(Ty::String) } (Ty::Int, other) | (other, Ty::Int) => { err!(right, TypeError::Mismatch { @@ -231,11 +244,13 @@ fn trans_exp<'a>( } } }, - &Number(_) => Ok(Ty::Int), - &String(_) => Ok(Ty::String), + &Number(n) => Ok((tr.make_num(n), Ty::Int)), + &String(_) => err!(exp, TypeError::Unimplemented), + // &String(_) => Ok(Ty::String), &Name(ref name) => { if let Some(ty) = venv.lookup(name) { - Ok(ty.clone()) + err!(exp, TypeError::Unimplemented) + // Ok(ty.clone()) } else { err!(exp, TypeError::UnboundName) diff --git a/src/semantic/ir.rs b/src/semantic/ir.rs index deeed96..be358c4 100644 --- a/src/semantic/ir.rs +++ b/src/semantic/ir.rs @@ -1,9 +1,11 @@ use super::temp; +#[derive(Debug)] pub enum Binop { Plus, } +#[derive(Debug)] pub enum Expression { Const(u64), Name(temp::TempLabel), @@ -14,6 +16,7 @@ pub enum Expression { Seq(Vec<Statement>, Box<Expression>), } +#[derive(Debug)] pub enum Statement { Exp(Expression), MoveTemp(temp::TempName, Expression), diff --git a/src/semantic/translate.rs b/src/semantic/translate.rs index e69de29..cc5aec0 100644 --- a/src/semantic/translate.rs +++ b/src/semantic/translate.rs @@ -0,0 +1,27 @@ +use super::ir; + +#[derive(Debug)] +pub enum Expression { + Exp(ir::Expression), + Void(ir::Statement), +} + +pub struct Translate { + +} + +pub enum Level { + Top, + Level, +} + +impl Translate { + pub fn new() -> Translate { + Translate { + } + } + + pub fn make_num(&mut self, num: u64) -> Expression { + Expression::Exp(ir::Expression::Const(num)) + } +} |