Permalink
Browse files

[Back][Refactor] Use the Env in the backend to make it compatible wit…

…h the rest.
  • Loading branch information...
ptal committed Aug 31, 2017
1 parent 351ebe9 commit 014c9cebae9a5e66805f06577121ad76d44cd6e7
View
@@ -17,7 +17,7 @@ name = "bonsai"
doc = false
[dependencies]
oak = "^0.5.3"
oak = "^0.5.4"
oak_runtime = "^0.5.5"
partial = "0.2.3"
clap = "^2"
@@ -13,29 +13,32 @@
// limitations under the License.
use context::*;
use session::*;
use back::code_formatter::*;
use std::collections::HashMap;
/// 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.
pub fn compile_expression(context: &Context, fmt: &mut CodeFormatter, expr: Expr) {
ExpressionCompiler::new(context, fmt).compile(expr)
pub fn compile_expression(session: &Session, context: &Context, fmt: &mut CodeFormatter, expr: Expr) {
ExpressionCompiler::new(session, context, fmt).compile(expr)
}
/// 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) {
ExpressionCompiler::new(context, fmt).closure(expr, return_expr)
pub fn compile_closure(session: &Session, context: &Context, fmt: &mut CodeFormatter, expr: Expr, return_expr: bool) {
ExpressionCompiler::new(session, context, fmt).closure(expr, return_expr)
}
struct ExpressionCompiler<'a> {
session: &'a Session,
context: &'a Context,
fmt: &'a mut CodeFormatter
}
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 {
session: session,
context: context,
fmt: fmt
}
@@ -13,23 +13,29 @@
// limitations under the License.
use context::*;
use session::*;
use back::code_formatter::*;
use back::compiler::expression::*;
use back::compiler::statement::*;
pub fn compile_module(context: &Context, module: JModule) -> Partial<String> {
ModuleCompiler::new(context).compile(module)
pub fn compile_module(env: Env<Context>, module: JModule) -> Env<(Context, String)> {
env.and_next(|session, context| {
let code = ModuleCompiler::new(&session, &context).compile(module);
Env::new(session, code.map(|code| (context, code)))
})
}
struct ModuleCompiler<'a> {
session: &'a Session,
context: &'a Context,
fmt: CodeFormatter
}
impl<'a> ModuleCompiler<'a>
{
fn new(context: &'a Context) -> Self {
fn new(session: &'a Session, context: &'a Context) -> Self {
ModuleCompiler {
session: session,
context: context,
fmt: CodeFormatter::new()
}
@@ -70,9 +76,9 @@ impl<'a> ModuleCompiler<'a>
}
fn runtime_boilerplate(&mut self, module: &JModule) {
self.runtime_object_uid(&module);
self.runtime_init_method(&module);
self.runtime_destroy_method(&module);
self.runtime_object_uid(module);
self.runtime_init_method(module);
self.runtime_destroy_method(module);
}
fn class_decl(&mut self, jclass: &JClass) {
@@ -95,11 +101,11 @@ impl<'a> ModuleCompiler<'a>
}
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 {
self.fmt.push_line("public static void main(String[] args)");
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!("\
{} current = new {}();\n\
Program program = current.{}();\n\
@@ -160,7 +166,7 @@ impl<'a> ModuleCompiler<'a>
self.fmt.push(&format!("new {}()", field.binding.ty.name));
}
else {
compile_expression(&self.context, &mut self.fmt, expr);
compile_expression(self.session, self.context, &mut self.fmt, expr);
}
}
self.fmt.terminate_line(";");
@@ -246,7 +252,7 @@ impl<'a> ModuleCompiler<'a>
self.proc_uid(&process, proc_instance);
self.fmt.push_line("return");
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.terminate_line(";");
self.fmt.close_block();
View
@@ -96,7 +96,7 @@ impl Config
output: file_to_test,
libs: libs,
main_method: None,
debug: true,
debug: false,
testing_mode: true
}
}
View
@@ -22,7 +22,7 @@ use self::module_file::*;
use session::*;
use front;
use middle;
// use back;
use back;
use context::Context;
use ast::{JModule, JCrate, TestAnnotation};
@@ -67,19 +67,18 @@ fn run_middle<'a>(env: Env<Context>) -> Env<Context> {
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);
Env::value(session, context)
// context.ast.modules.clone()
// .into_iter()
// .filter(|module| module.file.is_lib())
// .fold(Env::value(session, context), |env, module| {
// let file = module.file.clone();
// back::compile_module(env, module)
// .map(|(context, output)| {
// file.write_output(output);
// context
// })
// .ensure(ABORT_MSG)
// })
context.ast.modules.clone()
.into_iter()
.filter(|module| module.file.is_lib())
.fold(Env::value(session, context), |env, module| {
let file = module.file.clone();
back::compile_module(env, module)
.map(|(context, output)| {
file.write_output(output);
context
})
.ensure(ABORT_MSG)
})
}
View
@@ -30,4 +30,4 @@ pub mod context;
pub mod driver;
pub mod front;
pub mod middle;
// pub mod back;
pub mod back;
View
@@ -30,7 +30,7 @@ mod context;
mod driver;
mod front;
mod middle;
// mod back;
mod back;
fn main() {
driver::run();
@@ -19,14 +19,12 @@ use test::*;
use libbonsai::ast::*;
use libbonsai::context::*;
use partial::*;
use std::path::{PathBuf};
use ExpectedResult::*;
use ExpectedResult;
pub struct Unit<'a>
pub struct CompileTest<'a>
{
display: &'a mut Display,
result: Partial<Context>,
@@ -36,15 +34,15 @@ pub struct Unit<'a>
test_path: PathBuf
}
impl<'a> Unit<'a>
impl<'a> CompileTest<'a>
{
pub fn new(display: &'a mut Display,
result: Partial<Context>, expect: ExpectedResult,
expected_diagnostics: Vec<CompilerTest>,
obtained_diagnostics: Vec<CompilerTest>,
test_path: PathBuf) -> Self
{
Unit {
CompileTest {
display: display,
result: result,
expect: expect,
@@ -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();
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
}
}
@@ -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 {
self.display.diagnostics_failure(self.test_path, file_name,
&self.obtained_diagnostics,
&self.expected_diagnostics,
);
None
}
else {
self.display.success(file_name);
self.context_to_option()
}
}
View
@@ -14,14 +14,14 @@
use libbonsai::session::*;
use libbonsai::driver::*;
use libbonsai::context::*;
use syntex_syntax::codemap::{CodeMap};
use std::rc::Rc;
use std::cell::RefCell;
use std::path::{PathBuf, Path};
use std::fs::read_dir;
use partial::*;
use test::*;
use test::ExpectedResult::*;
@@ -63,14 +63,14 @@ impl Engine
}
fn test_directory(&mut self, start_msg: String, directory: PathBuf,
expect: ExpectedResult, run: bool)
expect: ExpectedResult, execute: bool)
{
self.display.info(start_msg);
match read_dir(&directory) {
Ok(dir_entries) => {
for entry in dir_entries.map(Result::unwrap).map(|entry| entry.path()) {
if entry.is_file() {
self.compile_and_run(entry, expect, run);
self.compile_and_run(entry, expect, execute);
} else {
self.display.warn(format!("Entry ignored because it's not a file."));
self.display.path(entry);
@@ -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 codemap = Rc::new(CodeMap::new());
let emitter = Box::new(TestEmitter::new(obtained_diagnostics.clone(), codemap.clone()));
@@ -93,11 +93,19 @@ impl Engine
let session = session.reset_diagnostic();
let obtained_diagnostics = Rc::try_unwrap(obtained_diagnostics)
.expect("Could not extract `obtained_diagnostics`.").into_inner();
let unit = Unit::new(&mut self.display, context, expect, session.compiler_tests,
obtained_diagnostics, filepath);
unit.diagnostic();
let context = {
let compile_test = CompileTest::new(&mut self.display, context, expect, session.compiler_tests.clone(),
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.");
}
}
View
@@ -13,13 +13,13 @@
// limitations under the License.
pub mod display;
pub mod unit;
pub mod compile_test;
pub mod expected_result;
pub mod test_emitter;
pub mod engine;
pub use self::display::*;
pub use self::unit::*;
pub use self::compile_test::*;
pub use self::expected_result::*;
pub use self::test_emitter::*;
pub use self::engine::*;

0 comments on commit 014c9ce

Please sign in to comment.