From 0abd075b0bebf85d3af099d1b09cb5985903351b Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 1 Jul 2018 18:14:45 -0600 Subject: [PATCH] complete trimdown of listing compilation. --- Cargo.lock | 106 +++++-------- Cargo.toml | 2 +- src/prolog/ast.rs | 50 +------ src/prolog/compile.rs | 182 +++++++++++++---------- src/prolog/machine/machine_state_impl.rs | 16 +- src/prolog/machine/mod.rs | 15 +- src/prolog/macros.rs | 4 +- src/prolog/toplevel.rs | 136 ++++++++--------- src/tests.rs | 6 +- 9 files changed, 222 insertions(+), 295 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a04f97a..8d7a9487 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,29 +1,8 @@ -[[package]] -name = "bitflags" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "downcast" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "fuchsia-zircon" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "libc" version = "0.2.34" @@ -31,63 +10,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num" -version = "0.1.41" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-complex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-bigint" -version = "0.1.41" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-complex" -version = "0.1.41" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-integer" -version = "0.1.35" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-iter" -version = "0.1.34" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-rational" -version = "0.1.40" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -95,6 +70,11 @@ name = "num-traits" version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "num-traits" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ordered-float" version = "0.5.0" @@ -104,15 +84,6 @@ dependencies = [ "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "redox_syscall" version = "0.1.32" @@ -126,17 +97,12 @@ dependencies = [ "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rustc-serialize" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "rusty-wam" version = "0.7.8" dependencies = [ "downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num 0.1.41 (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)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -165,23 +131,19 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] -"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf6d87c251688702a52991eaebd07c13eabba9cc0b7f8c31ef94dc881be706e8" -"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" -"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" "checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0" -"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca" -"checksum num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "bdc1494b5912f088f260b775799468d9b9209ac60885d8186a547a0476289e23" -"checksum num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "58de7b4bf7cf5dbecb635a5797d489864eadd03b107930cbccf9e0fd7428b47c" -"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" -"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" -"checksum num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "0c7cb72a95250d8a370105c828f388932373e0e94414919891a0f945222310fe" +"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db" +"checksum num-bigint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3eceac7784c5dc97c2d6edf30259b4e153e6e2b42b3c85e9a6e9f45d06caef6e" +"checksum num-complex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68de83578789e0fbda3fa923035be83cf8bfd3b30ccfdecd5aa89bf8601f408e" +"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" +"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" +"checksum num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10" "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 rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" "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 rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" diff --git a/Cargo.toml b/Cargo.toml index b030b91e..2f787b1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.7.8" authors = ["Mark Thom"] [dependencies] -num = "0.1" +num = "0.2" ordered-float = "0.5.0" downcast = "0.9.1" diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index 476cb3c1..4ddaa2d0 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -810,8 +810,8 @@ pub enum ClauseType { BuiltIn(BuiltInClauseType), CallN, Inlined(InlinedClauseType), - Op(ClauseName, Fixity, CodeIndex), Named(ClauseName, CodeIndex), + Op(ClauseName, Fixity, CodeIndex), System(SystemClauseType) } @@ -1121,54 +1121,6 @@ impl Number { &Number::Rational(ref r) => r.is_zero() } } - - pub fn gt(self, n2: Number) -> bool { - match NumberPair::from(self, n2) { - NumberPair::Integer(n1, n2) => n1 > n2, - NumberPair::Float(n1, n2) => n1 > n2, - NumberPair::Rational(n1, n2) => n1 > n2 - } - } - - pub fn gte(self, n2: Number) -> bool { - match NumberPair::from(self, n2) { - NumberPair::Integer(n1, n2) => n1 >= n2, - NumberPair::Float(n1, n2) => n1 >= n2, - NumberPair::Rational(n1, n2) => n1 >= n2 - } - } - - pub fn lt(self, n2: Number) -> bool { - match NumberPair::from(self, n2) { - NumberPair::Integer(n1, n2) => n1 < n2, - NumberPair::Float(n1, n2) => n1 < n2, - NumberPair::Rational(n1, n2) => n1 < n2 - } - } - - pub fn lte(self, n2: Number) -> bool { - match NumberPair::from(self, n2) { - NumberPair::Integer(n1, n2) => n1 <= n2, - NumberPair::Float(n1, n2) => n1 <= n2, - NumberPair::Rational(n1, n2) => n1 <= n2 - } - } - - pub fn ne(self, n2: Number) -> bool { - match NumberPair::from(self, n2) { - NumberPair::Integer(n1, n2) => n1 != n2, - NumberPair::Float(n1, n2) => n1 != n2, - NumberPair::Rational(n1, n2) => n1 != n2 - } - } - - pub fn eq(self, n2: Number) -> bool { - match NumberPair::from(self, n2) { - NumberPair::Integer(n1, n2) => n1 == n2, - NumberPair::Float(n1, n2) => n1 == n2, - NumberPair::Rational(n1, n2) => n1 == n2 - } - } } pub enum NumberPair { diff --git a/src/prolog/compile.rs b/src/prolog/compile.rs index 815a4259..50716f5c 100644 --- a/src/prolog/compile.rs +++ b/src/prolog/compile.rs @@ -4,6 +4,9 @@ use prolog::codegen::*; use prolog::machine::*; use prolog::toplevel::*; +use std::collections::{HashMap, VecDeque}; +use std::mem; + #[allow(dead_code)] fn print_code(code: &Code) { for clause in code { @@ -38,11 +41,11 @@ pub fn parse_code(wam: &mut Machine, buffer: &str) -> Result EvalSession } } -pub fn compile_listing(wam: &mut Machine, src_str: &str) -> EvalSession -{ - fn get_module_name(module: &Option) -> ClauseName { - match module { - &Some(ref module) => module.module_decl.name.clone(), - _ => ClauseName::BuiltIn("user") - } +pub struct ListingCompiler<'a> { + wam: &'a mut Machine, + module: Option +} + +impl<'a> ListingCompiler<'a> { + pub fn new(wam: &'a mut Machine) -> Self { + ListingCompiler { wam, module: None } } - let mut module: Option = None; + fn get_module_name(&self) -> ClauseName { + self.module.as_ref() + .map(|module| module.module_decl.name.clone()) + .unwrap_or(ClauseName::BuiltIn("user")) + } - let mut code_dir = CodeDir::new(); - let mut op_dir = default_op_dir(); + fn gen_code(&mut self, decls: Vec<(Predicate, VecDeque)>, code_dir: &mut CodeDir) + -> Result + { + let mut code = vec![]; - let mut code = Vec::new(); + for (decl, queue) in decls { + let (name, arity) = decl.0.first().and_then(|cl| { + let arity = cl.arity(); + cl.name().map(|name| (name, arity)) + }).ok_or(SessionError::NamelessEntry)?; - let tls = { - let indices = machine_code_index!(&mut code_dir, &mut op_dir, &wam.modules); - let mut worker = TopLevelWorker::new(src_str.as_bytes(), wam.atom_tbl(), indices); + let p = code.len() + self.wam.code_size(); + let mut decl_code = compile_relation(&TopLevel::Predicate(decl))?; - try_eval_session!(worker.parse_batch(clause_name!("user"))) - }; + compile_appendix(&mut decl_code, Vec::from(queue))?; - for tl in tls { - match tl { - TopLevelPacket::Query(..) => - return EvalSession::from(ParserError::ExpectedRel), - TopLevelPacket::Decl(TopLevel::Declaration(Declaration::Module(module_decl)), _) => - if module.is_none() { - module = Some(Module::new(module_decl)); - } else { - return EvalSession::from(ParserError::InvalidModuleDecl); - }, - TopLevelPacket::Decl(TopLevel::Declaration(Declaration::UseModule(name)), _) => { - if let Some(ref submodule) = wam.get_module(name.clone()) { - if let Some(ref mut module) = module { - let mut code_index = machine_code_index!(&mut code_dir, &mut op_dir, &wam.modules); + let idx = code_dir.entry((name, arity)).or_insert(CodeIndex::default()); + set_code_index!(idx, IndexPtr::Index(p), self.get_module_name()); - module.use_module(submodule); - code_index.use_module(submodule); + code.extend(decl_code.into_iter()); + } - continue; - } - } else { - return EvalSession::from(SessionError::ModuleNotFound); - } + Ok(code) + } - wam.use_module_in_toplevel(name); - }, - TopLevelPacket::Decl(TopLevel::Declaration(Declaration::UseQualifiedModule(name, exports)), _) - => - { - if let Some(ref submodule) = wam.get_module(name.clone()) { - if let Some(ref mut module) = module { - let mut code_index = machine_code_index!(&mut code_dir, &mut op_dir, &wam.modules); - - module.use_qualified_module(submodule, &exports); - code_index.use_qualified_module(submodule, &exports); - - continue; - } - } else { - return EvalSession::from(SessionError::ModuleNotFound); - } + fn add_code(self, code: Code, indices: MachineCodeIndex) { + let code_dir = mem::replace(indices.code_dir, HashMap::new()); + let op_dir = mem::replace(indices.op_dir, HashMap::new()); - wam.use_qualified_module_in_toplevel(name, exports); - }, - TopLevelPacket::Decl(TopLevel::Declaration(Declaration::Op(..)), _) => {}, - TopLevelPacket::Decl(decl, queue) => { - let p = code.len() + wam.code_size(); - let mut decl_code = try_eval_session!(compile_relation(&decl)); + if let Some(mut module) = self.module { + module.code_dir.extend(as_module_code_dir(code_dir)); + module.op_dir.extend(op_dir.into_iter()); - try_eval_session!(compile_appendix(&mut decl_code, queue)); + self.wam.add_module(module, code); + } else { + self.wam.add_batched_code(code, code_dir); + self.wam.add_batched_ops(op_dir); + } + } - let name = try_eval_session!(if let Some(name) = decl.name() { - Ok(name) - } else { - Err(SessionError::NamelessEntry) - }); +} - if let Some(ref mut idx) = code_dir.get_mut(&(name, decl.arity())) { - set_code_index!(idx, IndexPtr::Index(p), get_module_name(&module)); - } +fn use_module(module: &mut Option, submodule: &Module, indices: &mut MachineCodeIndex) +{ + indices.use_module(submodule); - code.extend(decl_code.into_iter()); - } - } + if let &mut Some(ref mut module) = module { + module.use_module(submodule); + } + + // self.wam.use_module_in_toplevel(name); +} + +fn use_qualified_module(module: &mut Option, submodule: &Module, exports: &Vec, + indices: &mut MachineCodeIndex) +{ + indices.use_qualified_module(submodule, exports); + + if let &mut Some(ref mut module) = module { + module.use_qualified_module(submodule, exports); } - if let Some(mut module) = module { - module.code_dir.extend(as_module_code_dir(code_dir)); - module.op_dir.extend(op_dir.into_iter()); + // self.wam.use_qualified_module_in_toplevel(name, exports); +} + +pub fn compile_listing(wam: &mut Machine, src_str: &str) -> EvalSession { + let mut indices = machine_code_index!(&mut CodeDir::new(), &mut default_op_dir()); - wam.add_module(module, code); - } else { - wam.add_batched_code(code, code_dir); - wam.add_batched_ops(op_dir); + let mut worker = TopLevelBatchWorker::new(src_str.as_bytes(), wam.atom_tbl()); + let mut compiler = ListingCompiler::new(wam); + + while let Some(decl) = try_eval_session!(worker.consume(&mut indices)) { + match decl { + Declaration::Op(op_decl) => + try_eval_session!(op_decl.submit(compiler.get_module_name(), &mut indices.op_dir)), + Declaration::UseModule(name) => + if let Some(ref submodule) = compiler.wam.get_module(name.clone()) { + use_module(&mut compiler.module, submodule, &mut indices); + } else { + return EvalSession::from(SessionError::ModuleNotFound); + }, + Declaration::UseQualifiedModule(name, exports) => + if let Some(ref submodule) = compiler.wam.get_module(name.clone()) { + use_qualified_module(&mut compiler.module, submodule, &exports, &mut indices); + } else { + return EvalSession::from(SessionError::ModuleNotFound); + }, + Declaration::Module(module_decl) => + if compiler.module.is_none() { + worker.source_mod = module_decl.name.clone(); + compiler.module = Some(Module::new(module_decl)); + } else { + return EvalSession::from(ParserError::InvalidModuleDecl); + } + } } + let code = try_eval_session!(compiler.gen_code(worker.results, &mut indices.code_dir)); + compiler.add_code(code, indices); + EvalSession::EntrySuccess } diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index cb1799ad..984d1dc2 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -1235,14 +1235,16 @@ impl MachineState { } fn compare_numbers(&mut self, cmp: CompareNumberQT, n1: Number, n2: Number) { + let ordering = n1.cmp(&n2); + self.fail = match cmp { - CompareNumberQT::GreaterThan if !(n1.gt(n2)) => true, - CompareNumberQT::GreaterThanOrEqual if !(n1.gte(n2)) => true, - CompareNumberQT::LessThan if !(n1.lt(n2)) => true, - CompareNumberQT::LessThanOrEqual if !(n1.lte(n2)) => true, - CompareNumberQT::NotEqual if !(n1.ne(n2)) => true, - CompareNumberQT::Equal if !(n1.eq(n2)) => true, - _ => false + CompareNumberQT::GreaterThan if ordering == Ordering::Greater => false, + CompareNumberQT::GreaterThanOrEqual if ordering != Ordering::Less => false, + CompareNumberQT::LessThan if ordering == Ordering::Less => false, + CompareNumberQT::LessThanOrEqual if ordering != Ordering::Greater => false, + CompareNumberQT::NotEqual if ordering != Ordering::Equal => false, + CompareNumberQT::Equal if ordering == Ordering::Equal => false, + _ => true }; self.p += 1; diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 888ddfe9..cac185c9 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -20,7 +20,7 @@ use std::rc::Rc; pub struct MachineCodeIndex<'a> { pub code_dir: &'a mut CodeDir, pub op_dir: &'a mut OpDir, - pub modules: &'a ModuleDir +// pub modules: &'a ModuleDir } impl<'a> MachineCodeIndex<'a> { @@ -111,13 +111,14 @@ impl Machine { cached_query: None }; - compile_listing(&mut wam, BUILTINS); - wam.use_module_in_toplevel(clause_name!("builtins")); + compile_listing(&mut wam, BUILTINS); compile_listing(&mut wam, LISTS); compile_listing(&mut wam, CONTROL); compile_listing(&mut wam, QUEUES); + wam.use_module_in_toplevel(clause_name!("builtins")); + wam } @@ -182,8 +183,8 @@ impl Machine { if let Some(mut module) = self.modules.remove(&name) { let result = { - let mut indices = machine_code_index!(&mut self.code_dir, &mut self.op_dir, - &self.modules); + let mut indices = machine_code_index!(&mut self.code_dir, &mut self.op_dir); + //&self.modules); indices.use_qualified_module(&mut module, &exports) }; @@ -200,8 +201,8 @@ impl Machine { if let Some(mut module) = self.modules.remove(&name) { let result = { - let mut indices = machine_code_index!(&mut self.code_dir, &mut self.op_dir, - &self.modules); + let mut indices = machine_code_index!(&mut self.code_dir, &mut self.op_dir); + //&self.modules); indices.use_module(&mut module) }; diff --git a/src/prolog/macros.rs b/src/prolog/macros.rs index 4f376140..f3bb0d50 100644 --- a/src/prolog/macros.rs +++ b/src/prolog/macros.rs @@ -234,8 +234,8 @@ macro_rules! set_code_index { } macro_rules! machine_code_index { - ($code_dir:expr, $op_dir:expr, $modules:expr) => ( - MachineCodeIndex { code_dir: $code_dir, op_dir: $op_dir, modules: $modules } + ($code_dir:expr, $op_dir:expr) => ( //, $modules:expr) => ( + MachineCodeIndex { code_dir: $code_dir, op_dir: $op_dir } //, modules: $modules } ) } diff --git a/src/prolog/toplevel.rs b/src/prolog/toplevel.rs index 982543bf..3fac73ca 100644 --- a/src/prolog/toplevel.rs +++ b/src/prolog/toplevel.rs @@ -212,9 +212,8 @@ fn merge_clauses(tls: &mut VecDeque) -> Result } } -fn append_preds(preds: &mut Vec) -> TopLevel { - let preds = mem::replace(preds, vec![]); - TopLevel::Predicate(Predicate(preds)) +fn append_preds(preds: &mut Vec) -> Predicate { + Predicate(mem::replace(preds, vec![])) } fn unfold_by_str_once(term: &mut Term, s: &str) -> Option<(Term, Term)> @@ -295,13 +294,12 @@ pub enum TopLevelPacket { } struct RelationWorker { - queue: VecDeque>, - source_mod: ClauseName + queue: VecDeque> } impl RelationWorker { - fn new(source_mod: ClauseName) -> Self { - RelationWorker { queue: VecDeque::new(), source_mod } + fn new() -> Self { + RelationWorker { queue: VecDeque::new() } } fn compute_head(&self, term: &Term) -> Vec @@ -393,7 +391,8 @@ impl RelationWorker { self.fabricate_rule(fold_by_str(prec_seq, body_term, comma_sym)) } - fn to_query_term(&mut self, indices: &mut MachineCodeIndex, term: Term) -> Result + fn to_query_term(&mut self, indices: &mut MachineCodeIndex, term: Term) + -> Result { match term { Term::Constant(r, Constant::Atom(name)) => @@ -562,7 +561,7 @@ impl RelationWorker { } } -pub struct TopLevelWorker<'a, R> where R: Read { +pub struct TopLevelWorker<'a, R: Read> { pub parser: Parser, indices: MachineCodeIndex<'a> } @@ -572,72 +571,9 @@ impl<'a, R: Read> TopLevelWorker<'a, R> { TopLevelWorker { parser: Parser::new(inner, atom_tbl), indices } } - fn add_predicate(&mut self, tl: TopLevel) -> Vec + pub fn parse_code(&mut self) -> Result { - match tl { - TopLevel::Rule(rule) => vec![PredicateClause::Rule(rule)], - TopLevel::Fact(fact) => vec![PredicateClause::Fact(fact)], - TopLevel::Predicate(preds) => preds.0, - _ => vec![] - } - } - - pub fn parse_batch(&mut self, source_mod: ClauseName) -> Result, SessionError> - { - let mut preds = vec![]; - let mut results = vec![]; - let mut mod_name = clause_name!("user"); - let mut rel_worker = RelationWorker::new(source_mod.clone()); - - while !self.parser.eof() { - self.parser.reset(); // empty the parser stack of token descriptions. - let term = self.parser.read_term(&self.indices.op_dir)?; - - let mut new_rel_worker = RelationWorker::new(source_mod.clone()); - let tl = new_rel_worker.try_term_to_tl(&mut self.indices, term, true)?; - - if !is_consistent(&tl, &preds) { // if is_consistent returns false, preds is non-empty. - let result_queue = rel_worker.parse_queue(&mut self.indices)?; - results.push(deque_to_packet(append_preds(&mut preds), result_queue)); - } - - rel_worker.absorb(new_rel_worker); - - match tl { - TopLevel::Declaration(Declaration::UseModule(name)) => - if let Some(module) = self.indices.modules.get(&name) { - self.indices.use_module(module); - }, - TopLevel::Declaration(Declaration::Op(op_decl)) => { - op_decl.submit(mod_name.clone(), self.indices.op_dir)?; - }, - TopLevel::Declaration(Declaration::Module(actual_mod)) => { - mod_name = actual_mod.name.clone(); - let tl = TopLevel::Declaration(Declaration::Module(actual_mod)); - results.push(TopLevelPacket::Decl(tl, vec![])); - }, - TopLevel::Declaration(decl) => { - results.push(TopLevelPacket::Decl(TopLevel::Declaration(decl), vec![])); - }, - tl => if tl.name().is_some() { - preds.extend(self.add_predicate(tl)) - } else { - return Err(SessionError::NamelessEntry) - } - }; - } - - if !preds.is_empty() { - results.push(deque_to_packet(append_preds(&mut preds), - rel_worker.parse_queue(&mut self.indices)?)); - } - - Ok(results) - } - - pub fn parse_code(&mut self, source_mod: ClauseName) -> Result - { - let mut rel_worker = RelationWorker::new(source_mod); + let mut rel_worker = RelationWorker::new(); let terms = self.parser.read(self.indices.op_dir)?; let mut tls = rel_worker.try_terms_to_tls(&mut self.indices, terms, true)?; @@ -659,3 +595,55 @@ impl<'a, R: Read> TopLevelWorker<'a, R> { } } } + +pub struct TopLevelBatchWorker { + parser: Parser, + rel_worker: RelationWorker, + pub source_mod: ClauseName, + pub results: Vec<(Predicate, VecDeque)> +} + +impl TopLevelBatchWorker { + pub fn new(inner: R, atom_tbl: TabledData) -> Self { + TopLevelBatchWorker { parser: Parser::new(inner, atom_tbl), + rel_worker: RelationWorker::new(), + source_mod: clause_name!("user"), + results: vec![] } + } + + pub + fn consume(&mut self, indices: &mut MachineCodeIndex) -> Result, SessionError> + { + let mut preds = vec![]; + + while !self.parser.eof() { + self.parser.reset(); // empty the parser stack of token descriptions. + + let mut new_rel_worker = RelationWorker::new(); + let term = self.parser.read_term(&indices.op_dir)?; + let tl = new_rel_worker.try_term_to_tl(indices, term, true)?; + + if !is_consistent(&tl, &preds) { // if is_consistent returns false, preds is non-empty. + let result_queue = self.rel_worker.parse_queue(indices)?; + self.results.push((append_preds(&mut preds), result_queue)); + } + + self.rel_worker.absorb(new_rel_worker); + + match tl { + TopLevel::Fact(fact) => preds.push(PredicateClause::Fact(fact)), + TopLevel::Rule(rule) => preds.push(PredicateClause::Rule(rule)), + TopLevel::Predicate(pred) => preds.extend(pred.0), + TopLevel::Declaration(decl) => return Ok(Some(decl)), + TopLevel::Query(_) => return Err(SessionError::NamelessEntry) + } + } + + if !preds.is_empty() { + let result_queue = self.rel_worker.parse_queue(indices)?; + self.results.push((append_preds(&mut preds), result_queue)); + } + + Ok(None) + } +} diff --git a/src/tests.rs b/src/tests.rs index 555270cd..d0d811a1 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1270,7 +1270,9 @@ fn test_queries_on_conditionals() fn test_queries_on_builtins() { let mut wam = Machine::new(); + wam.use_module_in_toplevel(clause_name!("lists")); + wam.use_module_in_toplevel(clause_name!("control")); assert_prolog_failure!(&mut wam, "?- atom(X)."); assert_prolog_success!(&mut wam, "?- atom(a)."); @@ -1333,8 +1335,8 @@ fn test_queries_on_builtins() 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, "?- 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 = \"sdf\""]]); -- 2.54.0