]> Repositorios git - scryer-prolog.git/commitdiff
reuse defunct AND stack frames.
authorMark Thom <[email protected]>
Sat, 11 Nov 2017 23:01:29 +0000 (16:01 -0700)
committerMark Thom <[email protected]>
Sat, 11 Nov 2017 23:01:29 +0000 (16:01 -0700)
src/prolog/and_stack.rs
src/prolog/machine.rs

index 77a729f93567b546934fbf7f888fff28362f3bf7..f4d043da8ae645a31381d9aca7ed7f32476aa110 100644 (file)
@@ -49,9 +49,17 @@ impl AndStack {
         self.0.clear()
     }
 
-    pub fn pop(&mut self) {
-        self.0.pop();
-    }
+    pub fn resize(&mut self, fr: usize, n: usize) {                        
+        let len = self[fr].perms.len();               
+        
+        if len < n {
+            self[fr].perms.reserve(n - len);
+
+            for i in len .. n {                
+                self[fr].perms.push(Addr::StackCell(fr, i));
+            }
+        }
+    }    
 }
 
 impl Index<usize> for AndStack {
index 0d9246188bacac02248c644e1e19fccab2031a44..f22f3ba85f5299189f4682792caac0b734e0d8bc 100644 (file)
@@ -1510,11 +1510,34 @@ impl MachineState {
     {
         match instr {
             &ControlInstruction::Allocate(num_cells) => {
-                let num_frames = self.num_frames();
+                if let Some(ref or_fr) = self.or_stack.top() {
+                    let and_gi = if self.and_stack.len() > self.e {
+                        self.and_stack[self.e].global_index
+                    } else {
+                        0
+                    };
+                                       
+                    if and_gi <= or_fr.global_index {
+                        self.e = or_fr.e;
+                    }                    
+                }
+
+                if self.e + 1 < self.and_stack.len() {
+                    let index = self.e + 1;
+                    
+                    self.and_stack[index].e  = self.e;
+                    self.and_stack[index].cp = self.cp;
+
+                    self.and_stack.resize(index, num_cells);
+
+                    self.e = index;
+                } else {
+                    let num_frames = self.num_frames();
+
+                    self.and_stack.push(num_frames + 1, self.e, self.cp, num_cells);
+                    self.e = self.and_stack.len() - 1;
+                };
 
-                self.and_stack.push(num_frames + 1, self.e, self.cp, num_cells);
-                self.e = self.and_stack.len() - 1;
-                
                 self.p += 1;
             },
             &ControlInstruction::Call(ref name, arity, _) =>
@@ -1539,7 +1562,7 @@ impl MachineState {
 
                 self.cp = self.and_stack[e].cp;
                 self.e  = self.and_stack[e].e;
-                
+
                 self.p += 1;
             },
             &ControlInstruction::Execute(ref name, arity) =>