add use_module/{1,2} as full fledged predicates
This commit is contained in:
@@ -11,7 +11,6 @@ license = "BSD-3-Clause"
|
|||||||
indexmap = "1.0.2"
|
indexmap = "1.0.2"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cfg-if = "0.1.7"
|
|
||||||
dirs = "2.0.2"
|
dirs = "2.0.2"
|
||||||
downcast = "0.10.0"
|
downcast = "0.10.0"
|
||||||
indexmap = "1.0.2"
|
indexmap = "1.0.2"
|
||||||
|
|||||||
@@ -236,6 +236,7 @@ The following predicates are built-in to Scryer.
|
|||||||
* `throw/1`
|
* `throw/1`
|
||||||
* `true/0`
|
* `true/0`
|
||||||
* `unify_with_occurs_check/2`
|
* `unify_with_occurs_check/2`
|
||||||
|
* `use_module/{1,2}`
|
||||||
* `user:goal_expansion/2`
|
* `user:goal_expansion/2`
|
||||||
* `user:term_expansion/2`
|
* `user:term_expansion/2`
|
||||||
* `var/1`
|
* `var/1`
|
||||||
|
|||||||
14
src/main.rs
14
src/main.rs
@@ -1,19 +1,10 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate cfg_if;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate downcast;
|
extern crate downcast;
|
||||||
extern crate indexmap;
|
extern crate indexmap;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate prolog_parser;
|
extern crate prolog_parser;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate ref_thread_local;
|
extern crate ref_thread_local;
|
||||||
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(feature = "readline_rs_compat")] {
|
|
||||||
extern crate readline_rs_compat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern crate termion;
|
extern crate termion;
|
||||||
|
|
||||||
mod prolog;
|
mod prolog;
|
||||||
@@ -25,9 +16,6 @@ use prolog::read::*;
|
|||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// #[cfg(feature = "readline_rs_compat")]
|
|
||||||
// readline::readline_initialize();
|
|
||||||
|
|
||||||
let mut wam = Machine::new(readline::input_stream());
|
let mut wam = Machine::new(readline::input_stream());
|
||||||
wam.run_toplevel();
|
wam.run_top_level();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -261,6 +261,16 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::REPL(REPLCodePtr::SubmitQueryAndPrintResults) => {
|
&SystemClauseType::REPL(REPLCodePtr::SubmitQueryAndPrintResults) => {
|
||||||
clause_name!("$submit_query_and_print_results")
|
clause_name!("$submit_query_and_print_results")
|
||||||
}
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
|
||||||
|
clause_name!("$use_qualified_module")
|
||||||
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile) => {
|
||||||
|
clause_name!("$use_module_from_file")
|
||||||
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::UseQualifiedModuleFromFile) => {
|
||||||
|
clause_name!("$use_qualified_module_from_file")
|
||||||
|
}
|
||||||
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
|
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
|
||||||
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
|
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
|
||||||
&SystemClauseType::DeleteHeadAttribute => clause_name!("$del_attr_head"),
|
&SystemClauseType::DeleteHeadAttribute => clause_name!("$del_attr_head"),
|
||||||
@@ -437,6 +447,13 @@ impl SystemClauseType {
|
|||||||
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
||||||
("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
|
("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
|
||||||
("$unify_with_occurs_check", 2) => Some(SystemClauseType::UnifyWithOccursCheck),
|
("$unify_with_occurs_check", 2) => Some(SystemClauseType::UnifyWithOccursCheck),
|
||||||
|
("$use_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
|
||||||
|
("$use_module_from_file", 1) =>
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile)),
|
||||||
|
("$use_qualified_module", 2) =>
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule)),
|
||||||
|
("$use_qualified_module_from_file", 2) =>
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::UseQualifiedModuleFromFile)),
|
||||||
("$variant", 2) => Some(SystemClauseType::Variant),
|
("$variant", 2) => Some(SystemClauseType::Variant),
|
||||||
("$write_term", 5) => Some(SystemClauseType::WriteTerm),
|
("$write_term", 5) => Some(SystemClauseType::WriteTerm),
|
||||||
("$wam_instructions", 3) => Some(SystemClauseType::WAMInstructions),
|
("$wam_instructions", 3) => Some(SystemClauseType::WAMInstructions),
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ impl DebrayAllocator {
|
|||||||
|
|
||||||
target.push(Target::move_to_register(r, k));
|
target.push(Target::move_to_register(r, k));
|
||||||
|
|
||||||
self.contents.remove(&k);
|
self.contents.swap_remove(&k);
|
||||||
self.contents.insert(r.reg_num(), var.clone());
|
self.contents.insert(r.reg_num(), var.clone());
|
||||||
|
|
||||||
self.record_register(var, r);
|
self.record_register(var, r);
|
||||||
|
|||||||
@@ -652,7 +652,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
self.cyclic_terms.remove(&addr);
|
self.cyclic_terms.swap_remove(&addr);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -442,7 +442,7 @@ fn add_module_code(wam: &mut Machine, mut module: Module, code: Code, mut indice
|
|||||||
if name.owning_module() == module.module_decl.name {
|
if name.owning_module() == module.module_decl.name {
|
||||||
wam.indices
|
wam.indices
|
||||||
.dynamic_code_dir
|
.dynamic_code_dir
|
||||||
.remove(&(name.owning_module(), name, arity));
|
.swap_remove(&(name.owning_module(), name, arity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,6 +466,7 @@ fn add_non_module_code(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super)
|
||||||
fn load_library(wam: &mut Machine, name: ClauseName) -> Result<ClauseName, SessionError> {
|
fn load_library(wam: &mut Machine, name: ClauseName) -> Result<ClauseName, SessionError> {
|
||||||
match LIBRARIES.borrow().get(name.as_str()) {
|
match LIBRARIES.borrow().get(name.as_str()) {
|
||||||
Some(code) => load_module(wam, name.as_str(), parsing_stream(code.as_bytes())),
|
Some(code) => load_module(wam, name.as_str(), parsing_stream(code.as_bytes())),
|
||||||
|
|||||||
@@ -291,6 +291,10 @@ pub enum DynamicTransactionType {
|
|||||||
pub enum REPLCodePtr {
|
pub enum REPLCodePtr {
|
||||||
CompileBatch,
|
CompileBatch,
|
||||||
SubmitQueryAndPrintResults,
|
SubmitQueryAndPrintResults,
|
||||||
|
UseModule,
|
||||||
|
UseQualifiedModule,
|
||||||
|
UseModuleFromFile,
|
||||||
|
UseQualifiedModuleFromFile
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
@@ -307,8 +311,8 @@ impl CodePtr {
|
|||||||
pub fn local(&self) -> LocalCodePtr {
|
pub fn local(&self) -> LocalCodePtr {
|
||||||
match self {
|
match self {
|
||||||
&CodePtr::BuiltInClause(_, ref local)
|
&CodePtr::BuiltInClause(_, ref local)
|
||||||
| &CodePtr::CallN(_, ref local)
|
| &CodePtr::CallN(_, ref local)
|
||||||
| &CodePtr::Local(ref local) => local.clone(),
|
| &CodePtr::Local(ref local) => local.clone(),
|
||||||
&CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
|
&CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
|
||||||
&CodePtr::REPL(_, p) | &CodePtr::DynamicTransaction(_, p) => p,
|
&CodePtr::REPL(_, p) | &CodePtr::DynamicTransaction(_, p) => p,
|
||||||
}
|
}
|
||||||
@@ -346,10 +350,10 @@ impl PartialOrd<LocalCodePtr> for LocalCodePtr {
|
|||||||
fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(&LocalCodePtr::InSituDirEntry(p1), &LocalCodePtr::InSituDirEntry(ref p2))
|
(&LocalCodePtr::InSituDirEntry(p1), &LocalCodePtr::InSituDirEntry(ref p2))
|
||||||
| (&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2))
|
| (&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2))
|
||||||
| (&LocalCodePtr::UserTermExpansion(p1), &LocalCodePtr::UserTermExpansion(ref p2))
|
| (&LocalCodePtr::UserTermExpansion(p1), &LocalCodePtr::UserTermExpansion(ref p2))
|
||||||
| (&LocalCodePtr::UserGoalExpansion(p1), &LocalCodePtr::UserGoalExpansion(ref p2))
|
| (&LocalCodePtr::UserGoalExpansion(p1), &LocalCodePtr::UserGoalExpansion(ref p2))
|
||||||
| (&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => {
|
| (&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => {
|
||||||
p1.partial_cmp(p2)
|
p1.partial_cmp(p2)
|
||||||
}
|
}
|
||||||
(_, &LocalCodePtr::TopLevel(_, _)) => Some(Ordering::Less),
|
(_, &LocalCodePtr::TopLevel(_, _)) => Some(Ordering::Less),
|
||||||
@@ -388,10 +392,10 @@ impl AddAssign<usize> for LocalCodePtr {
|
|||||||
fn add_assign(&mut self, rhs: usize) {
|
fn add_assign(&mut self, rhs: usize) {
|
||||||
match self {
|
match self {
|
||||||
&mut LocalCodePtr::InSituDirEntry(ref mut p)
|
&mut LocalCodePtr::InSituDirEntry(ref mut p)
|
||||||
| &mut LocalCodePtr::UserGoalExpansion(ref mut p)
|
| &mut LocalCodePtr::UserGoalExpansion(ref mut p)
|
||||||
| &mut LocalCodePtr::UserTermExpansion(ref mut p)
|
| &mut LocalCodePtr::UserTermExpansion(ref mut p)
|
||||||
| &mut LocalCodePtr::DirEntry(ref mut p)
|
| &mut LocalCodePtr::DirEntry(ref mut p)
|
||||||
| &mut LocalCodePtr::TopLevel(_, ref mut p) => *p += rhs,
|
| &mut LocalCodePtr::TopLevel(_, ref mut p) => *p += rhs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -402,8 +406,8 @@ impl Add<usize> for CodePtr {
|
|||||||
fn add(self, rhs: usize) -> Self::Output {
|
fn add(self, rhs: usize) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
p @ CodePtr::REPL(..)
|
p @ CodePtr::REPL(..)
|
||||||
| p @ CodePtr::VerifyAttrInterrupt(_)
|
| p @ CodePtr::VerifyAttrInterrupt(_)
|
||||||
| p @ CodePtr::DynamicTransaction(..) => p,
|
| p @ CodePtr::DynamicTransaction(..) => p,
|
||||||
CodePtr::Local(local) => CodePtr::Local(local + rhs),
|
CodePtr::Local(local) => CodePtr::Local(local + rhs),
|
||||||
CodePtr::CallN(_, local) | CodePtr::BuiltInClause(_, local) => {
|
CodePtr::CallN(_, local) | CodePtr::BuiltInClause(_, local) => {
|
||||||
CodePtr::Local(local + rhs)
|
CodePtr::Local(local + rhs)
|
||||||
@@ -480,7 +484,7 @@ impl IndexStore {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn remove_clause_subsection(&mut self, module: ClauseName, name: ClauseName, arity: usize) {
|
pub fn remove_clause_subsection(&mut self, module: ClauseName, name: ClauseName, arity: usize) {
|
||||||
self.dynamic_code_dir.remove(&(module, name, arity));
|
self.dynamic_code_dir.swap_remove(&(module, name, arity));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -495,7 +499,7 @@ impl IndexStore {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn take_module(&mut self, name: ClauseName) -> Option<Module> {
|
pub fn take_module(&mut self, name: ClauseName) -> Option<Module> {
|
||||||
self.modules.remove(&name)
|
self.modules.swap_remove(&name)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
@@ -3387,7 +3387,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.hb = 0;
|
self.hb = 0;
|
||||||
self.e = 0;
|
self.e = 0;
|
||||||
self.b = 0;
|
self.b = 0;
|
||||||
|
|||||||
@@ -216,15 +216,24 @@ impl Machine {
|
|||||||
self.machine_st.reset();
|
self.machine_st.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_toplevel(&mut self) {
|
pub fn run_top_level(&mut self) {
|
||||||
use std::env;
|
use std::env;
|
||||||
use prolog::machine::compile::load_module_from_file;
|
|
||||||
|
|
||||||
for filename in env::args() {
|
let mut filename_atoms = vec![];
|
||||||
load_module_from_file(self, &filename);
|
|
||||||
|
// the first of these is the path to the scryer-prolog executable, so skip
|
||||||
|
// it.
|
||||||
|
for filename in env::args().skip(1) {
|
||||||
|
let atom = atom!(filename, self.indices.atom_tbl);
|
||||||
|
filename_atoms.push(Addr::Con(atom));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let list_addr =
|
||||||
|
Addr::HeapCell(self.machine_st.heap.to_list(filename_atoms.into_iter()));
|
||||||
|
|
||||||
|
self.machine_st[temp_v!(1)] = list_addr;
|
||||||
self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(self.toplevel_idx));
|
self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(self.toplevel_idx));
|
||||||
|
|
||||||
self.run_query(&AllocVarDict::new());
|
self.run_query(&AllocVarDict::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,12 +256,13 @@ impl Machine {
|
|||||||
);
|
);
|
||||||
|
|
||||||
wam.compile_special_forms();
|
wam.compile_special_forms();
|
||||||
wam.compile_top_level();
|
|
||||||
|
|
||||||
compile_user_module(&mut wam, parsing_stream(ERROR.as_bytes()));
|
compile_user_module(&mut wam, parsing_stream(ERROR.as_bytes()));
|
||||||
compile_user_module(&mut wam, parsing_stream(LISTS.as_bytes()));
|
compile_user_module(&mut wam, parsing_stream(LISTS.as_bytes()));
|
||||||
compile_user_module(&mut wam, parsing_stream(NON_ISO.as_bytes()));
|
compile_user_module(&mut wam, parsing_stream(NON_ISO.as_bytes()));
|
||||||
|
compile_user_module(&mut wam, parsing_stream(SI.as_bytes()));
|
||||||
|
|
||||||
|
wam.compile_top_level();
|
||||||
wam.compile_scryerrc();
|
wam.compile_scryerrc();
|
||||||
|
|
||||||
wam
|
wam
|
||||||
@@ -356,16 +366,132 @@ impl Machine {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extract_predicate_indicator_list(&mut self) -> Vec<PredicateKey>
|
||||||
|
{
|
||||||
|
let export_list = self.machine_st[temp_v!(2)].clone();
|
||||||
|
let mut export_list = self.machine_st.store(self.machine_st.deref(export_list));
|
||||||
|
let mut exports = vec![];
|
||||||
|
|
||||||
|
while let Addr::Lis(l) = export_list {
|
||||||
|
match &self.machine_st.heap[l] {
|
||||||
|
&HeapCellValue::Addr(Addr::Str(s)) => {
|
||||||
|
let name = match &self.machine_st.heap[s+1] {
|
||||||
|
&HeapCellValue::Addr(Addr::Con(Constant::Atom(ref name, _))) =>
|
||||||
|
name.clone(),
|
||||||
|
_ =>
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let arity = match &self.machine_st.heap[s+2] {
|
||||||
|
&HeapCellValue::Addr(Addr::Con(Constant::Integer(ref arity))) =>
|
||||||
|
arity.to_usize().unwrap(),
|
||||||
|
_ =>
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.push((name, arity));
|
||||||
|
}
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
|
export_list = self.machine_st.heap[l+1].as_addr(l+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports
|
||||||
|
}
|
||||||
|
|
||||||
|
fn use_module<ToSource>(&mut self, to_src: ToSource)
|
||||||
|
where ToSource: Fn(ClauseName) -> ModuleSource
|
||||||
|
{
|
||||||
|
// the term expander will overwrite the cached query, so save it here.
|
||||||
|
let cached_query = mem::replace(&mut self.code_repo.cached_query, vec![]);
|
||||||
|
|
||||||
|
let module_spec = self.machine_st[temp_v!(1)].clone();
|
||||||
|
let name = match self.machine_st.store(self.machine_st.deref(module_spec)) {
|
||||||
|
Addr::Con(Constant::Atom(name, _)) => name,
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let load_result = match to_src(name) {
|
||||||
|
ModuleSource::Library(name) =>
|
||||||
|
if !self.indices.modules.contains_key(&name) {
|
||||||
|
load_library(self, name)
|
||||||
|
} else {
|
||||||
|
Ok(name)
|
||||||
|
},
|
||||||
|
ModuleSource::File(name) => load_module_from_file(self, name.as_str())
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = load_result.and_then(|name| {
|
||||||
|
let module = self.indices.take_module(name).unwrap();
|
||||||
|
|
||||||
|
// remove previous exports.
|
||||||
|
self.indices.remove_module(clause_name!("user"), &module);
|
||||||
|
self.indices.use_module(&mut self.code_repo, self.machine_st.flags, &module)?;
|
||||||
|
|
||||||
|
Ok(self.indices.insert_module(module))
|
||||||
|
});
|
||||||
|
|
||||||
|
self.code_repo.cached_query = cached_query;
|
||||||
|
|
||||||
|
if let Err(e) = result {
|
||||||
|
self.throw_session_error(e, (clause_name!("use_module"), 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn use_qualified_module<ToSource>(&mut self, to_src: ToSource)
|
||||||
|
where ToSource: Fn(ClauseName) -> ModuleSource
|
||||||
|
{
|
||||||
|
// the term expander will overwrite the cached query, so save it here.
|
||||||
|
let cached_query = mem::replace(&mut self.code_repo.cached_query, vec![]);
|
||||||
|
|
||||||
|
let module_spec = self.machine_st[temp_v!(1)].clone();
|
||||||
|
let name = match self.machine_st.store(self.machine_st.deref(module_spec)) {
|
||||||
|
Addr::Con(Constant::Atom(name, _)) => name,
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let exports = self.extract_predicate_indicator_list();
|
||||||
|
|
||||||
|
let load_result = match to_src(name) {
|
||||||
|
ModuleSource::Library(name) =>
|
||||||
|
if !self.indices.modules.contains_key(&name) {
|
||||||
|
load_library(self, name)
|
||||||
|
} else {
|
||||||
|
Ok(name)
|
||||||
|
},
|
||||||
|
ModuleSource::File(name) => load_module_from_file(self, name.as_str())
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = load_result.and_then(|name| {
|
||||||
|
let module = self.indices.take_module(name).unwrap();
|
||||||
|
|
||||||
|
// remove previous exports.
|
||||||
|
self.indices.remove_module(clause_name!("user"), &module);
|
||||||
|
self.indices.use_qualified_module(&mut self.code_repo,
|
||||||
|
self.machine_st.flags,
|
||||||
|
&module,
|
||||||
|
&exports)?;
|
||||||
|
|
||||||
|
Ok(self.indices.insert_module(module))
|
||||||
|
});
|
||||||
|
|
||||||
|
self.code_repo.cached_query = cached_query;
|
||||||
|
|
||||||
|
if let Err(e) = result {
|
||||||
|
self.throw_session_error(e, (clause_name!("use_module"), 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_toplevel_command(&mut self, code_ptr: REPLCodePtr, p: LocalCodePtr) {
|
fn handle_toplevel_command(&mut self, code_ptr: REPLCodePtr, p: LocalCodePtr) {
|
||||||
match code_ptr {
|
match code_ptr {
|
||||||
REPLCodePtr::CompileBatch => {
|
REPLCodePtr::CompileBatch => {
|
||||||
let src = readline::input_stream();
|
let src = readline::input_stream();
|
||||||
readline::set_prompt(false);
|
readline::set_prompt(false);
|
||||||
|
|
||||||
match compile_user_module(self, src) {
|
if let EvalSession::Error(e) = compile_user_module(self, src) {
|
||||||
EvalSession::Error(e) => self.throw_session_error(e, (clause_name!("repl"), 0)),
|
self.throw_session_error(e, (clause_name!("repl"), 0));
|
||||||
_ => {}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
REPLCodePtr::SubmitQueryAndPrintResults => {
|
REPLCodePtr::SubmitQueryAndPrintResults => {
|
||||||
let term = self.machine_st[temp_v!(1)].clone();
|
let term = self.machine_st[temp_v!(1)].clone();
|
||||||
@@ -416,6 +542,14 @@ impl Machine {
|
|||||||
|
|
||||||
self.handle_eval_session(result, snapshot);
|
self.handle_eval_session(result, snapshot);
|
||||||
}
|
}
|
||||||
|
REPLCodePtr::UseModule =>
|
||||||
|
self.use_module(ModuleSource::Library),
|
||||||
|
REPLCodePtr::UseModuleFromFile =>
|
||||||
|
self.use_module(ModuleSource::File),
|
||||||
|
REPLCodePtr::UseQualifiedModule =>
|
||||||
|
self.use_qualified_module(ModuleSource::Library),
|
||||||
|
REPLCodePtr::UseQualifiedModuleFromFile =>
|
||||||
|
self.use_qualified_module(ModuleSource::File)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.machine_st.p = CodePtr::Local(p);
|
self.machine_st.p = CodePtr::Local(p);
|
||||||
@@ -556,7 +690,8 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn run_query(&mut self, alloc_locs: &AllocVarDict) {
|
pub(super) fn run_query(&mut self, alloc_locs: &AllocVarDict) {
|
||||||
let end_ptr = top_level_code_ptr!(0, self.code_repo.size_of_cached_query());
|
self.machine_st.cp = LocalCodePtr::TopLevel(0, self.code_repo.size_of_cached_query());
|
||||||
|
let end_ptr = CodePtr::Local(self.machine_st.cp);
|
||||||
|
|
||||||
while self.machine_st.p < end_ptr {
|
while self.machine_st.p < end_ptr {
|
||||||
if let CodePtr::Local(LocalCodePtr::TopLevel(mut cn, p)) = self.machine_st.p {
|
if let CodePtr::Local(LocalCodePtr::TopLevel(mut cn, p)) = self.machine_st.p {
|
||||||
@@ -636,10 +771,7 @@ impl Machine {
|
|||||||
where
|
where
|
||||||
Outputter: HCValueOutputter,
|
Outputter: HCValueOutputter,
|
||||||
{
|
{
|
||||||
let mut sorted_vars: Vec<_> = self.machine_st.heap_locs.iter().collect();
|
for (var, addr) in self.machine_st.heap_locs.iter() {
|
||||||
sorted_vars.sort_by_key(|ref v| v.0);
|
|
||||||
|
|
||||||
for (var, addr) in sorted_vars {
|
|
||||||
let addr = self.machine_st.store(self.machine_st.deref(addr.clone()));
|
let addr = self.machine_st.store(self.machine_st.deref(addr.clone()));
|
||||||
output = self
|
output = self
|
||||||
.machine_st
|
.machine_st
|
||||||
@@ -654,10 +786,7 @@ impl Machine {
|
|||||||
where
|
where
|
||||||
Outputter: HCValueOutputter,
|
Outputter: HCValueOutputter,
|
||||||
{
|
{
|
||||||
let mut sorted_vars: Vec<(&Rc<Var>, &Addr)> = self.machine_st.heap_locs.iter().collect();
|
for (var, addr) in self.machine_st.heap_locs.iter() {
|
||||||
sorted_vars.sort_by_key(|ref v| v.0);
|
|
||||||
|
|
||||||
for (var, addr) in sorted_vars {
|
|
||||||
output = self.machine_st.print_var_eq(
|
output = self.machine_st.print_var_eq(
|
||||||
var.clone(),
|
var.clone(),
|
||||||
addr.clone(),
|
addr.clone(),
|
||||||
|
|||||||
@@ -339,8 +339,7 @@ impl MachineState {
|
|||||||
self.p.local() + 1
|
self.p.local() + 1
|
||||||
};
|
};
|
||||||
|
|
||||||
self.p = CodePtr::REPL(repl_code_ptr, p);
|
Ok(self.p = CodePtr::REPL(repl_code_ptr, p))
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn truncate_if_no_lifted_heap_diff<AddrConstr>(&mut self, addr_constr: AddrConstr)
|
fn truncate_if_no_lifted_heap_diff<AddrConstr>(&mut self, addr_constr: AddrConstr)
|
||||||
@@ -1513,7 +1512,7 @@ impl MachineState {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
indices.global_variables.remove(&key);
|
indices.global_variables.swap_remove(&key);
|
||||||
}
|
}
|
||||||
&SystemClauseType::RemoveCallPolicyCheck => {
|
&SystemClauseType::RemoveCallPolicyCheck => {
|
||||||
let restore_default = match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
|
let restore_default = match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
|
||||||
|
|||||||
@@ -743,12 +743,13 @@ impl RelationWorker {
|
|||||||
terms: Vec<Box<Term>>,
|
terms: Vec<Box<Term>>,
|
||||||
blocks_cuts: bool,
|
blocks_cuts: bool,
|
||||||
) -> Result<TopLevel, ParserError> {
|
) -> Result<TopLevel, ParserError> {
|
||||||
|
/*
|
||||||
match setup_declaration(terms.iter().cloned().collect()) {
|
match setup_declaration(terms.iter().cloned().collect()) {
|
||||||
Ok(Declaration::Op(..)) => {} // this is now a predicate call in the query context.
|
Ok(Declaration::Op(..)) => {} // this is now a predicate call in the query context.
|
||||||
Ok(decl) => return Ok(TopLevel::Declaration(decl)),
|
Ok(decl) => return Ok(TopLevel::Declaration(decl)),
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
Ok(TopLevel::Query(self.setup_query(
|
Ok(TopLevel::Query(self.setup_query(
|
||||||
indices,
|
indices,
|
||||||
terms,
|
terms,
|
||||||
|
|||||||
@@ -1,3 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* inserting the modules should not result in the insertion of
|
||||||
|
* code. this is because they're already loaded by this point -- see
|
||||||
|
* Machine::new.
|
||||||
|
*/
|
||||||
|
|
||||||
|
:- use_module(library(lists)).
|
||||||
|
:- use_module(library(si)).
|
||||||
|
|
||||||
|
'$repl'(ListOfModules) :-
|
||||||
|
maplist('$use_list_of_modules', ListOfModules),
|
||||||
|
false.
|
||||||
|
'$repl'(_) :- '$repl'.
|
||||||
|
|
||||||
|
'$use_list_of_modules'(Module) :-
|
||||||
|
catch(use_module(Module), E, '$print_exception'(E)).
|
||||||
|
|
||||||
'$repl' :-
|
'$repl' :-
|
||||||
catch('$read_and_match', E, '$print_exception'(E)),
|
catch('$read_and_match', E, '$print_exception'(E)),
|
||||||
false. %% this is for GC, until we get actual GC.
|
false. %% this is for GC, until we get actual GC.
|
||||||
@@ -17,3 +34,41 @@
|
|||||||
write_term('caught: ', [quoted(false)]),
|
write_term('caught: ', [quoted(false)]),
|
||||||
writeq(E),
|
writeq(E),
|
||||||
nl.
|
nl.
|
||||||
|
|
||||||
|
'$predicate_indicator'(Source, PI) :-
|
||||||
|
( nonvar(PI) ->
|
||||||
|
( PI = Name / Arity ->
|
||||||
|
( var(Name) -> throw(error(instantiation_error, Source))
|
||||||
|
; integer(Arity) ->
|
||||||
|
( \+ atom(Name) -> throw(error(type_error(atom, Name), Source))
|
||||||
|
; Arity < 0 -> throw(error(domain_error(not_less_than_zero, Arity), Source))
|
||||||
|
; true
|
||||||
|
)
|
||||||
|
; throw(error(type_error(integer, Arity), Source))
|
||||||
|
)
|
||||||
|
; throw(error(type_error(predicate_indicator, PI), Source))
|
||||||
|
)
|
||||||
|
; throw(error(instantiation_error, Source))
|
||||||
|
).
|
||||||
|
|
||||||
|
use_module(Module) :-
|
||||||
|
( nonvar(Module) ->
|
||||||
|
( Module = library(Filename) -> '$use_module'(Filename)
|
||||||
|
; atom(Module) -> '$use_module_from_file'(Module)
|
||||||
|
; throw(error(invalid_module_specifier, use_module/1))
|
||||||
|
)
|
||||||
|
; throw(error(instantiation_error, use_module/1))
|
||||||
|
).
|
||||||
|
|
||||||
|
use_module(Module, QualifiedExports) :-
|
||||||
|
( nonvar(Module) ->
|
||||||
|
( list_si(QualifiedExports) ->
|
||||||
|
maplist('$predicate_indicator'(use_module/2), QualifiedExports), !,
|
||||||
|
( Module = library(Filename) -> '$use_qualified_module'(Filename, QualifiedExports)
|
||||||
|
; atom(Module) -> '$use_qualified_module_from_file'(Module, QualifiedExports)
|
||||||
|
; throw(error(invalid_module_specifier, use_module/2))
|
||||||
|
)
|
||||||
|
; throw(error(type_error(list, QualifiedExports), use_module/2))
|
||||||
|
)
|
||||||
|
; throw(error(instantiation_error, use_module/2))
|
||||||
|
).
|
||||||
|
|||||||
@@ -33,6 +33,14 @@ impl fmt::Display for REPLCodePtr {
|
|||||||
REPLCodePtr::SubmitQueryAndPrintResults => {
|
REPLCodePtr::SubmitQueryAndPrintResults => {
|
||||||
write!(f, "REPLCodePtr::SubmitQueryAndPrintResults")
|
write!(f, "REPLCodePtr::SubmitQueryAndPrintResults")
|
||||||
}
|
}
|
||||||
|
REPLCodePtr::UseModule =>
|
||||||
|
write!(f, "REPLCodePtr::UseModule"),
|
||||||
|
REPLCodePtr::UseQualifiedModule =>
|
||||||
|
write!(f, "REPLCodePtr::UseQualifiedModule"),
|
||||||
|
REPLCodePtr::UseModuleFromFile =>
|
||||||
|
write!(f, "REPLCodePtr::UseModuleFromFile"),
|
||||||
|
REPLCodePtr::UseQualifiedModuleFromFile =>
|
||||||
|
write!(f, "REPLCodePtr::UseQualifiedModuleFromFile")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user