From 2d7032e61a2939f9ca76b568816c0297c1835754 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Mon, 18 Jun 2018 21:28:22 -0600 Subject: [PATCH] prepare for changes to relocation scheme --- src/prolog/ast.rs | 16 ++++++++- src/prolog/machine/mod.rs | 3 +- src/prolog/toplevel.rs | 75 ++++++++++++++++++++------------------- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index 7ba81748..b84cd603 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -147,6 +147,8 @@ pub type CodeDir = HashMap; pub type TermDir = HashMap; +pub type ModuleDir = HashMap; + pub type PredicateKey = (ClauseName, usize); // name, arity. pub struct ModuleDecl { @@ -586,7 +588,7 @@ impl InlinedClauseType { &InlinedClauseType::IsVar(..) => "var" } } - + pub fn from(name: &str, arity: usize) -> Option { let r1 = temp_v!(1); let r2 = temp_v!(2); @@ -974,6 +976,18 @@ impl ClauseType { } } + /* + pub fn lookup(wam: &Machine, name: ClauseName, arity: usize, fixity: Option) -> Self { + match ClauseType::from(name, arity, fixity) { + ClauseType::Named(name, default_idx) => { + + }, + ClauseType::Op(name, fixity, default_idx) => { + }, + ct => ct + } + } + */ pub fn from(name: ClauseName, arity: usize, fixity: Option) -> Self { InlinedClauseType::from(name.as_str(), arity) .map(ClauseType::Inlined) diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index ddbf0b37..91e4cdf6 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -20,6 +20,7 @@ use std::rc::Rc; pub struct MachineCodeIndex<'a> { pub code_dir: &'a mut CodeDir, pub op_dir: &'a mut OpDir, +// pub modules: &'a ModuleDir // &'a HashMap } pub struct Machine { @@ -30,7 +31,7 @@ pub struct Machine { pub(super) code_dir: CodeDir, pub(super) op_dir: OpDir, term_dir: TermDir, - modules: HashMap, + modules: ModuleDir, // HashMap, cached_query: Option } diff --git a/src/prolog/toplevel.rs b/src/prolog/toplevel.rs index 5b8f763a..f9aea022 100644 --- a/src/prolog/toplevel.rs +++ b/src/prolog/toplevel.rs @@ -239,7 +239,7 @@ fn unfold_by_str(mut term: Term, s: &str) -> Vec terms.push(fst); term = snd; } - + terms.push(term); terms } @@ -403,19 +403,19 @@ impl RelationWorker { }, Term::Var(_, ref v) if v.as_str() == "!" => Ok(QueryTerm::UnblockedCut(Cell::default())), - Term::Clause(r, name, mut terms, fixity) => + Term::Clause(r, name, mut terms, fixity) => if name.as_str() == ";" && terms.len() == 2 { let term = Term::Clause(r, name.clone(), terms, fixity); let (stub, clauses) = self.fabricate_disjunct(term); - + self.queue.push_back(clauses); Ok(QueryTerm::Jump(stub)) } else if name.as_str() == "->" && terms.len() == 2 { let conq = *terms.pop().unwrap(); let prec = *terms.pop().unwrap(); - + let (stub, clauses) = self.fabricate_if_then(prec, conq); - + self.queue.push_back(clauses); Ok(QueryTerm::Jump(stub)) } else if name.as_str() == "$get_level" && terms.len() == 1 { @@ -570,56 +570,51 @@ impl<'a, R: Read> TopLevelWorker<'a, R> { TopLevelWorker { parser: Parser::new(inner, atom_tbl), indices } } - fn add_predicate(&mut self, name: ClauseName, mod_name: ClauseName, tl: TopLevel) - -> Vec - { - let add_name = move |arity| { + fn add_name(&mut self, pred: &PredicateClause, mod_name: ClauseName) -> Option { + pred.name().and_then(move |name| { let idx = CodeIndex(Rc::new(RefCell::new((IndexPtr::Undefined, mod_name)))); - self.indices.code_dir.insert((name, arity), idx); - }; - + self.indices.code_dir.insert((name.clone(), pred.arity()), idx); + + Some(name) + }) + } + + fn add_predicate(&mut self, tl: TopLevel) -> Vec + { match tl { - TopLevel::Rule(rule) => { - add_name(rule.head.1.len()); - vec![PredicateClause::Rule(rule)] - }, - TopLevel::Fact(fact) => { - add_name(fact.arity()); - vec![PredicateClause::Fact(fact)] - }, - TopLevel::Predicate(preds) => { - add_name(preds.0.len()); - preds.0 - }, + TopLevel::Rule(rule) => vec![PredicateClause::Rule(rule)], + TopLevel::Fact(fact) => vec![PredicateClause::Fact(fact)], + TopLevel::Predicate(preds) => preds.0, _ => vec![] } } - + pub fn parse_batch(&mut self, wam: &Machine) -> Result, SessionError> { let mut preds = vec![]; let mut results = vec![]; - let mut mod_name = clause_name!("user"); + let mut mod_name = clause_name!("user"); let mut rel_worker = RelationWorker::new(); while !self.parser.eof() { self.parser.reset(); // empty the parser stack of token descriptions. let term = self.parser.read_term(&self.indices.op_dir)?; - let mut new_rel_worker = RelationWorker::new(); + let mut new_rel_worker = RelationWorker::new(); //wam, mod_name.clone()); let tl = new_rel_worker.try_term_to_tl(term, true)?; - if !is_consistent(&tl, &preds) { + if !is_consistent(&tl, &preds) { // if is_consistent returns false, preds is non-empty. + preds.first().map(|pred| self.add_name(pred, mod_name.clone())); results.push(deque_to_packet(append_preds(&mut preds), rel_worker.parse_queue()?)); } rel_worker.absorb(new_rel_worker); - + match tl { - TopLevel::Declaration(Declaration::UseModule(name)) => + TopLevel::Declaration(Declaration::UseModule(name)) => if let Some(module) = wam.get_module(name) { self.indices.use_module(module); - }, + }, TopLevel::Declaration(Declaration::Op(op_decl)) => { op_decl.submit(mod_name.clone(), self.indices.op_dir)?; }, @@ -631,9 +626,10 @@ impl<'a, R: Read> TopLevelWorker<'a, R> { TopLevel::Declaration(decl) => { results.push(TopLevelPacket::Decl(TopLevel::Declaration(decl), vec![])); }, - tl => match tl.name() { - Some(name) => preds.extend(self.add_predicate(name, mod_name.clone(), tl)), - _ => return Err(SessionError::NamelessEntry) + tl => if tl.name().is_some() { + preds.extend(self.add_predicate(tl)) + } else { + return Err(SessionError::NamelessEntry) } }; } @@ -641,13 +637,13 @@ impl<'a, R: Read> TopLevelWorker<'a, R> { if !preds.is_empty() { results.push(deque_to_packet(append_preds(&mut preds), rel_worker.parse_queue()?)); } - + Ok(results) } pub fn parse_code(&mut self) -> Result { - let mut rel_worker = RelationWorker::new(); + let mut rel_worker = RelationWorker::new(); //wam, clause_name!("user")); let terms = self.parser.read(self.indices.op_dir)?; let mut tls = rel_worker.try_terms_to_tls(terms, true)?; @@ -656,6 +652,13 @@ impl<'a, R: Read> TopLevelWorker<'a, R> { let tl = merge_clauses(&mut tls)?; if tls.is_empty() { + /* + match tl.name() { + Some(name) => self.add_name(name, tl.arity(), clause_name!("user")), + _ => {} + }; + */ + Ok(deque_to_packet(tl, results)) } else { Err(ParserError::InconsistentEntry) -- 2.54.0