From fcffb905497643438904f155f368c43b7d34d2e8 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 30 Jan 2019 21:31:48 -0700 Subject: [PATCH] add atts.pl, various fixes --- Cargo.lock | 8 +- Cargo.toml | 4 +- src/prolog/copier.rs | 4 +- src/prolog/heap_iter.rs | 3 +- src/prolog/heap_print.rs | 2 + src/prolog/instructions.rs | 18 +++- src/prolog/lib/atts.pl | 119 +++++++++++++++++++++++ src/prolog/machine/machine_state_impl.rs | 48 ++++++--- src/prolog/machine/system_calls.rs | 68 ++++++++++++- src/prolog/machine/term_expansion.rs | 26 ++--- src/prolog/read.rs | 4 +- src/prolog/write.rs | 2 +- 12 files changed, 261 insertions(+), 45 deletions(-) create mode 100644 src/prolog/lib/atts.pl diff --git a/Cargo.lock b/Cargo.lock index eeba3966..7367bf38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,8 +86,7 @@ dependencies = [ [[package]] name = "prolog_parser" -version = "0.7.22" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.8.0" dependencies = [ "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)", @@ -108,12 +107,12 @@ dependencies = [ [[package]] name = "rusty-wam" -version = "0.7.17" +version = "0.8.0" dependencies = [ "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)", "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)", ] @@ -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.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 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_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" diff --git a/Cargo.toml b/Cargo.toml index 628aa795..5eb3335c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rusty-wam" -version = "0.7.17" +version = "0.8.0" authors = ["Mark Thom "] repository = "https://github.com/mthom/rusty-wam" description = "The Warren Abstract Machine in Rust." @@ -10,7 +10,7 @@ license = "BSD-3-Clause" downcast = "0.9.1" num = "0.2" ordered-float = "0.5.0" -prolog_parser = "0.7.22" +prolog_parser = { version = "0.8.0", path = "../prolog_parser" } [dependencies.termion] version = "1.4.0" \ No newline at end of file diff --git a/src/prolog/copier.rs b/src/prolog/copier.rs index 1e084246..7efefef1 100644 --- a/src/prolog/copier.rs +++ b/src/prolog/copier.rs @@ -100,12 +100,12 @@ pub(crate) trait CopierTarget: IndexMut 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; }, diff --git a/src/prolog/heap_iter.rs b/src/prolog/heap_iter.rs index 2b96ff69..eb4dfe61 100644 --- a/src/prolog/heap_iter.rs +++ b/src/prolog/heap_iter.rs @@ -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. } } diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index 28e6e48f..86f946d0 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -373,6 +373,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> fn offset_as_string(&self, addr: Addr) -> Option { 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) => diff --git a/src/prolog/instructions.rs b/src/prolog/instructions.rs index 88a707a2..e2eaed46 100644 --- a/src/prolog/instructions.rs +++ b/src/prolog/instructions.rs @@ -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 { 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; #[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 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 { 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 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 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), diff --git a/src/prolog/lib/atts.pl b/src/prolog/lib/atts.pl new file mode 100644 index 00000000..a202e2de --- /dev/null +++ b/src/prolog/lib/atts.pl @@ -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). diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index dae94805..efe72501 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -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(&self, var: Rc, 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(&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())); diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 5de4f397..46dede29 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -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(); diff --git a/src/prolog/machine/term_expansion.rs b/src/prolog/machine/term_expansion.rs index 850786e0..2106895a 100644 --- a/src/prolog/machine/term_expansion.rs +++ b/src/prolog/machine/term_expansion.rs @@ -196,7 +196,7 @@ impl<'a, R: Read> TermStream<'a, R> { fn parse_expansion_output(&mut self, term_string: &str, op_dir: &OpDir) -> Result { - 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 @@ -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(); diff --git a/src/prolog/read.rs b/src/prolog/read.rs index 3b6053c0..891280ad 100644 --- a/src/prolog/read.rs +++ b/src/prolog/read.rs @@ -31,7 +31,7 @@ pub enum Input { Term(Term) } -pub fn read_toplevel(wam: &mut Machine) -> Result { +pub fn read_toplevel(wam: &mut Machine) -> Result { let mut buffer = String::new(); let stdin = stdin(); @@ -48,7 +48,7 @@ pub fn read_toplevel(wam: &mut Machine) -> Result { 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())?)) } diff --git a/src/prolog/write.rs b/src/prolog/write.rs index 9b5004b2..1b6bf0c1 100644 --- a/src/prolog/write.rs +++ b/src/prolog/write.rs @@ -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) -- 2.54.0