add atts.pl, various fixes
This commit is contained in:
@@ -100,12 +100,12 @@ pub(crate) trait CopierTarget: IndexMut<usize, Output=HeapCellValue>
|
||||
|
||||
scan += 1;
|
||||
},
|
||||
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => {
|
||||
Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(_, _) => {
|
||||
let ra = a;
|
||||
let rd = self.store(self.deref(ra.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);
|
||||
scan += 1;
|
||||
},
|
||||
|
||||
@@ -65,7 +65,8 @@ impl<'a> HCPreOrderIterator<'a> {
|
||||
|
||||
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.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,6 +373,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
|
||||
fn offset_as_string(&self, addr: Addr) -> Option<String> {
|
||||
match addr {
|
||||
Addr::AttrVar(h, _) =>
|
||||
Some(format!("_{}", h + 1)),
|
||||
Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) =>
|
||||
Some(format!("_{}", h)),
|
||||
Addr::StackCell(fr, sc) =>
|
||||
|
||||
@@ -238,9 +238,12 @@ pub struct Module {
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum SystemClauseType {
|
||||
CheckCutPoint,
|
||||
DeleteAttribute,
|
||||
DeleteHeadAttribute,
|
||||
DynamicModuleResolution,
|
||||
ExpandGoal,
|
||||
ExpandTerm,
|
||||
GetAttributedVariableList,
|
||||
GetBValue,
|
||||
GetSCCCleaner,
|
||||
InstallSCCCleaner,
|
||||
@@ -273,9 +276,12 @@ impl SystemClauseType {
|
||||
pub fn name(&self) -> ClauseName {
|
||||
match self {
|
||||
&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::ExpandTerm => clause_name!("$expand_term"),
|
||||
&SystemClauseType::ExpandGoal => clause_name!("$expand_goal"),
|
||||
&SystemClauseType::GetAttributedVariableList => clause_name!("$get_attr_list"),
|
||||
&SystemClauseType::GetBValue => clause_name!("$get_b_value"),
|
||||
&SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
|
||||
&SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
|
||||
@@ -311,9 +317,12 @@ impl SystemClauseType {
|
||||
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
|
||||
match (name, arity) {
|
||||
("$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),
|
||||
("$expand_term", 2) => Some(SystemClauseType::ExpandTerm),
|
||||
("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal),
|
||||
("$get_attr_list", 2) => Some(SystemClauseType::GetAttributedVariableList),
|
||||
("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
|
||||
("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
|
||||
("$get_scc_cleaner", 1) => Some(SystemClauseType::GetSCCCleaner),
|
||||
@@ -708,7 +717,7 @@ pub type CodeDeque = VecDeque<Line>;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Addr {
|
||||
AttrVar(usize),
|
||||
AttrVar(usize, usize), // the location of the AttrVal in the heap, the location of the attribute list.
|
||||
Con(Constant),
|
||||
Lis(usize),
|
||||
HeapCell(usize),
|
||||
@@ -751,14 +760,15 @@ impl PartialOrd<Ref> for Addr {
|
||||
impl Addr {
|
||||
pub fn is_ref(&self) -> bool {
|
||||
match self {
|
||||
&Addr::HeapCell(_) | &Addr::StackCell(_, _) => true,
|
||||
&Addr::AttrVar(..) | &Addr::HeapCell(_) | &Addr::StackCell(_, _) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_var(&self) -> Option<Ref> {
|
||||
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)),
|
||||
_ => None
|
||||
}
|
||||
@@ -777,7 +787,6 @@ impl Add<usize> for Addr {
|
||||
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
Addr::AttrVar(a) => Addr::AttrVar(a + rhs),
|
||||
Addr::Lis(a) => Addr::Lis(a + rhs),
|
||||
Addr::HeapCell(h) => Addr::HeapCell(h + rhs),
|
||||
Addr::Str(s) => Addr::Str(s + rhs),
|
||||
@@ -791,7 +800,6 @@ impl Sub<usize> for Addr {
|
||||
|
||||
fn sub(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
Addr::AttrVar(a) => Addr::AttrVar(a - rhs),
|
||||
Addr::Lis(a) => Addr::Lis(a - rhs),
|
||||
Addr::HeapCell(h) => Addr::HeapCell(h - 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).
|
||||
@@ -65,7 +65,7 @@ impl MachineState {
|
||||
println!("{} : {}", h, self.heap[h]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pub fn machine_flags(&self) -> MachineFlags {
|
||||
self.flags
|
||||
@@ -78,7 +78,7 @@ impl MachineState {
|
||||
|
||||
pub(crate) fn store(&self, a: Addr) -> Addr {
|
||||
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::StackCell(fr, sc) => self.and_stack[fr][sc].clone(),
|
||||
addr => addr
|
||||
@@ -130,7 +130,7 @@ impl MachineState {
|
||||
fn print_var_eq<Outputter>(&self, var: Rc<Var>, addr: Addr, var_dir: &HeapVarDict,
|
||||
mut output: Outputter)
|
||||
-> Outputter
|
||||
where Outputter: HCValueOutputter
|
||||
where Outputter: HCValueOutputter
|
||||
{
|
||||
let orig_len = output.len();
|
||||
|
||||
@@ -158,7 +158,7 @@ impl MachineState {
|
||||
pub(super)
|
||||
fn print_exception<Outputter>(&self, addr: Addr, var_dir: &HeapVarDict, output: Outputter)
|
||||
-> Outputter
|
||||
where Outputter: HCValueOutputter
|
||||
where Outputter: HCValueOutputter
|
||||
{
|
||||
let printer = HCPrinter::from_heap_locs(&self, output, var_dir);
|
||||
printer.print(addr)
|
||||
@@ -220,7 +220,7 @@ impl MachineState {
|
||||
|
||||
if d1 != d2 {
|
||||
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);
|
||||
},
|
||||
@@ -248,7 +248,7 @@ impl MachineState {
|
||||
self.fail = true;
|
||||
},
|
||||
(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 let Some(c) = s.head() {
|
||||
pdl.push(Addr::Con(Constant::String(s.tail())));
|
||||
@@ -289,7 +289,7 @@ impl MachineState {
|
||||
self.fail = true;
|
||||
},
|
||||
(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 s.is_expandable() && s.is_empty() {
|
||||
self.pstr_trail(s.clone());
|
||||
@@ -309,7 +309,7 @@ impl MachineState {
|
||||
(Addr::Con(Constant::String(ref mut s1)),
|
||||
Addr::Con(Constant::String(ref mut 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)) =>
|
||||
if c1 != c2 {
|
||||
self.fail = true;
|
||||
@@ -352,7 +352,7 @@ impl MachineState {
|
||||
self.pstr_tr += 1;
|
||||
}
|
||||
|
||||
fn trail(&mut self, r: TrailRef) {
|
||||
pub(super) fn trail(&mut self, r: TrailRef) {
|
||||
match r {
|
||||
TrailRef::HeapCell(h) =>
|
||||
if h < self.hb {
|
||||
@@ -486,7 +486,7 @@ impl MachineState {
|
||||
}
|
||||
|
||||
pub(super) fn write_constant_to_var(&mut self, addr: Addr, c: Constant) {
|
||||
match self.store(self.deref(addr)) {
|
||||
match self.store(self.deref(addr)) {
|
||||
Addr::HeapCell(h) => {
|
||||
self.heap[h] = HeapCellValue::Addr(Addr::Con(c.clone()));
|
||||
self.trail(TrailRef::HeapCell(h));
|
||||
@@ -1168,11 +1168,11 @@ impl MachineState {
|
||||
let addr = self.store(self.deref(a1));
|
||||
|
||||
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(_) => c,
|
||||
Addr::Lis(_) => l,
|
||||
Addr::Str(_) => s
|
||||
Addr::Str(_) => s,
|
||||
};
|
||||
|
||||
match offset {
|
||||
@@ -1789,6 +1789,17 @@ impl MachineState {
|
||||
|
||||
match d {
|
||||
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
|
||||
};
|
||||
},
|
||||
@@ -1797,6 +1808,17 @@ impl MachineState {
|
||||
|
||||
match d {
|
||||
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
|
||||
};
|
||||
},
|
||||
@@ -1844,7 +1866,7 @@ impl MachineState {
|
||||
},
|
||||
Addr::Lis(_) =>
|
||||
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 arity = self.store(self.deref(self[temp_v!(3)].clone()));
|
||||
|
||||
|
||||
@@ -203,6 +203,36 @@ impl MachineState {
|
||||
_ => 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 => {
|
||||
let module_name = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||
|
||||
@@ -213,14 +243,14 @@ impl MachineState {
|
||||
for i in 1 .. arity + 1 {
|
||||
self.registers[i] = self.heap[a+i].as_addr(a+i);
|
||||
}
|
||||
|
||||
|
||||
return self.module_lookup(indices, (name, arity), module_name, true);
|
||||
},
|
||||
Addr::Con(Constant::Atom(name, _)) =>
|
||||
return self.module_lookup(indices, (name, 0), module_name, true),
|
||||
addr => {
|
||||
let stub = MachineError::functor_stub(clause_name!("(:)"), 2);
|
||||
|
||||
|
||||
let type_error = MachineError::type_error(ValidType::Callable, addr);
|
||||
let type_error = self.error_form(type_error, stub);
|
||||
|
||||
@@ -237,6 +267,40 @@ impl MachineState {
|
||||
self.p = CodePtr::Local(LocalCodePtr::UserTermExpansion(0));
|
||||
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 => {
|
||||
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)
|
||||
-> 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);
|
||||
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 {
|
||||
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,
|
||||
code_repo: &mut CodeRepo, term: &Term, hook: CompileTimeHook)
|
||||
-> Option<String>
|
||||
@@ -308,17 +320,7 @@ impl MachineState {
|
||||
self.reset();
|
||||
None
|
||||
} else {
|
||||
let mut output = {
|
||||
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))
|
||||
};
|
||||
let mut output = self.print_with_locs(h, &var_dict);
|
||||
|
||||
output.push_char('.');
|
||||
self.reset();
|
||||
|
||||
@@ -31,7 +31,7 @@ pub enum Input {
|
||||
Term(Term)
|
||||
}
|
||||
|
||||
pub fn read_toplevel(wam: &mut Machine) -> Result<Input, ParserError> {
|
||||
pub fn read_toplevel(wam: &mut Machine) -> Result<Input, ParserError> {
|
||||
let mut buffer = String::new();
|
||||
|
||||
let stdin = stdin();
|
||||
@@ -48,7 +48,7 @@ pub fn read_toplevel(wam: &mut Machine) -> Result<Input, ParserError> {
|
||||
let mut term_stream = TermStream::new(stdin.lock(), wam.indices.atom_tbl.clone(),
|
||||
wam.machine_flags(), &mut wam.indices,
|
||||
&mut wam.policies, &mut wam.code_repo);
|
||||
|
||||
|
||||
term_stream.add_to_top(buffer.as_str());
|
||||
Ok(Input::Term(term_stream.read_term(&mut wam.machine_st, &OpDir::new())?))
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ impl fmt::Display for Addr {
|
||||
match self {
|
||||
&Addr::Con(ref c) => write!(f, "Addr::Con({})", c),
|
||||
&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::StackCell(fr, sc)=> write!(f, "Addr::StackCell({}, {})", fr, sc),
|
||||
&Addr::Str(s) => write!(f, "Addr::Str({})", s)
|
||||
|
||||
Reference in New Issue
Block a user