]> Repositorios git - scryer-prolog.git/commitdiff
fix cut expansions.
authorMark Thom <[email protected]>
Sat, 7 Apr 2018 22:44:51 +0000 (16:44 -0600)
committerMark Thom <[email protected]>
Sat, 7 Apr 2018 22:44:51 +0000 (16:44 -0600)
src/prolog/ast.rs
src/prolog/codegen.rs
src/prolog/fixtures.rs
src/prolog/io.rs
src/prolog/iterators.rs
src/prolog/parser

index f30644653580e8ab210713b24f56e05cf255dda3..113084c1364aeefa5f81c71cf6c45f91c4847e2b 100644 (file)
@@ -101,7 +101,25 @@ impl GenContext {
     }
 }
 
-pub type Predicate = Vec<PredicateClause>;
+pub struct Predicate(pub Vec<PredicateClause>);
+
+impl Predicate {
+    pub fn name(&self) -> Option<ClauseName> {
+        self.0.first().and_then(|t| t.name())
+    }
+
+    pub fn arity(&self) -> usize {
+        if let Some(ref clause) = self.0.first() {
+            clause.arity()
+        } else {
+            0
+        }        
+    }
+    
+    pub fn clauses(self) -> Vec<PredicateClause> {
+        self.0
+    }
+}
 
 pub enum PredicateClause {
     Fact(Term),
@@ -260,7 +278,7 @@ impl TopLevel {
             &TopLevel::Declaration(_) => None,
             &TopLevel::Fact(ref term) => term.name(),
             &TopLevel::Predicate(ref clauses) =>
-                clauses.first().and_then(|ref term| term.name()),
+                clauses.0.first().and_then(|ref term| term.name()),
             &TopLevel::Query(_) => None,
             &TopLevel::Rule(Rule { ref head, .. }) =>
                 Some(head.0.clone())
@@ -272,18 +290,18 @@ impl TopLevel {
             &TopLevel::Declaration(_) => 0,
             &TopLevel::Fact(ref term) => term.arity(),
             &TopLevel::Predicate(ref clauses) =>
-                clauses.first().map(|t| t.arity()).unwrap_or(0),
+                clauses.0.first().map(|t| t.arity()).unwrap_or(0),
             &TopLevel::Query(_) => 0,
             &TopLevel::Rule(Rule { ref head, .. }) => head.1.len()
         }
     }
 
-    pub fn as_predicate(self) -> Option<Predicate> {
+    pub fn as_predicate(self) -> Result<Predicate, TopLevel> {
         match self {
-            TopLevel::Fact(term) => Some(vec![PredicateClause::Fact(term)]),
-            TopLevel::Rule(rule) => Some(vec![PredicateClause::Rule(rule)]),
-            TopLevel::Predicate(pred) => Some(pred),
-            _ => None
+            TopLevel::Fact(term) => Ok(Predicate(vec![PredicateClause::Fact(term)])),
+            TopLevel::Rule(rule) => Ok(Predicate(vec![PredicateClause::Rule(rule)])),
+            TopLevel::Predicate(pred) => Ok(pred),
+            _ => Err(self)
         }
     }
 }
@@ -669,7 +687,7 @@ pub type JumpStub = Vec<Term>;
 pub enum QueryTerm {
     Clause(Cell<RegType>, ClauseType, Vec<Box<Term>>),
     BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q.
-    UnblockedCut,
+    UnblockedCut(Cell<VarReg>),
     Jump(JumpStub)
 }
 
@@ -677,7 +695,7 @@ impl QueryTerm {
     pub fn arity(&self) -> usize {
         match self {
             &QueryTerm::Clause(_, _, ref subterms) => subterms.len(),
-            &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut => 0,
+            &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => 0,
             &QueryTerm::Jump(ref vars) => vars.len()
         }
     }
index 05b9bf2aafa6e6ab17fd69ad2527a732bc467774..1b31f0fff55bc095c1ff3fc1333d0fd2e268fdc8 100644 (file)
@@ -408,8 +408,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                 };
 
                 match *term {
-                    &QueryTerm::UnblockedCut =>
-                        code.push(set_cp!(self.marker.get(rc_atom!("!")))),                    
+                    &QueryTerm::UnblockedCut(ref cell) =>
+                        code.push(set_cp!(cell.get().norm())),
                     &QueryTerm::BlockedCut =>
                         code.push(if chunk_num == 0 {
                             Line::Cut(CutInstruction::NeckCut)
@@ -482,7 +482,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
     {
         // add a proceed to bookend any trailing cuts.
         match toc {
-            &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut => code.push(proceed!()),
+            &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()),
             _ => {}
         };
 
index 34a70751a4ceef6ce85407b14806fee7ee4ccec7..00590e54808787e0a79c6827bfc5617f86698fbb 100644 (file)
@@ -159,7 +159,8 @@ impl<'a> VariableFixtures<'a>
         for term_ref in iter {
             if let &TermRef::Var(lvl, cell, ref var) = &term_ref {
                 let mut status = self.0.remove(var)
-                    .unwrap_or((VarStatus::Temp(chunk_num, TempVarData::new(lt_arity)), Vec::new()));
+                    .unwrap_or((VarStatus::Temp(chunk_num, TempVarData::new(lt_arity)),
+                                Vec::new()));
 
                 status.1.push(cell);
 
index 89440174e383801321460be9115d853554a94f58..4dbe7043f5961c040d541d07c99aebe690114231 100644 (file)
@@ -492,7 +492,7 @@ fn compile_relation(tl: &TopLevel) -> Result<Code, ParserError>
         &TopLevel::Declaration(_) | &TopLevel::Query(_) =>
             Err(ParserError::ExpectedRel),
         &TopLevel::Predicate(ref clauses) =>
-            cg.compile_predicate(clauses),
+            cg.compile_predicate(&clauses.0),
         &TopLevel::Fact(ref fact) =>
             Ok(cg.compile_fact(fact)),
         &TopLevel::Rule(ref rule) =>
@@ -576,7 +576,7 @@ fn compile_decl(wam: &mut Machine, tl: TopLevel, queue: Vec<TopLevel>) -> EvalSe
             print_code(&code);
             
             if !code.is_empty() {
-                wam.add_user_code(name, tl.arity(), code, tl.as_predicate().unwrap())
+                wam.add_user_code(name, tl.arity(), code, tl.as_predicate().ok().unwrap())
             } else {
                 EvalSession::from(EvalError::ImpermissibleEntry(String::from("no code generated.")))
             }
index 8ed518e61054ec5ff2c8ef9cb5aee30662278d25..23c5aad4344a7e2d0496246eb309cb5946b94bc2 100644 (file)
@@ -2,6 +2,7 @@ use prolog::ast::*;
 
 use std::collections::VecDeque;
 use std::iter::*;
+use std::rc::Rc;
 use std::vec::Vec;
 
 pub struct QueryIterator<'a> {
@@ -50,8 +51,12 @@ impl<'a> QueryIterator<'a> {
                 let state = TermIterState::Clause(Level::Root, 0, cell, ct.clone(), terms);
                 QueryIterator { state_stack: vec![state] }
             },
-            &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut =>
+            &QueryTerm::BlockedCut =>
                 QueryIterator { state_stack: vec![] },
+            &QueryTerm::UnblockedCut(ref cell) => {
+                let state = TermIterState::Var(Level::Root, cell, rc_atom!("!"));
+                QueryIterator { state_stack: vec![state] }
+            },
             &QueryTerm::Jump(ref vars) => {
                 let state_stack = vars.iter().rev().map(|t| {
                     TermIterState::subterm_to_state(Level::Shallow, t)
@@ -322,7 +327,7 @@ impl<'a> ChunkedIterator<'a>
                     if contains_cut_var(vars.iter()) && !self.cut_var_in_head {
                         self.deep_cut_encountered = true;
                     }
-                    
+
                     break;
                 },
                 ChunkedTerm::BodyTerm(&QueryTerm::BlockedCut) => {
@@ -332,8 +337,8 @@ impl<'a> ChunkedIterator<'a>
                         self.deep_cut_encountered = true;
                     }
                 },
-                ChunkedTerm::BodyTerm(&QueryTerm::UnblockedCut) =>
-                    result.push(term),                
+                ChunkedTerm::BodyTerm(&QueryTerm::UnblockedCut(..)) =>
+                    result.push(term),
                 ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), _)) =>
                     result.push(term),
                 ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms)) => {
index 737d6ba091bb5909b0af31c221f290debc95bf2d..ba9bd0098e66227006b799a6c5c2c583fa9d9009 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 737d6ba091bb5909b0af31c221f290debc95bf2d
+Subproject commit ba9bd0098e66227006b799a6c5c2c583fa9d9009