]> Repositorios git - scryer-prolog.git/commitdiff
slight polishing up, bug fixes
authorMark Thom <[email protected]>
Thu, 2 Feb 2017 23:09:18 +0000 (16:09 -0700)
committerMark Thom <[email protected]>
Thu, 2 Feb 2017 23:09:18 +0000 (16:09 -0700)
src/l1/ast.rs
src/l1/codegen.rs
src/l1/machine.rs
src/main.rs

index 74c509153e115fceefb59d4a05dcc0e14ea414db..25493f5b3023b8fa9187f5455820e30a6af67842 100644 (file)
@@ -31,7 +31,7 @@ pub enum Reg {
     Norm(usize)
 }
 
-impl Reg {    
+impl Reg {
     pub fn has_arg(&self) -> bool {
         match self {
             &Reg::ArgAndNorm(_, _) => true,
@@ -87,6 +87,17 @@ pub enum Addr {
     RegNum(usize)
 }
 
+#[derive(Clone)]
+pub enum HeapCellValue {
+    NamedStr(usize, Atom),
+    Ref(usize),
+    Str(usize),
+}
+
+pub type Heap = Vec<HeapCellValue>;
+
+pub type Registers = Vec<HeapCellValue>;
+
 impl Term {
     pub fn subterms(&self) -> usize {
         match self {
@@ -98,11 +109,11 @@ impl Term {
     pub fn name(&self) -> &Atom {
         match self {
             &Term::Atom(_, ref atom)
-            | &Term::Var(_, ref atom)                
+            | &Term::Var(_, ref atom)
             | &Term::Clause(_, ref atom, _) => atom
         }
     }
-    
+
     pub fn arity(&self) -> usize {
         match self {
             &Term::Atom(_, _) | &Term::Var(_, _) => 0,
index 6579ef0b95d0c1c28ce355ebb49038146705aadb..a62dc4074030f8e7682d4c8a2af873c5087dc88f 100644 (file)
@@ -255,8 +255,7 @@ fn var_term<'a, Target>(tm: &mut TermMarker<'a>,
     }
 }
 
-fn subterm_to_instr<'a, Target>(tm: &mut TermMarker<'a>,
-                                subterm: &'a Term)
+fn subterm_to_instr<'a, Target>(tm: &mut TermMarker<'a>, subterm: &'a Term)
                                 -> Target
     where Target: CompilationTarget<'a>
 {
@@ -274,7 +273,7 @@ fn compile_target<'a, Target>(term: &'a Term) -> Vec<Target>
     let iter       = Target::iter(term);
     let mut target = Vec::<Target>::new();
     let mut marker = TermMarker::new(term);
-
+    
     for term in iter {
         match term {
             TermRef::Atom(lvl, term, atom) =>
@@ -302,7 +301,7 @@ pub fn compile_fact(term: &Term) -> CompiledFact {
     compiled_fact
 }
 
-pub fn compile_query(term: &Term) -> CompiledQuery {
+pub fn compile_query<'a>(term: &'a Term) -> CompiledQuery {
     let mut compiled_query = compile_target(term);
 
     if let &Term::Clause(_, ref atom, ref terms) = term {
index 3ef4d2bca3e2db90b6b128a7df07eefd31d92fa9..c1bdd375fdd8c138df9c59985d6a3d04405551a4 100644 (file)
@@ -1,34 +1,25 @@
-use l1::ast::{Addr, Atom, CompiledFact, FactInstruction, QueryInstruction};
+use l1::ast::{Addr, Atom, CompiledFact, CompiledQuery,
+              FactInstruction, Heap, HeapCellValue, QueryInstruction,
+              Registers};
 
 use std::collections::HashMap;
 use std::vec::Vec;
 
-#[derive(Clone)]
-enum HeapCell {
-    NamedStr(usize, Atom),
-    Ref(usize),
-    Str(usize),
-}
-
 #[derive(Clone, Copy)]
 enum MachineMode {
     Read,
     Write
 }
 
-type Heap = Vec<HeapCell>;
-
-type Registers = Vec<HeapCell>;
-
 pub struct Machine {
     h : usize,
     s : usize,
     p : usize,
-    pub fail : bool,
+    code : CompiledFact,
+    code_dir : HashMap<(Atom, usize), usize>,
+    fail : bool,
     heap : Heap,
     mode : MachineMode,
-    pub code_dir : HashMap<(Atom, usize), usize>,
-    pub code : CompiledFact,
     registers : Registers
 }
 
@@ -37,15 +28,27 @@ impl Machine {
         Machine { h : 0,
                   s : 0,
                   p : 0,
+                  code : Vec::new(),
+                  code_dir : HashMap::new(),
                   fail : false,
                   heap : Vec::with_capacity(256),
                   mode : MachineMode::Write,
-                  code_dir : HashMap::new(),
-                  code : Vec::new(),
-                  registers : vec![HeapCell::Ref(0); 32] }
+                  registers : vec![HeapCellValue::Ref(0); 32] }
+    }
+
+    pub fn add_fact(&mut self, mut fact: CompiledFact, name: Atom, arity: usize)
+    {
+        let index = self.code.len();
+
+        self.code.append(&mut fact);
+        self.code_dir.insert((name, arity), index);
     }
 
-    fn lookup(&self, a: Addr) -> &HeapCell {
+    pub fn failed(&self) -> bool {
+        self.fail
+    }
+
+    fn lookup(&self, a: Addr) -> &HeapCellValue {
         match a {
             Addr::HeapCell(hc) => &self.heap[hc],
             Addr::RegNum(reg)  => &self.registers[reg]
@@ -56,12 +59,15 @@ impl Machine {
         let mut a = a;
 
         loop {
-            if let &HeapCell::Ref(value) = self.lookup(a) {
+            if let &HeapCellValue::Ref(value) = self.lookup(a) {
                 if let Addr::HeapCell(av) = a {
                     if value != av {
                         a = Addr::HeapCell(value);
                         continue;
                     }
+                } else {
+                    a = Addr::HeapCell(value);
+                    continue;
                 }
             }
 
@@ -69,21 +75,21 @@ impl Machine {
         };
     }
 
-    fn is_unbound(hc: &HeapCell, index: usize) -> bool {
+    fn is_unbound(hc: &HeapCellValue, index: usize) -> bool {
         match hc {
-            &HeapCell::Ref(r) => r == index,
+            &HeapCellValue::Ref(r) => r == index,
             _ => false
         }
     }
 
-    //TODO: try to compress this function. currently it is dog shit.
+    //TODO: try to compress this function.
     fn bind(&mut self, a: Addr, val: usize) {
         let mut a = a;
-        
+
         loop {
             match a {
                 Addr::RegNum(reg) => {
-                    if let HeapCell::Ref(hc) = self.registers[reg] {
+                    if let HeapCellValue::Ref(hc) = self.registers[reg] {
                         a = Addr::HeapCell(hc);
                     } else if Machine::is_unbound(&self.heap[val], val) {
                         self.heap[val] = self.registers[reg].clone();
@@ -91,18 +97,18 @@ impl Machine {
                     } else {
                         self.fail = true;
                         break;
-                    }                        
+                    }
                 },
                 Addr::HeapCell(hc) if Machine::is_unbound(&self.heap[hc], hc) => {
-                    self.heap[hc] = HeapCell::Ref(val);
+                    self.heap[hc] = HeapCellValue::Ref(val);
                     break;
                 },
-                Addr::HeapCell(hc) if Machine::is_unbound(&self.heap[val], val) => {                
-                    self.heap[val] = HeapCell::Ref(hc);
+                Addr::HeapCell(hc) if Machine::is_unbound(&self.heap[val], val) => {
+                    self.heap[val] = HeapCellValue::Ref(hc);
                     break;
                 },
                 _ => {
-                    self.fail = true;                    
+                    self.fail = true;
                     break;
                 }
             };
@@ -110,7 +116,7 @@ impl Machine {
     }
 
     fn unify(&mut self, a1: Addr, a2: Addr) {
-        let mut pdl : Vec<Addr> = vec![a1, a2];
+        let mut pdl = vec![a1, a2];
 
         self.fail = false;
 
@@ -120,16 +126,16 @@ impl Machine {
 
             if d1 != d2 {
                 match (self.lookup(d1), self.lookup(d2)) {
-                    (&HeapCell::Ref(hc), _) =>
+                    (&HeapCellValue::Ref(hc), _) =>
                         self.bind(d2, hc),
-                    (_, &HeapCell::Ref(hc)) =>
+                    (_, &HeapCellValue::Ref(hc)) =>
                         self.bind(d1, hc),
-                    (&HeapCell::Str(a1), &HeapCell::Str(a2)) => {
+                    (&HeapCellValue::Str(a1), &HeapCellValue::Str(a2)) => {
                         let r1 = &self.heap[a1];
                         let r2 = &self.heap[a2];
 
-                        if let &HeapCell::NamedStr(n1, ref f1) = r1 {
-                            if let &HeapCell::NamedStr(n2, ref f2) = r2 {
+                        if let &HeapCellValue::NamedStr(n1, ref f1) = r1 {
+                            if let &HeapCellValue::NamedStr(n2, ref f2) = r2 {
                                 if n1 == n2 && *f1 == *f2 {
                                     for i in 1 .. n1 {
                                         pdl.push(Addr::HeapCell(a1 + i));
@@ -162,12 +168,23 @@ impl Machine {
         }
     }
 
-    pub fn execute_query_instr<'a, 'b: 'a>(&'a mut self, instr: &'b QueryInstruction) {
+    pub fn execute_query(&mut self, query: &CompiledQuery) {
+        for instr in query {
+            self.execute_query_instr(instr);
+
+            if self.fail {
+                break;
+            }
+        }
+    }
+
+    fn execute_query_instr<'a, 'b: 'a>(&'a mut self, instr: &'b QueryInstruction) {
         match instr {
             &QueryInstruction::Call(ref name, arity) => {
                 // why is Option<&T> not Deref?!?!?
                 let compiled_fact_index =
-                    self.code_dir.get(&(name.clone(), arity)).map(|index| *index);
+                    self.code_dir.get(&(name.clone(), arity))
+                        .map(|index| *index);
 
                 match compiled_fact_index {
                     Some(compiled_fact_index) => {
@@ -178,8 +195,8 @@ impl Machine {
                 };
             }
             &QueryInstruction::PutStructure(_, ref name, arity, reg) => {
-                self.heap.push(HeapCell::Str(self.h + 1));
-                self.heap.push(HeapCell::NamedStr(arity, name.clone()));
+                self.heap.push(HeapCellValue::Str(self.h + 1));
+                self.heap.push(HeapCellValue::NamedStr(arity, name.clone()));
 
                 self.registers[reg] = self.heap[self.h].clone();
 
@@ -188,7 +205,7 @@ impl Machine {
             &QueryInstruction::PutValue(arg, norm) =>
                 self.registers[arg] = self.registers[norm].clone(),
             &QueryInstruction::PutVariable(arg, norm) => {
-                self.heap.push(HeapCell::Ref(self.h));
+                self.heap.push(HeapCellValue::Ref(self.h));
 
                 self.registers[norm] = self.heap[self.h].clone();
                 self.registers[arg]  = self.heap[self.h].clone();
@@ -196,7 +213,7 @@ impl Machine {
                 self.h += 1;
             },
             &QueryInstruction::SetVariable(reg) => {
-                self.heap.push(HeapCell::Ref(self.h));
+                self.heap.push(HeapCellValue::Ref(self.h));
                 self.registers[reg] = self.heap[self.h].clone();
 
                 self.h += 1;
@@ -215,10 +232,10 @@ impl Machine {
                 let addr = self.deref(Addr::RegNum(reg));
 
                 match self.lookup(addr) {
-                    &HeapCell::Str(a) => {
+                    &HeapCellValue::Str(a) => {
                         let result = &self.heap[a];
 
-                        if let &HeapCell::NamedStr(named_arity, ref named_str) = result {
+                        if let &HeapCellValue::NamedStr(named_arity, ref named_str) = result {
                             if arity == named_arity && *name == *named_str {
                                 self.s = a + 1;
                                 self.mode = MachineMode::Read;
@@ -227,13 +244,13 @@ impl Machine {
                             }
                         }
                     },
-                    &HeapCell::Ref(r) => {
-                        self.heap.push(HeapCell::Str(self.h + 1));
-                        self.heap.push(HeapCell::NamedStr(arity, name));
+                    &HeapCellValue::Ref(r) => {
+                        self.heap.push(HeapCellValue::Str(self.h + 1));
+                        self.heap.push(HeapCellValue::NamedStr(arity, name));
 
                         let h = self.h;
 
-                        self.bind(Addr::HeapCell(r), h);                        
+                        self.bind(Addr::HeapCell(r), h);
 
                         self.h += 2;
                         self.mode = MachineMode::Write;
@@ -251,7 +268,7 @@ impl Machine {
                 match self.mode {
                     MachineMode::Read  => self.registers[reg] = self.heap[self.s].clone(),
                     MachineMode::Write => {
-                        self.heap.push(HeapCell::Ref(self.h));
+                        self.heap.push(HeapCellValue::Ref(self.h));
                         self.registers[reg] = self.heap[self.h].clone();
                         self.h += 1;
                     }
@@ -285,6 +302,6 @@ impl Machine {
         self.fail = false;
         self.heap = Vec::with_capacity(256);
         self.mode = MachineMode::Write;
-        self.registers = vec![HeapCell::Ref(0); 32];
+        self.registers = vec![HeapCellValue::Ref(0); 32];
     }
 }
index 00878d92f12feb9f9dc0a0b3a21c7df7138ba484..e3fa65781213211a02d6a023ce13687ca2d43e16 100644 (file)
@@ -27,29 +27,23 @@ fn l1_repl() {
 
         match result {
             Ok(TopLevel::Fact(fact)) => {
-                let mut compiled_fact = compile_fact(&fact);
-                let index = ms.code.len();
+                let name  = fact.name().to_owned();
+                let arity = fact.arity();
+                let fact  = compile_fact(&fact);
 
-                ms.code.append(&mut compiled_fact);
-                ms.code_dir.insert((fact.name().clone(), fact.arity()), index);
+                ms.add_fact(fact, name, arity);
             },
             Ok(TopLevel::Query(query)) => {
                 let compiled_query = compile_query(&query);
                 
-                for instruction in &compiled_query {
-                    ms.execute_query_instr(instruction);
-
-                    if ms.fail {
-                        break;
-                    }
-                }
-
-                if ms.fail {
+                ms.execute_query(&compiled_query);
+                
+                if ms.failed() {
                     println!("no");
                 } else {
                     println!("yes");
-                }
-
+                }                
+                                
                 ms.reset_machine_state();
             },
             Err(_) => println!("Grammatical error of some kind!"),