@@ -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."
|
||||||
|
|||||||
@@ -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))
|
||||||
).
|
).
|
||||||
|
|||||||
@@ -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 => {
|
||||||
|
|||||||
@@ -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::*;
|
||||||
@@ -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),
|
||||||
|
|||||||
@@ -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 => {
|
||||||
|
|||||||
Reference in New Issue
Block a user