]> Repositorios git - scryer-prolog.git/commitdiff
make use of read_term in the repl
authorMark Thom <[email protected]>
Mon, 10 Sep 2018 06:18:17 +0000 (00:18 -0600)
committerMark Thom <[email protected]>
Mon, 10 Sep 2018 06:18:17 +0000 (00:18 -0600)
15 files changed:
Cargo.lock
Cargo.toml
README.md
src/main.rs
src/prolog/compile.rs
src/prolog/instructions.rs
src/prolog/machine/machine_errors.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/mod.rs
src/prolog/macros.rs
src/prolog/mod.rs
src/prolog/read.rs
src/prolog/toplevel.rs
src/prolog/write.rs [moved from src/prolog/io.rs with 92% similarity]
src/tests.rs

index 6fe939cef2c5e1f81f7b664d00f5efced46381c0..42d1dbcf8ea0f70a6f653186cc21dc30f901bfb2 100644 (file)
@@ -86,7 +86,7 @@ dependencies = [
 
 [[package]]
 name = "prolog_parser"
-version = "0.7.10"
+version = "0.7.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -113,7 +113,7 @@ dependencies = [
  "downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "prolog_parser 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "prolog_parser 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -152,7 +152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
 "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
 "checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
-"checksum prolog_parser 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "277adc8aef82e87336a642a9bbd480cac9550e5ec63c99465eed7cbc7c165808"
+"checksum prolog_parser 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "608b6d0e85a6ea8d4fda3679fc314a8b08efdb07f896438342a9d727b04b72d7"
 "checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
index 323432308608e159c5c3caeb8187aa5e527ea8b4..9080870dafaeef58247dbdd7328fb0ece0734342 100644 (file)
@@ -10,7 +10,7 @@ license = "BSD-3-Clause"
 downcast = "0.9.1"
 num = "0.2"
 ordered-float = "0.5.0"
-prolog_parser = "0.7.10"
+prolog_parser = "0.7.11"
 
 [dependencies.termion]
 version = "1.4.0"
\ No newline at end of file
index b3f6384f4d1e56dd66c58ccbb485c98707a7f00a..f81e78664156d39f75280a963fec151dfce6eba4 100644 (file)
--- a/README.md
+++ b/README.md
@@ -226,7 +226,9 @@ false.
 and so do conjunctive queries:
 ```
 prolog> f(X) :- g(X).
-prolog> g(x). g(y). g(z).
+prolog> :{
+g(x). g(y). g(z).
+}:
 prolog> h(call(f, X)).
 prolog> ?- h(X), X.
 true .
index 3c880a6299234fbc9821055d0cb88c75587e7426..a4fce5f1e242d41fdfb45eb088613e8db9b0f038 100644 (file)
@@ -7,8 +7,11 @@ use prolog::instructions::*;
 mod prolog;
 
 use prolog::compile::*;
-use prolog::io::*;
 use prolog::machine::*;
+use prolog::read::*;
+use prolog::write::*;
+
+use std::io::{Write, stdout};
 
 #[cfg(test)]
 mod tests;
@@ -20,7 +23,7 @@ fn parse_and_compile_line(wam: &mut Machine, buffer: &str)
             let result = compile_packet(wam, packet);
             print(wam, result);
         },
-        Err(s) => println!("{:?}", s)
+        Err(e) => print(wam, EvalSession::from(e))
     }
 }
 
@@ -29,19 +32,28 @@ fn prolog_repl() {
 
     loop {
         print!("prolog> ");
-
-        match read() {
-            Input::Line(line) => parse_and_compile_line(&mut wam, line.as_str()),
-            Input::Batch(batch) =>
-                match compile_user_module(&mut wam, batch.as_str()) {
-                    EvalSession::Error(e) => println!("{}", e),
-                    _ => {}
+        stdout().flush().unwrap();
+        
+        match read_toplevel(&mut wam) {
+            Ok(Input::Term(term)) =>
+                match compile_term(&mut wam, term) {
+                    Ok(packet) => {
+                        let result = compile_packet(&mut wam, packet);
+                        print(&mut wam, result);
+                    },
+                    Err(e) => print(&mut wam, EvalSession::from(e))
                 },
-            Input::Quit => break,
-            Input::Clear => {
+            Ok(Input::Line(line)) => parse_and_compile_line(&mut wam, line.as_str()),
+            Ok(Input::Batch(batch)) => {
+                let result = compile_user_module(&mut wam, batch.as_bytes());
+                print(&mut wam, result);
+            },
+            Ok(Input::Quit) => break,
+            Ok(Input::Clear) => {
                 wam.clear();
                 continue;
-            }
+            },
+            Err(e) => print(&mut wam, EvalSession::from(e))
         };
 
         wam.reset();
index eb57251c61403aeb43729d03498dfd9141d857f6..c6c3c3696b191c150701c6d6769b73d97dc7db2f 100644 (file)
@@ -7,6 +7,7 @@ use prolog::machine::*;
 use prolog::toplevel::*;
 
 use std::collections::{HashMap, HashSet, VecDeque};
+use std::io::Read;
 use std::mem;
 
 #[allow(dead_code)]
@@ -48,6 +49,11 @@ pub fn parse_code(wam: &mut Machine, buffer: &str) -> Result<TopLevelPacket, Par
     worker.parse_code()
 }
 
+pub fn compile_term(wam: &mut Machine, term: Term) -> Result<TopLevelPacket, ParserError> {
+    let indices = machine_code_indices!(&mut wam.code_dir, &mut wam.op_dir, &mut HashMap::new());
+    parse_term(term, indices)
+}
+
 // throw errors if declaration or query found.
 fn compile_relation(tl: &TopLevel, non_counted_bt: bool, flags: MachineFlags) -> Result<Code, ParserError>
 {
@@ -137,7 +143,7 @@ fn compile_decl(wam: &mut Machine, tl: TopLevel, queue: Vec<TopLevel>) -> EvalSe
             try_eval_session!(compile_appendix(&mut code, queue, false, wam.machine_flags()));
 
             if !code.is_empty() {
-                wam.add_user_code(name, tl.arity(), code, tl.as_predicate().ok().unwrap())
+                wam.add_user_code(name, tl.arity(), code)
             } else {
                 EvalSession::from(SessionError::ImpermissibleEntry(String::from("no code generated.")))
             }
@@ -177,8 +183,8 @@ impl<'a> ListingCompiler<'a> {
             .unwrap_or(ClauseName::BuiltIn("user"))
     }
 
-    fn gen_code(&mut self, decls: Vec<(Predicate, VecDeque<TopLevel>)>, code_dir: &mut CodeDir)
-                -> Result<Code, SessionError>
+    fn generate_code(&mut self, decls: Vec<(Predicate, VecDeque<TopLevel>)>, code_dir: &mut CodeDir)
+                     -> Result<Code, SessionError>
     {
         let mut code = vec![];
 
@@ -246,9 +252,9 @@ fn use_qualified_module(module: &mut Option<Module>, submodule: &Module, exports
 }
 
 pub
-fn compile_listing(wam: &mut Machine, src_str: &str, mut indices: MachineCodeIndices) -> EvalSession
+fn compile_listing<R: Read>(wam: &mut Machine, src: R, mut indices: MachineCodeIndices) -> EvalSession
 {
-    let mut worker = TopLevelBatchWorker::new(src_str.as_bytes(), wam.atom_tbl(), wam.machine_flags());
+    let mut worker = TopLevelBatchWorker::new(src, wam.atom_tbl(), wam.machine_flags());
     let mut compiler = ListingCompiler::new(wam);
 
     while let Some(decl) = try_eval_session!(worker.consume(&mut indices)) {
@@ -279,13 +285,13 @@ fn compile_listing(wam: &mut Machine, src_str: &str, mut indices: MachineCodeInd
         }
     }
 
-    let code = try_eval_session!(compiler.gen_code(worker.results, &mut indices.code_dir));
+    let code = try_eval_session!(compiler.generate_code(worker.results, &mut indices.code_dir));
     compiler.add_code(code, indices);
 
     EvalSession::EntrySuccess
 }
 
-pub fn compile_user_module(wam: &mut Machine, src_str: &str) -> EvalSession {
+pub fn compile_user_module<R: Read>(wam: &mut Machine, src: R) -> EvalSession {
     let mut indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir(),
                                             &mut HashMap::new());
 
@@ -295,5 +301,5 @@ pub fn compile_user_module(wam: &mut Machine, src_str: &str) -> EvalSession {
         return EvalSession::from(SessionError::ModuleNotFound);
     }
 
-    compile_listing(wam, src_str, indices)
+    compile_listing(wam, src, indices)
 }
index 770e23ae246083d19323b080305f26fa0f2a7197..1563648b826f07008baf407de9077c2af45e70a0 100644 (file)
@@ -28,7 +28,7 @@ impl InlinedClauseType {
             &InlinedClauseType::IsAtom(..) => "atom",
             &InlinedClauseType::IsAtomic(..) => "atomic",
             &InlinedClauseType::IsCompound(..) => "compound",
-            &InlinedClauseType::IsInteger (..) => "integer",            
+            &InlinedClauseType::IsInteger (..) => "integer",
             &InlinedClauseType::IsRational(..) => "rational",
             &InlinedClauseType::IsString(..) => "string",
             &InlinedClauseType::IsFloat (..) => "float",
@@ -195,7 +195,7 @@ pub type ModuleCodeDir = HashMap<PredicateKey, ModuleCodeIndex>;
 
 pub type CodeDir = HashMap<PredicateKey, CodeIndex>;
 
-pub type TermDir = HashMap<PredicateKey, Predicate>;
+//pub type TermDir = HashMap<PredicateKey, Predicate>;
 
 pub type ModuleDir = HashMap<ClauseName, Module>;
 
@@ -781,6 +781,7 @@ pub enum IndexPtr {
 pub struct CodeIndex(pub Rc<RefCell<(IndexPtr, ClauseName)>>);
 
 impl CodeIndex {
+    #[inline]
     pub fn is_undefined(&self) -> bool {
         let index_ptr = &self.0.borrow().0;
 
@@ -1140,15 +1141,6 @@ impl TopLevel {
             &TopLevel::Rule(Rule { ref head, .. }) => head.1.len()
         }
     }
-
-    pub fn as_predicate(self) -> Result<Predicate, TopLevel> {
-        match self {
-            TopLevel::Fact(term) => Ok(Predicate(vec![PredicateClause::Fact(term)])),
-            TopLevel::Rule(rule) => Ok(Predicate(vec![PredicateClause::Rule(rule)])),
-            TopLevel::Predicate(pred) => Ok(pred),
-            _ => Err(self)
-        }
-    }
 }
 
 #[derive(Clone, Copy)]
@@ -1239,7 +1231,7 @@ pub enum SessionError {
     OpIsInfixAndPostFix,
     ParserError(ParserError),
     QueryFailure,
-    QueryFailureWithException(String)
+    QueryFailureWithException(String)    
 }
 
 pub enum EvalSession {
index 692c6654157514c744518bd228a9de6c4b46ca81..5bbed80f6ee9670b3b6b0c48e23b11aaa07c50f5 100644 (file)
@@ -61,48 +61,7 @@ impl MachineError {
     }
 
     pub(super) fn syntax_error(h: usize, err: ParserError) -> Self {
-        let err = match err {
-            ParserError::Arithmetic(_) =>
-                vec![heap_atom!("arithmetic_error")],
-            ParserError::BackQuotedString =>
-                vec![heap_atom!("back_quoted_string")],
-            ParserError::UnexpectedChar(c) =>
-                functor!("unexpected_char", 1, [heap_char!(c)]),
-            ParserError::UnexpectedEOF =>
-                vec![heap_atom!("unexpected_end_of_file")],
-            ParserError::ExpectedRel =>
-                vec![heap_atom!("expected_relation")],
-            ParserError::InadmissibleFact =>                
-                vec![heap_atom!("inadmissible_fact")],
-            ParserError::InadmissibleQueryTerm =>                
-                vec![heap_atom!("inadmissible_query_term")],
-            ParserError::IncompleteReduction =>
-                vec![heap_atom!("incomplete_reduction")],
-            ParserError::InconsistentEntry =>
-                vec![heap_atom!("inconsistent_entry")],
-            ParserError::InvalidModuleDecl =>
-                vec![heap_atom!("invalid_module_declaration")],
-            ParserError::InvalidModuleExport =>
-                vec![heap_atom!("invalid_module_export")],
-            ParserError::InvalidModuleResolution =>
-                vec![heap_atom!("invalid_module_resolution")],
-            ParserError::InvalidRuleHead =>
-                vec![heap_atom!("invalid_head_of_rule")],
-            ParserError::InvalidUseModuleDecl =>
-                vec![heap_atom!("invalid_use_module_declaration")],
-            ParserError::IO(_) =>
-                vec![heap_atom!("input_output_error")],
-            ParserError::MissingQuote =>
-                vec![heap_atom!("missing_quote")],
-            ParserError::NonPrologChar =>
-                vec![heap_atom!("non_prolog_character")],
-            ParserError::ParseBigInt =>
-                vec![heap_atom!("cannot_parse_big_int")],
-            ParserError::ParseFloat =>
-                vec![heap_atom!("cannot_parse_float")],
-            ParserError::Utf8Conversion(_) =>
-                vec![heap_atom!("utf8_conversion_error")]
-        };
+        let err = vec![heap_atom!(err.as_str())];        
 
         let mut stub = if err.len() == 1 {
             functor!("syntax_error", 1)            
index f2e05c7b64f1c26a651abdf9c3f66feea946610d..a2a4c09e7b6f40cfdbb334ee4745bdbc21fc9719 100644 (file)
@@ -9,12 +9,12 @@ use prolog::machine::MachineCodeIndices;
 use prolog::machine::machine_errors::*;
 use prolog::num::{BigInt, BigUint, Zero, One};
 use prolog::or_stack::*;
-use prolog::read::*;
 
 use downcast::Any;
 
 use std::cell::RefCell;
 use std::cmp::Ordering;
+use std::io::stdin;
 use std::mem::swap;
 use std::ops::{Index, IndexMut};
 use std::rc::Rc;
@@ -297,7 +297,7 @@ pub struct MachineState {
     pub(super) ball: Ball,
     pub(super) interms: Vec<Number>, // intermediate numbers.
     pub(super) last_call: bool,
-    pub(super) flags: MachineFlags
+    pub(crate) flags: MachineFlags
 }
 
 fn call_at_index(machine_st: &mut MachineState, module_name: ClauseName, arity: usize, idx: usize)
@@ -570,25 +570,23 @@ pub(crate) trait CallPolicy: Any {
                 machine_st.fail = !machine_st.is_cyclic_term(addr);
                 return_from_clause!(machine_st.last_call, machine_st)
             },
-            &BuiltInClauseType::Read => {
-                let mut reader = Reader::new(machine_st);
-
-                match reader.read_stdin(&indices.op_dir) {
+            &BuiltInClauseType::Read => {                
+                match machine_st.read(stdin(), &indices.op_dir) {
                     Ok(offset) => {
-                        let addr = reader.machine_st[temp_v!(1)].clone();
-                        reader.machine_st.unify(addr, Addr::HeapCell(offset));
+                        let addr = machine_st[temp_v!(1)].clone();
+                        machine_st.unify(addr, Addr::HeapCell(offset));
                     },
                     Err(e) => {
-                        let h    = reader.machine_st.heap.h;
+                        let h    = machine_st.heap.h;
                         let stub = MachineError::functor_stub(clause_name!("read"), 1);
                         let err  = MachineError::syntax_error(h, e);
-                        let err  = reader.machine_st.error_form(err, stub);
+                        let err  = machine_st.error_form(err, stub);
 
                         return Err(err);
                     }
                 };
 
-                return_from_clause!(reader.machine_st.last_call, reader.machine_st)
+                return_from_clause!(machine_st.last_call, machine_st)
             },
             &BuiltInClauseType::Writeq => {
                 let output = machine_st.print_term(machine_st[temp_v!(1)].clone(),
index 5db6062efc6e7fb7125faedaa28e45f75d30f4e2..8c9f16a492bd29f55e4a5afaaa077cce3989443c 100644 (file)
@@ -62,7 +62,7 @@ pub struct Machine {
     code: Code,
     pub(super) code_dir: CodeDir,
     pub(super) op_dir: OpDir,
-    term_dir: TermDir,
+    // term_dir: TermDir,
     pub(super) modules: ModuleDir,
     cached_query: Option<Code>
 }
@@ -116,7 +116,7 @@ impl Machine {
             code: Code::new(),
             code_dir: CodeDir::new(),
             op_dir: default_op_dir(),
-            term_dir: TermDir::new(),            
+            // term_dir: TermDir::new(),            
             modules: HashMap::new(),
             cached_query: None
         };
@@ -124,11 +124,11 @@ impl Machine {
         let indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir(),
                                             &mut HashMap::new());
         
-        compile_listing(&mut wam, BUILTINS, indices);
+        compile_listing(&mut wam, BUILTINS.as_bytes(), indices);
 
-        compile_user_module(&mut wam, LISTS);
-        compile_user_module(&mut wam, CONTROL);
-        compile_user_module(&mut wam, QUEUES);
+        compile_user_module(&mut wam, LISTS.as_bytes());
+        compile_user_module(&mut wam, CONTROL.as_bytes());
+        compile_user_module(&mut wam, QUEUES.as_bytes());
 
         wam.use_module_in_toplevel(clause_name!("builtins"));
 
@@ -252,8 +252,7 @@ impl Machine {
         self.code.extend(code.into_iter());
     }
 
-    pub fn add_user_code(&mut self, name: ClauseName, arity: usize, code: Code, pred: Predicate)
-                         -> EvalSession
+    pub fn add_user_code(&mut self, name: ClauseName, arity: usize, code: Code) -> EvalSession
     {
         match self.code_dir.get(&(name.clone(), arity)) {
             Some(&CodeIndex (ref idx)) if idx.borrow().1 != clause_name!("user") =>
@@ -268,7 +267,7 @@ impl Machine {
         let offset = self.code.len();
 
         self.code.extend(code.into_iter());
-        self.term_dir.insert((name.clone(), arity), pred);
+        //self.term_dir.insert((name.clone(), arity), pred);
 
         let idx = self.code_dir.entry((name, arity))
             .or_insert(CodeIndex::from((offset, clause_name!("user"))));
index 02b2629b1dead934f84ffab571bc10765bda5821..48712dfc7b5edb1e01d349dac1be9de24bc61dca 100644 (file)
@@ -22,12 +22,6 @@ macro_rules! heap_integer {
     )
 }
 
-macro_rules! heap_char {
-    ($c:expr) => (
-        HeapCellValue::Addr(Addr::Con(Constant::Char($c)))
-    )
-}
-
 macro_rules! heap_atom {
     ($name:expr) => (
         HeapCellValue::Addr(Addr::Con(atom!($name)))
index 138b3e4946de72954a44b28e46e3cb92b6eab6db..4c77f937399fb106066980d6965bb0e5c4274d13 100644 (file)
@@ -16,9 +16,9 @@ mod debray_allocator;
 mod fixtures;
 mod heap_iter;
 mod indexing;
-pub mod io;
+pub mod write;
 mod iterators;
 mod or_stack;
 pub mod heap_print;
 mod targets;
-mod read;
+pub mod read;
index 7762923861367ec3ad1faa37e17f69ff8ae84160..7432ec654991b404db2241326e8f15fb88de5436 100644 (file)
@@ -3,14 +3,11 @@ use prolog_parser::parser::*;
 
 use prolog::instructions::*;
 use prolog::iterators::*;
-use prolog::machine::machine_state::*;
+use prolog::machine::*;
+use prolog::machine::machine_state::MachineState;
 
 use std::collections::VecDeque;
-use std::io::stdin;
-
-pub struct Reader<'a> {
-    pub machine_st: &'a mut MachineState,
-}
+use std::io::{Read, stdin};
 
 type SubtermDeque = VecDeque<(usize, usize)>;
 
@@ -25,133 +22,137 @@ impl<'a> TermRef<'a> {
     }
 }
 
-impl<'a> Reader<'a> {
-    pub fn new(machine_st: &'a mut MachineState) -> Self {
-        Reader { machine_st }
-    }
+pub enum Input {
+    Quit,
+    Clear,
+    Line(String),
+    Batch(String),
+    Term(Term)
+}
 
-    fn read_term(&self, buffer: &String, op_dir: &'a OpDir) -> Result<Term, ParserError>  {
-        let mut parser = Parser::new(buffer.as_bytes(), self.machine_st.atom_tbl.clone(),
-                                     self.machine_st.machine_flags());
+fn read_lines(buffer: &mut String, end_delim: &str) -> String {
+    let mut result = String::new();
+    let stdin = stdin();
 
-        parser.read_term(op_dir)
-    }
-    
-    fn read_term_loop(&mut self, buffer: &mut String, op_dir: &'a OpDir) -> Result<Term, ParserError> {
-        let stdin = stdin();
-        
-        loop {
-            match self.read_term(&buffer, op_dir) {
-                Err(ParserError::UnexpectedEOF) => {},
-                result => return result
-            };
-             
-            let mut append_buf = String::new();            
-            stdin.read_line(&mut append_buf).unwrap();
-            *buffer += append_buf.as_str();            
-        }
-    }
-/*    
-    pub fn repl_read(&mut self, op_dir: &'a OpDir) -> Result<Vec<Term>, ParserError> {
-        let mut buffer = String::new();
+    buffer.clear();
+    stdin.read_line(buffer).unwrap();
 
-        stdin().read_line(&mut buffer);
+    while &*buffer.trim() != end_delim {
+        result += buffer.as_str();
+        buffer.clear();
+        stdin.read_line(buffer).unwrap();
+    }
 
-        if buffer.as_str() == "[user]" {
-            let locked = stdin().lock();
-            let mut parser = Parser::new(locked, self.machine_st.atom_tbl.clone(),
-                                         self.machine_st.flags());
+    result
+}
 
-            parser.read(op_dir)
-        } else {
-            Ok(vec![self.read_term_loop(buffer, op_dir)?])
+pub fn read_toplevel(wam: &Machine) -> Result<Input, ParserError> {    
+    let mut buffer = String::new();
+
+    let stdin = stdin();
+    stdin.read_line(&mut buffer).unwrap();
+
+    match &*buffer.trim() {
+        ":{"    => Ok(Input::Line(read_lines(&mut buffer, "}:"))),
+        ":{{"   => Ok(Input::Batch(read_lines(&mut buffer, "}}:"))),
+        "quit"  => Ok(Input::Quit),
+        "clear" => Ok(Input::Clear),
+        _       => {
+            let mut parser = Parser::new(stdin.lock(), wam.atom_tbl(), wam.machine_flags());
+            
+            parser.add_to_top(buffer.as_str());
+            Ok(Input::Term(parser.read_term(&wam.op_dir)?))
         }
     }
-*/
-    pub fn read_stdin(&mut self, op_dir: &'a OpDir) -> Result<usize, ParserError>
+}
+
+impl MachineState {
+    pub fn read<R: Read>(&mut self, inner: R, op_dir: &OpDir) -> Result<usize, ParserError>
     {
-        let term = self.read_term_loop(&mut String::new(), op_dir)?;
-        Ok(self.write_term_to_heap(term))
-    }
+        let mut parser = Parser::new(inner, self.atom_tbl.clone(), self.flags);
+        let term = parser.read_term(op_dir)?;
 
-    fn push_stub_addr(&mut self) {
-        let h = self.machine_st.heap.h;
-        self.machine_st.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
+        Ok(write_term_to_heap(term, self))
     }
+}
 
-    fn modify_head_of_queue(&mut self, queue: &mut SubtermDeque, term: TermRef, h: usize) {
-        if let Some((arity, site_h)) = queue.pop_front() {
-            self.machine_st.heap[site_h] = HeapCellValue::Addr(term.as_addr(h));
+fn push_stub_addr(machine_st: &mut MachineState) {
+    let h = machine_st.heap.h;
+    machine_st.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
+}
+
+fn modify_head_of_queue(machine_st: &mut MachineState, queue: &mut SubtermDeque, term: TermRef, h: usize)
+{
+    if let Some((arity, site_h)) = queue.pop_front() {
+        machine_st.heap[site_h] = HeapCellValue::Addr(term.as_addr(h));
 
-            if arity > 1 {
-                queue.push_front((arity - 1, site_h + 1));
-            }
+        if arity > 1 {
+            queue.push_front((arity - 1, site_h + 1));
         }
     }
+}
 
-    fn write_term_to_heap(&mut self, term: Term) -> usize {
-        let h = self.machine_st.heap.h;
+fn write_term_to_heap(term: Term, machine_st: &mut MachineState) -> usize {
+    let h = machine_st.heap.h;
 
-        let mut queue = SubtermDeque::new();
-        let mut var_dict = HeapVarDict::new();
+    let mut queue = SubtermDeque::new();
+    let mut var_dict = HeapVarDict::new();
 
-        for term in breadth_first_iter(&term, true) {
-            let h = self.machine_st.heap.h;
+    for term in breadth_first_iter(&term, true) {
+        let h = machine_st.heap.h;
 
-            match &term {
-                &TermRef::Cons(lvl, ..) => {
-                    queue.push_back((2, h+1));
-                    self.machine_st.heap.push(HeapCellValue::Addr(Addr::Lis(h+1)));
+        match &term {
+            &TermRef::Cons(lvl, ..) => {
+                queue.push_back((2, h+1));
+                machine_st.heap.push(HeapCellValue::Addr(Addr::Lis(h+1)));
 
-                    self.push_stub_addr();
-                    self.push_stub_addr();
+                push_stub_addr(machine_st);
+                push_stub_addr(machine_st);
 
-                    if let Level::Root = lvl {
-                        continue;
-                    }
-                },
-                &TermRef::Clause(lvl, _, ref ct, subterms) => {
-                    queue.push_back((subterms.len(), h+1));
-                    let named = HeapCellValue::NamedStr(subterms.len(), ct.name(),
-                                                        ct.fixity());
+                if let Level::Root = lvl {
+                    continue;
+                }
+            },
+            &TermRef::Clause(lvl, _, ref ct, subterms) => {
+                queue.push_back((subterms.len(), h+1));
+                let named = HeapCellValue::NamedStr(subterms.len(), ct.name(), ct.fixity());
 
-                    self.machine_st.heap.push(named);
+                machine_st.heap.push(named);
 
-                    for _ in 0 .. subterms.len() {
-                        self.push_stub_addr();
-                    }
+                for _ in 0 .. subterms.len() {
+                    push_stub_addr(machine_st);
+                }
 
-                    if let Level::Root = lvl {
-                        continue;
-                    }
-                },
-                &TermRef::AnonVar(Level::Root)
-              | &TermRef::Var(Level::Root, ..)
-              | &TermRef::Constant(Level::Root, ..) =>
-                    self.machine_st.heap.push(HeapCellValue::Addr(term.as_addr(h))),
-                &TermRef::AnonVar(_) =>
-                    continue,
-                &TermRef::Var(_, _, ref var) => {
-                    if let Some((arity, site_h)) = queue.pop_front() {
-                        if let Some(addr) = var_dict.get(var).cloned() {
-                            self.machine_st.heap[site_h] = HeapCellValue::Addr(addr);
-                        } else {
-                            var_dict.insert(var.clone(), Addr::HeapCell(site_h));
-                        }
-
-                        if arity > 1 {
-                            queue.push_front((arity - 1, site_h + 1));
-                        }
+                if let Level::Root = lvl {
+                    continue;
+                }
+            },
+            &TermRef::AnonVar(Level::Root)
+                | &TermRef::Var(Level::Root, ..)
+                | &TermRef::Constant(Level::Root, ..) =>
+                machine_st.heap.push(HeapCellValue::Addr(term.as_addr(h))),
+            &TermRef::AnonVar(_) =>
+                continue,
+            &TermRef::Var(_, _, ref var) => {
+                if let Some((arity, site_h)) = queue.pop_front() {
+                    if let Some(addr) = var_dict.get(var).cloned() {
+                        machine_st.heap[site_h] = HeapCellValue::Addr(addr);
+                    } else {
+                        var_dict.insert(var.clone(), Addr::HeapCell(site_h));
                     }
 
-                    continue;
-                },
-                _ => {}
-            };
+                    if arity > 1 {
+                        queue.push_front((arity - 1, site_h + 1));
+                    }
+                }
 
-            self.modify_head_of_queue(&mut queue, term, h);
-        }
+                continue;
+            },
+            _ => {}
+        };
 
-        h
+        modify_head_of_queue(machine_st, &mut queue, term, h);
     }
+
+    h
 }
index fac313b5234daca58dd08f4266cf2879145a73e7..b07d85597ab46a0c46318c7154bee76d1d3864d7 100644 (file)
@@ -645,6 +645,16 @@ impl<'a, R: Read> TopLevelWorker<'a, R> {
     }
 }
 
+pub fn parse_term(term: Term, mut indices: MachineCodeIndices) -> Result<TopLevelPacket, ParserError>
+{
+    let mut rel_worker = RelationWorker::new();
+
+    let tl = rel_worker.try_term_to_tl(&mut indices, term, true)?;
+    let results = rel_worker.parse_queue(&mut indices)?;
+
+    Ok(deque_to_packet(tl, results))
+}
+
 pub struct TopLevelBatchWorker<R: Read> {
     parser: Parser<R>,
     rel_worker: RelationWorker,
@@ -666,7 +676,7 @@ impl<R: Read> TopLevelBatchWorker<R> {
     {
         let mut preds = vec![];
 
-        while !self.parser.eof() {
+        while !self.parser.eof()? {
             self.parser.reset(); // empty the parser stack of token descriptions.
 
             let mut new_rel_worker = RelationWorker::new();
similarity index 92%
rename from src/prolog/io.rs
rename to src/prolog/write.rs
index 6f7671c6a4cb245c408b3a04ae8a42c9e593b79c..c9259dab30d165989dbefdb20f3890cbbf42d7fb 100644 (file)
@@ -134,7 +134,7 @@ impl fmt::Display for ControlInstruction {
             &ControlInstruction::CallClause(ref ct, arity, pvs, true, false) =>
                 write!(f, "execute {}/{}, {}", ct, arity, pvs),
             &ControlInstruction::CallClause(ref ct, arity, pvs, false, false) =>
-                write!(f, "call {}/{}, {}", ct, arity, pvs),            
+                write!(f, "call {}/{}, {}", ct, arity, pvs),
             &ControlInstruction::Deallocate =>
                 write!(f, "deallocate"),
             &ControlInstruction::JmpBy(arity, offset, pvs, false) =>
@@ -162,7 +162,7 @@ impl fmt::Display for IndexedChoiceInstruction {
 
 impl fmt::Display for ChoiceInstruction {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match self {            
+        match self {
             &ChoiceInstruction::TryMeElse(offset) =>
                 write!(f, "try_me_else {}", offset),
             &ChoiceInstruction::DefaultRetryMeElse(offset) =>
@@ -201,7 +201,7 @@ impl fmt::Display for SessionError {
             &SessionError::OpIsInfixAndPostFix =>
                 write!(f, "cannot define an op to be both postfix and infix."),
             &SessionError::NamelessEntry => write!(f, "the predicate head is not an atom or clause."),
-            &SessionError::ParserError(ref e) => write!(f, "{:?}", e)
+            &SessionError::ParserError(ref e) => write!(f, "syntax_error({})", e.as_str()),
         }
     }
 }
@@ -281,59 +281,17 @@ impl fmt::Display for Level {
     }
 }
 
-pub enum Input {
-    Quit,
-    Clear,
-    Line(String),
-    Batch(String)
-}
-
-fn read_lines(buffer: &mut String, end_delim: &str) -> String {
-    let mut result = String::new();
-    let stdin = stdin();
-
-    buffer.clear();
-    stdin.read_line(buffer).unwrap();
-
-    while &*buffer.trim() != end_delim {
-        result += buffer.as_str();
-        buffer.clear();
-        stdin.read_line(buffer).unwrap();
-    }
-
-    result
-}
-
-pub fn read() -> Input {
-    let _ = stdout().flush();
-    let mut buffer = String::new();
-
-    let stdin = stdin();
-    stdin.read_line(&mut buffer).unwrap();
-
-    match &*buffer.trim() {
-        ":{"    => Input::Line(read_lines(&mut buffer, "}:")),
-        ":{{"   => Input::Batch(read_lines(&mut buffer, "}}:")),
-        "quit"  => Input::Quit,
-        "clear" => Input::Clear,
-        _       => Input::Line(buffer)
-    }
-}
-
 pub fn print(wam: &mut Machine, result: EvalSession) {
     match result {
         EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
-            print!("true");
-
-            if !wam.or_stack_is_empty() {
-                print!(" ");
-            }
-
-            println!(".");
-
             if heap_locs.is_empty() {
+                println!("true.");
                 return;
             }
+            
+            if !wam.or_stack_is_empty() {
+                println!("true .");
+            }
 
             loop {
                 let mut result = EvalSession::from(SessionError::QueryFailure);
index ea8446599e11b619c593167b305f9aecb6ab0693..e8e40271844b44be7d3c6cc5a34b84feb7284622 100644 (file)
@@ -129,7 +129,7 @@ pub fn submit(wam: &mut Machine, buffer: &str) -> bool
                     true,
                 _ => false
             },
-        Err(e) => panic!("parse error: {:?}", e)
+        Err(e) => panic!("syntax_error({})", e.as_str())
     }
 }
 
@@ -146,7 +146,7 @@ pub fn submit_query(wam: &mut Machine, buffer: &str, result: Vec<HashSet<String>
                 EvalSession::EntrySuccess => true,
                 _ => false
             },
-        Err(e) => panic!("parse error: {:?}", e)
+        Err(e) => panic!("syntax_error({})", e.as_str())
     }
 }
 
@@ -166,7 +166,7 @@ pub fn submit_query_with_limit(wam: &mut Machine, buffer: &str,
                 EvalSession::EntrySuccess => true,
                 _ => false
             },
-        Err(e) => panic!("parse error: {:?}", e)
+        Err(e) => panic!("syntax_error({})", e.as_str())
     }
 }
 
@@ -1351,7 +1351,7 @@ fn test_queries_on_modules()
 local_member(X, Xs) :- member(X, Xs).
 
 reverse(Xs, Ys) :- lists:reverse(Xs, Ys).
-");
+".as_bytes());
 
     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]).");
@@ -1359,13 +1359,11 @@ reverse(Xs, Ys) :- lists:reverse(Xs, Ys).
     compile_user_module(&mut wam, "
 :- use_module(library(my_lists), [local_member/2]).
 :- module(my_lists_2, [local_member/2]).
-");
+".as_bytes());
 
     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"]]);
-
-
 }
 
 #[test]