]> Repositorios git - scryer-prolog.git/commitdiff
add call support for numeric comparisons.
authorMark Thom <[email protected]>
Sat, 20 Jan 2018 02:39:46 +0000 (19:39 -0700)
committerMark Thom <[email protected]>
Sat, 20 Jan 2018 02:39:46 +0000 (19:39 -0700)
src/prolog/ast.rs
src/prolog/builtins.rs
src/prolog/io.rs
src/prolog/machine/machine_state.rs
src/prolog/macros.rs
src/prolog/parser

index 1c2443251cd87ca5bdc5e4decb0aac388e893495..a9dc647c5caa4002665e32f857cf2ee1560b1d67 100644 (file)
@@ -742,11 +742,12 @@ pub enum BuiltInInstruction {
     GetBall,
     GetCurrentBlock,
     GetCutPoint(RegType),
+    DynamicCompareNumber(CompareNumberQT),
+    DynamicIs,
     InstallNewBlock,
     InternalCallN,
     IsAtomic(RegType),
-    IsInteger(RegType),
-    IsOnHeap,
+    IsInteger(RegType),    
     IsVar(RegType),
     ResetBlock,
     SetBall,
index 119a118465a9e09f6d23029ecdba9c629915c115..58e37a25778fc5f4b00a7e6ac2d70d48d2ba4b5f 100644 (file)
@@ -276,7 +276,19 @@ fn get_builtins(atom_tbl: TabledData<Atom>) -> Code {
          goto!(173, 3), // goto arg_/3.
          display!(), // display/1, 192.
          proceed!(),
-         is_on_heap!(), // is/2, 194.
+         dynamic_is!(), // is/2, 194.
+         proceed!(),
+         dynamic_num_test!(cmp_gt!()), // >/2, 196.
+         proceed!(),
+         dynamic_num_test!(cmp_lt!()), // </2, 198.
+         proceed!(),
+         dynamic_num_test!(cmp_gte!()), // >=/2, 200.
+         proceed!(),
+         dynamic_num_test!(cmp_lte!()), // <=/2, 202.
+         proceed!(),
+         dynamic_num_test!(cmp_ne!()), // =\=, 204.
+         proceed!(),
+         dynamic_num_test!(cmp_eq!()), // =:=, 206.
          proceed!()
     ]
 }
@@ -350,7 +362,14 @@ pub fn build_code_dir(atom_tbl: TabledData<Atom>) -> (Code, CodeDir, OpDir)
     code_dir.insert((tabled_rc!("arg", atom_tbl), 3), (PredicateKeyType::BuiltIn, 150));
     code_dir.insert((tabled_rc!("integer", atom_tbl), 1), (PredicateKeyType::BuiltIn, 147));
     code_dir.insert((tabled_rc!("display", atom_tbl), 1), (PredicateKeyType::BuiltIn, 192));
+    
     code_dir.insert((tabled_rc!("is", atom_tbl), 2), (PredicateKeyType::BuiltIn, 194));
+    code_dir.insert((tabled_rc!(">", atom_tbl), 2), (PredicateKeyType::BuiltIn, 196));
+    code_dir.insert((tabled_rc!("<", atom_tbl), 2), (PredicateKeyType::BuiltIn, 198));
+    code_dir.insert((tabled_rc!(">=", atom_tbl), 2), (PredicateKeyType::BuiltIn, 200));
+    code_dir.insert((tabled_rc!("<=", atom_tbl), 2), (PredicateKeyType::BuiltIn, 202));
+    code_dir.insert((tabled_rc!("=\\=", atom_tbl), 2), (PredicateKeyType::BuiltIn, 204));
+    code_dir.insert((tabled_rc!("=:=", atom_tbl), 2), (PredicateKeyType::BuiltIn, 206));
 
     (builtin_code, code_dir, op_dir)
 }
index fc1f9eeb454ab70bac9680a011b4d5de83d68240..1e56aee49bbaf900a3b13a87839a782b961f50d0 100644 (file)
@@ -165,6 +165,8 @@ 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::DynamicCompareNumber(cmp) =>
+                write!(f, "dynamic_number_test {}", cmp),
             &BuiltInInstruction::EraseBall =>
                 write!(f, "erase_ball"),
             &BuiltInInstruction::Fail =>
@@ -185,8 +187,8 @@ impl fmt::Display for BuiltInInstruction {
                 write!(f, "is_atomic {}", r),
             &BuiltInInstruction::IsInteger(r) =>
                 write!(f, "is_integer {}", r),
-            &BuiltInInstruction::IsOnHeap =>
-                write!(f, "call_is A1, A2"),  
+            &BuiltInInstruction::DynamicIs =>
+                write!(f, "call_is"),  
             &BuiltInInstruction::IsVar(r) =>
                 write!(f, "is_var {}", r),            
             &BuiltInInstruction::ResetBlock =>
index 3b286b9406b928d972362ae44b31d754ea07d7cc..d50a1c001e2c81f76253d3ce6143dd5cd1a215f7 100644 (file)
@@ -497,12 +497,12 @@ impl MachineState {
         Rc::new(BigInt::from_signed_bytes_le(&f(&u_n1, &u_n2).to_bytes_le()))
     }
 
-    fn arith_eval_by_metacall(&self) -> Result<Number, Vec<HeapCellValue>>
+    fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, Vec<HeapCellValue>>
     {        
         let instantiation_err = functor!(self.atom_tbl.clone(), "instantiation_error", 1,
                                          [heap_atom!("(is)/2", self.atom_tbl.clone())]);
 
-        let a = self[temp_v!(2)].clone();
+        let a = self[r].clone();
             
         if let &Addr::Con(Constant::Number(ref n)) = &a {
             return Ok(n.clone());
@@ -1289,6 +1289,20 @@ impl MachineState {
         Ok(())
     }
 
+    fn compare_numbers(&mut self, cmp: CompareNumberQT, n1: Number, n2: Number) {
+        self.fail = match cmp {
+            CompareNumberQT::GreaterThan if !(n1.gt(n2)) => true,
+            CompareNumberQT::GreaterThanOrEqual if !(n1.gte(n2)) => true,
+            CompareNumberQT::LessThan if !(n1.lt(n2)) => true,
+            CompareNumberQT::LessThanOrEqual if !(n1.lte(n2)) => true,
+            CompareNumberQT::NotEqual if !(n1.ne(n2)) => true,
+            CompareNumberQT::Equal if !(n1.eq(n2)) => true,
+            _ => false
+        };
+
+        self.p += 1;
+    }
+    
     pub(super) fn execute_built_in_instr(&mut self, code_dir: &CodeDir, instr: &BuiltInInstruction)
     {
         match instr {
@@ -1296,16 +1310,19 @@ impl MachineState {
                 let n1 = try_or_fail!(self, self.get_number(at_1));
                 let n2 = try_or_fail!(self, self.get_number(at_2));
 
-                self.fail = match cmp {
-                    CompareNumberQT::GreaterThan if !(n1.gt(n2)) => true,
-                    CompareNumberQT::GreaterThanOrEqual if !(n1.gte(n2)) => true,
-                    CompareNumberQT::LessThan if !(n1.lt(n2)) => true,
-                    CompareNumberQT::LessThanOrEqual if !(n1.lte(n2)) => true,
-                    CompareNumberQT::NotEqual if !(n1.ne(n2)) => true,
-                    CompareNumberQT::Equal if !(n1.eq(n2)) => true,
-                    _ => false
-                };
+                self.compare_numbers(cmp, n1, n2);
+            },
+            &BuiltInInstruction::DynamicCompareNumber(cmp) => {
+                let n1 = try_or_fail!(self, self.arith_eval_by_metacall(temp_v!(1)));
+                let n2 = try_or_fail!(self, self.arith_eval_by_metacall(temp_v!(2)));
 
+                self.compare_numbers(cmp, n1, n2);
+            },
+            &BuiltInInstruction::DynamicIs => {
+                let a = self[temp_v!(1)].clone();
+                let result = try_or_fail!(self, self.arith_eval_by_metacall(temp_v!(2)));
+
+                self.unify(a, Addr::Con(Constant::Number(result)));
                 self.p += 1;
             },
             &BuiltInInstruction::GetArg =>
@@ -1352,14 +1369,7 @@ impl MachineState {
                 self[r] = Addr::Con(c);
 
                 self.p += 1;
-            },
-            &BuiltInInstruction::IsOnHeap => {
-                let a1 = self[temp_v!(1)].clone();
-                let result = try_or_fail!(self, self.arith_eval_by_metacall());
-
-                self.unify(a1, Addr::Con(Constant::Number(result)));
-                self.p += 1;
-            },
+            },            
             &BuiltInInstruction::SetBall => {
                 let addr = self[temp_v!(1)].clone();
                 self.ball.0 = self.heap.h;
index 94d4cdca1c290da63b7cd36236149dae7043c585..6ad024a5fac48c4ec488a1dd55b792e2936b43a0 100644 (file)
@@ -418,8 +418,50 @@ macro_rules! display {
     )
 }
 
-macro_rules! is_on_heap {
+macro_rules! dynamic_is {
     () => (
-        Line::BuiltIn(BuiltInInstruction::IsOnHeap)
+        Line::BuiltIn(BuiltInInstruction::DynamicIs)
+    )
+}
+
+macro_rules! dynamic_num_test {
+    ($cmp:expr) => (
+        Line::BuiltIn(BuiltInInstruction::DynamicCompareNumber($cmp))
+    )
+}
+
+macro_rules! cmp_gt {
+    () => (
+        CompareNumberQT::GreaterThan
+    )
+}
+
+macro_rules! cmp_lt {
+    () => (
+        CompareNumberQT::LessThan
+    )
+}
+
+macro_rules! cmp_gte {
+    () => (
+        CompareNumberQT::GreaterThanOrEqual
+    )
+}
+
+macro_rules! cmp_lte {
+    () => (
+        CompareNumberQT::LessThanOrEqual
+    )
+}
+
+macro_rules! cmp_ne {
+    () => (
+        CompareNumberQT::NotEqual
+    )
+}
+
+macro_rules! cmp_eq {
+    () => (
+        CompareNumberQT::Equal
     )
 }
index 3b1dd579b411a440cc4b475471231fb6f9f2ada9..87d3b043bb178fb10818cd7cd34dd8c47651621d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 3b1dd579b411a440cc4b475471231fb6f9f2ada9
+Subproject commit 87d3b043bb178fb10818cd7cd34dd8c47651621d