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)) +    } +}  | 
