From 1d5ec57d4ee0695a2a3e2542939b091f51c00036 Mon Sep 17 00:00:00 2001 From: David Li Date: Tue, 28 Nov 2017 19:42:11 -0500 Subject: Reference-count levels --- src/main.rs | 8 +++++--- src/semantic/analysis.rs | 26 ++++++++++++++------------ src/semantic/translate.rs | 23 ++++++++++++++--------- 3 files changed, 33 insertions(+), 24 deletions(-) (limited to 'src') 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::::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 = ::std::result::Result>; -pub fn translate<'a, F: frame::Frame>( +pub fn translate( translate: &mut Translate, - level: &mut Level<'a, F>, + level: LevelRef, 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, - level: &mut Level<'b, F>, + level: LevelRef, venv: &mut VarEnvironment<'a>, tenv: &mut TypeEnvironment<'a>, decl: &WithLocation) -> 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, - level: &mut Level<'b, F>, + level: LevelRef, venv: &mut VarEnvironment<'a>, tenv: &mut TypeEnvironment<'a>, exp: &WithLocation) @@ -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 { _frametype: ::std::marker::PhantomData, } -pub enum Level<'a, F> - where F: 'a + frame::Frame { +pub enum Level + where F: frame::Frame { Top, Level { - parent: &'a Level<'a, F>, + parent: LevelRef, frame: F, unique_id: usize, }, } +pub type LevelRef = Rc>>; + impl Translate { pub fn new() -> Translate { Translate { @@ -33,17 +38,17 @@ impl Translate { } } - pub fn make_level<'a>( + pub fn make_level( &mut self, - parent: &'a Level, - formals: Vec) -> Level<'a, F> { + parent: LevelRef, + formals: Vec) -> LevelRef { 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 Translate { } pub fn alloc_local<'a>(&mut self, - level: &mut Level<'a, F>, + level: &mut Level, escapes: frame::Escape) -> Expression { match level { &mut Level::Top => { -- cgit v1.2.3