use references when executing instructions, not moves.
This commit is contained in:
@@ -17,7 +17,6 @@ pub enum Term {
|
|||||||
Var(Var)
|
Var(Var)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum MachineInstruction {
|
pub enum MachineInstruction {
|
||||||
GetStructure(Atom, usize, usize),
|
GetStructure(Atom, usize, usize),
|
||||||
PutStructure(Atom, usize, usize),
|
PutStructure(Atom, usize, usize),
|
||||||
|
|||||||
@@ -112,9 +112,9 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(&mut self, instr: MachineInstruction) {
|
pub fn execute<'a, 'b : 'a>(&'a mut self, instr: &'b MachineInstruction) {
|
||||||
match instr {
|
match instr {
|
||||||
MachineInstruction::GetStructure(name, arity, reg) => {
|
&MachineInstruction::GetStructure(ref name, arity, reg) => {
|
||||||
let addr = self.deref(Addr::RegNum(reg));
|
let addr = self.deref(Addr::RegNum(reg));
|
||||||
|
|
||||||
match self.lookup(addr) {
|
match self.lookup(addr) {
|
||||||
@@ -122,7 +122,7 @@ impl MachineState {
|
|||||||
let result = &self.heap[a];
|
let result = &self.heap[a];
|
||||||
|
|
||||||
if let &HeapCell::NamedStr(named_arity, ref named_str) = result {
|
if let &HeapCell::NamedStr(named_arity, ref named_str) = result {
|
||||||
if arity == named_arity && name == *named_str {
|
if arity == named_arity && *name == *named_str {
|
||||||
self.s = a + 1;
|
self.s = a + 1;
|
||||||
self.mode = MachineMode::Read;
|
self.mode = MachineMode::Read;
|
||||||
} else {
|
} else {
|
||||||
@@ -132,7 +132,7 @@ impl MachineState {
|
|||||||
},
|
},
|
||||||
&HeapCell::Ref(reg) => {
|
&HeapCell::Ref(reg) => {
|
||||||
self.heap.push(HeapCell::Str(self.h + 1));
|
self.heap.push(HeapCell::Str(self.h + 1));
|
||||||
self.heap.push(HeapCell::NamedStr(arity, name));
|
self.heap.push(HeapCell::NamedStr(arity, name.clone()));
|
||||||
|
|
||||||
let h = self.h;
|
let h = self.h;
|
||||||
|
|
||||||
@@ -146,25 +146,25 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
MachineInstruction::PutStructure(name, arity, reg) => {
|
&MachineInstruction::PutStructure(ref name, arity, reg) => {
|
||||||
self.heap.push(HeapCell::Str(self.h + 1));
|
self.heap.push(HeapCell::Str(self.h + 1));
|
||||||
self.heap.push(HeapCell::NamedStr(arity, name));
|
self.heap.push(HeapCell::NamedStr(arity, name.clone()));
|
||||||
|
|
||||||
self.registers[reg] = self.heap[self.h].clone();
|
self.registers[reg] = self.heap[self.h].clone();
|
||||||
|
|
||||||
self.h += 2;
|
self.h += 2;
|
||||||
},
|
},
|
||||||
MachineInstruction::SetVariable(reg) => {
|
&MachineInstruction::SetVariable(reg) => {
|
||||||
self.heap.push(HeapCell::Ref(self.h));
|
self.heap.push(HeapCell::Ref(self.h));
|
||||||
self.registers[reg] = self.heap[self.h].clone();
|
self.registers[reg] = self.heap[self.h].clone();
|
||||||
|
|
||||||
self.h += 1;
|
self.h += 1;
|
||||||
},
|
},
|
||||||
MachineInstruction::SetValue(reg) => {
|
&MachineInstruction::SetValue(reg) => {
|
||||||
self.heap.push(self.registers[reg].clone());
|
self.heap.push(self.registers[reg].clone());
|
||||||
self.h += 1;
|
self.h += 1;
|
||||||
},
|
},
|
||||||
MachineInstruction::UnifyVariable(reg) => {
|
&MachineInstruction::UnifyVariable(reg) => {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
MachineMode::Read => self.registers[reg] = self.heap[self.s].clone(),
|
MachineMode::Read => self.registers[reg] = self.heap[self.s].clone(),
|
||||||
MachineMode::Write => {
|
MachineMode::Write => {
|
||||||
@@ -176,7 +176,7 @@ impl MachineState {
|
|||||||
|
|
||||||
self.s += 1;
|
self.s += 1;
|
||||||
},
|
},
|
||||||
MachineInstruction::UnifyValue(reg) => {
|
&MachineInstruction::UnifyValue(reg) => {
|
||||||
let s = self.s;
|
let s = self.s;
|
||||||
|
|
||||||
match self.mode {
|
match self.mode {
|
||||||
|
|||||||
@@ -40,14 +40,14 @@ fn l0_repl<'a>() {
|
|||||||
println!("Program stored.");
|
println!("Program stored.");
|
||||||
},
|
},
|
||||||
Ok(TopLevel::Query(query)) => {
|
Ok(TopLevel::Query(query)) => {
|
||||||
if let Some(program) = ms.program.clone().take() {
|
if let Some(program) = ms.program.take() {
|
||||||
let query = compile_query(&query);
|
let query = compile_query(&query);
|
||||||
|
|
||||||
for instruction in query {
|
for instruction in &query {
|
||||||
ms.execute(instruction);
|
ms.execute(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
for instruction in program {
|
for instruction in &program {
|
||||||
ms.execute(instruction);
|
ms.execute(instruction);
|
||||||
|
|
||||||
if ms.fail {
|
if ms.fail {
|
||||||
@@ -62,6 +62,7 @@ fn l0_repl<'a>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ms.reset_heap();
|
ms.reset_heap();
|
||||||
|
ms.program = Some(program);
|
||||||
} else {
|
} else {
|
||||||
println!("No program to speak of.");
|
println!("No program to speak of.");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user