fixes to binding.
This commit is contained in:
@@ -29,17 +29,8 @@ pub enum MachineInstruction {
|
|||||||
|
|
||||||
pub type Program = Vec<MachineInstruction>;
|
pub type Program = Vec<MachineInstruction>;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum Addr {
|
pub enum Addr {
|
||||||
HeapCell(usize),
|
HeapCell(usize),
|
||||||
RegNum(usize)
|
RegNum(usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Addr {
|
|
||||||
pub fn heap_offset(&self) -> usize {
|
|
||||||
match self {
|
|
||||||
&Addr::HeapCell(hc) => hc,
|
|
||||||
&Addr::RegNum(reg) => reg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ pub fn compile_fact<'a>(t: &'a Term) -> Program {
|
|||||||
if let &Term::Var(ref var) = t.as_ref() {
|
if let &Term::Var(ref var) = t.as_ref() {
|
||||||
if !variable_allocs.contains_key(var) {
|
if !variable_allocs.contains_key(var) {
|
||||||
variable_allocs.insert(var, counter);
|
variable_allocs.insert(var, counter);
|
||||||
|
|
||||||
fact.push(MachineInstruction::UnifyVariable(counter));
|
fact.push(MachineInstruction::UnifyVariable(counter));
|
||||||
counter += 1;
|
counter += 1;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::vec::{Vec};
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum HeapCell {
|
enum HeapCell {
|
||||||
NamedStr(usize, Atom),
|
NamedStr(usize, Atom),
|
||||||
Ref(usize), // these offsets are always in reference to cells on the Heap!
|
Ref(usize),
|
||||||
Str(usize),
|
Str(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,11 +53,11 @@ impl MachineState {
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
if let &HeapCell::Ref(value) = self.lookup(a) {
|
if let &HeapCell::Ref(value) = self.lookup(a) {
|
||||||
if value != a.heap_offset() {
|
if let Addr::HeapCell(av) = a {
|
||||||
a = Addr::HeapCell(value);
|
if value != av {
|
||||||
continue;
|
a = Addr::HeapCell(value);
|
||||||
} else {
|
continue;
|
||||||
return a;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,10 +65,10 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind(&mut self, a: Addr, val: Addr) {
|
fn bind(&mut self, a: Addr, val: usize) {
|
||||||
match a {
|
match a {
|
||||||
Addr::RegNum(reg) => self.registers[reg] = HeapCell::Ref(val.heap_offset()),
|
Addr::RegNum(reg) => self.registers[reg] = HeapCell::Ref(val),
|
||||||
Addr::HeapCell(hc) => self.heap[hc] = HeapCell::Ref(val.heap_offset()),
|
Addr::HeapCell(hc) => self.heap[hc] = HeapCell::Ref(val),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,8 +83,10 @@ impl MachineState {
|
|||||||
|
|
||||||
if d1 != d2 {
|
if d1 != d2 {
|
||||||
match (self.lookup(d1), self.lookup(d2)) {
|
match (self.lookup(d1), self.lookup(d2)) {
|
||||||
(&HeapCell::Ref(_), _) | (_, &HeapCell::Ref(_)) =>
|
(&HeapCell::Ref(hc), _) =>
|
||||||
self.bind(d1, d2),
|
self.bind(d2, hc),
|
||||||
|
(_, &HeapCell::Ref(hc)) =>
|
||||||
|
self.bind(d1, hc),
|
||||||
(&HeapCell::Str(a1), &HeapCell::Str(a2)) => {
|
(&HeapCell::Str(a1), &HeapCell::Str(a2)) => {
|
||||||
let r1 = &self.heap[a1];
|
let r1 = &self.heap[a1];
|
||||||
let r2 = &self.heap[a2];
|
let r2 = &self.heap[a2];
|
||||||
@@ -134,7 +136,7 @@ impl MachineState {
|
|||||||
|
|
||||||
let h = self.h;
|
let h = self.h;
|
||||||
|
|
||||||
self.bind(Addr::RegNum(reg), Addr::HeapCell(h));
|
self.bind(Addr::RegNum(reg), h);
|
||||||
|
|
||||||
self.h += 2;
|
self.h += 2;
|
||||||
self.mode = MachineMode::Write;
|
self.mode = MachineMode::Write;
|
||||||
|
|||||||
Reference in New Issue
Block a user