flatten CompiledQuery and CompiledFact in Code, remove CompiledQuery

This commit is contained in:
Mark Thom
2019-02-06 22:25:41 -07:00
parent 9f8dd56c3c
commit 046569b6a9
11 changed files with 179 additions and 126 deletions

View File

@@ -47,24 +47,40 @@ impl<'a> ConjunctInfo<'a>
fn mark_unsafe_vars(&self, mut unsafe_var_marker: UnsafeVarMarker, code: &mut Code) { fn mark_unsafe_vars(&self, mut unsafe_var_marker: UnsafeVarMarker, code: &mut Code) {
// target the last goal of the rule for handling unsafe variables. // target the last goal of the rule for handling unsafe variables.
// we use this weird logic to find the last goal. // we use this weird logic to find the last goal.
let index = if let &Line::Control(_) = code.last().unwrap() { let right_index = if let &Line::Control(_) = code.last().unwrap() {
code.len() - 2 code.len() - 2
} else { } else {
code.len() - 1 code.len() - 1
}; };
if let Line::Query(_) = &code[index] { let mut index = right_index;
if let Line::Query(_) = &code[right_index] {
while let Line::Query(_) = &code[index] { // index >= 0.
if index == 0 {
break;
} else {
index -= 1;
}
}
if let Line::Query(_) = &code[index] {} else {
index += 1;
}
unsafe_var_marker.record_unsafe_vars(&self.perm_vs); unsafe_var_marker.record_unsafe_vars(&self.perm_vs);
for line in code.iter_mut() { for line in code.iter_mut() {
if let &mut Line::Query(ref mut query) = line { if let &mut Line::Query(ref mut query_instr) = line {
unsafe_var_marker.mark_safe_vars(query); unsafe_var_marker.mark_safe_vars(query_instr);
} }
} }
}
if let &mut Line::Query(ref mut query) = &mut code[index] { for index in index .. right_index + 1 {
unsafe_var_marker.mark_unsafe_vars(query); if let &mut Line::Query(ref mut query_instr) = &mut code[index] {
unsafe_var_marker.mark_unsafe_vars(query_instr);
}
}
} }
} }
} }
@@ -110,7 +126,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target); self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
if !target.is_empty() { if !target.is_empty() {
code.push(Line::Query(target)); for query_instr in target {
code.push(Line::Query(query_instr));
}
} }
vr.get().norm() vr.get().norm()
@@ -445,7 +463,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
term_loc, &mut target); term_loc, &mut target);
if !target.is_empty() { if !target.is_empty() {
code.push(Line::Query(target)); for query_instr in target {
code.push(Line::Query(query_instr));
}
} }
if use_default_call_policy { if use_default_call_policy {
@@ -455,9 +475,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
} }
}, },
&Term::Constant(_, ref c @ Constant::Number(_)) => { &Term::Constant(_, ref c @ Constant::Number(_)) => {
code.push(query![put_constant!(Level::Shallow, code.push(Line::Query(put_constant!(Level::Shallow,
c.clone(), c.clone(),
temp_v!(1))]); temp_v!(1))));
if use_default_call_policy { if use_default_call_policy {
code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1)))) code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))))
@@ -490,7 +510,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
term_loc, &mut target); term_loc, &mut target);
if !target.is_empty() { if !target.is_empty() {
code.push(Line::Query(target)); for query_instr in target {
code.push(Line::Query(query_instr));
}
} }
code.push(get_level_and_unify!(cell.get().norm())); code.push(get_level_and_unify!(cell.get().norm()));
@@ -574,7 +596,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
if !fact.is_empty() { if !fact.is_empty() {
unsafe_var_marker = self.mark_unsafe_fact_vars(&mut fact); unsafe_var_marker = self.mark_unsafe_fact_vars(&mut fact);
code.push(Line::Fact(fact));
for fact_instr in fact {
code.push(Line::Fact(fact_instr));
}
} }
let iter = ChunkedIterator::from_rule_body(p1, clauses); let iter = ChunkedIterator::from_rule_body(p1, clauses);
@@ -637,7 +662,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
self.mark_unsafe_fact_vars(&mut compiled_fact); self.mark_unsafe_fact_vars(&mut compiled_fact);
if !compiled_fact.is_empty() { if !compiled_fact.is_empty() {
code.push(Line::Fact(compiled_fact)); for fact_instr in compiled_fact {
code.push(Line::Fact(fact_instr));
}
} }
} }
@@ -654,7 +681,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
let query = self.compile_target(iter, term_loc, is_exposed); let query = self.compile_target(iter, term_loc, is_exposed);
if !query.is_empty() { if !query.is_empty() {
code.push(Line::Query(query)); for query_instr in query {
code.push(Line::Query(query_instr));
}
} }
Self::add_conditional_call(code, term, num_perm_vars_left); Self::add_conditional_call(code, term, num_perm_vars_left);

View File

@@ -18,10 +18,8 @@ fn print_code(code: &Code) {
match clause { match clause {
&Line::Arithmetic(ref arith) => &Line::Arithmetic(ref arith) =>
println!("{}", arith), println!("{}", arith),
&Line::Fact(ref fact) => &Line::Fact(ref fact_instr) =>
for fact_instr in fact { println!("{}", fact_instr),
println!("{}", fact_instr);
},
&Line::Cut(ref cut) => &Line::Cut(ref cut) =>
println!("{}", cut), println!("{}", cut),
&Line::Choice(ref choice) => &Line::Choice(ref choice) =>
@@ -32,10 +30,8 @@ fn print_code(code: &Code) {
println!("{}", choice), println!("{}", choice),
&Line::Indexing(ref indexing) => &Line::Indexing(ref indexing) =>
println!("{}", indexing), println!("{}", indexing),
&Line::Query(ref query) => &Line::Query(ref query_instr) =>
for query_instr in query { println!("{}", query_instr)
println!("{}", query_instr);
}
} }
} }
} }
@@ -147,9 +143,9 @@ pub fn compile_term(wam: &mut Machine, packet: TopLevelPacket) -> EvalSession
Err(e) => EvalSession::from(e) Err(e) => EvalSession::from(e)
}, },
TopLevelPacket::Decl(TopLevel::Declaration(decl), _) => { TopLevelPacket::Decl(TopLevel::Declaration(decl), _) => {
let mut compiler = ListingCompiler::new(&wam.code_repo); let mut compiler = ListingCompiler::new(&wam.code_repo, wam.code_size());
let indices = try_eval_session!(compile_decl(wam, &mut compiler, decl)); let indices = try_eval_session!(compile_decl(wam, &mut compiler, decl));
try_eval_session!(compiler.add_code(wam, vec![], indices)); try_eval_session!(compiler.add_code(wam, vec![], indices));
EvalSession::EntrySuccess EvalSession::EntrySuccess
@@ -166,6 +162,7 @@ struct GatherResult {
} }
pub struct ListingCompiler { pub struct ListingCompiler {
code_size_offset: usize,
non_counted_bt_preds: HashSet<PredicateKey>, non_counted_bt_preds: HashSet<PredicateKey>,
module: Option<Module>, module: Option<Module>,
user_term_dir: TermDir, user_term_dir: TermDir,
@@ -175,9 +172,11 @@ pub struct ListingCompiler {
impl ListingCompiler { impl ListingCompiler {
#[inline] #[inline]
pub fn new(code_repo: &CodeRepo) -> Self { pub fn new(code_repo: &CodeRepo, code_size_offset: usize) -> Self {
ListingCompiler { ListingCompiler {
module: None, non_counted_bt_preds: HashSet::new(), code_size_offset,
non_counted_bt_preds: HashSet::new(),
module: None,
user_term_dir: TermDir::new(), user_term_dir: TermDir::new(),
orig_term_expansion_lens: code_repo.term_dir_entry_len((clause_name!("term_expansion"), 2)), orig_term_expansion_lens: code_repo.term_dir_entry_len((clause_name!("term_expansion"), 2)),
orig_goal_expansion_lens: code_repo.term_dir_entry_len((clause_name!("goal_expansion"), 2)), orig_goal_expansion_lens: code_repo.term_dir_entry_len((clause_name!("goal_expansion"), 2)),
@@ -239,8 +238,8 @@ impl ListingCompiler {
.unwrap_or(ClauseName::BuiltIn("user")) .unwrap_or(ClauseName::BuiltIn("user"))
} }
fn generate_code(&mut self, decls: Vec<PredicateCompileQueue>, fn generate_code(&mut self, decls: Vec<PredicateCompileQueue>, wam: &Machine,
wam: &Machine, code_dir: &mut CodeDir) code_dir: &mut CodeDir)
-> Result<Code, SessionError> -> Result<Code, SessionError>
{ {
let mut code = vec![]; let mut code = vec![];
@@ -253,7 +252,7 @@ impl ListingCompiler {
let non_counted_bt = self.non_counted_bt_preds.contains(&(name.clone(), arity)); let non_counted_bt = self.non_counted_bt_preds.contains(&(name.clone(), arity));
let p = code.len() + wam.code_size(); let p = code.len() + self.code_size_offset;
let mut decl_code = compile_relation(&TopLevel::Predicate(decl), non_counted_bt, let mut decl_code = compile_relation(&TopLevel::Predicate(decl), non_counted_bt,
wam.machine_flags())?; wam.machine_flags())?;
@@ -382,11 +381,9 @@ impl ListingCompiler {
-> Result<GatherResult, SessionError> -> Result<GatherResult, SessionError>
{ {
let flags = wam.machine_flags(); let flags = wam.machine_flags();
let wam_indices = &mut wam.indices; let atom_tbl = wam.indices.atom_tbl.clone();
let atom_tbl = wam_indices.atom_tbl.clone();
let mut worker = TopLevelBatchWorker::new(src, atom_tbl.clone(), flags, let mut worker = TopLevelBatchWorker::new(src, atom_tbl.clone(), flags,
wam_indices, &mut wam.policies, &mut wam.indices, &mut wam.policies,
&mut wam.code_repo); &mut wam.code_repo);
let mut toplevel_results = vec![]; let mut toplevel_results = vec![];
@@ -463,10 +460,24 @@ fn compile_work<R: Read>(compiler: &mut ListingCompiler, wam: &mut Machine, src:
EvalSession::EntrySuccess EvalSession::EntrySuccess
} }
/* This is a truncated version of compile_user_module, used for
compiling code composing special forms, ie. the code that calls
M:verify_attributes on attributed variables. */
pub fn compile_special_form<R: Read>(wam: &mut Machine, src: R) -> Result<Code, SessionError>
{
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
setup_indices(wam, &mut indices)?;
let mut compiler = ListingCompiler::new(&wam.code_repo, 0);
let results = compiler.gather_items(wam, src, &mut indices)?;
compiler.generate_code(results.worker_results, wam, &mut indices.code_dir)
}
#[inline] #[inline]
pub fn compile_listing<R: Read>(wam: &mut Machine, src: R, indices: IndexStore) -> EvalSession pub fn compile_listing<R: Read>(wam: &mut Machine, src: R, indices: IndexStore) -> EvalSession
{ {
let mut compiler = ListingCompiler::new(&wam.code_repo); let mut compiler = ListingCompiler::new(&wam.code_repo, wam.code_size());
match compile_work(&mut compiler, wam, src, indices) { match compile_work(&mut compiler, wam, src, indices) {
EvalSession::Error(e) => EvalSession::Error(compiler.drop_expansions(wam, e)), EvalSession::Error(e) => EvalSession::Error(compiler.drop_expansions(wam, e)),

View File

@@ -197,42 +197,38 @@ impl UnsafeVarMarker {
} }
} }
pub fn mark_safe_vars(&mut self, query: &mut CompiledQuery) { pub fn mark_safe_vars(&mut self, query_instr: &mut QueryInstruction) {
for query_instr in query.iter_mut() { match query_instr {
match query_instr { &mut QueryInstruction::PutVariable(RegType::Temp(r), _) =>
&mut QueryInstruction::PutVariable(RegType::Temp(r), _) => if let Some(found) = self.unsafe_vars.get_mut(&RegType::Temp(r)) {
if let Some(found) = self.unsafe_vars.get_mut(&RegType::Temp(r)) { *found = true;
*found = true; },
}, &mut QueryInstruction::SetVariable(reg) =>
&mut QueryInstruction::SetVariable(reg) => if let Some(found) = self.unsafe_vars.get_mut(&reg) {
if let Some(found) = self.unsafe_vars.get_mut(&reg) { *found = true;
*found = true; },
}, _ => {}
_ => {}
}
} }
} }
pub fn mark_unsafe_vars(&mut self, query: &mut CompiledQuery) pub fn mark_unsafe_vars(&mut self, query_instr: &mut QueryInstruction)
{ {
for query_instr in query.iter_mut() { match query_instr {
match query_instr { &mut QueryInstruction::PutValue(RegType::Perm(i), arg) =>
&mut QueryInstruction::PutValue(RegType::Perm(i), arg) => if let Some(found) = self.unsafe_vars.get_mut(&RegType::Perm(i)) {
if let Some(found) = self.unsafe_vars.get_mut(&RegType::Perm(i)) { if !*found {
if !*found { *found = true;
*found = true; *query_instr = QueryInstruction::PutUnsafeValue(i, arg);
*query_instr = QueryInstruction::PutUnsafeValue(i, arg); }
} },
}, &mut QueryInstruction::SetValue(reg) =>
&mut QueryInstruction::SetValue(reg) => if let Some(found) = self.unsafe_vars.get_mut(&reg) {
if let Some(found) = self.unsafe_vars.get_mut(&reg) { if !*found {
if !*found { *found = true;
*found = true; *query_instr = QueryInstruction::SetLocalValue(reg);
*query_instr = QueryInstruction::SetLocalValue(reg); }
} },
}, _ => {}
_ => {}
};
} }
} }
} }

View File

@@ -216,6 +216,7 @@ pub struct CodeRepo {
pub(super) term_expanders: Code, pub(super) term_expanders: Code,
pub(super) code: Code, pub(super) code: Code,
pub(super) in_situ_code: Code, pub(super) in_situ_code: Code,
pub(super) verify_attrs_code: Code,
pub(super) term_dir: TermDir pub(super) term_dir: TermDir
} }
@@ -248,6 +249,7 @@ pub enum SystemClauseType {
GetSCCCleaner, GetSCCCleaner,
InstallSCCCleaner, InstallSCCCleaner,
InstallInferenceCounter, InstallInferenceCounter,
ModuleOf,
RemoveCallPolicyCheck, RemoveCallPolicyCheck,
RemoveInferenceCounter, RemoveInferenceCounter,
RestoreCutPolicy, RestoreCutPolicy,
@@ -262,6 +264,7 @@ pub enum SystemClauseType {
GetDoubleQuotes, GetDoubleQuotes,
InstallNewBlock, InstallNewBlock,
ResetBlock, ResetBlock,
RestoreCodePtrFromSpecialFormCP,
SetBall, SetBall,
SetCutPointByDefault(RegType), SetCutPointByDefault(RegType),
SetDoubleQuotes, SetDoubleQuotes,
@@ -286,12 +289,10 @@ impl SystemClauseType {
&SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"), &SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
&SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"), &SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
&SystemClauseType::InstallSCCCleaner => clause_name!("$install_scc_cleaner"), &SystemClauseType::InstallSCCCleaner => clause_name!("$install_scc_cleaner"),
&SystemClauseType::InstallInferenceCounter => &SystemClauseType::InstallInferenceCounter => clause_name!("$install_inference_counter"),
clause_name!("$install_inference_counter"), &SystemClauseType::ModuleOf => clause_name!("$module_of"),
&SystemClauseType::RemoveCallPolicyCheck => &SystemClauseType::RemoveCallPolicyCheck => clause_name!("$remove_call_policy_check"),
clause_name!("$remove_call_policy_check"), &SystemClauseType::RemoveInferenceCounter => clause_name!("$remove_inference_counter"),
&SystemClauseType::RemoveInferenceCounter =>
clause_name!("$remove_inference_counter"),
&SystemClauseType::RestoreCutPolicy => clause_name!("$restore_cut_policy"), &SystemClauseType::RestoreCutPolicy => clause_name!("$restore_cut_policy"),
&SystemClauseType::SetCutPoint(_) => clause_name!("$set_cp"), &SystemClauseType::SetCutPoint(_) => clause_name!("$set_cp"),
&SystemClauseType::InferenceLevel => clause_name!("$inference_level"), &SystemClauseType::InferenceLevel => clause_name!("$inference_level"),
@@ -303,6 +304,7 @@ impl SystemClauseType {
&SystemClauseType::GetCurrentBlock => clause_name!("$get_current_block"), &SystemClauseType::GetCurrentBlock => clause_name!("$get_current_block"),
&SystemClauseType::InstallNewBlock => clause_name!("$install_new_block"), &SystemClauseType::InstallNewBlock => clause_name!("$install_new_block"),
&SystemClauseType::ResetBlock => clause_name!("$reset_block"), &SystemClauseType::ResetBlock => clause_name!("$reset_block"),
&SystemClauseType::RestoreCodePtrFromSpecialFormCP => clause_name!("$restore_p_from_sfcp"),
&SystemClauseType::SetBall => clause_name!("$set_ball"), &SystemClauseType::SetBall => clause_name!("$set_ball"),
&SystemClauseType::SetCutPointByDefault(_) => clause_name!("$set_cp_by_default"), &SystemClauseType::SetCutPointByDefault(_) => clause_name!("$set_cp_by_default"),
&SystemClauseType::SetDoubleQuotes => clause_name!("$set_double_quotes"), &SystemClauseType::SetDoubleQuotes => clause_name!("$set_double_quotes"),
@@ -326,14 +328,11 @@ impl SystemClauseType {
("$get_b_value", 1) => Some(SystemClauseType::GetBValue), ("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes), ("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
("$get_scc_cleaner", 1) => Some(SystemClauseType::GetSCCCleaner), ("$get_scc_cleaner", 1) => Some(SystemClauseType::GetSCCCleaner),
("$install_scc_cleaner", 2) => ("$install_scc_cleaner", 2) => Some(SystemClauseType::InstallSCCCleaner),
Some(SystemClauseType::InstallSCCCleaner), ("$install_inference_counter", 3) => Some(SystemClauseType::InstallInferenceCounter),
("$install_inference_counter", 3) => ("$module_of", 2) => Some(SystemClauseType::ModuleOf),
Some(SystemClauseType::InstallInferenceCounter), ("$remove_call_policy_check", 1) => Some(SystemClauseType::RemoveCallPolicyCheck),
("$remove_call_policy_check", 1) => ("$remove_inference_counter", 2) => Some(SystemClauseType::RemoveInferenceCounter),
Some(SystemClauseType::RemoveCallPolicyCheck),
("$remove_inference_counter", 2) =>
Some(SystemClauseType::RemoveInferenceCounter),
("$restore_cut_policy", 0) => Some(SystemClauseType::RestoreCutPolicy), ("$restore_cut_policy", 0) => Some(SystemClauseType::RestoreCutPolicy),
("$set_cp", 1) => Some(SystemClauseType::SetCutPoint(temp_v!(1))), ("$set_cp", 1) => Some(SystemClauseType::SetCutPoint(temp_v!(1))),
("$inference_level", 2) => Some(SystemClauseType::InferenceLevel), ("$inference_level", 2) => Some(SystemClauseType::InferenceLevel),
@@ -345,6 +344,7 @@ impl SystemClauseType {
("$get_cp", 1) => Some(SystemClauseType::GetCutPoint), ("$get_cp", 1) => Some(SystemClauseType::GetCutPoint),
("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock), ("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
("$reset_block", 1) => Some(SystemClauseType::ResetBlock), ("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
("$restore_p_from_sfcp", 0) => Some(SystemClauseType::RestoreCodePtrFromSpecialFormCP),
("$set_ball", 1) => Some(SystemClauseType::SetBall), ("$set_ball", 1) => Some(SystemClauseType::SetBall),
("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))), ("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))),
("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes), ("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
@@ -696,17 +696,15 @@ pub enum QueryInstruction {
pub type CompiledFact = Vec<FactInstruction>; pub type CompiledFact = Vec<FactInstruction>;
pub type CompiledQuery = Vec<QueryInstruction>;
pub enum Line { pub enum Line {
Arithmetic(ArithmeticInstruction), Arithmetic(ArithmeticInstruction),
Choice(ChoiceInstruction), Choice(ChoiceInstruction),
Control(ControlInstruction), Control(ControlInstruction),
Cut(CutInstruction), Cut(CutInstruction),
Fact(CompiledFact), Fact(FactInstruction),
Indexing(IndexingInstruction), Indexing(IndexingInstruction),
IndexedChoice(IndexedChoiceInstruction), IndexedChoice(IndexedChoiceInstruction),
Query(CompiledQuery) Query(QueryInstruction)
} }
pub type ThirdLevelIndex = Vec<IndexedChoiceInstruction>; pub type ThirdLevelIndex = Vec<IndexedChoiceInstruction>;

View File

@@ -206,6 +206,7 @@ pub struct MachineState {
pub(super) e: usize, pub(super) e: usize,
pub(super) num_of_args: usize, pub(super) num_of_args: usize,
pub(super) cp: LocalCodePtr, pub(super) cp: LocalCodePtr,
pub(super) special_form_cp: CodePtr,
pub(super) fail: bool, pub(super) fail: bool,
pub(crate) heap: Heap, pub(crate) heap: Heap,
pub(super) mode: MachineMode, pub(super) mode: MachineMode,

View File

@@ -40,6 +40,7 @@ impl MachineState {
e: 0, e: 0,
num_of_args: 0, num_of_args: 0,
cp: LocalCodePtr::default(), cp: LocalCodePtr::default(),
special_form_cp: CodePtr::default(),
fail: false, fail: false,
heap: Heap::with_capacity(256), heap: Heap::with_capacity(256),
mode: MachineMode::Write, mode: MachineMode::Write,
@@ -2363,6 +2364,7 @@ impl MachineState {
self.pstr_tr = 0; self.pstr_tr = 0;
self.p = CodePtr::default(); self.p = CodePtr::default();
self.cp = LocalCodePtr::default(); self.cp = LocalCodePtr::default();
self.special_form_cp = CodePtr::default();
self.num_of_args = 0; self.num_of_args = 0;
self.fail = false; self.fail = false;

View File

@@ -7,6 +7,7 @@ use prolog::debray_allocator::*;
use prolog::heap_print::*; use prolog::heap_print::*;
use prolog::instructions::*; use prolog::instructions::*;
mod attributed_variables;
mod machine_errors; mod machine_errors;
pub(super) mod machine_state; pub(super) mod machine_state;
pub(super) mod term_expansion; pub(super) mod term_expansion;
@@ -14,6 +15,7 @@ pub(super) mod term_expansion;
#[macro_use] mod machine_state_impl; #[macro_use] mod machine_state_impl;
mod system_calls; mod system_calls;
use prolog::machine::attributed_variables::*;
use prolog::machine::machine_state::*; use prolog::machine::machine_state::*;
use std::collections::{HashMap, VecDeque}; use std::collections::{HashMap, VecDeque};
@@ -21,8 +23,6 @@ use std::mem;
use std::ops::Index; use std::ops::Index;
use std::rc::Rc; use std::rc::Rc;
static BUILTINS: &str = include_str!("../lib/builtins.pl");
pub type InSituCodeDir = HashMap<PredicateKey, usize>; pub type InSituCodeDir = HashMap<PredicateKey, usize>;
pub struct IndexStore { pub struct IndexStore {
@@ -118,6 +118,7 @@ impl CodeRepo {
term_expanders: Code::new(), term_expanders: Code::new(),
code: Code::new(), code: Code::new(),
in_situ_code: Code::new(), in_situ_code: Code::new(),
verify_attrs_code: Code::new(),
term_dir: TermDir::new() term_dir: TermDir::new()
} }
} }
@@ -308,15 +309,23 @@ impl SubModuleUser for IndexStore {
} }
} }
static LISTS: &str = include_str!("../lib/lists.pl"); static BUILTINS: &str = include_str!("../lib/builtins.pl");
static CONTROL: &str = include_str!("../lib/control.pl"); static LISTS: &str = include_str!("../lib/lists.pl");
static QUEUES: &str = include_str!("../lib/queues.pl"); static CONTROL: &str = include_str!("../lib/control.pl");
static ERROR: &str = include_str!("../lib/error.pl"); static QUEUES: &str = include_str!("../lib/queues.pl");
static TERMS: &str = include_str!("../lib/terms.pl"); static ERROR: &str = include_str!("../lib/error.pl");
static DCGS: &str = include_str!("../lib/dcgs.pl"); static TERMS: &str = include_str!("../lib/terms.pl");
static ATTS: &str = include_str!("../lib/atts.pl"); static DCGS: &str = include_str!("../lib/dcgs.pl");
static ATTS: &str = include_str!("../lib/atts.pl");
impl Machine { impl Machine {
fn compile_special_forms(&mut self) {
match compile_special_form(self, VERIFY_ATTRS.as_bytes()) {
Ok(code) => self.code_repo.verify_attrs_code = code,
Err(_e) => panic!("Machine::compile_special_forms() failed")
}
}
pub fn new() -> Self { pub fn new() -> Self {
let mut wam = Machine { let mut wam = Machine {
machine_st: MachineState::new(), machine_st: MachineState::new(),
@@ -338,6 +347,7 @@ impl Machine {
compile_user_module(&mut wam, DCGS.as_bytes()); compile_user_module(&mut wam, DCGS.as_bytes());
compile_user_module(&mut wam, ATTS.as_bytes()); compile_user_module(&mut wam, ATTS.as_bytes());
wam.compile_special_forms();
wam wam
} }
@@ -512,30 +522,16 @@ impl MachineState {
&Line::Control(ref control_instr) => &Line::Control(ref control_instr) =>
self.execute_ctrl_instr(indices, &mut policies.call_policy, self.execute_ctrl_instr(indices, &mut policies.call_policy,
&mut policies.cut_policy, control_instr), &mut policies.cut_policy, control_instr),
&Line::Fact(ref fact) => { &Line::Fact(ref fact_instr) => {
for fact_instr in fact { self.execute_fact_instr(&fact_instr);
if self.fail {
break;
}
self.execute_fact_instr(&fact_instr);
}
self.p += 1; self.p += 1;
}, },
&Line::Indexing(ref indexing_instr) => &Line::Indexing(ref indexing_instr) =>
self.execute_indexing_instr(&indexing_instr), self.execute_indexing_instr(&indexing_instr),
&Line::IndexedChoice(ref choice_instr) => &Line::IndexedChoice(ref choice_instr) =>
self.execute_indexed_choice_instr(choice_instr, &mut policies.call_policy), self.execute_indexed_choice_instr(choice_instr, &mut policies.call_policy),
&Line::Query(ref query) => { &Line::Query(ref query_instr) => {
for query_instr in query { self.execute_query_instr(&query_instr);
if self.fail {
break;
}
self.execute_query_instr(&query_instr);
}
self.p += 1; self.p += 1;
} }
} }

View File

@@ -375,6 +375,29 @@ impl MachineState {
} }
}; };
}, },
&SystemClauseType::ModuleOf => {
let module = self.store(self.deref(self[temp_v!(2)].clone()));
match module {
Addr::Con(Constant::Atom(name, _)) => {
let module = Addr::Con(Constant::Atom(name.owning_module(), None));
let target = self[temp_v!(1)].clone();
self.unify(target, module);
},
Addr::Str(s) =>
match self.heap[s].clone() {
HeapCellValue::NamedStr(_, name, ..) => {
let module = Addr::Con(Constant::Atom(name.owning_module(), None));
let target = self[temp_v!(1)].clone();
self.unify(target, module);
},
_ => self.fail = true
},
_ => self.fail = true
};
},
&SystemClauseType::RemoveCallPolicyCheck => { &SystemClauseType::RemoveCallPolicyCheck => {
let restore_default = let restore_default =
match call_policy.downcast_mut::<CWILCallPolicy>().ok() { match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
@@ -418,6 +441,10 @@ impl MachineState {
None => panic!("remove_inference_counter: requires \\ None => panic!("remove_inference_counter: requires \\
CWILCallPolicy.") CWILCallPolicy.")
}, },
&SystemClauseType::RestoreCodePtrFromSpecialFormCP => {
self.p = self.special_form_cp.clone();
return Ok(());
},
&SystemClauseType::RestoreCutPolicy => { &SystemClauseType::RestoreCutPolicy => {
let restore_default = let restore_default =
if let Ok(cut_policy) = cut_policy.downcast_ref::<SCCCutPolicy>() { if let Ok(cut_policy) = cut_policy.downcast_ref::<SCCCutPolicy>() {

View File

@@ -4,12 +4,6 @@ macro_rules! interm {
) )
} }
macro_rules! query {
[$($x:expr),+] => (
Line::Query(vec![$($x),+])
)
}
macro_rules! heap_str { macro_rules! heap_str {
($s:expr) => ( ($s:expr) => (
HeapCellValue::Addr(Addr::Str($s)) HeapCellValue::Addr(Addr::Str($s))

View File

@@ -814,8 +814,7 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
Ok(result) Ok(result)
} }
pub pub fn consume(&mut self, indices: &mut IndexStore) -> Result<Option<Declaration>, SessionError>
fn consume(&mut self, indices: &mut IndexStore) -> Result<Option<Declaration>, SessionError>
{ {
let mut preds = vec![]; let mut preds = vec![];