From 08b94dcdf536188b889005a4e52c5c2ad4d17dd0 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 14 Jan 2018 22:11:02 -0700 Subject: [PATCH] add display predicate --- README.md | 1 + src/prolog/ast.rs | 8 ++++++- src/prolog/codegen.rs | 4 ++++ src/prolog/heap_print.rs | 13 +++++++++-- src/prolog/io.rs | 10 +++++--- src/prolog/iterators.rs | 9 ++++++++ src/prolog/machine/machine_state.rs | 36 +++++++++++++++++++++++++++++ src/prolog/machine/mod.rs | 29 ++++------------------- src/prolog/parser | 2 +- 9 files changed, 80 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 62319166..14529d93 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ The following predicates are built-in to rusty-wam. * `atomic/1` * `call/N` (1 <= N <= 63) * `catch/3` +* `display/1` * `duplicate_term/2` * `false/0` * `functor/3` diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index 61572fd4..6e5f5503 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -335,8 +335,9 @@ pub enum CompareNumberQT { pub enum QueryTerm { Arg(Vec>), CallN(Vec>), - Catch(Vec>), + Catch(Vec>), Cut, + Display(Vec>), Functor(Vec>), Inlined(InlinedQueryTerm), Is(Vec>), @@ -350,6 +351,7 @@ impl QueryTerm { &QueryTerm::Arg(_) => 3, &QueryTerm::Catch(_) => 3, &QueryTerm::Throw(_) => 1, + &QueryTerm::Display(_) => 1, &QueryTerm::Functor(_) => 3, &QueryTerm::Inlined(ref term) => term.arity(), &QueryTerm::Is(_) => 2, @@ -747,6 +749,8 @@ pub enum ControlInstruction { CatchCall, CatchExecute, Deallocate, + DisplayCall, + DisplayExecute, Execute(Rc, usize), ExecuteN(usize), FunctorCall, @@ -767,6 +771,8 @@ impl ControlInstruction { &ControlInstruction::Call(_, _, _) => true, &ControlInstruction::CatchCall => true, &ControlInstruction::CatchExecute => true, + &ControlInstruction::DisplayCall => true, + &ControlInstruction::DisplayExecute => true, &ControlInstruction::Execute(_, _) => true, &ControlInstruction::CallN(_) => true, &ControlInstruction::ExecuteN(_) => true, diff --git a/src/prolog/codegen.rs b/src/prolog/codegen.rs index 9251622a..252fa1c1 100644 --- a/src/prolog/codegen.rs +++ b/src/prolog/codegen.rs @@ -247,6 +247,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> }, &QueryTerm::Catch(_) => code.push(Line::Control(ControlInstruction::CatchCall)), + &QueryTerm::Display(_) => + code.push(Line::Control(ControlInstruction::DisplayCall)), &QueryTerm::Functor(_) => code.push(Line::Control(ControlInstruction::FunctorCall)), &QueryTerm::Inlined(_) => @@ -281,6 +283,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> *ctrl = ControlInstruction::Execute(name, arity), ControlInstruction::CallN(arity) => *ctrl = ControlInstruction::ExecuteN(arity), + ControlInstruction::DisplayCall => + *ctrl = ControlInstruction::DisplayExecute, ControlInstruction::FunctorCall => *ctrl = ControlInstruction::FunctorExecute, ControlInstruction::CatchCall => diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index 67989799..c441436c 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -44,10 +44,19 @@ pub trait HeapCellValueFormatter { pub struct DisplayFormatter {} impl HeapCellValueFormatter for DisplayFormatter { - fn format_clause(&self, arity: usize, name: Rc, _: Option, + fn format_clause(&self, arity: usize, name: Rc, fixity: Option, state_stack: &mut Vec) { - self.format_struct(arity, name, state_stack); + if fixity.is_some() { + let mut new_name = String::from("'"); + new_name += name.as_ref(); + new_name += "'"; + + let name = Rc::new(new_name); + self.format_struct(arity, name, state_stack); + } else { + self.format_struct(arity, name, state_stack); + } } } diff --git a/src/prolog/io.rs b/src/prolog/io.rs index 8cbb748f..a50abf80 100644 --- a/src/prolog/io.rs +++ b/src/prolog/io.rs @@ -109,13 +109,17 @@ impl fmt::Display for ControlInstruction { &ControlInstruction::CatchCall => write!(f, "call_catch"), &ControlInstruction::CatchExecute => - write!(f, "execute_catch"), + write!(f, "execute_catch"), + &ControlInstruction::DisplayCall => + write!(f, "call_display"), + &ControlInstruction::DisplayExecute => + write!(f, "execute_display"), &ControlInstruction::ExecuteN(arity) => write!(f, "execute_N {}", arity), &ControlInstruction::FunctorCall => - write!(f, "functor_call"), + write!(f, "call_functor"), &ControlInstruction::FunctorExecute => - write!(f, "functor_execute"), + write!(f, "execute_functor"), &ControlInstruction::Deallocate => write!(f, "deallocate"), &ControlInstruction::Execute(ref name, arity) => diff --git a/src/prolog/iterators.rs b/src/prolog/iterators.rs index 52293a1b..17ba7847 100644 --- a/src/prolog/iterators.rs +++ b/src/prolog/iterators.rs @@ -40,6 +40,10 @@ impl<'a> QueryIterator<'a> { let state = TermIterState::Clause(0, ClauseType::Catch, terms); QueryIterator { state_stack: vec![state] } }, + &QueryTerm::Display(ref terms) => { + let state = TermIterState::Clause(0, ClauseType::Root, terms); + QueryIterator { state_stack: vec![state] } + }, &QueryTerm::Arg(ref terms) | &QueryTerm::Functor(ref terms) => { let state = TermIterState::Clause(0, ClauseType::Root, terms); @@ -277,6 +281,11 @@ impl<'a> ChunkedIterator<'a> arity = child_terms.len(); break; }, + &QueryTerm::Display(_) => { + result.push(term); + arity = 1; + break; + }, &QueryTerm::Arg(_) | &QueryTerm::Functor(_) => { result.push(term); diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 36cb2e03..8b25cb14 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -2,6 +2,8 @@ use prolog::and_stack::*; use prolog::ast::*; use prolog::builtins::*; use prolog::copier::*; +use prolog::heap_iter::*; +use prolog::heap_print::*; use prolog::num::{Integer, ToPrimitive, Zero}; use prolog::num::bigint::{BigInt, BigUint}; use prolog::num::rational::Ratio; @@ -254,7 +256,29 @@ impl MachineState { self.trail(r1); } + + fn print_var(&self, r: Ref, fmt: Fmt) -> String + where Fmt: HeapCellValueFormatter + { + let iter = HeapCellIterator::new(&self, r); + let mut printer = HeapCellPrinter::new(iter, fmt); + + printer.print() + } + pub(super) fn print_term(&self, addr: &Addr, fmt: Fmt) -> String + where Fmt: HeapCellValueFormatter + { + match addr { + &Addr::Con(ref c) => + format!("{}", c), + &Addr::Lis(h) | &Addr::HeapCell(h) | &Addr::Str(h) => + self.print_var(Ref::HeapCell(h), fmt), + &Addr::StackCell(fr, sc) => + self.print_var(Ref::StackCell(fr, sc), fmt) + } + } + fn unify(&mut self, a1: Addr, a2: Addr) { let mut pdl = vec![a1, a2]; @@ -1498,6 +1522,18 @@ impl MachineState { self.p += 1; }, + &ControlInstruction::DisplayCall => { + let result = self.print_term(&self[temp_v!(1)], DisplayFormatter {}); + println!("{}", result); + + self.p += 1; + }, + &ControlInstruction::DisplayExecute => { + let result = self.print_term(&self[temp_v!(1)], DisplayFormatter {}); + println!("{}", result); + + self.p = self.cp; + }, &ControlInstruction::Execute(ref name, arity) => self.try_execute_predicate(code_dir, name.clone(), arity), &ControlInstruction::ExecuteN(arity) => diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 7fe8d2bd..019e56e8 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -1,7 +1,6 @@ use prolog::ast::*; use prolog::builtins::*; use prolog::codegen::*; -use prolog::heap_iter::*; use prolog::heap_print::*; use prolog::fixtures::*; @@ -265,7 +264,9 @@ impl Machine { let h = self.ms.heap.h; self.ms.copy_and_align_ball_to_heap(); - EvalSession::QueryFailureWithException(self.print_term(&Addr::HeapCell(h))) + let msg = self.ms.print_term(&Addr::HeapCell(h), TermFormatter {}); + + EvalSession::QueryFailureWithException(msg) } else { EvalSession::QueryFailure } @@ -345,28 +346,6 @@ impl Machine { } } - fn print_var(&self, r: Ref) -> String - { - let disp = TermFormatter {}; - let iter = HeapCellIterator::new(&self.ms, r); - - let mut printer = HeapCellPrinter::new(iter, disp); - - printer.print() - } - - fn print_term(&self, addr: &Addr) -> String - { - match addr { - &Addr::Con(ref c) => - format!("{}", c), - &Addr::Lis(h) | &Addr::HeapCell(h) | &Addr::Str(h) => - self.print_var(Ref::HeapCell(h)), - &Addr::StackCell(fr, sc) => - self.print_var(Ref::StackCell(fr, sc)) - } - } - pub fn heap_view(&self, var_dir: &HeapVarDict) -> String { let mut result = String::new(); @@ -378,7 +357,7 @@ impl Machine { result += var.as_str(); result += " = "; - result += self.print_term(addr).as_str(); + result += self.ms.print_term(addr, TermFormatter {}).as_str(); } result diff --git a/src/prolog/parser b/src/prolog/parser index 159f82cd..d2d6cd53 160000 --- a/src/prolog/parser +++ b/src/prolog/parser @@ -1 +1 @@ -Subproject commit 159f82cd836192cc1970187b67b2fb44ef7e6c68 +Subproject commit d2d6cd53af484607b89f3a979f51db66b3710c84 -- 2.54.0