summaryrefslogtreecommitdiff
path: root/src/semantic
diff options
context:
space:
mode:
Diffstat (limited to 'src/semantic')
-rw-r--r--src/semantic/analysis.rs12
-rw-r--r--src/semantic/frame.rs33
-rw-r--r--src/semantic/translate.rs14
3 files changed, 50 insertions, 9 deletions
diff --git a/src/semantic/analysis.rs b/src/semantic/analysis.rs
index 973e703..152ede9 100644
--- a/src/semantic/analysis.rs
+++ b/src/semantic/analysis.rs
@@ -75,7 +75,7 @@ fn trans_decl<'a, 'b, F: frame::Frame>(
level: &mut Level<'b, F>,
venv: &mut TypeEnvironment<'a>,
tenv: &mut TypeEnvironment<'a>,
- decl: &WithLocation<ast::Declaration>) -> Result<Ty> {
+ decl: &WithLocation<ast::Declaration>) -> Result<(translate::Expression, Ty)> {
match decl.declaration {
ast::DeclarationBody::Fun { ref ty, ref params, ref body } => {
let declared_ty = if let &Some(ref ty) = ty {
@@ -103,10 +103,12 @@ fn trans_decl<'a, 'b, F: frame::Frame>(
}
}
- Ok(Ty::Function(arg_types, Box::new(body_ty)))
+ return err!(decl, TypeError::Unimplemented);
+ // Ok(Ty::Function(arg_types, Box::new(body_ty)))
}
ast::DeclarationBody::Ty { ref ty } => {
- trans_ty(venv, tenv, ty)
+ return err!(decl, TypeError::Unimplemented);
+ // trans_ty(venv, tenv, ty)
}
ast::DeclarationBody::Var { ref ty, ref value } => {
let (var_exp, actual_ty) =
@@ -120,7 +122,7 @@ fn trans_decl<'a, 'b, F: frame::Frame>(
});
}
}
- Ok(actual_ty)
+ Ok((tr.alloc_local(level, frame::Escape::Yes), actual_ty))
}
}
}
@@ -139,7 +141,7 @@ fn trans_exp<'a, 'b, F: frame::Frame>(
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(tr, level, &mut new_venv, &mut new_tenv, decl)?;
+ let (decl_exp, decl_ty) = trans_decl(tr, level, &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);
diff --git a/src/semantic/frame.rs b/src/semantic/frame.rs
index ddfc330..95d18a1 100644
--- a/src/semantic/frame.rs
+++ b/src/semantic/frame.rs
@@ -1,3 +1,4 @@
+use super::ir;
use super::temp;
pub enum Location {
@@ -16,17 +17,20 @@ pub trait Frame {
fn new(name: temp::TempLabel, formals: Vec<Escape>) -> Self;
fn name(&self) -> temp::TempLabel;
fn formals(&self) -> &[Location];
- fn alloc_local(&mut self, escapes: Escape) -> Location;
+ fn alloc_local(&mut self, temp: &mut temp::Temp, escapes: Escape) -> Location;
+ fn location_to_exp(&mut self, location: Location) -> ir::Expression;
}
pub struct Amd64Frame {
+ offset: u64,
name: temp::TempLabel,
}
impl Frame for Amd64Frame {
fn new(name: temp::TempLabel, formals: Vec<Escape>) -> Self {
Amd64Frame {
- name,
+ offset: 0,
+ name: name,
}
}
@@ -38,7 +42,28 @@ impl Frame for Amd64Frame {
unimplemented!();
}
- fn alloc_local(&mut self, escapes: Escape) -> Location {
- unimplemented!();
+ fn alloc_local(&mut self, temp: &mut temp::Temp, escapes: Escape) -> Location {
+ // TODO: this is WRONG
+ Location::InFrame { offset: 0 }
+ }
+
+ fn location_to_exp(&mut self, location: Location) -> ir::Expression {
+ match location {
+ Location::InFrame { offset } => {
+ ir::Expression::Memory(
+ Box::new(
+ ir::Expression::BinOp(
+ ir::BinOp::Plus,
+ Box::new(ir::Expression::Const(self.offset)),
+ Box::new(ir::Expression::Const(offset as u64)),
+ )
+ )
+ )
+ }
+ Location::Register(name) => {
+ ir::Expression::Temp(name)
+ }
+ }
+
}
}
diff --git a/src/semantic/translate.rs b/src/semantic/translate.rs
index 57581a4..5e68f36 100644
--- a/src/semantic/translate.rs
+++ b/src/semantic/translate.rs
@@ -59,4 +59,18 @@ impl<F: frame::Frame> Translate<F> {
_ => panic!("Can't make binop from Void"),
}
}
+
+ pub fn alloc_local<'a>(&mut self,
+ level: &mut Level<'a, F>,
+ escapes: frame::Escape) -> Expression {
+ match level {
+ &mut Level::Top => {
+ panic!("Can't allocate in toplevel frame")
+ },
+ &mut Level::Level { parent: _, ref mut frame, .. } => {
+ let access = frame.alloc_local(&mut self.temp, escapes);
+ Expression::Exp(frame.location_to_exp(access))
+ }
+ }
+ }
}