From: Mark Thom Date: Fri, 6 Sep 2019 04:43:50 +0000 (-0600) Subject: address issue #153 X-Git-Tag: v0.8.110~48 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=9d2ac9e2352813546f57c02d50c802c3873d2e24;p=scryer-prolog.git address issue #153 --- diff --git a/Cargo.toml b/Cargo.toml index 34c49552..7005232a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scryer-prolog" -version = "0.8.88" +version = "0.8.89" authors = ["Mark Thom "] repository = "https://github.com/mthom/scryer-prolog" description = "A modern Prolog implementation written mostly in Rust." diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index e093a1dd..b2898af0 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -675,9 +675,6 @@ current_predicate(Pred) :- -> throw(error(type_error(predicate_indicator, Pred), current_predicate/1)) ; '$get_next_db_ref'(Ref, _), '$iterate_db_refs'(Ref, Pred) - ; Pred = call/N, - max_arity(Max), - between:between(0, Max, N) ). '$iterate_op_db_refs'(Ref, Priority, Spec, Op) :- diff --git a/src/prolog/machine/machine_indices.rs b/src/prolog/machine/machine_indices.rs index 99a91998..9aad8050 100644 --- a/src/prolog/machine/machine_indices.rs +++ b/src/prolog/machine/machine_indices.rs @@ -21,7 +21,6 @@ pub type OssifiedOpDir = BTreeMap; #[derive(Clone, PartialEq, Eq, Hash)] pub enum DBRef { - BuiltInPred(ClauseName, usize, Option), NamedPred(ClauseName, usize, Option), Op(usize, Specifier, ClauseName, Rc, SharedOpDesc) } diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 9d6ef0e9..c8cbce26 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -153,9 +153,10 @@ 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"); 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 { fn compile_special_forms(&mut self) { @@ -229,7 +230,8 @@ impl Machine { wam.compile_special_forms(); 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())); wam.compile_scryerrc(); diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index d6015741..06fbffb0 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -15,8 +15,6 @@ use prolog::ordered_float::OrderedFloat; use prolog::read::{PrologStream, readline}; use prolog::rug::Integer; -use ref_thread_local::RefThreadLocal; - use std::collections::{HashMap, HashSet}; use std::io::{stdout, Write}; 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 { // a step in Brent's algorithm. fn brents_alg_step(&self, brent_st: &mut BrentAlgState) -> Option @@ -260,65 +265,31 @@ impl MachineState { fn get_next_db_ref(&mut self, indices: &IndexStore, db_ref: &DBRef) { 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, _) => { let key = (name.clone(), arity); + let mut iter = indices.code_dir.range(key ..).skip(1); - match indices.code_dir.range(key ..).skip(1).next() { - Some(((name, arity), idx)) => { - let a2 = self[temp_v!(2)].clone(); + while let Some(((name, arity), idx)) = iter.next() { + if idx.is_undefined() { + self.fail = true; + return; + } - if idx.is_undefined() { - self.fail = true; - return; - } + if is_builtin_predicate(&name) { + continue; + } - 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 + let a2 = self[temp_v!(2)].clone(); + + 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))); + return; + } } + + self.fail = true; }, &DBRef::Op(_, spec, ref name, ref op_dir, _) => { let fixity = match spec { @@ -900,19 +871,25 @@ impl MachineState { match self.store(self.deref(a1)) { addr @ Addr::HeapCell(_) | addr @ Addr::StackCell(..) - | addr @ Addr::AttrVar(_) => - match CLAUSE_TYPE_FORMS.borrow().iter().next() { - Some(((_, arity), ct)) => { - let db_ref = DBRef::BuiltInPred(ct.name(), *arity, ct.spec()); - let r = addr.as_var().unwrap(); - - self.bind(r, Addr::DBRef(db_ref)); - }, - None => { - self.fail = true; - return Ok(()); + | addr @ Addr::AttrVar(_) => { + let mut iter = indices.code_dir.iter(); + + while let Some(((name, arity), _)) = iter.next() { + if is_builtin_predicate(&name) { + continue; } - }, + + 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(ref 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, Addr::DBRef(ref db_ref) => self.get_next_db_ref(&indices, db_ref), @@ -976,7 +953,7 @@ impl MachineState { match self.store(self.deref(a1)) { Addr::DBRef(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 a3 = self[temp_v!(3)].clone(); diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index 15a3cc80..532291f9 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -1,9 +1,9 @@ -repl :- - catch(read_and_match, E, '$print_exception'(E)), +'$repl' :- + catch('$read_and_match', E, '$print_exception'(E)), false. %% this is for GC, until we get actual GC. -repl :- repl. +'$repl' :- '$repl'. -read_and_match :- +'$read_and_match' :- write_term('?- ', [quoted(false)]), read_term(Term, [variable_names(VarList)]), '$instruction_match'(Term, VarList). diff --git a/src/prolog/write.rs b/src/prolog/write.rs index df2400e6..c8f9d8e4 100644 --- a/src/prolog/write.rs +++ b/src/prolog/write.rs @@ -164,7 +164,6 @@ impl fmt::Display for HeapCellValue { impl fmt::Display for DBRef { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 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::Op(priority, spec, ref name, ..) => write!(f, "db_ref:op({}, {}, {})", priority, spec, name)