]> Repositorios git - scryer-prolog.git/commitdiff
fix duplicate_term bug
authorMark Thom <[email protected]>
Mon, 15 Jan 2018 06:05:15 +0000 (23:05 -0700)
committerMark Thom <[email protected]>
Mon, 15 Jan 2018 06:05:15 +0000 (23:05 -0700)
src/prolog/ast.rs
src/prolog/builtins.rs
src/prolog/codegen.rs
src/prolog/copier.rs
src/prolog/io.rs
src/prolog/iterators.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/mod.rs
src/prolog/macros.rs
src/prolog/parser

index 6e5f550388bfc97395152cd0cbd6e86854f807e4..e489d099962bd9a2e1932cd8790c1054011a3370 100644 (file)
@@ -338,6 +338,7 @@ pub enum QueryTerm {
     Catch(Vec<Box<Term>>),    
     Cut,
     Display(Vec<Box<Term>>),
+    DuplicateTerm(Vec<Box<Term>>),
     Functor(Vec<Box<Term>>),
     Inlined(InlinedQueryTerm),
     Is(Vec<Box<Term>>),
@@ -350,8 +351,9 @@ impl QueryTerm {
         match self {
             &QueryTerm::Arg(_) => 3,
             &QueryTerm::Catch(_) => 3,
-            &QueryTerm::Throw(_) => 1,
+            &QueryTerm::Throw(_) => 1,            
             &QueryTerm::Display(_) => 1,
+            &QueryTerm::DuplicateTerm(_) => 2,
             &QueryTerm::Functor(_) => 3,
             &QueryTerm::Inlined(ref term) => term.arity(),
             &QueryTerm::Is(_) => 2,
@@ -720,7 +722,6 @@ pub enum ArithmeticInstruction {
 pub enum BuiltInInstruction {
     CleanUpBlock,
     CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
-    DuplicateTerm,
     EraseBall,
     Fail,
     GetArg,
@@ -751,6 +752,8 @@ pub enum ControlInstruction {
     Deallocate,
     DisplayCall,
     DisplayExecute,
+    DuplicateTermCall,
+    DuplicateTermExecute,
     Execute(Rc<Atom>, usize),
     ExecuteN(usize),
     FunctorCall,
@@ -773,6 +776,8 @@ impl ControlInstruction {
             &ControlInstruction::CatchExecute => true,
             &ControlInstruction::DisplayCall => true,
             &ControlInstruction::DisplayExecute => true,
+            &ControlInstruction::DuplicateTermCall => true,
+            &ControlInstruction::DuplicateTermExecute => true,
             &ControlInstruction::Execute(_, _)  => true,
             &ControlInstruction::CallN(_) => true,
             &ControlInstruction::ExecuteN(_) => true,
index d87ac5b2b4ba9e9a4a67c1d2ac984d28d78bafec..0048004f9b30387d69f653fe09369717f0e50967 100644 (file)
@@ -271,7 +271,9 @@ fn get_builtins() -> Code {
                 put_value!(perm_v!(3), 4),
                 put_value!(perm_v!(5), 5)],
          deallocate!(),
-         goto!(173, 3) // goto arg_/3.
+         goto!(173, 3), // goto arg_/3.
+         display!(), // display/1, 192.
+         proceed!()
     ]
 }
 
@@ -344,5 +346,7 @@ pub fn build_code_dir() -> (Code, CodeDir, OpDir)
     code_dir.insert((rc_atom!("arg"), 3), (PredicateKeyType::BuiltIn, 150));
     code_dir.insert((rc_atom!("integer"), 1), (PredicateKeyType::BuiltIn, 147));
 
+    code_dir.insert((rc_atom!("display"), 1), (PredicateKeyType::BuiltIn, 192));
+
     (builtin_code, code_dir, op_dir)
 }
index 252fa1c176ec2dc38d90ec2e9463177a386189bb..384423c394af465519ba96439d257b34f8a9a32b 100644 (file)
@@ -249,6 +249,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                 code.push(Line::Control(ControlInstruction::CatchCall)),
             &QueryTerm::Display(_) =>
                 code.push(Line::Control(ControlInstruction::DisplayCall)),
+            &QueryTerm::DuplicateTerm(_) =>
+                code.push(Line::Control(ControlInstruction::DuplicateTermCall)),
             &QueryTerm::Functor(_) =>
                 code.push(Line::Control(ControlInstruction::FunctorCall)),            
             &QueryTerm::Inlined(_) =>
@@ -285,6 +287,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                         *ctrl = ControlInstruction::ExecuteN(arity),
                     ControlInstruction::DisplayCall =>
                         *ctrl = ControlInstruction::DisplayExecute,
+                    ControlInstruction::DuplicateTermCall =>
+                        *ctrl = ControlInstruction::DuplicateTermExecute,
                     ControlInstruction::FunctorCall =>
                         *ctrl = ControlInstruction::FunctorExecute,
                     ControlInstruction::CatchCall =>
index 6c598543ccbedd186a7d6b294e0faf13f540a99f..ce738218a238fd209cc49342920504b108b729e6 100644 (file)
@@ -25,7 +25,7 @@ pub trait CopierTarget
 
         while scan < self.threshold() {
             match self[scan].clone() {
-                HeapCellValue::NamedStr(_, _, _) =>
+                HeapCellValue::NamedStr(..) =>
                     scan += 1,
                 HeapCellValue::Addr(a) =>
                     match a.clone() {
@@ -88,7 +88,7 @@ pub trait CopierTarget
                                 HeapCellValue::Addr(Addr::Str(o)) =>
                                     self[scan] = HeapCellValue::Addr(Addr::Str(o)),
                                 _ => {}
-                            }
+                            };
 
                             scan += 1;
                         },
index a50abf805da734f01eb1b44b10f164a1863f5a9b..5ff9bb27f86933a554864ea42fbe262c1cee23fb 100644 (file)
@@ -114,6 +114,10 @@ impl fmt::Display for ControlInstruction {
                 write!(f, "call_display"),
             &ControlInstruction::DisplayExecute =>
                 write!(f, "execute_display"),
+            &ControlInstruction::DuplicateTermCall =>
+                write!(f, "call_duplicate_term"),
+            &ControlInstruction::DuplicateTermExecute =>
+                write!(f, "execute_duplicate_term"),
             &ControlInstruction::ExecuteN(arity) =>
                 write!(f, "execute_N {}", arity),
             &ControlInstruction::FunctorCall =>
@@ -160,8 +164,6 @@ impl fmt::Display for BuiltInInstruction {
                 write!(f, "clean_up_block"),
             &BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) =>
                 write!(f, "number_test {}, {}, {} ", cmp, at_1, at_2),
-            &BuiltInInstruction::DuplicateTerm =>
-                write!(f, "duplicate_term X1"),
             &BuiltInInstruction::EraseBall =>
                 write!(f, "erase_ball"),
             &BuiltInInstruction::Fail =>
index 17ba78470ae2ff600b0fbb6e6d1f50926ba42884..90701d49a6204444a8b791d9531a3c632ce1e825 100644 (file)
@@ -40,7 +40,8 @@ impl<'a> QueryIterator<'a> {
                 let state = TermIterState::Clause(0, ClauseType::Catch, terms);
                 QueryIterator { state_stack: vec![state] }
             },
-            &QueryTerm::Display(ref terms) => {
+            &QueryTerm::Display(ref terms)
+          | &QueryTerm::DuplicateTerm(ref terms) => {
                 let state = TermIterState::Clause(0, ClauseType::Root, terms);
                 QueryIterator { state_stack: vec![state] }
             },
@@ -292,7 +293,7 @@ impl<'a> ChunkedIterator<'a>
                     arity = 3;
                     break;
                 },
-                &QueryTerm::Is(_) => {
+                &QueryTerm::Is(_) | &QueryTerm::DuplicateTerm(_) => {
                     result.push(term);
                     arity = 2;
                     break;
index 8b25cb14647051d748b10c2f1428bc6c3009eca4..53d4c4eefd5612e704bd6150031422bcb63d22ef 100644 (file)
@@ -48,8 +48,7 @@ impl<'a> CopierTarget for DuplicateTerm<'a> {
     }
 
     fn push(&mut self, hcv: HeapCellValue) {
-        self.state.heap.push(hcv);
-        self.state.heap.h += 1;
+        self.state.heap.push(hcv);        
     }
 
     fn store(&self, a: Addr) -> Addr {
@@ -1216,24 +1215,7 @@ impl MachineState {
                 };
 
                 self.p += 1;
-            },
-            &BuiltInInstruction::DuplicateTerm => {
-                let old_h = self.heap.h;
-
-                let a1 = self[temp_v!(1)].clone();
-                let a2 = self[temp_v!(2)].clone();
-
-                // drop the mutable references contained in gadget
-                // once the term has been duplicated.
-                {
-                    let mut gadget = DuplicateTerm::new(self);
-                    gadget.duplicate_term(a1);
-                }
-
-                self.unify(Addr::HeapCell(old_h), a2);
-
-                self.p += 1;
-            },
+            },            
             &BuiltInInstruction::GetArg => 
                 try_or_fail!(self, {
                     let val = self.try_get_arg();
@@ -1453,6 +1435,22 @@ impl MachineState {
 
         Ok(())
     }
+
+    fn duplicate_term(&mut self) {
+        let old_h = self.heap.h;
+
+        let a1 = self[temp_v!(1)].clone();
+        let a2 = self[temp_v!(2)].clone();
+
+        // drop the mutable references contained in gadget
+        // once the term has been duplicated.
+        {
+            let mut gadget = DuplicateTerm::new(self);
+            gadget.duplicate_term(a1);
+        }
+
+        self.unify(Addr::HeapCell(old_h), a2);        
+    }
     
     pub(super) fn execute_ctrl_instr(&mut self, code_dir: &CodeDir, instr: &ControlInstruction)
     {
@@ -1534,6 +1532,14 @@ impl MachineState {
                 
                 self.p = self.cp;
             },
+            &ControlInstruction::DuplicateTermCall => {
+                self.duplicate_term();
+                self.p += 1;
+            },
+            &ControlInstruction::DuplicateTermExecute => {
+                self.duplicate_term();
+                self.p = self.cp;
+            },
             &ControlInstruction::Execute(ref name, arity) =>
                 self.try_execute_predicate(code_dir, name.clone(), arity),
             &ControlInstruction::ExecuteN(arity) =>
index 019e56e83eb17af54a2289448c31565f725bee41..0562ef45b4049ed10f67da8851878d39ba348b4b 100644 (file)
@@ -356,7 +356,7 @@ impl Machine {
 
             result += var.as_str();
             result += " = ";
-
+            
             result += self.ms.print_term(addr, TermFormatter {}).as_str();
         }
 
index b5b11d18b03945d183622e6303590b7adb6bd33f..53cc21444257fef29dceb4605c02be493d118041 100644 (file)
@@ -276,7 +276,7 @@ macro_rules! succeed {
 
 macro_rules! duplicate_term {
     () => (
-        Line::BuiltIn(BuiltInInstruction::DuplicateTerm)
+        Line::Control(ControlInstruction::DuplicateTermCall)
     )
 }
 
@@ -393,3 +393,9 @@ macro_rules! infix {
         Fixity::In
     )
 }
+
+macro_rules! display {
+    () => (
+        Line::Control(ControlInstruction::DisplayCall)
+    )
+}
index d2d6cd53af484607b89f3a979f51db66b3710c84..dcf51680fb2f030ad2dcdd77237c8faedc8f7107 160000 (submodule)
@@ -1 +1 @@
-Subproject commit d2d6cd53af484607b89f3a979f51db66b3710c84
+Subproject commit dcf51680fb2f030ad2dcdd77237c8faedc8f7107