diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 2097d0b690743..55de0c4d54f38 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -47,7 +47,7 @@ pub struct Repl { running: bool, view_items: ~str, lib_search_paths: ~[~str], - stmts: ~str + stmts: ~[~str], } // Action to do after reading a :command @@ -88,28 +88,32 @@ fn record(mut repl: Repl, blk: &ast::blk, intr: @token::ident_interner) -> Repl repl.view_items = repl.view_items + "\n" + new_view_items } - if blk.node.stmts.len() > 0 { - let new_stmts = do with_pp(intr) |pp, writer| { - for blk.node.stmts.each |stmt| { - match stmt.node { - ast::stmt_decl(*) | ast::stmt_mac(*) => { - pprust::print_stmt(pp, *stmt); - writer.write_line(""); - } - ast::stmt_expr(expr, _) | ast::stmt_semi(expr, _) => { - match expr.node { - ast::expr_assign(*) | - ast::expr_assign_op(*) | - _ => {} - } - } - } - } - }; - debug!("new stmts %s", new_stmts); + fn keep(expr: @ast::expr) -> bool { + match expr.node { + ast::expr_assign(*) | ast::expr_assign_op(*) => true, + _ => false + } + } - repl.stmts = repl.stmts + "\n" + new_stmts + for blk.node.stmts.each |stmt| { + match stmt.node { + ast::stmt_expr(expr, _) | + ast::stmt_semi(expr, _) if !keep(expr) => { loop } + _ => {} + } + let s = do with_pp(intr) |pp, _| { + pprust::print_stmt(pp, *stmt); + }; + repl.stmts.push(s); + } + for blk.node.expr.each |&e| { + if keep(e) { + let s = do with_pp(intr) |pp, _| { + pprust::print_expr(pp, e); + }; + repl.stmts.push(s + ";"); + } } return repl; @@ -128,8 +132,16 @@ fn run(repl: Repl, input: ~str) -> Repl { debug!("building driver input"); let head = include_str!("wrapper.rs").to_owned(); - let foot = fmt!("fn main() {\n%s\n%s\n\nprint({\n%s\n})\n}", - repl.view_items, repl.stmts, input); + let mut foot = fmt!("fn main() {\n%s\n", repl.view_items); + for repl.stmts.each |stmt| { + foot.push_str("{"); + foot.push_str(*stmt); + } + foot.push_str(fmt!("\npp({\n%s\n})\n", input)); + for repl.stmts.len().times { + foot.push_str("}"); + } + foot.push_str("\n}"); let wrapped = driver::str_input(head + foot); debug!("inputting %s", head + foot); @@ -161,18 +173,24 @@ fn run(repl: Repl, input: ~str) -> Repl { } } - let e = opt.unwrap(); - let blk = match e.node { - ast::expr_call(_, ref exprs, _) => { - match exprs[0].node { - ast::expr_block(ref blk) => blk, - _ => fail!() + let mut e = opt.expect("the main function should exist"); + loop { + match e.node { + ast::expr_call(_, ref exprs, _) => { + match exprs[0].node { + ast::expr_block(ref blk) => { + debug!("recording input into repl history"); + return record(repl, blk, sess.parse_sess.interner); + } + _ => fail!("expr_call should have a block inside"), + } } + + ast::expr_block(ref blk) => { e = blk.node.expr.unwrap() } + + _ => fail!("unknown ast node") } - _ => fail!() - }; - debug!("recording input into repl history"); - record(repl, blk, sess.parse_sess.interner) + } } // Compiles a crate given by the filename as a library if the compiled @@ -264,7 +282,7 @@ fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer, ~"exit" => repl.running = false, ~"clear" => { repl.view_items = ~""; - repl.stmts = ~""; + repl.stmts = ~[]; // XXX: Win32 version of linenoise can't do this //rl::clear(); @@ -386,7 +404,7 @@ pub fn main() { running: true, view_items: ~"", lib_search_paths: ~[], - stmts: ~"" + stmts: ~[] }; let istty = unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0; @@ -440,7 +458,7 @@ mod tests { running: true, view_items: ~"", lib_search_paths: ~[], - stmts: ~"" + stmts: ~[] } } @@ -453,7 +471,8 @@ mod tests { } } - #[test] #[ignore] + // FIXME(#6489): these tests mysteriously fail on i686 + #[test] #[ignore(cfg(target_arch = "x86"))] fn run_all() { // By default, unit tests are run in parallel. Rusti, on the other hand, // does not enjoy doing this. I suspect that it is because the LLVM @@ -475,5 +494,12 @@ mod tests { debug!("regression test for #5803"); run_cmds(["spawn( || println(\"Please don't segfault\") );", "do spawn { println(\"Please?\"); }"]); + + debug!("regression test for #5675"); + run_cmds(["fn f() {}", "fn f() {}", "fn f() {}"]); + + debug!("assignments are recorded"); + run_cmds(["let mut a = 3;", "a = 4", "assert!(a == 4)"]); + run_cmds(["let mut a = 3;", "a = 4;", "assert!(a == 4)"]); } } diff --git a/src/librusti/wrapper.rs b/src/librusti/wrapper.rs index 9c3026f0915cd..95540f42ffef8 100644 --- a/src/librusti/wrapper.rs +++ b/src/librusti/wrapper.rs @@ -25,6 +25,6 @@ extern mod std; -fn print(result: T) { +fn pp(result: T) { io::println(fmt!("%?", result)); }