[[package]]
name = "prolog_parser"
-version = "0.7.16"
+version = "0.7.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "prolog_parser 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "prolog_parser 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
"checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
-"checksum prolog_parser 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71a1f33a90a68d4641143f591c9d97d6c939622d5bfbebed3630d7264f593736"
+"checksum prolog_parser 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)" = "221eed4744a63708fac45edb126b86f8ef2713757bc647dfcda4ee51c8ef57c1"
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
downcast = "0.9.1"
num = "0.2"
ordered-float = "0.5.0"
-prolog_parser = "0.7.16"
+prolog_parser = "0.7.17"
[dependencies.termion]
version = "1.4.0"
\ No newline at end of file
use prolog_parser::ast::*;
+use prolog_parser::tabled_rc::TabledData;
use prolog::instructions::*;
use prolog::debray_allocator::*;
fn package_term(wam: &mut Machine, term: Term) -> Result<TopLevelPacket, ParserError> {
let code_dir = wam.code_dir.clone();
- let indices = machine_code_indices!(&mut CodeDir::new(), &mut wam.op_dir, &mut wam.modules);
+ let indices = machine_code_indices!(&mut CodeDir::new(),
+ &mut wam.op_dir,
+ &mut wam.modules);
consume_term(code_dir, term, indices)
}
}
impl ListingCompiler {
+ #[inline]
pub fn new() -> Self {
- ListingCompiler { module: None, non_counted_bt_preds: HashSet::new() }
+ ListingCompiler {
+ module: None, non_counted_bt_preds: HashSet::new()
+ }
}
fn use_module(&mut self, submodule: Module, wam: &mut Machine, indices: &mut MachineCodeIndices)
wam.remove_module(&submodule);
}
- wam.insert_module(submodule);
- Ok(())
+ Ok(wam.insert_module(submodule))
}
fn use_qualified_module(&mut self, submodule: Module, wam: &mut Machine,
wam.remove_module(&submodule);
}
- wam.insert_module(submodule);
- Ok(())
+ Ok(wam.insert_module(submodule))
}
fn get_module_name(&self) -> ClauseName {
},
Declaration::Module(module_decl) =>
if self.module.is_none() {
- Ok(self.module = Some(Module::new(module_decl)))
+ let module_name = module_decl.name.clone();
+ let atom_tbl = TabledData::new(module_name.to_rc());
+
+ Ok(self.module = Some(Module::new(module_decl, atom_tbl)))
} else {
Err(SessionError::from(ParserError::InvalidModuleDecl))
}
toplevel_indices.copy_and_swap(&mut indices);
mem::swap(&mut worker.results, &mut toplevel_results);
worker.in_module = true;
- }
- try_eval_session!(compiler.process_decl(decl, wam, &mut indices));
+ try_eval_session!(compiler.process_decl(decl, wam, &mut indices));
+
+ if let &Some(ref module) = &compiler.module {
+ worker.term_stream.set_atom_tbl(module.atom_tbl.clone());
+ }
+ } else {
+ try_eval_session!(compiler.process_decl(decl, wam, &mut indices));
+ }
}
let module_code = try_eval_session!(compiler.generate_code(worker.results, wam,
pub fn compile_user_module<R: Read>(wam: &mut Machine, src: R) -> EvalSession {
let mut indices = default_machine_code_indices!();
try_eval_session!(setup_indices(&wam, &mut indices));
-
compile_listing(wam, src, indices, default_machine_code_indices!())
}
use prolog_parser::ast::*;
+use prolog_parser::tabled_rc::*;
use std::cell::{Cell, RefCell};
use std::collections::{BTreeSet, HashMap, VecDeque};
}
pub struct Module {
+ pub atom_tbl: TabledData<Atom>,
pub module_decl: ModuleDecl,
pub code_dir: ModuleCodeDir,
pub op_dir: OpDir
#[inline]
pub fn module_name(&self) -> ClauseName {
- self.0.borrow().1.clone()
+ self.0.borrow().1.clone()
}
}
match self {
&CodePtr::BuiltInClause(_, ref local)
| &CodePtr::CallN(_, ref local)
- | &CodePtr::Local(ref local) => local.clone()
+ | &CodePtr::Local(ref local) => local.clone()
}
}
}
match self {
&mut LocalCodePtr::UserTermExpansion(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
}
}
}
}
impl Module {
- pub fn new(module_decl: ModuleDecl) -> Self {
- Module { module_decl,
+ pub fn new(module_decl: ModuleDecl, atom_tbl: TabledData<Atom>) -> Self {
+ Module { module_decl, atom_tbl,
code_dir: ModuleCodeDir::new(),
op_dir: default_op_dir() }
}
pub trait SubModuleUser {
fn op_dir(&mut self) -> &mut OpDir;
- fn remove_code_index(&mut self, key: PredicateKey);
- fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex>;
-
+ fn remove_code_index(&mut self, PredicateKey);
+ fn get_code_index(&self, PredicateKey, ClauseName) -> Option<CodeIndex>;
+
fn insert_dir_entry(&mut self, ClauseName, usize, ModuleCodeIndex);
fn remove_module(&mut self, mod_name: ClauseName, module: &Module) {
};
}
}
-
+
// returns true on successful import.
fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool {
let name = name.defrock_brackets();
}
if let Some(code_data) = submodule.code_dir.get(&(name.clone(), arity)) {
+ let name = name.with_table(submodule.atom_tbl.clone());
self.insert_dir_entry(name, arity, code_data.clone());
true
} else {
fn remove_code_index(&mut self, key: PredicateKey) {
self.code_dir.remove(&key);
}
-
- fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex) {
+
+ fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex)
+ {
self.code_dir.insert((name, arity), idx);
}
}
-pub enum Declaration {
- Hook(CompileTimeHook, PredicateClause),
+pub enum Declaration {
+ Hook(CompileTimeHook, PredicateClause),
Module(ModuleDecl),
NonCountedBacktracking(ClauseName, usize), // name, arity
Op(OpDecl),
pub enum TopLevel {
Declaration(Declaration),
- Fact(Term),
+ Fact(Term),
Predicate(Predicate),
Query(Vec<QueryTerm>),
- Rule(Rule),
+ Rule(Rule),
}
impl TopLevel {
(=:=)/2, (-)/1, (>=)/2, (=<)/2, (,)/2, (->)/2, (;)/2, (=..)/2,
(==)/2, (\==)/2, (@=<)/2, (@>=)/2, (@<)/2, (@>)/2, (=@=)/2,
(\=@=)/2, (:)/2, call_with_inference_limit/3, catch/3,
- current_prolog_flag/2, set_prolog_flag/2,
- setup_call_cleanup/3, term_variables/2, throw/1, true/0,
- false/0]).
+ current_prolog_flag/2, set_prolog_flag/2, term_variables/2,
+ setup_call_cleanup/3, throw/1, true/0, false/0]).
/* this is an implementation specific declarative operator used to implement call_with_inference_limit/3
and setup_call_cleanup/3. switches to the default trust_me and retry_me_else. Indexing choice
'$call_with_default_policy'(I1 is I0 + 1),
'$call_with_default_policy'(get_args(Args, Func, I1, N)).
-term_variables(Term, Vars) :- '$term_variables'(Term, Vars).
-
+% term_variables.
+
+term_variables(Term, Vars) :-
+ error:can_be(list, Vars),
+ '$term_variables'(Term, Vars).
+
% setup_call_cleanup.
setup_call_cleanup(S, G, C) :- '$get_b_value'(B),
:- module(terms, [numbervars/3]).
:- use_module(library(error)).
-
+
numbervars(Term, N0, N) :-
+ catch(internal_numbervars(Term, N0, N), error(E,Ctx),
+ ( ( var(Ctx) -> Ctx = numbervars/3 ; true ), throw(error(E,Ctx) ) ) ).
+
+internal_numbervars(Term, N0, N) :-
must_be(integer, N0),
can_be(integer, N),
term_variables(Term, Vars),
- numberlist(Vars, N0,N).
+ numberlist(Vars, N0, N).
numberlist([], N,N).
numberlist(['$VAR'(N0)|Vars], N0,N) :-
machine_st.pstr_tr = machine_st.or_stack[b].pstr_tr;
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
-
+
machine_st.heap.truncate(machine_st.or_stack[b].h);
machine_st.hb = machine_st.heap.h;
let curr_tr = machine_st.tr;
machine_st.unwind_trail(old_tr, curr_tr);
- machine_st.tr = machine_st.or_stack[b].tr;
+ machine_st.tr = machine_st.or_stack[b].tr;
machine_st.trail.truncate(machine_st.tr);
machine_st.pstr_tr = machine_st.or_stack[b].pstr_tr;
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
-
+
machine_st.heap.truncate(machine_st.or_stack[b].h);
machine_st.hb = machine_st.heap.h;
machine_st.unwind_trail(old_tr, curr_tr);
machine_st.tr = machine_st.or_stack[b].tr;
-
+
machine_st.trail.truncate(machine_st.tr);
let old_pstr_tr = machine_st.or_stack[b].pstr_tr;
machine_st.pstr_tr = machine_st.or_stack[b].pstr_tr;
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
-
+
machine_st.heap.truncate(machine_st.or_stack[b].h);
machine_st.b = machine_st.or_stack[b].b;
machine_st.unwind_trail(old_tr, curr_tr);
machine_st.tr = machine_st.or_stack[b].tr;
-
+
machine_st.trail.truncate(machine_st.tr);
let old_pstr_tr = machine_st.or_stack[b].pstr_tr;
machine_st.pstr_tr = machine_st.or_stack[b].pstr_tr;
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
-
+
machine_st.heap.truncate(machine_st.or_stack[b].h);
machine_st.b = machine_st.or_stack[b].b;
stub));
},
IndexPtr::Index(compiled_tl_index) =>
- execute_at_index(machine_st, arity, compiled_tl_index)
+ execute_at_index(machine_st, arity, compiled_tl_index)
}
Ok(())
}
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize,
- indices: MachineCodeIndices<'a>) //code_dirs: CodeDirs)
+ indices: MachineCodeIndices<'a>)
-> CallResult
{
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
- let user = clause_name!("user");
-
match ClauseType::from(name.clone(), arity, None) {
ClauseType::CallN => {
machine_st.handle_internal_call_n(arity);
},
ClauseType::Inlined(inlined) =>
machine_st.execute_inlined(&inlined),
- ClauseType::Op(..) | ClauseType::Named(..) =>
- if let Some(idx) = indices.get_code_index((name.clone(), arity), user) {
+ ClauseType::Op(..) | ClauseType::Named(..) => {
+ let module = name.owning_module();
+
+ if let Some(idx) = indices.get_code_index((name.clone(), arity), module) {
self.context_call(machine_st, name, arity, idx, indices)?;
} else {
let h = machine_st.heap.h;
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
return Err(machine_st.error_form(MachineError::existence_error(h, name, arity),
stub));
- },
+ }
+ },
ClauseType::Hook(_) | ClauseType::System(_) => {
let name = Addr::Con(Constant::Atom(name, None));
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
use prolog_parser::ast::*;
use prolog_parser::string_list::StringList;
+use prolog_parser::tabled_rc::TabledData;
use prolog::instructions::*;
use prolog::and_stack::*;
use prolog::num::rational::Ratio;
use prolog::or_stack::*;
-use std::cell::RefCell;
use std::cmp::{max, Ordering};
use std::collections::{HashMap, HashSet};
use std::rc::Rc;
impl MachineState {
pub(super) fn new() -> Self {
MachineState {
- atom_tbl: Rc::new(RefCell::new(HashSet::new())),
+ atom_tbl: TabledData::new(Rc::new("user".to_string())),
s: 0,
p: CodePtr::default(),
b: 0,
cached_query: Option<Code>
}
-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 Index<LocalCodePtr> for Machine {
type Output = Line;
self.op_dir
}
- fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex> {
- get_code_index(&self.code_dir, &self.modules, key, module)
+ fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex>
+ {
+ match module.as_str() {
+ "user" | "builtin" => self.code_dir.get(&key).cloned(),
+ _ => self.modules.get(&module).and_then(|ref module| {
+ module.code_dir.get(&key).cloned().map(CodeIndex::from)
+ })
+ }
}
fn remove_code_index(&mut self, key: PredicateKey) {
self.code_dir.remove(&key);
}
- fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex) {
+ fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex)
+ {
if let Some(ref mut code_idx) = self.code_dir.get_mut(&(name.clone(), arity)) {
if !code_idx.is_undefined() {
println!("warning: overwriting {}/{}", &name, arity);
static LISTS: &str = include_str!("../lib/lists.pl");
static CONTROL: &str = include_str!("../lib/control.pl");
static QUEUES: &str = include_str!("../lib/queues.pl");
-static ERROR: &str = include_str!("../lib/error.pl");
+static ERROR: &str = include_str!("../lib/error.pl");
static TERMS: &str = include_str!("../lib/terms.pl");
impl Machine {
#[inline]
pub fn remove_module(&mut self, module: &Module) {
- let mut indices = machine_code_indices!(&mut self.code_dir.borrow_mut(), &mut self.op_dir,
+ let mut indices = machine_code_indices!(&mut self.code_dir.borrow_mut(),
+ &mut self.op_dir,
&mut self.modules);
indices.remove_module(clause_name!("user"), module);
}
{
let key = (clause_name!("term_expansion"), 2);
let preds = self.term_dir.entry(key).or_insert(Predicate(vec![]));
-
+
preds.0.push(clause);
-
+
let mut cg = CodeGenerator::<DebrayAllocator>::new(false, self.ms.flags);
let code = cg.compile_predicate(&preds.0)?;
Ok(self.term_expanders = code)
}
-
+
fn lookup_instr(&self, p: CodePtr) -> Option<Line> {
match p {
CodePtr::Local(LocalCodePtr::UserTermExpansion(p)) =>
}
}
+ #[inline]
+ pub fn set_atom_tbl(&mut self, atom_tbl: TabledData<Atom>) {
+ self.parser.set_atom_tbl(atom_tbl);
+ }
+
#[inline]
pub fn add_to_top(&mut self, buf: &str) {
self.parser.add_to_top(buf);
}
macro_rules! machine_code_indices {
- ($code_dir:expr, $op_dir:expr, $modules:expr) => ( //, $modules:expr) => (
- MachineCodeIndices { code_dir: $code_dir, op_dir: $op_dir,
- modules: $modules} //, modules: $modules }
+ ($code_dir:expr, $op_dir:expr, $modules:expr) => (
+ MachineCodeIndices { code_dir: $code_dir,
+ op_dir: $op_dir,
+ modules: $modules }
)
}
macro_rules! default_machine_code_indices {
() => (
- machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir(),
- &mut HashMap::new());
+ machine_code_indices!(&mut CodeDir::new(),
+ &mut default_op_dir(),
+ &mut HashMap::new())
)
}
}
pub struct TopLevelBatchWorker<R: Read> {
- term_stream: TermStream<R>,
+ pub(crate) term_stream: TermStream<R>,
rel_worker: RelationWorker,
static_code_dir: Rc<RefCell<CodeDir>>,
- pub results: Vec<(Predicate, VecDeque<TopLevel>)>,
- pub in_module: bool
+ pub(crate) results: Vec<(Predicate, VecDeque<TopLevel>)>,
+ pub(crate) in_module: bool
}
impl<R: Read> TopLevelBatchWorker<R> {
}
}
+impl fmt::Display for ModuleCodeIndex {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", self.0)
+ }
+}
+
impl fmt::Display for FactInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {