address issue #153

This commit is contained in:
Mark Thom
2019-09-05 22:43:50 -06:00
parent 4b22f80a77
commit 9d2ac9e235
7 changed files with 56 additions and 82 deletions

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "scryer-prolog" name = "scryer-prolog"
version = "0.8.88" version = "0.8.89"
authors = ["Mark Thom <markjordanthom@gmail.com>"] authors = ["Mark Thom <markjordanthom@gmail.com>"]
repository = "https://github.com/mthom/scryer-prolog" repository = "https://github.com/mthom/scryer-prolog"
description = "A modern Prolog implementation written mostly in Rust." description = "A modern Prolog implementation written mostly in Rust."

View File

@@ -675,9 +675,6 @@ current_predicate(Pred) :-
-> throw(error(type_error(predicate_indicator, Pred), current_predicate/1)) -> throw(error(type_error(predicate_indicator, Pred), current_predicate/1))
; '$get_next_db_ref'(Ref, _), ; '$get_next_db_ref'(Ref, _),
'$iterate_db_refs'(Ref, Pred) '$iterate_db_refs'(Ref, Pred)
; Pred = call/N,
max_arity(Max),
between:between(0, Max, N)
). ).
'$iterate_op_db_refs'(Ref, Priority, Spec, Op) :- '$iterate_op_db_refs'(Ref, Priority, Spec, Op) :-

View File

@@ -21,7 +21,6 @@ pub type OssifiedOpDir = BTreeMap<OrderedOpDirKey, (usize, Specifier)>;
#[derive(Clone, PartialEq, Eq, Hash)] #[derive(Clone, PartialEq, Eq, Hash)]
pub enum DBRef { pub enum DBRef {
BuiltInPred(ClauseName, usize, Option<SharedOpDesc>),
NamedPred(ClauseName, usize, Option<SharedOpDesc>), NamedPred(ClauseName, usize, Option<SharedOpDesc>),
Op(usize, Specifier, ClauseName, Rc<OssifiedOpDir>, SharedOpDesc) Op(usize, Specifier, ClauseName, Rc<OssifiedOpDir>, SharedOpDesc)
} }

View File

@@ -153,9 +153,10 @@ impl SubModuleUser for IndexStore {
} }
static BUILTINS: &str = include_str!("../lib/builtins.pl"); 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");
static TOPLEVEL: &str = include_str!("../toplevel.pl"); static TOPLEVEL: &str = include_str!("../toplevel.pl");
static BETWEEN: &str = include_str!("../lib/between.pl");
static NON_ISO: &str = include_str!("../lib/non_iso.pl");
impl Machine { impl Machine {
fn compile_special_forms(&mut self) { fn compile_special_forms(&mut self) {
@@ -229,7 +230,8 @@ impl Machine {
wam.compile_special_forms(); wam.compile_special_forms();
wam.compile_top_level(); wam.compile_top_level();
compile_user_module(&mut wam, parsing_stream(BETWEEN.as_bytes())); compile_user_module(&mut wam, parsing_stream(ERROR.as_bytes()));
compile_user_module(&mut wam, parsing_stream(LISTS.as_bytes()));
compile_user_module(&mut wam, parsing_stream(NON_ISO.as_bytes())); compile_user_module(&mut wam, parsing_stream(NON_ISO.as_bytes()));
wam.compile_scryerrc(); wam.compile_scryerrc();

View File

@@ -15,8 +15,6 @@ use prolog::ordered_float::OrderedFloat;
use prolog::read::{PrologStream, readline}; use prolog::read::{PrologStream, readline};
use prolog::rug::Integer; use prolog::rug::Integer;
use ref_thread_local::RefThreadLocal;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::io::{stdout, Write}; use std::io::{stdout, Write};
use std::iter::once; use std::iter::once;
@@ -36,6 +34,13 @@ impl BrentAlgState {
} }
} }
fn is_builtin_predicate(name: &ClauseName) -> bool {
let in_builtins = name.owning_module().as_str() == "builtins";
let hidden_name = name.as_str().starts_with("$");
in_builtins || hidden_name
}
impl MachineState { impl MachineState {
// a step in Brent's algorithm. // a step in Brent's algorithm.
fn brents_alg_step(&self, brent_st: &mut BrentAlgState) -> Option<CycleSearchResult> fn brents_alg_step(&self, brent_st: &mut BrentAlgState) -> Option<CycleSearchResult>
@@ -260,65 +265,31 @@ impl MachineState {
fn get_next_db_ref(&mut self, indices: &IndexStore, db_ref: &DBRef) { fn get_next_db_ref(&mut self, indices: &IndexStore, db_ref: &DBRef) {
match db_ref { match db_ref {
&DBRef::BuiltInPred(ref name, arity, _) => {
let key = (name.as_str(), arity);
match CLAUSE_TYPE_FORMS.borrow().range(&key ..).skip(1).next() {
Some(((_, arity), ct)) => {
let a2 = self[temp_v!(2)].clone();
if let Some(r) = a2.as_var() {
self.bind(r, Addr::DBRef(DBRef::BuiltInPred(ct.name(), *arity, ct.spec())));
} else {
self.fail = true;
}
},
None =>
match indices.code_dir.iter().next() {
Some(((ref name, arity), idx)) => {
let a2 = self[temp_v!(2)].clone();
if idx.is_undefined() {
self.fail = true;
return;
}
if let Some(r) = a2.as_var() {
let spec = get_clause_spec(name.clone(), *arity,
composite_op!(&indices.op_dir));
self.bind(r, Addr::DBRef(DBRef::NamedPred(name.clone(), *arity, spec)));
} else {
self.fail = true;
}
},
None => {
self.fail = true;
}
}
}
},
&DBRef::NamedPred(ref name, arity, _) => { &DBRef::NamedPred(ref name, arity, _) => {
let key = (name.clone(), arity); let key = (name.clone(), arity);
let mut iter = indices.code_dir.range(key ..).skip(1);
match indices.code_dir.range(key ..).skip(1).next() { while let Some(((name, arity), idx)) = iter.next() {
Some(((name, arity), idx)) => { if idx.is_undefined() {
let a2 = self[temp_v!(2)].clone(); self.fail = true;
return;
}
if idx.is_undefined() { if is_builtin_predicate(&name) {
self.fail = true; continue;
return; }
}
if let Some(r) = a2.as_var() { let a2 = self[temp_v!(2)].clone();
let spec = get_clause_spec(name.clone(), *arity,
composite_op!(&indices.op_dir)); if let Some(r) = a2.as_var() {
self.bind(r, Addr::DBRef(DBRef::NamedPred(name.clone(), *arity, spec))); let spec = get_clause_spec(name.clone(), *arity,
} else { composite_op!(&indices.op_dir));
self.fail = true; self.bind(r, Addr::DBRef(DBRef::NamedPred(name.clone(), *arity, spec)));
} return;
}, }
None => self.fail = true
} }
self.fail = true;
}, },
&DBRef::Op(_, spec, ref name, ref op_dir, _) => { &DBRef::Op(_, spec, ref name, ref op_dir, _) => {
let fixity = match spec { let fixity = match spec {
@@ -900,19 +871,25 @@ impl MachineState {
match self.store(self.deref(a1)) { match self.store(self.deref(a1)) {
addr @ Addr::HeapCell(_) addr @ Addr::HeapCell(_)
| addr @ Addr::StackCell(..) | addr @ Addr::StackCell(..)
| addr @ Addr::AttrVar(_) => | addr @ Addr::AttrVar(_) => {
match CLAUSE_TYPE_FORMS.borrow().iter().next() { let mut iter = indices.code_dir.iter();
Some(((_, arity), ct)) => {
let db_ref = DBRef::BuiltInPred(ct.name(), *arity, ct.spec()); while let Some(((name, arity), _)) = iter.next() {
let r = addr.as_var().unwrap(); if is_builtin_predicate(&name) {
continue;
self.bind(r, Addr::DBRef(db_ref));
},
None => {
self.fail = true;
return Ok(());
} }
},
let spec = get_clause_spec(name.clone(), *arity,
composite_op!(&indices.op_dir));
let db_ref = DBRef::NamedPred(name.clone(), *arity, spec);
let r = addr.as_var().unwrap();
self.bind(r, Addr::DBRef(db_ref));
return return_from_clause!(self.last_call, self);
}
self.fail = true;
},
Addr::DBRef(DBRef::Op(..)) => self.fail = true, Addr::DBRef(DBRef::Op(..)) => self.fail = true,
Addr::DBRef(ref db_ref) => Addr::DBRef(ref db_ref) =>
self.get_next_db_ref(&indices, db_ref), self.get_next_db_ref(&indices, db_ref),
@@ -961,7 +938,7 @@ impl MachineState {
} }
} }
}, },
Addr::DBRef(DBRef::BuiltInPred(..)) | Addr::DBRef(DBRef::NamedPred(..)) => Addr::DBRef(DBRef::NamedPred(..)) =>
self.fail = true, self.fail = true,
Addr::DBRef(ref db_ref) => Addr::DBRef(ref db_ref) =>
self.get_next_db_ref(&indices, db_ref), self.get_next_db_ref(&indices, db_ref),
@@ -976,7 +953,7 @@ impl MachineState {
match self.store(self.deref(a1)) { match self.store(self.deref(a1)) {
Addr::DBRef(db_ref) => Addr::DBRef(db_ref) =>
match db_ref { match db_ref {
DBRef::BuiltInPred(name, arity, spec) | DBRef::NamedPred(name, arity, spec) => { DBRef::NamedPred(name, arity, spec) => {
let a2 = self[temp_v!(2)].clone(); let a2 = self[temp_v!(2)].clone();
let a3 = self[temp_v!(3)].clone(); let a3 = self[temp_v!(3)].clone();

View File

@@ -1,9 +1,9 @@
repl :- '$repl' :-
catch(read_and_match, E, '$print_exception'(E)), catch('$read_and_match', E, '$print_exception'(E)),
false. %% this is for GC, until we get actual GC. false. %% this is for GC, until we get actual GC.
repl :- repl. '$repl' :- '$repl'.
read_and_match :- '$read_and_match' :-
write_term('?- ', [quoted(false)]), write_term('?- ', [quoted(false)]),
read_term(Term, [variable_names(VarList)]), read_term(Term, [variable_names(VarList)]),
'$instruction_match'(Term, VarList). '$instruction_match'(Term, VarList).

View File

@@ -164,7 +164,6 @@ impl fmt::Display for HeapCellValue {
impl fmt::Display for DBRef { impl fmt::Display for DBRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
&DBRef::BuiltInPred(ref name, arity, _) => write!(f, "db_ref:builtin:{}/{}", name, arity),
&DBRef::NamedPred(ref name, arity, _) => write!(f, "db_ref:named:{}/{}", name, arity), &DBRef::NamedPred(ref name, arity, _) => write!(f, "db_ref:named:{}/{}", name, arity),
&DBRef::Op(priority, spec, ref name, ..) => write!(f, "db_ref:op({}, {}, {})", priority, &DBRef::Op(priority, spec, ref name, ..) => write!(f, "db_ref:op({}, {}, {})", priority,
spec, name) spec, name)