]> Repositorios git - scryer-prolog.git/commitdiff
read from streams.
authorMark Thom <[email protected]>
Sun, 14 Apr 2019 00:40:17 +0000 (18:40 -0600)
committerMark Thom <[email protected]>
Sun, 14 Apr 2019 00:40:17 +0000 (18:40 -0600)
25 files changed:
Cargo.toml
src/main.rs
src/prolog/clause_types.rs
src/prolog/heap_print.rs
src/prolog/lib/builtins.pl
src/prolog/lib/dif.pl
src/prolog/machine/and_stack.rs
src/prolog/machine/attributed_variables.rs
src/prolog/machine/code_repo.rs
src/prolog/machine/compile.rs
src/prolog/machine/dynamic_database.rs
src/prolog/machine/heap.rs
src/prolog/machine/machine_errors.rs
src/prolog/machine/machine_indices.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs
src/prolog/machine/or_stack.rs
src/prolog/machine/system_calls.rs
src/prolog/machine/term_expansion.rs
src/prolog/machine/toplevel.rs
src/prolog/read.rs
src/prolog/toplevel.pl [new file with mode: 0644]
src/prolog/write.rs
src/tests.rs

index e9944e99f7ca78ffa50886c2241d668e335769ea..ae82d3a659bf6a39bab1d67b09ac506f4896492c 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "scryer-prolog"
-version = "0.8.51"
+version = "0.8.52"
 authors = ["Mark Thom <[email protected]>"]
 repository = "https://github.com/mthom/scryer-prolog"
 description = "A modern Prolog implementation written mostly in Rust."
@@ -14,8 +14,8 @@ cfg-if = "0.1.7"
 downcast = "0.10.0"
 num = "0.2"
 ordered-float = "0.5.0"
-prolog_parser = "0.8.18"
-readline_rs_compat = { version = "0.1.7", optional = true }
+prolog_parser = { version = "0.8.19", path = "../prolog_parser" }
+readline_rs_compat = { version = "0.1.8", path = "../readline.rs", optional = true }
 ref_thread_local = "0.0.0"
 
 [dependencies.termion]
index ebfe87c22dda1d145128bc6d1bc343746faaa18f..a339ad105dc0949d784667f232b43a638dfd96a9 100644 (file)
@@ -14,59 +14,16 @@ extern crate termion;
 mod prolog;
 
 use prolog::machine::*;
-use prolog::machine::compile::*;
 use prolog::machine::machine_errors::*;
-use prolog::machine::toplevel::string_to_toplevel;
 use prolog::read::*;
-use prolog::write::*;
 
 #[cfg(test)]
 mod tests;
 
-fn prolog_repl() {
-    let mut wam = Machine::new();
-
-    loop {
-        #[cfg(feature = "readline_rs_compat")]
-        readline::set_line_mode(readline::LineMode::Single);
-
-        match toplevel_read_line() {
-            Ok(Input::TermString(buffer)) => {
-                let result = match string_to_toplevel(buffer.as_bytes(), &mut wam) {
-                    Ok(packet) => compile_term(&mut wam, packet),
-                    Err(e) => EvalSession::from(e)
-                };
-
-                print(&mut wam, result)
-            },
-            Ok(Input::Batch) => {
-                #[cfg(feature = "readline_rs_compat")]
-                readline::set_line_mode(readline::LineMode::Multi);
-
-                let src = match readline::read_batch("") {
-                    Ok(src) => src,
-                    Err(e) => {
-                        println!("{}", e);
-                        continue;
-                    }
-                };
-
-                let result = compile_user_module(&mut wam, &src[0 ..]);
-                print(&mut wam, result);
-            },
-            Ok(Input::Clear) => {
-                wam.clear();
-                continue;
-            },
-            Err(e) => print(&mut wam, EvalSession::from(e))
-        };
-
-        wam.reset();
-    }
-}
-
 fn main() {
     #[cfg(feature = "readline_rs_compat")]
     readline::readline_initialize();
-    prolog_repl();
+
+    let mut wam = Machine::new(readline::input_stream());
+    wam.run_toplevel();
 }
index 7eb0a03c15b6ff8b3f46ae37270cc6b5ee56fadd..fc78dfd309152d51821714449cd5251b934e2781 100644 (file)
@@ -130,7 +130,7 @@ ref_thread_local! {
         m.insert(("partial_string", 2), ClauseType::BuiltIn(BuiltInClauseType::PartialString));
         m.insert(("read", 1), ClauseType::BuiltIn(BuiltInClauseType::Read));
         m.insert(("sort", 2), ClauseType::BuiltIn(BuiltInClauseType::Sort));
-        
+
         m
     };
 }
@@ -177,7 +177,7 @@ pub enum SystemClauseType {
     FetchGlobalVar,
     GetChar,
     TruncateIfNoLiftedHeapGrowthDiff,
-    TruncateIfNoLiftedHeapGrowth,    
+    TruncateIfNoLiftedHeapGrowth,
     GetAttributedVariableList,
     GetAttrVarQueueDelimiter,
     GetAttrVarQueueBeyond,
@@ -201,6 +201,8 @@ pub enum SystemClauseType {
     ModuleRetractClause,
     NoSuchPredicate,
     OpDeclaration,
+    REPL(REPLCodePtr),
+    ReadTerm,
     RedoAttrVarBindings,
     RemoveCallPolicyCheck,
     RemoveInferenceCounter,
@@ -236,7 +238,7 @@ impl SystemClauseType {
     pub fn name(&self) -> ClauseName {
         match self {
             &SystemClauseType::AbolishClause => clause_name!("$abolish_clause"),
-            &SystemClauseType::AbolishModuleClause => clause_name!("$abolish_module_clause"),            
+            &SystemClauseType::AbolishModuleClause => clause_name!("$abolish_module_clause"),
             &SystemClauseType::AssertDynamicPredicateToBack => clause_name!("$assertz"),
             &SystemClauseType::AssertDynamicPredicateToFront => clause_name!("$asserta"),
             &SystemClauseType::AtomChars => clause_name!("$atom_chars"),
@@ -246,6 +248,9 @@ impl SystemClauseType {
             &SystemClauseType::ModuleAssertDynamicPredicateToBack => clause_name!("$module_assertz"),
             &SystemClauseType::CharCode => clause_name!("char_code"),
             &SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
+            &SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
+            &SystemClauseType::REPL(REPLCodePtr::SubmitQueryAndPrintResults) =>
+                clause_name!("$submit_query_and_print_results"),
             &SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
             &SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
             &SystemClauseType::DeleteHeadAttribute => clause_name!("$del_attr_head"),
@@ -296,6 +301,7 @@ impl SystemClauseType {
             &SystemClauseType::GetCurrentBlock => clause_name!("$get_current_block"),
             &SystemClauseType::InstallNewBlock => clause_name!("$install_new_block"),
             &SystemClauseType::ModuleRetractClause => clause_name!("$module_retract_clause"),
+            &SystemClauseType::ReadTerm => clause_name!("$read_term"),
             &SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
             &SystemClauseType::RetractClause => clause_name!("$retract_clause"),
             &SystemClauseType::ResetBlock => clause_name!("$reset_block"),
@@ -326,6 +332,7 @@ impl SystemClauseType {
             ("$assertz", 4) => Some(SystemClauseType::AssertDynamicPredicateToBack),
             ("$char_code", 2) => Some(SystemClauseType::CharCode),
             ("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
+            ("$compile_batch", 0) => Some(SystemClauseType::REPL(REPLCodePtr::CompileBatch)),
             ("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap),
             ("$del_attr_non_head", 1) => Some(SystemClauseType::DeleteAttribute),
             ("$del_attr_head", 1) => Some(SystemClauseType::DeleteHeadAttribute),
@@ -375,6 +382,7 @@ impl SystemClauseType {
             ("$get_current_block", 1) => Some(SystemClauseType::GetCurrentBlock),
             ("$get_cp", 1) => Some(SystemClauseType::GetCutPoint),
             ("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
+            ("$read_term", 2) => Some(SystemClauseType::ReadTerm),
             ("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
             ("$reset_global_var_at_key", 1) => Some(SystemClauseType::ResetGlobalVarAtKey),
             ("$retract_clause", 4) => Some(SystemClauseType::RetractClause),
@@ -385,6 +393,8 @@ impl SystemClauseType {
             ("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
             ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
             ("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
+            ("$submit_query_and_print_results", 2) =>
+                Some(SystemClauseType::REPL(REPLCodePtr::SubmitQueryAndPrintResults)),
             ("$term_variables", 2) => Some(SystemClauseType::TermVariables),
             ("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
             ("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
@@ -397,7 +407,7 @@ impl SystemClauseType {
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd)]
 pub enum BuiltInClauseType {
     AcyclicTerm,
-    Arg, 
+    Arg,
     Compare,
     CompareTerm(CompareTermQT),
     CyclicTerm,
index 79319e95180f24c80d53c6a024bae0e88295b753..a106ded15be7b16d81fafc157350deb446409b3a 100644 (file)
@@ -398,6 +398,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
         printer
     }
 
+    pub fn drop_toplevel_spec(&mut self) {
+        self.toplevel_spec = None;
+    }
+
     #[inline]
     pub fn see_all_locs(&mut self) {
         for key in self.heap_locs.keys().cloned() {
@@ -559,8 +563,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
     fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<HeapCellValue>
     {
         iter.stack().last().cloned().and_then(|addr| {
-            let addr = self.machine_st.store(self.machine_st.deref(addr));
-
+            let addr = self.machine_st.store(self.machine_st.deref(addr));            
+            
             match self.heap_locs.get(&addr).cloned() {
                 Some(var) => if !self.printed_vars.contains(&addr) {
                     self.printed_vars.insert(addr);
index 6e87ff6671c435029373c84474c1e6768a470370..8036284e525609ab221460e12e7f820f1521caf2 100644 (file)
@@ -12,7 +12,7 @@
        char_code/2, clause/2, current_predicate/1, current_op/3,
        current_prolog_flag/2, expand_goal/2, expand_term/2,
        findall/3, findall/4, get_char/1, halt/0, once/1, op/3,
-       repeat/0, retract/1, set_prolog_flag/2, setof/3,
+       read_term/2, repeat/0, retract/1, set_prolog_flag/2, setof/3,
        setup_call_cleanup/3, term_variables/2, throw/1, true/0,
        false/0, write/1, write_canonical/1, writeq/1, write_term/2]).
 
@@ -231,10 +231,23 @@ inst_member_or([X|Xs], Y, _) :-
     ; throw(instantiation_error) ). % 8.14.2.3 b)
 inst_member_or([], Y, Y).
 
+%% TODO: complete the predicate! Most read options are missing.
+read_term(Term, Options) :-
+    '$skip_max_list'(_, -1, Options, Options0),
+    (  Options0 == [] -> true
+    ;  var(Options0)  -> throw(error(instantiation_error, read_term/2)) % 8.14.1.3 b)
+    ;  throw(error(type_error(list, Options), read_term/2)) % 8.14.1.3 d)
+    ),
+    (  Options = [variable_names(VarList)] -> '$read_term'(Term, VarList)
+    ;  Options = [] -> read(Term)
+    ;  false
+    ).
+    
 write_term(Term, Options) :-
     '$skip_max_list'(_, -1, Options, Options0),
-    ( Options0 == [] -> true
-    ; throw(error(type_error(list, Options), write_term/2)) ), % 8.14.2.3 c)
+    (  Options0 == [] -> true
+    ;  throw(error(type_error(list, Options), write_term/2))
+    ), % 8.14.2.3 c)
     inst_member_or(Options, ignore_ops(IgnoreOps), ignore_ops(false)),
     inst_member_or(Options, numbervars(NumberVars), numbervars(false)),
     inst_member_or(Options, quoted(Quoted), quoted(false)),
index 75dd8a17eb38d7104c0280e12a31a1e95b52e0da..15508363f3cac12d44c8b001d27f6e0316506b6d 100644 (file)
@@ -1,16 +1,13 @@
 :- module(dif, [dif/2]).
 
 :- use_module(library(atts)).
-:- use_module(library(ordsets)).
 
 :- attribute dif/1.
 
 put_dif_att(Var, X, Y) :-
     (   get_atts(Var, +dif(Z)) ->
-       ord_add_element(Z, X \== Y, NewZ),
-       (   Z == NewZ -> true
-       ;   put_atts(Var, +dif(NewZ))
-       )
+       sort([X \== Y | Z], NewZ),
+       put_atts(Var, +dif(NewZ))
     ;   put_atts(Var, +dif([X \== Y]))
     ).
 
index 747fc53292de5839320491074bdd23df0b01a9b3..40318a124ab3f976aaeb2d1622a0c266dd91fb6a 100644 (file)
@@ -1,5 +1,6 @@
 use prolog::machine::machine_indices::*;
 
+use std::mem;
 use std::ops::{Index, IndexMut};
 use std::vec::Vec;
 
@@ -8,7 +9,7 @@ pub struct Frame {
     pub global_index: usize,
     pub e: usize,
     pub cp: LocalCodePtr,
-    pub special_form_cp: LocalCodePtr,
+    pub interrupt_cp: LocalCodePtr,
     perms: Vec<Addr>
 }
 
@@ -18,7 +19,7 @@ impl Frame {
             global_index,
             e: e,
             cp: cp,
-            special_form_cp: LocalCodePtr::default(),
+            interrupt_cp: LocalCodePtr::default(),
             perms: (1 .. n+1).map(|i| Addr::StackCell(fr, i)).collect()
         }
     }
@@ -36,6 +37,11 @@ impl AndStack {
         AndStack(Vec::new())
     }
 
+    #[inline]
+    pub(crate) fn take(&mut self) -> Self {
+        AndStack(mem::replace(&mut self.0, vec![]))
+    }
+    
     pub fn push(&mut self, global_index: usize, e: usize, cp: LocalCodePtr, n: usize) {
         let len = self.0.len();
         self.0.push(Frame::new(global_index, len, e, cp, n));
index 9301fdfffee501f13a8baf351799d4d56545df9f..7062876027eb2da811c1e3adb4829f67496a4805 100644 (file)
@@ -57,14 +57,6 @@ impl MachineState {
         (var_list_addr, value_list_addr)
     }
 
-    pub(super)
-    fn calculate_register_threshold(&self) -> usize {
-        /* for all we know, all registers might be valid when we
-         * return from the verify_attributes interrupt. we currently
-         * lack a more precise way of determining this. */
-        MAX_ARITY
-    }
-
     fn verify_attributes(&mut self)
     {
         for (h, _) in &self.attr_var_init.bindings {
@@ -122,17 +114,17 @@ impl MachineState {
 
     pub(super)
     fn verify_attr_interrupt(&mut self, p: usize) {
-        let rs = self.calculate_register_threshold();
+        let rs = MAX_ARITY;
 
-        // store temp vars in perm vars slots along with
-        // self.b0 and self.num_of_args. why self.bo? if we return to a
-        // NeckCut after finishing the interrupt, it won't
-        // work correctly if self.b == self.b0. we must
-        // change it back when we return, as if nothing happened.
+        // store temp vars in perm vars slots along with self.b0 and
+        // self.num_of_args. why self.b0? if we return to a NeckCut
+        // after finishing the interrupt, it won't work correctly if
+        // self.b == self.b0. we must change it back when we return,
+        // as if nothing happened.
         self.allocate(rs + 2);
 
         let e = self.e;
-        self.and_stack[e].special_form_cp = self.attr_var_init.cp;
+        self.and_stack[e].interrupt_cp = self.attr_var_init.cp;
 
         for i in 1 .. rs + 1 {
             self.and_stack[e][i] = self[RegType::Temp(i)].clone();
@@ -193,7 +185,8 @@ impl Machine {
         self.machine_st[temp_v!(2)] = attr_vars;
 
         self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
-        self.machine_st.query_stepper(&mut self.indices, &mut self.policies, &mut self.code_repo);
+        self.machine_st.query_stepper(&mut self.indices, &mut self.policies, &mut self.code_repo,
+                                      &mut readline::input_stream());
 
         self.machine_st.print_attribute_goals_string(var_dict)
     }
index 2388459524ea0c379a061135e31c52a4867a6065..dce28eaa0ce2ec3392f039e36417011739d36813 100644 (file)
@@ -32,7 +32,7 @@ impl CodeRepo {
             term_dir: TermDir::new()
         }
     }
-
+    
     #[inline]
     pub fn term_dir_entry_len(&self, key: PredicateKey) -> (usize, usize) {
         self.term_dir.get(&key)
@@ -105,6 +105,8 @@ impl CodeRepo {
                 Some(RefOrOwned::Borrowed(&self.in_situ_code[p])),
             &CodePtr::Local(LocalCodePtr::DirEntry(p)) =>
                 Some(RefOrOwned::Borrowed(&self.code[p])),
+            &CodePtr::REPL(..) =>
+                None,
             &CodePtr::BuiltInClause(ref built_in, _) => {
                 let call_clause = call_clause!(ClauseType::BuiltIn(built_in.clone()),
                                                built_in.arity(),
index 559985fb46b7736081d6fd9563ecef97fdaf39cf..b2b1af20305557096487fe74f05bb94a37655516 100644 (file)
@@ -123,6 +123,7 @@ fn compile_query(terms: Vec<QueryTerm>, queue: VecDeque<TopLevel>, flags: Machin
     let mut code = try!(cg.compile_query(&terms));
 
     compile_appendix(&mut code, &queue, false, flags)?;
+
     Ok((code, cg.take_vars()))
 }
 
@@ -214,7 +215,8 @@ fn setup_module_expansions(wam: &mut Machine, module_name: ClauseName)
 }
 
 pub(super)
-fn compile_into_module<R: Read>(wam: &mut Machine, module_name: ClauseName, src: R, name: ClauseName)
+fn compile_into_module<R: Read>(wam: &mut Machine, module_name: ClauseName,
+                                src: ParsingStream<R>, name: ClauseName)
                                 -> EvalSession
 {
     let mut indices = default_index_store!(wam.atom_tbl_of(&name));
@@ -232,7 +234,8 @@ fn compile_into_module<R: Read>(wam: &mut Machine, module_name: ClauseName, src:
 }
 
 fn compile_into_module_impl<R: Read>(wam: &mut Machine, compiler: &mut ListingCompiler,
-                                     module_name: ClauseName, src: R, mut indices: IndexStore)
+                                     module_name: ClauseName, src: ParsingStream<R>,
+                                     mut indices: IndexStore)
                                      -> Result<(), SessionError>
 {
     setup_module_expansions(wam, module_name.clone());
@@ -556,7 +559,7 @@ impl ListingCompiler {
                 let spec = get_desc(op_decl.name(), composite_op!(self.module.is_some(),
                                                                   &wam_indices.op_dir,
                                                                   &mut indices.op_dir));
-                
+
                 op_decl.submit(self.get_module_name(), spec, &mut indices.op_dir)
             },
             Declaration::UseModule(name) =>
@@ -597,12 +600,13 @@ impl ListingCompiler {
     }
 
     pub(crate)
-    fn gather_items<R: Read>(&mut self, wam: &mut Machine, src: R, indices: &mut IndexStore)
+    fn gather_items<R: Read>(&mut self, wam: &mut Machine, mut src: ParsingStream<R>,
+                             indices: &mut IndexStore)
                              -> Result<GatherResult, SessionError>
     {
         let flags      = wam.machine_flags();
         let atom_tbl   = indices.atom_tbl.clone();
-        let mut worker = TopLevelBatchWorker::new(src, atom_tbl.clone(), flags,
+        let mut worker = TopLevelBatchWorker::new(&mut src, atom_tbl.clone(), flags,
                                                   &mut wam.indices, &mut wam.policies,
                                                   &mut wam.code_repo);
 
@@ -649,8 +653,8 @@ impl ListingCompiler {
     }
 }
 
-fn compile_work<R: Read>(compiler: &mut ListingCompiler, wam: &mut Machine, src: R,
-                         mut indices: IndexStore)
+fn compile_work<R: Read>(compiler: &mut ListingCompiler, wam: &mut Machine,
+                         src: ParsingStream<R>, mut indices: IndexStore)
                          -> EvalSession
 {
     let mut results = try_eval_session!(compiler.gather_items(wam, src, &mut indices));
@@ -693,7 +697,8 @@ fn compile_work<R: Read>(compiler: &mut ListingCompiler, wam: &mut Machine, src:
 /* This is a truncated version of compile_user_module, used for
    compiling code composing special forms, ie. the code that calls
    M:verify_attributes on attributed variables. */
-pub fn compile_special_form<R: Read>(wam: &mut Machine, src: R) -> Result<Code, SessionError>
+pub fn compile_special_form<R: Read>(wam: &mut Machine, src: ParsingStream<R>)
+                                     -> Result<Code, SessionError>
 {
     let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
     setup_indices(wam, clause_name!("builtins"), &mut indices)?;
@@ -705,7 +710,9 @@ pub fn compile_special_form<R: Read>(wam: &mut Machine, src: R) -> Result<Code,
 }
 
 #[inline]
-pub fn compile_listing<R: Read>(wam: &mut Machine, src: R, indices: IndexStore) -> EvalSession
+pub
+fn compile_listing<R: Read>(wam: &mut Machine, src: ParsingStream<R>, indices: IndexStore)
+                            -> EvalSession
 {
     let mut compiler = ListingCompiler::new(&wam.code_repo);
 
@@ -733,7 +740,7 @@ fn setup_indices(wam: &mut Machine, module: ClauseName, indices: &mut IndexStore
     }
 }
 
-pub fn compile_user_module<R: Read>(wam: &mut Machine, src: R) -> EvalSession {
+pub fn compile_user_module<R: Read>(wam: &mut Machine, src: ParsingStream<R>) -> EvalSession {
     let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
     try_eval_session!(setup_indices(wam, clause_name!("builtins"), &mut indices));
     compile_listing(wam, src, indices)
index 169613b4188e1cb4dc7de5ffc93640fabc27639c..abbb421dcf0f26591b51616a6f67bb4ebcfe2be6 100644 (file)
@@ -17,7 +17,8 @@ impl Machine {
         }
     }
 
-    fn compile_into_machine<R: Read>(&mut self, src: R, name: ClauseName, arity: usize) -> EvalSession
+    fn compile_into_machine<R: Read>(&mut self, src: ParsingStream<R>, name: ClauseName, arity: usize)
+                                     -> EvalSession
     {
         match name.owning_module().as_str() {
             "user" => match self.indices.code_dir.get(&(name.clone(), arity)).cloned() {
@@ -118,7 +119,7 @@ impl Machine {
     {
         let machine_st = mem::replace(&mut self.machine_st, MachineState::new());
 
-        let result = self.compile_into_machine(pred_str.as_bytes(), name, arity);
+        let result = self.compile_into_machine(parsing_stream(pred_str.as_bytes()), name, arity);
         self.machine_st = machine_st;
 
         if let EvalSession::Error(err) = result {
index b5141f08c8cf738800c659a73eb55eed26cf010d..d64654d9bb9a198722fcfc82dffefec0a578edee 100644 (file)
@@ -2,6 +2,7 @@ use prolog_parser::ast::*;
 
 use prolog::machine::machine_indices::*;
 
+use std::mem;
 use std::ops::{Index, IndexMut};
 
 pub struct Heap {
@@ -21,6 +22,17 @@ impl Heap {
         self.h += 1;
     }
 
+    #[inline]
+    pub(crate) fn take(&mut self) -> Self {
+        let h = self.h;
+        self.h = 0;
+
+        Heap {
+            heap: mem::replace(&mut self.heap, vec![]),
+            h
+        }
+    }
+
     #[inline]
     pub fn truncate(&mut self, h: usize) {
         self.h = h;
index d69bfef60a67cef2f6edf038d4d32d81670fceb2..b37fb6377aad29bb28eafcc99b9f371d5a01852d 100644 (file)
@@ -385,8 +385,6 @@ pub enum SessionError {
     NamelessEntry,
     OpIsInfixAndPostFix(ClauseName),
     ParserError(ParserError),
-    QueryFailure,
-    QueryFailureWithException(ClauseName),
     UserPrompt
 }
 
@@ -394,6 +392,7 @@ pub enum EvalSession {
     EntrySuccess,
     Error(SessionError),
     InitialQuerySuccess(AllocVarDict, HeapVarDict),
+    QueryFailure,
     SubsequentQuerySuccess,
 }
 
index 00945f0d6d4cea553a8af75e663103bb0b650e7d..07b1f25c9da3a83b280973f334412d5fca4cd909 100644 (file)
@@ -124,6 +124,24 @@ impl Add<usize> for Addr {
     }
 }
 
+impl Sub<i64> for Addr {
+    type Output = Addr;
+
+    fn sub(self, rhs: i64) -> Self::Output {
+        if rhs < 0 {
+            match self {
+                Addr::Lis(a) => Addr::Lis(a + rhs.abs() as usize),
+                Addr::AttrVar(h) => Addr::AttrVar(h + rhs.abs() as usize),
+                Addr::HeapCell(h) => Addr::HeapCell(h + rhs.abs() as usize),
+                Addr::Str(s) => Addr::Str(s + rhs.abs() as usize),
+                _ => self
+            }
+        } else {
+            self.sub(rhs as usize)
+        }
+    }
+}
+
 impl Sub<usize> for Addr {
     type Output = Addr;
 
@@ -260,13 +278,20 @@ pub enum DynamicTransactionType {
     Retract // dynamic index of the clause to remove.
 }
 
+#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
+pub enum REPLCodePtr {
+    CompileBatch,    
+    SubmitQueryAndPrintResults
+}
+
 #[derive(Clone, PartialEq)]
 pub enum CodePtr {
     BuiltInClause(BuiltInClauseType, LocalCodePtr), // local is the successor call.
     CallN(usize, LocalCodePtr), // arity, local.
     Local(LocalCodePtr),
     DynamicTransaction(DynamicTransactionType, LocalCodePtr), // the type of transaction, the return pointer.
-    VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir.
+    REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
+    VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir.    
 }
 
 impl CodePtr {
@@ -276,7 +301,8 @@ impl CodePtr {
           | &CodePtr::CallN(_, ref local)
           | &CodePtr::Local(ref local) => local.clone(),
             &CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
-            &CodePtr::DynamicTransaction(_, p) => p
+            &CodePtr::REPL(_, p)
+          | &CodePtr::DynamicTransaction(_, p) => p
         }
     }
 }
@@ -367,7 +393,8 @@ impl Add<usize> for CodePtr {
 
     fn add(self, rhs: usize) -> Self::Output {
         match self {
-            p @ CodePtr::VerifyAttrInterrupt(_)
+            p @ CodePtr::REPL(..)
+          | p @ CodePtr::VerifyAttrInterrupt(_)
           | p @ CodePtr::DynamicTransaction(..) => p,
             CodePtr::Local(local) => CodePtr::Local(local + rhs),
             CodePtr::CallN(_, local) | CodePtr::BuiltInClause(_, local) => CodePtr::Local(local + rhs)
@@ -412,7 +439,7 @@ pub struct IndexStore {
     pub(super) global_variables: GlobalVarDir,
     pub(super) in_situ_code_dir: InSituCodeDir,
     pub(super) modules: ModuleDir,
-    pub(super) op_dir: OpDir,    
+    pub(super) op_dir: OpDir,
 }
 
 impl IndexStore {    
@@ -475,6 +502,7 @@ impl IndexStore {
             in_situ_code_dir: InSituCodeDir::new(),
             op_dir: default_op_dir(),
             modules: ModuleDir::new(),
+//            parsing_stream: readline::parsing_stream(String::new())
         }
     }
 
index 656563c0783b4a3658f212b92d07b080a12bb8b8..c6200b7e37d520ddd68332d001b319c100cf9145 100644 (file)
@@ -12,12 +12,13 @@ use prolog::machine::machine_indices::*;
 use prolog::machine::modules::*;
 use prolog::machine::or_stack::*;
 use prolog::num::{BigInt, BigUint, Zero, One};
+use prolog::read::{PrologStream, readline};
 
 use downcast::Any;
 
 use std::cmp::Ordering;
-use std::io::{Write, stdin, stdout};
-use std::mem::swap;
+use std::io::{Write, stdout};
+use std::mem;
 use std::ops::{Index, IndexMut};
 use std::rc::Rc;
 
@@ -35,6 +36,16 @@ impl Ball {
         self.boundary = 0;
         self.stub.clear();
     }
+
+    pub(super) fn take(&mut self) -> Ball {
+        let boundary = self.boundary;
+        self.boundary = 0;
+        
+        Ball {
+            boundary,
+            stub: mem::replace(&mut self.stub, vec![])
+        }
+    }
 }
 
 pub(super) struct CopyTerm<'a> {
@@ -88,7 +99,7 @@ pub(super) struct CopyBallTerm<'a> {
     and_stack: &'a mut AndStack,
     heap: &'a mut Heap,
     heap_boundary: usize,
-    stub: &'a mut MachineStub,    
+    stub: &'a mut MachineStub,
 }
 
 impl<'a> CopyBallTerm<'a> {
@@ -227,7 +238,7 @@ pub struct MachineState {
     pub(crate) flags: MachineFlags
 }
 
-impl MachineState {
+impl MachineState {    
     fn call_at_index(&mut self, arity: usize, p: usize)
     {
         self.cp.assign_if_local(self.p.clone() + 1);
@@ -518,7 +529,7 @@ pub(crate) trait CallPolicy: Any {
     }
 
     fn call_builtin(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
-                    indices: &mut IndexStore)
+                    indices: &mut IndexStore, parsing_stream: &mut PrologStream)
                     -> CallResult
     {
         match ct {
@@ -572,10 +583,12 @@ pub(crate) trait CallPolicy: Any {
                 return_from_clause!(machine_st.last_call, machine_st)
             },
             &BuiltInClauseType::Read => {
-                match machine_st.read(stdin(), indices.atom_tbl.clone(), &indices.op_dir) {
+                readline::toggle_prompt(false);
+                
+                match machine_st.read(parsing_stream, indices.atom_tbl.clone(), &indices.op_dir) {
                     Ok(offset) => {
                         let addr = machine_st[temp_v!(1)].clone();
-                        machine_st.unify(addr, Addr::HeapCell(offset));
+                        machine_st.unify(addr, Addr::HeapCell(offset.heap_loc));
                     },
                     Err(e) => {
                         let h    = machine_st.heap.h;
@@ -695,7 +708,8 @@ pub(crate) trait CallPolicy: Any {
         Ok(())
     }
 
-    fn call_n(&mut self, machine_st: &mut MachineState, arity: usize, indices: &mut IndexStore)
+    fn call_n(&mut self, machine_st: &mut MachineState, arity: usize, indices: &mut IndexStore,
+              parsing_stream: &mut PrologStream)
               -> CallResult
     {
         if let Some((name, arity)) = machine_st.setup_call_n(arity) {
@@ -711,7 +725,7 @@ pub(crate) trait CallPolicy: Any {
                 },
                 ClauseType::BuiltIn(built_in) => {
                     machine_st.setup_built_in_call(built_in.clone());
-                    self.call_builtin(machine_st, &built_in, indices)?;
+                    self.call_builtin(machine_st, &built_in, indices, parsing_stream)?;
                 },
                 ClauseType::Inlined(inlined) => {
                     machine_st.execute_inlined(&inlined);
@@ -781,17 +795,18 @@ impl CallPolicy for CWILCallPolicy {
     }
 
     fn call_builtin(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
-                    indices: &mut IndexStore)
+                    indices: &mut IndexStore, parsing_stream: &mut PrologStream)
                     -> CallResult
     {
-        self.prev_policy.call_builtin(machine_st, ct, indices)?;
+        self.prev_policy.call_builtin(machine_st, ct, indices, parsing_stream)?;
         self.increment(machine_st)
     }
 
-    fn call_n(&mut self, machine_st: &mut MachineState, arity: usize, indices: &mut IndexStore)
+    fn call_n(&mut self, machine_st: &mut MachineState, arity: usize, indices: &mut IndexStore,
+              parsing_stream: &mut PrologStream)
               -> CallResult
     {
-        self.prev_policy.call_n(machine_st, arity, indices)?;
+        self.prev_policy.call_n(machine_st, arity, indices, parsing_stream)?;
         self.increment(machine_st)
     }
 }
@@ -813,7 +828,7 @@ impl CWILCallPolicy {
     pub(crate) fn new_in_place(policy: &mut Box<CallPolicy>)
     {
         let mut prev_policy: Box<CallPolicy> = Box::new(DefaultCallPolicy {});
-        swap(&mut prev_policy, policy);
+        mem::swap(&mut prev_policy, policy);
 
         let new_policy = CWILCallPolicy { prev_policy,
                                           count:  BigUint::zero(),
@@ -870,7 +885,7 @@ impl CWILCallPolicy {
 
     pub(crate) fn into_inner(&mut self) -> Box<CallPolicy> {
         let mut new_inner: Box<CallPolicy> = Box::new(DefaultCallPolicy {});
-        swap(&mut self.prev_policy, &mut new_inner);
+        mem::swap(&mut self.prev_policy, &mut new_inner);
         new_inner
     }
 }
index a59e3f14730825f3d693b2f22e4338aabaf75f45..59c7051046bb3634f8d381dc19b5cfbb155fd653 100644 (file)
@@ -17,9 +17,11 @@ use prolog::machine::machine_state::*;
 use prolog::num::{Integer, Signed, ToPrimitive, One, Zero};
 use prolog::num::bigint::{BigInt, BigUint};
 use prolog::num::rational::Ratio;
+use prolog::read::PrologStream;
 
 use std::cmp::{max, Ordering};
 use std::collections::{HashMap, HashSet};
+use std::mem;
 use std::rc::Rc;
 
 macro_rules! try_or_fail {
@@ -65,6 +67,36 @@ impl MachineState {
         }
     }
 
+    pub(crate) fn with_capacity(capacity: usize) -> Self {
+        MachineState {
+            s: 0,
+            p: CodePtr::default(),
+            b: 0,
+            b0: 0,
+            e: 0,
+            num_of_args: 0,
+            cp: LocalCodePtr::default(),
+            attr_var_init: AttrVarInitializer::new(0, 0),
+            fail: false,
+            heap: Heap::with_capacity(capacity),
+            mode: MachineMode::Write,
+            and_stack: AndStack::new(),
+            or_stack: OrStack::new(),
+            registers: vec![Addr::HeapCell(0); MAX_ARITY + 1], // self.registers[0] is never used.
+            trail: vec![],
+            pstr_trail: vec![],
+            pstr_tr: 0,
+            tr: 0,
+            hb: 0,
+            block: 0,
+            ball: Ball::new(),
+            lifted_heap: Vec::with_capacity(capacity),
+            interms: vec![Number::default(); 0],
+            last_call: false,
+            flags: MachineFlags::default()
+        }
+    }
+
     #[allow(dead_code)]
     pub fn print_heap(&self) {
         for h in 0 .. self.heap.h {
@@ -182,19 +214,6 @@ impl MachineState {
         output
     }
 
-    pub(super)
-    fn print_exception<Outputter>(&self, addr: Addr, var_dict: &HeapVarDict, output: Outputter)
-                                  -> Outputter
-      where Outputter: HCValueOutputter
-    {
-        let mut printer = HCPrinter::from_heap_locs(&self, output, var_dict);
-
-        printer.see_all_locs();
-        printer.quoted = true;
-
-        printer.print(addr)
-    }
-
     pub(super)
     fn unify_strings(&mut self, pdl: &mut Vec<Addr>, s1: &mut StringList, s2: &mut StringList) -> bool
     {
@@ -1546,27 +1565,24 @@ impl MachineState {
         self.fail = true;
     }
 
-    fn heap_ball_boundary_diff(&self) -> usize {
-        if self.ball.boundary > self.heap.h {
-            self.ball.boundary - self.heap.h
-        } else {
-            self.heap.h - self.ball.boundary
-        }
+    fn heap_ball_boundary_diff(&self) -> i64 {
+        self.ball.boundary as i64 - self.heap.h as i64
     }
 
-    pub(super) fn copy_and_align_ball_to_heap(&mut self, from: usize) -> usize {
+    pub(super) fn copy_and_align_ball(&self) -> MachineStub {
         let diff = self.heap_ball_boundary_diff();
+        let mut stub = vec![];
 
-        for index in from .. self.ball.stub.len() {
+        for index in 0 .. self.ball.stub.len() {
             let heap_value = self.ball.stub[index].clone();
 
-            self.heap.push(match heap_value {
+            stub.push(match heap_value {
                 HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
                 _ => heap_value
             });
         }
 
-        diff
+        stub
     }
 
     pub(crate) fn is_cyclic_term(&self, addr: Addr) -> bool {
@@ -2363,6 +2379,7 @@ impl MachineState {
     fn handle_call_clause(&mut self, indices: &mut IndexStore,
                           call_policy: &mut Box<CallPolicy>,
                           cut_policy:  &mut Box<CutPolicy>,
+                          parsing_stream: &mut PrologStream,
                           ct: &ClauseType,
                           arity: usize,
                           lco: bool,
@@ -2379,9 +2396,9 @@ impl MachineState {
 
         match ct {
             &ClauseType::BuiltIn(ref ct) =>
-                try_or_fail!(self, call_policy.call_builtin(self, ct, indices)),
+                try_or_fail!(self, call_policy.call_builtin(self, ct, indices, parsing_stream)),
             &ClauseType::CallN =>
-                try_or_fail!(self, call_policy.call_n(self, arity, indices)),
+                try_or_fail!(self, call_policy.call_n(self, arity, indices, parsing_stream)),
             &ClauseType::Hook(ref hook) =>
                 try_or_fail!(self, call_policy.compile_hook(self, hook)),
             &ClauseType::Inlined(ref ct) => {
@@ -2395,13 +2412,15 @@ impl MachineState {
                 try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone(),
                                                             indices)),
             &ClauseType::System(ref ct) =>
-                try_or_fail!(self, self.system_call(ct, indices, call_policy, cut_policy))
+                try_or_fail!(self, self.system_call(ct, indices, call_policy, cut_policy,
+                                                    parsing_stream))
         };
     }
 
     pub(super) fn execute_ctrl_instr(&mut self, indices: &mut IndexStore,
                                      call_policy: &mut Box<CallPolicy>,
                                      cut_policy:  &mut Box<CutPolicy>,
+                                     parsing_stream: &mut PrologStream,
                                      instr: &ControlInstruction)
     {
         match instr {
@@ -2409,7 +2428,8 @@ impl MachineState {
                 self.allocate(num_cells),
             &ControlInstruction::CallClause(ref ct, arity, _, lco, use_default_cp) =>
                 self.handle_call_clause(indices, call_policy, cut_policy,
-                                        ct, arity, lco, use_default_cp),
+                                        parsing_stream, ct, arity, lco,
+                                        use_default_cp),
             &ControlInstruction::Deallocate => self.deallocate(),
             &ControlInstruction::JmpBy(arity, offset, _, lco) => {
                 if !lco {
@@ -2569,4 +2589,58 @@ impl MachineState {
         self.ball.reset();
         self.lifted_heap.clear();
     }
+
+    pub(super)
+    fn sink_to_snapshot(&mut self) -> MachineState {
+        let mut snapshot = MachineState::with_capacity(0);
+        
+        snapshot.hb = self.hb;
+        snapshot.e = self.e;
+        snapshot.b = self.b;
+        snapshot.b0 = self.b0;
+        snapshot.s = self.s;
+        snapshot.tr = self.tr;
+        snapshot.pstr_tr = self.pstr_tr;
+        snapshot.num_of_args = self.num_of_args;
+
+        snapshot.fail = self.fail;
+        snapshot.trail = mem::replace(&mut self.trail, vec![]);
+        snapshot.pstr_trail = mem::replace(&mut self.pstr_trail, vec![]);
+        snapshot.heap = self.heap.take();        
+        snapshot.mode = self.mode;
+        snapshot.and_stack = self.and_stack.take();
+        snapshot.or_stack = self.or_stack.take();
+        snapshot.registers = mem::replace(&mut self.registers, vec![]);
+        snapshot.block = self.block;
+
+        snapshot.ball = self.ball.take();
+        snapshot.lifted_heap = mem::replace(&mut self.lifted_heap, vec![]);
+
+        snapshot
+    }
+
+    pub(super)
+    fn absorb_snapshot(&mut self, mut snapshot: MachineState) {
+        self.hb = snapshot.hb;
+        self.e = snapshot.e;
+        self.b = snapshot.b;
+        self.b0 = snapshot.b0;
+        self.s = snapshot.s;
+        self.tr = snapshot.tr;
+        self.pstr_tr = snapshot.pstr_tr;
+        self.num_of_args = snapshot.num_of_args;
+
+        self.fail = snapshot.fail;
+        self.trail = mem::replace(&mut snapshot.trail, vec![]);
+        self.pstr_trail = mem::replace(&mut snapshot.pstr_trail, vec![]);
+        self.heap = snapshot.heap.take();
+        self.mode = snapshot.mode;
+        self.and_stack = snapshot.and_stack.take();
+        self.or_stack = snapshot.or_stack.take();
+        self.registers = mem::replace(&mut snapshot.registers, vec![]);
+        self.block = snapshot.block;
+
+        self.ball = snapshot.ball.take();
+        self.lifted_heap = mem::replace(&mut snapshot.lifted_heap, vec![]);
+    }
 }
index cc9d6f6780719752308a855a024ccbbcde6e424a..c359efb5759184595c4e7e896a9f04af1811f1d0 100644 (file)
@@ -6,6 +6,8 @@ use prolog::fixtures::*;
 use prolog::forms::*;
 use prolog::heap_print::*;
 use prolog::instructions::*;
+use prolog::read::*;
+use prolog::write::{ContinueResult, next_keypress};
 
 pub mod machine_indices;
 pub mod heap;
@@ -32,12 +34,17 @@ use prolog::machine::machine_errors::*;
 use prolog::machine::machine_indices::*;
 use prolog::machine::machine_state::*;
 use prolog::machine::modules::*;
+use prolog::machine::toplevel::stream_to_toplevel;
+use prolog::read::PrologStream;
 
 use std::collections::{HashMap, VecDeque};
+use std::io::{Read, Write, stdout};
 use std::mem;
 use std::ops::Index;
 use std::rc::Rc;
 
+use termion::raw::{IntoRawMode};
+
 pub struct MachinePolicies {
     call_policy: Box<CallPolicy>,
     cut_policy: Box<CutPolicy>,
@@ -57,7 +64,9 @@ pub struct Machine {
     pub(super) machine_st: MachineState,
     pub(super) policies: MachinePolicies,
     pub(super) indices: IndexStore,
-    pub(super) code_repo: CodeRepo
+    pub(super) code_repo: CodeRepo,
+    pub(super) toplevel_idx: usize,
+    pub(super) prolog_stream: ParsingStream<Box<Read>>
 }
 
 impl Index<LocalCodePtr> for CodeRepo {
@@ -157,9 +166,11 @@ static REIF: &str     = include_str!("../lib/reif.pl");
 static ASSOC: &str    = include_str!("../lib/assoc.pl");
 static ORDSETS: &str  = include_str!("../lib/ordsets.pl");
 
+static TOPLEVEL: &str = include_str!("../toplevel.pl");
+
 impl Machine {
     fn compile_special_forms(&mut self) {
-        match compile_special_form(self, VERIFY_ATTRS.as_bytes()) {
+        match compile_special_form(self, parsing_stream(VERIFY_ATTRS.as_bytes())) {
             Ok(code) => {
                 self.machine_st.attr_var_init.verify_attrs_loc = self.code_repo.code.len();
                 self.code_repo.code.extend(code.into_iter());
@@ -167,7 +178,7 @@ impl Machine {
             Err(_) => panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS")
         }
 
-        match compile_special_form(self, PROJECT_ATTRS.as_bytes()) {
+        match compile_special_form(self, parsing_stream(PROJECT_ATTRS.as_bytes())) {
             Ok(code) => {
                 self.machine_st.attr_var_init.project_attrs_loc = self.code_repo.code.len();
                 self.code_repo.code.extend(code.into_iter());
@@ -176,37 +187,57 @@ impl Machine {
         }
     }
 
+    fn compile_top_level(&mut self) {
+        self.toplevel_idx = self.code_repo.code.len();
+        compile_user_module(self, parsing_stream(TOPLEVEL.as_bytes()));
+    }
+
     fn compile_libraries(&mut self) {
-        compile_user_module(self, NON_ISO.as_bytes());
-        compile_user_module(self, LISTS.as_bytes());
-        compile_user_module(self, QUEUES.as_bytes());
-        compile_user_module(self, ERROR.as_bytes());
-        compile_user_module(self, BETWEEN.as_bytes());
-       compile_user_module(self, TERMS.as_bytes());
-        compile_user_module(self, DCGS.as_bytes());
-        compile_user_module(self, ATTS.as_bytes());
-        compile_user_module(self, ORDSETS.as_bytes());
-        compile_user_module(self, DIF.as_bytes());
-        compile_user_module(self, FREEZE.as_bytes());
-        compile_user_module(self, REIF.as_bytes());
-        compile_user_module(self, ASSOC.as_bytes());
-    }
-
-    pub fn new() -> Self {
+        compile_user_module(self, parsing_stream(NON_ISO.as_bytes()));
+        compile_user_module(self, parsing_stream(LISTS.as_bytes()));
+        compile_user_module(self, parsing_stream(QUEUES.as_bytes()));
+        compile_user_module(self, parsing_stream(ERROR.as_bytes()));
+        compile_user_module(self, parsing_stream(BETWEEN.as_bytes()));
+       compile_user_module(self, parsing_stream(TERMS.as_bytes()));
+        compile_user_module(self, parsing_stream(DCGS.as_bytes()));
+        compile_user_module(self, parsing_stream(ATTS.as_bytes()));
+        compile_user_module(self, parsing_stream(ORDSETS.as_bytes()));
+        compile_user_module(self, parsing_stream(DIF.as_bytes()));
+        compile_user_module(self, parsing_stream(FREEZE.as_bytes()));
+        compile_user_module(self, parsing_stream(REIF.as_bytes()));
+        compile_user_module(self, parsing_stream(ASSOC.as_bytes()));
+    }
+
+    #[cfg(test)]    
+    pub fn reset(&mut self) {
+        self.prolog_stream = readline::input_stream();
+        self.policies.cut_policy = Box::new(DefaultCutPolicy {});
+        self.machine_st.reset();
+    }
+    
+    pub fn run_toplevel(&mut self) {
+        self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(self.toplevel_idx));
+        self.run_query(&AllocVarDict::new(), &mut HeapVarDict::new());
+    }
+
+    pub fn new(prolog_stream: PrologStream) -> Self {
         let mut wam = Machine {
             machine_st: MachineState::new(),
             policies: MachinePolicies::new(),
             indices: IndexStore::new(),
-            code_repo: CodeRepo::new()
+            code_repo: CodeRepo::new(),
+            toplevel_idx: 0,
+            prolog_stream
         };
 
         let atom_tbl = wam.indices.atom_tbl.clone();
 
-        compile_listing(&mut wam, BUILTINS.as_bytes(),
+        compile_listing(&mut wam, parsing_stream(BUILTINS.as_bytes()),
                         default_index_store!(atom_tbl.clone()));
 
         wam.compile_libraries();
         wam.compile_special_forms();
+        wam.compile_top_level();
 
         wam
     }
@@ -251,7 +282,7 @@ impl Machine {
 
         Ok(())
     }
-        
+
     pub fn add_batched_code(&mut self, code: Code, code_dir: CodeDir)
     {
         // error detection has finished, so update the master index of keys.
@@ -283,33 +314,15 @@ impl Machine {
         self.code_repo.code.extend(code.into_iter());
     }
 
-    fn fail(&mut self) -> EvalSession
-    {
-        if self.machine_st.ball.stub.len() > 0 {
-            let h = self.machine_st.heap.h;
-            self.machine_st.copy_and_align_ball_to_heap(0);
-
-            let err_str = self.machine_st.print_exception(Addr::HeapCell(h),
-                                                          &HeapVarDict::new(),
-                                                          PrinterOutputter::new())
-                .result();
-
-            let err_str = clause_name!(err_str, self.indices.atom_tbl());
-            EvalSession::from(SessionError::QueryFailureWithException(err_str))
-        } else {
-            EvalSession::from(SessionError::QueryFailure)
-        }
-    }
-
     pub fn submit_query(&mut self, code: Code, alloc_locs: AllocVarDict) -> EvalSession
     {
-        let mut heap_locs = HashMap::new();
+        let mut heap_locs = HeapVarDict::new();
 
         self.code_repo.cached_query = code;
         self.run_query(&alloc_locs, &mut heap_locs);
 
         if self.machine_st.fail {
-            self.fail()
+            EvalSession::QueryFailure
         } else {
             EvalSession::InitialQuerySuccess(alloc_locs, heap_locs)
         }
@@ -341,6 +354,194 @@ impl Machine {
         }
     }
 
+    pub fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
+        let h = self.machine_st.heap.h;
+
+        let err  = MachineError::session_error(h, err);
+        let stub = MachineError::functor_stub(key.0, key.1);
+        let err  = self.machine_st.error_form(err, stub);
+
+        self.machine_st.throw_exception(err);
+        return;
+    }
+
+    fn handle_toplevel_command(&mut self, code_ptr: REPLCodePtr, p: LocalCodePtr)
+    {
+        match code_ptr {
+            REPLCodePtr::CompileBatch => {
+                #[cfg(feature = "readline_rs_compat")]
+                readline::set_line_mode(readline::LineMode::Multi);
+
+                let src = match readline::read_batch("") {
+                    Ok(src) => src,
+                    Err(e) => {
+                        self.throw_session_error(e, (clause_name!("repl"), 0));
+                        return;
+                    }
+                };
+
+                #[cfg(feature = "readline_rs_compat")]
+                readline::set_line_mode(readline::LineMode::Single);
+
+                match compile_user_module(self, parsing_stream(&src[0 ..])) {
+                    EvalSession::Error(e) =>
+                        self.throw_session_error(e, (clause_name!("repl"), 0)),
+                    _ => {}
+                };
+            },
+            REPLCodePtr::SubmitQueryAndPrintResults => {
+                let term = self.machine_st[temp_v!(1)].clone();
+                let stub = MachineError::functor_stub(clause_name!("repl"), 0);
+
+                let s = match self.machine_st.try_from_list(temp_v!(2), stub) {
+                    Ok(addrs) => {
+                        let mut var_dict = HeapVarDict::new();
+
+                        for addr in addrs {
+                            match addr {
+                                Addr::Str(s) => {
+                                    let var_atom = match self.machine_st.heap[s+1].as_addr(s+1) {
+                                        Addr::Con(Constant::Atom(var_atom, _)) =>
+                                            Rc::new(var_atom.to_string()),
+                                        _ => unreachable!()
+                                    };
+
+                                    let var_addr = self.machine_st.heap[s+2].as_addr(s+2);
+                                    var_dict.insert(var_atom, var_addr);
+                                },
+                                _ => unreachable!()
+                            };
+                        }
+
+                        let term_output = self.machine_st.print_with_locs(term, &var_dict);
+                        term_output.result()
+                    },
+                    Err(err_stub) => {
+                        self.machine_st.throw_exception(err_stub);
+                        return;
+                    }
+                };
+
+                let stream = parsing_stream(s.as_bytes());
+
+                let snapshot = self.machine_st.sink_to_snapshot();
+                self.machine_st.reset();
+
+                let result = match stream_to_toplevel(stream, self) {
+                    Ok(packet) => compile_term(self, packet),
+                    Err(e) => EvalSession::from(e)
+                };
+
+                self.handle_eval_session(result, snapshot);
+            }
+        }
+
+        self.machine_st.p = CodePtr::Local(p);
+    }
+
+    fn handle_eval_session(&mut self, result: EvalSession, snapshot: MachineState) {
+        match result {
+            EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) =>
+                loop {
+                    let bindings = {
+                        let mut output = PrinterOutputter::new();
+                        self.toplevel_heap_view(&heap_locs, output).result()
+                    };
+
+                    let attr_goals = self.attribute_goals(&heap_locs);
+
+                    if !(self.machine_st.b > 0) {
+                        if bindings.is_empty() {
+                            if !attr_goals.is_empty() {
+                                println!("{}.", attr_goals);
+                            } else {
+                                println!("true.");
+                            }
+
+                            self.machine_st.absorb_snapshot(snapshot);
+                            return;
+                        }
+                    } else if bindings.is_empty() && attr_goals.is_empty() {
+                        print!("true");
+                        stdout().flush().unwrap();
+                    }
+
+                    let mut raw_stdout = stdout().into_raw_mode().unwrap();
+
+                    if !attr_goals.is_empty() {
+                        if bindings.is_empty() {
+                            write!(raw_stdout, "{}", attr_goals).unwrap();
+                        } else {
+                            write!(raw_stdout, "{}, {}", bindings, attr_goals).unwrap();
+                        }
+                    } else if !bindings.is_empty() {
+                        write!(raw_stdout, "{}", bindings).unwrap();
+                    }
+
+                    if self.machine_st.b > 0 {
+                        raw_stdout.flush().unwrap();
+
+                        let result = match next_keypress(raw_stdout) {
+                            ContinueResult::ContinueQuery =>
+                                self.continue_query(&alloc_locs, &mut heap_locs),
+                            ContinueResult::Conclude => {
+                                self.machine_st.absorb_snapshot(snapshot);
+                                return;
+                            }
+                        };
+
+                        let mut raw_stdout = stdout().into_raw_mode().unwrap();
+
+                        match result {
+                            EvalSession::QueryFailure => {
+                                write!(raw_stdout, "false.\r\n").unwrap();
+                                raw_stdout.flush().unwrap();
+                                
+                                self.machine_st.absorb_snapshot(snapshot);
+                                return;
+                            },
+                            EvalSession::Error(err) => {
+                                self.machine_st.absorb_snapshot(snapshot);
+                                self.throw_session_error(err, (clause_name!("repl"), 0));
+                                return;
+                            },
+                            _ => {}
+                        }
+                    } else {
+                        if bindings.is_empty() && attr_goals.is_empty() {
+                            write!(raw_stdout, "true.\r\n").unwrap();
+                        } else {
+                            write!(raw_stdout, ".\r\n").unwrap();
+                        }
+
+                        break;
+                    }
+                },
+            EvalSession::Error(err) => {
+                self.machine_st.absorb_snapshot(snapshot);
+                self.throw_session_error(err, (clause_name!("repl"), 0));
+                return;
+            },
+            EvalSession::QueryFailure =>
+                if self.machine_st.ball.stub.len() > 0 {
+                    let ball = self.machine_st.ball.take();
+                    
+                    self.machine_st.absorb_snapshot(snapshot);
+                    self.machine_st.ball = ball;
+                    
+                    let stub = self.machine_st.copy_and_align_ball();
+                    self.machine_st.throw_exception(stub);
+
+                    return;
+                } else {
+                    println!("false.");
+                },
+            _ => {}
+        }
+
+        self.machine_st.absorb_snapshot(snapshot);
+    }
+
     pub(super)
     fn run_query(&mut self, alloc_locs: &AllocVarDict, heap_locs: &mut HeapVarDict)
     {
@@ -359,10 +560,13 @@ impl Machine {
                 self.machine_st.p = top_level_code_ptr!(cn, p);
             }
 
-            self.machine_st.query_stepper(&mut self.indices, &mut self.policies, &mut self.code_repo);
+            self.machine_st.query_stepper(&mut self.indices, &mut self.policies, &mut self.code_repo,
+                                          &mut self.prolog_stream);
 
             match self.machine_st.p {
                 CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {},
+                CodePtr::REPL(code_ptr, p) =>
+                    self.handle_toplevel_command(code_ptr, p),
                 CodePtr::DynamicTransaction(trans_type, p) => {
                     // self.code_repo.cached_query is about to be overwritten by the term expander,
                     // so hold onto it locally and restore it after the compiler has finished.
@@ -399,21 +603,22 @@ impl Machine {
             self.machine_st.p = self.machine_st.or_stack[b].bp.clone();
 
             if let CodePtr::Local(LocalCodePtr::TopLevel(_, 0)) = self.machine_st.p {
-                return EvalSession::from(SessionError::QueryFailure);
+                self.machine_st.fail = true;
+                return EvalSession::QueryFailure;
             }
 
             self.run_query(alloc_l, heap_l);
 
             if self.machine_st.fail {
-                self.fail()
+                EvalSession::QueryFailure
             } else {
                 EvalSession::SubsequentQuerySuccess
             }
         } else {
-            EvalSession::from(SessionError::QueryFailure)
+            EvalSession::QueryFailure
         }
     }
-    
+
     pub fn toplevel_heap_view<Outputter>(&self, var_dir: &HeapVarDict, mut output: Outputter) -> Outputter
        where Outputter: HCValueOutputter
     {
@@ -422,11 +627,6 @@ impl Machine {
 
         for (var, addr) in sorted_vars {
             let addr = self.machine_st.store(self.machine_st.deref(addr.clone()));
-
-//            if addr.is_ref() {
-//                continue;
-//            }
-
             output = self.machine_st.print_var_eq(var.clone(), addr, var_dir, output);
         }
 
@@ -450,22 +650,12 @@ impl Machine {
     pub fn or_stack_is_empty(&self) -> bool {
         self.machine_st.b == 0
     }
-
-    pub fn clear(&mut self) {
-        let mut machine = Machine::new();
-        mem::swap(self, &mut machine);
-    }
-
-    pub fn reset(&mut self) {
-        self.policies.cut_policy = Box::new(DefaultCutPolicy {});
-        self.machine_st.reset();
-    }
 }
 
 
 impl MachineState {
     fn execute_instr(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies,
-                     code_repo: &CodeRepo)
+                     code_repo: &CodeRepo, prolog_stream: &mut PrologStream)
     {
         let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
             Some(instr) => instr,
@@ -481,7 +671,8 @@ impl MachineState {
                 self.execute_cut_instr(cut_instr, &mut policies.cut_policy),
             &Line::Control(ref control_instr) =>
                 self.execute_ctrl_instr(indices, &mut policies.call_policy,
-                                        &mut policies.cut_policy, control_instr),
+                                        &mut policies.cut_policy, prolog_stream,
+                                        control_instr),
             &Line::Fact(ref fact_instr) => {
                 self.execute_fact_instr(&fact_instr);
                 self.p += 1;
@@ -516,10 +707,10 @@ impl MachineState {
     }
 
     fn query_stepper(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies,
-                     code_repo: &mut CodeRepo)
+                     code_repo: &mut CodeRepo, prolog_stream: &mut PrologStream)
     {
         loop {
-            self.execute_instr(indices, policies, code_repo);
+            self.execute_instr(indices, policies, code_repo, prolog_stream);
 
             if self.fail {
                 self.backtrack();
@@ -538,7 +729,7 @@ impl MachineState {
                     self.fail = true,
                 CodePtr::Local(LocalCodePtr::InSituDirEntry(p))
                     if p < code_repo.in_situ_code.len() => {},
-                CodePtr::Local(_) =>
+                CodePtr::Local(_) | CodePtr::REPL(..) =>
                     break,
                 CodePtr::VerifyAttrInterrupt(p) =>
                     self.verify_attr_interrupt(p),
@@ -546,7 +737,7 @@ impl MachineState {
                     // prevent use of dynamic transactions from
                     // succeeding in expansions. this will be toggled
                     // back to true later.
-                    self.fail = true; 
+                    self.fail = true;
                     break;
                 },
                 _ => {}
index 4c189548c3576bca2ab0663b226b641b5f1ff328..5fc9fab0576884f7035f72146d88e65beeca1dec 100644 (file)
@@ -1,5 +1,6 @@
 use prolog::machine::machine_indices::*;
 
+use std::mem;
 use std::ops::{Index, IndexMut};
 use std::vec::Vec;
 
@@ -74,6 +75,11 @@ impl OrStack {
         self.0.push(Frame::new(global_index, e, cp, attr_var_init_b, b, bp, tr, pstr_tr, h, b0, n));
     }
 
+    #[inline]
+    pub(crate) fn take(&mut self) -> Self {
+        OrStack(mem::replace(&mut self.0, vec![]))
+    }
+
     pub fn len(&self) -> usize {
         self.0.len()
     }
index ebf42e07d9a7a92bf6c8b75fa77cdc8356cce188..de4f6e75d3c05969687e9a41fdf91caeb1ec9049 100644 (file)
@@ -11,11 +11,12 @@ use prolog::machine::machine_state::*;
 use prolog::machine::toplevel::to_op_decl;
 use prolog::num::{FromPrimitive, ToPrimitive, Zero};
 use prolog::num::bigint::{BigInt};
+use prolog::read::{PrologStream, readline};
 
 use ref_thread_local::RefThreadLocal;
 
 use std::collections::HashSet;
-use std::io::{stdout, Read, Write};
+use std::io::{stdout, Write};
 use std::iter::once;
 use std::mem;
 use std::rc::Rc;
@@ -201,6 +202,17 @@ impl MachineState {
         threshold + lh_offset + 2
     }
 
+    fn repl_redirect(&mut self, repl_code_ptr: REPLCodePtr) -> CallResult {
+        let p = if self.last_call {
+            self.cp
+        } else {
+            self.p.local() + 1
+        };
+
+        self.p = CodePtr::REPL(repl_code_ptr, p);
+        return Ok(());
+    }
+
     fn truncate_if_no_lifted_heap_diff<AddrConstr>(&mut self, addr_constr: AddrConstr)
        where AddrConstr: Fn(usize) -> Addr
     {
@@ -301,7 +313,8 @@ impl MachineState {
                               ct: &SystemClauseType,
                               indices: &mut IndexStore,
                               call_policy: &mut Box<CallPolicy>,
-                              cut_policy:  &mut Box<CutPolicy>)
+                              cut_policy:  &mut Box<CutPolicy>,
+                              parsing_stream: &mut PrologStream)
                               -> CallResult
     {
         match ct {
@@ -498,7 +511,7 @@ impl MachineState {
                     },
                     ref addr if addr.is_ref() => {
                         let a2 = self[temp_v!(2)].clone();
-                        
+
                         match self.store(self.deref(a2)) {
                             Addr::Con(Constant::CharCode(code)) =>
                                 self.unify(Addr::Con(Constant::Char(code as char)), addr.clone()),
@@ -542,23 +555,21 @@ impl MachineState {
                 };
             },
             &SystemClauseType::GetChar => {
-                let c = std::io::stdin()
-                    .bytes() 
-                    .next()
-                    .and_then(|result| result.ok());
+                readline::toggle_prompt(false);
 
+                let result = parsing_stream.next();
                 let a1 = self[temp_v!(1)].clone();
-                
-                match c {
-                    Some(c) => self.unify(Addr::Con(Constant::Char(c as char)), a1),
-                    None => {
+
+                match result {
+                    Some(Ok(b)) => self.unify(Addr::Con(Constant::Char(b as char)), a1),
+                    _ => {
                         let stub = MachineError::functor_stub(clause_name!("get_char"), 1);
                         let err = MachineError::representation_error(RepFlag::Character);
                         let err = self.error_form(err, stub);
 
                         return Err(err);
                     }
-                }                
+                }
             },
             &SystemClauseType::GetModuleClause => {
                 let module = self[temp_v!(3)].clone();
@@ -1228,6 +1239,8 @@ impl MachineState {
                     None => panic!("remove_inference_counter: requires \\
                                     CWILCallPolicy.")
                 },
+            &SystemClauseType::REPL(repl_code_ptr) =>
+                return self.repl_redirect(repl_code_ptr),
             &SystemClauseType::ModuleRetractClause => {
                 let p = self.cp;
                 let trans_type = DynamicTransactionType::ModuleRetract;
@@ -1249,7 +1262,6 @@ impl MachineState {
             },
             &SystemClauseType::ReturnFromVerifyAttr => {
                 let e = self.e;
-
                 let frame_len = self.and_stack[e].len();
 
                 for i in 1 .. frame_len - 1 {
@@ -1264,7 +1276,7 @@ impl MachineState {
                     self.num_of_args = num_of_args;
                 }
 
-                self.p = CodePtr::Local(self.and_stack[e].special_form_cp);
+                self.p = CodePtr::Local(self.and_stack[e].interrupt_cp);
                 self.deallocate();
 
                 return Ok(());
@@ -1334,7 +1346,8 @@ impl MachineState {
                 let h = self.heap.h;
 
                 if self.ball.stub.len() > 0 {
-                    self.copy_and_align_ball_to_heap(0);
+                    let stub = self.copy_and_align_ball();
+                    self.heap.append(stub);
                 } else {
                     self.fail = true;
                     return Ok(());
@@ -1391,6 +1404,51 @@ impl MachineState {
             &SystemClauseType::InstallNewBlock => {
                 self.install_new_block(temp_v!(1));
             },
+            &SystemClauseType::ReadTerm => {
+                readline::toggle_prompt(true);
+
+                match self.read(parsing_stream, indices.atom_tbl.clone(), &indices.op_dir) {
+                    Ok(term_write_result) => {
+                        let a1 = self[temp_v!(1)].clone();
+                        self.unify(Addr::HeapCell(term_write_result.heap_loc), a1);
+
+                        if self.fail {
+                            return Ok(());
+                        }
+
+                        let mut list_of_var_eqs = vec![];
+
+                        for (var, binding) in term_write_result.var_dict {
+                            let var_atom = clause_name!(var.to_string(), indices.atom_tbl);
+                            let var_atom = Constant::Atom(var_atom, None);
+
+                            let h = self.heap.h;
+                            let op_desc = Some(SharedOpDesc::new(700, XFX));
+
+                            self.heap.push(HeapCellValue::NamedStr(2, clause_name!("="), op_desc));
+                            self.heap.push(HeapCellValue::Addr(Addr::Con(var_atom)));
+                            self.heap.push(HeapCellValue::Addr(binding));
+
+                            list_of_var_eqs.push(Addr::Str(h));
+                        }
+
+                        let a2 = self[temp_v!(2)].clone();
+                        let list_offset = Addr::HeapCell(self.heap.to_list(list_of_var_eqs.into_iter()));
+
+                        self.unify(list_offset, a2);
+                    },
+                    Err(err) => {
+                        // reset the input stream after an input failure.
+                        *parsing_stream = readline::input_stream();
+
+                        let h = self.heap.h;
+                        let syntax_error = MachineError::syntax_error(h, err);
+                        let stub = MachineError::functor_stub(clause_name!("read_term"), 2);
+
+                        return Err(self.error_form(syntax_error, stub));
+                    }
+                }
+            },
             &SystemClauseType::ResetBlock => {
                 let addr = self.deref(self[temp_v!(1)].clone());
                 self.reset_block(addr);
@@ -1414,43 +1472,19 @@ impl MachineState {
             &SystemClauseType::Succeed => {},
             &SystemClauseType::TermVariables => {
                 let a1 = self[temp_v!(1)].clone();
-                let mut vars = Vec::new();
-
-                {
-                    let iter = self.acyclic_pre_order_iter(a1);
-
-                    for item in iter {
-                        match item {
-                            HeapCellValue::Addr(Addr::AttrVar(h)) =>
-                                vars.push(Ref::AttrVar(h)),
-                            HeapCellValue::Addr(Addr::HeapCell(h)) =>
-                                vars.push(Ref::HeapCell(h)),
-                            HeapCellValue::Addr(Addr::StackCell(fr, sc)) =>
-                                vars.push(Ref::StackCell(fr, sc)),
-                            _ => {}
-                        }
-                    }
-                }
-
-                let mut h = self.heap.h;
-                let outcome = Addr::HeapCell(h);
-
                 let mut seen_vars = HashSet::new();
 
-                for r in vars {
-                    if seen_vars.contains(&r) {
-                        continue;
+                for item in self.acyclic_pre_order_iter(a1) {
+                    match item {
+                        HeapCellValue::Addr(addr) =>
+                            if addr.is_ref() {
+                                seen_vars.insert(addr);
+                            },
+                        _ => {}
                     }
-
-                    self.heap.push(HeapCellValue::Addr(Addr::Lis(h+1)));
-                    self.heap.push(HeapCellValue::Addr(r.as_addr()));
-
-                    h += 2;
-
-                    seen_vars.insert(r);
                 }
 
-                self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::EmptyList)));
+                let outcome = Addr::HeapCell(self.heap.to_list(seen_vars.into_iter()));
 
                 let a2 = self[temp_v!(2)].clone();
                 self.unify(a2, outcome);
index d94569fb8d6479c40c526458b8cadb2622c354e3..72999709adfe84b70352728d0d7d6a94d11c2428 100644 (file)
@@ -4,7 +4,6 @@ use prolog_parser::parser::*;
 use prolog::machine::*;
 use prolog::machine::machine_indices::HeapCellValue;
 use prolog::num::*;
-use prolog::read::*;
 
 use std::cell::Cell;
 use std::collections::VecDeque;
@@ -74,7 +73,7 @@ pub struct TermStream<'a, R: Read> {
     pub(crate) indices: &'a mut IndexStore,
     policies: &'a mut MachinePolicies,
     pub(crate) code_repo: &'a mut CodeRepo,
-    parser: Parser<R>,
+    parser: Parser<'a, R>,
     in_module: bool,
     pub(crate) flags: MachineFlags,
     term_expansion_lens: (usize, usize),
@@ -111,7 +110,7 @@ impl<'a, R: Read> Drop for TermStream<'a, R> {
 }
 
 impl<'a, R: Read> TermStream<'a, R> {
-    pub fn new(src: R, atom_tbl: TabledData<Atom>, flags: MachineFlags,
+    pub fn new(src: &'a mut ParsingStream<R>, atom_tbl: TabledData<Atom>, flags: MachineFlags,
                indices: &'a mut IndexStore, policies: &'a mut MachinePolicies,
                code_repo: &'a mut CodeRepo)
                -> Self
@@ -129,6 +128,11 @@ impl<'a, R: Read> TermStream<'a, R> {
         }
     }
 
+    #[inline]
+    pub fn add_to_top(&mut self, buf: &str) {
+        self.parser.add_to_top(buf);
+    }
+
     #[inline]
     pub fn incr_expansion_lens(&mut self, hook: CompileTimeHook, len: usize, queue_len: usize) {
         match hook {
@@ -185,14 +189,16 @@ impl<'a, R: Read> TermStream<'a, R> {
             },
             Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) =>
                 Ok(self.stack.push(term)),
-            _ => Err(ParserError::ExpectedTopLevelTerm)
+            _ =>
+                Err(ParserError::ExpectedTopLevelTerm)
         }
     }
 
     fn parse_expansion_output(&self, term_string: &str, op_dir: &OpDir) -> Result<Term, ParserError>
     {
-        let mut parser = Parser::new(term_string.trim().as_bytes(), self.parser.get_atom_tbl(),
-                                     self.flags);
+        let mut stream = parsing_stream(term_string.trim().as_bytes());
+        let mut parser = Parser::new(&mut stream, self.parser.get_atom_tbl(), self.flags);
+
         parser.read_term(composite_op!(self.in_module, &self.indices.op_dir, op_dir))
     }
 
@@ -230,24 +236,23 @@ impl<'a, R: Read> TermStream<'a, R> {
         match term {
             Term::Clause(cell, name, mut terms, arity) => {
                 let mut new_terms = {
-                    let old_terms = if name.as_str() == ":-" && terms.len() == 2 {
-                        let comma_term = *terms.pop().unwrap();
-                        unfold_by_str(comma_term, ",")
-                    } else if name.as_str() == "?-" && terms.len() == 1 {
-                        let comma_term = *terms.pop().unwrap();
-                        unfold_by_str(comma_term, ",")
-                    } else {
-                        return Ok(Term::Clause(cell, name, terms, arity));
+                    let old_terms = match (name.as_str(), terms.len()) {
+                        (":-", 2) => {
+                            let comma_term = *terms.pop().unwrap();
+                            unfold_by_str(comma_term, ",")
+                        },
+                        ("?-", 1) =>
+                            unfold_by_str(*terms.pop().unwrap(), ","),
+                        _ => return Ok(Term::Clause(cell, name, terms, arity))
                     };
 
                     self.expand_goals(machine_st, op_dir, VecDeque::from(old_terms))?
                 };
 
                 let initial_term = new_terms.pop().unwrap();
-
                 terms.push(Box::new(fold_by_str(new_terms.into_iter(), initial_term,
                                                 clause_name!(","))));
-                Ok(Term::Clause(cell, name, terms, None))
+                Ok(Term::Clause(cell, name, terms, arity))
             },
             _ =>
                 Ok(term)
@@ -302,6 +307,8 @@ impl MachineState {
         // style variable names will be longer than the keys of the var_dict, and therefore
         // not equal to any of them.
         printer.numbervars_offset = pow(BigInt::from(10), max_var_length) * 26;
+        printer.drop_toplevel_spec();
+
         printer.see_all_locs();
 
         let mut output = printer.print(addr);
@@ -324,7 +331,7 @@ impl MachineState {
         let code = vec![call_clause!(ClauseType::Hook(hook), 2, 0, true)];
 
         code_repo.cached_query = code;
-        self.query_stepper(indices, policies, code_repo);
+        self.query_stepper(indices, policies, code_repo, &mut readline::input_stream());
 
         if self.fail {
             self.reset();
index 0b2ba52e73f1ea0b129708fea7d109f90fdf66eb..65ed9c9a798252851c61dc7c1a600d031eae8a64 100644 (file)
@@ -681,6 +681,18 @@ impl RelationWorker {
         }
     }
 
+    fn try_term_to_query(&mut self, indices: &mut CompositeIndices, terms: Vec<Box<Term>>, blocks_cuts: bool)
+                         -> Result<TopLevel, ParserError>
+    {
+        match setup_declaration(terms.iter().cloned().collect()) {
+            Ok(Declaration::Op(..)) => {}, // this is now a predicate call in the query context.
+            Ok(decl) => return Ok(TopLevel::Declaration(decl)),
+            _ => {}
+        };
+
+        Ok(TopLevel::Query(self.setup_query(indices, terms, blocks_cuts)?))
+    }
+
     fn try_term_to_tl(&mut self, indices: &mut CompositeIndices, term: Term, blocks_cuts: bool)
                       -> Result<TopLevel, ParserError>
     {
@@ -692,13 +704,7 @@ impl RelationWorker {
 
                     Ok(TopLevel::Declaration(Declaration::Hook(hook, clause, queue)))
                 } else if name.as_str() == "?-" {
-                    match setup_declaration(terms.iter().cloned().collect()) {
-                        Ok(Declaration::Op(..)) => {}, // this is now a predicate call in the query context.
-                        Ok(decl) => return Ok(TopLevel::Declaration(decl)),
-                        _ => {}
-                    };
-
-                    Ok(TopLevel::Query(self.setup_query(indices, terms, blocks_cuts)?))
+                    self.try_term_to_query(indices, terms, blocks_cuts)
                 } else if name.as_str() == ":-" && terms.len() == 2 {
                     Ok(TopLevel::Rule(self.setup_rule(indices, terms, blocks_cuts, true)?))
                 } else if name.as_str() == ":-" && terms.len() == 1 {
@@ -770,21 +776,24 @@ fn term_to_toplevel<R>(term_stream: &mut TermStream<R>, code_dir: &mut CodeDir,
     let mut indices = composite_indices!(false, term_stream.indices, code_dir);
 
     let tl = rel_worker.try_term_to_tl(&mut indices, term, true)?;
+
     Ok((tl, rel_worker))
 }
 
 pub
-fn string_to_toplevel<R: Read>(buffer: R, wam: &mut Machine) -> Result<TopLevelPacket, SessionError>
+fn stream_to_toplevel<R: Read>(mut buffer: ParsingStream<R>, wam: &mut Machine)
+                               -> Result<TopLevelPacket, SessionError>
 {
-    let mut term_stream = TermStream::new(buffer, wam.indices.atom_tbl(),
+    let mut term_stream = TermStream::new(&mut buffer, wam.indices.atom_tbl(),
                                           wam.machine_flags(), &mut wam.indices,
                                           &mut wam.policies, &mut wam.code_repo);
 
+    term_stream.add_to_top("?- ");
+
     let term = term_stream.read_term(&OpDir::new())?;
     let mut code_dir = CodeDir::new();
 
     let (tl, mut rel_worker) = term_to_toplevel(&mut term_stream, &mut code_dir, term)?;
-
     rel_worker.expand_queue_contents(&mut term_stream, &OpDir::new())?;
 
     let mut indices = composite_indices!(false, term_stream.indices, &mut code_dir);
@@ -804,7 +813,8 @@ pub struct TopLevelBatchWorker<'a, R: Read> {
 }
 
 impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
-    pub fn new(inner: R, atom_tbl: TabledData<Atom>,
+
+    pub fn new(inner: &'a mut ParsingStream<R>, atom_tbl: TabledData<Atom>,
                flags: MachineFlags, indices: &'a mut IndexStore,
                policies: &'a mut MachinePolicies, code_repo: &'a mut CodeRepo)
                -> Self
index 1506486851bdb4219b57943bd2b0d14063f1a1ff..8808713679ed954b19aa55c62c565024bd7ede6b 100644 (file)
@@ -4,7 +4,6 @@ use prolog_parser::tabled_rc::TabledData;
 
 use prolog::forms::*;
 use prolog::iterators::*;
-use prolog::machine::machine_errors::*;
 use prolog::machine::machine_indices::*;
 use prolog::machine::machine_state::MachineState;
 
@@ -24,16 +23,14 @@ impl<'a> TermRef<'a> {
     }
 }
 
-pub enum Input {
-    Clear,
-    Batch,
-    TermString(String)
-}
+pub type PrologStream = ParsingStream<Box<Read>>;
 
 #[cfg(feature = "readline_rs_compat")]
 pub mod readline
 {
+    use prolog_parser::ast::*;
     use readline_rs_compat::readline::*;
+    use std::io::{Error, Read};
 
     #[derive(Clone, Copy)]
     pub enum LineMode {
@@ -41,9 +38,74 @@ pub mod readline
         Multi
     }
 
+    pub struct ReadlineStream {
+        pending_input: String
+    }
+
+    impl ReadlineStream {
+        #[inline]
+        fn new(pending_input: String) -> Self {
+            ReadlineStream { pending_input }
+        }
+
+        fn call_readline(&mut self, prompt: &str, buf: &mut [u8]) -> std::io::Result<usize> {
+            match readline_rl(prompt) {
+                Some(text) => {
+                    self.pending_input += &text;
+                    Ok(self.write_to_buf(buf))
+                },
+                None => Err(Error::last_os_error())
+            }
+        }
+
+        fn split_pending(&mut self, buf: &mut [u8], split_idx: usize) -> usize {
+            let (outgoing, _) = self.pending_input.split_at(split_idx);
+
+            for (idx, b) in outgoing.bytes().enumerate() {
+                buf[idx] = b;
+            }
+
+            outgoing.len()
+        }
+
+        fn write_to_buf(&mut self, buf: &mut [u8]) -> usize {
+            let split_idx = std::cmp::min(self.pending_input.len(), buf.len());
+            let output_len = self.split_pending(buf, split_idx);
+
+            if split_idx < self.pending_input.len() {
+                self.pending_input = self.pending_input[split_idx ..].to_string();
+            } else {
+                self.pending_input.clear();
+            }
+
+            output_len
+        }
+    }
+
+    impl Read for ReadlineStream {
+        fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
+            if self.pending_input.is_empty() {
+                let prompt = unsafe {
+                    if PRINT_PROMPT { "?- " } else { "" }
+                };
+
+                self.call_readline(prompt, buf)
+            } else {
+                Ok(self.write_to_buf(buf))
+            }
+        }
+    }
+
+    static mut PRINT_PROMPT: bool = true;
     static mut LINE_MODE: LineMode = LineMode::Single;
     static mut END_OF_LINE: bool = false;
 
+    pub fn toggle_prompt(on_or_off: bool) {
+        unsafe {
+            PRINT_PROMPT = on_or_off;
+        }
+    }
+
     pub fn set_line_mode(mode: LineMode) {
         unsafe {
             LINE_MODE = mode;
@@ -52,13 +114,6 @@ pub mod readline
         }
     }
 
-    fn is_directive(buf: &str) -> bool {
-        match buf {
-            "?- [user]." | "?- [clear]." => true,
-            _ => false
-        }
-    }
-
     unsafe extern "C" fn bind_end_chord(_: i32, _: i32) -> i32 {
         if let LineMode::Multi = LINE_MODE {
             rl_done = 1;
@@ -67,26 +122,9 @@ pub mod readline
         0
     }
 
-    unsafe extern "C" fn bind_end_key(_: i32, _: i32) -> i32 {
-        insert_text_rl(".");
-
-        if let LineMode::Single = LINE_MODE {
-            END_OF_LINE = true;
-        }
-
-        0
-    }
-
     unsafe extern "C" fn bind_cr(_: i32, _: i32) -> i32 {
-        if END_OF_LINE {
-            if let Some(buf) = rl_line_buffer_as_str() {
-                if is_directive(buf) {
-                    println!("");
-                    rl_done = 1;
-                    return 0;
-                }
-            }
-
+        if let LineMode::Single = LINE_MODE {
+            insert_text_rl("\n");
             println!("");
             rl_done = 1;
         } else {
@@ -103,24 +141,11 @@ pub mod readline
             panic!("initialize_rl() failed with return code {}", rc);
         }
 
-        unsafe {
-            rl_startup_hook = insert_query_prompt;
-        }
-
-        bind_key_rl('.' as i32, bind_end_key);
         bind_key_rl('\n' as i32, bind_cr);
         bind_key_rl('\r' as i32, bind_cr);
         bind_keyseq_rl("\\C-d", bind_end_chord);
     }
 
-    unsafe extern "C" fn insert_query_prompt() -> i32 {
-        if let LineMode::Single = LINE_MODE {
-            insert_text_rl("?- ");
-        }
-
-        0
-    }
-
     pub fn read_batch(prompt: &str) -> Result<Vec<u8>, ::SessionError> {
         match readline_rl(prompt) {
             Some(input) => Ok(Vec::from(input.as_bytes())),
@@ -128,18 +153,41 @@ pub mod readline
         }
     }
 
-    pub fn read_line(prompt: &str) -> Result<String, ::SessionError> {
-        match readline_rl(prompt) {
-            Some(input) => Ok(String::from(input)),
-            None => Err(::SessionError::UserPrompt)
-        }
+    #[inline]
+    pub fn input_stream() -> ::PrologStream {
+        let reader: Box<Read> = Box::new(ReadlineStream::new(String::from("")));
+        parsing_stream(reader)
     }
 }
 
 #[cfg(not(feature = "readline_rs_compat"))]
 pub mod readline
 {
-    use std::io::{BufRead, Read, stdin, stdout, Write};
+    use prolog_parser::ast::*;
+    use std::io::{BufReader, Read, Stdin, Write, stdin, stdout};
+
+    static mut PRINT_PROMPT: bool = false;
+
+    struct StdinWrapper {
+        buf: BufReader<Stdin>
+    }
+
+    fn print_prompt() {
+        unsafe {
+            if PRINT_PROMPT {
+                print!("?- ");
+                stdout().flush().unwrap();
+                PRINT_PROMPT = false;
+            }
+        }
+    }
+
+    impl Read for StdinWrapper {
+        fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
+            print_prompt();
+            self.buf.read(buf)
+        }
+    }
 
     pub fn read_batch(_: &str) -> Result<Vec<u8>, ::SessionError> {
         let mut buf = vec![];
@@ -153,54 +201,30 @@ pub mod readline
         }
     }
 
-    pub fn read_line(_: &str) -> Result<String, ::SessionError> {
-        print!("?- ");
-        stdout().flush().unwrap();
-
-        let stdin = stdin();
-        let stdin = stdin.lock();
+    #[inline]
+    pub fn input_stream() -> ::PrologStream {
+        print_prompt();
 
-        let mut buf = "?- ".to_string();
+        let reader: Box<Read> = Box::new(StdinWrapper { buf: BufReader::new(stdin()) });
+        parsing_stream(reader)
+    }
 
-        for line in stdin.lines() {
-            match line {
-                Ok(line) => {
-                    buf += &line;
 
-                    if line.trim().ends_with(".") {
-                        break;
-                    }
-                },
-                _ => return Err(::SessionError::UserPrompt)
-            }
+    pub fn toggle_prompt(on_or_off: bool) {
+        unsafe {
+            PRINT_PROMPT = on_or_off;
         }
-
-        Ok(buf)
     }
 }
 
-pub fn toplevel_read_line() -> Result<Input, SessionError>
-{
-    let buffer = readline::read_line("")?;
-
-    Ok(match &*buffer.trim() {
-        "?- [clear]." => Input::Clear,
-        "?- [user]." => {
-            println!("(type Enter + Ctrl-D to terminate the stream when finished)");
-            Input::Batch
-        },
-        _ => Input::TermString(buffer)
-    })
-}
-
 impl MachineState {
-    pub fn read<R: Read>(&mut self, inner: R, atom_tbl: TabledData<Atom>, op_dir: &OpDir)
-                         -> Result<usize, ParserError>
+    pub fn read(&mut self, inner: &mut PrologStream, atom_tbl: TabledData<Atom>, op_dir: &OpDir)
+                -> Result<TermWriteResult, ParserError>
     {
         let mut parser = Parser::new(inner, atom_tbl, self.flags);
         let term = parser.read_term(composite_op!(op_dir))?;
 
-        Ok(write_term_to_heap(&term, self).heap_loc)
+        Ok(write_term_to_heap(&term, self))
     }
 }
 
@@ -220,12 +244,13 @@ fn modify_head_of_queue(machine_st: &mut MachineState, queue: &mut SubtermDeque,
     }
 }
 
-pub(crate) struct TermWriteResult {
+pub struct TermWriteResult {
     pub(crate) heap_loc: usize,
     pub(crate) var_dict: HeapVarDict,
 }
 
-pub(crate) fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult
+pub(crate)
+fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult
 {
     let heap_loc = machine_st.heap.h;
 
diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl
new file mode 100644 (file)
index 0000000..55a044d
--- /dev/null
@@ -0,0 +1,19 @@
+repl :-
+    catch(read_and_match, E, '$print_exception'(E)),
+    false. %% this is for GC, until we get actual GC.
+repl :- repl.
+    
+read_and_match :-
+    read_term(Term, [variable_names(VarList)]),
+    '$instruction_match'(Term, VarList).
+
+'$instruction_match'([user], []) :-
+    !, '$compile_batch'.
+'$instruction_match'(Term, VarList) :-
+    '$submit_query_and_print_results'(Term, VarList),
+    !.
+
+'$print_exception'(E) :-
+    write_term('error: exception thrown: ', [quoted(false)]),
+    writeq(E),
+    nl.
index cc83ad0386a13d0194b5fe8c246e7f03157940a8..682e7e03820745158481f8e71d444e4b427dffcc 100644 (file)
@@ -1,22 +1,16 @@
 use prolog::clause_types::*;
 use prolog::forms::*;
-use prolog::heap_print::*;
 use prolog::instructions::*;
-use prolog::machine::*;
 use prolog::machine::machine_errors::*;
 use prolog::machine::machine_indices::*;
 
-use termion::raw::{IntoRawMode, RawTerminal};
 use termion::input::TermRead;
 use termion::event::Key;
+use termion::raw::{RawTerminal};
 
-use std::io::{Write, stdin, stdout};
+use std::io::{Write, stdin};
 use std::fmt;
 
-fn error_string<StringT: AsRef<str>>(e: &StringT) -> String {
-    format!("error: exception thrown: {}", e.as_ref())
-}
-
 impl fmt::Display for LocalCodePtr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -34,6 +28,17 @@ impl fmt::Display for LocalCodePtr {
     }
 }
 
+impl fmt::Display for REPLCodePtr {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            REPLCodePtr::CompileBatch =>
+                write!(f, "REPLCodePtr::CompileBatch"),
+            REPLCodePtr::SubmitQueryAndPrintResults =>
+                write!(f, "REPLCodePtr::SubmitQueryAndPrintResults")
+        }
+    }
+}
+
 impl fmt::Display for IndexPtr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -262,10 +267,6 @@ impl fmt::Display for SessionError {
             &SessionError::ModuleNotFound => write!(f, "module not found."),
             &SessionError::ModuleDoesNotContainExport =>
                 write!(f, "module does not contain claimed export."),
-            &SessionError::QueryFailure =>
-                write!(f, "false."),
-            &SessionError::QueryFailureWithException(ref e) =>
-                write!(f, "{}", error_string(e)),
             &SessionError::OpIsInfixAndPostFix(_) =>
                 write!(f, "cannot define an op to be both postfix and infix."),
             &SessionError::NamelessEntry =>
@@ -302,7 +303,7 @@ impl fmt::Display for ArithmeticInstruction {
             &ArithmeticInstruction::Pow(ref a1, ref a2, ref t) =>
                 write!(f, "** {}, {}, @{}", a1, a2, t),
             &ArithmeticInstruction::IntPow(ref a1, ref a2, ref t) =>
-                write!(f, "^ {}, {}, @{}", a1, a2, t),            
+                write!(f, "^ {}, {}, @{}", a1, a2, t),
             &ArithmeticInstruction::Div(ref a1, ref a2, ref t) =>
                 write!(f, "div {}, {}, @{}", a1, a2, t),
             &ArithmeticInstruction::IDiv(ref a1, ref a2, ref t) =>
@@ -357,12 +358,13 @@ impl fmt::Display for Level {
     }
 }
 
-enum ContinueResult {
+pub enum ContinueResult {
     ContinueQuery,
     Conclude
 }
 
-fn next_step(mut stdout: RawTerminal<std::io::Stdout>) -> ContinueResult
+pub
+fn next_keypress(mut stdout: RawTerminal<std::io::Stdout>) -> ContinueResult
 {
     let stdin = stdin();
 
@@ -382,81 +384,3 @@ fn next_step(mut stdout: RawTerminal<std::io::Stdout>) -> ContinueResult
 
     ContinueResult::Conclude
 }
-
-pub fn print(wam: &mut Machine, result: EvalSession) {
-    match result {
-        EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) =>
-            loop {
-                let bindings = {
-                    let mut output = PrinterOutputter::new();
-                    wam.toplevel_heap_view(&heap_locs, output).result()
-                };
-
-                let attr_goals = wam.attribute_goals(&heap_locs);
-
-                if wam.or_stack_is_empty() {
-                    if bindings.is_empty() {
-                        if !attr_goals.is_empty() {
-                            println!("{}.", attr_goals);
-                        } else {
-                            println!("true.");
-                        }
-
-                        return;
-                    }
-                } else if bindings.is_empty() && attr_goals.is_empty() {
-                    print!("true");
-                    stdout().flush().unwrap();
-                }
-
-                let mut raw_stdout = stdout().into_raw_mode().unwrap();
-
-                if !attr_goals.is_empty() {
-                    if bindings.is_empty() {
-                        write!(raw_stdout, "{}", attr_goals).unwrap();
-                    } else {
-                        write!(raw_stdout, "{}, {}", bindings, attr_goals).unwrap();
-                    }
-                } else if !bindings.is_empty() {
-                    write!(raw_stdout, "{}", bindings).unwrap();
-                }
-
-                if !wam.or_stack_is_empty() {
-                    raw_stdout.flush().unwrap();
-
-                    let result = match next_step(raw_stdout) {
-                        ContinueResult::ContinueQuery =>
-                            wam.continue_query(&alloc_locs, &mut heap_locs),
-                        ContinueResult::Conclude =>
-                            return
-                    };
-
-                    let mut raw_stdout = stdout().into_raw_mode().unwrap();
-
-                    if let &EvalSession::Error(SessionError::QueryFailure) = &result
-                    {
-                        write!(raw_stdout, "false.\r\n").unwrap();
-                        raw_stdout.flush().unwrap();
-                        return;
-                    }
-
-                    if let &EvalSession::Error(SessionError::QueryFailureWithException(ref e)) = &result
-                    {
-                        write!(raw_stdout, "{}\r\n", error_string(e)).unwrap();
-                        raw_stdout.flush().unwrap();
-                        return;
-                    }
-                } else {
-                    if bindings.is_empty() && attr_goals.is_empty() {
-                        write!(raw_stdout, "true.\r\n").unwrap();
-                    } else {
-                        write!(raw_stdout, ".\r\n").unwrap();
-                    }
-
-                    break;
-                }
-            },
-        EvalSession::Error(e) => println!("{}", e),
-        _ => {}
-    };
-}
index 9f3a2ecacaa1d01331dae3f6223e86c6a210aa72..f6d788fffb57e47c7d312e5ee754ee9ecf32607d 100644 (file)
@@ -1,9 +1,12 @@
+use prolog_parser::ast::parsing_stream;
+
 use prolog::heap_print::*;
 use prolog::machine::*;
 use prolog::machine::compile::*;
 use prolog::machine::machine_errors::*;
 use prolog::machine::machine_indices::*;
 use prolog::machine::toplevel::*;
+use prolog::read::readline;
 
 use std::collections::HashSet;
 use std::mem::swap;
@@ -133,7 +136,7 @@ pub fn submit(wam: &mut Machine, buffer: &str) -> bool
 {
     wam.reset();
 
-    match compile_user_module(wam, buffer.as_bytes()) {
+    match submit_code(wam, buffer) {
         EvalSession::InitialQuerySuccess(_, _) |
         EvalSession::EntrySuccess |
         EvalSession::SubsequentQuerySuccess =>
@@ -147,7 +150,7 @@ pub fn submit_query(wam: &mut Machine, buffer: &str, result: Vec<HashSet<String>
 {
     wam.reset();
 
-    match string_to_toplevel(buffer.as_bytes(), wam) {
+    match stream_to_toplevel(parsing_stream(buffer.as_bytes()), wam) {
         Ok(term) =>
             match compile_term(wam, term) {
                 EvalSession::InitialQuerySuccess(alloc_locs, heap_locs) =>
@@ -164,7 +167,7 @@ pub fn submit_query_without_results(wam: &mut Machine, buffer: &str) -> bool
 {
     wam.reset();
 
-    match string_to_toplevel(buffer.as_bytes(), wam) {
+    match stream_to_toplevel(parsing_stream(buffer.as_bytes()), wam) {
         Ok(term) =>
             match compile_term(wam, term) {
                 EvalSession::InitialQuerySuccess(..)
@@ -182,7 +185,7 @@ pub fn submit_query_with_limit(wam: &mut Machine, buffer: &str,
 {
     wam.reset();
 
-    match string_to_toplevel(buffer.as_bytes(), wam) {
+    match stream_to_toplevel(parsing_stream(buffer.as_bytes()), wam) {
         Ok(term) =>
             match compile_term(wam, term) {
                 EvalSession::InitialQuerySuccess(alloc_locs, heap_locs) =>
@@ -195,6 +198,11 @@ pub fn submit_query_with_limit(wam: &mut Machine, buffer: &str,
     }
 }
 
+#[allow(dead_code)]
+pub fn submit_code(wam: &mut Machine, buf: &str) -> EvalSession {
+    compile_user_module(wam, parsing_stream(buf.as_bytes()))
+}
+
 #[allow(unused_macros)]
 macro_rules! expand_strs {
     ($arr:expr) => (
@@ -229,154 +237,154 @@ macro_rules! assert_prolog_success {
 #[test]
 fn test_queries_on_facts()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     submit(&mut wam, "p(Z, Z).");
     submit(&mut wam, "clouds(are, nice).");
 
-    assert_prolog_success!(&mut wam, "?- p(Z, Z).", [["Z = _0"]]);
-    assert_prolog_success!(&mut wam, "?- p(Z, z).", [["Z = z"]]);
-    assert_prolog_success!(&mut wam, "?- p(Z, w).", [["Z = w"]]);
+    assert_prolog_success!(&mut wam, "p(Z, Z).", [["Z = _0"]]);
+    assert_prolog_success!(&mut wam, "p(Z, z).", [["Z = z"]]);
+    assert_prolog_success!(&mut wam, "p(Z, w).", [["Z = w"]]);
 
-    assert_prolog_failure!(&mut wam, "?- p(z, w).");
+    assert_prolog_failure!(&mut wam, "p(z, w).");
 
-    assert_prolog_success!(&mut wam, "?- p(w, w).");
+    assert_prolog_success!(&mut wam, "p(w, w).");
 
-    assert_prolog_failure!(&mut wam, "?- clouds(Z, Z).");
+    assert_prolog_failure!(&mut wam, "clouds(Z, Z).");
 
-    assert_prolog_success!(&mut wam, "?- clouds(are, Z).", [["Z = nice"]]);
-    assert_prolog_success!(&mut wam, "?- clouds(Z, nice).", [["Z = are"]]);
+    assert_prolog_success!(&mut wam, "clouds(are, Z).", [["Z = nice"]]);
+    assert_prolog_success!(&mut wam, "clouds(Z, nice).", [["Z = are"]]);
 
     submit(&mut wam, "p(Z, h(Z, W), f(W)).");
 
-    assert_prolog_failure!(&mut wam, "?- p(z, h(z, z), f(w)).");
-    assert_prolog_success!(&mut wam, "?- p(z, h(z, w), f(w)).");
-    assert_prolog_success!(&mut wam, "?- p(z, h(z, W), f(w)).", [["W = w"]]);
-    assert_prolog_success!(&mut wam, "?- p(Z, h(Z, w), f(Z)).", [["Z = w"]]);
-    assert_prolog_failure!(&mut wam, "?- p(z, h(Z, w), f(Z)).");
+    assert_prolog_failure!(&mut wam, "p(z, h(z, z), f(w)).");
+    assert_prolog_success!(&mut wam, "p(z, h(z, w), f(w)).");
+    assert_prolog_success!(&mut wam, "p(z, h(z, W), f(w)).", [["W = w"]]);
+    assert_prolog_success!(&mut wam, "p(Z, h(Z, w), f(Z)).", [["Z = w"]]);
+    assert_prolog_failure!(&mut wam, "p(z, h(Z, w), f(Z)).");
 
     submit(&mut wam, "p(f(X), h(Y, f(a)), Y).");
 
-    assert_prolog_success!(&mut wam, "?- p(Z, h(Z, W), f(W)).", [["W = f(a)", "Z = f(f(a))"]]);
+    assert_prolog_success!(&mut wam, "p(Z, h(Z, W), f(W)).", [["W = f(a)", "Z = f(f(a))"]]);
 }
 
 #[test]
 fn test_queries_on_rules() {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     submit(&mut wam, "p(X, Y) :- q(X, Z), r(Z, Y).");
     submit(&mut wam, "q(q, s).");
     submit(&mut wam, "r(s, t).");
 
-    assert_prolog_success!(&mut wam, "?- p(X, Y).", [["Y = t", "X = q"]]);
-    assert_prolog_success!(&mut wam, "?- p(q, t).");
-    assert_prolog_failure!(&mut wam, "?- p(t, q).");
-    assert_prolog_success!(&mut wam, "?- p(q, T).", [["T = t"]]);
-    assert_prolog_failure!(&mut wam, "?- p(t, t).");
+    assert_prolog_success!(&mut wam, "p(X, Y).", [["Y = t", "X = q"]]);
+    assert_prolog_success!(&mut wam, "p(q, t).");
+    assert_prolog_failure!(&mut wam, "p(t, q).");
+    assert_prolog_success!(&mut wam, "p(q, T).", [["T = t"]]);
+    assert_prolog_failure!(&mut wam, "p(t, t).");
 
     submit(&mut wam, "p(X, Y) :- q(f(f(X)), R), r(S, T).");
     submit(&mut wam, "q(f(f(X)), r).");
 
-    assert_prolog_success!(&mut wam, "?- p(X, Y).", [["X = _0", "Y = _1"]]);
+    assert_prolog_success!(&mut wam, "p(X, Y).", [["X = _0", "Y = _1"]]);
 
     submit(&mut wam, "q(f(f(x)), r).");
 
-    assert_prolog_success!(&mut wam, "?- p(X, Y).", [["X = x", "Y = _1"]]);
+    assert_prolog_success!(&mut wam, "p(X, Y).", [["X = x", "Y = _1"]]);
 
     submit(&mut wam, "p(X, Y) :- q(X, Y), r(X, Y).");
     submit(&mut wam, "q(s, t).");
     submit(&mut wam, "r(X, Y) :- r(a).");
     submit(&mut wam, "r(a).");
 
-    assert_prolog_success!(&mut wam, "?- p(X, Y).", [["X = s", "Y = t"]]);
-    assert_prolog_failure!(&mut wam, "?- p(t, S).");
-    assert_prolog_success!(&mut wam, "?- p(s, T).", [["T = t"]]);
-    assert_prolog_success!(&mut wam, "?- p(S, t).", [["S = s"]]);
+    assert_prolog_success!(&mut wam, "p(X, Y).", [["X = s", "Y = t"]]);
+    assert_prolog_failure!(&mut wam, "p(t, S).");
+    assert_prolog_success!(&mut wam, "p(s, T).", [["T = t"]]);
+    assert_prolog_success!(&mut wam, "p(S, t).", [["S = s"]]);
 
     submit(&mut wam, "p(f(f(a), g(b), X), g(b), h) :- q(X, Y).");
     submit(&mut wam, "q(X, Y).");
 
-    assert_prolog_success!(&mut wam,  "?- p(f(X, Y, Z), g(b), h).",
+    assert_prolog_success!(&mut wam,  "p(f(X, Y, Z), g(b), h).",
                            [["Z = _3", "Y = g(b)", "X = f(a)"]]);
-    assert_prolog_failure!(&mut wam, "?- p(f(X, g(Y), Z), g(Z), X).");
-    assert_prolog_success!(&mut wam, "?- p(f(X, g(Y), Z), g(Z), h).",
+    assert_prolog_failure!(&mut wam, "p(f(X, g(Y), Z), g(Z), X).");
+    assert_prolog_success!(&mut wam, "p(f(X, g(Y), Z), g(Z), h).",
                            [["Z = b", "Y = b", "X = f(a)"]]);
-    assert_prolog_success!(&mut wam, "?- p(Z, Y, X).",
+    assert_prolog_success!(&mut wam, "p(Z, Y, X).",
                            [["X = h", "Y = g(b)", "Z = f(f(a), g(b), _7)"]]);
-    assert_prolog_success!(&mut wam, "?- p(f(X, Y, Z), Y, h).",
+    assert_prolog_success!(&mut wam, "p(f(X, Y, Z), Y, h).",
                            [["Y = g(b)", "Z = _3", "X = f(a)"]]);
 
     submit(&mut wam, "p(_, f(_, Y, _)) :- h(Y).");
     submit(&mut wam, "h(y).");
 
-    assert_prolog_success!(&mut wam, "?- p(_, f(_, Y, _)).", [["Y = y"]]);
-    assert_prolog_success!(&mut wam, "?- p(_, f(_, y, _)).");
-    assert_prolog_failure!(&mut wam, "?- p(_, f(_, z, _)).");
+    assert_prolog_success!(&mut wam, "p(_, f(_, Y, _)).", [["Y = y"]]);
+    assert_prolog_success!(&mut wam, "p(_, f(_, y, _)).");
+    assert_prolog_failure!(&mut wam, "p(_, f(_, z, _)).");
 }
 
 #[test]
 fn test_queries_on_predicates() {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     submit(&mut wam, "p(X, a). p(b, X).");
 
-    assert_prolog_success!(&mut wam, "?- p(x, Y).", [["Y = a"]]);
-    assert_prolog_success!(&mut wam, "?- p(X, a).", [["X = _0"],  // 1st case
+    assert_prolog_success!(&mut wam, "p(x, Y).", [["Y = a"]]);
+    assert_prolog_success!(&mut wam, "p(X, a).", [["X = _0"],  // 1st case
                                                      ["X = b"]]); // 2nd case.
-    assert_prolog_success!(&mut wam, "?- p(b, X).", [["X = a"],  // 1st case
+    assert_prolog_success!(&mut wam, "p(b, X).", [["X = a"],  // 1st case
                                                      ["X = _0"]]); // 2nd case.
-    assert_prolog_success!(&mut wam, "?- p(X, X).", [["X = a"],
+    assert_prolog_success!(&mut wam, "p(X, X).", [["X = a"],
                                                      ["X = b"]]);
-    assert_prolog_success!(&mut wam, "?- p(b, a).");
-    assert_prolog_failure!(&mut wam, "?- p(a, b).");
+    assert_prolog_success!(&mut wam, "p(b, a).");
+    assert_prolog_failure!(&mut wam, "p(a, b).");
 
     submit(&mut wam, "p(X, Y, a). p(X, a, Y). p(X, Y, a).");
 
-    assert_prolog_success!(&mut wam, "?- p(c, d, X).", [["X = a"],
+    assert_prolog_success!(&mut wam, "p(c, d, X).", [["X = a"],
                                                         ["X = a"]]);
-    assert_prolog_success!(&mut wam, "?- p(a, a, a).");
-    assert_prolog_failure!(&mut wam, "?- p(b, c, d).");
+    assert_prolog_success!(&mut wam, "p(a, a, a).");
+    assert_prolog_failure!(&mut wam, "p(b, c, d).");
 
     submit(&mut wam, "p(X, a). p(X, Y) :- q(Z), p(X, X).");
 
-    assert_prolog_success!(&mut wam, "?- p(X, Y).", [["X = _0", "Y = a"]]);
-    assert_prolog_success!(&mut wam, "?- p(x, a).");
-    assert_prolog_success!(&mut wam, "?- p(X, a).", [["X = _0"]]);
-    assert_prolog_failure!(&mut wam, "?- p(X, b).");
+    assert_prolog_success!(&mut wam, "p(X, Y).", [["X = _0", "Y = a"]]);
+    assert_prolog_success!(&mut wam, "p(x, a).");
+    assert_prolog_success!(&mut wam, "p(X, a).", [["X = _0"]]);
+    assert_prolog_failure!(&mut wam, "p(X, b).");
 
     submit(&mut wam, "q(z).");
 
-    assert_prolog_success_with_limit!(&mut wam, "?- p(X, b).", [["X = a"],
+    assert_prolog_success_with_limit!(&mut wam, "p(X, b).", [["X = a"],
                                                                 ["X = a"],
                                                                 ["X = a"]],
                                       3);
-    assert_prolog_success!(&mut wam, "?- p(x, a).");
-    assert_prolog_success_with_limit!(&mut wam, "?- p(X, Y).", [["X = _0", "Y = a"],
+    assert_prolog_success!(&mut wam, "p(x, a).");
+    assert_prolog_success_with_limit!(&mut wam, "p(X, Y).", [["X = _0", "Y = a"],
                                                                 ["Y = _1", "X = a"],
                                                                 ["Y = _1", "X = a"]],
                                       3);
 
     submit(&mut wam, "p(X, a). p(X, Y) :- q(Y), p(X, X).");
 
-    assert_prolog_success_with_limit!(&mut wam, "?- p(X, Y).", [["X = _0", "Y = a"],
+    assert_prolog_success_with_limit!(&mut wam, "p(X, Y).", [["X = _0", "Y = a"],
                                                                 ["Y = z", "X = a"]],
                                       2);
-    assert_prolog_failure!(&mut wam, "?- p(X, b).");
+    assert_prolog_failure!(&mut wam, "p(X, b).");
 
     submit(&mut wam, "p(a, z). p(X, Y) :- q(Y), p(X, Y).");
 
-    assert_prolog_success_with_limit!(&mut wam, "?- p(X, Y).", [["X = a", "Y = z"],
+    assert_prolog_success_with_limit!(&mut wam, "p(X, Y).", [["X = a", "Y = z"],
                                                                 ["X = a", "Y = z"]],
                                       2);
 
-    assert_prolog_success_with_limit!(&mut wam, "?- p(X, z).", [["X = a"],
+    assert_prolog_success_with_limit!(&mut wam, "p(X, z).", [["X = a"],
                                                                 ["X = a"]],
                                       2);
-    assert_prolog_success!(&mut wam, "?- p(a, z).");
-    assert_prolog_success_with_limit!(&mut wam, "?- p(a, X).", [["X = z"],
+    assert_prolog_success!(&mut wam, "p(a, z).");
+    assert_prolog_success_with_limit!(&mut wam, "p(a, X).", [["X = z"],
                                                                 ["X = z"]],
                                       2);
-    assert_prolog_failure!(&mut wam, "?- p(b, a).");
+    assert_prolog_failure!(&mut wam, "p(b, a).");
 
     submit(&mut wam, "p(X, Y, Z) :- q(X), r(Y), s(Z).
                       p(a, b, Z) :- q(Z).");
@@ -385,10 +393,10 @@ fn test_queries_on_predicates() {
     submit(&mut wam, "r(y).");
     submit(&mut wam, "s(z).");
 
-    assert_prolog_success!(&mut wam, "?- p(X, Y, Z).", [["Y = y", "X = x", "Z = z"],
+    assert_prolog_success!(&mut wam, "p(X, Y, Z).", [["Y = y", "X = x", "Z = z"],
                                                         ["Y = b", "X = a", "Z = x"]]);
-    assert_prolog_failure!(&mut wam, "?- p(a, b, c).");
-    assert_prolog_success!(&mut wam, "?- p(a, b, C).", [["C = x"]]);
+    assert_prolog_failure!(&mut wam, "p(a, b, c).");
+    assert_prolog_success!(&mut wam, "p(a, b, C).", [["C = x"]]);
 
     submit(&mut wam, "p(X) :- r(X).");
     submit(&mut wam, "r(X) :- s(X, t). r(X) :- t(X, u).");
@@ -396,11 +404,11 @@ fn test_queries_on_predicates() {
     submit(&mut wam, "s(x, t).");
     submit(&mut wam, "t(y, u).");
 
-    assert_prolog_success!(&mut wam, "?- p(X).", [["X = x"],
+    assert_prolog_success!(&mut wam, "p(X).", [["X = x"],
                                                   ["X = y"]]);
-    assert_prolog_success!(&mut wam, "?- p(x).");
-    assert_prolog_success!(&mut wam, "?- p(y).");
-    assert_prolog_failure!(&mut wam, "?- p(z).");
+    assert_prolog_success!(&mut wam, "p(x).");
+    assert_prolog_success!(&mut wam, "p(y).");
+    assert_prolog_failure!(&mut wam, "p(z).");
 
     submit(&mut wam, "p(f(f(X)), h(W), Y) :- g(W), h(W), f(X).
                       p(X, Y, Z) :- h(Y), g(W), z(Z).");
@@ -409,7 +417,7 @@ fn test_queries_on_predicates() {
     submit(&mut wam, "f(s).");
     submit(&mut wam, "z(Z).");
 
-    assert_prolog_success!(&mut wam, "?- p(X, Y, Z).", [["Y = h(w)", "X = f(f(s))", "Z = _2"],
+    assert_prolog_success!(&mut wam, "p(X, Y, Z).", [["Y = h(w)", "X = f(f(s))", "Z = _2"],
                                                         ["Y = h(x)", "X = f(f(s))", "Z = _2"],
                                                         ["Y = h(z)", "X = f(f(s))", "Z = _2"],
                                                         ["Y = w", "Z = _2", "X = _0"],
@@ -424,7 +432,7 @@ fn test_queries_on_predicates() {
                                                         ["Y = z", "Z = _2", "X = _0"],
                                                         ["Y = z", "Z = _2", "X = _0"],
                                                         ["Y = z", "Z = _2", "X = _0"]]);
-    assert_prolog_success!(&mut wam, "?- p(X, X, Z).", [["Z = _1", "X = w"],
+    assert_prolog_success!(&mut wam, "p(X, X, Z).", [["Z = _1", "X = w"],
                                                         ["Z = _1", "X = w"],
                                                         ["Z = _1", "X = w"],
                                                         ["Z = _1", "X = w"],
@@ -436,7 +444,7 @@ fn test_queries_on_predicates() {
                                                         ["Z = _1", "X = z"],
                                                         ["Z = _1", "X = z"],
                                                         ["Z = _1", "X = z"]]);
-    assert_prolog_success!(&mut wam, "?- p(f(f(Z)), Y, Z).", [["Y = h(w)", "Z = s"],
+    assert_prolog_success!(&mut wam, "p(f(f(Z)), Y, Z).", [["Y = h(w)", "Z = s"],
                                                               ["Y = h(x)", "Z = s"],
                                                               ["Y = h(z)", "Z = s"],
                                                               ["Y = w", "Z = _1"],
@@ -451,7 +459,7 @@ fn test_queries_on_predicates() {
                                                               ["Y = z", "Z = _1"],
                                                               ["Y = z", "Z = _1"],
                                                               ["Y = z", "Z = _1"]]);
-    assert_prolog_success!(&mut wam, "?- p(X, X, X).", [["X = w"],
+    assert_prolog_success!(&mut wam, "p(X, X, X).", [["X = w"],
                                                         ["X = w"],
                                                         ["X = w"],
                                                         ["X = w"],
@@ -463,7 +471,7 @@ fn test_queries_on_predicates() {
                                                         ["X = z"],
                                                         ["X = z"],
                                                         ["X = z"]]);
-    assert_prolog_success!(&mut wam, "?- p(X, Y, X).", [["Y = h(w)", "X = f(f(s))"],
+    assert_prolog_success!(&mut wam, "p(X, Y, X).", [["Y = h(w)", "X = f(f(s))"],
                                                         ["Y = h(x)", "X = f(f(s))"],
                                                         ["Y = h(z)", "X = f(f(s))"],
                                                         ["Y = w", "X = _0"],
@@ -478,178 +486,178 @@ fn test_queries_on_predicates() {
                                                         ["Y = z", "X = _0"],
                                                         ["Y = z", "X = _0"],
                                                         ["Y = z", "X = _0"]]);
-    assert_prolog_failure!(&mut wam, "?- p(f(f(X)), h(f(X)), Y).");
+    assert_prolog_failure!(&mut wam, "p(f(f(X)), h(f(X)), Y).");
 
     submit(&mut wam, "p(X) :- f(Y), g(Y), i(X, Y).");
     submit(&mut wam, "g(f(a)). g(f(b)). g(f(c)).");
     submit(&mut wam, "f(f(a)). f(f(b)). f(f(c)).");
     submit(&mut wam, "i(X, X).");
 
-    assert_prolog_success!(&mut wam, "?- p(X).", [["X = f(a)"],
+    assert_prolog_success!(&mut wam, "p(X).", [["X = f(a)"],
                                                   ["X = f(b)"],
                                                   ["X = f(c)"]]);
 
     submit(&mut wam, "p(X) :- f(f(Y)), g(Y, f(Y)), i(X, f(Y)).");
     submit(&mut wam, "g(Y, f(Y)) :- g(f(Y)).");
 
-    assert_prolog_success!(&mut wam, "?- p(X).", [["X = f(a)"],
+    assert_prolog_success!(&mut wam, "p(X).", [["X = f(a)"],
                                                   ["X = f(b)"],
                                                   ["X = f(c)"]]);
 }
 
 #[test]
 fn test_queries_on_cuts() {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     // test shallow cuts.
     submit(&mut wam, "memberchk(X, [X|_]) :- !.
                       memberchk(X, [_|Xs]) :- memberchk(X, Xs).");
 
-    assert_prolog_success!(&mut wam, "?- memberchk(X, [a,b,c]).", [["X = a"]]);
-    assert_prolog_success!(&mut wam, "?- memberchk([X,X], [a,b,c,[d,e],[d,d]]).", [["X = d"]]);
-    assert_prolog_success!(&mut wam, "?- memberchk([X,X], [a,b,c,[D,d],[e,e]]).", [["X = d", "D = d"]]);
-    assert_prolog_failure!(&mut wam, "?- memberchk([X,X], [a,b,c,[e,d],[f,e]]).");
-    assert_prolog_failure!(&mut wam, "?- memberchk([X,X,Y], [a,b,c,[e,d],[f,e]]).");
-    assert_prolog_success!(&mut wam, "?- memberchk([X,X,Y], [a,b,c,[e,e,d],[f,e]]).", [["X = e", "Y = d"]]);
+    assert_prolog_success!(&mut wam, "memberchk(X, [a,b,c]).", [["X = a"]]);
+    assert_prolog_success!(&mut wam, "memberchk([X,X], [a,b,c,[d,e],[d,d]]).", [["X = d"]]);
+    assert_prolog_success!(&mut wam, "memberchk([X,X], [a,b,c,[D,d],[e,e]]).", [["X = d", "D = d"]]);
+    assert_prolog_failure!(&mut wam, "memberchk([X,X], [a,b,c,[e,d],[f,e]]).");
+    assert_prolog_failure!(&mut wam, "memberchk([X,X,Y], [a,b,c,[e,d],[f,e]]).");
+    assert_prolog_success!(&mut wam, "memberchk([X,X,Y], [a,b,c,[e,e,d],[f,e]]).", [["X = e", "Y = d"]]);
 
     // test deep cuts.
     submit(&mut wam, "commit :- a, !.");
 
-    assert_prolog_failure!(&mut wam, "?- commit.");
+    assert_prolog_failure!(&mut wam, "commit.");
 
     submit(&mut wam, "a.");
 
-    assert_prolog_success!(&mut wam, "?- commit.");
+    assert_prolog_success!(&mut wam, "commit.");
 
     submit(&mut wam, "commit(X) :- a(X), !.");
 
-    assert_prolog_failure!(&mut wam, "?- commit(X).");
+    assert_prolog_failure!(&mut wam, "commit(X).");
 
     submit(&mut wam, "a(x).");
 
-    assert_prolog_success!(&mut wam, "?- commit(X).", [["X = x"]]);
+    assert_prolog_success!(&mut wam, "commit(X).", [["X = x"]]);
 
     submit(&mut wam, "a :- b, !, c. a :- d.");
 
-    assert_prolog_failure!(&mut wam, "?- a.");
+    assert_prolog_failure!(&mut wam, "a.");
 
     submit(&mut wam, "b.");
 
-    assert_prolog_failure!(&mut wam, "?- a.");
+    assert_prolog_failure!(&mut wam, "a.");
 
     submit(&mut wam, "d.");
 
     // we've committed to the first clause since the query on b
     // succeeds, so we expect failure here.
-    assert_prolog_failure!(&mut wam, "?- a.");
+    assert_prolog_failure!(&mut wam, "a.");
 
     submit(&mut wam, "c.");
 
-    assert_prolog_success!(&mut wam, "?- a.");
+    assert_prolog_success!(&mut wam, "a.");
 
     submit(&mut wam, "a(X) :- b, !, c(X). a(X) :- d(X).");
 
-    assert_prolog_failure!(&mut wam, "?- a(X).");
+    assert_prolog_failure!(&mut wam, "a(X).");
 
     submit(&mut wam, "c(c).");
     submit(&mut wam, "d(d).");
 
-    assert_prolog_success!(&mut wam, "?- a(X).", [["X = c"]]);
+    assert_prolog_success!(&mut wam, "a(X).", [["X = c"]]);
 
     submit(&mut wam, "b.");
 
-    assert_prolog_success!(&mut wam, "?- a(X).", [["X = c"]]);
+    assert_prolog_success!(&mut wam, "a(X).", [["X = c"]]);
 }
 
 #[test]
 fn test_queries_on_lists()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     submit(&mut wam, "p([Z, W]).");
 
-    assert_prolog_success!(&mut wam, "?- p([Z, Z]).", [["Z = _0"]]);
-    assert_prolog_failure!(&mut wam, "?- p([Z, W, Y]).");
-    assert_prolog_success!(&mut wam, "?- p([Z | W]).", [["Z = _0", "W = [_3]"]]);
-    assert_prolog_success!(&mut wam, "?- p([Z | [Z]]).", [["Z = _0"]]);
-    assert_prolog_success!(&mut wam, "?- p([Z | [W]]).", [["Z = _2", "W = _0"]]);
-    assert_prolog_failure!(&mut wam, "?- p([Z | []]).");
+    assert_prolog_success!(&mut wam, "p([Z, Z]).", [["Z = _0"]]);
+    assert_prolog_failure!(&mut wam, "p([Z, W, Y]).");
+    assert_prolog_success!(&mut wam, "p([Z | W]).", [["Z = _0", "W = [_3]"]]);
+    assert_prolog_success!(&mut wam, "p([Z | [Z]]).", [["Z = _0"]]);
+    assert_prolog_success!(&mut wam, "p([Z | [W]]).", [["Z = _2", "W = _0"]]);
+    assert_prolog_failure!(&mut wam, "p([Z | []]).");
 
     submit(&mut wam, "p([Z, Z]).");
 
-    assert_prolog_success!(&mut wam, "?- p([Z, Z]).", [["Z = _0"]]);
-    assert_prolog_failure!(&mut wam, "?- p([Z, W, Y]).");
-    assert_prolog_success!(&mut wam, "?- p([Z | W]).", [["Z = _0", "W = [_0]"]]);
-    assert_prolog_success!(&mut wam, "?- p([Z | [Z]]).", [["Z = _0"]]);
-    assert_prolog_success!(&mut wam, "?- p([Z | [W]]).", [["Z = _0", "W = _0"]]);
-    assert_prolog_failure!(&mut wam, "?- p([Z | []]).");
+    assert_prolog_success!(&mut wam, "p([Z, Z]).", [["Z = _0"]]);
+    assert_prolog_failure!(&mut wam, "p([Z, W, Y]).");
+    assert_prolog_success!(&mut wam, "p([Z | W]).", [["Z = _0", "W = [_0]"]]);
+    assert_prolog_success!(&mut wam, "p([Z | [Z]]).", [["Z = _0"]]);
+    assert_prolog_success!(&mut wam, "p([Z | [W]]).", [["Z = _0", "W = _0"]]);
+    assert_prolog_failure!(&mut wam, "p([Z | []]).");
 
     submit(&mut wam, "p([Z]).");
 
-    assert_prolog_failure!(&mut wam, "?- p([Z, Z]).");
-    assert_prolog_failure!(&mut wam, "?- p([Z, W, Y]).");
-    assert_prolog_success!(&mut wam, "?- p([Z | W]).", [["W = []", "Z = _0"]]);
-    assert_prolog_failure!(&mut wam, "?- p([Z | [Z]]).");
-    assert_prolog_failure!(&mut wam, "?- p([Z | [W]]).");
-    assert_prolog_success!(&mut wam, "?- p([Z | []]).", [["Z = _0"]]);
+    assert_prolog_failure!(&mut wam, "p([Z, Z]).");
+    assert_prolog_failure!(&mut wam, "p([Z, W, Y]).");
+    assert_prolog_success!(&mut wam, "p([Z | W]).", [["W = []", "Z = _0"]]);
+    assert_prolog_failure!(&mut wam, "p([Z | [Z]]).");
+    assert_prolog_failure!(&mut wam, "p([Z | [W]]).");
+    assert_prolog_success!(&mut wam, "p([Z | []]).", [["Z = _0"]]);
 
     submit(&mut wam, "member(X, [X|_]).
                       member(X, [_|Xs]) :- member(X, Xs).");
 
-    assert_prolog_failure!(&mut wam, "?- member(a, [c, [X, Y]]).");
-    assert_prolog_failure!(&mut wam, "?- member(c, [a, [X, Y]]).");
-    assert_prolog_success!(&mut wam, "?- member(a, [a, [X, Y]]).", [["X = _2", "Y = _0"]]);
+    assert_prolog_failure!(&mut wam, "member(a, [c, [X, Y]]).");
+    assert_prolog_failure!(&mut wam, "member(c, [a, [X, Y]]).");
+    assert_prolog_success!(&mut wam, "member(a, [a, [X, Y]]).", [["X = _2", "Y = _0"]]);
 
-    assert_prolog_success!(&mut wam, "?- member(a, [X, Y, Z]).", [["Y = _2", "X = a",  "Z = _0"],
+    assert_prolog_success!(&mut wam, "member(a, [X, Y, Z]).", [["Y = _2", "X = a",  "Z = _0"],
                                                                   ["Y = a",  "X = _4", "Z = _0"],
                                                                   ["Y = _2",  "X = _4", "Z = a"]]);
 
-    assert_prolog_success!(&mut wam, "?- member([X, X], [a, [X, Y]]).", [["X = _0", "Y = _0"]]);
-    assert_prolog_success!(&mut wam, "?- member([X, X], [a, [b, c], [b, b], [Z, x], [d, f]]).",
+    assert_prolog_success!(&mut wam, "member([X, X], [a, [X, Y]]).", [["X = _0", "Y = _0"]]);
+    assert_prolog_success!(&mut wam, "member([X, X], [a, [b, c], [b, b], [Z, x], [d, f]]).",
                            [["Z = _14", "X = b"],
                             ["Z = x",   "X = x"]]);
-    assert_prolog_failure!(&mut wam, "?- member([X, X], [a, [b, c], [b, d], [foo, x], [d, f]]).");
-    assert_prolog_success!(&mut wam, "?- member([X, Y], [a, [b, c], [b, b], [Z, x], [d, f]]).",
+    assert_prolog_failure!(&mut wam, "member([X, X], [a, [b, c], [b, d], [foo, x], [d, f]]).");
+    assert_prolog_success!(&mut wam, "member([X, Y], [a, [b, c], [b, b], [Z, x], [d, f]]).",
                            [["X = b", "Y = c", "Z = _14"],
                             ["X = b", "Y = b", "Z = _14"],
                             ["X = _2", "Y = x", "Z = _2"],
                             ["X = d", "Y = f", "Z = _14"]]);
-    assert_prolog_failure!(&mut wam, "?- member([X, Y, Y], [a, [b, c], [b, b], [Z, x], [d, f]]).");
-    assert_prolog_failure!(&mut wam, "?- member([X, Y, Z], [a, [b, c], [b, b], [Z, x], [d, f]]).");
+    assert_prolog_failure!(&mut wam, "member([X, Y, Y], [a, [b, c], [b, b], [Z, x], [d, f]]).");
+    assert_prolog_failure!(&mut wam, "member([X, Y, Z], [a, [b, c], [b, b], [Z, x], [d, f]]).");
 }
 
 #[test]
 fn test_queries_on_conjuctive_queries() {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     submit(&mut wam, "p(a, b).");
     submit(&mut wam, "q(b, c).");
 
-    assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, Z).", [["X = a", "Z = c", "Y = b"]]);
-    assert_prolog_failure!(&mut wam, "?- p(X, Y), q(Y, X).");
+    assert_prolog_success!(&mut wam, "p(X, Y), q(Y, Z).", [["X = a", "Z = c", "Y = b"]]);
+    assert_prolog_failure!(&mut wam, "p(X, Y), q(Y, X).");
 
     submit(&mut wam, "p(a, [f(g(X))]).");
     submit(&mut wam, "q(Y, c).");
 
-    assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, Z).", [["Y = [f(g(_9))]", "X = a", "Z = c"]]);
-    assert_prolog_failure!(&mut wam, "?- p(X, Y), q(Y, X).");
+    assert_prolog_success!(&mut wam, "p(X, Y), q(Y, Z).", [["Y = [f(g(_9))]", "X = a", "Z = c"]]);
+    assert_prolog_failure!(&mut wam, "p(X, Y), q(Y, X).");
 
     submit(&mut wam, "member(X, [X|_]).
                       member(X, [_|Xs]) :- member(X, Xs).");
 
-    assert_prolog_success!(&mut wam, "?- member(X, [a,b,c]), member(X, [a,b,c]).",
+    assert_prolog_success!(&mut wam, "member(X, [a,b,c]), member(X, [a,b,c]).",
                            [["X = a"],
                             ["X = b"],
                             ["X = c"]]);
-    assert_prolog_success!(&mut wam, "?- member(X, [a,b,c]), member(X, [b,c]).",
+    assert_prolog_success!(&mut wam, "member(X, [a,b,c]), member(X, [b,c]).",
                            [["X = b"],
                             ["X = c"]]);
-    assert_prolog_success!(&mut wam, "?- member(X, [a,c]), member(X, [b,c]).",
+    assert_prolog_success!(&mut wam, "member(X, [a,c]), member(X, [b,c]).",
                            [["X = c"]]);
-    assert_prolog_success!(&mut wam, "?- member(X, [a,b,c,d]), !, member(X, [a,d]).",
+    assert_prolog_success!(&mut wam, "member(X, [a,b,c,d]), !, member(X, [a,d]).",
                            [["X = a"]]);
-    assert_prolog_failure!(&mut wam, "?- member(X, [a,b,c,d]), !, member(X, [e]).");
-    assert_prolog_success!(&mut wam, "?- member([X,X],[a,b,c,[d,d],[e,d]]),
+    assert_prolog_failure!(&mut wam, "member(X, [a,b,c,d]), !, member(X, [e]).");
+    assert_prolog_success!(&mut wam, "member([X,X],[a,b,c,[d,d],[e,d]]),
                                          member(X, [a,b,c,d,e,f,g]),
                                          member(Y, [X, a, b, c, d]).",
                            [["X = d", "Y = d"],
@@ -662,49 +670,49 @@ fn test_queries_on_conjuctive_queries() {
     submit(&mut wam, "c.");
     submit(&mut wam, "q(Y, c).");
 
-    assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, Z).",
+    assert_prolog_success!(&mut wam, "p(X, Y), q(Y, Z).",
                            [["X = a",  "Z = c", "Y = [f(g(_9))]"],
                             ["X = _0", "Z = c", "Y = c"]]);
-    assert_prolog_success!(&mut wam, "?- p(X, Y), !, q(Y, Z).",
+    assert_prolog_success!(&mut wam, "p(X, Y), !, q(Y, Z).",
                            [["Z = c", "Y = [f(g(_9))]", "X = a"]]);
 
     submit(&mut wam, "q([f(g(x))], Z). q([f(g(y))], Y). q([f(g(z))], a).");
 
-    assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, Z).",
+    assert_prolog_success!(&mut wam, "p(X, Y), q(Y, Z).",
                            [["Z = _11", "X = a", "Y = [f(g(x))]"],
                             ["Z = _11", "X = a", "Y = [f(g(y))]"],
                             ["Z = a", "X = a", "Y = [f(g(z))]"]]);
-    assert_prolog_success!(&mut wam, "?- p(X, Y), !, q(Y, Z).",
+    assert_prolog_success!(&mut wam, "p(X, Y), !, q(Y, Z).",
                            [["X = a", "Y = [f(g(x))]", "Z = _11"],
                             ["X = a", "Y = [f(g(y))]", "Z = _11"],
                             ["X = a", "Y = [f(g(z))]", "Z = a"]]);
-    assert_prolog_success!(&mut wam, "?- p(X, Y), !, q(Y, X).",
+    assert_prolog_success!(&mut wam, "p(X, Y), !, q(Y, X).",
                            [["X = a", "Y = [f(g(x))]"],
                             ["X = a", "Y = [f(g(y))]"],
                             ["X = a", "Y = [f(g(z))]"]]);
 
     submit(&mut wam, "p(X, [f(g(x))]). p(X, [f(g(y))]). p(X, [f(g(z))]).");
 
-    assert_prolog_failure!(&mut wam, "?- q(f(X), Y), p(X, Y).");
-    assert_prolog_success!(&mut wam, "?- q(X, Y), p(X, Y).",
+    assert_prolog_failure!(&mut wam, "q(f(X), Y), p(X, Y).");
+    assert_prolog_success!(&mut wam, "q(X, Y), p(X, Y).",
                            [["Y = [f(g(x))]", "X = [f(g(x))]"],
                             ["Y = [f(g(y))]", "X = [f(g(x))]"],
                             ["Y = [f(g(z))]", "X = [f(g(x))]"],
                             ["Y = [f(g(x))]", "X = [f(g(y))]"],
                             ["Y = [f(g(y))]", "X = [f(g(y))]"],
                             ["Y = [f(g(z))]", "X = [f(g(y))]"]]);
-    assert_prolog_success!(&mut wam, "?- p(X, Y), q(X, Y).",
+    assert_prolog_success!(&mut wam, "p(X, Y), q(X, Y).",
                            [["Y = [f(g(x))]", "X = [f(g(x))]"],
                             ["Y = [f(g(x))]", "X = [f(g(y))]"],
                             ["Y = [f(g(y))]", "X = [f(g(x))]"],
                             ["Y = [f(g(y))]", "X = [f(g(y))]"],
                             ["Y = [f(g(z))]", "X = [f(g(x))]"],
                             ["Y = [f(g(z))]", "X = [f(g(y))]"]]);
-    assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, X).",
+    assert_prolog_success!(&mut wam, "p(X, Y), q(Y, X).",
                            [["Y = [f(g(x))]", "X = _10"],
                             ["Y = [f(g(y))]", "X = _10"],
                             ["Y = [f(g(z))]", "X = a"]]);
-    assert_prolog_success!(&mut wam, "?- q(X, Y), p(Y, X).",
+    assert_prolog_success!(&mut wam, "q(X, Y), p(Y, X).",
                            [["Y = _9", "X = [f(g(x))]"],
                             ["Y = _9", "X = [f(g(y))]"],
                             ["Y = a"    , "X = [f(g(z))]"]]);
@@ -713,13 +721,13 @@ fn test_queries_on_conjuctive_queries() {
 #[test]
 fn test_queries_on_call_n()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     submit(&mut wam, "maplist(_, []).
                       maplist(P, [X|Xs]) :- call(P, X), maplist(P, Xs).");
     submit(&mut wam, "f(a). f(b). f(c).");
 
-    assert_prolog_success!(&mut wam, "?- maplist(f, [X,Y,Z]).",
+    assert_prolog_success!(&mut wam, "maplist(f, [X,Y,Z]).",
                            [["X = a", "Y = a", "Z = a"],
                             ["X = a", "Y = a", "Z = b"],
                             ["X = a", "Y = a", "Z = c"],
@@ -748,7 +756,7 @@ fn test_queries_on_call_n()
                             ["X = c", "Y = c", "Z = b"],
                             ["X = c", "Y = c", "Z = c"]]);
 
-    assert_prolog_success!(&mut wam, "?- maplist(f, [a,Y,Z]).",
+    assert_prolog_success!(&mut wam, "maplist(f, [a,Y,Z]).",
                            [["Y = a", "Z = a"],
                             ["Y = a", "Z = b"],
                             ["Y = a", "Z = c"],
@@ -759,53 +767,53 @@ fn test_queries_on_call_n()
                             ["Y = c", "Z = b"],
                             ["Y = c", "Z = c"]]);
 
-    assert_prolog_success!(&mut wam, "?- maplist(f, [X,a,b]).",
+    assert_prolog_success!(&mut wam, "maplist(f, [X,a,b]).",
                            [["X = a"],
                             ["X = b"],
                             ["X = c"]]);
-    assert_prolog_success!(&mut wam, "?- maplist(f, [c,a,b]).");
-    assert_prolog_failure!(&mut wam, "?- maplist(f, [d,e,f]).");
-    assert_prolog_success!(&mut wam, "?- maplist(f, []).");
-    assert_prolog_failure!(&mut wam, "?- maplist(f(X), [a,b,c]).");
+    assert_prolog_success!(&mut wam, "maplist(f, [c,a,b]).");
+    assert_prolog_failure!(&mut wam, "maplist(f, [d,e,f]).");
+    assert_prolog_success!(&mut wam, "maplist(f, []).");
+    assert_prolog_failure!(&mut wam, "maplist(f(X), [a,b,c]).");
 
     submit(&mut wam, "f(X) :- call(X), call(X).");
     submit(&mut wam, "p(x). p(y).");
 
-    assert_prolog_failure!(&mut wam, "?- f(p).");
-    assert_prolog_success!(&mut wam, "?- f(p(X)).", [["X = x"],
+    assert_prolog_failure!(&mut wam, "f(p).");
+    assert_prolog_success!(&mut wam, "f(p(X)).", [["X = x"],
                                                      ["X = y"]]);
-    assert_prolog_success!(&mut wam, "?- f(p(x)).");
-    assert_prolog_failure!(&mut wam, "?- f(p(w)).");
-    assert_prolog_failure!(&mut wam, "?- f(p(X, Y)).");
+    assert_prolog_success!(&mut wam, "f(p(x)).");
+    assert_prolog_failure!(&mut wam, "f(p(w)).");
+    assert_prolog_failure!(&mut wam, "f(p(X, Y)).");
 
     submit(&mut wam, "f(P) :- call(P, X), call(P, Y).");
 
-    assert_prolog_success!(&mut wam, "?- f(p).");
-    assert_prolog_failure!(&mut wam, "?- f(non_existent).");
+    assert_prolog_success!(&mut wam, "f(p).");
+    assert_prolog_failure!(&mut wam, "f(non_existent).");
 
     submit(&mut wam, "f(P, X, Y) :- call(P, X), call(P, Y).");
 
-    assert_prolog_success!(&mut wam, "?- f(p, X, Y).", [["Y = x", "X = x"],
+    assert_prolog_success!(&mut wam, "f(p, X, Y).", [["Y = x", "X = x"],
                                                         ["Y = y", "X = x"],
                                                         ["Y = x", "X = y"],
                                                         ["Y = y", "X = y"]]);
-    assert_prolog_success!(&mut wam, "?- f(p, x, Y).", [["Y = x"],
+    assert_prolog_success!(&mut wam, "f(p, x, Y).", [["Y = x"],
                                                         ["Y = y"]]);
-    assert_prolog_success!(&mut wam, "?- f(p, X, y).", [["X = x"],
+    assert_prolog_success!(&mut wam, "f(p, X, y).", [["X = x"],
                                                         ["X = y"]]);
-    assert_prolog_success!(&mut wam, "?- f(p, x, y).");
-    assert_prolog_failure!(&mut wam, "?- f(p, X, z).");
-    assert_prolog_failure!(&mut wam, "?- f(p, z, Y).");
+    assert_prolog_success!(&mut wam, "f(p, x, y).");
+    assert_prolog_failure!(&mut wam, "f(p, X, z).");
+    assert_prolog_failure!(&mut wam, "f(p, z, Y).");
 
-    assert_prolog_success!(&mut wam, "?- call(p, X).", [["X = x"],
+    assert_prolog_success!(&mut wam, "call(p, X).", [["X = x"],
                                                         ["X = y"]]);
-    assert_prolog_success!(&mut wam, "?- call(p, x).");
-    assert_prolog_success!(&mut wam, "?- call(p, y).");
-    assert_prolog_failure!(&mut wam, "?- call(p, z).");
+    assert_prolog_success!(&mut wam, "call(p, x).");
+    assert_prolog_success!(&mut wam, "call(p, y).");
+    assert_prolog_failure!(&mut wam, "call(p, z).");
 
     submit(&mut wam, "r(f(X)) :- p(X). r(g(Y)) :- p(Y).");
 
-    assert_prolog_success!(&mut wam, "?- f(r, X, Y).",
+    assert_prolog_success!(&mut wam, "f(r, X, Y).",
                            [["X = f(x)", "Y = f(x)"],
                             ["X = f(x)", "Y = f(y)"],
                             ["X = f(x)", "Y = g(x)"],
@@ -822,57 +830,57 @@ fn test_queries_on_call_n()
                             ["X = g(y)", "Y = f(y)"],
                             ["X = g(y)", "Y = g(x)"],
                             ["X = g(y)", "Y = g(y)"]]);
-    assert_prolog_success!(&mut wam, "?- f(r, X, X).",
+    assert_prolog_success!(&mut wam, "f(r, X, X).",
                            [["X = f(x)"],
                             ["X = f(y)"],
                             ["X = g(x)"],
                             ["X = g(y)"]]);
-    assert_prolog_success!(&mut wam, "?- f(r, f(X), g(Y)).",
+    assert_prolog_success!(&mut wam, "f(r, f(X), g(Y)).",
                            [["X = x", "Y = x"],
                             ["X = x", "Y = y"],
                             ["X = y", "Y = x"],
                             ["X = y", "Y = y"]]);
-    assert_prolog_failure!(&mut wam, "?- f(r, j(X), h(Y)).");
+    assert_prolog_failure!(&mut wam, "f(r, j(X), h(Y)).");
 
     submit(&mut wam, "p(one, one). p(one, two). p(two, two).");
 
-    assert_prolog_success!(&mut wam, "?- f(p(one), X, Y).",
+    assert_prolog_success!(&mut wam, "f(p(one), X, Y).",
                            [["X = one", "Y = one"],
                             ["X = one", "Y = two"],
                             ["X = two", "Y = one"],
                             ["X = two", "Y = two"]]);
-    assert_prolog_success!(&mut wam, "?- f(p(one), X, X).",
+    assert_prolog_success!(&mut wam, "f(p(one), X, X).",
                            [["X = one"],
                             ["X = two"]]);
-    assert_prolog_success!(&mut wam, "?- f(p(one), one, Y).",
+    assert_prolog_success!(&mut wam, "f(p(one), one, Y).",
                            [["Y = one"],
                             ["Y = two"]]);
-    assert_prolog_success!(&mut wam, "?- f(p(one), one, two).");
-    assert_prolog_failure!(&mut wam, "?- f(p(one), one, three).");
+    assert_prolog_success!(&mut wam, "f(p(one), one, two).");
+    assert_prolog_failure!(&mut wam, "f(p(one), one, three).");
 
-    assert_prolog_failure!(&mut wam, "?- f(p(two), one, two).");
-    assert_prolog_failure!(&mut wam, "?- f(p(two), two, one).");
-    assert_prolog_success!(&mut wam, "?- f(p(two), two, two).");
-    assert_prolog_failure!(&mut wam, "?- f(p(two), two, three).");
+    assert_prolog_failure!(&mut wam, "f(p(two), one, two).");
+    assert_prolog_failure!(&mut wam, "f(p(two), two, one).");
+    assert_prolog_success!(&mut wam, "f(p(two), two, two).");
+    assert_prolog_failure!(&mut wam, "f(p(two), two, three).");
 
-    assert_prolog_failure!(&mut wam, "?- f(p(three), X, Y).");
-    assert_prolog_failure!(&mut wam, "?- f(p(three), X, X).");
-    assert_prolog_failure!(&mut wam, "?- f(p(three), one, Y).");
-    assert_prolog_failure!(&mut wam, "?- f(p(three), one, two).");
-    assert_prolog_failure!(&mut wam, "?- f(p(three), one, three).");
+    assert_prolog_failure!(&mut wam, "f(p(three), X, Y).");
+    assert_prolog_failure!(&mut wam, "f(p(three), X, X).");
+    assert_prolog_failure!(&mut wam, "f(p(three), one, Y).");
+    assert_prolog_failure!(&mut wam, "f(p(three), one, two).");
+    assert_prolog_failure!(&mut wam, "f(p(three), one, three).");
 
     submit(&mut wam, "f(P, X) :- call(P, X).");
 
-    assert_prolog_success!(&mut wam, "?- f(p(one), one).");
-    assert_prolog_success!(&mut wam, "?- f(p(two), two).");
-    assert_prolog_failure!(&mut wam, "?- f(p(two), one).");
-    assert_prolog_failure!(&mut wam, "?- f(p(three), one).");
-    assert_prolog_failure!(&mut wam, "?- f(p(one), three).");
-    assert_prolog_failure!(&mut wam, "?- f(p(two), three).");
+    assert_prolog_success!(&mut wam, "f(p(one), one).");
+    assert_prolog_success!(&mut wam, "f(p(two), two).");
+    assert_prolog_failure!(&mut wam, "f(p(two), one).");
+    assert_prolog_failure!(&mut wam, "f(p(three), one).");
+    assert_prolog_failure!(&mut wam, "f(p(one), three).");
+    assert_prolog_failure!(&mut wam, "f(p(two), three).");
 
     submit(&mut wam, "p(f(g(X)), compound, [lists,are,good]).");
 
-    assert_prolog_success!(&mut wam, "?- call(p(f(g(X))), Y, Z).",
+    assert_prolog_success!(&mut wam, "call(p(f(g(X))), Y, Z).",
                            [["Y = compound", "Z = [lists, are, good]", "X = _3"]]);
 
     submit(&mut wam, "david_lynch(coffee).
@@ -884,63 +892,63 @@ fn test_queries_on_call_n()
                       kyle(showgirls).
                       kyle(flintstones).");
 
-    assert_prolog_success!(&mut wam, "?- call(david_lynch, X).",
+    assert_prolog_success!(&mut wam, "call(david_lynch, X).",
                            [["X = coffee"],
                             ["X = pie"],
                             ["X = kyle(dune)"],
                             ["X = kyle(blue_velvet)"],
                             ["X = kyle(showgirls)"],
                             ["X = kyle(flintstones)"]]);
-    assert_prolog_success!(&mut wam, "?- call(david_lynch, kyle(Film)).",
+    assert_prolog_success!(&mut wam, "call(david_lynch, kyle(Film)).",
                            [["Film = dune"],
                             ["Film = blue_velvet"],
                             ["Film = showgirls"],
                             ["Film = flintstones"]]);
-    assert_prolog_failure!(&mut wam, "?- call(david_lynch, kyle(Film), _).");
+    assert_prolog_failure!(&mut wam, "call(david_lynch, kyle(Film), _).");
 
     submit(&mut wam, "call_mult(P, X) :- call(call(P), X).");
 
-    assert_prolog_success!(&mut wam, "?- call_mult(p(X), Y).",
+    assert_prolog_success!(&mut wam, "call_mult(p(X), Y).",
                            [["Y = one", "X = one"],
                             ["Y = two", "X = one"],
                             ["Y = two", "X = two"]]);
-    assert_prolog_success!(&mut wam, "?- call_mult(p(X), X).",
+    assert_prolog_success!(&mut wam, "call_mult(p(X), X).",
                            [["X = one"],
                             ["X = two"]]);
-    assert_prolog_success!(&mut wam, "?- call_mult(p(one), X).",
+    assert_prolog_success!(&mut wam, "call_mult(p(one), X).",
                            [["X = one"],
                             ["X = two"]]);
-    assert_prolog_success!(&mut wam, "?- call_mult(p(X), one).",
+    assert_prolog_success!(&mut wam, "call_mult(p(X), one).",
                            [["X = one"]]);
 
-    assert_prolog_failure!(&mut wam, "?- call_mult(p(two), one).");
-    assert_prolog_success!(&mut wam, "?- call_mult(p(two), two).");
+    assert_prolog_failure!(&mut wam, "call_mult(p(two), one).");
+    assert_prolog_success!(&mut wam, "call_mult(p(two), two).");
 
-    assert_prolog_success!(&mut wam, "?- call(call(p(one)), X), call(call(p(two)), two).",
+    assert_prolog_success!(&mut wam, "call(call(p(one)), X), call(call(p(two)), two).",
                            [["X = one"],
                             ["X = two"]]);
-    assert_prolog_success!(&mut wam, "?- call(call(p(one, X))), call(call(p(two, two))).",
+    assert_prolog_success!(&mut wam, "call(call(p(one, X))), call(call(p(two, two))).",
                            [["X = one"],
                             ["X = two"]]);
-    assert_prolog_failure!(&mut wam, "?- call(call(p(one)), X), call(call(p(two)), one).");
-    assert_prolog_success!(&mut wam, "?- call(call(p(X)), X), call(call(p(Y)), Y).",
+    assert_prolog_failure!(&mut wam, "call(call(p(one)), X), call(call(p(two)), one).");
+    assert_prolog_success!(&mut wam, "call(call(p(X)), X), call(call(p(Y)), Y).",
                            [["X = one", "Y = one"],
                             ["X = one", "Y = two"],
                             ["X = two", "Y = one"],
                             ["X = two", "Y = two"]]);
-    assert_prolog_success!(&mut wam, "?- call(call(p(X)), Y), call(call(p(Y)), X).",
+    assert_prolog_success!(&mut wam, "call(call(p(X)), Y), call(call(p(Y)), X).",
                            [["X = one", "Y = one"],
                             ["X = two", "Y = two"]]);
-    assert_prolog_success!(&mut wam, "?- call(call(p), X, Y), call(call(call(p)), X, Y).",
+    assert_prolog_success!(&mut wam, "call(call(p), X, Y), call(call(call(p)), X, Y).",
                            [["X = one", "Y = one"],
                             ["Y = two", "X = one"],
                             ["Y = two", "X = two"]]);
-    assert_prolog_success!(&mut wam, "?- call(call(p), X, Y), call(call(call(p(X))), Y).",
+    assert_prolog_success!(&mut wam, "call(call(p), X, Y), call(call(call(p(X))), Y).",
                            [["X = one", "Y = one"],
                             ["Y = two", "X = one"],
                             ["Y = two", "X = two"]]);
-    assert_prolog_failure!(&mut wam, "?- call(call(p), X, Y), call(call(call(p(X))), X, Y).");
-    assert_prolog_success!(&mut wam, "?- call(call(p), X, Y), call(call(call(p(X))), X).",
+    assert_prolog_failure!(&mut wam, "call(call(p), X, Y), call(call(call(p(X))), X, Y).");
+    assert_prolog_success!(&mut wam, "call(call(p), X, Y), call(call(call(p(X))), X).",
                            [["X = one", "Y = one"],
                             ["Y = two", "X = one"],
                             ["Y = two", "X = two"]]);
@@ -948,18 +956,18 @@ fn test_queries_on_call_n()
     submit(&mut wam, "f(call(f, undefined)). f(undefined).");
     submit(&mut wam, "call_var(P) :- P.");
 
-    assert_prolog_success!(&mut wam, "?- f(X), call_var(X).",
+    assert_prolog_success!(&mut wam, "f(X), call_var(X).",
                            [["X = call(f, undefined)"]]);
-    assert_prolog_success!(&mut wam, "?- f(call(f, Q)), call_var(call(f, Q)).",
+    assert_prolog_success!(&mut wam, "f(call(f, Q)), call_var(call(f, Q)).",
                            [["Q = undefined"]]);
-    assert_prolog_failure!(&mut wam, "?- call_var(call(undefined, Q)).");
-
-    assert_prolog_failure!(&mut wam, "?- call(call).");
-    assert_prolog_failure!(&mut wam, "?- call(call(call)).");
-    assert_prolog_failure!(&mut wam, "?- call(call(call(call))).");
-    assert_prolog_failure!(&mut wam, "?- call(call(call(call(call)))).");
-    assert_prolog_failure!(&mut wam, "?- call(call(call(call(call(call))))).");
-    assert_prolog_success!(&mut wam, "?- call(call(call(call(call(call(p(X))))))).",
+    assert_prolog_failure!(&mut wam, "call_var(call(undefined, Q)).");
+
+    assert_prolog_failure!(&mut wam, "call(call).");
+    assert_prolog_failure!(&mut wam, "call(call(call)).");
+    assert_prolog_failure!(&mut wam, "call(call(call(call))).");
+    assert_prolog_failure!(&mut wam, "call(call(call(call(call)))).");
+    assert_prolog_failure!(&mut wam, "call(call(call(call(call(call))))).");
+    assert_prolog_success!(&mut wam, "call(call(call(call(call(call(p(X))))))).",
                            [["X = x"],
                             ["X = y"]]);
 }
@@ -967,85 +975,85 @@ fn test_queries_on_call_n()
 #[test]
 fn test_queries_on_arithmetic()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
-    assert_prolog_success!(&mut wam, "?- X is 1, X is X.", [["X = 1"]]);
-    assert_prolog_failure!(&mut wam, "?- X is 1, X is X + 1.");
-    assert_prolog_success!(&mut wam, "?- X is 1, X is X + 0.", [["X = 1"]]);
-    assert_prolog_success!(&mut wam, "?- X is 1, X is X * 1.", [["X = 1"]]);
-    assert_prolog_failure!(&mut wam, "?- X is 1, X is X * 2.");
+    assert_prolog_success!(&mut wam, "X is 1, X is X.", [["X = 1"]]);
+    assert_prolog_failure!(&mut wam, "X is 1, X is X + 1.");
+    assert_prolog_success!(&mut wam, "X is 1, X is X + 0.", [["X = 1"]]);
+    assert_prolog_success!(&mut wam, "X is 1, X is X * 1.", [["X = 1"]]);
+    assert_prolog_failure!(&mut wam, "X is 1, X is X * 2.");
 
-    // assert_prolog_failure!(&mut wam, "?- X is 1 + a.");
-    // assert_prolog_failure!(&mut wam, "?- X is 1 + Y.");
-    assert_prolog_success!(&mut wam, "?- Y is 2 + 2 - 2, X is 1 + Y, X = 3.",
+    // assert_prolog_failure!(&mut wam, "X is 1 + a.");
+    // assert_prolog_failure!(&mut wam, "X is 1 + Y.");
+    assert_prolog_success!(&mut wam, "Y is 2 + 2 - 2, X is 1 + Y, X = 3.",
                            [["X = 3", "Y = 2"]]);
-    assert_prolog_failure!(&mut wam, "?- Y is 2 + 2 - 2, X is 1 + Y, X = 2.");
-
-    assert_prolog_success!(&mut wam, "?- 6 is 6.");
-    assert_prolog_success!(&mut wam, "?- 6 is 3 + 3.");
-    assert_prolog_success!(&mut wam, "?- 6 is 3 * 2.");
-    assert_prolog_failure!(&mut wam, "?- 7 is 3 * 2.");
-    assert_prolog_failure!(&mut wam, "?- 7 is 3.5 * 2.");
-    assert_prolog_success!(&mut wam, "?- 7.0 is 3.5 * 2.");
-    assert_prolog_success!(&mut wam, "?- 7.0 is 14 / 2.");
-    assert_prolog_failure!(&mut wam, "?- 4.666 is 14.0 / 3.");
-    assert_prolog_success!(&mut wam, "?- 4.0 is 8.0 / 2.");
+    assert_prolog_failure!(&mut wam, "Y is 2 + 2 - 2, X is 1 + Y, X = 2.");
+
+    assert_prolog_success!(&mut wam, "6 is 6.");
+    assert_prolog_success!(&mut wam, "6 is 3 + 3.");
+    assert_prolog_success!(&mut wam, "6 is 3 * 2.");
+    assert_prolog_failure!(&mut wam, "7 is 3 * 2.");
+    assert_prolog_failure!(&mut wam, "7 is 3.5 * 2.");
+    assert_prolog_success!(&mut wam, "7.0 is 3.5 * 2.");
+    assert_prolog_success!(&mut wam, "7.0 is 14 / 2.");
+    assert_prolog_failure!(&mut wam, "4.666 is 14.0 / 3.");
+    assert_prolog_success!(&mut wam, "4.0 is 8.0 / 2.");
 
     submit(&mut wam, "f(X) :- X is 5 // 0.");
 
-    assert_prolog_success!(&mut wam, "?- catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
+    assert_prolog_success!(&mut wam, "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
                            [["E = zero_divisor", "X = _1"]]);
 
     submit(&mut wam, "f(X) :- X is (5 rdiv 1) / 0.");
 
-    assert_prolog_success!(&mut wam, "?- catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
+    assert_prolog_success!(&mut wam, "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
                            [["E = zero_divisor", "X = _1"]]);
 
     submit(&mut wam, "f(X) :- X is 5.0 / 0.");
 
-    assert_prolog_success!(&mut wam, "?- catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
+    assert_prolog_success!(&mut wam, "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
                            [["E = zero_divisor", "X = _1"]]);
 
-    assert_prolog_success!(&mut wam, "?- X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z is X+Y.",
+    assert_prolog_success!(&mut wam, "X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z is X+Y.",
                            [["Y = 4", "X = 4", "Z = 8"]]);
 
-    assert_prolog_success!(&mut wam, "?- X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z = 8, Y is 4.",
+    assert_prolog_success!(&mut wam, "X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z = 8, Y is 4.",
                            [["Y = 4", "X = 4", "Z = 8"]]);
 
-    assert_prolog_success!(&mut wam, "?- X is (3 rdiv 4) / 2, Y is 3 rdiv 8, X = Y.",
+    assert_prolog_success!(&mut wam, "X is (3 rdiv 4) / 2, Y is 3 rdiv 8, X = Y.",
                            [["X = 3/8", "Y = 3/8"]]);
 
-    assert_prolog_success!(&mut wam, "?- X is 10 xor -4, X is -10.", [["X = -10"]]);
-    assert_prolog_success!(&mut wam, "?- X is 4 xor -7, X is -3.", [["X = -3"]]);
-    assert_prolog_success!(&mut wam, "?- X is 10 xor 5 + 55, X = 70.", [["X = 70"]]);
+    assert_prolog_success!(&mut wam, "X is 10 xor -4, X is -10.", [["X = -10"]]);
+    assert_prolog_success!(&mut wam, "X is 4 xor -7, X is -3.", [["X = -3"]]);
+    assert_prolog_success!(&mut wam, "X is 10 xor 5 + 55, X = 70.", [["X = 70"]]);
 
-    assert_prolog_success!(&mut wam, "?- X is 10 rem -3, X = 1.",   [["X = 1"]]);
-    assert_prolog_success!(&mut wam, "?- X is 10 mod -3, X is -2.", [["X = -2"]]);
+    assert_prolog_success!(&mut wam, "X is 10 rem -3, X = 1.",   [["X = 1"]]);
+    assert_prolog_success!(&mut wam, "X is 10 mod -3, X is -2.", [["X = -2"]]);
 
-    assert_prolog_success!(&mut wam, "?- call(is, X, 3 + 4).", [["X = 7"]]);
+    assert_prolog_success!(&mut wam, "call(is, X, 3 + 4).", [["X = 7"]]);
 
-    assert_prolog_success!(&mut wam, "?- Y is 3 + 3, call(is, X, Y + 4).", [["Y = 6", "X = 10"]]);
-    assert_prolog_success!(&mut wam, "?- call(is, X, 3 + 4.5).", [["X = 7.5"]]);
-    assert_prolog_success!(&mut wam, "?- X is 2 rdiv 3, call(is, Y, X*X).", [["X = 2/3", "Y = 4/9"]]);
+    assert_prolog_success!(&mut wam, "Y is 3 + 3, call(is, X, Y + 4).", [["Y = 6", "X = 10"]]);
+    assert_prolog_success!(&mut wam, "call(is, X, 3 + 4.5).", [["X = 7.5"]]);
+    assert_prolog_success!(&mut wam, "X is 2 rdiv 3, call(is, Y, X*X).", [["X = 2/3", "Y = 4/9"]]);
 
-    assert_prolog_failure!(&mut wam, "?- call(>, 3, 3 + 3).");
-    assert_prolog_failure!(&mut wam, "?- X is 3 + 3, call(>, 3, X).");
+    assert_prolog_failure!(&mut wam, "call(>, 3, 3 + 3).");
+    assert_prolog_failure!(&mut wam, "X is 3 + 3, call(>, 3, X).");
 
-    assert_prolog_success!(&mut wam, "?- X is 3 + 3, call(<, 3, X).", [["X = 6"]]);
-    assert_prolog_success!(&mut wam, "?- X is 3 + 3, X =:= 3 + 3.", [["X = 6"]]);
+    assert_prolog_success!(&mut wam, "X is 3 + 3, call(<, 3, X).", [["X = 6"]]);
+    assert_prolog_success!(&mut wam, "X is 3 + 3, X =:= 3 + 3.", [["X = 6"]]);
 
-    assert_prolog_success!(&mut wam, "?- catch(call(is, X, 3 // 0), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(call(is, X, 3 // 0), error(E, _), true).",
                            [["X = _5", "E = evaluation_error(zero_divisor)"]]);
 
-    assert_prolog_success!(&mut wam, "?- catch(call(is, X, 3 // 3), _, true).", [["X = 1"]]);
+    assert_prolog_success!(&mut wam, "catch(call(is, X, 3 // 3), _, true).", [["X = 1"]]);
 
     submit(&mut wam, "f(X, Sum) :- ( integer(X) -> Sum is X + X * X + 3 ;
                                      var(X) -> Sum = 1, X = 1 ).");
 
-    assert_prolog_success!(&mut wam, "?- f(X, Sum).", [["X = 1", "Sum = 1"]]);
-    assert_prolog_success!(&mut wam, "?- f(5, Sum).", [["Sum = 33"]]);
-    assert_prolog_success!(&mut wam, "?- f(5, 33).");
-    assert_prolog_failure!(&mut wam, "?- f(5, 32).");
+    assert_prolog_success!(&mut wam, "f(X, Sum).", [["X = 1", "Sum = 1"]]);
+    assert_prolog_success!(&mut wam, "f(5, Sum).", [["Sum = 33"]]);
+    assert_prolog_success!(&mut wam, "f(5, 33).");
+    assert_prolog_failure!(&mut wam, "f(5, 32).");
 
     // exponentiation.
 
@@ -1054,78 +1062,78 @@ fn test_queries_on_arithmetic()
     submit(&mut wam, ":- op(900, xfx, ~).");
     submit(&mut wam, "X ~ Y :- abs(X - Y) =< 1 rdiv 10000.");
 
-    assert_prolog_success!(&mut wam, "?- X is 3 ** 3.",
+    assert_prolog_success!(&mut wam, "X is 3 ** 3.",
                            [["X = 27"]]);
-    assert_prolog_success!(&mut wam, "?- X is 3 ** 0.",
+    assert_prolog_success!(&mut wam, "X is 3 ** 0.",
                            [["X = 1"]]);
-    assert_prolog_success!(&mut wam, "?- X is 3 ** -0.",
+    assert_prolog_success!(&mut wam, "X is 3 ** -0.",
                            [["X = 1"]]);
-    assert_prolog_success!(&mut wam, "?- X is 3 ** 1.",
+    assert_prolog_success!(&mut wam, "X is 3 ** 1.",
                            [["X = 3"]]);
-    assert_prolog_success!(&mut wam, "?- X is 3 ** -3.",
+    assert_prolog_success!(&mut wam, "X is 3 ** -3.",
                            [["X = 1/27"]]);
-    assert_prolog_success!(&mut wam, "?- X is (-3) ** 3.",
+    assert_prolog_success!(&mut wam, "X is (-3) ** 3.",
                            [["X = -27"]]);
-    assert_prolog_success!(&mut wam, "?- X is (-3) ** 3.",
+    assert_prolog_success!(&mut wam, "X is (-3) ** 3.",
                            [["X = -27"]]);
-    assert_prolog_success!(&mut wam, "?- X is (-3) ** 0.",
+    assert_prolog_success!(&mut wam, "X is (-3) ** 0.",
                            [["X = 1"]]);
-    assert_prolog_success!(&mut wam, "?- X is (-3) ** -0.",
+    assert_prolog_success!(&mut wam, "X is (-3) ** -0.",
                            [["X = 1"]]);
-    assert_prolog_success!(&mut wam, "?- X is (-3) ** 1.",
+    assert_prolog_success!(&mut wam, "X is (-3) ** 1.",
                            [["X = -3"]]);
-    assert_prolog_success!(&mut wam, "?- X is (-3) ** -3.",
+    assert_prolog_success!(&mut wam, "X is (-3) ** -3.",
                            [["X = -1/27"]]);
-    assert_prolog_success!(&mut wam, "?- X is (1 rdiv 27) ** -3, X ~ 19683.");
-    assert_prolog_success!(&mut wam, "?- X is (-1 rdiv 27) ** -3, X ~ -19683.");
+    assert_prolog_success!(&mut wam, "X is (1 rdiv 27) ** -3, X ~ 19683.");
+    assert_prolog_success!(&mut wam, "X is (-1 rdiv 27) ** -3, X ~ -19683.");
 
-    assert_prolog_success!(&mut wam, "?- X is 0.0 ** 0.",
+    assert_prolog_success!(&mut wam, "X is 0.0 ** 0.",
                            [["X = 1.0"]]);
-    assert_prolog_success!(&mut wam, "?- catch(_ is 0.0 ** -2342, error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(_ is 0.0 ** -2342, error(E, _), true).",
                            [["E = evaluation_error(no_roots)"]]);
-    assert_prolog_success!(&mut wam, "?- X is 0.0 ** 2342.",
+    assert_prolog_success!(&mut wam, "X is 0.0 ** 2342.",
                            [["X = 0"]]);
 
-    assert_prolog_success!(&mut wam, "?- catch(_ is (-3) ** (1 rdiv 2), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(_ is (-3) ** (1 rdiv 2), error(E, _), true).",
                            [["E = evaluation_error(no_roots)"]]);
-    assert_prolog_success!(&mut wam, "?- catch(_ is (-3/2) ** (1 rdiv 2), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(_ is (-3/2) ** (1 rdiv 2), error(E, _), true).",
                            [["E = evaluation_error(no_roots)"]]);
-    assert_prolog_success!(&mut wam, "?- catch(_ is (-3 rdiv 2) ** (1 rdiv 4), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(_ is (-3 rdiv 2) ** (1 rdiv 4), error(E, _), true).",
                            [["E = evaluation_error(no_roots)"]]);
-    assert_prolog_success!(&mut wam, "?- catch(_ is (-3 rdiv 2) ** (-1 rdiv 4), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(_ is (-3 rdiv 2) ** (-1 rdiv 4), error(E, _), true).",
                            [["E = evaluation_error(no_roots)"]]);
-    assert_prolog_success!(&mut wam, "?- catch(_ is 0 ** (-5 rdiv 4), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(_ is 0 ** (-5 rdiv 4), error(E, _), true).",
                            [["E = evaluation_error(no_roots)"]]);
 
-    assert_prolog_success!(&mut wam, "?- X is 3 ** (1 rdiv 3), Y is X ** 3, Y ~ 3.");
-    assert_prolog_success!(&mut wam, "?- X is (-3) ** (1 rdiv 3), Y is X ** 3, Y ~ -3.");
-    assert_prolog_failure!(&mut wam, "?- X is (-5) ** (1 rdiv 3), Y is X ** 3, Y ~ -3.");
-    assert_prolog_failure!(&mut wam, "?- X is 5 ** (1 rdiv 3), Y is X ** 3, Y ~ 3.");
-    assert_prolog_failure!(&mut wam, "?- X is (1 rdiv 3) ** 0.5, Y is X ** 2, X ~ Y.");
-    assert_prolog_success!(&mut wam, "?- X is (1 rdiv 3) ** 0.5, Y is X ** 2, 1 rdiv 3 ~ Y.");
+    assert_prolog_success!(&mut wam, "X is 3 ** (1 rdiv 3), Y is X ** 3, Y ~ 3.");
+    assert_prolog_success!(&mut wam, "X is (-3) ** (1 rdiv 3), Y is X ** 3, Y ~ -3.");
+    assert_prolog_failure!(&mut wam, "X is (-5) ** (1 rdiv 3), Y is X ** 3, Y ~ -3.");
+    assert_prolog_failure!(&mut wam, "X is 5 ** (1 rdiv 3), Y is X ** 3, Y ~ 3.");
+    assert_prolog_failure!(&mut wam, "X is (1 rdiv 3) ** 0.5, Y is X ** 2, X ~ Y.");
+    assert_prolog_success!(&mut wam, "X is (1 rdiv 3) ** 0.5, Y is X ** 2, 1 rdiv 3 ~ Y.");
 
-    assert_prolog_success!(&mut wam, "?- X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ -1 rdiv 5.");
-    assert_prolog_failure!(&mut wam, "?- X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ 1 rdiv 5.");
+    assert_prolog_success!(&mut wam, "X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ -1 rdiv 5.");
+    assert_prolog_failure!(&mut wam, "X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ 1 rdiv 5.");
 
-    assert_prolog_success!(&mut wam, "?- X is (0 rdiv 5) ** 5.",
+    assert_prolog_success!(&mut wam, "X is (0 rdiv 5) ** 5.",
                            [["X = 0"]]);
-    assert_prolog_success!(&mut wam, "?- X is (-0 rdiv 5) ** 5.",
+    assert_prolog_success!(&mut wam, "X is (-0 rdiv 5) ** 5.",
                            [["X = 0"]]);
-    assert_prolog_success!(&mut wam, "?- X is (0 rdiv 5) ** 0.",
+    assert_prolog_success!(&mut wam, "X is (0 rdiv 5) ** 0.",
                            [["X = 1.0"]]);
-    assert_prolog_success!(&mut wam, "?- catch(_ is (0 rdiv 0) ** 5, error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(_ is (0 rdiv 0) ** 5, error(E, _), true).",
                            [["E = evaluation_error(zero_divisor)"]]);
 }
 
 #[test]
 fn test_queries_on_exceptions()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     submit(&mut wam, "f(a). f(_) :- throw(stuff).");
     submit(&mut wam, "handle(stuff).");
 
-    assert_prolog_success!(&mut wam, "?- catch(f(X), E, handle(E)).",
+    assert_prolog_success!(&mut wam, "catch(f(X), E, handle(E)).",
                            [["E = _2", "X = a"],
                             ["E = stuff", "X = _1"]]);
 
@@ -1133,62 +1141,62 @@ fn test_queries_on_exceptions()
     submit(&mut wam, "g(x). g(y). g(z).");
     submit(&mut wam, "handle(x). handle(y).");
 
-    assert_prolog_success!(&mut wam, "?- catch(f(X), X, handle(X)).",
+    assert_prolog_success!(&mut wam, "catch(f(X), X, handle(X)).",
                            [["X = a"],
                             ["X = x"],
                             ["X = y"],
                             ["X = z"]]);
-    assert_prolog_success!(&mut wam, "?- catch(f(a), _, handle(X)).",
+    assert_prolog_success!(&mut wam, "catch(f(a), _, handle(X)).",
                            [["X = _4"]]);
-    assert_prolog_failure!(&mut wam, "?- catch(f(b), _, handle(X)).");
+    assert_prolog_failure!(&mut wam, "catch(f(b), _, handle(X)).");
 
     submit(&mut wam, "g(x). g(X) :- throw(x).");
 
-    assert_prolog_success!(&mut wam, "?- catch(f(X), x, handle(X)).",
+    assert_prolog_success!(&mut wam, "catch(f(X), x, handle(X)).",
                            [["X = a"],
                             ["X = x"],
                             ["X = x"],
                             ["X = y"]]);
-    assert_prolog_success!(&mut wam, "?- catch(f(X), x, handle(z)).",
+    assert_prolog_success!(&mut wam, "catch(f(X), x, handle(z)).",
                            [["X = a"],
                             ["X = x"]]);
-    assert_prolog_success!(&mut wam, "?- catch(f(z), x, handle(x)).");
-    assert_prolog_success!(&mut wam, "?- catch(f(z), x, handle(y)).");
-    assert_prolog_failure!(&mut wam, "?- catch(f(z), x, handle(z)).");
+    assert_prolog_success!(&mut wam, "catch(f(z), x, handle(x)).");
+    assert_prolog_success!(&mut wam, "catch(f(z), x, handle(y)).");
+    assert_prolog_failure!(&mut wam, "catch(f(z), x, handle(z)).");
 
     submit(&mut wam, "f(X) :- throw(stuff).");
     submit(&mut wam, "handle(stuff). handle(other_stuff).");
 
     // the first 3 cases should deterministically succeed.
-    assert_prolog_success!(&mut wam, "?- catch(f(X), E, handle(E)).",
+    assert_prolog_success!(&mut wam, "catch(f(X), E, handle(E)).",
                            [["X = _1", "E = stuff"]]);
-    assert_prolog_success!(&mut wam, "?- catch(f(X), E, handle(stuff)).",
+    assert_prolog_success!(&mut wam, "catch(f(X), E, handle(stuff)).",
                            [["X = _1", "E = stuff"]]);
-    assert_prolog_success!(&mut wam, "?- catch(f(X), E, handle(other_stuff)).",
+    assert_prolog_success!(&mut wam, "catch(f(X), E, handle(other_stuff)).",
                            [["X = _1", "E = stuff"]]);
-    assert_prolog_failure!(&mut wam, "?- catch(f(X), E, handle(not_stuff)).");
+    assert_prolog_failure!(&mut wam, "catch(f(X), E, handle(not_stuff)).");
 
     submit(&mut wam, "f(success). f(X) :- catch(g(X), E, handle(E)).");
     submit(&mut wam, "g(g_success). g(g_success_2). g(X) :- throw(X).");
     submit(&mut wam, "handle(x). handle(y). handle(z).");
 
-    assert_prolog_success!(&mut wam, "?- catch(f(X), E, E).",
+    assert_prolog_success!(&mut wam, "catch(f(X), E, E).",
                            [["X = success", "E = _2"],
                             ["X = g_success", "E = _2"],
                             ["X = g_success_2", "E = _2"],
                             ["X = _1", "E = _2"],
                             ["X = _1", "E = _2"],
                             ["X = _1", "E = _2"]]);
-    assert_prolog_failure!(&mut wam, "?- catch(f(fail), _, _).");
-    assert_prolog_success!(&mut wam, "?- catch(f(x), _, _).");
-    assert_prolog_success!(&mut wam, "?- catch(f(y), _, _).");
-    assert_prolog_success!(&mut wam, "?- catch(f(z), _, _).");
+    assert_prolog_failure!(&mut wam, "catch(f(fail), _, _).");
+    assert_prolog_success!(&mut wam, "catch(f(x), _, _).");
+    assert_prolog_success!(&mut wam, "catch(f(y), _, _).");
+    assert_prolog_success!(&mut wam, "catch(f(z), _, _).");
 
     submit(&mut wam, "f(success). f(E) :- catch(g(E), E, handle(E)).");
     submit(&mut wam, "g(g_success). g(g_success_2). g(X) :- throw(X).");
     submit(&mut wam, "handle(x). handle(y). handle(z). handle(v) :- throw(X).");
 
-    assert_prolog_success!(&mut wam, "?- catch(f(X), E, E).",
+    assert_prolog_success!(&mut wam, "catch(f(X), E, E).",
                            [["X = success", "E = _2"],
                             ["X = g_success", "E = _2"],
                             ["X = g_success_2", "E = _2"],
@@ -1199,7 +1207,7 @@ fn test_queries_on_exceptions()
     submit(&mut wam, "handle(x). handle(y). handle(z). handle(v) :- throw(handle_top(X)).");
     submit(&mut wam, "handle_top(an_error_1). handle_top(an_error_2).");
 
-    assert_prolog_success!(&mut wam, "?- catch(f(X), E, E).",
+    assert_prolog_success!(&mut wam, "catch(f(X), E, E).",
                            [["X = success", "E = _2"],
                             ["X = g_success", "E = _2"],
                             ["X = g_success_2", "E = _2"],
@@ -1211,7 +1219,7 @@ fn test_queries_on_exceptions()
 
     submit(&mut wam, "handle(x). handle(y). handle(z). handle(v) :- throw(X).");
 
-    assert_prolog_success!(&mut wam, "?- catch(f(X), E, handle_top(E)).",
+    assert_prolog_success!(&mut wam, "catch(f(X), E, handle_top(E)).",
                            [["X = success", "E = _2"],
                             ["X = g_success", "E = _2"],
                             ["X = g_success_2", "E = _2"],
@@ -1224,93 +1232,93 @@ fn test_queries_on_exceptions()
 
 #[test]
 fn test_queries_on_skip_max_list() {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     // test on proper and empty lists.
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, 5, [], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(N, 5, [], Xs).",
                            [["Xs = []", "N = 0"]]);
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, 5, [a,b,c], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(N, 5, [a,b,c], Xs).",
                            [["Xs = []", "N = 3"]]);
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, 2, [a,b,c], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(N, 2, [a,b,c], Xs).",
                            [["Xs = [c]", "N = 2"]]);
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, 3, [a,b,c], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(N, 3, [a,b,c], Xs).",
                            [["Xs = []", "N = 3"]]);
 
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, 0, [], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(N, 0, [], Xs).",
                            [["Xs = []", "N = 0"]]);
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, 0, [a,b,c], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(N, 0, [a,b,c], Xs).",
                            [["Xs = [a, b, c]", "N = 0"]]);
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, 0, [a,b,c], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(N, 0, [a,b,c], Xs).",
                            [["Xs = [a, b, c]", "N = 0"]]);
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, 0, [a,b,c], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(N, 0, [a,b,c], Xs).",
                            [["Xs = [a, b, c]", "N = 0"]]);
 
-    assert_prolog_failure!(&mut wam, "?- '$skip_max_list'(4, 0, [], Xs).");
-    assert_prolog_failure!(&mut wam, "?- '$skip_max_list'(3, 0, [a,b,c], Xs).");
-    assert_prolog_failure!(&mut wam, "?- '$skip_max_list'(2, 0, [a,b,c], Xs).");
-    assert_prolog_failure!(&mut wam, "?- '$skip_max_list'(1, 0, [a,b,c], Xs).");
+    assert_prolog_failure!(&mut wam, "'$skip_max_list'(4, 0, [], Xs).");
+    assert_prolog_failure!(&mut wam, "'$skip_max_list'(3, 0, [a,b,c], Xs).");
+    assert_prolog_failure!(&mut wam, "'$skip_max_list'(2, 0, [a,b,c], Xs).");
+    assert_prolog_failure!(&mut wam, "'$skip_max_list'(1, 0, [a,b,c], Xs).");
 
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(0, 5, [], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(0, 5, [], Xs).",
                            [["Xs = []"]]);
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(3, 5, [a,b,c], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(3, 5, [a,b,c], Xs).",
                            [["Xs = []"]]);
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(2, 2, [a,b,c], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(2, 2, [a,b,c], Xs).",
                            [["Xs = [c]"]]);
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(3, 3, [a,b,c], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(3, 3, [a,b,c], Xs).",
                            [["Xs = []"]]);
 
     // tests on proper and empty lists with no max.
 
     // test on proper and empty lists.
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, -1, [], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(N, -1, [], Xs).",
                            [["Xs = []", "N = 0"]]);
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, -1, [a,b,c], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(N, -1, [a,b,c], Xs).",
                            [["Xs = []", "N = 3"]]);
 
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, -1, [], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(N, -1, [], Xs).",
                            [["Xs = []", "N = 0"]]);
 
-    assert_prolog_failure!(&mut wam, "?- '$skip_max_list'(4, -1, [], Xs).");
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(3, -1, [a,b,c], Xs).",
+    assert_prolog_failure!(&mut wam, "'$skip_max_list'(4, -1, [], Xs).");
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(3, -1, [a,b,c], Xs).",
                            [["Xs = []"]]);
 
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(0, -1, [], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(0, -1, [], Xs).",
                            [["Xs = []"]]);
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(3, -1, [a,b,c], Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(3, -1, [a,b,c], Xs).",
                            [["Xs = []"]]);
 
     // tests on partial lists.
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(3, 4, [a,b,c|X], Xs0).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(3, 4, [a,b,c|X], Xs0).",
                            [["X = _1", "Xs0 = _1"]]);
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(3, 3, [a,b,c|X], Xs0).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(3, 3, [a,b,c|X], Xs0).",
                            [["X = _1", "Xs0 = _1"]]);
-    assert_prolog_failure!(&mut wam, "?- '$skip_max_list'(3, 2, [a,b,c|X], Xs0).");
-    assert_prolog_failure!(&mut wam, "?- '$skip_max_list'(3, 1, [a,b,c|X], Xs0).");
-    assert_prolog_failure!(&mut wam, "?- '$skip_max_list'(3, 0, [a,b,c|X], Xs0).");
+    assert_prolog_failure!(&mut wam, "'$skip_max_list'(3, 2, [a,b,c|X], Xs0).");
+    assert_prolog_failure!(&mut wam, "'$skip_max_list'(3, 1, [a,b,c|X], Xs0).");
+    assert_prolog_failure!(&mut wam, "'$skip_max_list'(3, 0, [a,b,c|X], Xs0).");
 
     // tests on cyclic lists.
-    assert_prolog_failure!(&mut wam, "?- Xs = [a,b|Xs], '$skip_max_list'(3, 5, X, Xs0).");
-    assert_prolog_failure!(&mut wam, "?- X = [a,b|Y], Y = [c,d|X], '$skip_max_list'(4, 5, X, Xs0).");
-    assert_prolog_failure!(&mut wam, "?- X = [a,b|Y], Y = [c,d|X], '$skip_max_list'(4, 3, X, Xs0).");
+    assert_prolog_failure!(&mut wam, "Xs = [a,b|Xs], '$skip_max_list'(3, 5, X, Xs0).");
+    assert_prolog_failure!(&mut wam, "X = [a,b|Y], Y = [c,d|X], '$skip_max_list'(4, 5, X, Xs0).");
+    assert_prolog_failure!(&mut wam, "X = [a,b|Y], Y = [c,d|X], '$skip_max_list'(4, 3, X, Xs0).");
 
     // tests on non lists.
-    assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, 9, non_list, Xs).",
+    assert_prolog_success!(&mut wam, "'$skip_max_list'(N, 9, non_list, Xs).",
                            [["Xs = non_list", "N = 0"]]);
 }
 
 #[test]
 fn test_queries_on_conditionals()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     submit(&mut wam, "test(A) :- (   A =:= 2 -> writeq(\"A is 2\")
                                  ;   A =:= 3 -> writeq(\"A is 3\")
                                  ;   A = \"not 2 or 3\"
                                  ).");
 
-    assert_prolog_success!(&mut wam, "?- catch(test(A), error(instantiation_error, _), true).");
-    assert_prolog_success!(&mut wam, "?- A = 2, test(A).", [["A = 2"]]);
-    assert_prolog_success!(&mut wam, "?- A = 3, test(A), B = 3, test(B).", [["A = 3", "B = 3"]]);
+    assert_prolog_success!(&mut wam, "catch(test(A), error(instantiation_error, _), true).");
+    assert_prolog_success!(&mut wam, "A = 2, test(A).", [["A = 2"]]);
+    assert_prolog_success!(&mut wam, "A = 3, test(A), B = 3, test(B).", [["A = 3", "B = 3"]]);
 
     submit(&mut wam, "f(a). f(b).");
     submit(&mut wam, "g(1). g(2). g(3).");
@@ -1319,174 +1327,172 @@ fn test_queries_on_conditionals()
                                            ; integer(X) -> g(X)
                                            ; atomic(X)).");
 
-    assert_prolog_success!(&mut wam, "?- typed_dispatch(X).", [["X = a"], ["X = b"]]);
-    assert_prolog_success!(&mut wam, "?- typed_dispatch(a).");
-    assert_prolog_success!(&mut wam, "?- typed_dispatch(b).");
-    assert_prolog_success!(&mut wam, "?- typed_dispatch(c).");
-    assert_prolog_success!(&mut wam, "?- typed_dispatch(1).");
-    assert_prolog_success!(&mut wam, "?- typed_dispatch(2).");
-    assert_prolog_success!(&mut wam, "?- typed_dispatch(3).");
-    assert_prolog_failure!(&mut wam, "?- typed_dispatch(4).");
-    assert_prolog_failure!(&mut wam, "?- typed_dispatch(5).");
-    assert_prolog_failure!(&mut wam, "?- typed_dispatch(compound(term)).");
+    assert_prolog_success!(&mut wam, "typed_dispatch(X).", [["X = a"], ["X = b"]]);
+    assert_prolog_success!(&mut wam, "typed_dispatch(a).");
+    assert_prolog_success!(&mut wam, "typed_dispatch(b).");
+    assert_prolog_success!(&mut wam, "typed_dispatch(c).");
+    assert_prolog_success!(&mut wam, "typed_dispatch(1).");
+    assert_prolog_success!(&mut wam, "typed_dispatch(2).");
+    assert_prolog_success!(&mut wam, "typed_dispatch(3).");
+    assert_prolog_failure!(&mut wam, "typed_dispatch(4).");
+    assert_prolog_failure!(&mut wam, "typed_dispatch(5).");
+    assert_prolog_failure!(&mut wam, "typed_dispatch(compound(term)).");
 
     submit(&mut wam, "f(a). f(b). f(compound(term)).");
     submit(&mut wam, "g(X, Y) :- f(X), (atomic(X) -> X = a ; X = a ; X = compound(Y)).");
 
-    assert_prolog_success!(&mut wam, "?- g(X, Y).",
+    assert_prolog_success!(&mut wam, "g(X, Y).",
                            [["Y = _1", "X = a"],
                             ["Y = term", "X = compound(term)"]]);
 
-    assert_prolog_success!(&mut wam, "?- g(X, X).", [["X = a"]]);
-    assert_prolog_success!(&mut wam, "?- g(compound(X), X).", [["X = term"]]);
-    assert_prolog_success!(&mut wam, "?- g(X, term).", [["X = a"], ["X = compound(term)"]]);
-    assert_prolog_success!(&mut wam, "?- g(a, _).");
-    assert_prolog_success!(&mut wam, "?- g(X, _), X = a.", [["X = a"]]);
+    assert_prolog_success!(&mut wam, "g(X, X).", [["X = a"]]);
+    assert_prolog_success!(&mut wam, "g(compound(X), X).", [["X = term"]]);
+    assert_prolog_success!(&mut wam, "g(X, term).", [["X = a"], ["X = compound(term)"]]);
+    assert_prolog_success!(&mut wam, "g(a, _).");
+    assert_prolog_success!(&mut wam, "g(X, _), X = a.", [["X = a"]]);
 
     submit(&mut wam, "g(X) :- var(X) -> (var(X) -> X is 3 + 3 ; X = not_6).");
 
-    assert_prolog_success!(&mut wam, "?- g(X).", [["X = 6"]]);
-    assert_prolog_failure!(&mut wam, "?- g(1).");
-    assert_prolog_failure!(&mut wam, "?- g(6).");
-    assert_prolog_failure!(&mut wam, "?- g(not_6).");
+    assert_prolog_success!(&mut wam, "g(X).", [["X = 6"]]);
+    assert_prolog_failure!(&mut wam, "g(1).");
+    assert_prolog_failure!(&mut wam, "g(6).");
+    assert_prolog_failure!(&mut wam, "g(not_6).");
 
-    assert_prolog_success!(&mut wam, "?- f(X), (g(Y), !).", [["X = a", "Y = 6"]]);
+    assert_prolog_success!(&mut wam, "f(X), (g(Y), !).", [["X = a", "Y = 6"]]);
 
     submit(&mut wam, "test(X, [X]) :- (atomic(X) -> true ; throw(type_error(atomic_expected, X))).
                       test(_, _).");
 
-    assert_prolog_success!(&mut wam, "?- catch(test(a, [a]), type_error(E), true).",
+    assert_prolog_success!(&mut wam, "catch(test(a, [a]), type_error(E), true).",
                            [["E = _6"], ["E = _6"]]);
 
-    assert_prolog_success!(&mut wam, "?- f(X), call(->, atomic(X), true).",
+    assert_prolog_success!(&mut wam, "f(X), call(->, atomic(X), true).",
                            [["X = a"], ["X = b"]]);
 }
 
 #[test]
 fn test_queries_on_modules()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     submit(&mut wam, ":- use_module(library(lists)).");
 
-    compile_user_module(&mut wam, "
+    submit_code(&mut wam, "
 :- module(my_lists, [local_member/2, reverse/2]).
 :- use_module(library(lists), [member/2]).
 
 local_member(X, Xs) :- member(X, Xs).
 
-reverse(Xs, Ys) :- lists:reverse(Xs, Ys).
-".as_bytes());
+reverse(Xs, Ys) :- lists:reverse(Xs, Ys).");
 
-    assert_prolog_success!(&mut wam, "?- my_lists:local_member(1, [1,2,3]).");
-    assert_prolog_success!(&mut wam, "?- my_lists:reverse([a,b,c], [c,b,a]).");
+    assert_prolog_success!(&mut wam, "my_lists:local_member(1, [1,2,3]).");
+    assert_prolog_success!(&mut wam, "my_lists:reverse([a,b,c], [c,b,a]).");
 
-    compile_user_module(&mut wam, "
+    submit_code(&mut wam, "
 :- module(my_lists_2, [local_member/2]).
-:- use_module(library(my_lists), [local_member/2]).
-".as_bytes());
+:- use_module(library(my_lists), [local_member/2]).");
 
-    assert_prolog_success!(&mut wam, "?- my_lists_2:local_member(1, [1,2,3]).");
-    assert_prolog_success!(&mut wam, "?- catch(local_member(X, Xs), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "my_lists_2:local_member(1, [1,2,3]).");
+    assert_prolog_success!(&mut wam, "catch(local_member(X, Xs), error(E, _), true).",
                            [["X = _1", "E = existence_error(procedure, local_member/2)", "Xs = _2"]]);
 
     submit(&mut wam, ":- use_module(library(lists), [reverse/2]).");
 
-    assert_prolog_success!(&mut wam, "?- catch(member(_, _), error(existence_error(procedure, P), _), true).",
+    assert_prolog_success!(&mut wam, "catch(member(_, _), error(existence_error(procedure, P), _), true).",
                            [["P = member/2"]]);
-    assert_prolog_success!(&mut wam, "?- reverse(_, _).");
+    assert_prolog_success!(&mut wam, "reverse(_, _).");
 
     submit(&mut wam, ":- use_module(library(lists), []).");
 
-    assert_prolog_success!(&mut wam, "?- catch(reverse(_, _), error(existence_error(procedure, P), _), true).",
+    assert_prolog_success!(&mut wam, "catch(reverse(_, _), error(existence_error(procedure, P), _), true).",
                            [["P = reverse/2"]]);
 }
 
 #[test]
 fn test_queries_on_builtins()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     submit(&mut wam, ":- use_module(library(lists)).");
     submit(&mut wam, ":- use_module(library(control)).");
 
-    assert_prolog_failure!(&mut wam, "?- atom(X).");
-    assert_prolog_success!(&mut wam, "?- atom(a).");
-    assert_prolog_failure!(&mut wam, "?- atom(\"string\").");
-    assert_prolog_success!(&mut wam, "?- atom([]).");
-    assert_prolog_failure!(&mut wam, "?- atom(1).");
-    assert_prolog_failure!(&mut wam, "?- atom(0).");
-    assert_prolog_failure!(&mut wam, "?- atom(0.0).");
-    assert_prolog_failure!(&mut wam, "?- atom([a,b,c]).");
-    assert_prolog_failure!(&mut wam, "?- atom(atop(the_trees)).");
-
-    assert_prolog_failure!(&mut wam, "?- atomic(X).");
-    assert_prolog_success!(&mut wam, "?- atomic(a).");
-    assert_prolog_success!(&mut wam, "?- atomic(\"string\").");
-    assert_prolog_success!(&mut wam, "?- atomic([]).");
-    assert_prolog_success!(&mut wam, "?- atomic(1).");
-    assert_prolog_success!(&mut wam, "?- atomic(0).");
-    assert_prolog_success!(&mut wam, "?- atomic(0.0).");
-    assert_prolog_failure!(&mut wam, "?- atomic([a,b,c]).");
-    assert_prolog_failure!(&mut wam, "?- atomic(atop(the_trees)).");
-
-    assert_prolog_success!(&mut wam, "?- var(X), X = 3, atomic(X).", [["X = 3"]]);
-    assert_prolog_failure!(&mut wam, "?- var(X), X = 3, var(X).");
-
-    assert_prolog_success!(&mut wam, "?- arg(1, f(a,b,c,d), Arg).", [["Arg = a"]]);
-    assert_prolog_success!(&mut wam, "?- arg(2, f(a,b,c,d), Arg).", [["Arg = b"]]);
-    assert_prolog_success!(&mut wam, "?- arg(3, f(a,b,c,d), Arg).", [["Arg = c"]]);
-    assert_prolog_success!(&mut wam, "?- arg(4, f(a,b,c,d), Arg).", [["Arg = d"]]);
-
-    assert_prolog_success!(&mut wam, "?- catch(arg(N, f, Arg), error(E, _), true).",
+    assert_prolog_failure!(&mut wam, "atom(X).");
+    assert_prolog_success!(&mut wam, "atom(a).");
+    assert_prolog_failure!(&mut wam, "atom(\"string\").");
+    assert_prolog_success!(&mut wam, "atom([]).");
+    assert_prolog_failure!(&mut wam, "atom(1).");
+    assert_prolog_failure!(&mut wam, "atom(0).");
+    assert_prolog_failure!(&mut wam, "atom(0.0).");
+    assert_prolog_failure!(&mut wam, "atom([a,b,c]).");
+    assert_prolog_failure!(&mut wam, "atom(atop(the_trees)).");
+
+    assert_prolog_failure!(&mut wam, "atomic(X).");
+    assert_prolog_success!(&mut wam, "atomic(a).");
+    assert_prolog_success!(&mut wam, "atomic(\"string\").");
+    assert_prolog_success!(&mut wam, "atomic([]).");
+    assert_prolog_success!(&mut wam, "atomic(1).");
+    assert_prolog_success!(&mut wam, "atomic(0).");
+    assert_prolog_success!(&mut wam, "atomic(0.0).");
+    assert_prolog_failure!(&mut wam, "atomic([a,b,c]).");
+    assert_prolog_failure!(&mut wam, "atomic(atop(the_trees)).");
+
+    assert_prolog_success!(&mut wam, "var(X), X = 3, atomic(X).", [["X = 3"]]);
+    assert_prolog_failure!(&mut wam, "var(X), X = 3, var(X).");
+
+    assert_prolog_success!(&mut wam, "arg(1, f(a,b,c,d), Arg).", [["Arg = a"]]);
+    assert_prolog_success!(&mut wam, "arg(2, f(a,b,c,d), Arg).", [["Arg = b"]]);
+    assert_prolog_success!(&mut wam, "arg(3, f(a,b,c,d), Arg).", [["Arg = c"]]);
+    assert_prolog_success!(&mut wam, "arg(4, f(a,b,c,d), Arg).", [["Arg = d"]]);
+
+    assert_prolog_success!(&mut wam, "catch(arg(N, f, Arg), error(E, _), true).",
                            [["E = instantiation_error", "Arg = _3", "N = _1"]]);
 
-    assert_prolog_failure!(&mut wam, "?- arg(N, f(arg, arg, arg), not_arg).");
-    assert_prolog_failure!(&mut wam, "?- arg(1, f(arg, not_arg, not_arg), not_arg).");
-    assert_prolog_success!(&mut wam, "?- arg(2, f(arg, not_arg, not_arg), not_arg).");
-    assert_prolog_success!(&mut wam, "?- arg(3, f(arg, not_arg, not_arg), not_arg).");
+    assert_prolog_failure!(&mut wam, "arg(N, f(arg, arg, arg), not_arg).");
+    assert_prolog_failure!(&mut wam, "arg(1, f(arg, not_arg, not_arg), not_arg).");
+    assert_prolog_success!(&mut wam, "arg(2, f(arg, not_arg, not_arg), not_arg).");
+    assert_prolog_success!(&mut wam, "arg(3, f(arg, not_arg, not_arg), not_arg).");
 
-    assert_prolog_success!(&mut wam, "?- functor(f(a,b,c), F, Arity).",
+    assert_prolog_success!(&mut wam, "functor(f(a,b,c), F, Arity).",
                            [["F = f", "Arity = 3"]]);
 
-    assert_prolog_success!(&mut wam, "?- functor(f(a,b,c), F, N).",
+    assert_prolog_success!(&mut wam, "functor(f(a,b,c), F, N).",
                            [["F = f", "N = 3"]]);
-    assert_prolog_failure!(&mut wam, "?- functor(f(a,b,c), g, N).");
-    assert_prolog_success!(&mut wam, "?- functor(f(a,b,c), F, 3).", [["F = f"]]);
-    assert_prolog_failure!(&mut wam, "?- functor(f(a,b,c), F, 4).");
-    assert_prolog_failure!(&mut wam, "?- functor(f(a,b,c), g, 3).");
+    assert_prolog_failure!(&mut wam, "functor(f(a,b,c), g, N).");
+    assert_prolog_success!(&mut wam, "functor(f(a,b,c), F, 3).", [["F = f"]]);
+    assert_prolog_failure!(&mut wam, "functor(f(a,b,c), F, 4).");
+    assert_prolog_failure!(&mut wam, "functor(f(a,b,c), g, 3).");
 
-    assert_prolog_success!(&mut wam, "?- functor(F, f, 0).", [["F = f"]]);
+    assert_prolog_success!(&mut wam, "functor(F, f, 0).", [["F = f"]]);
 
-    assert_prolog_success!(&mut wam, "?- functor(Func, f, 3).", [["Func = f(_2, _3, _4)"]]);
-    assert_prolog_success!(&mut wam, "?- functor(Func, f, 4).", [["Func = f(_2, _3, _4, _5)"]]);
+    assert_prolog_success!(&mut wam, "functor(Func, f, 3).", [["Func = f(_2, _3, _4)"]]);
+    assert_prolog_success!(&mut wam, "functor(Func, f, 4).", [["Func = f(_2, _3, _4, _5)"]]);
 
-    assert_prolog_success!(&mut wam, "?- catch(functor(F, \"sdf\", 3), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(functor(F, \"sdf\", 3), error(E, _), true).",
                            [["E = type_error(atom, [s, d, f])", "F = _1"]]);
-    assert_prolog_success!(&mut wam, "?- catch(functor(Func, F, 3), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(functor(Func, F, 3), error(E, _), true).",
                            [["E = instantiation_error", "Func = _1", "F = _2"]]);
-    assert_prolog_success!(&mut wam, "?- catch(functor(Func, f, N), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(functor(Func, f, N), error(E, _), true).",
                            [["E = instantiation_error", "Func = _1", "N = _3"]]);
-    assert_prolog_failure!(&mut wam, "?- catch(functor(Func, f, N), error(E, _), false).");
-
-    assert_prolog_success!(&mut wam, "?- X is 3, call(integer, X).");
-    assert_prolog_failure!(&mut wam, "?- X is 3 + 3.5, call(integer, X).");
-    assert_prolog_success!(&mut wam, "?- X is 3 + 3.5, \\+ call(integer, X).");
-    assert_prolog_success!(&mut wam, "?- X is 3 + 3.5, \\+ integer(X).");
-
-    assert_prolog_success!(&mut wam, "?- Func =.. [atom].", [["Func = atom"]]);
-    assert_prolog_success!(&mut wam, "?- Func =.. [\"sdf\"].", [["Func = [s, d, f]"]]);
-    assert_prolog_success!(&mut wam, "?- Func =.. [1].", [["Func = 1"]]);
-    assert_prolog_success!(&mut wam, "?- catch(Func =.. [1,2], error(type_error(atom, 1), _), true).");
-    assert_prolog_success!(&mut wam, "?- f(1,2,3) =.. List.", [["List = [f, 1, 2, 3]"]]);
-    assert_prolog_success!(&mut wam, "?- f(1,2,3) =.. [f,1,2,3].");
-    assert_prolog_failure!(&mut wam, "?- f(1,2,3) =.. [f,1].");
-    assert_prolog_failure!(&mut wam, "?- f(1,2,3) =.. [g,1,2,3].");
-    assert_prolog_success!(&mut wam, "?- f(1,2,3) =.. [f,X,Y,Z].",
+    assert_prolog_failure!(&mut wam, "catch(functor(Func, f, N), error(E, _), false).");
+
+    assert_prolog_success!(&mut wam, "X is 3, call(integer, X).");
+    assert_prolog_failure!(&mut wam, "X is 3 + 3.5, call(integer, X).");
+    assert_prolog_success!(&mut wam, "X is 3 + 3.5, \\+ call(integer, X).");
+    assert_prolog_success!(&mut wam, "X is 3 + 3.5, \\+ integer(X).");
+
+    assert_prolog_success!(&mut wam, "Func =.. [atom].", [["Func = atom"]]);
+    assert_prolog_success!(&mut wam, "Func =.. [\"sdf\"].", [["Func = [s, d, f]"]]);
+    assert_prolog_success!(&mut wam, "Func =.. [1].", [["Func = 1"]]);
+    assert_prolog_success!(&mut wam, "catch(Func =.. [1,2], error(type_error(atom, 1), _), true).");
+    assert_prolog_success!(&mut wam, "f(1,2,3) =.. List.", [["List = [f, 1, 2, 3]"]]);
+    assert_prolog_success!(&mut wam, "f(1,2,3) =.. [f,1,2,3].");
+    assert_prolog_failure!(&mut wam, "f(1,2,3) =.. [f,1].");
+    assert_prolog_failure!(&mut wam, "f(1,2,3) =.. [g,1,2,3].");
+    assert_prolog_success!(&mut wam, "f(1,2,3) =.. [f,X,Y,Z].",
                            [["X = 1", "Y = 2", "Z = 3"]]);
 
-    assert_prolog_success!(&mut wam, "?- length([a,b,c], N).", [["N = 3"]]);
-    assert_prolog_success_with_limit!(&mut wam, "?- length(Xs, N).",
+    assert_prolog_success!(&mut wam, "length([a,b,c], N).", [["N = 3"]]);
+    assert_prolog_success_with_limit!(&mut wam, "length(Xs, N).",
                                       [["N = 0", "Xs = []"],
                                        ["N = 1", "Xs = [_4]"],
                                        ["N = 2", "Xs = [_4, _8]"],
@@ -1495,321 +1501,320 @@ fn test_queries_on_builtins()
                                        ["N = 5", "Xs = [_4, _8, _12, _16, _20]"]],
                                       6);
 
-    assert_prolog_success!(&mut wam, "?- length(Xs, 3).", [["Xs = [_5, _9, _13]"]]);
-    assert_prolog_success!(&mut wam, "?- length([], N).", [["N = 0"]]);
-    assert_prolog_success!(&mut wam, "?- length(Xs, 0).", [["Xs = []"]]);
-    assert_prolog_success!(&mut wam, "?- length([a,b,[a,b,c]], 3).");
-    assert_prolog_failure!(&mut wam, "?- length([a,b,[a,b,c]], 2).");
-    assert_prolog_success!(&mut wam, "?- catch(length(a, []), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "length(Xs, 3).", [["Xs = [_5, _9, _13]"]]);
+    assert_prolog_success!(&mut wam, "length([], N).", [["N = 0"]]);
+    assert_prolog_success!(&mut wam, "length(Xs, 0).", [["Xs = []"]]);
+    assert_prolog_success!(&mut wam, "length([a,b,[a,b,c]], 3).");
+    assert_prolog_failure!(&mut wam, "length([a,b,[a,b,c]], 2).");
+    assert_prolog_success!(&mut wam, "catch(length(a, []), error(E, _), true).",
                            [["E = type_error(integer, [])"]]);
 
-    assert_prolog_success!(&mut wam, "?- copy_term([1,2,3], [X,Y,Z]).",
+    assert_prolog_success!(&mut wam, "copy_term([1,2,3], [X,Y,Z]).",
                            [["Z = 3", "Y = 2", "X = 1"]]);
-    assert_prolog_success!(&mut wam, "?- copy_term(f(X, [a], Z), f(X, Y, Z)).",
+    assert_prolog_success!(&mut wam, "copy_term(f(X, [a], Z), f(X, Y, Z)).",
                            [["X = _3", "Y = [a]", "Z = _5"]]);
-    assert_prolog_failure!(&mut wam, "?- copy_term(g(X), f(X)).");
-    assert_prolog_success!(&mut wam, "?- copy_term(f(X), f(X)).",
+    assert_prolog_failure!(&mut wam, "copy_term(g(X), f(X)).");
+    assert_prolog_success!(&mut wam, "copy_term(f(X), f(X)).",
                            [["X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- copy_term([[[[X, Y], Y], X]], Term).",
+    assert_prolog_success!(&mut wam, "copy_term([[[[X, Y], Y], X]], Term).",
                            [["Term = [[[[_22, _26], _26], _22]]", "X = _2", "Y = _0"]]);
-    assert_prolog_success!(&mut wam, "?- copy_term([X, [Y, [X]]], Term).",
+    assert_prolog_success!(&mut wam, "copy_term([X, [Y, [X]]], Term).",
                            [["Term = [_12, [_16, [_12]]]", "X = _0", "Y = _4"]]);
 
     // test copy_term on cyclic terms.
-    assert_prolog_failure!(&mut wam, "?- X = g(X, Y), Y = f(X), copy_term(Y, g(Z)).");
-    assert_prolog_success!(&mut wam, "?- X = g(X, Y), Y = f(X), copy_term(Y, f(Z)).",
+    assert_prolog_failure!(&mut wam, "X = g(X, Y), Y = f(X), copy_term(Y, g(Z)).");
+    assert_prolog_success!(&mut wam, "X = g(X, Y), Y = f(X), copy_term(Y, f(Z)).",
                            [["Y = f(g(X, Y))", "X = g(X, f(X))", "Z = g(Z, f(Z))"]]);
-    assert_prolog_success!(&mut wam, "?- X = g(X, Y), Y = f(X), copy_term(Y, V).",
+    assert_prolog_success!(&mut wam, "X = g(X, Y), Y = f(X), copy_term(Y, V).",
                            [["Y = f(g(X, Y))", "X = g(X, f(X))", "V = f(g(_9, V))"]]);
-    assert_prolog_success!(&mut wam, "?- f(Y,Y,[X,a,[],Y]) = Term, copy_term(Term, NewTerm).",
+    assert_prolog_success!(&mut wam, "f(Y,Y,[X,a,[],Y]) = Term, copy_term(Term, NewTerm).",
                            [["NewTerm = f(_16, _16, [_19, a, [], _16])",
                              "Term = f(_0, Y, [_6, a, [], Y])",
                              "X = _6", "Y = _0"]]);
 
-    assert_prolog_success!(&mut wam, "?- float(3.14159269).");
-    assert_prolog_failure!(&mut wam, "?- float(3).");
-    assert_prolog_failure!(&mut wam, "?- float(\"sdfsa\").");
-    assert_prolog_failure!(&mut wam, "?- float(atom).");
-    assert_prolog_failure!(&mut wam, "?- float(structure(functor)).");
-    assert_prolog_failure!(&mut wam, "?- float([1,2,3]).");
-    assert_prolog_failure!(&mut wam, "?- float([1,2,X]).");
-    assert_prolog_failure!(&mut wam, "?- X is 3 rdiv 4, float(X).");
-
-    assert_prolog_success!(&mut wam, "?- X is 3 rdiv 4, rational(X).");
-    assert_prolog_failure!(&mut wam, "?- rational(3).");
-    assert_prolog_failure!(&mut wam, "?- rational(f(X)).");
-    assert_prolog_failure!(&mut wam, "?- rational(\"sdfsa\").");
-    assert_prolog_failure!(&mut wam, "?- rational(atom).");
-    assert_prolog_failure!(&mut wam, "?- rational(structure(functor)).");
-    assert_prolog_failure!(&mut wam, "?- rational([1,2,3]).");
-    assert_prolog_failure!(&mut wam, "?- rational([1,2,X]).");
-
-    assert_prolog_success!(&mut wam, "?- compound(functor(compound)).");
-    assert_prolog_success!(&mut wam, "?- compound(f(X)).");
-    assert_prolog_success!(&mut wam, "?- compound([1,2,3]).");
-    assert_prolog_failure!(&mut wam, "?- compound([]).");
-    assert_prolog_failure!(&mut wam, "?- compound(3.14159269).");
-    assert_prolog_failure!(&mut wam, "?- compound(3).");
-    assert_prolog_failure!(&mut wam, "?- compound(\"sdfsa\").");
-    assert_prolog_failure!(&mut wam, "?- compound(atom).");
-
-    assert_prolog_failure!(&mut wam, "?- string(functor(string)).");
-    assert_prolog_failure!(&mut wam, "?- string(3.14159269).");
-    assert_prolog_failure!(&mut wam, "?- string(3).");
-    assert_prolog_failure!(&mut wam, "?- string(f(X)).");
-    assert_prolog_success!(&mut wam, "?- string(\"sdfsa\").");
-    assert_prolog_failure!(&mut wam, "?- string(atom).");
-    assert_prolog_failure!(&mut wam, "?- string([1,2,3]).");
-    assert_prolog_failure!(&mut wam, "?- string([1,2,X]).");
-
-    assert_prolog_success!(&mut wam, "?- X = nonvar, nonvar(X).");
-    assert_prolog_failure!(&mut wam, "?- nonvar(X).");
-    assert_prolog_success!(&mut wam, "?- nonvar(f(X)).");
-    assert_prolog_success!(&mut wam, "?- nonvar(functor(nonvar)).");
-    assert_prolog_success!(&mut wam, "?- nonvar(3.14159269).");
-    assert_prolog_success!(&mut wam, "?- nonvar(3).");
-    assert_prolog_success!(&mut wam, "?- nonvar(\"sdfsa\").");
-    assert_prolog_success!(&mut wam, "?- nonvar(atom).");
-    assert_prolog_success!(&mut wam, "?- nonvar([1,2,3]).");
-    assert_prolog_success!(&mut wam, "?- nonvar([1,2,X]).");
-
-    assert_prolog_success!(&mut wam, "?- A = f(A), ground(f(f(A))), ground(f(A)), ground(A).");
-    assert_prolog_failure!(&mut wam, "?- B = f(A), ground(B).");
-    assert_prolog_failure!(&mut wam, "?- B = f(A), ground(A).");
-
-    assert_prolog_success!(&mut wam, "?- ground(x), ground(f(x)), X = f(x), ground(g(f(X), [a,b])).");
-
-    assert_prolog_success!(&mut wam, "?- A = f(A), g(A, B) == g(f(A), B).");
-    assert_prolog_failure!(&mut wam, "?- A = f(A), g(A, B) == g(f(A), b).");
-    assert_prolog_failure!(&mut wam, "?- A == B.");
-    assert_prolog_failure!(&mut wam, "?- A == 12.1.");
-    assert_prolog_success!(&mut wam, "?- X = x, f(X, x) == f(x, X).");
-
-    assert_prolog_failure!(&mut wam, "?- A = f(A), g(A, B) \\== g(f(A), B).");
-    assert_prolog_success!(&mut wam, "?- A = f(A), g(A, B) \\== g(f(A), b).");
-    assert_prolog_success!(&mut wam, "?- A \\== B.");
-    assert_prolog_success!(&mut wam, "?- A \\== 12.1.");
-    assert_prolog_failure!(&mut wam, "?- X = x, f(X, x) \\== f(x, X).");
-
-    assert_prolog_success!(&mut wam, "?- X @=< Y.");
-    assert_prolog_failure!(&mut wam, "?- X @>= Y.");
-    assert_prolog_failure!(&mut wam, "?- X @> Y.");
-    assert_prolog_success!(&mut wam, "?- X @>= X.");
-    assert_prolog_failure!(&mut wam, "?- atom @=< \"string\".");
-    assert_prolog_success!(&mut wam, "?- atom @=< atom.");
-    assert_prolog_failure!(&mut wam, "?- atom @=< aaa.");
-    assert_prolog_success!(&mut wam, "?- atom @>= \"string\".");
-    assert_prolog_success!(&mut wam, "?- X is 3 + 3, X @>= Y.");
-    assert_prolog_success!(&mut wam, "?- f(X) @>= f(X).");
-    assert_prolog_success!(&mut wam, "?- f(X) @>= a.");
-    assert_prolog_failure!(&mut wam, "?- f(X) @=< a.");
-    assert_prolog_success!(&mut wam, "?- [1,2] @=< [1,2].");
-    assert_prolog_failure!(&mut wam, "?- [1,2,3] @=< [1,2].");
-    assert_prolog_success!(&mut wam, "?- [] @=< [1,2].");
-    assert_prolog_failure!(&mut wam, "?- [] @< 1.");
-    assert_prolog_failure!(&mut wam, "?- [] @< \"string\".");
-    assert_prolog_failure!(&mut wam, "?- [] @< atom.");
-    assert_prolog_success!(&mut wam, "?- atom @< [].");
-    assert_prolog_failure!(&mut wam, "?- 1.1 @< 1.");
-    assert_prolog_success!(&mut wam, "?- 1.0 @=< 1.");
-    assert_prolog_success!(&mut wam, "?- 1 @=< 1.0."); //TODO: currently this succeeds. make it fail.
-
-    assert_prolog_success!(&mut wam, "?- X =@= Y.");
-    assert_prolog_failure!(&mut wam, "?- f(X) =@= f(x).");
-    assert_prolog_failure!(&mut wam, "?- X \\=@= X.");
-    assert_prolog_success!(&mut wam, "?- f(x) =@= f(x).");
-    assert_prolog_failure!(&mut wam, "?- [X,Y,Z] =@= [V,W,V].");
-    assert_prolog_success!(&mut wam, "?- [X,Y,Z] =@= [V,W,Z].");
-    assert_prolog_success!(&mut wam, "?- [X,Y,X] =@= [V,W,V].");
-    assert_prolog_success!(&mut wam, "?- g(B) = B, g(A) = A, A =@= B.");
-
-    assert_prolog_success!(&mut wam, "?- keysort([1-1, 1-1], Sorted).",
+    assert_prolog_success!(&mut wam, "float(3.14159269).");
+    assert_prolog_failure!(&mut wam, "float(3).");
+    assert_prolog_failure!(&mut wam, "float(\"sdfsa\").");
+    assert_prolog_failure!(&mut wam, "float(atom).");
+    assert_prolog_failure!(&mut wam, "float(structure(functor)).");
+    assert_prolog_failure!(&mut wam, "float([1,2,3]).");
+    assert_prolog_failure!(&mut wam, "float([1,2,X]).");
+    assert_prolog_failure!(&mut wam, "X is 3 rdiv 4, float(X).");
+
+    assert_prolog_success!(&mut wam, "X is 3 rdiv 4, rational(X).");
+    assert_prolog_failure!(&mut wam, "rational(3).");
+    assert_prolog_failure!(&mut wam, "rational(f(X)).");
+    assert_prolog_failure!(&mut wam, "rational(\"sdfsa\").");
+    assert_prolog_failure!(&mut wam, "rational(atom).");
+    assert_prolog_failure!(&mut wam, "rational(structure(functor)).");
+    assert_prolog_failure!(&mut wam, "rational([1,2,3]).");
+    assert_prolog_failure!(&mut wam, "rational([1,2,X]).");
+
+    assert_prolog_success!(&mut wam, "compound(functor(compound)).");
+    assert_prolog_success!(&mut wam, "compound(f(X)).");
+    assert_prolog_success!(&mut wam, "compound([1,2,3]).");
+    assert_prolog_failure!(&mut wam, "compound([]).");
+    assert_prolog_failure!(&mut wam, "compound(3.14159269).");
+    assert_prolog_failure!(&mut wam, "compound(3).");
+    assert_prolog_failure!(&mut wam, "compound(\"sdfsa\").");
+    assert_prolog_failure!(&mut wam, "compound(atom).");
+
+    assert_prolog_failure!(&mut wam, "string(functor(string)).");
+    assert_prolog_failure!(&mut wam, "string(3.14159269).");
+    assert_prolog_failure!(&mut wam, "string(3).");
+    assert_prolog_failure!(&mut wam, "string(f(X)).");
+    assert_prolog_success!(&mut wam, "string(\"sdfsa\").");
+    assert_prolog_failure!(&mut wam, "string(atom).");
+    assert_prolog_failure!(&mut wam, "string([1,2,3]).");
+    assert_prolog_failure!(&mut wam, "string([1,2,X]).");
+
+    assert_prolog_success!(&mut wam, "X = nonvar, nonvar(X).");
+    assert_prolog_failure!(&mut wam, "nonvar(X).");
+    assert_prolog_success!(&mut wam, "nonvar(f(X)).");
+    assert_prolog_success!(&mut wam, "nonvar(functor(nonvar)).");
+    assert_prolog_success!(&mut wam, "nonvar(3.14159269).");
+    assert_prolog_success!(&mut wam, "nonvar(3).");
+    assert_prolog_success!(&mut wam, "nonvar(\"sdfsa\").");
+    assert_prolog_success!(&mut wam, "nonvar(atom).");
+    assert_prolog_success!(&mut wam, "nonvar([1,2,3]).");
+    assert_prolog_success!(&mut wam, "nonvar([1,2,X]).");
+
+    assert_prolog_success!(&mut wam, "A = f(A), ground(f(f(A))), ground(f(A)), ground(A).");
+    assert_prolog_failure!(&mut wam, "B = f(A), ground(B).");
+    assert_prolog_failure!(&mut wam, "B = f(A), ground(A).");
+
+    assert_prolog_success!(&mut wam, "ground(x), ground(f(x)), X = f(x), ground(g(f(X), [a,b])).");
+
+    assert_prolog_success!(&mut wam, "A = f(A), g(A, B) == g(f(A), B).");
+    assert_prolog_failure!(&mut wam, "A = f(A), g(A, B) == g(f(A), b).");
+    assert_prolog_failure!(&mut wam, "A == B.");
+    assert_prolog_failure!(&mut wam, "A == 12.1.");
+    assert_prolog_success!(&mut wam, "X = x, f(X, x) == f(x, X).");
+
+    assert_prolog_failure!(&mut wam, "A = f(A), g(A, B) \\== g(f(A), B).");
+    assert_prolog_success!(&mut wam, "A = f(A), g(A, B) \\== g(f(A), b).");
+    assert_prolog_success!(&mut wam, "A \\== B.");
+    assert_prolog_success!(&mut wam, "A \\== 12.1.");
+    assert_prolog_failure!(&mut wam, "X = x, f(X, x) \\== f(x, X).");
+
+    assert_prolog_success!(&mut wam, "X @=< Y.");
+    assert_prolog_failure!(&mut wam, "X @>= Y.");
+    assert_prolog_failure!(&mut wam, "X @> Y.");
+    assert_prolog_success!(&mut wam, "X @>= X.");
+    assert_prolog_failure!(&mut wam, "atom @=< \"string\".");
+    assert_prolog_success!(&mut wam, "atom @=< atom.");
+    assert_prolog_failure!(&mut wam, "atom @=< aaa.");
+    assert_prolog_success!(&mut wam, "atom @>= \"string\".");
+    assert_prolog_success!(&mut wam, "X is 3 + 3, X @>= Y.");
+    assert_prolog_success!(&mut wam, "f(X) @>= f(X).");
+    assert_prolog_success!(&mut wam, "f(X) @>= a.");
+    assert_prolog_failure!(&mut wam, "f(X) @=< a.");
+    assert_prolog_success!(&mut wam, "[1,2] @=< [1,2].");
+    assert_prolog_failure!(&mut wam, "[1,2,3] @=< [1,2].");
+    assert_prolog_success!(&mut wam, "[] @=< [1,2].");
+    assert_prolog_failure!(&mut wam, "[] @< 1.");
+    assert_prolog_failure!(&mut wam, "[] @< \"string\".");
+    assert_prolog_failure!(&mut wam, "[] @< atom.");
+    assert_prolog_success!(&mut wam, "atom @< [].");
+    assert_prolog_failure!(&mut wam, "1.1 @< 1.");
+    assert_prolog_success!(&mut wam, "1.0 @=< 1.");
+    assert_prolog_success!(&mut wam, "1 @=< 1.0."); //TODO: currently this succeeds. make it fail.
+
+    assert_prolog_success!(&mut wam, "X =@= Y.");
+    assert_prolog_failure!(&mut wam, "f(X) =@= f(x).");
+    assert_prolog_failure!(&mut wam, "X \\=@= X.");
+    assert_prolog_success!(&mut wam, "f(x) =@= f(x).");
+    assert_prolog_failure!(&mut wam, "[X,Y,Z] =@= [V,W,V].");
+    assert_prolog_success!(&mut wam, "[X,Y,Z] =@= [V,W,Z].");
+    assert_prolog_success!(&mut wam, "[X,Y,X] =@= [V,W,V].");
+    assert_prolog_success!(&mut wam, "g(B) = B, g(A) = A, A =@= B.");
+
+    assert_prolog_success!(&mut wam, "keysort([1-1, 1-1], Sorted).",
                            [["Sorted = [1-1, 1-1]"]]);
-    assert_prolog_success!(&mut wam, "?- keysort([2-99, 1-a, 3-f(_), 1-z, 1-a, 2-44], Sorted).",
+    assert_prolog_success!(&mut wam, "keysort([2-99, 1-a, 3-f(_), 1-z, 1-a, 2-44], Sorted).",
                            [["Sorted = [1-a, 1-z, 1-a, 2-99, 2-44, 3-f(_7)]"]]);
-    assert_prolog_success!(&mut wam, "?- keysort([X-1,1-1],[2-1,1-1]).",
+    assert_prolog_success!(&mut wam, "keysort([X-1,1-1],[2-1,1-1]).",
                            [["X = 2"]]);
 
-    assert_prolog_failure!(&mut wam, "?- Pairs = [a-a|Pairs], keysort(Pairs, _).");
-    assert_prolog_success!(&mut wam, "?- Pairs = [a-a|Pairs], catch(keysort(Pairs, _), error(E, _), true).",
+    assert_prolog_failure!(&mut wam, "Pairs = [a-a|Pairs], keysort(Pairs, _).");
+    assert_prolog_success!(&mut wam, "Pairs = [a-a|Pairs], catch(keysort(Pairs, _), error(E, _), true).",
                            [["E = type_error(list, [a-a | _25])", "Pairs = [a-a | Pairs]"]]);
 
-    assert_prolog_success!(&mut wam, "?- keysort([], L).",
+    assert_prolog_success!(&mut wam, "keysort([], L).",
                            [["L = []"]]);
-    assert_prolog_success!(&mut wam, "?- catch(keysort([a|_], _), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(keysort([a|_], _), error(E, _), true).",
                            [["E = instantiation_error"]]);
-    assert_prolog_success!(&mut wam, "?- catch(keysort([],[a|a]),error(Pat, _),true).",
+    assert_prolog_success!(&mut wam, "catch(keysort([],[a|a]),error(Pat, _),true).",
                            [["Pat = type_error(list, [a | a])"]]);
-    assert_prolog_success!(&mut wam, "?- catch(keysort(_, _), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(keysort(_, _), error(E, _), true).",
                            [["E = type_error(list, _16)"]]);
-    assert_prolog_success!(&mut wam, "?- catch(keysort([a-1], [_|b]), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(keysort([a-1], [_|b]), error(E, _), true).",
                            [["E = type_error(list, [_27 | b])"]]);
-    assert_prolog_success!(&mut wam, "?- catch(keysort([a-1], [a-b,c-d,a]), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(keysort([a-1], [a-b,c-d,a]), error(E, _), true).",
                            [["E = type_error(pair, a)"]]);
-    assert_prolog_success!(&mut wam, "?- catch(keysort([a], [a-b]), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(keysort([a], [a-b]), error(E, _), true).",
                            [["E = type_error(pair, a)"]]);
 
-    assert_prolog_success!(&mut wam, "?- catch(sort([a|_], _), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(sort([a|_], _), error(E, _), true).",
                            [["E = instantiation_error"]]);
-    assert_prolog_success!(&mut wam, "?- catch(sort([],[a|a]),error(Pat, _),true).",
+    assert_prolog_success!(&mut wam, "catch(sort([],[a|a]),error(Pat, _),true).",
                            [["Pat = type_error(list, [a | a])"]]);
-    assert_prolog_success!(&mut wam, "?- sort([], L).",
+    assert_prolog_success!(&mut wam, "sort([], L).",
                            [["L = []"]]);
-    assert_prolog_success!(&mut wam, "?- catch(sort(_, []), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(sort(_, []), error(E, _), true).",
                            [["E = type_error(list, _16)"]]);
-    assert_prolog_success!(&mut wam, "?- catch(sort([a,b,c], not_a_list), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(sort([a,b,c], not_a_list), error(E, _), true).",
                            [["E = type_error(list, not_a_list)"]]);
 
-    assert_prolog_success!(&mut wam, "?- call(((G = 2 ; fail), B=3, !)).",
+    assert_prolog_success!(&mut wam, "call(((G = 2 ; fail), B=3, !)).",
                            [["G = 2", "B = 3"]]);
 
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)), B=3, !), 100, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)), B=3, !), 100, R).",
                            [["G = 2", "B = 3", "R = !", "S = 1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)), B=3, !), 10, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)), B=3, !), 10, R).",
                            [["S = _1", "G = _4", "B = _14", "R = inference_limit_exceeded"]]);
 
-    assert_prolog_success!(&mut wam, "?- X = '\\033\\'.",
+    assert_prolog_success!(&mut wam, "X = '\\033\\'.",
                            [["X = '\\x1b\\'"]]);
-    
-    assert_prolog_success!(&mut wam, "?- X = '\\n'.",
+
+    assert_prolog_success!(&mut wam, "X = '\\n'.",
                            [["X = '\\n'"]]);
-    assert_prolog_success!(&mut wam, "?- X = '\\b'.",
+    assert_prolog_success!(&mut wam, "X = '\\b'.",
                            [["X = '\\b'"]]);
-    assert_prolog_success!(&mut wam, "?- X = '\\v'.",
+    assert_prolog_success!(&mut wam, "X = '\\v'.",
                            [["X = '\\v'"]]);
-    assert_prolog_success!(&mut wam, "?- X = '\\a'.",
+    assert_prolog_success!(&mut wam, "X = '\\a'.",
                            [["X = '\\a'"]]);
-    assert_prolog_success!(&mut wam, "?- X = '\\f'.",
+    assert_prolog_success!(&mut wam, "X = '\\f'.",
                            [["X = '\\f'"]]);
-    assert_prolog_success!(&mut wam, "?- X = '\\b\\r\\f\\t\\n'.",
+    assert_prolog_success!(&mut wam, "X = '\\b\\r\\f\\t\\n'.",
                            [["X = '\\b\\r\\f\\t\\n'"]]);
 
-    assert_prolog_success!(&mut wam, "?- (- (1)) = -(1).");
-    assert_prolog_success!(&mut wam, "?- (- -1) = -(-1).");
-    
-    assert_prolog_success!(&mut wam, "?- X = ((*)=(*)).",
+    assert_prolog_success!(&mut wam, "(- (1)) = -(1).");
+    assert_prolog_success!(&mut wam, "(- -1) = -(-1).");
+
+    assert_prolog_success!(&mut wam, "X = ((*)=(*)).",
                            [["X = ((*)=(*))"]]);
-    assert_prolog_success!(&mut wam, "?- X = [.,.(.,.,.)].",
+    assert_prolog_success!(&mut wam, "X = [.,.(.,.,.)].",
                            [["X = ['.', '.'('.', '.', '.')]"]]);
-    assert_prolog_success!(&mut wam, "?- X = a+(b*c).",
+    assert_prolog_success!(&mut wam, "X = a+(b*c).",
                            [["X = a+b*c"]]);
-    assert_prolog_success!(&mut wam, "?- X = a*(b+c).",
+    assert_prolog_success!(&mut wam, "X = a*(b+c).",
                            [["X = a*(b+c)"]]);
-    assert_prolog_success!(&mut wam, "?- X = [:-,-].",
+    assert_prolog_success!(&mut wam, "X = [:-,-].",
                            [["X = [:-, -]"]]);
-    assert_prolog_success!(&mut wam, "?- X = a*(b+c).",
+    assert_prolog_success!(&mut wam, "X = a*(b+c).",
                            [["X = a*(b+c)"]]);
-    assert_prolog_success!(&mut wam, "?- X = (-)-(-).",
+    assert_prolog_success!(&mut wam, "X = (-)-(-).",
                            [["X = (-)-(-)"]]);
-    assert_prolog_success!(&mut wam, "?- X = ((:-):-(:-)).",
+    assert_prolog_success!(&mut wam, "X = ((:-):-(:-)).",
                            [["X = ((:-):-(:-))"]]);
-    assert_prolog_success!(&mut wam, "?- X = (a:-b,c).",
+    assert_prolog_success!(&mut wam, "X = (a:-b,c).",
                            [["X = (a:-b,c)"]]);
-    assert_prolog_success!(&mut wam, "?- X = f((f:-a,b,c)).",
+    assert_prolog_success!(&mut wam, "X = f((f:-a,b,c)).",
                            [["X = f((f:-a,b,c))"]]);
-    assert_prolog_success!(&mut wam, "?- X = f((f:-a,(b,c))).",
+    assert_prolog_success!(&mut wam, "X = f((f:-a,(b,c))).",
                            [["X = f((f:-a,b,c))"]]);
-    assert_prolog_success!(&mut wam, "?- X = f((a,b,c)).",
+    assert_prolog_success!(&mut wam, "X = f((a,b,c)).",
                            [["X = f((a,b,c))"]]);
-    assert_prolog_success!(&mut wam, "?- X = f((a,(b,c))).",
+    assert_prolog_success!(&mut wam, "X = f((a,(b,c))).",
                            [["X = f((a,b,c))"]]);
-    assert_prolog_success!(&mut wam, "?- X = f(((a,b),c)).",
+    assert_prolog_success!(&mut wam, "X = f(((a,b),c)).",
                            [["X = f(((a,b),c))"]]);
-    assert_prolog_success!(&mut wam, "?- X = f(((a,b),(c, d))).",
+    assert_prolog_success!(&mut wam, "X = f(((a,b),(c, d))).",
                            [["X = f(((a,b),c,d))"]]);
 
-    assert_prolog_success!(&mut wam, "?- findall(X, (X = 1 ; X = 2), S).",
+    assert_prolog_success!(&mut wam, "findall(X, (X = 1 ; X = 2), S).",
                            [["S = [1, 2]", "X = _0"]]);
-    assert_prolog_success!(&mut wam, "?- findall(X+Y, (X = 1), S).",
+    assert_prolog_success!(&mut wam, "findall(X+Y, (X = 1), S).",
                            [["S = [1+_36]", "X = _1", "Y = _2"]]);
-    assert_prolog_success!(&mut wam, "?- findall(X, false, S).",
+    assert_prolog_success!(&mut wam, "findall(X, false, S).",
                            [["S = []", "X = _0"]]);
-    assert_prolog_success!(&mut wam, "?- findall(X, (X = 1 ; X = 1), S).",
+    assert_prolog_success!(&mut wam, "findall(X, (X = 1 ; X = 1), S).",
                            [["S = [1, 1]", "X = _0"]]);
-    assert_prolog_failure!(&mut wam, "?- findall(X, (X = 2 ; X = 1), [1, 2]).");
-    assert_prolog_success!(&mut wam, "?- findall(X, (X = 1 ; X = 2), [X, Y]).",
+    assert_prolog_failure!(&mut wam, "findall(X, (X = 2 ; X = 1), [1, 2]).");
+    assert_prolog_success!(&mut wam, "findall(X, (X = 1 ; X = 2), [X, Y]).",
                            [["X = 1", "Y = 2"]]);
-    assert_prolog_success!(&mut wam, "?- catch(findall(X, 4, S), error(type_error(callable, 4), _), true).",
+    assert_prolog_success!(&mut wam, "catch(findall(X, 4, S), error(type_error(callable, 4), _), true).",
                            [["S = _3", "X = _1"]]);
 
-    assert_prolog_success!(&mut wam, "?- bagof(X, (X=Y; X=Z), S).",
+    assert_prolog_success!(&mut wam, "bagof(X, (X=Y; X=Z), S).",
                            [["S = [_3, _6]", "X = _0", "Y = _3", "Z = _6"]]);
-    assert_prolog_success!(&mut wam, "?- bagof(X, (X=1 ; X = 2), X).",
+    assert_prolog_success!(&mut wam, "bagof(X, (X=1 ; X = 2), X).",
                            [["X = [1, 2]"]]);
-    assert_prolog_success!(&mut wam, "?- bagof(X, (X=1 ; X = 2), S).",
+    assert_prolog_success!(&mut wam, "bagof(X, (X=1 ; X = 2), S).",
                            [["S = [1, 2]", "X = _0"]]);
-    assert_prolog_success!(&mut wam, "?- bagof(1, (Y=1 ; Y=2), L).",
+    assert_prolog_success!(&mut wam, "bagof(1, (Y=1 ; Y=2), L).",
                            [["L = [1]", "Y = 1"],
                             ["L = [1]", "Y = 2"]]);
 
     submit(&mut wam, "b(1, 1). b(1, 1). b(1, 2). b(2, 1). b(2, 2). b(2, 2).");
 
-    assert_prolog_success!(&mut wam, "?- bagof(X, b(X, Y), L).",
+    assert_prolog_success!(&mut wam, "bagof(X, b(X, Y), L).",
                            [["L = [1, Y, 2]", "X = _0", "Y = 1"],
                             ["L = [1, 2, Y]", "X = _0", "Y = 2"]]);
 
-    assert_prolog_success!(&mut wam, "?- bagof(X, (X=Y; X=Z; Y=1), L).",
+    assert_prolog_success!(&mut wam, "bagof(X, (X=Y; X=Z; Y=1), L).",
                            [["L = [_3, _6]", "X = _0", "Y = _3", "Z = _6"],
                             ["L = [_112]", "X = _0", "Y = 1", "Z = _6"]]);
 
     submit(&mut wam, "a(1, f(_)). a(2, f(_)).");
 
-    assert_prolog_success!(&mut wam, "?- bagof(X, a(X, Y), L).",
+    assert_prolog_success!(&mut wam, "bagof(X, a(X, Y), L).",
                            [["L = [1, 2]", "X = _0", "Y = f(_78)"]]);
 
-    assert_prolog_success!(&mut wam, "?- setof(X, (X = 1 ; X = 2), S).",
+    assert_prolog_success!(&mut wam, "setof(X, (X = 1 ; X = 2), S).",
                            [["S = [1, 2]", "X = _0"]]);
-    assert_prolog_success!(&mut wam, "?- setof(X, (X=Y ; X=Z), S).",
+    assert_prolog_success!(&mut wam, "setof(X, (X=Y ; X=Z), S).",
                            [["S = [_3, _6]", "X = _0", "Y = _3", "Z = _6"]]);
-    assert_prolog_failure!(&mut wam, "?- setof(X, false, S).");
-    assert_prolog_success!(&mut wam, "?- setof(1, (Y=1 ; Y=2), L).",
+    assert_prolog_failure!(&mut wam, "setof(X, false, S).");
+    assert_prolog_success!(&mut wam, "setof(1, (Y=1 ; Y=2), L).",
                            [["L = [1]", "Y = 1"],
                             ["L = [1]", "Y = 2"]]);
-    assert_prolog_success!(&mut wam, "?- setof(X, (X=Y; X=Z; Y=1), L).",
+    assert_prolog_success!(&mut wam, "setof(X, (X=Y; X=Z; Y=1), L).",
                            [["L = [_3, _6]", "X = _0", "Y = _3", "Z = _6"],
                             ["L = [_112]", "Y = 1", "X = _0", "Y = 1", "Z = _6"]]);
-    assert_prolog_failure!(&mut wam, "?- setof(X, member(X, [f(U,b),f(V,c)]), [f(a,c),f(a,b)]).");
-    assert_prolog_success!(&mut wam, "?- setof(X, member(X, [f(U,b),f(V,c)]), [f(a,b),f(a,c)]).",
+    assert_prolog_failure!(&mut wam, "setof(X, member(X, [f(U,b),f(V,c)]), [f(a,c),f(a,b)]).");
+    assert_prolog_success!(&mut wam, "setof(X, member(X, [f(U,b),f(V,c)]), [f(a,b),f(a,c)]).",
                            [["U = a", "V = a", "X = _0"]]);
-    assert_prolog_success!(&mut wam, "?- setof(X, member(X, [V,U,f(U),f(V)]), L).",
+    assert_prolog_success!(&mut wam, "setof(X, member(X, [V,U,f(U),f(V)]), L).",
                            [["L = [_2, _4, f(U), f(V)]", "U = _2", "V = _4", "X = _0"]]);
-    assert_prolog_success!(&mut wam, "?- setof(X, member(X, [V,U,f(U),f(V)]), [a,b,f(a),f(b)]).",
+    assert_prolog_success!(&mut wam, "setof(X, member(X, [V,U,f(U),f(V)]), [a,b,f(a),f(b)]).",
                            [["U = a", "V = b", "X = _0"]]);
 
-    assert_prolog_success!(&mut wam, "?- findall(X, (X = 1 ; X = 2), S0, S1).",
+    assert_prolog_success!(&mut wam, "findall(X, (X = 1 ; X = 2), S0, S1).",
                            [["S0 = [1, 2 | _11]", "S1 = _11", "X = _0"]]);
-    assert_prolog_success!(&mut wam, "?- findall(X+Y, (X = 1), S0, S1).",
+    assert_prolog_success!(&mut wam, "findall(X+Y, (X = 1), S0, S1).",
                            [["S0 = [1+_44 | _7]", "S1 = _7", "X = _1", "Y = _2"]]);
-    assert_prolog_success!(&mut wam, "?- findall(X, false, S, _).",
+    assert_prolog_success!(&mut wam, "findall(X, false, S, _).",
                            [["S = []", "X = _0"]]);
-    assert_prolog_success!(&mut wam, "?- findall(X, (X = 1 ; X = 1), S0, S1).",
+    assert_prolog_success!(&mut wam, "findall(X, (X = 1 ; X = 1), S0, S1).",
                            [["S0 = [1, 1 | _11]", "S1 = _11", "X = _0"]]);
-    assert_prolog_failure!(&mut wam, "?- findall(X, (X = 2 ; X = 1), [1, 2 | S], S).");
-    assert_prolog_success!(&mut wam, "?- findall(X, (X = 1 ; X = 2), [X, Y | S], S).",
+    assert_prolog_failure!(&mut wam, "findall(X, (X = 2 ; X = 1), [1, 2 | S], S).");
+    assert_prolog_success!(&mut wam, "findall(X, (X = 1 ; X = 2), [X, Y | S], S).",
                            [["S = _11", "X = 1", "Y = 2"]]);
-    assert_prolog_success!(&mut wam, "?- catch(findall(X, 4, S0, S1), error(type_error(callable, 4), _), true).",
+    assert_prolog_success!(&mut wam, "catch(findall(X, 4, S0, S1), error(type_error(callable, 4), _), true).",
                            [["S0 = _3", "S1 = _4", "X = _1"]]);
 
     // bagof & setof with existential variables.
-    assert_prolog_success!(&mut wam, "?- bagof(X, Y^((X = 1, Y = 1; (X = 2, Y = 2))), S).",
+    assert_prolog_success!(&mut wam, "bagof(X, Y^((X = 1, Y = 1; (X = 2, Y = 2))), S).",
                            [["S = [1, 2]", "X = _0", "Y = _5"]]);
-    assert_prolog_success!(&mut wam, "?- bagof(X, Y^((X = 1 ; Y = 1) ; (X = 2, Y = 2)), S).",
+    assert_prolog_success!(&mut wam, "bagof(X, Y^((X = 1 ; Y = 1) ; (X = 2, Y = 2)), S).",
                            [["S = [1, _126, 2]", "X = _0", "Y = _5"]]);
 
-    assert_prolog_success!(&mut wam, "?- setof(X, Y^((X = 1, Y = 1; (X = 2, Y = 2))), S).",
+    assert_prolog_success!(&mut wam, "setof(X, Y^((X = 1, Y = 1; (X = 2, Y = 2))), S).",
                            [["S = [1, 2]", "X = _0", "Y = _5"]]);
-    assert_prolog_success!(&mut wam, "?- setof(X, Y^((X = 1 ; Y = 1) ; (X = 2, Y = 2)), S).",
+    assert_prolog_success!(&mut wam, "setof(X, Y^((X = 1 ; Y = 1) ; (X = 2, Y = 2)), S).",
                            [["S = [_126, 1, 2]", "X = _0", "Y = _5"]]);
-    assert_prolog_success!(&mut wam, "?- setof(X, (exists(U,V) ^ member(X, [V,U,f(U),f(V)])), [a,b,f(b),f(a)]).");
 
     submit(&mut wam, ":- use_module(library(non_iso)).");
-    
-    assert_prolog_failure!(&mut wam, "?- forall(true, false).");
-    assert_prolog_success!(&mut wam, "?- forall(false, true).");
-    assert_prolog_success!(&mut wam, "?- catch(forall(_, true), error(instantiation_error, _), true).");
-    assert_prolog_success!(&mut wam, "?- catch(forall(true, _), error(instantiation_error, _), true).");
-    assert_prolog_success!(&mut wam, "?- catch(forall(1, true), error(type_error(callable, 1), _), true).");
-    assert_prolog_success!(&mut wam, "?- catch(forall(true, 1), error(type_error(callable, 1), _), true).");
+
+    assert_prolog_failure!(&mut wam, "forall(true, false).");
+    assert_prolog_success!(&mut wam, "forall(false, true).");
+    assert_prolog_success!(&mut wam, "catch(forall(_, true), error(instantiation_error, _), true).");
+    assert_prolog_success!(&mut wam, "catch(forall(true, _), error(instantiation_error, _), true).");
+    assert_prolog_success!(&mut wam, "catch(forall(1, true), error(type_error(callable, 1), _), true).");
+    assert_prolog_success!(&mut wam, "catch(forall(true, 1), error(type_error(callable, 1), _), true).");
 
     submit(&mut wam, "
 :- dynamic(cat/0).
@@ -1828,32 +1833,32 @@ legs(A, 7) :- A, call(A).
 insect(ant).
 insect(bee).");
 
-    assert_prolog_success!(&mut wam, "?- clause(cat, true).");
-    assert_prolog_success!(&mut wam, "?- clause(dog, true).");
-    assert_prolog_success!(&mut wam, "?- clause(legs(I, 6), Body).",
+    assert_prolog_success!(&mut wam, "clause(cat, true).");
+    assert_prolog_success!(&mut wam, "clause(dog, true).");
+    assert_prolog_success!(&mut wam, "clause(legs(I, 6), Body).",
                            [["I = _1", "Body = insect(_1)"]]);
-    assert_prolog_success!(&mut wam, "?- clause(legs(C, 7), Body).",
+    assert_prolog_success!(&mut wam, "clause(legs(C, 7), Body).",
                            [["C = _1", "Body = ','(_1, call(C))"]]);
-    assert_prolog_success!(&mut wam, "?- clause(insect(I), T).",
+    assert_prolog_success!(&mut wam, "clause(insect(I), T).",
                            [["I = ant", "T = true"],
                             ["I = bee", "T = true"]]);
-    assert_prolog_failure!(&mut wam, "?- clause(x, Body).");
-    assert_prolog_success!(&mut wam, "?- catch(clause(_, _), error(instantiation_error, _), true).");
-    assert_prolog_success!(&mut wam, "?- catch(clause(4, _), error(type_error(callable, 4), _), true).");
-    assert_prolog_success!(&mut wam, "?- catch(clause(elk(N), _), error(permission_error(access, private_procedure, elk/1), _), true).");
-    assert_prolog_success!(&mut wam, "?- catch(clause(atom(N), _), error(permission_error(access, private_procedure, atom/1), _), true).");
-
-    assert_prolog_success!(&mut wam, "?- asserta(legs(octopus, 8)).");
-    assert_prolog_success!(&mut wam, "?- asserta( (legs(A, 4) :- animal(A)) ).");
-    assert_prolog_success!(&mut wam, "?- asserta( (foo(X) :- X, call(X)) ).");
-    assert_prolog_success!(&mut wam, "?- catch(asserta(_), error(instantiation_error, _), true).");
-    assert_prolog_failure!(&mut wam, "?- asserta(_).");
-    assert_prolog_success!(&mut wam, "?- catch(asserta(4), error(type_error(callable, 4), _), true).");
-    assert_prolog_failure!(&mut wam, "?- asserta(4).");
-    assert_prolog_success!(&mut wam, "?- catch(asserta( (foo :- 4) ), error(type_error(callable, 4), _), true).");
-    assert_prolog_failure!(&mut wam, "?- asserta( (foo :- 4) ).");
-    assert_prolog_success!(&mut wam, "?- catch(asserta( (atom(_) :- true) ), error(permission_error(modify, static_procedure, atom/1), _), true).");
-    assert_prolog_failure!(&mut wam, "?- asserta( (atom(_) :- true) ).");
+    assert_prolog_failure!(&mut wam, "clause(x, Body).");
+    assert_prolog_success!(&mut wam, "catch(clause(_, _), error(instantiation_error, _), true).");
+    assert_prolog_success!(&mut wam, "catch(clause(4, _), error(type_error(callable, 4), _), true).");
+    assert_prolog_success!(&mut wam, "catch(clause(elk(N), _), error(permission_error(access, private_procedure, elk/1), _), true).");
+    assert_prolog_success!(&mut wam, "catch(clause(atom(N), _), error(permission_error(access, private_procedure, atom/1), _), true).");
+
+    assert_prolog_success!(&mut wam, "asserta(legs(octopus, 8)).");
+    assert_prolog_success!(&mut wam, "asserta( (legs(A, 4) :- animal(A)) ).");
+    assert_prolog_success!(&mut wam, "asserta( (foo(X) :- X, call(X)) ).");
+    assert_prolog_success!(&mut wam, "catch(asserta(_), error(instantiation_error, _), true).");
+    assert_prolog_failure!(&mut wam, "asserta(_).");
+    assert_prolog_success!(&mut wam, "catch(asserta(4), error(type_error(callable, 4), _), true).");
+    assert_prolog_failure!(&mut wam, "asserta(4).");
+    assert_prolog_success!(&mut wam, "catch(asserta( (foo :- 4) ), error(type_error(callable, 4), _), true).");
+    assert_prolog_failure!(&mut wam, "asserta( (foo :- 4) ).");
+    assert_prolog_success!(&mut wam, "catch(asserta( (atom(_) :- true) ), error(permission_error(modify, static_procedure, atom/1), _), true).");
+    assert_prolog_failure!(&mut wam, "asserta( (atom(_) :- true) ).");
 
     submit(&mut wam, "
 :- dynamic(cat/0).
@@ -1872,17 +1877,17 @@ legs(A, 7) :- A, call(A).
 insect(ant).
 insect(bee).");
 
-    assert_prolog_success!(&mut wam, "?- assertz(legs(octopus, 8)).");
-    assert_prolog_success!(&mut wam, "?- assertz( (legs(A, 4) :- animal(A)) ).");
-    assert_prolog_success!(&mut wam, "?- assertz( (foo(X) :- X, call(X)) ).");
-    assert_prolog_success!(&mut wam, "?- catch(assertz(_), error(instantiation_error, _), true).");
-    assert_prolog_failure!(&mut wam, "?- assertz(_).");
-    assert_prolog_success!(&mut wam, "?- catch(assertz(4), error(type_error(callable, 4), _), true).");
-    assert_prolog_failure!(&mut wam, "?- assertz(4).");
-    assert_prolog_success!(&mut wam, "?- catch(assertz( (foo :- 4) ), error(type_error(callable, 4), _), true).");
-    assert_prolog_failure!(&mut wam, "?- assertz( (foo :- 4) ).");
-    assert_prolog_success!(&mut wam, "?- catch(assertz( (atom(_) :- true) ), error(permission_error(modify, static_procedure, atom/1), _), true).");
-    assert_prolog_failure!(&mut wam, "?- assertz( (atom(_) :- true) ).");
+    assert_prolog_success!(&mut wam, "assertz(legs(octopus, 8)).");
+    assert_prolog_success!(&mut wam, "assertz( (legs(A, 4) :- animal(A)) ).");
+    assert_prolog_success!(&mut wam, "assertz( (foo(X) :- X, call(X)) ).");
+    assert_prolog_success!(&mut wam, "catch(assertz(_), error(instantiation_error, _), true).");
+    assert_prolog_failure!(&mut wam, "assertz(_).");
+    assert_prolog_success!(&mut wam, "catch(assertz(4), error(type_error(callable, 4), _), true).");
+    assert_prolog_failure!(&mut wam, "assertz(4).");
+    assert_prolog_success!(&mut wam, "catch(assertz( (foo :- 4) ), error(type_error(callable, 4), _), true).");
+    assert_prolog_failure!(&mut wam, "assertz( (foo :- 4) ).");
+    assert_prolog_success!(&mut wam, "catch(assertz( (atom(_) :- true) ), error(permission_error(modify, static_procedure, atom/1), _), true).");
+    assert_prolog_failure!(&mut wam, "assertz( (atom(_) :- true) ).");
 
     submit(&mut wam, "
 :- dynamic(legs/2).
@@ -1900,29 +1905,29 @@ insect(bee).
 foo(X) :- call(X), call(X).
 foo(X) :- call(X) -> call(X).");
 
-    assert_prolog_success!(&mut wam, "?- retract(legs(octopus, 8)).");
-    assert_prolog_failure!(&mut wam, "?- retract(legs(spider, 6)).");
-    assert_prolog_success!(&mut wam, "?- retract( (legs(X, 2) :- T) ).",
+    assert_prolog_success!(&mut wam, "retract(legs(octopus, 8)).");
+    assert_prolog_failure!(&mut wam, "retract(legs(spider, 6)).");
+    assert_prolog_success!(&mut wam, "retract( (legs(X, 2) :- T) ).",
                            [["X = _1", "T = bird(_1)"]]);
-    assert_prolog_success!(&mut wam, "?- retract( (legs(X, Y) :- Z) ).",
+    assert_prolog_success!(&mut wam, "retract( (legs(X, Y) :- Z) ).",
                            [["X = _1", "Y = 4", "Z = animal(_1)"],
                             ["X = _1", "Y = 6", "Z = insect(_1)"],
                             ["X = spider", "Y = 8", "Z = true"]]);
-    assert_prolog_failure!(&mut wam, "?- retract( (legs(X, Y) :- Z) ).");
-    assert_prolog_success!(&mut wam, "?- retract(insect(I)).",
+    assert_prolog_failure!(&mut wam, "retract( (legs(X, Y) :- Z) ).");
+    assert_prolog_success!(&mut wam, "retract(insect(I)).",
                            [["I = ant"],
                             ["I = bee"]]);
-    assert_prolog_success!(&mut wam, "?- retract(( foo(A) :- A, call(A) )).",
+    assert_prolog_success!(&mut wam, "retract(( foo(A) :- A, call(A) )).",
                            [["A = call(A)"]]);
-    assert_prolog_success!(&mut wam, "?- foo(atom(atom)).");
-    assert_prolog_success!(&mut wam, "?- retract(( foo(C) :- A -> B )).",
+    assert_prolog_success!(&mut wam, "foo(atom(atom)).");
+    assert_prolog_success!(&mut wam, "retract(( foo(C) :- A -> B )).",
                            [["A = call(_1)", "B = call(_1)", "C = _1"]]);
-    assert_prolog_failure!(&mut wam, "?- retract( (X :- in_eec(Y)) ).");
-    assert_prolog_success!(&mut wam, "?- catch(retract( (X :- in_eec(Y)) ), error(instantiation_error, _), true).");
-    assert_prolog_failure!(&mut wam, "?- retract( (4 :- X) ).");
-    assert_prolog_success!(&mut wam, "?- catch(retract( (4 :- X) ), error(type_error(callable, 4), _), true).");
-    assert_prolog_failure!(&mut wam, "?- retract( (atom(X) :- X == '[]') ).");
-    assert_prolog_success!(&mut wam, "?- catch(retract( (atom(X) :- X == '[]') ), error(permission_error(modify, static_procedure, atom/1), _), true).");
+    assert_prolog_failure!(&mut wam, "retract( (X :- in_eec(Y)) ).");
+    assert_prolog_success!(&mut wam, "catch(retract( (X :- in_eec(Y)) ), error(instantiation_error, _), true).");
+    assert_prolog_failure!(&mut wam, "retract( (4 :- X) ).");
+    assert_prolog_success!(&mut wam, "catch(retract( (4 :- X) ), error(type_error(callable, 4), _), true).");
+    assert_prolog_failure!(&mut wam, "retract( (atom(X) :- X == '[]') ).");
+    assert_prolog_success!(&mut wam, "catch(retract( (atom(X) :- X == '[]') ), error(permission_error(modify, static_procedure, atom/1), _), true).");
 
     /* This example shows why machine::compile::localize_self_calls is necessary. */
 submit(&mut wam, "
@@ -1933,37 +1938,37 @@ p(b).
 p(c) :- p(d).
 p(d).");
 
-    assert_prolog_success!(&mut wam, "?- p(X), retract(p(_)).",
+    assert_prolog_success!(&mut wam, "p(X), retract(p(_)).",
                            [["X = a"],
                             ["X = a"],
                             ["X = a"]]);
-    
+
     submit(&mut wam, "
 :- dynamic(foo/1).
 foo(X) :- call(X), call(X).
 foo(X) :- call(X) -> call(X).");
 
-    assert_prolog_success!(&mut wam, "?- abolish(foo/2).");
-    assert_prolog_failure!(&mut wam, "?- abolish(foo/_).");
-    assert_prolog_success!(&mut wam, "?- catch(abolish(foo/_), error(instantiation_error, abolish/1), true).");
-    assert_prolog_failure!(&mut wam, "?- abolish(foo).");
-    assert_prolog_success!(&mut wam, "?- catch(abolish(foo), error(type_error(predicate_indicator, foo), abolish/1), true).");
-    assert_prolog_failure!(&mut wam, "?- abolish(foo(_)).");
-    assert_prolog_success!(&mut wam, "?- catch(abolish(foo(_)), error(type_error(predicate_indicator, foo(_)), abolish/1), true).");
-    assert_prolog_failure!(&mut wam, "?- abolish(abolish/1).");
-    assert_prolog_success!(&mut wam, "?- catch(abolish(abolish/1), error(permission_error(modify, static_procedure, abolish/1), abolish/1), true).");
-
-    assert_prolog_success!(&mut wam, "?- atom_length('enchanted evening', N).",
+    assert_prolog_success!(&mut wam, "abolish(foo/2).");
+    assert_prolog_failure!(&mut wam, "abolish(foo/_).");
+    assert_prolog_success!(&mut wam, "catch(abolish(foo/_), error(instantiation_error, abolish/1), true).");
+    assert_prolog_failure!(&mut wam, "abolish(foo).");
+    assert_prolog_success!(&mut wam, "catch(abolish(foo), error(type_error(predicate_indicator, foo), abolish/1), true).");
+    assert_prolog_failure!(&mut wam, "abolish(foo(_)).");
+    assert_prolog_success!(&mut wam, "catch(abolish(foo(_)), error(type_error(predicate_indicator, foo(_)), abolish/1), true).");
+    assert_prolog_failure!(&mut wam, "abolish(abolish/1).");
+    assert_prolog_success!(&mut wam, "catch(abolish(abolish/1), error(permission_error(modify, static_procedure, abolish/1), abolish/1), true).");
+
+    assert_prolog_success!(&mut wam, "atom_length('enchanted evening', N).",
                            [["N = 17"]]);
-    assert_prolog_success!(&mut wam, r"?- atom_length('enchanted\
+    assert_prolog_success!(&mut wam, r"atom_length('enchanted\
  evening', N).",
                            [["N = 17"]]);
-    assert_prolog_success!(&mut wam, "?- atom_length('', N).",
+    assert_prolog_success!(&mut wam, "atom_length('', N).",
                            [["N = 0"]]);
-    assert_prolog_failure!(&mut wam, "?- atom_length('scarlet', 5).");
-    assert_prolog_success!(&mut wam, "?- catch((atom_length(Atom, 4), false), error(instantiation_error, _), true).");
-    assert_prolog_success!(&mut wam, "?- catch((atom_length(1.23, 4), false), error(type_error(atom, 1.23), _), true).");
-    assert_prolog_success!(&mut wam, "?- catch((atom_length(atom, '4'), false), error(type_error(integer, '4'), _), true).");
+    assert_prolog_failure!(&mut wam, "atom_length('scarlet', 5).");
+    assert_prolog_success!(&mut wam, "catch((atom_length(Atom, 4), false), error(instantiation_error, _), true).");
+    assert_prolog_success!(&mut wam, "catch((atom_length(1.23, 4), false), error(type_error(atom, 1.23), _), true).");
+    assert_prolog_success!(&mut wam, "catch((atom_length(atom, '4'), false), error(type_error(integer, '4'), _), true).");
 
 }
 
@@ -1971,93 +1976,93 @@ foo(X) :- call(X) -> call(X).");
 #[test]
 fn test_queries_on_setup_call_cleanup()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     // Test examples from the ISO Prolog page for setup_call_catch.
-    assert_prolog_failure!(&mut wam, "?- setup_call_cleanup(false, _, _).");
-    assert_prolog_success!(&mut wam, "?- catch(setup_call_cleanup(true, throw(unthrown), _), error(instantiation_error, _), true).");
-    assert_prolog_success!(&mut wam, "?- setup_call_cleanup(true, true, (true ; throw(x))).");
-    assert_prolog_success!(&mut wam, "?- setup_call_cleanup(true, X = 1, X = 2).",
+    assert_prolog_failure!(&mut wam, "setup_call_cleanup(false, _, _).");
+    assert_prolog_success!(&mut wam, "catch(setup_call_cleanup(true, throw(unthrown), _), error(instantiation_error, _), true).");
+    assert_prolog_success!(&mut wam, "setup_call_cleanup(true, true, (true ; throw(x))).");
+    assert_prolog_success!(&mut wam, "setup_call_cleanup(true, X = 1, X = 2).",
                            [["X = 1"]]);
-    assert_prolog_success!(&mut wam, "?- setup_call_cleanup(true, true, X = 2).",
+    assert_prolog_success!(&mut wam, "setup_call_cleanup(true, true, X = 2).",
                            [["X = 2"]]);
-    assert_prolog_success!(&mut wam, "?- catch(setup_call_cleanup(true, X=true, X), error(E, _), true).",
+    assert_prolog_success!(&mut wam, "catch(setup_call_cleanup(true, X=true, X), error(E, _), true).",
                            [["E = instantiation_error", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- catch(setup_call_cleanup(X=throw(ex), true, X), E, true).",
+    assert_prolog_success!(&mut wam, "catch(setup_call_cleanup(X=throw(ex), true, X), E, true).",
                            [["E = ex", "X = _3"]]);
-    assert_prolog_success!(&mut wam, "?- setup_call_cleanup(true, true, false).");
-    assert_prolog_success!(&mut wam, "?- setup_call_cleanup(S = 1, G = 2, C = 3).",
+    assert_prolog_success!(&mut wam, "setup_call_cleanup(true, true, false).");
+    assert_prolog_success!(&mut wam, "setup_call_cleanup(S = 1, G = 2, C = 3).",
                            [["S = 1", "G = 2", "C = 3"]]);
-    assert_prolog_success!(&mut wam, "?- setup_call_cleanup((S=1;S=2), G=3, C=4).",
+    assert_prolog_success!(&mut wam, "setup_call_cleanup((S=1;S=2), G=3, C=4).",
                            [["S = 1", "G = 3", "C = 4"]]);
-    assert_prolog_success!(&mut wam, "?- setup_call_cleanup(S=1, G=2, writeq(S+G)).",
+    assert_prolog_success!(&mut wam, "setup_call_cleanup(S=1, G=2, writeq(S+G)).",
                            [["S = 1", "G = 2"]]);
-    assert_prolog_success!(&mut wam, "?- setup_call_cleanup(S=1, (G=2;G=3), writeq(S+G)).",
+    assert_prolog_success!(&mut wam, "setup_call_cleanup(S=1, (G=2;G=3), writeq(S+G)).",
                            [["S = 1", "G = 2"],
                             ["S = 1", "G = 3"]]);
-    assert_prolog_success!(&mut wam, "?- setup_call_cleanup(S=1, G=2, writeq(S+G>A+B)), A=3, B=4.",
+    assert_prolog_success!(&mut wam, "setup_call_cleanup(S=1, G=2, writeq(S+G>A+B)), A=3, B=4.",
                            [["S = 1", "G = 2", "A = 3", "B = 4"]]);
     assert_prolog_success!(&mut wam,
-                           "?- catch(setup_call_cleanup(S=1, (G=2;G=3,throw(x)), writeq(S+G)), E, true).",
+                           "catch(setup_call_cleanup(S=1, (G=2;G=3,throw(x)), writeq(S+G)), E, true).",
                            [["S = 1", "G = 2", "E = _26"], ["G = _4", "E = x", "S = _1"]]);
     assert_prolog_success!(&mut wam,
-                           "?- setup_call_cleanup(S=1, (G=2;G=3),writeq(S+G>B)), B=4, !.",
+                           "setup_call_cleanup(S=1, (G=2;G=3),writeq(S+G>B)), B=4, !.",
                            [["S = 1", "B = 4", "G = 2"]]);
     assert_prolog_success!(&mut wam,
-                           "?- setup_call_cleanup(S=1,G=2,writeq(S+G>B)),B=3,!.",
+                           "setup_call_cleanup(S=1,G=2,writeq(S+G>B)),B=3,!.",
                            [["S = 1", "G = 2", "B = 3"]]);
     assert_prolog_success!(&mut wam,
-                           "?- setup_call_cleanup(S=1,(G=2;false),writeq(S+G>B)),B=3,!.",
+                           "setup_call_cleanup(S=1,(G=2;false),writeq(S+G>B)),B=3,!.",
                            [["S = 1", "G = 2", "B = 3"]]);
     assert_prolog_success!(&mut wam,
-                           "?- setup_call_cleanup(S=1,(G=2;S=2),writeq(S+G>B)), B=3, !.",
+                           "setup_call_cleanup(S=1,(G=2;S=2),writeq(S+G>B)), B=3, !.",
                            [["S = 1", "B = 3", "G = 2"]]);
     assert_prolog_failure!(&mut wam,
-                           "?- setup_call_cleanup(S=1,(G=2;G=3), writeq(S+G>B)), B=4, !, throw(x).");
+                           "setup_call_cleanup(S=1,(G=2;G=3), writeq(S+G>B)), B=4, !, throw(x).");
 
     assert_prolog_success!(&mut wam,
-                           "?- catch(setup_call_cleanup(true,throw(goal),throw(cl)), Pat, true).",
+                           "catch(setup_call_cleanup(true,throw(goal),throw(cl)), Pat, true).",
                            [["Pat = goal"]]);
     assert_prolog_success!(&mut wam,
-                           "?- catch(( setup_call_cleanup(true,(G=1;G=2),throw(cl)), throw(cont)), Pat, true).",
+                           "catch(( setup_call_cleanup(true,(G=1;G=2),throw(cl)), throw(cont)), Pat, true).",
                            [["Pat = cont", "G = _1"]]);
 
     // fails here.
     assert_prolog_success!(&mut wam,
-"?- setup_call_cleanup(true, (X=1;X=2), writeq(a)), setup_call_cleanup(true,(Y=1;Y=2),writeq(b)), !.",
+"setup_call_cleanup(true, (X=1;X=2), writeq(a)), setup_call_cleanup(true,(Y=1;Y=2),writeq(b)), !.",
                            [["Y = 1", "X = 1"]]);
 }
 
 #[test]
 fn test_queries_on_call_with_inference_limit()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(throw(error), 0, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(throw(error), 0, R).",
                            [["R = inference_limit_exceeded"]]);
-    assert_prolog_success!(&mut wam, "?- catch(call_with_inference_limit(throw(error), 1, R), error, true).");
+    assert_prolog_success!(&mut wam, "catch(call_with_inference_limit(throw(error), 1, R), error, true).");
 
-    assert_prolog_failure!(&mut wam, "?- call_with_inference_limit(g(X), 5, R).");
+    assert_prolog_failure!(&mut wam, "call_with_inference_limit(g(X), 5, R).");
 
     submit(&mut wam, "g(1). g(2). g(3). g(4). g(5).");
 
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(g(X), 5, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 5, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = true", "X = 3"],
                             ["R = true", "X = 4"],
                             ["R = !", "X = 5"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(g(X), 5, R), call(true).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 5, R), call(true).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = true", "X = 3"],
                             ["R = true", "X = 4"],
                             ["R = !", "X = 5"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(g(X), 2, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 2, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(g(X), 3, R1),
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 3, R1),
                                          call_with_inference_limit(g(X), 5, R2).",
                            [["X = 1", "R1 = true", "R2 = !"],
                             ["X = 2", "R1 = true", "R2 = !"],
@@ -2067,59 +2072,59 @@ fn test_queries_on_call_with_inference_limit()
 
     submit(&mut wam, "f(X) :- call_with_inference_limit(g(X), 5, _).");
 
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 7, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 7, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = true", "X = 3"],
                             ["R = true", "X = 4"],
                             ["R = !", "X = 5"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 6, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 6, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = true", "X = 3"],
                             ["R = true", "X = 4"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 4, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 4, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 3, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 3, R).",
                            [["R = true", "X = 1"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 2, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 2, R).",
                            [["R = inference_limit_exceeded", "X = _1"]]);
 
     submit(&mut wam, "e(X) :- call_with_inference_limit(f(X), 10, _).");
 
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 10, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 10, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = true", "X = 3"],
                             ["R = true", "X = 4"],
                             ["R = !", "X = 5"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 8, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 8, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = true", "X = 3"],
                             ["R = true", "X = 4"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 6, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 6, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 5, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 5, R).",
                            [["R = true", "X = 1"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 4, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 4, R).",
                            [["R = inference_limit_exceeded", "X = _1"]]);
 
     submit(&mut wam, "f(X, R) :- call_with_inference_limit(g(X), 5, R).");
 
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X, R), 4, S).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X, R), 4, S).",
                            [["S = true", "X = 1", "R = true"],
                             ["S = true", "X = 2", "R = true"],
                             ["S = inference_limit_exceeded", "X = _1", "R = _2"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X, R), 8, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X, R), 8, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = true", "X = 3"],
@@ -2128,35 +2133,35 @@ fn test_queries_on_call_with_inference_limit()
 
     submit(&mut wam, "g(1). g(2). g(3). g(4). g(5). g(6).");
 
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X, R), 8, S).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X, R), 8, S).",
                            [["R = true", "X = 1", "S = true"],
                             ["R = true", "X = 2", "S = true"],
                             ["R = true", "X = 3", "S = true"],
                             ["R = true", "X = 4", "S = true"],
                             ["R = true", "X = 5", "S = true"],
                             ["R = inference_limit_exceeded", "S = !", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(g(X), 2, R), call_with_inference_limit(g(X), 1, S).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 2, R), call_with_inference_limit(g(X), 1, S).",
                            [["R = true", "X = 1", "S = !"],
                             ["R = true", "X = 2", "S = !"],
                             ["R = true", "X = 3", "S = !"],
                             ["R = true", "X = 4", "S = !"],
                             ["R = true", "X = 5", "S = !"],
                             ["R = !", "X = 6", "S = !"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(g(X), 2, R), call_with_inference_limit(g(X), 1, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 2, R), call_with_inference_limit(g(X), 1, R).",
                            [["R = !", "X = 6"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(g(X), 1, R), call_with_inference_limit(g(X), 1, R).",
+    assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 1, R), call_with_inference_limit(g(X), 1, R).",
                            [["R = inference_limit_exceeded", "X = _1"]]);
 }
 
 #[test]
 fn test_queries_on_dcgs()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     submit(&mut wam, ":- use_module(library(dcgs)).");
 
     // test case by YeGoblynQueene from hacker news.
-    compile_user_module(&mut wam,
+    submit_code(&mut wam,
     " ability(destroy, X) --> destroy(X).
       destroy(X) --> [destroy], target(X).
       target(X) --> [target], permanent(X).
@@ -2171,9 +2176,9 @@ fn test_queries_on_dcgs()
       land('Mountain') --> [].
       % etc permanents
       sorcery('Duress') --> [].
-      instant('Lightning Bolt') --> [].".as_bytes());
+      instant('Lightning Bolt') --> [].");
 
-    assert_prolog_success!(&mut wam, "?- phrase(ability(destroy, X), P).",
+    assert_prolog_success!(&mut wam, "phrase(ability(destroy, X), P).",
                            [["P = [destroy, target, creature]", "X = 'Llanowar Elves'"],
                             ["P = [destroy, target, artifact]", "X = 'Ankh of Mishra'"],
                             ["P = [destroy, target, land]", "X = 'Mountain'"]]);
@@ -2182,150 +2187,150 @@ fn test_queries_on_dcgs()
 #[test]
 fn test_queries_on_string_lists()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     // double_quotes is chars by default.
-    assert_prolog_success!(&mut wam, "?- \"\" =@= [].");
-    assert_prolog_failure!(&mut wam, "?- \"\" == [].");
-    assert_prolog_failure!(&mut wam, "?- \"abc\" == [].");
-    assert_prolog_success!(&mut wam, "?- \"abc\" =@= ['a', 'b', 'c'].");
-    assert_prolog_success!(&mut wam, "?- \"abc\" =@= ['a', 'b', c].");
-    assert_prolog_success!(&mut wam, "?- \"abc\" =@= ['a', b, 'c'].");
-    assert_prolog_success!(&mut wam, "?- \"abc\" =@= [a, 'b', 'c'].");
-    assert_prolog_success!(&mut wam, "?- \"abc\" =@= [a, 'b', c].");
-    assert_prolog_failure!(&mut wam, "?- \"abc\" == ['a', 'b', 'c'].");
-    assert_prolog_failure!(&mut wam, "?- \"abc\" == ['a', 'b', c].");
-    assert_prolog_failure!(&mut wam, "?- \"abc\" == ['a', b, 'c'].");
-    assert_prolog_failure!(&mut wam, "?- \"abc\" == [a, 'b', 'c'].");
-    assert_prolog_failure!(&mut wam, "?- \"abc\" == [a, 'b', c].");
-    assert_prolog_failure!(&mut wam, "?- \"koen\" == [k, o, e, n].");
-    assert_prolog_success!(&mut wam, "?- \"koen\" = [k, o, e, n].");
-    assert_prolog_success!(&mut wam, "?- \"koen\" =@= [k, o, e, n].");
-    assert_prolog_success!(&mut wam, "?- \"koen\" =@= \"koen\".");
-    assert_prolog_success!(&mut wam, "?- \"koen\" = [k, o | X].",
+    assert_prolog_success!(&mut wam, "\"\" =@= [].");
+    assert_prolog_failure!(&mut wam, "\"\" == [].");
+    assert_prolog_failure!(&mut wam, "\"abc\" == [].");
+    assert_prolog_success!(&mut wam, "\"abc\" =@= ['a', 'b', 'c'].");
+    assert_prolog_success!(&mut wam, "\"abc\" =@= ['a', 'b', c].");
+    assert_prolog_success!(&mut wam, "\"abc\" =@= ['a', b, 'c'].");
+    assert_prolog_success!(&mut wam, "\"abc\" =@= [a, 'b', 'c'].");
+    assert_prolog_success!(&mut wam, "\"abc\" =@= [a, 'b', c].");
+    assert_prolog_failure!(&mut wam, "\"abc\" == ['a', 'b', 'c'].");
+    assert_prolog_failure!(&mut wam, "\"abc\" == ['a', 'b', c].");
+    assert_prolog_failure!(&mut wam, "\"abc\" == ['a', b, 'c'].");
+    assert_prolog_failure!(&mut wam, "\"abc\" == [a, 'b', 'c'].");
+    assert_prolog_failure!(&mut wam, "\"abc\" == [a, 'b', c].");
+    assert_prolog_failure!(&mut wam, "\"koen\" == [k, o, e, n].");
+    assert_prolog_success!(&mut wam, "\"koen\" = [k, o, e, n].");
+    assert_prolog_success!(&mut wam, "\"koen\" =@= [k, o, e, n].");
+    assert_prolog_success!(&mut wam, "\"koen\" =@= \"koen\".");
+    assert_prolog_success!(&mut wam, "\"koen\" = [k, o | X].",
                            [["X = [e, n]"]]);
-    assert_prolog_success!(&mut wam, "?- \"koen\" = [k, o | X], X = \"en\".",
+    assert_prolog_success!(&mut wam, "\"koen\" = [k, o | X], X = \"en\".",
                            [["X = [e, n]"]]);
-    assert_prolog_failure!(&mut wam, "?- \"koen\" = [k, o | X], X == \"en\".");
-    assert_prolog_success!(&mut wam, "?- \"koen\" = [k, o | X], X =@= \"en\".",
+    assert_prolog_failure!(&mut wam, "\"koen\" = [k, o | X], X == \"en\".");
+    assert_prolog_success!(&mut wam, "\"koen\" = [k, o | X], X =@= \"en\".",
                            [["X = [e, n]"]]);
 
-    assert_prolog_failure!(&mut wam, "?- X = \"abc\", Y = \"abc\", X == Y.");
-    assert_prolog_failure!(&mut wam, "?- partial_string(\"abc\", X), partial_string(\"abc\", Y), X == Y.");
+    assert_prolog_failure!(&mut wam, "X = \"abc\", Y = \"abc\", X == Y.");
+    assert_prolog_failure!(&mut wam, "partial_string(\"abc\", X), partial_string(\"abc\", Y), X == Y.");
 
-    assert_prolog_success!(&mut wam, "?- X = \"abc\", Y = \"abc\", X =@= Y.");
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), partial_string(\"abc\", Y), X =@= Y.");
+    assert_prolog_success!(&mut wam, "X = \"abc\", Y = \"abc\", X =@= Y.");
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), partial_string(\"abc\", Y), X =@= Y.");
 
     submit(&mut wam, "matcher([a,b,c|X], ['d','e','f'|X]).");
 
-    assert_prolog_success!(&mut wam, "?- matcher(\"abcdef\", \"defdef\").");
-    assert_prolog_failure!(&mut wam, "?- matcher(\"abcdef\", \"defdff\").");
+    assert_prolog_success!(&mut wam, "matcher(\"abcdef\", \"defdef\").");
+    assert_prolog_failure!(&mut wam, "matcher(\"abcdef\", \"defdff\").");
 
-    assert_prolog_success!(&mut wam, "?- matcher([X, Y, Z | W], [A, B, C | W]).",
+    assert_prolog_success!(&mut wam, "matcher([X, Y, Z | W], [A, B, C | W]).",
                            [["A = d", "B = e", "C = f", "W = _1", "X = a", "Y = b", "Z = c"]]);
-    assert_prolog_failure!(&mut wam, "?- matcher([X, Y, Z | W], [X, B, C | W]).");
+    assert_prolog_failure!(&mut wam, "matcher([X, Y, Z | W], [X, B, C | W]).");
 
     submit(&mut wam, "matcher([a,b,c|X], X).");
 
-    assert_prolog_success!(&mut wam, "?- matcher(\"abcdef\", X), X = [d,e,f|Y], Y =@= [], X = \"def\".",
+    assert_prolog_success!(&mut wam, "matcher(\"abcdef\", X), X = [d,e,f|Y], Y =@= [], X = \"def\".",
                            [["X = [d, e, f]", "Y = []"]]);
-    assert_prolog_success!(&mut wam, "?- matcher(\"abcdef\", X), X = [d,e,f|Y], Y =@= [], X =@= \"def\".",
+    assert_prolog_success!(&mut wam, "matcher(\"abcdef\", X), X = [d,e,f|Y], Y =@= [], X =@= \"def\".",
                            [["X = [d, e, f]", "Y = []"]]);
-    assert_prolog_success!(&mut wam, "?- X = ['a', 'b', 'c' | \"def\"].",
+    assert_prolog_success!(&mut wam, "X = ['a', 'b', 'c' | \"def\"].",
                            [["X = [a, b, c, d, e, f]"]]);
 
-    assert_prolog_success!(&mut wam, "?- X = [a,b,c|\"abc\"].",
+    assert_prolog_success!(&mut wam, "X = [a,b,c|\"abc\"].",
                            [["X = [a, b, c, a, b, c]"]]);
 
-    assert_prolog_success!(&mut wam, "?- set_prolog_flag(double_quotes, atom).");
+    assert_prolog_success!(&mut wam, "set_prolog_flag(double_quotes, atom).");
 
-    assert_prolog_success!(&mut wam, "?- matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "matcher(X, Y).",
                           [["X = [a, b, c | _1]", "Y = _1"]]);
-    assert_prolog_failure!(&mut wam, "?- matcher(\"abcdef\", Y).");
+    assert_prolog_failure!(&mut wam, "matcher(\"abcdef\", Y).");
 
-    assert_prolog_success!(&mut wam, "?- set_prolog_flag(double_quotes, chars).");
+    assert_prolog_success!(&mut wam, "set_prolog_flag(double_quotes, chars).");
 
-    assert_prolog_success!(&mut wam, "?- X = \"abc\", X = ['a' | Y], set_prolog_flag(double_quotes, atom).",
+    assert_prolog_success!(&mut wam, "X = \"abc\", X = ['a' | Y], set_prolog_flag(double_quotes, atom).",
                            [["X = \"abc\"", "Y = \"bc\""]]);
 
     // partial strings.
-    assert_prolog_success!(&mut wam, "?- set_prolog_flag(double_quotes, chars).");
+    assert_prolog_success!(&mut wam, "set_prolog_flag(double_quotes, chars).");
 
-    assert_prolog_failure!(&mut wam, "?- Y = 5, partial_string(\"abc\", Y).");
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X).",
+    assert_prolog_failure!(&mut wam, "Y = 5, partial_string(\"abc\", Y).");
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X).",
                            [["X = [a, b, c | _]"]]);
 
-    assert_prolog_failure!(&mut wam, "?- partial_string(\"abc\", X), partial_string(\"abc\", Y), matcher(X, V),
+    assert_prolog_failure!(&mut wam, "partial_string(\"abc\", X), partial_string(\"abc\", Y), matcher(X, V),
                                          matcher(Y, Z), V = Z.");
 
     submit(&mut wam, "matcher([a, b, c | X], X).");
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y).",
                            [["X = [a, b, c | _]", "Y = _"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), Y = \"def\".",
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), Y = \"def\".",
                            [["X = [a, b, c, d, e, f]", "Y = [d, e, f]"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), \"def\" = Y.",
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), \"def\" = Y.",
                            [["X = [a, b, c, d, e, f]", "Y = [d, e, f]"]]);
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y).",
                            [["X = [a, b, c, d, e, f | _]",
                              "Y = [d, e, f | _]"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y),
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y),
                                          Y = \"defghijkl\".",
                            [["X = [a, b, c, d, e, f, g, h, i, j, k, l]",
                              "Y = [d, e, f, g, h, i, j, k, l]"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y),
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y),
                                          \"defghijkl\" = Y.",
                            [["X = [a, b, c, d, e, f, g, h, i, j, k, l]",
                              "Y = [d, e, f, g, h, i, j, k, l]"]]);
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G].",
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G].",
                            [["X = [a, b, c, d, e, f | _]", "Y = [d, e, f | _]", "G = _"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), [d, e, f | G] = Y.",
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), [d, e, f | G] = Y.",
                            [["X = [a, b, c, d, e, f | _]", "Y = [d, e, f | _]", "G = _"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G],
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G],
                                          G = \"ghi\".",
                            [["X = [a, b, c, d, e, f, g, h, i]", "Y = [d, e, f, g, h, i]", "G = [g, h, i]"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G],
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G],
                                          is_partial_string(Y), G = \"ghi\".",
                            [["X = [a, b, c, d, e, f, g, h, i]", "Y = [d, e, f, g, h, i]", "G = [g, h, i]"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G],
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G],
                                          is_partial_string(Y), is_partial_string(G), G = \"ghi\".",
                            [["X = [a, b, c, d, e, f, g, h, i]", "Y = [d, e, f, g, h, i]", "G = [g, h, i]"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), partial_string(\"ababc\", Y), Y = [a,b|Z],
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), partial_string(\"ababc\", Y), Y = [a,b|Z],
                                          X =@= Z.",
                            [["X = [a, b, c | _]", "Y = [a, b, a, b, c | _]", "Z = [a, b, c | _]"]]);
-    assert_prolog_failure!(&mut wam, "?- partial_string(\"abc\", X), partial_string(\"ababc\", Y), Y = [a,b|Z],
+    assert_prolog_failure!(&mut wam, "partial_string(\"abc\", X), partial_string(\"ababc\", Y), Y = [a,b|Z],
                                          X == Z.");
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), X @> \"abc\".");
-    assert_prolog_failure!(&mut wam, "?- partial_string(\"abc\", X), X \\=@= \"abc\".");
-    assert_prolog_failure!(&mut wam, "?- partial_string(\"abc\", X), X @< \"abc\".");
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), X @> \"abc\".");
+    assert_prolog_failure!(&mut wam, "partial_string(\"abc\", X), X \\=@= \"abc\".");
+    assert_prolog_failure!(&mut wam, "partial_string(\"abc\", X), X @< \"abc\".");
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"ab\", X), matcher(X, Y), Y = [a,b|V],
+    assert_prolog_success!(&mut wam, "partial_string(\"ab\", X), matcher(X, Y), Y = [a,b|V],
                                          matcher(Y, Z), is_partial_string(Y).",
                            [["V = [c | _]", "X = [a, b, c, a, b, c | _]", "Y = [a, b, c | _]", "Z = _"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"a\", X), matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"a\", X), matcher(X, Y).",
                            [["X = [a, b, c | _]", "Y = _"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"a\", X), matcher(X, Y), is_partial_string(Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"a\", X), matcher(X, Y), is_partial_string(Y).",
                            [["X = [a, b, c | _]", "Y = _"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"a\", X), matcher(X, Y), Y = \"def\".",
+    assert_prolog_success!(&mut wam, "partial_string(\"a\", X), matcher(X, Y), Y = \"def\".",
                            [["X = [a, b, c, d, e, f]", "Y = [d, e, f]"]]);
 
     submit(&mut wam, "matcher([a,b,c|X], X).
                       matcher([a,b,d|X], X).");
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"ab\", X), matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"ab\", X), matcher(X, Y).",
                            [["X = [a, b, c | _]", "Y = _"],
                             ["X = [a, b, d | _]", "Y = _"]]);
 
     submit(&mut wam, "matcher([a,b,c,d|X], X).
                       matcher([a,c,d|X], X).");
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"ab\", X), matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"ab\", X), matcher(X, Y).",
                            [["X = [a, b, c, d | _]", "Y = _"]]);
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"a\", X), matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"a\", X), matcher(X, Y).",
                            [["X = [a, b, c, d | _]", "Y = _"],
                             ["X = [a, c, d | _]", "Y = _"]]);
 
@@ -2333,11 +2338,11 @@ fn test_queries_on_string_lists()
                       matcher([a,c,d|X], X).
                       matcher([a,e,f|X], X).");
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"a\", X), matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"a\", X), matcher(X, Y).",
                            [["X = [a, b, c, d | _]", "Y = _"],
                             ["X = [a, c, d | _]", "Y = _"],
                             ["X = [a, e, f | _]", "Y = _"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"a\", X), matcher(X, Y), Y = \" t\".",
+    assert_prolog_success!(&mut wam, "partial_string(\"a\", X), matcher(X, Y), Y = \" t\".",
                            [["X = [a, b, c, d, ' ', t]", "Y = [' ', t]"],
                             ["X = [a, c, d, ' ', t]", "Y = [' ', t]"],
                             ["X = [a, e, f, ' ', t]", "Y = [' ', t]"]]);
@@ -2345,14 +2350,14 @@ fn test_queries_on_string_lists()
     submit(&mut wam, "matcher([a,b,c|X], X) :- X = [].
                       matcher([a,b,c|X], X).");
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y).",
                            [["X = [a, b, c]", "Y = []"],
                             ["X = [a, b, c | _]", "Y = _"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"a\", X), matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"a\", X), matcher(X, Y).",
                            [["X = [a, b, c]", "Y = []"],
                             ["X = [a, b, c | _]", "Y = _"]]);
 
-    assert_prolog_failure!(&mut wam, "?- partial_string(\"abc\", X), partial_string(\"bc\", Y), X = [a | Y].");
+    assert_prolog_failure!(&mut wam, "partial_string(\"abc\", X), partial_string(\"bc\", Y), X = [a | Y].");
 
     submit(&mut wam, "matcher([a|X], X) :- matcher2(X, _).
                       matcher([b|X], X) :- matcher2(X, _).
@@ -2360,39 +2365,39 @@ fn test_queries_on_string_lists()
                       matcher2([c|X], X).
                       matcher2([d|X], X).");
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"\", X), matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"\", X), matcher(X, Y).",
                            [["X = [a, c | _]", "Y = [c | _]"],
                             ["X = [a, d | _]", "Y = [d | _]"],
                             ["X = [b, c | _]", "Y = [c | _]"],
                             ["X = [b, d | _]", "Y = [d | _]"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"a\", X), matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"a\", X), matcher(X, Y).",
                            [["X = [a, c | _]", "Y = [c | _]"],
                             ["X = [a, d | _]", "Y = [d | _]"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"b\", X), matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"b\", X), matcher(X, Y).",
                            [["X = [b, c | _]", "Y = [c | _]"],
                             ["X = [b, d | _]", "Y = [d | _]"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"bc\", X), matcher(X, Y).",
+    assert_prolog_success!(&mut wam, "partial_string(\"bc\", X), matcher(X, Y).",
                            [["X = [b, c | _]", "Y = [c | _]"]]);
 
     submit(&mut wam, "f(\"appendy jones\").
                       f(\"appendy smithers jones\").
                       f(\"appendy o'toole\").");
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"appendy\", X), f(X).",
+    assert_prolog_success!(&mut wam, "partial_string(\"appendy\", X), f(X).",
                            [["X = [a, p, p, e, n, d, y, ' ', j, o, n, e, s]"],
                             ["X = [a, p, p, e, n, d, y, ' ', s, m, i, t, h, e, r, s, ' ', j, o, n, e, s]"],
                             ["X = [a, p, p, e, n, d, y, ' ', o, ''', t, o, o, l, e]"]]);
 
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), partial_string(\"abcdef\", X).",
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), partial_string(\"abcdef\", X).",
                            [["X = [a, b, c, d, e, f | _]"]]);
-    assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), partial_string(\"abcdef\", X), X = \"abcdef\".",
+    assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), partial_string(\"abcdef\", X), X = \"abcdef\".",
                            [["X = [a, b, c, d, e, f]"]]);
 }
 
 #[test]
 fn test_queries_on_attributed_variables()
 {
-    let mut wam = Machine::new();
+    let mut wam = Machine::new(readline::input_stream());
 
     submit(&mut wam, "
 :- module(my_mod, []).
@@ -2400,12 +2405,12 @@ fn test_queries_on_attributed_variables()
 
 :- attribute dif/1, frozen/1.");
 
-    assert_prolog_success!(&mut wam, "?- ( put_atts(V, my_mod, dif(1)) ; put_atts(V, my_mod, dif(2)) ),
-                                         get_atts(V, my_mod, L).",
+    assert_prolog_success!(&mut wam, "( put_atts(V, my_mod, dif(1)) ; put_atts(V, my_mod, dif(2)) ),
+                                      get_atts(V, my_mod, L).",
                            [["L = [dif(1)]", "V = _10"],
                             ["L = [dif(2)]", "V = _10"]]);
 
-    assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, frozen(a)),
+    assert_prolog_success!(&mut wam, "put_atts(V, my_mod, frozen(a)),
                                       ( put_atts(V, my_mod, dif(1))
                                       ; put_atts(V, my_mod, -frozen(a)), put_atts(V, my_mod, dif(2))
                                       ; put_atts(V, my_mod, dif(different)) ),
@@ -2414,43 +2419,43 @@ fn test_queries_on_attributed_variables()
                             ["Ls = [dif(2)]", "V = _10"],
                             ["Ls = [frozen(a), dif(different)]", "V = _10"]]);
 
-    assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a)]),
+    assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a)]),
                                       ( put_atts(V, my_mod, -dif(2)); put_atts(V, my_mod, -frozen(A)) ),
                                         get_atts(V, my_mod, L).",
                            [["A = _71", "L = [frozen(a)]", "V = _25"],
                             ["A = _71", "L = [dif(2)]", "V = _25"]]);
-    assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
+    assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
                                       ( put_atts(V, my_mod, -dif(2)) ; put_atts(V, my_mod, -frozen(A)) ),
                                         get_atts(V, my_mod, L).",
                            [["A = _111", "L = [frozen(b)]", "V = _29"],
                             ["A = _111", "L = [dif(2)]", "V = _29"]]);
-    assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
+    assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
                                          get_atts(V, my_mod, -dif(1)).");
-    assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
+    assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
                                          get_atts(V, my_mod, -dif(3)).");
-    assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
+    assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
                                          get_atts(V, my_mod, dif(X)).",
                            [["X = 2", "V = _29"]]);
-    assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
+    assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
                                          put_atts(V, my_mod, -dif(A)), get_atts(V, my_mod, Ls).",
                            [["A = _112", "Ls = [frozen(b)]", "V = _29"]]);
-    assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), frozen(a), dif(2), frozen(b)]),
+    assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), frozen(a), dif(2), frozen(b)]),
                                          put_atts(V, my_mod, -dif(A)), get_atts(V, my_mod, Ls).",
                            [["A = _114", "Ls = [frozen(b)]", "V = _29"]]);
 
     submit(&mut wam, include_str!("./prolog/examples/minatotask.pl"));
     submit(&mut wam, ":- use_module(library(zdd)).");
 
-    assert_prolog_failure!(&mut wam, "?- ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ),
+    assert_prolog_failure!(&mut wam, "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ),
                                          Vs = [X,Y],
                                          variables_set_zdd(Vs, ZDD),
                                          Vs = [1,1].");
-    assert_prolog_success!(&mut wam, "?- ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ),
+    assert_prolog_success!(&mut wam, "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ),
                                         Vs = [X,Y],
                                         variables_set_zdd(Vs, ZDD),
                                         X = 1.",
                            [["X = 1", "Y = 0", "Vs = [1, 0]", "ZDD = (1->b(true);0->b(true);b(false))"]]);
-    assert_prolog_success!(&mut wam, "?- ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ),
+    assert_prolog_success!(&mut wam, "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ),
                                         Vs = [X,Y],
                                         variables_set_zdd(Vs, ZDD),
                                         X = 0.",