summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2017-11-28 19:42:11 -0500
committerDavid Li <li.davidm96@gmail.com>2017-11-28 19:42:11 -0500
commit1d5ec57d4ee0695a2a3e2542939b091f51c00036 (patch)
tree944c4758ed4cb21314f2f0b1ca56d883eb78220a /src
parent5a335165bd60c068875d75d313c66e8bccc47a86 (diff)
Reference-count levels
Diffstat (limited to 'src')
-rw-r--r--src/main.rs8
-rw-r--r--src/semantic/analysis.rs26
-rw-r--r--src/semantic/translate.rs23
3 files changed, 33 insertions, 24 deletions
diff --git a/src/main.rs b/src/main.rs
index f3128a2..8d8486e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,15 +7,17 @@ pub mod ast;
pub mod semantic;
pub mod taiga;
+use std::cell::RefCell;
use std::io::{self, BufRead, Write};
+use std::rc::Rc;
fn main() {
let stdin = io::stdin();
let mut handle = stdin.lock();
loop {
let mut translate = semantic::translate::Translate::<semantic::frame::Amd64Frame>::new();
- let mut toplevel = semantic::translate::Level::Top;
- let mut level = translate.make_level(&mut toplevel, vec![]);
+ let toplevel = Rc::new(RefCell::new(semantic::translate::Level::Top));
+ let level = translate.make_level(toplevel, vec![]);
let mut input = String::new();
print!("taiga> ");
io::stdout().flush().unwrap();
@@ -24,7 +26,7 @@ fn main() {
let program = taiga::parse_Program(&input);
println!("{:?}", program);
if let Ok(program) = program {
- let result = semantic::analysis::translate(&mut translate, &mut level, &program);
+ let result = semantic::analysis::translate(&mut translate, level, &program);
println!("{:?}", result);
}
}
diff --git a/src/semantic/analysis.rs b/src/semantic/analysis.rs
index c7acfc9..b7462a0 100644
--- a/src/semantic/analysis.rs
+++ b/src/semantic/analysis.rs
@@ -3,11 +3,13 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+use std::rc::Rc;
+
use ::ast::{self, WithLocation};
use super::environment;
use super::frame;
use super::ir;
-use super::translate::{self, Expression, Level, Translate};
+use super::translate::{self, Expression, LevelRef, Translate};
use super::types::{self, Ty};
#[derive(Debug)]
@@ -33,9 +35,9 @@ type VarEnvironment<'a> = environment::Environment<'a, String, VarValue>;
type TypeEnvironment<'a> = environment::Environment<'a, String, Ty>;
pub type Result<T> = ::std::result::Result<T, WithLocation<TypeError>>;
-pub fn translate<'a, F: frame::Frame>(
+pub fn translate<F: frame::Frame>(
translate: &mut Translate<F>,
- level: &mut Level<'a, F>,
+ level: LevelRef<F>,
program: &ast::Program)
-> Result<(translate::Expression, Ty)> {
let mut venv = VarEnvironment::new(None);
@@ -76,9 +78,9 @@ fn trans_ty<'a>(
}
}
-fn trans_decl<'a, 'b, F: frame::Frame>(
+fn trans_decl<'a, F: frame::Frame>(
tr: &mut Translate<F>,
- level: &mut Level<'b, F>,
+ level: LevelRef<F>,
venv: &mut VarEnvironment<'a>,
tenv: &mut TypeEnvironment<'a>,
decl: &WithLocation<ast::Declaration>) -> Result<(translate::Expression, Ty)> {
@@ -119,7 +121,7 @@ fn trans_decl<'a, 'b, F: frame::Frame>(
}
ast::DeclarationBody::Var { ref ty, ref value } => {
let (var_exp, actual_ty) =
- trans_exp(tr, level, venv, tenv, &value)?;
+ trans_exp(tr, level.clone(), venv, tenv, &value)?;
if let &Some(ref ty) = ty {
let decl_ty = trans_ty(venv, tenv, &ty)?;
if decl_ty != actual_ty {
@@ -129,14 +131,14 @@ fn trans_decl<'a, 'b, F: frame::Frame>(
});
}
}
- Ok((tr.alloc_local(level, frame::Escape::Yes), actual_ty))
+ Ok((tr.alloc_local(&mut level.borrow_mut(), frame::Escape::Yes), actual_ty))
}
}
}
-fn trans_exp<'a, 'b, F: frame::Frame>(
+fn trans_exp<'a, F: frame::Frame>(
tr: &mut Translate<F>,
- level: &mut Level<'b, F>,
+ level: LevelRef<F>,
venv: &mut VarEnvironment<'a>,
tenv: &mut TypeEnvironment<'a>,
exp: &WithLocation<ast::Expression>)
@@ -148,7 +150,7 @@ fn trans_exp<'a, 'b, 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, &mut new_venv, &mut new_tenv, decl)?;
+ 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));
@@ -163,7 +165,7 @@ fn trans_exp<'a, 'b, F: frame::Frame>(
&Call(ref name, ref args) => {
let mut arg_types = vec![];
for arg in args {
- arg_types.push(trans_exp(tr, level, venv, tenv, arg)?);
+ arg_types.push(trans_exp(tr, level.clone(), venv, tenv, arg)?);
}
let value = venv.lookup(name)
@@ -234,7 +236,7 @@ fn trans_exp<'a, 'b, F: frame::Frame>(
},
&BinOp(ref op, ref left, ref right) => {
use ast::BinOp::*;
- let (left_exp, left_ty) = trans_exp(tr, level, venv, tenv, left)?;
+ let (left_exp, left_ty) = trans_exp(tr, level.clone(), venv, tenv, left)?;
let (right_exp, right_ty) = trans_exp(tr, level, venv, tenv, right)?;
match op {
&Add => {
diff --git a/src/semantic/translate.rs b/src/semantic/translate.rs
index f802c3f..08e600f 100644
--- a/src/semantic/translate.rs
+++ b/src/semantic/translate.rs
@@ -1,3 +1,6 @@
+use std::cell::RefCell;
+use std::rc::Rc;
+
use super::frame;
use super::ir;
use super::temp;
@@ -14,16 +17,18 @@ pub struct Translate<F> {
_frametype: ::std::marker::PhantomData<F>,
}
-pub enum Level<'a, F>
- where F: 'a + frame::Frame {
+pub enum Level<F>
+ where F: frame::Frame {
Top,
Level {
- parent: &'a Level<'a, F>,
+ parent: LevelRef<F>,
frame: F,
unique_id: usize,
},
}
+pub type LevelRef<F> = Rc<RefCell<Level<F>>>;
+
impl<F: frame::Frame> Translate<F> {
pub fn new() -> Translate<F> {
Translate {
@@ -33,17 +38,17 @@ impl<F: frame::Frame> Translate<F> {
}
}
- pub fn make_level<'a>(
+ pub fn make_level(
&mut self,
- parent: &'a Level<F>,
- formals: Vec<frame::Escape>) -> Level<'a, F> {
+ parent: LevelRef<F>,
+ formals: Vec<frame::Escape>) -> LevelRef<F> {
let id = self.level_counter;
self.level_counter += 1;
- Level::Level {
+ Rc::new(RefCell::new(Level::Level {
parent: parent,
frame: F::new(self.temp.next_label(), formals),
unique_id: id,
- }
+ }))
}
pub fn make_num(&mut self, num: u64) -> Expression {
@@ -61,7 +66,7 @@ impl<F: frame::Frame> Translate<F> {
}
pub fn alloc_local<'a>(&mut self,
- level: &mut Level<'a, F>,
+ level: &mut Level<F>,
escapes: frame::Escape) -> Expression {
match level {
&mut Level::Top => {