provisional #4
This commit is contained in:
@@ -100,7 +100,7 @@ fn compile_query(terms: Vec<QueryTerm>, queue: Vec<TopLevel>, flags: MachineFlag
|
|||||||
fn package_term(wam: &mut Machine, term: Term) -> Result<TopLevelPacket, ParserError> {
|
fn package_term(wam: &mut Machine, term: Term) -> Result<TopLevelPacket, ParserError> {
|
||||||
let mut code_dir = wam.code_dir.borrow_mut();
|
let mut code_dir = wam.code_dir.borrow_mut();
|
||||||
let indices = machine_code_indices!(code_dir.deref_mut(), &mut wam.op_dir, &mut wam.modules);
|
let indices = machine_code_indices!(code_dir.deref_mut(), &mut wam.op_dir, &mut wam.modules);
|
||||||
|
|
||||||
parse_term(term, indices)
|
parse_term(term, indices)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +267,8 @@ pub fn compile_listing<'a, R>(wam: &mut Machine, src: R, mut indices: MachineCod
|
|||||||
-> EvalSession
|
-> EvalSession
|
||||||
where R: Read
|
where R: Read
|
||||||
{
|
{
|
||||||
let mut worker = TopLevelBatchWorker::new(src, wam.atom_tbl(), wam.machine_flags());
|
let mut worker = TopLevelBatchWorker::new(src, wam.atom_tbl(), wam.machine_flags(),
|
||||||
|
wam.code_dir.clone());
|
||||||
let mut compiler = ListingCompiler::new();
|
let mut compiler = ListingCompiler::new();
|
||||||
let mut toplevel_results = vec![];
|
let mut toplevel_results = vec![];
|
||||||
|
|
||||||
@@ -275,6 +276,7 @@ pub fn compile_listing<'a, R>(wam: &mut Machine, src: R, mut indices: MachineCod
|
|||||||
if decl.is_module_decl() {
|
if decl.is_module_decl() {
|
||||||
toplevel_indices.copy_and_swap(&mut indices);
|
toplevel_indices.copy_and_swap(&mut indices);
|
||||||
mem::swap(&mut worker.results, &mut toplevel_results);
|
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));
|
||||||
|
|||||||
@@ -38,26 +38,6 @@ impl<'a> MachineCodeIndices<'a> {
|
|||||||
swap(&mut self.modules, &mut other.modules);
|
swap(&mut self.modules, &mut other.modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
|
||||||
fn get_clause_type(&mut self, name: ClauseName, arity: usize, fixity: Option<Fixity>) -> ClauseType
|
|
||||||
{
|
|
||||||
match ClauseType::from(name, arity, fixity) {
|
|
||||||
ClauseType::Named(name, _) => {
|
|
||||||
let idx = self.code_dir.entry((name.clone(), arity))
|
|
||||||
.or_insert(CodeIndex::default());
|
|
||||||
|
|
||||||
ClauseType::Named(name, idx.clone())
|
|
||||||
},
|
|
||||||
ClauseType::Op(name, fixity, _) => {
|
|
||||||
let idx = self.code_dir.entry((name.clone(), arity))
|
|
||||||
.or_insert(CodeIndex::default());
|
|
||||||
|
|
||||||
ClauseType::Op(name, fixity, idx.clone())
|
|
||||||
},
|
|
||||||
ct => ct
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn to_code_dirs(self) -> CodeDirs<'a> {
|
pub(super) fn to_code_dirs(self) -> CodeDirs<'a> {
|
||||||
CodeDirs { code_dir: self.code_dir,
|
CodeDirs { code_dir: self.code_dir,
|
||||||
@@ -176,7 +156,7 @@ impl Machine {
|
|||||||
pub fn atom_tbl(&self) -> TabledData<Atom> {
|
pub fn atom_tbl(&self) -> TabledData<Atom> {
|
||||||
self.ms.atom_tbl.clone()
|
self.ms.atom_tbl.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_batched_code(&mut self, code: Code, code_dir: CodeDir) -> Result<(), SessionError>
|
pub fn add_batched_code(&mut self, code: Code, code_dir: CodeDir) -> Result<(), SessionError>
|
||||||
{
|
{
|
||||||
for (ref key, ref idx) in code_dir.iter() {
|
for (ref key, ref idx) in code_dir.iter() {
|
||||||
@@ -230,7 +210,7 @@ impl Machine {
|
|||||||
pub fn insert_module(&mut self, module: Module) {
|
pub fn insert_module(&mut self, module: Module) {
|
||||||
self.modules.insert(module.module_decl.name.clone(), module);
|
self.modules.insert(module.module_decl.name.clone(), module);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn add_module(&mut self, module: Module, code: Code) {
|
pub fn add_module(&mut self, module: Module, code: Code) {
|
||||||
self.modules.insert(module.module_decl.name.clone(), module);
|
self.modules.insert(module.module_decl.name.clone(), module);
|
||||||
|
|||||||
@@ -13,6 +13,58 @@ use std::io::Read;
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
struct CompositeIndices<'a, 'b : 'a> {
|
||||||
|
local: &'a mut MachineCodeIndices<'b>,
|
||||||
|
static_code_dir: Option<Rc<RefCell<CodeDir>>>
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! composite_indices {
|
||||||
|
($in_module: expr, $local: expr, $static_code_dir: expr) => (
|
||||||
|
CompositeIndices { local: $local,
|
||||||
|
static_code_dir: if $in_module {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some($static_code_dir)
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
($local: expr) => (
|
||||||
|
CompositeIndices { local: $local, static_code_dir: None }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b : 'a> CompositeIndices<'a, 'b>
|
||||||
|
{
|
||||||
|
fn get_code_index(&mut self, name: ClauseName, arity: usize) -> CodeIndex {
|
||||||
|
let idx_opt = self.local.code_dir.get(&(name.clone(), arity)).cloned()
|
||||||
|
.or_else(|| self.static_code_dir.clone().and_then(|code_dir| {
|
||||||
|
code_dir.borrow().get(&(name.clone(), arity)).cloned()
|
||||||
|
}));
|
||||||
|
|
||||||
|
if let Some(idx) = idx_opt {
|
||||||
|
idx.clone()
|
||||||
|
} else {
|
||||||
|
let idx = CodeIndex::default();
|
||||||
|
self.local.code_dir.insert((name, arity), idx.clone());
|
||||||
|
idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_clause_type(&mut self, name: ClauseName, arity: usize, fixity: Option<Fixity>) -> ClauseType
|
||||||
|
{
|
||||||
|
match ClauseType::from(name, arity, fixity) {
|
||||||
|
ClauseType::Named(name, _) => {
|
||||||
|
let idx = self.get_code_index(name.clone(), arity);
|
||||||
|
ClauseType::Named(name, idx.clone())
|
||||||
|
},
|
||||||
|
ClauseType::Op(name, fixity, _) => {
|
||||||
|
let idx = self.get_code_index(name.clone(), arity);
|
||||||
|
ClauseType::Op(name, fixity, idx.clone())
|
||||||
|
},
|
||||||
|
ct => ct
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn setup_fact(term: Term) -> Result<Term, ParserError>
|
fn setup_fact(term: Term) -> Result<Term, ParserError>
|
||||||
{
|
{
|
||||||
match term {
|
match term {
|
||||||
@@ -312,7 +364,7 @@ pub enum TopLevelPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct RelationWorker {
|
struct RelationWorker {
|
||||||
queue: VecDeque<VecDeque<Term>>
|
queue: VecDeque<VecDeque<Term>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RelationWorker {
|
impl RelationWorker {
|
||||||
@@ -409,7 +461,7 @@ impl RelationWorker {
|
|||||||
self.fabricate_rule(fold_by_str(prec_seq, body_term, comma_sym))
|
self.fabricate_rule(fold_by_str(prec_seq, body_term, comma_sym))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_query_term(&mut self, indices: &mut MachineCodeIndices, term: Term) -> Result<QueryTerm, ParserError>
|
fn to_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result<QueryTerm, ParserError>
|
||||||
{
|
{
|
||||||
match term {
|
match term {
|
||||||
Term::Constant(r, Constant::Atom(name)) =>
|
Term::Constant(r, Constant::Atom(name)) =>
|
||||||
@@ -496,7 +548,7 @@ impl RelationWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pre_query_term(&mut self, indices: &mut MachineCodeIndices, term: Term) -> Result<QueryTerm, ParserError>
|
fn pre_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result<QueryTerm, ParserError>
|
||||||
{
|
{
|
||||||
match term {
|
match term {
|
||||||
Term::Clause(r, name, mut subterms, fixity) =>
|
Term::Clause(r, name, mut subterms, fixity) =>
|
||||||
@@ -513,7 +565,7 @@ impl RelationWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_query(&mut self, indices: &mut MachineCodeIndices, terms: Vec<Box<Term>>, blocks_cuts: bool)
|
fn setup_query(&mut self, indices: &mut CompositeIndices, terms: Vec<Box<Term>>, blocks_cuts: bool)
|
||||||
-> Result<Vec<QueryTerm>, ParserError>
|
-> Result<Vec<QueryTerm>, ParserError>
|
||||||
{
|
{
|
||||||
let mut query_terms = vec![];
|
let mut query_terms = vec![];
|
||||||
@@ -548,7 +600,7 @@ impl RelationWorker {
|
|||||||
Ok(query_terms)
|
Ok(query_terms)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_rule(&mut self, indices: &mut MachineCodeIndices, mut terms: Vec<Box<Term>>, blocks_cuts: bool)
|
fn setup_rule(&mut self, indices: &mut CompositeIndices, mut terms: Vec<Box<Term>>, blocks_cuts: bool)
|
||||||
-> Result<Rule, ParserError>
|
-> Result<Rule, ParserError>
|
||||||
{
|
{
|
||||||
let post_head_terms = terms.drain(1..).collect();
|
let post_head_terms = terms.drain(1..).collect();
|
||||||
@@ -565,7 +617,7 @@ impl RelationWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_term_to_tl(&mut self, indices: &mut MachineCodeIndices, term: Term, blocks_cuts: bool)
|
fn try_term_to_tl(&mut self, indices: &mut CompositeIndices, term: Term, blocks_cuts: bool)
|
||||||
-> Result<TopLevel, ParserError>
|
-> Result<TopLevel, ParserError>
|
||||||
{
|
{
|
||||||
match term {
|
match term {
|
||||||
@@ -584,7 +636,7 @@ impl RelationWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_terms_to_tls<I>(&mut self, indices: &mut MachineCodeIndices, terms: I, blocks_cuts: bool)
|
fn try_terms_to_tls<I>(&mut self, indices: &mut CompositeIndices, terms: I, blocks_cuts: bool)
|
||||||
-> Result<VecDeque<TopLevel>, ParserError>
|
-> Result<VecDeque<TopLevel>, ParserError>
|
||||||
where I: IntoIterator<Item=Term>
|
where I: IntoIterator<Item=Term>
|
||||||
{
|
{
|
||||||
@@ -597,7 +649,7 @@ impl RelationWorker {
|
|||||||
Ok(results)
|
Ok(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_queue(&mut self, indices: &mut MachineCodeIndices) -> Result<VecDeque<TopLevel>, ParserError>
|
fn parse_queue(&mut self, indices: &mut CompositeIndices) -> Result<VecDeque<TopLevel>, ParserError>
|
||||||
{
|
{
|
||||||
let mut queue = VecDeque::new();
|
let mut queue = VecDeque::new();
|
||||||
|
|
||||||
@@ -614,10 +666,11 @@ impl RelationWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_term(term: Term, mut indices: MachineCodeIndices) -> Result<TopLevelPacket, ParserError>
|
pub fn parse_term<'a>(term: Term, mut indices: MachineCodeIndices<'a>) -> Result<TopLevelPacket, ParserError>
|
||||||
{
|
{
|
||||||
let mut rel_worker = RelationWorker::new();
|
let mut rel_worker = RelationWorker::new();
|
||||||
|
let mut indices = composite_indices!(&mut indices);
|
||||||
|
|
||||||
let tl = rel_worker.try_term_to_tl(&mut indices, term, true)?;
|
let tl = rel_worker.try_term_to_tl(&mut indices, term, true)?;
|
||||||
let results = rel_worker.parse_queue(&mut indices)?;
|
let results = rel_worker.parse_queue(&mut indices)?;
|
||||||
|
|
||||||
@@ -627,40 +680,47 @@ pub fn parse_term(term: Term, mut indices: MachineCodeIndices) -> Result<TopLeve
|
|||||||
pub struct TopLevelBatchWorker<R: Read> {
|
pub struct TopLevelBatchWorker<R: Read> {
|
||||||
parser: Parser<R>,
|
parser: Parser<R>,
|
||||||
rel_worker: RelationWorker,
|
rel_worker: RelationWorker,
|
||||||
|
static_code_dir: Rc<RefCell<CodeDir>>,
|
||||||
pub results: Vec<(Predicate, VecDeque<TopLevel>)>,
|
pub results: Vec<(Predicate, VecDeque<TopLevel>)>,
|
||||||
pub in_module: bool
|
pub in_module: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read> TopLevelBatchWorker<R> {
|
impl<R: Read> TopLevelBatchWorker<R> {
|
||||||
pub fn new(inner: R, atom_tbl: TabledData<Atom>, flags: MachineFlags) -> Self
|
pub fn new(inner: R, atom_tbl: TabledData<Atom>, flags: MachineFlags,
|
||||||
|
static_code_dir: Rc<RefCell<CodeDir>>)
|
||||||
|
-> Self
|
||||||
{
|
{
|
||||||
TopLevelBatchWorker { parser: Parser::new(inner, atom_tbl, flags),
|
TopLevelBatchWorker { parser: Parser::new(inner, atom_tbl, flags),
|
||||||
rel_worker: RelationWorker::new(),
|
rel_worker: RelationWorker::new(),
|
||||||
|
static_code_dir,
|
||||||
results: vec![],
|
results: vec![],
|
||||||
in_module: false }
|
in_module: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_term(&mut self, static_op_dir: &OpDir, op_dir: &OpDir) -> Result<Term, ParserError> {
|
fn read_term(&mut self, static_op_dir: &OpDir, op_dir: &OpDir) -> Result<Term, ParserError> {
|
||||||
let composite_op = composite_op!(self.in_module, op_dir, static_op_dir);
|
let composite_op = composite_op!(self.in_module, op_dir, static_op_dir);
|
||||||
self.parser.read_term(composite_op)
|
self.parser.read_term(composite_op)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub
|
pub
|
||||||
fn consume(&mut self, op_dir: &OpDir, indices: &mut MachineCodeIndices)
|
fn consume<'a, 'b : 'a>(&mut self, op_dir: &OpDir, indices: &'a mut MachineCodeIndices<'b>)
|
||||||
-> Result<Option<Declaration>, SessionError>
|
-> Result<Option<Declaration>, SessionError>
|
||||||
{
|
{
|
||||||
let mut preds = vec![];
|
let mut preds = vec![];
|
||||||
|
let mut indices = composite_indices!(self.in_module, indices,
|
||||||
|
self.static_code_dir.clone());
|
||||||
|
|
||||||
while !self.parser.eof()? {
|
while !self.parser.eof()? {
|
||||||
self.parser.reset(); // empty the parser stack of token descriptions.
|
self.parser.reset(); // empty the parser stack of token descriptions.
|
||||||
|
|
||||||
let mut new_rel_worker = RelationWorker::new();
|
let mut new_rel_worker = RelationWorker::new();
|
||||||
let term = self.read_term(op_dir, &indices.op_dir)?;
|
let term = self.read_term(op_dir, &indices.local.op_dir)?;
|
||||||
let tl = new_rel_worker.try_term_to_tl(indices, term, true)?;
|
|
||||||
|
let tl = new_rel_worker.try_term_to_tl(&mut indices, term, true)?;
|
||||||
|
|
||||||
if !is_consistent(&tl, &preds) { // if is_consistent returns false, preds is non-empty.
|
if !is_consistent(&tl, &preds) { // if is_consistent returns false, preds is non-empty.
|
||||||
let result_queue = self.rel_worker.parse_queue(indices)?;
|
let result_queue = self.rel_worker.parse_queue(&mut indices)?;
|
||||||
self.results.push((append_preds(&mut preds), result_queue));
|
self.results.push((append_preds(&mut preds), result_queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,7 +736,7 @@ impl<R: Read> TopLevelBatchWorker<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !preds.is_empty() {
|
if !preds.is_empty() {
|
||||||
let result_queue = self.rel_worker.parse_queue(indices)?;
|
let result_queue = self.rel_worker.parse_queue(&mut indices)?;
|
||||||
self.results.push((append_preds(&mut preds), result_queue));
|
self.results.push((append_preds(&mut preds), result_queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user