]> Repositorios git - scryer-prolog.git/commitdiff
add display predicate
authorMark Thom <[email protected]>
Mon, 15 Jan 2018 05:11:02 +0000 (22:11 -0700)
committerMark Thom <[email protected]>
Mon, 15 Jan 2018 05:11:02 +0000 (22:11 -0700)
README.md
src/prolog/ast.rs
src/prolog/codegen.rs
src/prolog/heap_print.rs
src/prolog/io.rs
src/prolog/iterators.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/mod.rs
src/prolog/parser

index 62319166a3ffaf745db8328d5b39b7b7accc3a04..14529d93680ffabd87613ad0243b428df6b891e5 100644 (file)
--- 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`
index 61572fd41246175306eaa8043f034c1e86a32d93..6e5f550388bfc97395152cd0cbd6e86854f807e4 100644 (file)
@@ -335,8 +335,9 @@ pub enum CompareNumberQT {
 pub enum QueryTerm {
     Arg(Vec<Box<Term>>),
     CallN(Vec<Box<Term>>),
-    Catch(Vec<Box<Term>>),
+    Catch(Vec<Box<Term>>),    
     Cut,
+    Display(Vec<Box<Term>>),
     Functor(Vec<Box<Term>>),
     Inlined(InlinedQueryTerm),
     Is(Vec<Box<Term>>),
@@ -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<Atom>, 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,
index 9251622aaef3d33abe3ac75d7d08e11fc3649054..252fa1c176ec2dc38d90ec2e9463177a386189bb 100644 (file)
@@ -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 =>
index 6798979947b00324e24946d91481ff839c8adcb1..c441436cc769d1a44c3e2fbbe55aaa55f73a8222 100644 (file)
@@ -44,10 +44,19 @@ pub trait HeapCellValueFormatter {
 pub struct DisplayFormatter {}
 
 impl HeapCellValueFormatter for DisplayFormatter {
-    fn format_clause(&self, arity: usize, name: Rc<Atom>, _: Option<Fixity>,
+    fn format_clause(&self, arity: usize, name: Rc<Atom>, fixity: Option<Fixity>,
                      state_stack: &mut Vec<TokenOrRedirect>)
     {
-        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);
+        }
     }
 }
 
index 8cbb748fced522d1c1d546ac5cb799413877a47d..a50abf805da734f01eb1b44b10f164a1863f5a9b 100644 (file)
@@ -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) =>
index 52293a1bf2247d3bdc4f4465a510d43f12d63fc1..17ba78470ae2ff600b0fbb6e6d1f50926ba42884 100644 (file)
@@ -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);
index 36cb2e0383b107565a232e7f129c544ff335b024..8b25cb14647051d748b10c2f1428bc6c3009eca4 100644 (file)
@@ -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<Fmt>(&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<Fmt>(&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) =>
index 7fe8d2bd575224386bc44321a38331cf2300e8b5..019e56e83eb17af54a2289448c31565f725bee41 100644 (file)
@@ -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
index 159f82cd836192cc1970187b67b2fb44ef7e6c68..d2d6cd53af484607b89f3a979f51db66b3710c84 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 159f82cd836192cc1970187b67b2fb44ef7e6c68
+Subproject commit d2d6cd53af484607b89f3a979f51db66b3710c84