Skip to content

Commit

Permalink
[Back][Refactor] Use the Env in the backend to make it compatible wit…
Browse files Browse the repository at this point in the history
…h the rest.
  • Loading branch information
ptal committed Aug 31, 2017
1 parent 351ebe9 commit 014c9ce
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 52 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -17,7 +17,7 @@ name = "bonsai"
doc = false doc = false


[dependencies] [dependencies]
oak = "^0.5.3" oak = "^0.5.4"
oak_runtime = "^0.5.5" oak_runtime = "^0.5.5"
partial = "0.2.3" partial = "0.2.3"
clap = "^2" clap = "^2"
Expand Down
13 changes: 8 additions & 5 deletions src/back/compiler/expression.rs
Expand Up @@ -13,29 +13,32 @@
// limitations under the License. // limitations under the License.


use context::*; use context::*;
use session::*;
use back::code_formatter::*; use back::code_formatter::*;
use std::collections::HashMap; use std::collections::HashMap;


/// Useful to compile expression without using the environment (for example when initializing a field). /// Useful to compile expression without using the environment (for example when initializing a field).
/// Precondition: All the free variables occuring in `expr` are supposed to be in scope. /// Precondition: All the free variables occuring in `expr` are supposed to be in scope.
pub fn compile_expression(context: &Context, fmt: &mut CodeFormatter, expr: Expr) { pub fn compile_expression(session: &Session, context: &Context, fmt: &mut CodeFormatter, expr: Expr) {
ExpressionCompiler::new(context, fmt).compile(expr) ExpressionCompiler::new(session, context, fmt).compile(expr)
} }


/// Wrap the expression inside a closure `(env) -> [[expr]]` to be executed later with the environment. /// Wrap the expression inside a closure `(env) -> [[expr]]` to be executed later with the environment.
pub fn compile_closure(context: &Context, fmt: &mut CodeFormatter, expr: Expr, return_expr: bool) { pub fn compile_closure(session: &Session, context: &Context, fmt: &mut CodeFormatter, expr: Expr, return_expr: bool) {
ExpressionCompiler::new(context, fmt).closure(expr, return_expr) ExpressionCompiler::new(session, context, fmt).closure(expr, return_expr)
} }


struct ExpressionCompiler<'a> { struct ExpressionCompiler<'a> {
session: &'a Session,
context: &'a Context, context: &'a Context,
fmt: &'a mut CodeFormatter fmt: &'a mut CodeFormatter
} }


impl<'a> ExpressionCompiler<'a> impl<'a> ExpressionCompiler<'a>
{ {
fn new(context: &'a Context, fmt: &'a mut CodeFormatter) -> Self { fn new(session: &'a Session, context: &'a Context, fmt: &'a mut CodeFormatter) -> Self {
ExpressionCompiler { ExpressionCompiler {
session: session,
context: context, context: context,
fmt: fmt fmt: fmt
} }
Expand Down
26 changes: 16 additions & 10 deletions src/back/compiler/module.rs
Expand Up @@ -13,23 +13,29 @@
// limitations under the License. // limitations under the License.


use context::*; use context::*;
use session::*;
use back::code_formatter::*; use back::code_formatter::*;
use back::compiler::expression::*; use back::compiler::expression::*;
use back::compiler::statement::*; use back::compiler::statement::*;


pub fn compile_module(context: &Context, module: JModule) -> Partial<String> { pub fn compile_module(env: Env<Context>, module: JModule) -> Env<(Context, String)> {
ModuleCompiler::new(context).compile(module) env.and_next(|session, context| {
let code = ModuleCompiler::new(&session, &context).compile(module);
Env::new(session, code.map(|code| (context, code)))
})
} }


struct ModuleCompiler<'a> { struct ModuleCompiler<'a> {
session: &'a Session,
context: &'a Context, context: &'a Context,
fmt: CodeFormatter fmt: CodeFormatter
} }


impl<'a> ModuleCompiler<'a> impl<'a> ModuleCompiler<'a>
{ {
fn new(context: &'a Context) -> Self { fn new(session: &'a Session, context: &'a Context) -> Self {
ModuleCompiler { ModuleCompiler {
session: session,
context: context, context: context,
fmt: CodeFormatter::new() fmt: CodeFormatter::new()
} }
Expand Down Expand Up @@ -70,9 +76,9 @@ impl<'a> ModuleCompiler<'a>
} }


fn runtime_boilerplate(&mut self, module: &JModule) { fn runtime_boilerplate(&mut self, module: &JModule) {
self.runtime_object_uid(&module); self.runtime_object_uid(module);
self.runtime_init_method(&module); self.runtime_init_method(module);
self.runtime_destroy_method(&module); self.runtime_destroy_method(module);
} }


fn class_decl(&mut self, jclass: &JClass) { fn class_decl(&mut self, jclass: &JClass) {
Expand All @@ -95,11 +101,11 @@ impl<'a> ModuleCompiler<'a>
} }


fn main_method(&mut self, class_name: Ident) { fn main_method(&mut self, class_name: Ident) {
if let Some(main) = self.context.config().main_method.clone() { if let Some(main) = self.session.config().main_method.clone() {
if main.class == *class_name { if main.class == *class_name {
self.fmt.push_line("public static void main(String[] args)"); self.fmt.push_line("public static void main(String[] args)");
self.fmt.open_block(); self.fmt.open_block();
let machine_method = if self.context.config().debug { "createDebug" } else { "create" }; let machine_method = if self.session.config().debug { "createDebug" } else { "create" };
self.fmt.push_block(format!("\ self.fmt.push_block(format!("\
{} current = new {}();\n\ {} current = new {}();\n\
Program program = current.{}();\n\ Program program = current.{}();\n\
Expand Down Expand Up @@ -160,7 +166,7 @@ impl<'a> ModuleCompiler<'a>
self.fmt.push(&format!("new {}()", field.binding.ty.name)); self.fmt.push(&format!("new {}()", field.binding.ty.name));
} }
else { else {
compile_expression(&self.context, &mut self.fmt, expr); compile_expression(self.session, self.context, &mut self.fmt, expr);
} }
} }
self.fmt.terminate_line(";"); self.fmt.terminate_line(";");
Expand Down Expand Up @@ -246,7 +252,7 @@ impl<'a> ModuleCompiler<'a>
self.proc_uid(&process, proc_instance); self.proc_uid(&process, proc_instance);
self.fmt.push_line("return"); self.fmt.push_line("return");
self.fmt.indent(); self.fmt.indent();
compile_statement(self.context, &mut self.fmt, process.body); compile_statement(self.session, self.context, &mut self.fmt, process.body);
self.fmt.unindent(); self.fmt.unindent();
self.fmt.terminate_line(";"); self.fmt.terminate_line(";");
self.fmt.close_block(); self.fmt.close_block();
Expand Down
2 changes: 1 addition & 1 deletion src/driver/config.rs
Expand Up @@ -96,7 +96,7 @@ impl Config
output: file_to_test, output: file_to_test,
libs: libs, libs: libs,
main_method: None, main_method: None,
debug: true, debug: false,
testing_mode: true testing_mode: true
} }
} }
Expand Down
29 changes: 14 additions & 15 deletions src/driver/mod.rs
Expand Up @@ -22,7 +22,7 @@ use self::module_file::*;
use session::*; use session::*;
use front; use front;
use middle; use middle;
// use back; use back;
use context::Context; use context::Context;
use ast::{JModule, JCrate, TestAnnotation}; use ast::{JModule, JCrate, TestAnnotation};


Expand Down Expand Up @@ -67,19 +67,18 @@ fn run_middle<'a>(env: Env<Context>) -> Env<Context> {
middle::analyse_bonsai(env) middle::analyse_bonsai(env)
} }


fn run_back(session: Session, context: Context) -> Env<Context> { pub fn run_back(session: Session, context: Context) -> Env<Context> {
assert_eq!(session.has_errors(), false); assert_eq!(session.has_errors(), false);
Env::value(session, context) context.ast.modules.clone()
// context.ast.modules.clone() .into_iter()
// .into_iter() .filter(|module| module.file.is_lib())
// .filter(|module| module.file.is_lib()) .fold(Env::value(session, context), |env, module| {
// .fold(Env::value(session, context), |env, module| { let file = module.file.clone();
// let file = module.file.clone(); back::compile_module(env, module)
// back::compile_module(env, module) .map(|(context, output)| {
// .map(|(context, output)| { file.write_output(output);
// file.write_output(output); context
// context })
// }) .ensure(ABORT_MSG)
// .ensure(ABORT_MSG) })
// })
} }
2 changes: 1 addition & 1 deletion src/lib.rs
Expand Up @@ -30,4 +30,4 @@ pub mod context;
pub mod driver; pub mod driver;
pub mod front; pub mod front;
pub mod middle; pub mod middle;
// pub mod back; pub mod back;
2 changes: 1 addition & 1 deletion src/main.rs
Expand Up @@ -30,7 +30,7 @@ mod context;
mod driver; mod driver;
mod front; mod front;
mod middle; mod middle;
// mod back; mod back;


fn main() { fn main() {
driver::run(); driver::run();
Expand Down
27 changes: 19 additions & 8 deletions tests/test/unit.rs → tests/test/compile_test.rs
Expand Up @@ -19,14 +19,12 @@ use test::*;
use libbonsai::ast::*; use libbonsai::ast::*;
use libbonsai::context::*; use libbonsai::context::*;


use partial::*;

use std::path::{PathBuf}; use std::path::{PathBuf};


use ExpectedResult::*; use ExpectedResult::*;
use ExpectedResult; use ExpectedResult;


pub struct Unit<'a> pub struct CompileTest<'a>
{ {
display: &'a mut Display, display: &'a mut Display,
result: Partial<Context>, result: Partial<Context>,
Expand All @@ -36,15 +34,15 @@ pub struct Unit<'a>
test_path: PathBuf test_path: PathBuf
} }


impl<'a> Unit<'a> impl<'a> CompileTest<'a>
{ {
pub fn new(display: &'a mut Display, pub fn new(display: &'a mut Display,
result: Partial<Context>, expect: ExpectedResult, result: Partial<Context>, expect: ExpectedResult,
expected_diagnostics: Vec<CompilerTest>, expected_diagnostics: Vec<CompilerTest>,
obtained_diagnostics: Vec<CompilerTest>, obtained_diagnostics: Vec<CompilerTest>,
test_path: PathBuf) -> Self test_path: PathBuf) -> Self
{ {
Unit { CompileTest {
display: display, display: display,
result: result, result: result,
expect: expect, expect: expect,
Expand All @@ -54,10 +52,21 @@ impl<'a> Unit<'a>
} }
} }


pub fn diagnostic(mut self) { /// Returns the context if the compilation succeeded as expected.
pub fn diagnostic(mut self) -> Option<Context> {
let file_name = self.file_name(); let file_name = self.file_name();
if self.compilation_status(file_name.clone()) { if self.compilation_status(file_name.clone()) {
self.compare_diagnostics(file_name); self.compare_diagnostics(file_name)
}
else {
None
}
}

pub fn context_to_option(self) -> Option<Context> {
match self.result {
Partial::Value(x) => Some(x),
_ => None
} }
} }


Expand All @@ -76,15 +85,17 @@ impl<'a> Unit<'a>
} }
} }


fn compare_diagnostics(self, file_name: String) { fn compare_diagnostics(self, file_name: String) -> Option<Context> {
if &self.obtained_diagnostics != &self.expected_diagnostics { if &self.obtained_diagnostics != &self.expected_diagnostics {
self.display.diagnostics_failure(self.test_path, file_name, self.display.diagnostics_failure(self.test_path, file_name,
&self.obtained_diagnostics, &self.obtained_diagnostics,
&self.expected_diagnostics, &self.expected_diagnostics,
); );
None
} }
else { else {
self.display.success(file_name); self.display.success(file_name);
self.context_to_option()
} }
} }


Expand Down
24 changes: 16 additions & 8 deletions tests/test/engine.rs
Expand Up @@ -14,14 +14,14 @@


use libbonsai::session::*; use libbonsai::session::*;
use libbonsai::driver::*; use libbonsai::driver::*;
use libbonsai::context::*;


use syntex_syntax::codemap::{CodeMap}; use syntex_syntax::codemap::{CodeMap};
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell; use std::cell::RefCell;


use std::path::{PathBuf, Path}; use std::path::{PathBuf, Path};
use std::fs::read_dir; use std::fs::read_dir;
use partial::*;


use test::*; use test::*;
use test::ExpectedResult::*; use test::ExpectedResult::*;
Expand Down Expand Up @@ -63,14 +63,14 @@ impl Engine
} }


fn test_directory(&mut self, start_msg: String, directory: PathBuf, fn test_directory(&mut self, start_msg: String, directory: PathBuf,
expect: ExpectedResult, run: bool) expect: ExpectedResult, execute: bool)
{ {
self.display.info(start_msg); self.display.info(start_msg);
match read_dir(&directory) { match read_dir(&directory) {
Ok(dir_entries) => { Ok(dir_entries) => {
for entry in dir_entries.map(Result::unwrap).map(|entry| entry.path()) { for entry in dir_entries.map(Result::unwrap).map(|entry| entry.path()) {
if entry.is_file() { if entry.is_file() {
self.compile_and_run(entry, expect, run); self.compile_and_run(entry, expect, execute);
} else { } else {
self.display.warn(format!("Entry ignored because it's not a file.")); self.display.warn(format!("Entry ignored because it's not a file."));
self.display.path(entry); self.display.path(entry);
Expand All @@ -83,7 +83,7 @@ impl Engine
} }
} }


fn compile_and_run(&mut self, filepath: PathBuf, expect: ExpectedResult, run: bool) { fn compile_and_run(&mut self, filepath: PathBuf, expect: ExpectedResult, execute: bool) {
let obtained_diagnostics = Rc::new(RefCell::new(vec![])); let obtained_diagnostics = Rc::new(RefCell::new(vec![]));
let codemap = Rc::new(CodeMap::new()); let codemap = Rc::new(CodeMap::new());
let emitter = Box::new(TestEmitter::new(obtained_diagnostics.clone(), codemap.clone())); let emitter = Box::new(TestEmitter::new(obtained_diagnostics.clone(), codemap.clone()));
Expand All @@ -93,11 +93,19 @@ impl Engine
let session = session.reset_diagnostic(); let session = session.reset_diagnostic();
let obtained_diagnostics = Rc::try_unwrap(obtained_diagnostics) let obtained_diagnostics = Rc::try_unwrap(obtained_diagnostics)
.expect("Could not extract `obtained_diagnostics`.").into_inner(); .expect("Could not extract `obtained_diagnostics`.").into_inner();
let unit = Unit::new(&mut self.display, context, expect, session.compiler_tests, let context = {
obtained_diagnostics, filepath); let compile_test = CompileTest::new(&mut self.display, context, expect, session.compiler_tests.clone(),
unit.diagnostic(); obtained_diagnostics, filepath);
compile_test.diagnostic()
};
if let Some(context) = context {
if execute {
self.run_file(session, context);
}
}
} }


fn run_file(&mut self, filepath: PathBuf) { fn run_file(&mut self, session: Session, context: Context) {
run_back(session, context).expect("[Test] Could not generate the Bonsai code.");
} }
} }
4 changes: 2 additions & 2 deletions tests/test/mod.rs
Expand Up @@ -13,13 +13,13 @@
// limitations under the License. // limitations under the License.


pub mod display; pub mod display;
pub mod unit; pub mod compile_test;
pub mod expected_result; pub mod expected_result;
pub mod test_emitter; pub mod test_emitter;
pub mod engine; pub mod engine;


pub use self::display::*; pub use self::display::*;
pub use self::unit::*; pub use self::compile_test::*;
pub use self::expected_result::*; pub use self::expected_result::*;
pub use self::test_emitter::*; pub use self::test_emitter::*;
pub use self::engine::*; pub use self::engine::*;

0 comments on commit 014c9ce

Please sign in to comment.