add atts.pl, various fixes
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -86,8 +86,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prolog_parser"
|
name = "prolog_parser"
|
||||||
version = "0.7.22"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -108,12 +107,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rusty-wam"
|
name = "rusty-wam"
|
||||||
version = "0.7.17"
|
version = "0.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"prolog_parser 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"prolog_parser 0.8.0",
|
||||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -152,7 +151,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
|
"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
|
||||||
"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
|
"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
|
||||||
"checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
|
"checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
|
||||||
"checksum prolog_parser 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "73457bb9d32e6c60048f7cb10f41ed6f9d07053bccd188ff14f79e0af3046789"
|
|
||||||
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
|
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
|
||||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rusty-wam"
|
name = "rusty-wam"
|
||||||
version = "0.7.17"
|
version = "0.8.0"
|
||||||
authors = ["Mark Thom <markjordanthom@gmail.com>"]
|
authors = ["Mark Thom <markjordanthom@gmail.com>"]
|
||||||
repository = "https://github.com/mthom/rusty-wam"
|
repository = "https://github.com/mthom/rusty-wam"
|
||||||
description = "The Warren Abstract Machine in Rust."
|
description = "The Warren Abstract Machine in Rust."
|
||||||
@@ -10,7 +10,7 @@ license = "BSD-3-Clause"
|
|||||||
downcast = "0.9.1"
|
downcast = "0.9.1"
|
||||||
num = "0.2"
|
num = "0.2"
|
||||||
ordered-float = "0.5.0"
|
ordered-float = "0.5.0"
|
||||||
prolog_parser = "0.7.22"
|
prolog_parser = { version = "0.8.0", path = "../prolog_parser" }
|
||||||
|
|
||||||
[dependencies.termion]
|
[dependencies.termion]
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -100,12 +100,12 @@ pub(crate) trait CopierTarget: IndexMut<usize, Output=HeapCellValue>
|
|||||||
|
|
||||||
scan += 1;
|
scan += 1;
|
||||||
},
|
},
|
||||||
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => {
|
Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(_, _) => {
|
||||||
let ra = a;
|
let ra = a;
|
||||||
let rd = self.store(self.deref(ra.clone()));
|
let rd = self.store(self.deref(ra.clone()));
|
||||||
|
|
||||||
match rd.clone() {
|
match rd.clone() {
|
||||||
Addr::AttrVar(h) | Addr::HeapCell(h) if h >= old_h => {
|
Addr::AttrVar(h, _) | Addr::HeapCell(h) if h >= old_h => {
|
||||||
self[scan] = HeapCellValue::Addr(rd);
|
self[scan] = HeapCellValue::Addr(rd);
|
||||||
scan += 1;
|
scan += 1;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
|
|
||||||
da
|
da
|
||||||
},
|
},
|
||||||
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => da,
|
Addr::HeapCell(_) | Addr::StackCell(_, _) => da,
|
||||||
|
Addr::AttrVar(h, _) => self.follow_heap(h + 1),
|
||||||
Addr::Str(s) => self.follow_heap(s) // record terms of structure.
|
Addr::Str(s) => self.follow_heap(s) // record terms of structure.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -373,6 +373,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
|||||||
|
|
||||||
fn offset_as_string(&self, addr: Addr) -> Option<String> {
|
fn offset_as_string(&self, addr: Addr) -> Option<String> {
|
||||||
match addr {
|
match addr {
|
||||||
|
Addr::AttrVar(h, _) =>
|
||||||
|
Some(format!("_{}", h + 1)),
|
||||||
Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) =>
|
Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) =>
|
||||||
Some(format!("_{}", h)),
|
Some(format!("_{}", h)),
|
||||||
Addr::StackCell(fr, sc) =>
|
Addr::StackCell(fr, sc) =>
|
||||||
|
|||||||
@@ -238,9 +238,12 @@ pub struct Module {
|
|||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub enum SystemClauseType {
|
pub enum SystemClauseType {
|
||||||
CheckCutPoint,
|
CheckCutPoint,
|
||||||
|
DeleteAttribute,
|
||||||
|
DeleteHeadAttribute,
|
||||||
DynamicModuleResolution,
|
DynamicModuleResolution,
|
||||||
ExpandGoal,
|
ExpandGoal,
|
||||||
ExpandTerm,
|
ExpandTerm,
|
||||||
|
GetAttributedVariableList,
|
||||||
GetBValue,
|
GetBValue,
|
||||||
GetSCCCleaner,
|
GetSCCCleaner,
|
||||||
InstallSCCCleaner,
|
InstallSCCCleaner,
|
||||||
@@ -273,9 +276,12 @@ impl SystemClauseType {
|
|||||||
pub fn name(&self) -> ClauseName {
|
pub fn name(&self) -> ClauseName {
|
||||||
match self {
|
match self {
|
||||||
&SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
|
&SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
|
||||||
|
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr"),
|
||||||
|
&SystemClauseType::DeleteHeadAttribute => clause_name!("$del_attr_head"),
|
||||||
&SystemClauseType::DynamicModuleResolution => clause_name!("$module_call"),
|
&SystemClauseType::DynamicModuleResolution => clause_name!("$module_call"),
|
||||||
&SystemClauseType::ExpandTerm => clause_name!("$expand_term"),
|
&SystemClauseType::ExpandTerm => clause_name!("$expand_term"),
|
||||||
&SystemClauseType::ExpandGoal => clause_name!("$expand_goal"),
|
&SystemClauseType::ExpandGoal => clause_name!("$expand_goal"),
|
||||||
|
&SystemClauseType::GetAttributedVariableList => clause_name!("$get_attr_list"),
|
||||||
&SystemClauseType::GetBValue => clause_name!("$get_b_value"),
|
&SystemClauseType::GetBValue => clause_name!("$get_b_value"),
|
||||||
&SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
|
&SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
|
||||||
&SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
|
&SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
|
||||||
@@ -311,9 +317,12 @@ impl SystemClauseType {
|
|||||||
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
|
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
|
||||||
match (name, arity) {
|
match (name, arity) {
|
||||||
("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
|
("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
|
||||||
|
("$del_attr", 1) => Some(SystemClauseType::DeleteAttribute),
|
||||||
|
("$del_attr_head", 1) => Some(SystemClauseType::DeleteHeadAttribute),
|
||||||
("$module_call", 2) => Some(SystemClauseType::DynamicModuleResolution),
|
("$module_call", 2) => Some(SystemClauseType::DynamicModuleResolution),
|
||||||
("$expand_term", 2) => Some(SystemClauseType::ExpandTerm),
|
("$expand_term", 2) => Some(SystemClauseType::ExpandTerm),
|
||||||
("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal),
|
("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal),
|
||||||
|
("$get_attr_list", 2) => Some(SystemClauseType::GetAttributedVariableList),
|
||||||
("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
|
("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
|
||||||
("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
|
("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
|
||||||
("$get_scc_cleaner", 1) => Some(SystemClauseType::GetSCCCleaner),
|
("$get_scc_cleaner", 1) => Some(SystemClauseType::GetSCCCleaner),
|
||||||
@@ -708,7 +717,7 @@ pub type CodeDeque = VecDeque<Line>;
|
|||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum Addr {
|
pub enum Addr {
|
||||||
AttrVar(usize),
|
AttrVar(usize, usize), // the location of the AttrVal in the heap, the location of the attribute list.
|
||||||
Con(Constant),
|
Con(Constant),
|
||||||
Lis(usize),
|
Lis(usize),
|
||||||
HeapCell(usize),
|
HeapCell(usize),
|
||||||
@@ -751,14 +760,15 @@ impl PartialOrd<Ref> for Addr {
|
|||||||
impl Addr {
|
impl Addr {
|
||||||
pub fn is_ref(&self) -> bool {
|
pub fn is_ref(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
&Addr::HeapCell(_) | &Addr::StackCell(_, _) => true,
|
&Addr::AttrVar(..) | &Addr::HeapCell(_) | &Addr::StackCell(_, _) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_var(&self) -> Option<Ref> {
|
pub fn as_var(&self) -> Option<Ref> {
|
||||||
match self {
|
match self {
|
||||||
&Addr::HeapCell(hc) => Some(Ref::HeapCell(hc)),
|
&Addr::AttrVar(h, _) => Some(Ref::HeapCell(h)),
|
||||||
|
&Addr::HeapCell(h) => Some(Ref::HeapCell(h)),
|
||||||
&Addr::StackCell(fr, sc) => Some(Ref::StackCell(fr, sc)),
|
&Addr::StackCell(fr, sc) => Some(Ref::StackCell(fr, sc)),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
@@ -777,7 +787,6 @@ impl Add<usize> for Addr {
|
|||||||
|
|
||||||
fn add(self, rhs: usize) -> Self::Output {
|
fn add(self, rhs: usize) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
Addr::AttrVar(a) => Addr::AttrVar(a + rhs),
|
|
||||||
Addr::Lis(a) => Addr::Lis(a + rhs),
|
Addr::Lis(a) => Addr::Lis(a + rhs),
|
||||||
Addr::HeapCell(h) => Addr::HeapCell(h + rhs),
|
Addr::HeapCell(h) => Addr::HeapCell(h + rhs),
|
||||||
Addr::Str(s) => Addr::Str(s + rhs),
|
Addr::Str(s) => Addr::Str(s + rhs),
|
||||||
@@ -791,7 +800,6 @@ impl Sub<usize> for Addr {
|
|||||||
|
|
||||||
fn sub(self, rhs: usize) -> Self::Output {
|
fn sub(self, rhs: usize) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
Addr::AttrVar(a) => Addr::AttrVar(a - rhs),
|
|
||||||
Addr::Lis(a) => Addr::Lis(a - rhs),
|
Addr::Lis(a) => Addr::Lis(a - rhs),
|
||||||
Addr::HeapCell(h) => Addr::HeapCell(h - rhs),
|
Addr::HeapCell(h) => Addr::HeapCell(h - rhs),
|
||||||
Addr::Str(s) => Addr::Str(s - rhs),
|
Addr::Str(s) => Addr::Str(s - rhs),
|
||||||
|
|||||||
119
src/prolog/lib/atts.pl
Normal file
119
src/prolog/lib/atts.pl
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
:- module(atts, [attribute/1, absent_attr/2, get_attr/2, put_attr/2,
|
||||||
|
absent_from_list/2, get_from_list/2, add_to_list/2,
|
||||||
|
del_attr/3, del_attr_step/2, del_attr_non_head/3]).
|
||||||
|
|
||||||
|
:- use_module(library(control)).
|
||||||
|
:- use_module(library(dcgs)).
|
||||||
|
:- use_module(library(terms)).
|
||||||
|
|
||||||
|
:- op(1199, fx, attribute).
|
||||||
|
|
||||||
|
absent_attr(V, Attr) :-
|
||||||
|
'$get_attr_list'(V, Ls),
|
||||||
|
absent_from_list(Ls, Attr).
|
||||||
|
|
||||||
|
absent_from_list(X, _) :-
|
||||||
|
var(X), !.
|
||||||
|
absent_from_list([L|Ls], Attr) :-
|
||||||
|
( L \= Attr -> absent_from_list(Ls, Attr) ).
|
||||||
|
|
||||||
|
get_attr(V, Attr) :-
|
||||||
|
'$get_attr_list'(V, Ls), nonvar(Ls), get_from_list(Ls, Attr).
|
||||||
|
|
||||||
|
get_from_list([L|Ls], Attr) :-
|
||||||
|
nonvar(L),
|
||||||
|
( L \= Attr -> nonvar(Ls), get_from_list(Ls, Attr)
|
||||||
|
; copy_term(L, L0), L0 = Attr
|
||||||
|
; get_from_list(Ls, Attr)
|
||||||
|
).
|
||||||
|
|
||||||
|
put_attr(V, Attr) :-
|
||||||
|
'$get_attr_list'(V, Ls), add_to_list(Ls, Attr).
|
||||||
|
|
||||||
|
add_to_list(Ls, Attr) :-
|
||||||
|
( var(Ls) -> Ls = [Attr | _]
|
||||||
|
; Ls = [_ | Ls0] -> add_to_list(Ls0, Attr)
|
||||||
|
).
|
||||||
|
|
||||||
|
del_attr(Ls0, _, _) :-
|
||||||
|
var(Ls0), !.
|
||||||
|
del_attr(Ls0, V, Attr) :-
|
||||||
|
Ls0 = [Att | Ls1],
|
||||||
|
nonvar(Att),
|
||||||
|
( Att \= Attr -> del_attr_non_head(Ls0, Ls1, Attr)
|
||||||
|
; '$del_attr_head'(V), del_attr(Ls1, V, Attr)
|
||||||
|
).
|
||||||
|
|
||||||
|
del_attr_step(Ls1, Attr) :-
|
||||||
|
( nonvar(Ls1) -> Ls1 = [_ | Ls2], del_attr_non_head(Ls1, Ls2, Attr)
|
||||||
|
; true ).
|
||||||
|
|
||||||
|
%% assumptions: Ls0 is a list, Ls1 is its tail;
|
||||||
|
%% the head of Ls0 can be ignored.
|
||||||
|
del_attr_non_head(Ls0, Ls1, Attr) :-
|
||||||
|
Ls0 = [_, Att | _],
|
||||||
|
nonvar(Att),
|
||||||
|
!,
|
||||||
|
( Att \= Attr -> del_attr_step(Ls1, Attr)
|
||||||
|
; '$del_attr'(Ls0), %% set tail of Ls0 = tail of Ls1. can be undone by backtracking.
|
||||||
|
del_attr_step(Ls1, Attr)
|
||||||
|
).
|
||||||
|
del_attr_non_head(_, _, _).
|
||||||
|
|
||||||
|
user:term_expansion(Term0, Terms) :-
|
||||||
|
nonvar(Term0),
|
||||||
|
Term0 = (:- attribute Atts),
|
||||||
|
nonvar(Atts),
|
||||||
|
phrase(put_attrs_var_check, Terms, Terms1),
|
||||||
|
phrase(put_attrs(Atts), Terms1, Terms2),
|
||||||
|
phrase(get_attrs_var_check, Terms2, Terms3),
|
||||||
|
phrase(get_attrs(Atts), Terms3).
|
||||||
|
|
||||||
|
put_attrs_var_check -->
|
||||||
|
{ numbervars([Var, Attr], 0, _) },
|
||||||
|
[(put_atts(Var, Attr) :- nonvar(Var), throw(error(type_error(variable, Var), put_atts/2))),
|
||||||
|
(put_atts(Var, Attr) :- var(Attr), throw(error(instantiation_error, put_atts/2)))].
|
||||||
|
|
||||||
|
get_attrs_var_check -->
|
||||||
|
{ numbervars([Var, Attr], 0, _) },
|
||||||
|
[(get_atts(Var, Attr) :- nonvar(Var), throw(error(type_error(variable, Var), get_atts/2))),
|
||||||
|
(get_atts(Var, Attr) :- var(Attr), !, '$get_attr_list'(Var, Attr))].
|
||||||
|
|
||||||
|
put_attrs(Name/Arity) -->
|
||||||
|
put_attr(Name, Arity),
|
||||||
|
{ numbervars([Var, Attr], 0, _) },
|
||||||
|
[(put_atts(Var, Attr) :- lists:maplist(put_atts(Var), Attr))].
|
||||||
|
put_attrs((Name/Arity, Atts)) -->
|
||||||
|
{ nonvar(Atts) },
|
||||||
|
put_attr(Name, Arity),
|
||||||
|
put_attrs(Atts).
|
||||||
|
|
||||||
|
get_attrs(Name/Arity) -->
|
||||||
|
get_attr(Name, Arity).
|
||||||
|
get_attrs((Name/Arity, Atts)) -->
|
||||||
|
{ nonvar(Atts) },
|
||||||
|
get_attr(Name, Arity),
|
||||||
|
get_attrs(Atts).
|
||||||
|
|
||||||
|
put_attr(Name, Arity) -->
|
||||||
|
{ functor(Attr, Name, Arity),
|
||||||
|
numbervars(Attr, 0, Arity),
|
||||||
|
V = '$VAR'(Arity) },
|
||||||
|
[(put_atts(V, +Attr) :- !, functor(Attr, _, _), put_attr(V, Attr)),
|
||||||
|
(put_atts(V, Attr) :- !, functor(Attr, _, _), put_attr(V, Attr)),
|
||||||
|
(put_atts(V, -Attr) :- !, functor(Attr, _, _), '$get_attr_list'(V, Ls), del_attr(Ls, V, Attr))].
|
||||||
|
|
||||||
|
get_attr(Name, Arity) -->
|
||||||
|
{ functor(Attr, Name, Arity),
|
||||||
|
numbervars(Attr, 0, Arity),
|
||||||
|
V = '$VAR'(Arity) },
|
||||||
|
[(get_atts(V, +Attr) :- !, functor(Attr, _, _), get_attr(V, Attr)),
|
||||||
|
(get_atts(V, Attr) :- !, functor(Attr, _, _), get_attr(V, Attr)),
|
||||||
|
(get_atts(V, -Attr) :- !, functor(Attr, _, _), absent_attr(V, Attr))].
|
||||||
|
|
||||||
|
user:goal_expansion(Term, [M:put_atts(Var, Attr)]) :-
|
||||||
|
nonvar(Term),
|
||||||
|
Term = put_atts(Var, M, Attr).
|
||||||
|
user:goal_expansion(Term, [M:get_atts(Var, Attr)]) :-
|
||||||
|
nonvar(Term),
|
||||||
|
Term = get_atts(Var, M, Attr).
|
||||||
@@ -78,7 +78,7 @@ impl MachineState {
|
|||||||
|
|
||||||
pub(crate) fn store(&self, a: Addr) -> Addr {
|
pub(crate) fn store(&self, a: Addr) -> Addr {
|
||||||
match a {
|
match a {
|
||||||
Addr::AttrVar(h) => self.heap[h+1].as_addr(h+1),
|
Addr::AttrVar(h, _) => self.heap[h].as_addr(h),
|
||||||
Addr::HeapCell(h) => self.heap[h].as_addr(h),
|
Addr::HeapCell(h) => self.heap[h].as_addr(h),
|
||||||
Addr::StackCell(fr, sc) => self.and_stack[fr][sc].clone(),
|
Addr::StackCell(fr, sc) => self.and_stack[fr][sc].clone(),
|
||||||
addr => addr
|
addr => addr
|
||||||
@@ -130,7 +130,7 @@ impl MachineState {
|
|||||||
fn print_var_eq<Outputter>(&self, var: Rc<Var>, addr: Addr, var_dir: &HeapVarDict,
|
fn print_var_eq<Outputter>(&self, var: Rc<Var>, addr: Addr, var_dir: &HeapVarDict,
|
||||||
mut output: Outputter)
|
mut output: Outputter)
|
||||||
-> Outputter
|
-> Outputter
|
||||||
where Outputter: HCValueOutputter
|
where Outputter: HCValueOutputter
|
||||||
{
|
{
|
||||||
let orig_len = output.len();
|
let orig_len = output.len();
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ impl MachineState {
|
|||||||
pub(super)
|
pub(super)
|
||||||
fn print_exception<Outputter>(&self, addr: Addr, var_dir: &HeapVarDict, output: Outputter)
|
fn print_exception<Outputter>(&self, addr: Addr, var_dir: &HeapVarDict, output: Outputter)
|
||||||
-> Outputter
|
-> Outputter
|
||||||
where Outputter: HCValueOutputter
|
where Outputter: HCValueOutputter
|
||||||
{
|
{
|
||||||
let printer = HCPrinter::from_heap_locs(&self, output, var_dir);
|
let printer = HCPrinter::from_heap_locs(&self, output, var_dir);
|
||||||
printer.print(addr)
|
printer.print(addr)
|
||||||
@@ -220,7 +220,7 @@ impl MachineState {
|
|||||||
|
|
||||||
if d1 != d2 {
|
if d1 != d2 {
|
||||||
match (self.store(d1.clone()), self.store(d2.clone())) {
|
match (self.store(d1.clone()), self.store(d2.clone())) {
|
||||||
(Addr::AttrVar(h), addr) | (addr, Addr::AttrVar(h)) => {
|
(Addr::AttrVar(h, _), addr) | (addr, Addr::AttrVar(h, _)) => {
|
||||||
pdl.push(Addr::HeapCell(h+1));
|
pdl.push(Addr::HeapCell(h+1));
|
||||||
pdl.push(addr);
|
pdl.push(addr);
|
||||||
},
|
},
|
||||||
@@ -248,7 +248,7 @@ impl MachineState {
|
|||||||
self.fail = true;
|
self.fail = true;
|
||||||
},
|
},
|
||||||
(Addr::Lis(a1), Addr::Con(Constant::String(ref mut s)))
|
(Addr::Lis(a1), Addr::Con(Constant::String(ref mut s)))
|
||||||
| (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1))
|
| (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1))
|
||||||
if self.flags.double_quotes.is_chars() => {
|
if self.flags.double_quotes.is_chars() => {
|
||||||
if let Some(c) = s.head() {
|
if let Some(c) = s.head() {
|
||||||
pdl.push(Addr::Con(Constant::String(s.tail())));
|
pdl.push(Addr::Con(Constant::String(s.tail())));
|
||||||
@@ -289,7 +289,7 @@ impl MachineState {
|
|||||||
self.fail = true;
|
self.fail = true;
|
||||||
},
|
},
|
||||||
(Addr::Con(Constant::EmptyList), Addr::Con(Constant::String(ref s)))
|
(Addr::Con(Constant::EmptyList), Addr::Con(Constant::String(ref s)))
|
||||||
| (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList))
|
| (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList))
|
||||||
if self.flags.double_quotes.is_chars() => {
|
if self.flags.double_quotes.is_chars() => {
|
||||||
if s.is_expandable() && s.is_empty() {
|
if s.is_expandable() && s.is_empty() {
|
||||||
self.pstr_trail(s.clone());
|
self.pstr_trail(s.clone());
|
||||||
@@ -309,7 +309,7 @@ impl MachineState {
|
|||||||
(Addr::Con(Constant::String(ref mut s1)),
|
(Addr::Con(Constant::String(ref mut s1)),
|
||||||
Addr::Con(Constant::String(ref mut s2))) =>
|
Addr::Con(Constant::String(ref mut s2))) =>
|
||||||
self.fail = !(self.unify_string(&mut pdl, s1, s2)
|
self.fail = !(self.unify_string(&mut pdl, s1, s2)
|
||||||
|| self.unify_string(&mut pdl, s2, s1)),
|
|| self.unify_string(&mut pdl, s2, s1)),
|
||||||
(Addr::Con(ref c1), Addr::Con(ref c2)) =>
|
(Addr::Con(ref c1), Addr::Con(ref c2)) =>
|
||||||
if c1 != c2 {
|
if c1 != c2 {
|
||||||
self.fail = true;
|
self.fail = true;
|
||||||
@@ -352,7 +352,7 @@ impl MachineState {
|
|||||||
self.pstr_tr += 1;
|
self.pstr_tr += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trail(&mut self, r: TrailRef) {
|
pub(super) fn trail(&mut self, r: TrailRef) {
|
||||||
match r {
|
match r {
|
||||||
TrailRef::HeapCell(h) =>
|
TrailRef::HeapCell(h) =>
|
||||||
if h < self.hb {
|
if h < self.hb {
|
||||||
@@ -1168,11 +1168,11 @@ impl MachineState {
|
|||||||
let addr = self.store(self.deref(a1));
|
let addr = self.store(self.deref(a1));
|
||||||
|
|
||||||
let offset = match addr {
|
let offset = match addr {
|
||||||
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => v,
|
Addr::HeapCell(_) | Addr::StackCell(..) | Addr::AttrVar(..) => v,
|
||||||
Addr::Con(Constant::String(_)) if self.flags.double_quotes.is_chars() => l,
|
Addr::Con(Constant::String(_)) if self.flags.double_quotes.is_chars() => l,
|
||||||
Addr::Con(_) => c,
|
Addr::Con(_) => c,
|
||||||
Addr::Lis(_) => l,
|
Addr::Lis(_) => l,
|
||||||
Addr::Str(_) => s
|
Addr::Str(_) => s,
|
||||||
};
|
};
|
||||||
|
|
||||||
match offset {
|
match offset {
|
||||||
@@ -1789,6 +1789,17 @@ impl MachineState {
|
|||||||
|
|
||||||
match d {
|
match d {
|
||||||
Addr::HeapCell(_) | Addr::StackCell(..) => self.fail = true,
|
Addr::HeapCell(_) | Addr::StackCell(..) => self.fail = true,
|
||||||
|
Addr::AttrVar(h, _) => {
|
||||||
|
let addr = self.heap[h].as_addr(h);
|
||||||
|
|
||||||
|
if let Some(_) = addr.as_var() {
|
||||||
|
if self.store(self.deref(addr)).as_var().is_some() {
|
||||||
|
self.fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.p += 1;
|
||||||
|
},
|
||||||
_ => self.p += 1
|
_ => self.p += 1
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -1797,6 +1808,17 @@ impl MachineState {
|
|||||||
|
|
||||||
match d {
|
match d {
|
||||||
Addr::HeapCell(_) | Addr::StackCell(_,_) => self.p += 1,
|
Addr::HeapCell(_) | Addr::StackCell(_,_) => self.p += 1,
|
||||||
|
Addr::AttrVar(h, _) => {
|
||||||
|
let addr = self.heap[h].as_addr(h);
|
||||||
|
|
||||||
|
if let Some(_) = addr.as_var() {
|
||||||
|
if self.store(self.deref(addr)).as_var().is_none() {
|
||||||
|
self.fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.p += 1;
|
||||||
|
},
|
||||||
_ => self.fail = true
|
_ => self.fail = true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -1844,7 +1866,7 @@ impl MachineState {
|
|||||||
},
|
},
|
||||||
Addr::Lis(_) =>
|
Addr::Lis(_) =>
|
||||||
self.try_functor_compound_case(clause_name!("."), 2),
|
self.try_functor_compound_case(clause_name!("."), 2),
|
||||||
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(..) => {
|
Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(..) => {
|
||||||
let name = self.store(self.deref(self[temp_v!(2)].clone()));
|
let name = self.store(self.deref(self[temp_v!(2)].clone()));
|
||||||
let arity = self.store(self.deref(self[temp_v!(3)].clone()));
|
let arity = self.store(self.deref(self[temp_v!(3)].clone()));
|
||||||
|
|
||||||
|
|||||||
@@ -203,6 +203,36 @@ impl MachineState {
|
|||||||
_ => self.fail = true
|
_ => self.fail = true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
&SystemClauseType::DeleteAttribute => {
|
||||||
|
let ls0 = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
|
||||||
|
if let Addr::Lis(l1) = ls0 {
|
||||||
|
if let Addr::Lis(l2) = self.store(self.deref(Addr::HeapCell(l1 + 1))) {
|
||||||
|
let addr = self.heap[l1 + 1].as_addr(l1 + 1);
|
||||||
|
self.heap[l1 + 1] = HeapCellValue::Addr(Addr::HeapCell(l2 + 1));
|
||||||
|
self.trail(TrailRef::AttrVarLink(l2 + 1, addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
&SystemClauseType::DeleteHeadAttribute => {
|
||||||
|
let addr = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
|
||||||
|
match addr {
|
||||||
|
Addr::AttrVar(_, attr_var) => {
|
||||||
|
let addr = self.heap[attr_var].as_addr(attr_var).clone();
|
||||||
|
let addr = self.store(self.deref(addr));
|
||||||
|
|
||||||
|
match addr {
|
||||||
|
Addr::Lis(l) => {
|
||||||
|
self.heap[attr_var] = HeapCellValue::Addr(Addr::HeapCell(l+1));
|
||||||
|
self.trail(TrailRef::AttrVarLink(attr_var, Addr::Lis(l)));
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
&SystemClauseType::DynamicModuleResolution => {
|
&SystemClauseType::DynamicModuleResolution => {
|
||||||
let module_name = self.store(self.deref(self[temp_v!(1)].clone()));
|
let module_name = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
|
||||||
@@ -237,6 +267,40 @@ impl MachineState {
|
|||||||
self.p = CodePtr::Local(LocalCodePtr::UserTermExpansion(0));
|
self.p = CodePtr::Local(LocalCodePtr::UserTermExpansion(0));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
},
|
},
|
||||||
|
&SystemClauseType::GetAttributedVariableList => {
|
||||||
|
let attr_var = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
let mut attr_var_list = match attr_var {
|
||||||
|
Addr::AttrVar(_, attr_var_list) => attr_var_list,
|
||||||
|
attr_var @ Addr::HeapCell(_) | attr_var @ Addr::StackCell(..) => {
|
||||||
|
// create an AttrVar in the heap.
|
||||||
|
let h = self.heap.h;
|
||||||
|
|
||||||
|
self.heap.push(HeapCellValue::Addr(Addr::AttrVar(h, h + 2)));
|
||||||
|
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h + 1)));
|
||||||
|
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h + 2)));
|
||||||
|
|
||||||
|
match attr_var.as_var().unwrap() {
|
||||||
|
Ref::HeapCell(r) => {
|
||||||
|
self.heap[r] = HeapCellValue::Addr(Addr::HeapCell(h));
|
||||||
|
self.trail(TrailRef::HeapCell(r));
|
||||||
|
},
|
||||||
|
Ref::StackCell(fr, sc) => {
|
||||||
|
self.and_stack[fr][sc] = Addr::HeapCell(h);
|
||||||
|
self.trail(TrailRef::StackCell(fr, sc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h + 2
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
self.fail = true;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let list_var = self[temp_v!(2)].clone();
|
||||||
|
self.unify(Addr::HeapCell(attr_var_list), list_var);
|
||||||
|
},
|
||||||
&SystemClauseType::GetDoubleQuotes => {
|
&SystemClauseType::GetDoubleQuotes => {
|
||||||
let a1 = self[temp_v!(1)].clone();
|
let a1 = self[temp_v!(1)].clone();
|
||||||
|
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ impl<'a, R: Read> TermStream<'a, R> {
|
|||||||
fn parse_expansion_output(&mut self, term_string: &str, op_dir: &OpDir)
|
fn parse_expansion_output(&mut self, term_string: &str, op_dir: &OpDir)
|
||||||
-> Result<Term, ParserError>
|
-> Result<Term, ParserError>
|
||||||
{
|
{
|
||||||
let mut parser = Parser::new(term_string.trim().as_bytes(), self.indices.atom_tbl.clone(),
|
let mut parser = Parser::new(term_string.trim().as_bytes(), self.parser.get_atom_tbl(),
|
||||||
self.flags);
|
self.flags);
|
||||||
parser.read_term(composite_op!(self.in_module, &self.indices.op_dir, op_dir))
|
parser.read_term(composite_op!(self.in_module, &self.indices.op_dir, op_dir))
|
||||||
}
|
}
|
||||||
@@ -288,6 +288,18 @@ impl<'a, R: Read> TermStream<'a, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
|
fn print_with_locs(&self, target: usize, var_dict: &HeapVarDict) -> PrinterOutputter {
|
||||||
|
let output = PrinterOutputter::new();
|
||||||
|
let mut printer = HCPrinter::from_heap_locs(&self, output, &var_dict);
|
||||||
|
|
||||||
|
printer.quoted = true;
|
||||||
|
printer.numbervars = true;
|
||||||
|
|
||||||
|
printer.see_all_locs();
|
||||||
|
|
||||||
|
printer.print(Addr::HeapCell(target))
|
||||||
|
}
|
||||||
|
|
||||||
fn try_expand_term(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies,
|
fn try_expand_term(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies,
|
||||||
code_repo: &mut CodeRepo, term: &Term, hook: CompileTimeHook)
|
code_repo: &mut CodeRepo, term: &Term, hook: CompileTimeHook)
|
||||||
-> Option<String>
|
-> Option<String>
|
||||||
@@ -308,17 +320,7 @@ impl MachineState {
|
|||||||
self.reset();
|
self.reset();
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let mut output = {
|
let mut output = self.print_with_locs(h, &var_dict);
|
||||||
let output = PrinterOutputter::new();
|
|
||||||
let mut printer = HCPrinter::from_heap_locs(&self, output, &var_dict);
|
|
||||||
|
|
||||||
printer.quoted = true;
|
|
||||||
printer.numbervars = true;
|
|
||||||
|
|
||||||
printer.see_all_locs();
|
|
||||||
|
|
||||||
printer.print(Addr::HeapCell(h))
|
|
||||||
};
|
|
||||||
|
|
||||||
output.push_char('.');
|
output.push_char('.');
|
||||||
self.reset();
|
self.reset();
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ impl fmt::Display for Addr {
|
|||||||
match self {
|
match self {
|
||||||
&Addr::Con(ref c) => write!(f, "Addr::Con({})", c),
|
&Addr::Con(ref c) => write!(f, "Addr::Con({})", c),
|
||||||
&Addr::Lis(l) => write!(f, "Addr::Lis({})", l),
|
&Addr::Lis(l) => write!(f, "Addr::Lis({})", l),
|
||||||
&Addr::AttrVar(h) => write!(f, "Addr::AttrVar({})", h),
|
&Addr::AttrVar(h, attr_var_list) => write!(f, "Addr::AttrVar({}, {})", h, attr_var_list),
|
||||||
&Addr::HeapCell(h) => write!(f, "Addr::HeapCell({})", h),
|
&Addr::HeapCell(h) => write!(f, "Addr::HeapCell({})", h),
|
||||||
&Addr::StackCell(fr, sc)=> write!(f, "Addr::StackCell({}, {})", fr, sc),
|
&Addr::StackCell(fr, sc)=> write!(f, "Addr::StackCell({}, {})", fr, sc),
|
||||||
&Addr::Str(s) => write!(f, "Addr::Str({})", s)
|
&Addr::Str(s) => write!(f, "Addr::Str({})", s)
|
||||||
|
|||||||
Reference in New Issue
Block a user