Skip to content

Commit

Permalink
make *.pl files in src/prolog/lib available from libraries.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Thom committed Sep 27, 2019
1 parent 2c1c1b7 commit 9a83ccb
Show file tree
Hide file tree
Showing 19 changed files with 130 additions and 57 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
[package]
name = "scryer-prolog"
version = "0.8.94"
version = "0.8.95"
authors = ["Mark Thom <markjordanthom@gmail.com>"]
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"
Expand Down
48 changes: 48 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -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();
}
4 changes: 2 additions & 2 deletions src/prolog/examples/domain.pl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

:- 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
Expand Down
4 changes: 2 additions & 2 deletions src/prolog/examples/expert_system.pl
Original file line number Diff line number Diff line change
@@ -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')]),
Expand Down
6 changes: 3 additions & 3 deletions src/prolog/examples/minatotask.pl
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
6 changes: 3 additions & 3 deletions src/prolog/examples/plres.pl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/prolog/lib/assoc.pl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/prolog/lib/atts.pl
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down
4 changes: 2 additions & 2 deletions src/prolog/lib/between.pl
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
4 changes: 2 additions & 2 deletions src/prolog/lib/dcgs.pl
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [_|_], !.
Expand Down
2 changes: 1 addition & 1 deletion src/prolog/lib/diag.pl
Original file line number Diff line number Diff line change
@@ -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) ->
Expand Down
4 changes: 2 additions & 2 deletions src/prolog/lib/dif.pl
Original file line number Diff line number Diff line change
@@ -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.

Expand Down
2 changes: 1 addition & 1 deletion src/prolog/lib/freeze.pl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
:- module(freeze, [freeze/2]).

:- use_module('src/prolog/lib/atts.pl').
:- use_module(library(atts)).

:- attribute frozen/1.

Expand Down
2 changes: 1 addition & 1 deletion src/prolog/lib/ordsets.pl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/prolog/lib/reif.pl
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
2 changes: 1 addition & 1 deletion src/prolog/lib/terms.pl
Original file line number Diff line number Diff line change
@@ -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),
Expand Down
64 changes: 45 additions & 19 deletions src/prolog/machine/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -54,38 +56,42 @@ 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.
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
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>);
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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();
Expand Down
13 changes: 5 additions & 8 deletions src/prolog/machine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 3 additions & 5 deletions src/prolog/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub mod readline {
if PROMPT { "?- " } else { "" }
}
}

pub struct ReadlineStream {
rl: Editor<()>,
pending_input: String,
Expand All @@ -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 }
}

Expand All @@ -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))
}
Expand Down

0 comments on commit 9a83ccb

Please sign in to comment.