diff options
author | David Li <li.davidm96@gmail.com> | 2017-11-28 20:16:25 -0500 |
---|---|---|
committer | David Li <li.davidm96@gmail.com> | 2017-11-28 20:16:25 -0500 |
commit | 9630b53836c0717a7ac0ab86dda3a4efb5bf9fb9 (patch) | |
tree | b4dab117fe506f7d6f3b35d1a974492816343620 | |
parent | 84babea244bb8ef85c6b84fd63eeeedc85781c03 (diff) |
-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()) + } + } + } } |