transition to MachineCodeIndices internally
This commit is contained in:
@@ -42,12 +42,9 @@ pub fn parse_code(wam: &mut Machine, buffer: &str) -> Result<TopLevelPacket, Par
|
|||||||
let atom_tbl = wam.atom_tbl();
|
let atom_tbl = wam.atom_tbl();
|
||||||
let flags = wam.machine_flags();
|
let flags = wam.machine_flags();
|
||||||
|
|
||||||
let index = MachineCodeIndices {
|
let indices = machine_code_indices!(&mut wam.code_dir, &mut wam.op_dir, &mut HashMap::new());
|
||||||
code_dir: &mut wam.code_dir,
|
|
||||||
op_dir: &mut wam.op_dir,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut worker = TopLevelWorker::new(buffer.as_bytes(), atom_tbl, flags, index);
|
let mut worker = TopLevelWorker::new(buffer.as_bytes(), atom_tbl, flags, indices);
|
||||||
worker.parse_code()
|
worker.parse_code()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +136,7 @@ fn compile_decl(wam: &mut Machine, tl: TopLevel, queue: Vec<TopLevel>) -> EvalSe
|
|||||||
let mut code = try_eval_session!(compile_relation(&tl, false, wam.machine_flags()));
|
let mut code = try_eval_session!(compile_relation(&tl, false, wam.machine_flags()));
|
||||||
try_eval_session!(compile_appendix(&mut code, queue, false, wam.machine_flags()));
|
try_eval_session!(compile_appendix(&mut code, queue, false, wam.machine_flags()));
|
||||||
|
|
||||||
if !code.is_empty() {
|
if !code.is_empty() {
|
||||||
wam.add_user_code(name, tl.arity(), code, tl.as_predicate().ok().unwrap())
|
wam.add_user_code(name, tl.arity(), code, tl.as_predicate().ok().unwrap())
|
||||||
} else {
|
} else {
|
||||||
EvalSession::from(SessionError::ImpermissibleEntry(String::from("no code generated.")))
|
EvalSession::from(SessionError::ImpermissibleEntry(String::from("no code generated.")))
|
||||||
@@ -289,7 +286,8 @@ fn compile_listing(wam: &mut Machine, src_str: &str, mut indices: MachineCodeInd
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_user_module(wam: &mut Machine, src_str: &str) -> EvalSession {
|
pub fn compile_user_module(wam: &mut Machine, src_str: &str) -> EvalSession {
|
||||||
let mut indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir());
|
let mut indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir(),
|
||||||
|
&mut HashMap::new());
|
||||||
|
|
||||||
if let Some(ref builtins) = wam.modules.get(&clause_name!("builtins")) {
|
if let Some(ref builtins) = wam.modules.get(&clause_name!("builtins")) {
|
||||||
indices.use_module(builtins);
|
indices.use_module(builtins);
|
||||||
|
|||||||
@@ -238,7 +238,8 @@ pub enum SystemClauseType {
|
|||||||
SetDoubleQuotes,
|
SetDoubleQuotes,
|
||||||
SkipMaxList,
|
SkipMaxList,
|
||||||
Succeed,
|
Succeed,
|
||||||
UnwindStack
|
UnwindStack,
|
||||||
|
CompileAndRunQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SystemClauseType {
|
impl SystemClauseType {
|
||||||
@@ -276,6 +277,7 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
|
&SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
|
||||||
&SystemClauseType::Succeed => clause_name!("$succeed"),
|
&SystemClauseType::Succeed => clause_name!("$succeed"),
|
||||||
&SystemClauseType::UnwindStack => clause_name!("$unwind_stack"),
|
&SystemClauseType::UnwindStack => clause_name!("$unwind_stack"),
|
||||||
|
&SystemClauseType::CompileAndRunQuery => clause_name!("$compile_and_run_query")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,6 +311,7 @@ impl SystemClauseType {
|
|||||||
("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
|
("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
|
||||||
("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
|
("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
|
||||||
("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
|
("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
|
||||||
|
("$compile_and_run_query", 1) => Some(SystemClauseType::CompileAndRunQuery),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -307,3 +307,5 @@ handle_ball(C, C, R) :- !, '$erase_ball', call(R).
|
|||||||
handle_ball(_, _, _) :- '$unwind_stack'.
|
handle_ball(_, _, _) :- '$unwind_stack'.
|
||||||
|
|
||||||
throw(Ball) :- '$set_ball'(Ball), '$unwind_stack'.
|
throw(Ball) :- '$set_ball'(Ball), '$unwind_stack'.
|
||||||
|
|
||||||
|
repl :- read(X), '$compile_and_run_query'(X), repl.
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ impl MachineError {
|
|||||||
};
|
};
|
||||||
|
|
||||||
stub.extend(err.into_iter());
|
stub.extend(err.into_iter());
|
||||||
|
|
||||||
MachineError { stub, from: ErrorProvenance::Constructed }
|
MachineError { stub, from: ErrorProvenance::Constructed }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use prolog::instructions::*;
|
|||||||
use prolog::and_stack::*;
|
use prolog::and_stack::*;
|
||||||
use prolog::copier::*;
|
use prolog::copier::*;
|
||||||
use prolog::heap_print::*;
|
use prolog::heap_print::*;
|
||||||
|
use prolog::machine::MachineCodeIndices;
|
||||||
use prolog::machine::machine_errors::*;
|
use prolog::machine::machine_errors::*;
|
||||||
use prolog::num::{BigInt, BigUint, Zero, One};
|
use prolog::num::{BigInt, BigUint, Zero, One};
|
||||||
use prolog::or_stack::*;
|
use prolog::or_stack::*;
|
||||||
@@ -46,19 +47,6 @@ impl<'a> CodeDirs<'a> {
|
|||||||
CodeDirs { code_dir, op_dir, modules }
|
CodeDirs { code_dir, op_dir, modules }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get(&self, name: ClauseName, arity: usize, in_mod: ClauseName) -> Option<CodeIndex>
|
|
||||||
{
|
|
||||||
match in_mod.as_str() {
|
|
||||||
"user" | "builtin" => self.code_dir.get(&(name, arity)).cloned(),
|
|
||||||
_ =>
|
|
||||||
match self.modules.get(&in_mod) {
|
|
||||||
Some(&Module { ref code_dir, .. }) =>
|
|
||||||
code_dir.get(&(name, arity)).cloned().map(CodeIndex::from),
|
|
||||||
None => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_internal(&self, name: ClauseName, arity: usize, in_mod: ClauseName) -> Option<ModuleCodeIndex> {
|
fn get_internal(&self, name: ClauseName, arity: usize, in_mod: ClauseName) -> Option<ModuleCodeIndex> {
|
||||||
self.modules.get(&in_mod)
|
self.modules.get(&in_mod)
|
||||||
.and_then(|ref module| module.code_dir.get(&(name, arity)))
|
.and_then(|ref module| module.code_dir.get(&(name, arity)))
|
||||||
@@ -90,9 +78,34 @@ pub trait CodeDirsAdapter<'a> {
|
|||||||
fn op_dir(&self) -> &OpDir;
|
fn op_dir(&self) -> &OpDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_code_index(code_dir: &CodeDir, modules: &ModuleDir, key: PredicateKey, module: ClauseName)
|
||||||
|
-> Option<CodeIndex>
|
||||||
|
{
|
||||||
|
match module.as_str() {
|
||||||
|
"user" | "builtin" => code_dir.get(&key).cloned(),
|
||||||
|
_ => modules.get(&module).and_then(|ref module| {
|
||||||
|
module.code_dir.get(&key).cloned().map(CodeIndex::from)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CodeDirsAdapter<'a> for MachineCodeIndices<'a> {
|
||||||
|
fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex> {
|
||||||
|
get_code_index(&self.code_dir, &self.modules, key, module)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_op(&self, key: OpDirKey) -> Option<(Specifier, usize, ClauseName)> {
|
||||||
|
self.op_dir.get(&key).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn op_dir(&self) -> &OpDir {
|
||||||
|
&self.op_dir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> CodeDirsAdapter<'a> for CodeDirs<'a> {
|
impl<'a> CodeDirsAdapter<'a> for CodeDirs<'a> {
|
||||||
fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex> {
|
fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex> {
|
||||||
self.get(key.0, key.1, module)
|
get_code_index(&self.code_dir, &self.modules, key, module)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_op(&self, key: OpDirKey) -> Option<(Specifier, usize, ClauseName)> {
|
fn get_op(&self, key: OpDirKey) -> Option<(Specifier, usize, ClauseName)> {
|
||||||
@@ -433,18 +446,18 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
|
fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
|
||||||
idx: CodeIndex, code_dirs: CodeDirs)
|
idx: CodeIndex, indices: MachineCodeIndices)
|
||||||
-> CallResult
|
-> CallResult
|
||||||
{
|
{
|
||||||
if machine_st.last_call {
|
if machine_st.last_call {
|
||||||
self.try_execute(machine_st, name, arity, idx, code_dirs)
|
self.try_execute(machine_st, name, arity, idx, indices)
|
||||||
} else {
|
} else {
|
||||||
self.try_call(machine_st, name, arity, idx, code_dirs)
|
self.try_call(machine_st, name, arity, idx, indices)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_call<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
|
fn try_call<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
|
||||||
idx: CodeIndex, code_dirs: CodeDirs)
|
idx: CodeIndex, indices: MachineCodeIndices<'a>)
|
||||||
-> CallResult
|
-> CallResult
|
||||||
{
|
{
|
||||||
match idx.0.borrow().0 {
|
match idx.0.borrow().0 {
|
||||||
@@ -453,7 +466,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
let module_name = idx.0.borrow().1.clone();
|
let module_name = idx.0.borrow().1.clone();
|
||||||
let h = machine_st.heap.h;
|
let h = machine_st.heap.h;
|
||||||
|
|
||||||
if let Some(ref idx) = code_dirs.get_code_index((name.clone(), arity), module_name.clone())
|
if let Some(ref idx) = indices.get_code_index((name.clone(), arity), module_name.clone())
|
||||||
{
|
{
|
||||||
if let IndexPtr::Index(compiled_tl_index) = idx.0.borrow().0 {
|
if let IndexPtr::Index(compiled_tl_index) = idx.0.borrow().0 {
|
||||||
call_at_index(machine_st, module_name, arity, compiled_tl_index);
|
call_at_index(machine_st, module_name, arity, compiled_tl_index);
|
||||||
@@ -481,7 +494,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn try_execute<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
fn try_execute<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
||||||
arity: usize, idx: CodeIndex, code_dirs: CodeDirs)
|
arity: usize, idx: CodeIndex, indices: MachineCodeIndices<'a>)
|
||||||
-> CallResult
|
-> CallResult
|
||||||
{
|
{
|
||||||
match idx.0.borrow().0 {
|
match idx.0.borrow().0 {
|
||||||
@@ -490,7 +503,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
let module_name = idx.0.borrow().1.clone();
|
let module_name = idx.0.borrow().1.clone();
|
||||||
let h = machine_st.heap.h;
|
let h = machine_st.heap.h;
|
||||||
|
|
||||||
if let Some(ref idx) = code_dirs.get_code_index((name.clone(), arity), module_name.clone())
|
if let Some(ref idx) = indices.get_code_index((name.clone(), arity), module_name.clone())
|
||||||
{
|
{
|
||||||
if let IndexPtr::Index(compiled_tl_index) = idx.0.borrow().0 {
|
if let IndexPtr::Index(compiled_tl_index) = idx.0.borrow().0 {
|
||||||
execute_at_index(machine_st, module_name, arity, compiled_tl_index);
|
execute_at_index(machine_st, module_name, arity, compiled_tl_index);
|
||||||
@@ -518,10 +531,10 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
|
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
|
||||||
code_dirs: CodeDirs)
|
indices: MachineCodeIndices<'a>) //code_dirs: CodeDirs)
|
||||||
-> CallResult
|
-> CallResult
|
||||||
{
|
{
|
||||||
match ct {
|
match ct {
|
||||||
&BuiltInClauseType::AcyclicTerm => {
|
&BuiltInClauseType::AcyclicTerm => {
|
||||||
let addr = machine_st[temp_v!(1)].clone();
|
let addr = machine_st[temp_v!(1)].clone();
|
||||||
machine_st.fail = machine_st.is_cyclic_term(addr);
|
machine_st.fail = machine_st.is_cyclic_term(addr);
|
||||||
@@ -564,7 +577,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
&BuiltInClauseType::Read => {
|
&BuiltInClauseType::Read => {
|
||||||
let mut reader = Reader::new(machine_st);
|
let mut reader = Reader::new(machine_st);
|
||||||
|
|
||||||
match reader.read_stdin(code_dirs.op_dir()) {
|
match reader.read_stdin(&indices.op_dir) {
|
||||||
Ok(offset) => {
|
Ok(offset) => {
|
||||||
let addr = reader.machine_st[temp_v!(1)].clone();
|
let addr = reader.machine_st[temp_v!(1)].clone();
|
||||||
reader.machine_st.unify(addr, Addr::HeapCell(offset));
|
reader.machine_st.unify(addr, Addr::HeapCell(offset));
|
||||||
@@ -574,7 +587,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
let stub = MachineError::functor_stub(clause_name!("read"), 1);
|
let stub = MachineError::functor_stub(clause_name!("read"), 1);
|
||||||
let err = MachineError::syntax_error(h, e);
|
let err = MachineError::syntax_error(h, e);
|
||||||
let err = reader.machine_st.error_form(err, stub);
|
let err = reader.machine_st.error_form(err, stub);
|
||||||
|
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -614,7 +627,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
},
|
},
|
||||||
&BuiltInClauseType::PartialString => {
|
&BuiltInClauseType::PartialString => {
|
||||||
@@ -679,7 +692,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize,
|
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize,
|
||||||
code_dirs: CodeDirs)
|
indices: MachineCodeIndices<'a>) //code_dirs: CodeDirs)
|
||||||
-> CallResult
|
-> CallResult
|
||||||
{
|
{
|
||||||
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
|
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
|
||||||
@@ -697,13 +710,13 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
},
|
},
|
||||||
ClauseType::BuiltIn(built_in) => {
|
ClauseType::BuiltIn(built_in) => {
|
||||||
machine_st.setup_built_in_call(built_in.clone());
|
machine_st.setup_built_in_call(built_in.clone());
|
||||||
self.call_builtin(machine_st, &built_in, code_dirs)?;
|
self.call_builtin(machine_st, &built_in, indices)?;
|
||||||
},
|
},
|
||||||
ClauseType::Inlined(inlined) =>
|
ClauseType::Inlined(inlined) =>
|
||||||
machine_st.execute_inlined(&inlined),
|
machine_st.execute_inlined(&inlined),
|
||||||
ClauseType::Op(..) | ClauseType::Named(..) =>
|
ClauseType::Op(..) | ClauseType::Named(..) =>
|
||||||
if let Some(idx) = code_dirs.get_code_index((name.clone(), arity), user) {
|
if let Some(idx) = indices.get_code_index((name.clone(), arity), user) {
|
||||||
self.context_call(machine_st, name, arity, idx, code_dirs)?;
|
self.context_call(machine_st, name, arity, idx, indices)?;
|
||||||
} else {
|
} else {
|
||||||
let h = machine_st.heap.h;
|
let h = machine_st.heap.h;
|
||||||
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
|
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
|
||||||
@@ -727,10 +740,10 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
|
|
||||||
impl CallPolicy for CWILCallPolicy {
|
impl CallPolicy for CWILCallPolicy {
|
||||||
fn context_call<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
fn context_call<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
||||||
arity: usize, idx: CodeIndex, code_dirs: CodeDirs)
|
arity: usize, idx: CodeIndex, indices: MachineCodeIndices<'a>)
|
||||||
-> CallResult
|
-> CallResult
|
||||||
{
|
{
|
||||||
self.prev_policy.context_call(machine_st, name, arity, idx, code_dirs)?;
|
self.prev_policy.context_call(machine_st, name, arity, idx, indices)?;
|
||||||
self.increment(machine_st)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -759,18 +772,17 @@ impl CallPolicy for CWILCallPolicy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
|
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
|
||||||
code_dirs: CodeDirs)
|
indices: MachineCodeIndices<'a>)
|
||||||
-> CallResult
|
-> CallResult
|
||||||
{
|
{
|
||||||
self.prev_policy.call_builtin(machine_st, ct, code_dirs)?;
|
self.prev_policy.call_builtin(machine_st, ct, indices)?;
|
||||||
self.increment(machine_st)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize,
|
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize, indices: MachineCodeIndices<'a>)
|
||||||
code_dirs: CodeDirs)
|
|
||||||
-> CallResult
|
-> CallResult
|
||||||
{
|
{
|
||||||
self.prev_policy.call_n(machine_st, arity, code_dirs)?;
|
self.prev_policy.call_n(machine_st, arity, indices)?;
|
||||||
self.increment(machine_st)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use prolog::and_stack::*;
|
|||||||
use prolog::copier::*;
|
use prolog::copier::*;
|
||||||
use prolog::heap_iter::*;
|
use prolog::heap_iter::*;
|
||||||
use prolog::heap_print::*;
|
use prolog::heap_print::*;
|
||||||
|
use prolog::machine::MachineCodeIndices;
|
||||||
use prolog::machine::machine_errors::*;
|
use prolog::machine::machine_errors::*;
|
||||||
use prolog::machine::machine_state::*;
|
use prolog::machine::machine_state::*;
|
||||||
use prolog::num::{Integer, Signed, ToPrimitive, Zero};
|
use prolog::num::{Integer, Signed, ToPrimitive, Zero};
|
||||||
@@ -2045,7 +2046,7 @@ impl MachineState {
|
|||||||
self.p += 1;
|
self.p += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_call_clause<'a>(&mut self, code_dirs: CodeDirs<'a>,
|
fn handle_call_clause<'a>(&mut self, indices: MachineCodeIndices<'a>,
|
||||||
call_policy: &mut Box<CallPolicy>,
|
call_policy: &mut Box<CallPolicy>,
|
||||||
cut_policy: &mut Box<CutPolicy>,
|
cut_policy: &mut Box<CutPolicy>,
|
||||||
ct: &ClauseType,
|
ct: &ClauseType,
|
||||||
@@ -2064,20 +2065,20 @@ impl MachineState {
|
|||||||
|
|
||||||
match ct {
|
match ct {
|
||||||
&ClauseType::BuiltIn(ref ct) =>
|
&ClauseType::BuiltIn(ref ct) =>
|
||||||
try_or_fail!(self, call_policy.call_builtin(self, ct, code_dirs)),
|
try_or_fail!(self, call_policy.call_builtin(self, ct, indices)),
|
||||||
&ClauseType::CallN =>
|
&ClauseType::CallN =>
|
||||||
try_or_fail!(self, call_policy.call_n(self, arity, code_dirs)),
|
try_or_fail!(self, call_policy.call_n(self, arity, indices)),
|
||||||
&ClauseType::Inlined(ref ct) =>
|
&ClauseType::Inlined(ref ct) =>
|
||||||
self.execute_inlined(ct),
|
self.execute_inlined(ct),
|
||||||
&ClauseType::Named(ref name, ref idx) | &ClauseType::Op(ref name, _, ref idx) =>
|
&ClauseType::Named(ref name, ref idx) | &ClauseType::Op(ref name, _, ref idx) =>
|
||||||
try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone(),
|
try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone(),
|
||||||
code_dirs)),
|
indices)),
|
||||||
&ClauseType::System(ref ct) =>
|
&ClauseType::System(ref ct) =>
|
||||||
try_or_fail!(self, self.system_call(ct, code_dirs, call_policy, cut_policy))
|
try_or_fail!(self, self.system_call(ct, indices, call_policy, cut_policy))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn execute_ctrl_instr<'a>(&mut self, code_dirs: CodeDirs<'a>,
|
pub(super) fn execute_ctrl_instr<'a>(&mut self, indices: MachineCodeIndices<'a>,
|
||||||
call_policy: &mut Box<CallPolicy>,
|
call_policy: &mut Box<CallPolicy>,
|
||||||
cut_policy: &mut Box<CutPolicy>,
|
cut_policy: &mut Box<CutPolicy>,
|
||||||
instr: &ControlInstruction)
|
instr: &ControlInstruction)
|
||||||
@@ -2086,7 +2087,7 @@ impl MachineState {
|
|||||||
&ControlInstruction::Allocate(num_cells) =>
|
&ControlInstruction::Allocate(num_cells) =>
|
||||||
self.allocate(num_cells),
|
self.allocate(num_cells),
|
||||||
&ControlInstruction::CallClause(ref ct, arity, _, lco, use_default_cp) =>
|
&ControlInstruction::CallClause(ref ct, arity, _, lco, use_default_cp) =>
|
||||||
self.handle_call_clause(code_dirs, call_policy, cut_policy, ct, arity, lco,
|
self.handle_call_clause(indices, call_policy, cut_policy, ct, arity, lco,
|
||||||
use_default_cp),
|
use_default_cp),
|
||||||
&ControlInstruction::Deallocate => self.deallocate(),
|
&ControlInstruction::Deallocate => self.deallocate(),
|
||||||
&ControlInstruction::JmpBy(arity, offset, _, lco) => {
|
&ControlInstruction::JmpBy(arity, offset, _, lco) => {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ static BUILTINS: &str = include_str!("../lib/builtins.pl");
|
|||||||
pub struct MachineCodeIndices<'a> {
|
pub struct MachineCodeIndices<'a> {
|
||||||
pub(super) code_dir: &'a mut CodeDir,
|
pub(super) code_dir: &'a mut CodeDir,
|
||||||
pub(super) op_dir: &'a mut OpDir,
|
pub(super) op_dir: &'a mut OpDir,
|
||||||
|
pub(super) modules: &'a mut ModuleDir
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MachineCodeIndices<'a> {
|
impl<'a> MachineCodeIndices<'a> {
|
||||||
@@ -45,6 +46,13 @@ impl<'a> MachineCodeIndices<'a> {
|
|||||||
ct => ct
|
ct => ct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(super) fn to_code_dirs(self) -> CodeDirs<'a> {
|
||||||
|
CodeDirs { code_dir: self.code_dir,
|
||||||
|
op_dir: self.op_dir,
|
||||||
|
modules: self.modules }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Machine {
|
pub struct Machine {
|
||||||
@@ -107,13 +115,15 @@ impl Machine {
|
|||||||
cut_policy: Box::new(DefaultCutPolicy {}),
|
cut_policy: Box::new(DefaultCutPolicy {}),
|
||||||
code: Code::new(),
|
code: Code::new(),
|
||||||
code_dir: CodeDir::new(),
|
code_dir: CodeDir::new(),
|
||||||
term_dir: TermDir::new(),
|
|
||||||
op_dir: default_op_dir(),
|
op_dir: default_op_dir(),
|
||||||
|
term_dir: TermDir::new(),
|
||||||
modules: HashMap::new(),
|
modules: HashMap::new(),
|
||||||
cached_query: None
|
cached_query: None
|
||||||
};
|
};
|
||||||
|
|
||||||
let indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir());
|
let indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir(),
|
||||||
|
&mut HashMap::new());
|
||||||
|
|
||||||
compile_listing(&mut wam, BUILTINS, indices);
|
compile_listing(&mut wam, BUILTINS, indices);
|
||||||
|
|
||||||
compile_user_module(&mut wam, LISTS);
|
compile_user_module(&mut wam, LISTS);
|
||||||
@@ -194,7 +204,8 @@ impl Machine {
|
|||||||
|
|
||||||
if let Some(mut module) = self.modules.remove(&name) {
|
if let Some(mut module) = self.modules.remove(&name) {
|
||||||
let result = {
|
let result = {
|
||||||
let mut indices = machine_code_indices!(&mut self.code_dir, &mut self.op_dir);
|
let mut indices = machine_code_indices!(&mut self.code_dir, &mut self.op_dir,
|
||||||
|
&mut self.modules);
|
||||||
indices.use_qualified_module(&mut module, &exports)
|
indices.use_qualified_module(&mut module, &exports)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -211,7 +222,8 @@ impl Machine {
|
|||||||
|
|
||||||
if let Some(mut module) = self.modules.remove(&name) {
|
if let Some(mut module) = self.modules.remove(&name) {
|
||||||
let result = {
|
let result = {
|
||||||
let mut indices = machine_code_indices!(&mut self.code_dir, &mut self.op_dir);
|
let mut indices = machine_code_indices!(&mut self.code_dir, &mut self.op_dir,
|
||||||
|
&mut self.modules);
|
||||||
indices.use_module(&mut module)
|
indices.use_module(&mut module)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -308,9 +320,11 @@ impl Machine {
|
|||||||
Line::Cut(ref cut_instr) =>
|
Line::Cut(ref cut_instr) =>
|
||||||
self.ms.execute_cut_instr(cut_instr, &mut self.cut_policy),
|
self.ms.execute_cut_instr(cut_instr, &mut self.cut_policy),
|
||||||
Line::Control(ref control_instr) => {
|
Line::Control(ref control_instr) => {
|
||||||
let code_dirs = CodeDirs::new(&self.code_dir, &self.op_dir,
|
let indices = machine_code_indices!(&mut self.code_dir, &mut self.op_dir,
|
||||||
&self.modules);
|
&mut self.modules);
|
||||||
self.ms.execute_ctrl_instr(code_dirs, &mut self.call_policy,
|
// let code_dirs = CodeDirs::new(&self.code_dir, &self.op_dir,
|
||||||
|
// &self.modules);
|
||||||
|
self.ms.execute_ctrl_instr(indices, &mut self.call_policy,
|
||||||
&mut self.cut_policy, control_instr)
|
&mut self.cut_policy, control_instr)
|
||||||
},
|
},
|
||||||
Line::Fact(ref fact) => {
|
Line::Fact(ref fact) => {
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
use prolog_parser::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
|
||||||
use prolog::instructions::*;
|
use prolog::instructions::*;
|
||||||
|
use prolog::machine::MachineCodeIndices;
|
||||||
use prolog::machine::machine_errors::*;
|
use prolog::machine::machine_errors::*;
|
||||||
use prolog::machine::machine_state::*;
|
use prolog::machine::machine_state::*;
|
||||||
use prolog::num::{ToPrimitive, Zero};
|
use prolog::num::{ToPrimitive, Zero};
|
||||||
use prolog::num::bigint::{BigInt};
|
use prolog::num::bigint::{BigInt};
|
||||||
|
//use prolog::term_writer::*;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@@ -164,6 +166,7 @@ impl MachineState {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn install_new_block(&mut self, r: RegType) -> usize {
|
fn install_new_block(&mut self, r: RegType) -> usize {
|
||||||
self.block = self.b;
|
self.block = self.b;
|
||||||
|
|
||||||
@@ -174,6 +177,7 @@ impl MachineState {
|
|||||||
self.block
|
self.block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn set_p(&mut self) {
|
fn set_p(&mut self) {
|
||||||
if self.last_call {
|
if self.last_call {
|
||||||
self.p = CodePtr::Local(self.cp.clone());
|
self.p = CodePtr::Local(self.cp.clone());
|
||||||
@@ -183,7 +187,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn system_call<'a>(&mut self, ct: &SystemClauseType,
|
pub(super) fn system_call<'a>(&mut self, ct: &SystemClauseType,
|
||||||
code_dirs: CodeDirs<'a>,
|
indices: MachineCodeIndices<'a>,
|
||||||
call_policy: &mut Box<CallPolicy>,
|
call_policy: &mut Box<CallPolicy>,
|
||||||
cut_policy: &mut Box<CutPolicy>,)
|
cut_policy: &mut Box<CutPolicy>,)
|
||||||
-> CallResult
|
-> CallResult
|
||||||
@@ -237,7 +241,7 @@ impl MachineState {
|
|||||||
let prev_block = self.block;
|
let prev_block = self.block;
|
||||||
|
|
||||||
if cut_policy.downcast_ref::<SCCCutPolicy>().is_err() {
|
if cut_policy.downcast_ref::<SCCCutPolicy>().is_err() {
|
||||||
let (r_c_w_h, r_c_wo_h) = code_dirs.get_cleaner_sites();
|
let (r_c_w_h, r_c_wo_h) = indices.to_code_dirs().get_cleaner_sites();
|
||||||
*cut_policy = Box::new(SCCCutPolicy::new(r_c_w_h, r_c_wo_h));
|
*cut_policy = Box::new(SCCCutPolicy::new(r_c_w_h, r_c_wo_h));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +435,14 @@ impl MachineState {
|
|||||||
return Err(err);
|
return Err(err);
|
||||||
},
|
},
|
||||||
&SystemClauseType::Succeed => {},
|
&SystemClauseType::Succeed => {},
|
||||||
&SystemClauseType::UnwindStack => self.unwind_stack()
|
&SystemClauseType::UnwindStack => self.unwind_stack(),
|
||||||
|
&SystemClauseType::CompileAndRunQuery => {}
|
||||||
|
/* let addr = self[temp_v!(1)].clone();
|
||||||
|
|
||||||
|
match term_write(&self, addr) {
|
||||||
|
Err(e) => machine_error
|
||||||
|
Ok(term) =>
|
||||||
|
}*/
|
||||||
};
|
};
|
||||||
|
|
||||||
self.set_p();
|
self.set_p();
|
||||||
|
|||||||
@@ -216,8 +216,9 @@ macro_rules! set_code_index {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! machine_code_indices {
|
macro_rules! machine_code_indices {
|
||||||
($code_dir:expr, $op_dir:expr) => ( //, $modules:expr) => (
|
($code_dir:expr, $op_dir:expr, $modules:expr) => ( //, $modules:expr) => (
|
||||||
MachineCodeIndices { code_dir: $code_dir, op_dir: $op_dir } //, modules: $modules }
|
MachineCodeIndices { code_dir: $code_dir, op_dir: $op_dir,
|
||||||
|
modules: $modules} //, modules: $modules }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,22 +3,22 @@ extern crate ordered_float;
|
|||||||
extern crate prolog_parser;
|
extern crate prolog_parser;
|
||||||
|
|
||||||
#[macro_use] pub mod instructions;
|
#[macro_use] pub mod instructions;
|
||||||
pub mod and_stack;
|
mod and_stack;
|
||||||
#[macro_use] pub mod macros;
|
#[macro_use] mod macros;
|
||||||
#[macro_use] pub mod allocator;
|
#[macro_use] mod allocator;
|
||||||
pub mod toplevel;
|
mod toplevel;
|
||||||
pub mod machine;
|
pub mod machine;
|
||||||
pub mod compile;
|
pub mod compile;
|
||||||
pub mod arithmetic;
|
mod arithmetic;
|
||||||
pub mod codegen;
|
mod codegen;
|
||||||
pub mod copier;
|
mod copier;
|
||||||
pub mod debray_allocator;
|
mod debray_allocator;
|
||||||
pub mod fixtures;
|
mod fixtures;
|
||||||
pub mod heap_iter;
|
mod heap_iter;
|
||||||
pub mod indexing;
|
mod indexing;
|
||||||
pub mod io;
|
pub mod io;
|
||||||
pub mod iterators;
|
mod iterators;
|
||||||
pub mod or_stack;
|
mod or_stack;
|
||||||
pub mod heap_print;
|
pub mod heap_print;
|
||||||
pub mod targets;
|
mod targets;
|
||||||
pub mod read;
|
mod read;
|
||||||
|
|||||||
43
src/prolog/term_writer.rs
Normal file
43
src/prolog/term_writer.rs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
use prolog_parser::ast::*;
|
||||||
|
|
||||||
|
use prolog::heap_iter::*;
|
||||||
|
use prolog::instructions::HeapCellValue;
|
||||||
|
use prolog::machine::machine_state::MachineState;
|
||||||
|
|
||||||
|
pub fn term_write(machine_st: &'a MachineState, addr: Addr) -> Result<Term, ParserError> {
|
||||||
|
let pre_order_iter = HCPreOrderIterator::new(machine_st, addr);
|
||||||
|
let post_order_iter = HCPostOrderIterator::new(pre_order_iter);
|
||||||
|
let acyclic_post_order_iter = HCAcyclicIterator::new(post_order_iter);
|
||||||
|
|
||||||
|
let mut stack = vec![];
|
||||||
|
|
||||||
|
for value in acyclic_post_order_iter {
|
||||||
|
match value {
|
||||||
|
HeapCellValue::NamedStr(arity, name, fixity)
|
||||||
|
if stack.len() >= arity => {
|
||||||
|
let subterms: Vec<_> = stack[stack.len() - arity ..].drain().collect();
|
||||||
|
stack.push(Box::new(Term::Clause(Cell::default(), name, subterms, fixity)));
|
||||||
|
},
|
||||||
|
HeapCellValue::Addr(Addr::Con(constant)) =>
|
||||||
|
stack.push(Box::new(Term::Constant(Cell::default(), constant))),
|
||||||
|
HeapCellValue::Addr(Addr::Lis(_))
|
||||||
|
if stack.len() >= 2 => {
|
||||||
|
let subterms: Vec<_> = stack[stack.len() - 2 ..].drain().collect();
|
||||||
|
stack.push(Box::new(Term::Cons(Cell::default(), subterms[0], subterms[1])));
|
||||||
|
},
|
||||||
|
HeapCellValue::Addr(Addr::HeapCell(h)) =>
|
||||||
|
stack.push(Box::new(Term::Var(Cell::default(), Rc::new(format!("_{}", h))))),
|
||||||
|
HeapCellValue::Addr(Addr::StackCell(fr, sc)) =>
|
||||||
|
stack.push(Box::new(Term::Var(Cell::default(), Rc::new(format!("_{}_{}", sc, fr))))),
|
||||||
|
_ => return Err(ParserError::IncompleteReduction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(term) = stack.pop() {
|
||||||
|
if stack.is_empty() {
|
||||||
|
return Ok(term);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(ParserError::IncompleteReduction)
|
||||||
|
}
|
||||||
@@ -496,8 +496,7 @@ impl RelationWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pre_query_term(&mut self, idx: &mut MachineCodeIndices, term: Term)
|
fn pre_query_term(&mut self, idx: &mut MachineCodeIndices, term: Term) -> Result<QueryTerm, ParserError>
|
||||||
-> Result<QueryTerm, ParserError>
|
|
||||||
{
|
{
|
||||||
match term {
|
match term {
|
||||||
Term::Clause(r, name, mut subterms, fixity) =>
|
Term::Clause(r, name, mut subterms, fixity) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user