]> Repositorios git - scryer-prolog.git/commitdiff
make *.pl files in src/prolog/lib available from libraries.rs
authorMark Thom <[email protected]>
Fri, 27 Sep 2019 05:10:04 +0000 (23:10 -0600)
committerMark Thom <[email protected]>
Fri, 27 Sep 2019 05:10:04 +0000 (23:10 -0600)
19 files changed:
Cargo.toml
build.rs [new file with mode: 0644]
src/prolog/examples/domain.pl
src/prolog/examples/expert_system.pl
src/prolog/examples/minatotask.pl
src/prolog/examples/plres.pl
src/prolog/lib/assoc.pl
src/prolog/lib/atts.pl
src/prolog/lib/between.pl
src/prolog/lib/dcgs.pl
src/prolog/lib/diag.pl
src/prolog/lib/dif.pl
src/prolog/lib/freeze.pl
src/prolog/lib/ordsets.pl
src/prolog/lib/reif.pl
src/prolog/lib/terms.pl
src/prolog/machine/compile.rs
src/prolog/machine/mod.rs
src/prolog/read.rs

index 93ab38523fb1c26455a0521c0ff3b190de0f14ff..4f3145fe4ec53074cb9b5607658949d6a023c955 100644 (file)
@@ -1,11 +1,15 @@
 [package]
 name = "scryer-prolog"
-version = "0.8.94"
+version = "0.8.95"
 authors = ["Mark Thom <[email protected]>"]
+build = "build.rs"
 repository = "https://github.com/mthom/scryer-prolog"
 description = "A modern Prolog implementation written mostly in Rust."
 license = "BSD-3-Clause"
 
+[build-dependencies]
+indexmap = "1.0.2"
+
 [dependencies]
 cfg-if = "0.1.7"
 dirs = "2.0.2"
diff --git a/build.rs b/build.rs
new file mode 100644 (file)
index 0000000..bee7469
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,48 @@
+extern crate indexmap;
+
+use indexmap::IndexSet;
+
+use std::fs::{File, read_dir};
+use std::io::Write;
+use std::path::Path;
+
+fn main()
+{
+    let dest_path = Path::new("./src/prolog/machine/libraries.rs");
+
+    let mut libraries = File::create(&dest_path).unwrap();
+    let mut library_index = IndexSet::new();
+
+    let paths = read_dir("./src/prolog/lib").unwrap();
+
+    for item in paths {
+        let item = item.unwrap().path();
+
+        if item.is_file() {
+            if let Some(ext) = item.extension() {
+                if ext == "pl" {
+                    let file_stem = item.file_stem().unwrap();
+                    let file_str  = file_stem.to_string_lossy().to_uppercase();
+
+                    let include_line = format!("static {}: &str = include_str!(\"{}/{}.pl\");\n",
+                                               file_str, "../lib", file_stem.to_string_lossy());
+
+                    libraries.write_all(include_line.as_bytes()).unwrap();
+                    library_index.insert(file_stem.to_string_lossy().to_string());
+                }
+            }
+        }
+    }
+
+    libraries.write_all(b"\nref_thread_local! {
+    pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = {
+        let mut m = IndexMap::new();\n").unwrap();
+
+    for item in library_index {
+        let line = format!("\n        m.insert(\"{}\", {});", item, item.to_uppercase());
+        libraries.write_all(line.as_bytes()).unwrap();
+    }
+
+    libraries.write_all(b"\n\n        m\n    };
+}").unwrap();
+}
index f1fadad921d7d5475abe4604242495190c9a457f..cfada79f51c82f79f0d46995d2b17c5cbfadf607 100644 (file)
@@ -4,8 +4,8 @@ https://sicstus.sics.se/sicstus/docs/3.7.1/html/sicstus_17.html
 
 :- module(domain, [domain/2]).
 
-:- use_module('src/prolog/lib/atts').
-:- use_module('src/prolog/lib/ordsets', [
+:- use_module(library(atts)).
+:- use_module(library(ordsets), [
         ord_intersection/3,
         ord_intersect/2,
         list_to_ord_set/2
index 55b5d28712e65ba6dc339160d91ad9256b649dfb..43ba9bd76a53d1d5bf231052d791a85f2e1b9f28 100644 (file)
@@ -1,5 +1,5 @@
-:- use_module('src/prolog/lib/dcgs').
-:- use_module('src/prolog/lib/reif').
+:- use_module(library(dcgs)).
+:- use_module(library(reif)).
 
 animals([animal(dog, [is_true('has fur'), is_true('says woof')]),
          animal(cat, [is_true('has fur'), is_true('says meow')]),
index 2d0d4ff9c563604b0aff43f62971b8ce175cddff..fd1a4233a1ae033178ce9103814d9a0a5fb7abd2 100644 (file)
@@ -60,9 +60,9 @@
 
 :- module(zdd, [variables_set_zdd/2]).
 
-:- use_module('src/prolog/lib/atts').
-:- use_module('src/prolog/lib/dcgs').
-:- use_module('src/prolog/lib/lists').
+:- use_module(library(atts)).
+:- use_module(library(dcgs)).
+:- use_module(library(lists)).
 
 :- attribute zdd_vs/2.
 
index 3ccfc4090961fd7381da2db352666bf282e3bbe6..a19ca5a73a9dc7f6c86f5f6a70fc7020edbab801 100644 (file)
@@ -29,9 +29,9 @@
 
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 
-:- use_module('src/prolog/lib/dcgs').
-:- use_module('src/prolog/lib/dif').
-:- use_module('src/prolog/lib/lists').
+:- use_module(library(dcgs)).
+:- use_module(library(dif)).
+:- use_module(library(lists)).
 
 pl_resolution(Clauses0, Chain) :-
         maplist(sort, Clauses0, Clauses), % remove duplicates
index 7880a9e664fb50950b9264d2df10a5af857b506b..b99b1c4b0ec0e69aa39fd777f6cbd8d57a54e106 100644 (file)
@@ -52,7 +52,7 @@
             del_max_assoc/4             % +Assoc0, ?Key, ?Value, ?Assoc
           ]).
 
-:- use_module('src/prolog/lib/lists.pl').
+:- use_module(library(lists)).
 
 /** <module> Binary associations
 
index 1ea94277c8c2a760941e8762240455eeb2e92fa2..6f3b109b924f73d7a1cd4e0fed357536855b8f89 100644 (file)
@@ -4,8 +4,8 @@
                 '$add_to_list'/3, '$del_attr'/3, '$del_attr_step'/3,
                 '$del_attr_buried'/4]).
 
-:- use_module('src/prolog/lib/dcgs.pl').
-:- use_module('src/prolog/lib/terms.pl').
+:- use_module(library(dcgs)).
+:- use_module(library(terms)).
 
 :- op(1199, fx, attribute).
 
index 900909862772dfe765320b7c06b2761775871a1c..16c7314591f506be79898a2e5ebbc5373cfd1fea 100644 (file)
@@ -2,8 +2,8 @@
 
 %% TODO: numlist/5.
 
-:- use_module('src/prolog/lib/lists.pl', [length/2]).
-:- use_module('src/prolog/lib/error.pl').
+:- use_module(library(lists), [length/2]).
+:- use_module(library(error)).
 
 between(Lower, Upper, X) :-
     must_be(integer, Lower),
index fabd67b016680735b2b633964bd72a3fc50d8762..60fe71264f4dbe5089b1af094064f788f5bc108f 100644 (file)
@@ -2,8 +2,8 @@
 
 :- module(dcgs, [phrase/2, phrase/3]).
 
-:- use_module('src/prolog/lib/lists.pl', [append/3]).
-:- use_module('src/prolog/lib/terms.pl').
+:- use_module(library(lists), [append/3]).
+:- use_module(library(terms)).
 
 phrase(G, G) :-
     nonvar(G), G = [_|_], !.
index 8e4799edad842a5756d62b7ba6183f3df3367509..d135238bb7e70fdb53092e6153165ed3cd0cd1fb 100644 (file)
@@ -1,6 +1,6 @@
 :- module(diag, [wam_instructions/2]).
 
-:- use_module('src/prolog/lib/error').
+:- use_module(library(error)).
 
 wam_instructions(Clause, Listing) :-
     (  nonvar(Clause) ->
index cd779375ad50c4409df70a37ec5b1ac32d056058..991db075f6ed1d9ff32de014bcf0ea8cedf1d440 100644 (file)
@@ -1,7 +1,7 @@
 :- module(dif, [dif/2]).
 
-:- use_module('src/prolog/lib/atts.pl').
-:- use_module('src/prolog/lib/lists.pl', [append/3]).
+:- use_module(library(atts)).
+:- use_module(library(lists), [append/3]).
 
 :- attribute dif/1.
 
index 3fa4ef9149371eb933038cbbd9c31308215e1187..d3a92eaf24535515d460143955bbe79612f9c1ef 100644 (file)
@@ -1,6 +1,6 @@
 :- module(freeze, [freeze/2]).
 
-:- use_module('src/prolog/lib/atts.pl').
+:- use_module(library(atts)).
 
 :- attribute frozen/1.
 
index a97c609b8bb35fc2a5bd0c3058fce12d13e4f0c4..ff08096295e7c30bab404bddb2a67f531338cf79 100644 (file)
@@ -52,7 +52,7 @@
             ord_intersection/2          % +PowerSet, -Intersection
           ]).
 
-:- use_module('src/prolog/lib/lists.pl').
+:- use_module(library(lists)).
 
 /** <module> Ordered set manipulation
 Ordered sets are lists with unique elements sorted to the standard order
index 603d1188d431b04a611bc1d955e145cac05f445e..0e958356995c5491a297cefc0963a69735cd519d 100644 (file)
@@ -2,7 +2,7 @@
                 memberd_t/3, tfilter/3, tmember/2, tmember_t/3,
                 tpartition/4]).
 
-:- use_module('src/prolog/lib/dif.pl').
+:- use_module(library(dif)).
 
 if_(If_1, Then_0, Else_0) :-
     call(If_1, T),
index 9b3944600eb763fbab9545ba67b47cd91d2aa764..8391457b9c0b4b25ea6647432da019cbcf9e86f2 100644 (file)
@@ -1,6 +1,6 @@
 :- module(terms, [numbervars/3]).
 
-:- use_module('src/prolog/lib/error.pl').
+:- use_module(library(error)).
     
 numbervars(Term, N0, N) :-
    catch(internal_numbervars(Term, N0, N), error(E,Ctx),
index 071d8f49253c1caa5f08e24e1223ea658fd681d2..c6818c39a8e59014bc5c6a3d84c9b6822df24cbe 100644 (file)
@@ -14,6 +14,8 @@ use prolog::machine::*;
 
 use indexmap::{IndexMap, IndexSet};
 
+use ref_thread_local::RefThreadLocal;
+
 use std::cell::Cell;
 use std::collections::VecDeque;
 use std::fs::File;
@@ -54,16 +56,9 @@ fn fix_filename(atom_tbl: TabledData<Atom>, filename: &str) -> Result<PathBuf, S
     Ok(path)
 }
 
-fn load_module_from_file(wam: &mut Machine, filename: &str) -> Result<ClauseName, SessionError> {
-    let path = fix_filename(wam.indices.atom_tbl.clone(), filename)?;
-
-    let file_handle = File::open(&path).or_else(|_| {
-        let filename = clause_name!(path.to_string_lossy().to_string(), wam.indices.atom_tbl);
-        Err(SessionError::InvalidFileName(filename))
-    })?;
-
-    let file_src = parsing_stream(file_handle);
-
+fn load_module<R: Read>(wam: &mut Machine, name: &str, stream: ParsingStream<R>)
+                        -> Result<ClauseName, SessionError>
+{
     // follow the operation of compile_user_module, but before
     // compiling, check that a module is declared in the file. if not,
     // throw an exception.
@@ -71,21 +66,32 @@ fn load_module_from_file(wam: &mut Machine, filename: &str) -> Result<ClauseName
     setup_indices(wam, clause_name!("builtins"), &mut indices)?;
 
     let mut compiler = ListingCompiler::new(&wam.code_repo);
-    let results = compiler.gather_items(wam, file_src, &mut indices)?;
+    let results = compiler.gather_items(wam, stream, &mut indices)?;
 
     let module_name = if let Some(ref module) = &compiler.module {
         module.module_decl.name.clone()
     } else {
-        let module_name = path.to_string_lossy().to_string();
-        let module_name = clause_name!(module_name, wam.indices.atom_tbl);
-
+        let module_name = clause_name!(name.to_string(), wam.indices.atom_tbl);
         return Err(SessionError::NoModuleDeclaration(module_name));
     };
 
     match compile_work_impl(&mut compiler, wam, indices, results) {
         EvalSession::Error(e) => Err(e),
         _ => Ok(module_name),
-    }
+    }    
+}
+
+fn load_module_from_file(wam: &mut Machine, filename: &str) -> Result<ClauseName, SessionError>
+{
+    let path = fix_filename(wam.indices.atom_tbl.clone(), filename)?;
+
+    let file_handle = File::open(&path).or_else(|_| {
+        let filename = clause_name!(path.to_string_lossy().to_string(), wam.indices.atom_tbl);
+        Err(SessionError::InvalidFileName(filename))
+    })?;
+
+    let file_stem = path.file_stem().unwrap().to_string_lossy();    
+    load_module(wam, &file_stem, parsing_stream(file_handle))
 }
 
 pub type PredicateCompileQueue = (Predicate, VecDeque<TopLevel>);
@@ -459,6 +465,13 @@ fn add_non_module_code(
     Ok(())
 }
 
+fn load_library(wam: &mut Machine, name: ClauseName) -> Result<ClauseName, SessionError> {
+    match LIBRARIES.borrow().get(name.as_str()) {
+        Some(code) => load_module(wam, name.as_str(), parsing_stream(code.as_bytes())),
+        None => Err(SessionError::ModuleNotFound)
+    }
+}
+
 impl ListingCompiler {
     #[inline]
     pub fn new(code_repo: &CodeRepo) -> Self {
@@ -702,17 +715,30 @@ impl ListingCompiler {
                 op_decl.submit(self.get_module_name(), spec, &mut indices.op_dir)
             }
             Declaration::UseModule(ModuleSource::Library(name)) => {
+                let name = if !wam.indices.modules.contains_key(&name) {
+                    load_library(wam, name)?
+                } else {
+                    name
+                };
+
                 self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices)
             }
-            Declaration::UseQualifiedModule(ModuleSource::Library(name), exports) => self
-                .use_qualified_module(
+            Declaration::UseQualifiedModule(ModuleSource::Library(name), exports) => {
+                let name = if !wam.indices.modules.contains_key(&name) {
+                    load_library(wam, name)?
+                } else {
+                    name
+                };
+
+                self.use_qualified_module(
                     name,
                     &mut wam.code_repo,
                     flags,
                     &exports,
                     &mut wam.indices,
-                    indices,
-                ),
+                    indices
+                )
+            },
             Declaration::Module(module_decl) => {
                 if self.module.is_none() {
                     let module_name = module_decl.name.clone();
index 73159f38d792abfc77f9e6821198bea0865d2726..2ed98032372a4db49df6b8c6018f80612d2bdbe9 100644 (file)
@@ -163,10 +163,8 @@ impl SubModuleUser for IndexStore {
     }
 }
 
-static BUILTINS: &str = include_str!("../lib/builtins.pl");
-static ERROR: &str = include_str!("../lib/error.pl");
-static LISTS: &str = include_str!("../lib/lists.pl");
-static NON_ISO: &str = include_str!("../lib/non_iso.pl");
+include!("libraries.rs");
+
 static TOPLEVEL: &str = include_str!("../toplevel.pl");
 
 impl Machine {
@@ -538,14 +536,13 @@ impl Machine {
                 self.throw_session_error(err, (clause_name!("repl"), 0));
                 return;
             }
-            EvalSession::QueryFailure => {
+            EvalSession::QueryFailure =>
                 if self.machine_st.ball.stub.len() > 0 {
                     return self.propagate_exception_to_toplevel(snapshot);
                 } else {
                     println!("false.");
-                }
-            }
-            _ => {}
+                },
+            _ => println!("true.")
         }
 
         self.machine_st.absorb_snapshot(snapshot);
index a56e957a2db8a0985dc6daf6fec4077648a4b517..b003bdda78dd03e9d250733c1d27c0d00ff8ba05 100644 (file)
@@ -45,7 +45,7 @@ pub mod readline {
             if PROMPT { "?- " } else { "" }
         }
     }
-    
+
     pub struct ReadlineStream {
         rl: Editor<()>,
         pending_input: String,
@@ -54,9 +54,7 @@ pub mod readline {
     impl ReadlineStream {
         fn input_stream(pending_input: String) -> Self {
             let mut rl = Editor::<()>::new();
-
             rl.bind_sequence(KeyPress::Tab, Cmd::Insert(1, "\t".to_string()));
-
             ReadlineStream { rl, pending_input }
         }
 
@@ -72,11 +70,11 @@ pub mod readline {
                         }
                     }
 
-                    self.pending_input += "\n";                    
+                    self.pending_input += "\n";
                     Ok(self.write_to_buf(buf))
                 }
                 Err(ReadlineError::Eof) =>
-                    Ok(self.write_to_buf(buf)),                
+                    Ok(self.write_to_buf(buf)),
                 Err(e) =>
                     Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, e))
             }