From d09e9fd8d81c0a05063d244ab4e610dccd465a56 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Thu, 13 Sep 2018 00:46:41 -0600 Subject: [PATCH] provisional #4 --- src/prolog/compile.rs | 6 ++- src/prolog/machine/mod.rs | 24 +--------- src/prolog/toplevel.rs | 98 +++++++++++++++++++++++++++++++-------- 3 files changed, 85 insertions(+), 43 deletions(-) diff --git a/src/prolog/compile.rs b/src/prolog/compile.rs index f0332607..385eeb19 100644 --- a/src/prolog/compile.rs +++ b/src/prolog/compile.rs @@ -100,7 +100,7 @@ fn compile_query(terms: Vec, queue: Vec, flags: MachineFlag fn package_term(wam: &mut Machine, term: Term) -> Result { 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); - + parse_term(term, indices) } @@ -267,7 +267,8 @@ pub fn compile_listing<'a, R>(wam: &mut Machine, src: R, mut indices: MachineCod -> EvalSession 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 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() { 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)); diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 6d1c226e..16dfc389 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -38,26 +38,6 @@ impl<'a> MachineCodeIndices<'a> { swap(&mut self.modules, &mut other.modules); } - pub(super) - fn get_clause_type(&mut self, name: ClauseName, arity: usize, fixity: Option) -> 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] pub(super) fn to_code_dirs(self) -> CodeDirs<'a> { CodeDirs { code_dir: self.code_dir, @@ -176,7 +156,7 @@ impl Machine { pub fn atom_tbl(&self) -> TabledData { self.ms.atom_tbl.clone() } - + pub fn add_batched_code(&mut self, code: Code, code_dir: CodeDir) -> Result<(), SessionError> { for (ref key, ref idx) in code_dir.iter() { @@ -230,7 +210,7 @@ impl Machine { pub fn insert_module(&mut self, module: Module) { self.modules.insert(module.module_decl.name.clone(), module); } - + #[inline] pub fn add_module(&mut self, module: Module, code: Code) { self.modules.insert(module.module_decl.name.clone(), module); diff --git a/src/prolog/toplevel.rs b/src/prolog/toplevel.rs index e32a86e1..b4b7f832 100644 --- a/src/prolog/toplevel.rs +++ b/src/prolog/toplevel.rs @@ -13,6 +13,58 @@ use std::io::Read; use std::mem; use std::rc::Rc; +struct CompositeIndices<'a, 'b : 'a> { + local: &'a mut MachineCodeIndices<'b>, + static_code_dir: Option>> +} + +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) -> 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 { match term { @@ -312,7 +364,7 @@ pub enum TopLevelPacket { } struct RelationWorker { - queue: VecDeque> + queue: VecDeque>, } impl RelationWorker { @@ -409,7 +461,7 @@ impl RelationWorker { self.fabricate_rule(fold_by_str(prec_seq, body_term, comma_sym)) } - fn to_query_term(&mut self, indices: &mut MachineCodeIndices, term: Term) -> Result + fn to_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result { match term { Term::Constant(r, Constant::Atom(name)) => @@ -496,7 +548,7 @@ impl RelationWorker { } } - fn pre_query_term(&mut self, indices: &mut MachineCodeIndices, term: Term) -> Result + fn pre_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result { match term { Term::Clause(r, name, mut subterms, fixity) => @@ -513,7 +565,7 @@ impl RelationWorker { } } - fn setup_query(&mut self, indices: &mut MachineCodeIndices, terms: Vec>, blocks_cuts: bool) + fn setup_query(&mut self, indices: &mut CompositeIndices, terms: Vec>, blocks_cuts: bool) -> Result, ParserError> { let mut query_terms = vec![]; @@ -548,7 +600,7 @@ impl RelationWorker { Ok(query_terms) } - fn setup_rule(&mut self, indices: &mut MachineCodeIndices, mut terms: Vec>, blocks_cuts: bool) + fn setup_rule(&mut self, indices: &mut CompositeIndices, mut terms: Vec>, blocks_cuts: bool) -> Result { 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 { match term { @@ -584,7 +636,7 @@ impl RelationWorker { } } - fn try_terms_to_tls(&mut self, indices: &mut MachineCodeIndices, terms: I, blocks_cuts: bool) + fn try_terms_to_tls(&mut self, indices: &mut CompositeIndices, terms: I, blocks_cuts: bool) -> Result, ParserError> where I: IntoIterator { @@ -597,7 +649,7 @@ impl RelationWorker { Ok(results) } - fn parse_queue(&mut self, indices: &mut MachineCodeIndices) -> Result, ParserError> + fn parse_queue(&mut self, indices: &mut CompositeIndices) -> Result, ParserError> { let mut queue = VecDeque::new(); @@ -614,10 +666,11 @@ impl RelationWorker { } } -pub fn parse_term(term: Term, mut indices: MachineCodeIndices) -> Result +pub fn parse_term<'a>(term: Term, mut indices: MachineCodeIndices<'a>) -> Result { 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 results = rel_worker.parse_queue(&mut indices)?; @@ -627,40 +680,47 @@ pub fn parse_term(term: Term, mut indices: MachineCodeIndices) -> Result { parser: Parser, rel_worker: RelationWorker, + static_code_dir: Rc>, pub results: Vec<(Predicate, VecDeque)>, pub in_module: bool } impl TopLevelBatchWorker { - pub fn new(inner: R, atom_tbl: TabledData, flags: MachineFlags) -> Self + pub fn new(inner: R, atom_tbl: TabledData, flags: MachineFlags, + static_code_dir: Rc>) + -> Self { TopLevelBatchWorker { parser: Parser::new(inner, atom_tbl, flags), rel_worker: RelationWorker::new(), + static_code_dir, results: vec![], in_module: false } - } + } #[inline] fn read_term(&mut self, static_op_dir: &OpDir, op_dir: &OpDir) -> Result { let composite_op = composite_op!(self.in_module, op_dir, static_op_dir); self.parser.read_term(composite_op) } - + pub - fn consume(&mut self, op_dir: &OpDir, indices: &mut MachineCodeIndices) - -> Result, SessionError> + fn consume<'a, 'b : 'a>(&mut self, op_dir: &OpDir, indices: &'a mut MachineCodeIndices<'b>) + -> Result, SessionError> { let mut preds = vec![]; + let mut indices = composite_indices!(self.in_module, indices, + self.static_code_dir.clone()); while !self.parser.eof()? { self.parser.reset(); // empty the parser stack of token descriptions. let mut new_rel_worker = RelationWorker::new(); - let term = self.read_term(op_dir, &indices.op_dir)?; - let tl = new_rel_worker.try_term_to_tl(indices, term, true)?; + let term = self.read_term(op_dir, &indices.local.op_dir)?; + + 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. - 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)); } @@ -676,7 +736,7 @@ impl TopLevelBatchWorker { } 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)); } -- 2.54.0