diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 3 | ||||
| -rw-r--r-- | src/semantic/analysis.rs | 37 | ||||
| -rw-r--r-- | src/semantic/frame.rs | 7 | ||||
| -rw-r--r-- | src/semantic/translate.rs | 28 | 
4 files changed, 58 insertions, 17 deletions
diff --git a/src/main.rs b/src/main.rs index 8d8486e..c987005 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,8 @@ fn main() {      loop {          let mut translate = semantic::translate::Translate::<semantic::frame::Amd64Frame>::new();          let toplevel = Rc::new(RefCell::new(semantic::translate::Level::Top)); -        let level = translate.make_level(toplevel, vec![]); +        let escapes: Vec<semantic::frame::Escape> = vec![]; +        let level = translate.make_level(toplevel, escapes.into_iter());          let mut input = String::new();          print!("taiga> ");          io::stdout().flush().unwrap(); diff --git a/src/semantic/analysis.rs b/src/semantic/analysis.rs index 8335719..0c8dfa3 100644 --- a/src/semantic/analysis.rs +++ b/src/semantic/analysis.rs @@ -9,7 +9,7 @@ use ::ast::{self, WithLocation};  use super::environment;  use super::frame;  use super::ir; -use super::translate::{self, Expression, LevelRef, Translate}; +use super::translate::{self, Expression, Level, LevelRef, Translate};  use super::types::{self, Ty};  #[derive(Debug)] @@ -88,9 +88,10 @@ fn trans_decl<'a, F: frame::Frame>(      level: LevelRef<F>,      venv: &mut VarEnvironment<'a, F>,      tenv: &mut TypeEnvironment<'a>, -    decl: &WithLocation<ast::Declaration>) -> Result<(translate::Expression, Ty)> { +    decl: &WithLocation<ast::Declaration>) -> Result<VarValue<F>> {      match decl.declaration {          ast::DeclarationBody::Fun { ref ty, ref params, ref body } => { +            let new_level = tr.make_level(level, params.iter().map(|_| frame::Escape::Yes));              let declared_ty = if let &Some(ref ty) = ty {                  Some(ast::WithLocation::new(trans_ty(venv, tenv, &ty)?, ty.start, ty.end))              } else { None }; @@ -101,12 +102,13 @@ fn trans_decl<'a, F: frame::Frame>(              for param in params.iter() {                  let arg_ty = trans_ty(&mut new_venv, &mut new_tenv, ¶m.ty)?;                  arg_types.push(arg_ty.clone()); -                // TODO: -                // new_venv.add_binding(param.name.value.clone(), arg_ty); +                // TODO: don't assume args are in registers +                new_venv.add_binding(param.name.value.clone(), +                                     VarValue::Variable(unimplemented!(), arg_ty));              }              let (body_exp, body_ty) = -                trans_exp(tr, level, &mut new_venv, &mut new_tenv, &*body)?; +                trans_exp(tr, new_level.clone(), &mut new_venv, &mut new_tenv, &*body)?;              if let Some(decl_ty) = declared_ty {                  if &decl_ty.value != &body_ty { @@ -117,8 +119,13 @@ fn trans_decl<'a, F: frame::Frame>(                  }              } -            return err!(decl, TypeError::Unimplemented); -            // Ok(Ty::Function(arg_types, Box::new(body_ty))) +            let label = new_level.borrow().to_exp(); +            Ok(VarValue::Function { +                level: new_level, +                label: label, +                body: body_exp, +                ty: Ty::Function(arg_types, Box::new(body_ty)), +            })          }          ast::DeclarationBody::Ty { ref ty } => {              return err!(decl, TypeError::Unimplemented); @@ -136,7 +143,9 @@ fn trans_decl<'a, F: frame::Frame>(                      });                  }              } -            Ok((tr.alloc_local(&mut level.borrow_mut(), frame::Escape::Yes), actual_ty)) +            Ok(VarValue::Variable( +                tr.alloc_local(&mut level.borrow_mut(), frame::Escape::Yes), +                actual_ty))          }      }  } @@ -155,13 +164,14 @@ fn trans_exp<'a, F: frame::Frame>(              let mut new_venv = VarEnvironment::new(Some(venv));              let mut new_tenv = TypeEnvironment::new(Some(tenv));              for decl in decls.iter() { -                let (decl_exp, decl_ty) = trans_decl(tr, level.clone(), &mut new_venv, &mut new_tenv, decl)?;                  match decl.declaration {                      ast::DeclarationBody::Fun { .. } | ast::DeclarationBody::Var { .. } => { -                        new_venv.add_binding(decl.name.clone(), VarValue::Variable(decl_exp, decl_ty)); +                        let binding = trans_decl(tr, level.clone(), &mut new_venv, &mut new_tenv, decl)?; +                        new_venv.add_binding(decl.name.clone(), binding);                      }                      ast::DeclarationBody::Ty { .. } => { -                        new_tenv.add_binding(decl.name.clone(), decl_ty); +                        unimplemented!(); +                        // new_tenv.add_binding(decl.name.clone(), decl_ty);                      }                  }              } @@ -200,7 +210,10 @@ fn trans_exp<'a, F: frame::Frame>(                                          })                                      }                                  } -                            Ok((label.clone(), (**result).clone())) +                            Ok(( +                                tr.call(label.clone(), arg_types.into_iter().map(|(a, b)| a)), +                                (**result).clone() +                            ))                          },                          otherwise => {                              err!(exp, TypeError::Mismatch { diff --git a/src/semantic/frame.rs b/src/semantic/frame.rs index 95d18a1..5b7bfaa 100644 --- a/src/semantic/frame.rs +++ b/src/semantic/frame.rs @@ -14,11 +14,14 @@ pub enum Escape {  }  pub trait Frame { -    fn new(name: temp::TempLabel, formals: Vec<Escape>) -> Self; +    fn new<I: Iterator<Item=Escape>>(name: temp::TempLabel, formals: I) -> Self;      fn name(&self) -> temp::TempLabel;      fn formals(&self) -> &[Location];      fn alloc_local(&mut self, temp: &mut temp::Temp, escapes: Escape) -> Location;      fn location_to_exp(&mut self, location: Location) -> ir::Expression; +    fn to_exp(&self) -> ir::Expression { +        ir::Expression::Name(self.name()) +    }  }  pub struct Amd64Frame { @@ -27,7 +30,7 @@ pub struct Amd64Frame {  }  impl Frame for Amd64Frame { -    fn new(name: temp::TempLabel, formals: Vec<Escape>) -> Self { +    fn new<I: Iterator<Item=Escape>>(name: temp::TempLabel, formals: I) -> Self {          Amd64Frame {              offset: 0,              name: name, diff --git a/src/semantic/translate.rs b/src/semantic/translate.rs index 08e600f..4d51e60 100644 --- a/src/semantic/translate.rs +++ b/src/semantic/translate.rs @@ -38,10 +38,10 @@ impl<F: frame::Frame> Translate<F> {          }      } -    pub fn make_level( +    pub fn make_level<I: Iterator<Item=frame::Escape>>(          &mut self,          parent: LevelRef<F>, -        formals: Vec<frame::Escape>) -> LevelRef<F> { +        formals: I) -> LevelRef<F> {          let id = self.level_counter;          self.level_counter += 1;          Rc::new(RefCell::new(Level::Level { @@ -78,4 +78,28 @@ impl<F: frame::Frame> Translate<F> {              }          }      } + +    pub fn call<I: Iterator<Item=Expression>>(&mut self, target: Expression, parameters: I) -> Expression { +        Expression::Exp(ir::Expression::Call( +            Box::new(match target { +                Expression::Exp(e) => e, +                Expression::Void(_) => panic!("Can't call Void expression"), +            }), parameters.into_iter().map(|p| match p { +                Expression::Exp(e) => e, +                Expression::Void(_) => panic!("Can't evaluate Void expression"), +            }).collect())) +    } +} + +impl<F: frame::Frame> Level<F> { +    pub fn to_exp(&self) -> Expression { +        match self { +            &Level::Top => { +                panic!("Function defined in top level frame") +            } +            &Level::Level { ref frame, .. } => { +                Expression::Exp(frame.to_exp()) +            } +        } +    }  }  | 
