address issues #114, #115

This commit is contained in:
Mark Thom
2019-04-25 09:10:52 -06:00
parent 18a9a6434f
commit b07a19fc47
5 changed files with 52 additions and 34 deletions

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "scryer-prolog" name = "scryer-prolog"
version = "0.8.63" version = "0.8.64"
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

@@ -769,6 +769,7 @@ char_code(Char, Code) :-
get_char(C) :- get_char(C) :-
( var(C) -> '$get_char'(C) ( var(C) -> '$get_char'(C)
; C == end_of_file -> '$get_char'(C)
; atom_length(C, 1) -> '$get_char'(C) ; atom_length(C, 1) -> '$get_char'(C)
; throw(error(type_error(in_character, C), get_char/1)) ; throw(error(type_error(in_character, C), get_char/1))
). ).

View File

@@ -619,7 +619,7 @@ pub(crate) trait CallPolicy: Any {
return_from_clause!(machine_st.last_call, machine_st) return_from_clause!(machine_st.last_call, machine_st)
}, },
&BuiltInClauseType::Functor => { &BuiltInClauseType::Functor => {
machine_st.try_functor(&indices.op_dir)?; machine_st.try_functor(&indices)?;
return_from_clause!(machine_st.last_call, machine_st) return_from_clause!(machine_st.last_call, machine_st)
}, },
&BuiltInClauseType::NotEq => { &BuiltInClauseType::NotEq => {

View File

@@ -1,5 +1,6 @@
use prolog_parser::ast::*; use prolog_parser::ast::*;
use prolog_parser::string_list::StringList; use prolog_parser::string_list::StringList;
use prolog_parser::tabled_rc::*;
use prolog::clause_types::*; use prolog::clause_types::*;
use prolog::forms::*; use prolog::forms::*;
@@ -191,7 +192,7 @@ impl MachineState {
-> Outputter -> Outputter
where Outputter: HCValueOutputter where Outputter: HCValueOutputter
{ {
let orig_len = output.len(); let orig_len = output.len();
output.begin_new_var(); output.begin_new_var();
@@ -204,7 +205,7 @@ impl MachineState {
printer.quoted = true; printer.quoted = true;
let mut output = printer.print(addr); let mut output = printer.print(addr);
let bad_ending = format!("= {}", &var); let bad_ending = format!("= {}", &var);
if output.ends_with(&bad_ending) { if output.ends_with(&bad_ending) {
@@ -702,7 +703,7 @@ impl MachineState {
Ok(Rc::new(Ratio::from_integer((*bi).clone()))) Ok(Rc::new(Ratio::from_integer((*bi).clone())))
} }
} }
fn get_rational(&mut self, at: &ArithmeticTerm, caller: &MachineStub) fn get_rational(&mut self, at: &ArithmeticTerm, caller: &MachineStub)
-> Result<Rc<Ratio<BigInt>>, MachineStub> -> Result<Rc<Ratio<BigInt>>, MachineStub>
{ {
@@ -857,12 +858,12 @@ impl MachineState {
(Number::Integer(_), n) | (n, _) => { (Number::Integer(_), n) | (n, _) => {
let n = Addr::Con(Constant::Number(n)); let n = Addr::Con(Constant::Number(n));
let stub = MachineError::functor_stub(clause_name!("^"), 2); let stub = MachineError::functor_stub(clause_name!("^"), 2);
Err(self.error_form(MachineError::type_error(ValidType::Integer, n), stub)) Err(self.error_form(MachineError::type_error(ValidType::Integer, n), stub))
} }
} }
} }
fn pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> fn pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub>
{ {
match n1.pow(n2) { match n1.pow(n2) {
@@ -2049,7 +2050,29 @@ impl MachineState {
self.try_functor_unify_components(name, arity); self.try_functor_unify_components(name, arity);
} }
pub(super) fn try_functor(&mut self, op_dir: &OpDir) -> CallResult { fn try_functor_fabricate_struct(&mut self, name: ClauseName, arity: isize,
spec: Option<SharedOpDesc>, op_dir: &OpDir,
r: Ref)
{
let spec = fetch_atom_op_spec(name.clone(), spec, op_dir);
let f_a = if name.as_str() == "." && arity == 2 {
Addr::Lis(self.heap.h)
} else {
let h = self.heap.h;
self.heap.push(HeapCellValue::NamedStr(arity as usize, name, spec));
Addr::Str(h)
};
for _ in 0 .. arity {
let h = self.heap.h;
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
}
self.bind(r, f_a);
}
pub(super) fn try_functor(&mut self, indices: &IndexStore) -> CallResult {
let stub = MachineError::functor_stub(clause_name!("functor"), 3); let stub = MachineError::functor_stub(clause_name!("functor"), 3);
let a1 = self.store(self.deref(self[temp_v!(1)].clone())); let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
@@ -2061,13 +2084,13 @@ impl MachineState {
Addr::Str(o) => Addr::Str(o) =>
match self.heap[o].clone() { match self.heap[o].clone() {
HeapCellValue::NamedStr(arity, name, spec) => { HeapCellValue::NamedStr(arity, name, spec) => {
let spec = fetch_op_spec(name.clone(), arity, spec, op_dir); let spec = fetch_op_spec(name.clone(), arity, spec, &indices.op_dir);
self.try_functor_compound_case(name, arity, spec) self.try_functor_compound_case(name, arity, spec)
}, },
_ => self.fail = true _ => self.fail = true
}, },
Addr::Lis(_) => { Addr::Lis(_) => {
let shared_op_desc = fetch_op_spec(clause_name!("."), 2, None, op_dir); let shared_op_desc = fetch_op_spec(clause_name!("."), 2, None, &indices.op_dir);
self.try_functor_compound_case(clause_name!("."), 2, shared_op_desc) self.try_functor_compound_case(clause_name!("."), 2, shared_op_desc)
}, },
Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(..) => { Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(..) => {
@@ -2101,23 +2124,13 @@ impl MachineState {
match name { match name {
Addr::Con(_) if arity == 0 => Addr::Con(_) if arity == 0 =>
self.unify(a1, name), self.unify(a1, name),
Addr::Con(Constant::Atom(name, spec)) => { Addr::Con(Constant::Atom(name, spec)) =>
let spec = fetch_atom_op_spec(name.clone(), spec, op_dir); self.try_functor_fabricate_struct(name, arity, spec, &indices.op_dir,
a1.as_var().unwrap()),
let f_a = if name.as_str() == "." && arity == 2 { Addr::Con(Constant::Char(c)) => {
Addr::Lis(self.heap.h) let name = clause_name!(c.to_string(), indices.atom_tbl);
} else { self.try_functor_fabricate_struct(name, arity, None, &indices.op_dir,
let h = self.heap.h; a1.as_var().unwrap());
self.heap.push(HeapCellValue::NamedStr(arity as usize, name, spec));
Addr::Str(h)
};
for _ in 0 .. arity {
let h = self.heap.h;
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
}
self.unify(a1, f_a);
}, },
Addr::Con(_) => Addr::Con(_) =>
return Err(self.error_form(MachineError::type_error(ValidType::Atom, name), return Err(self.error_form(MachineError::type_error(ValidType::Atom, name),
@@ -2621,7 +2634,7 @@ impl MachineState {
pub(super) pub(super)
fn sink_to_snapshot(&mut self) -> MachineState { fn sink_to_snapshot(&mut self) -> MachineState {
let mut snapshot = MachineState::with_capacity(0); let mut snapshot = MachineState::with_capacity(0);
snapshot.hb = self.hb; snapshot.hb = self.hb;
snapshot.e = self.e; snapshot.e = self.e;
snapshot.b = self.b; snapshot.b = self.b;
@@ -2634,7 +2647,7 @@ impl MachineState {
snapshot.fail = self.fail; snapshot.fail = self.fail;
snapshot.trail = mem::replace(&mut self.trail, vec![]); snapshot.trail = mem::replace(&mut self.trail, vec![]);
snapshot.pstr_trail = mem::replace(&mut self.pstr_trail, vec![]); snapshot.pstr_trail = mem::replace(&mut self.pstr_trail, vec![]);
snapshot.heap = self.heap.take(); snapshot.heap = self.heap.take();
snapshot.mode = self.mode; snapshot.mode = self.mode;
snapshot.and_stack = self.and_stack.take(); snapshot.and_stack = self.and_stack.take();
snapshot.or_stack = self.or_stack.take(); snapshot.or_stack = self.or_stack.take();

View File

@@ -323,7 +323,7 @@ impl MachineState {
Err(err) Err(err)
} }
} }
pub(super) fn system_call(&mut self, pub(super) fn system_call(&mut self,
ct: &SystemClauseType, ct: &SystemClauseType,
indices: &mut IndexStore, indices: &mut IndexStore,
@@ -573,13 +573,17 @@ impl MachineState {
match result { match result {
Some(Ok(b)) => self.unify(Addr::Con(Constant::Char(b as char)), a1), Some(Ok(b)) => self.unify(Addr::Con(Constant::Char(b as char)), a1),
_ => { Some(Err(_)) => {
let end_of_file = clause_name!("end_of_file");
self.unify(a1, Addr::Con(Constant::Atom(end_of_file, None)));
},
None => {
let stub = MachineError::functor_stub(clause_name!("get_char"), 1); let stub = MachineError::functor_stub(clause_name!("get_char"), 1);
let err = MachineError::representation_error(RepFlag::Character); let err = MachineError::representation_error(RepFlag::Character);
let err = self.error_form(err, stub); let err = self.error_form(err, stub);
return Err(err); return Err(err);
} },
} }
}, },
&SystemClauseType::GetModuleClause => { &SystemClauseType::GetModuleClause => {