]> Repositorios git - scryer-prolog.git/commitdiff
farm parser out to a crate, remove it as a git submodule.
authorMark Thom <[email protected]>
Tue, 4 Sep 2018 03:58:07 +0000 (21:58 -0600)
committerMark Thom <[email protected]>
Tue, 4 Sep 2018 03:58:07 +0000 (21:58 -0600)
29 files changed:
.gitmodules
Cargo.lock
Cargo.toml
src/main.rs
src/prolog/allocator.rs
src/prolog/arithmetic.rs
src/prolog/ast.rs
src/prolog/codegen.rs
src/prolog/compile.rs
src/prolog/copier.rs
src/prolog/debray_allocator.rs
src/prolog/fixtures.rs
src/prolog/heap_iter.rs
src/prolog/heap_print.rs
src/prolog/indexing.rs
src/prolog/io.rs
src/prolog/iterators.rs
src/prolog/machine/machine_errors.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs
src/prolog/machine/system_calls.rs
src/prolog/macros.rs
src/prolog/mod.rs
src/prolog/parser [deleted submodule]
src/prolog/read.rs
src/prolog/targets.rs
src/prolog/toplevel.rs
src/tests.rs

index ca057cc18e763e1b070bb49aaba5fb700faded93..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,4 +0,0 @@
-[submodule "src/prolog/parser"]
-       path = src/prolog/parser
-       url = http://github.com/mthom/prolog-parser
-       branch = rusty-wam_branch
index 3626ee47509a127f75fdd896a156df6809719056..a33c62b14f91a3b3756debc38968bd5301f7eac7 100644 (file)
@@ -84,6 +84,14 @@ dependencies = [
  "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "prolog_parser"
+version = "0.7.9"
+dependencies = [
+ "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)",
+]
+
 [[package]]
 name = "redox_syscall"
 version = "0.1.32"
@@ -104,6 +112,7 @@ dependencies = [
  "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.9",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
index 6c9f0e0afec27c377f2f4737a21be6bf89668c8f..4cafa5991390cd808ce4c96fd198f91a39002cae 100644 (file)
@@ -1,12 +1,16 @@
 [package]
 name = "rusty-wam"
 version = "0.7.9"
-authors = ["Mark Thom"]
+authors = ["Mark Thom <[email protected]>"]
+repository = "https://github.com/mthom/rusty-wam"
+description = "The Warren Abstract Machine in Rust."
+license = "BSD-3-Clause"
 
 [dependencies]
 downcast = "0.9.1"
 num = "0.2"
 ordered-float = "0.5.0"
+prolog_parser = "0.7.9"
 
 [dependencies.termion]
 version = "1.4.0"
\ No newline at end of file
index ddc82b101b978a543ff842d2c92f35bb9aa06946..2c53b5ffe89afee462f5631d4e682ea587188b45 100644 (file)
@@ -1,10 +1,11 @@
 #[macro_use] extern crate downcast;
+#[macro_use] extern crate prolog_parser;
 extern crate termion;
 
-#[macro_use]
+use prolog::ast::*;
+
 mod prolog;
 
-use prolog::ast::*;
 use prolog::compile::*;
 use prolog::io::*;
 use prolog::machine::*;
index b075b5c1fcf04d6f8bff75f1a19014106e56270a..cf6456813a52e6b681316eb3eb64234d8a4e6654 100644 (file)
@@ -1,3 +1,5 @@
+use prolog_parser::ast::*;
+
 use prolog::ast::*;
 use prolog::fixtures::*;
 use prolog::targets::*;
index 72f5c56289448ee258dfeb557f87a327e0d98244..b91df8f07d2b4b054778beedfb0efe869262e85d 100644 (file)
@@ -1,5 +1,6 @@
-use prolog::ast::*;
+use prolog_parser::ast::*;
 
+use prolog::ast::*;
 use std::cell::Cell;
 use std::cmp::{min, max};
 use std::rc::Rc;
index 3a51a0867076ab7c898608c344c202f5d7216d51..9a7fbf59559057db456e19ff6535af2dee412285 100644 (file)
-use prolog::num::bigint::{BigInt, BigUint};
-use prolog::num::{Float, Integer, One, Signed, ToPrimitive, Zero};
-use prolog::num::rational::{BigRational, Ratio};
-use prolog::ordered_float::*;
-use prolog::string_list::*;
-use prolog::tabled_rc::*;
+use prolog_parser::ast::*;
 
 use std::cell::{Cell, RefCell};
-use std::cmp::Ordering;
 use std::collections::{BTreeSet, HashMap, VecDeque};
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::io::Error as IOError;
-use std::ops::{Add, AddAssign, Div, Index, IndexMut, Sub, Mul, MulAssign, Neg};
+use std::cmp::Ordering;
+use std::ops::{Add, AddAssign, Index, IndexMut, Sub};
 use std::rc::Rc;
-use std::str::Utf8Error;
-use std::vec::Vec;
-
-pub type Atom = String;
-
-pub type Var = String;
-
-pub type Specifier = u32;
-
-pub const MAX_ARITY: usize = 63;
-
-pub const XFX: u32 = 0x0001;
-pub const XFY: u32 = 0x0002;
-pub const YFX: u32 = 0x0004;
-pub const XF: u32  = 0x0010;
-pub const YF: u32  = 0x0020;
-pub const FX: u32  = 0x0040;
-pub const FY: u32  = 0x0080;
-pub const DELIMITER: u32 = 0x0100;
-pub const TERM: u32  = 0x1000;
-pub const LTERM: u32 = 0x3000;
-
-macro_rules! is_term {
-    ($x:expr) => ( ($x & TERM) != 0 )
-}
-
-macro_rules! is_lterm {
-    ($x:expr) => ( ($x & LTERM) != 0 )
-}
 
-macro_rules! is_op {
-    ($x:expr) => ( $x & (XF | YF | FX | FY | XFX | XFY | YFX) != 0 )
+#[derive(Clone, PartialEq)]
+pub enum InlinedClauseType {
+    CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),    
+    IsAtom(RegType),
+    IsAtomic(RegType),
+    IsCompound(RegType),
+    IsInteger(RegType),
+    IsRational(RegType),
+    IsString(RegType),
+    IsFloat(RegType),
+    IsNonVar(RegType),
+    IsPartialString(RegType),
+    IsVar(RegType)
 }
 
-macro_rules! is_postfix {
-    ($x:expr) => ( $x & (XF | YF) != 0 )
-}
+impl InlinedClauseType {
+    pub fn name(&self) -> &'static str {
+        match self {
+            &InlinedClauseType::CompareNumber(qt, ..) => qt.name(),
+            &InlinedClauseType::IsAtom(..) => "atom",
+            &InlinedClauseType::IsAtomic(..) => "atomic",
+            &InlinedClauseType::IsCompound(..) => "compound",
+            &InlinedClauseType::IsInteger (..) => "integer",
+            &InlinedClauseType::IsRational(..) => "rational",
+            &InlinedClauseType::IsString(..) => "string",
+            &InlinedClauseType::IsFloat (..) => "float",
+            &InlinedClauseType::IsNonVar(..) => "nonvar",
+            &InlinedClauseType::IsPartialString(..) => "partial_string",
+            &InlinedClauseType::IsVar(..) => "var",            
+        }
+    }
 
-macro_rules! is_infix {
-    ($x:expr) => ( ($x & (XFX | XFY | YFX)) != 0 )
-}
+    pub fn from(name: &str, arity: usize) -> Option<Self> {
+        let r1 = temp_v!(1);
+        let r2 = temp_v!(2);
 
-macro_rules! is_xfx {
-    ($x:expr) => ( ($x & XFX) != 0 )
-}
+        let a1 = ArithmeticTerm::Reg(r1);
+        let a2 = ArithmeticTerm::Reg(r2);
 
-macro_rules! is_xfy {
-    ($x:expr) => ( ($x & XFY) != 0 )
+        match (name, arity) {
+            (">", 2) =>
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan, a1, a2)),
+            ("<", 2) =>
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan, a1, a2)),
+            (">=", 2) =>
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual,a1, a2)),
+            ("=<", 2) =>
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual, a1, a2)),
+            ("=\\=", 2) =>
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual, a1, a2)),
+            ("=:=", 2) =>
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal, a1, a2)),
+            ("atom", 1) => Some(InlinedClauseType::IsAtom(r1)),
+            ("atomic", 1) => Some(InlinedClauseType::IsAtomic(r1)),
+            ("compound", 1) => Some(InlinedClauseType::IsCompound(r1)),
+            ("integer", 1) => Some(InlinedClauseType::IsInteger(r1)),
+            ("rational", 1) => Some(InlinedClauseType::IsRational(r1)),
+            ("string", 1) => Some(InlinedClauseType::IsString(r1)),
+            ("float", 1) => Some(InlinedClauseType::IsFloat(r1)),
+            ("nonvar", 1) => Some(InlinedClauseType::IsNonVar(r1)),
+            ("var", 1) => Some(InlinedClauseType::IsVar(r1)),
+            ("is_partial_string", 1) => Some(InlinedClauseType::IsPartialString(r1)),
+            _ => None
+        }
+    }
 }
 
-macro_rules! is_yfx {
-    ($x:expr) => ( ($x & YFX) != 0 )
+#[derive(Clone, Copy, PartialEq)]
+pub enum CompareNumberQT {
+    GreaterThan,
+    LessThan,
+    GreaterThanOrEqual,
+    LessThanOrEqual,
+    NotEqual,
+    Equal
 }
 
-macro_rules! is_yf {
-    ($x:expr) => ( ($x & YF) != 0 )
+impl CompareNumberQT {
+    fn name(self) -> &'static str {
+        match self {
+            CompareNumberQT::GreaterThan => ">",
+            CompareNumberQT::LessThan => "<",
+            CompareNumberQT::GreaterThanOrEqual => ">=",
+            CompareNumberQT::LessThanOrEqual => "=<",
+            CompareNumberQT::NotEqual => "=\\=",
+            CompareNumberQT::Equal => "=:="
+        }
+    }
 }
 
-macro_rules! is_xf {
-    ($x:expr) => ( ($x & XF) != 0 )
+#[derive(Clone, Copy, PartialEq)]
+pub enum CompareTermQT {
+    LessThan,
+    LessThanOrEqual,
+    Equal,
+    GreaterThanOrEqual,
+    GreaterThan,
+    NotEqual,
 }
 
-macro_rules! is_fx {
-    ($x:expr) => ( ($x & FX) != 0 )
+impl CompareTermQT {
+    fn name<'a>(self) -> &'a str {
+        match self {
+            CompareTermQT::GreaterThan => "@>",
+            CompareTermQT::LessThan => "@<",
+            CompareTermQT::GreaterThanOrEqual => "@>=",
+            CompareTermQT::LessThanOrEqual => "@=<",
+            CompareTermQT::NotEqual => "\\=@=",
+            CompareTermQT::Equal => "=@="
+        }
+    }
 }
 
-macro_rules! is_fy {
-    ($x:expr) => ( ($x & FY) != 0 )
-}
+// vars of predicate, toplevel offset.  Vec<Term> is always a vector
+// of vars (we get their adjoining cells this way).
+pub type JumpStub = Vec<Term>;
 
-macro_rules! prefix {
-    ($x:expr) => ($x & (FX | FY))
+pub enum QueryTerm {
+    // register, clause type, subterms, use default call policy.
+    Clause(Cell<RegType>, ClauseType, Vec<Box<Term>>, bool),
+    BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q.
+    UnblockedCut(Cell<VarReg>),
+    GetLevelAndUnify(Cell<VarReg>, Rc<Var>),
+    Jump(JumpStub)
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
-pub enum GenContext {
-    Head, Mid(usize), Last(usize) // Mid & Last: chunk_num
-}
+impl QueryTerm {
+    pub fn set_default_caller(&mut self) {
+        match self {
+            &mut QueryTerm::Clause(_, _, _, ref mut use_default_cp) => *use_default_cp = true,
+            _ => {}
+        };
+    }
 
-impl GenContext {
-    pub fn chunk_num(self) -> usize {
+    pub fn arity(&self) -> usize {
         match self {
-            GenContext::Head => 0,
-            GenContext::Mid(cn) | GenContext::Last(cn) => cn
+            &QueryTerm::Clause(_, _, ref subterms, ..) => subterms.len(),
+            &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => 0,
+            &QueryTerm::Jump(ref vars) => vars.len(),
+            &QueryTerm::GetLevelAndUnify(..) => 1,
         }
     }
 }
 
+pub struct Rule {
+    pub head: (ClauseName, Vec<Box<Term>>, QueryTerm),
+    pub clauses: Vec<QueryTerm>
+}
+
 pub struct Predicate(pub Vec<PredicateClause>);
 
 impl Predicate {
@@ -137,11 +191,6 @@ impl PredicateClause {
     }
 }
 
-pub type OpDirKey = (ClauseName, Fixity);
-
-// name and fixity -> operator type and precedence.
-pub type OpDir = HashMap<OpDirKey, (Specifier, usize, ClauseName)>;
-
 pub type ModuleCodeDir = HashMap<PredicateKey, ModuleCodeIndex>;
 
 pub type CodeDir = HashMap<PredicateKey, CodeIndex>;
@@ -163,683 +212,106 @@ pub struct Module {
     pub op_dir: OpDir
 }
 
-pub fn default_op_dir() -> OpDir {
-    let module_name = clause_name!("builtins");
-    let mut op_dir = OpDir::new();
-
-    op_dir.insert((clause_name!(":-"), Fixity::In),  (XFX, 1200, module_name.clone()));
-    op_dir.insert((clause_name!(":-"), Fixity::Pre), (FX,  1200, module_name.clone()));
-    op_dir.insert((clause_name!("?-"), Fixity::Pre), (FX,  1200, module_name.clone()));
-
-    op_dir
+#[derive(Copy, Clone, PartialEq)]
+pub enum SystemClauseType {
+    CheckCutPoint,
+    GetBValue,
+    GetSCCCleaner,
+    InstallSCCCleaner,
+    InstallInferenceCounter,
+    RemoveCallPolicyCheck,
+    RemoveInferenceCounter,
+    RestoreCutPolicy,
+    SetCutPoint(RegType),
+    InferenceLevel,
+    CleanUpBlock,
+    EraseBall,
+    Fail,
+    GetBall,
+    GetCurrentBlock,
+    GetCutPoint,
+    GetDoubleQuotes,
+    InstallNewBlock,
+    ResetBlock,
+    SetBall,
+    SetCutPointByDefault(RegType),
+    SetDoubleQuotes,
+    SkipMaxList,
+    Succeed,
+    UnwindStack
 }
 
-pub static BUILTINS: &str = include_str!("./lib/builtins.pl");
+impl SystemClauseType {
+    pub fn fixity(&self) -> Option<Fixity> {
+        None
+    }
 
-impl Module {
-    pub fn new(module_decl: ModuleDecl) -> Self {
-        Module { module_decl,
-                 code_dir: ModuleCodeDir::new(),
-                 op_dir: default_op_dir() }
+    pub fn name(&self) -> ClauseName {
+        match self {
+            &SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
+            &SystemClauseType::GetBValue => clause_name!("$get_b_value"),
+            &SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
+            &SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
+            &SystemClauseType::InstallSCCCleaner => clause_name!("$install_scc_cleaner"),
+            &SystemClauseType::InstallInferenceCounter =>
+                clause_name!("$install_inference_counter"),
+            &SystemClauseType::RemoveCallPolicyCheck =>
+                clause_name!("$remove_call_policy_check"),
+            &SystemClauseType::RemoveInferenceCounter =>
+                clause_name!("$remove_inference_counter"),
+            &SystemClauseType::RestoreCutPolicy => clause_name!("$restore_cut_policy"),
+            &SystemClauseType::SetCutPoint(_) => clause_name!("$set_cp"),
+            &SystemClauseType::InferenceLevel => clause_name!("$inference_level"),
+            &SystemClauseType::CleanUpBlock => clause_name!("$clean_up_block"),
+            &SystemClauseType::EraseBall => clause_name!("$erase_ball"),
+            &SystemClauseType::Fail => clause_name!("$fail"),
+            &SystemClauseType::GetBall => clause_name!("$get_ball"),
+            &SystemClauseType::GetCutPoint => clause_name!("$get_cp"),
+            &SystemClauseType::GetCurrentBlock => clause_name!("$get_current_block"),
+            &SystemClauseType::InstallNewBlock => clause_name!("$install_new_block"),
+            &SystemClauseType::ResetBlock => clause_name!("$reset_block"),
+            &SystemClauseType::SetBall => clause_name!("$set_ball"),
+            &SystemClauseType::SetCutPointByDefault(_) => clause_name!("$set_cp_by_default"),
+            &SystemClauseType::SetDoubleQuotes => clause_name!("$set_double_quotes"),
+            &SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
+            &SystemClauseType::Succeed => clause_name!("$succeed"),
+            &SystemClauseType::UnwindStack => clause_name!("$unwind_stack"),
+        }
     }
-}
 
-pub fn as_module_code_dir(code_dir: CodeDir) -> ModuleCodeDir {
-    code_dir.into_iter()
-        .map(|(k, code_idx)| {
-            let (idx, module_name) = code_idx.0.borrow().clone();
-            (k, ModuleCodeIndex(idx, module_name))
-        })
-        .collect()
-}
-
-impl SubModuleUser for Module {
-    fn op_dir(&mut self) -> &mut OpDir {
-        &mut self.op_dir
-    }
-
-    fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex) {
-        self.code_dir.insert((name, arity), idx);
-    }
-}
-
-pub trait SubModuleUser {
-    fn op_dir(&mut self) -> &mut OpDir;
-    fn insert_dir_entry(&mut self, ClauseName, usize, ModuleCodeIndex);
-
-    // returns true on successful import.
-    fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool {
-        let name = name.defrock_brackets();
-        let mut found_op = false;
-
-        {
-            let mut insert_op_dir = |fix| {
-                if let Some(op_data) = submodule.op_dir.get(&(name.clone(), fix)) {
-                    self.op_dir().insert((name.clone(), fix), op_data.clone());
-                    found_op = true;
-                }
-            };
-
-            if arity == 1 {
-                insert_op_dir(Fixity::Pre);
-                insert_op_dir(Fixity::Post);
-            } else if arity == 2 {
-                insert_op_dir(Fixity::In);
-            }
-        }
-
-        if let Some(code_data) = submodule.code_dir.get(&(name.clone(), arity)) {
-            self.insert_dir_entry(name, arity, code_data.clone());
-            true
-        } else {
-            found_op
-        }
-    }
-
-    fn use_qualified_module(&mut self, submodule: &Module, exports: &Vec<PredicateKey>) -> EvalSession
-    {
-        for (name, arity) in exports.iter().cloned() {
-            if !submodule.module_decl.exports.contains(&(name.clone(), arity)) {
-                continue;
-            }
-
-            if !self.import_decl(name, arity, submodule) {
-                return EvalSession::from(SessionError::ModuleDoesNotContainExport);
-            }
-        }
-
-        EvalSession::EntrySuccess
-    }
-
-    fn use_module(&mut self, submodule: &Module) -> EvalSession {
-        for (name, arity) in submodule.module_decl.exports.iter().cloned() {
-            if !self.import_decl(name, arity, submodule) {
-                return EvalSession::from(SessionError::ModuleDoesNotContainExport);
-            }
-        }
-
-        EvalSession::EntrySuccess
-    }
-}
-
-pub enum Declaration {
-    NonCountedBacktracking(ClauseName, usize), // name, arity
-    Module(ModuleDecl),
-    Op(OpDecl),
-    UseModule(ClauseName),
-    UseQualifiedModule(ClauseName, Vec<PredicateKey>)
-}
-
-pub enum TopLevel {
-    Declaration(Declaration),
-    Fact(Term),
-    Predicate(Predicate),
-    Query(Vec<QueryTerm>),
-    Rule(Rule)
-}
-
-impl TopLevel {
-    pub fn name(&self) -> Option<ClauseName> {
-        match self {
-            &TopLevel::Declaration(_) => None,
-            &TopLevel::Fact(ref term) => term.name(),
-            &TopLevel::Predicate(ref clauses) =>
-                clauses.0.first().and_then(|ref term| term.name()),
-            &TopLevel::Query(_) => None,
-            &TopLevel::Rule(Rule { ref head, .. }) =>
-                Some(head.0.clone())
-        }
-    }
-
-    pub fn arity(&self) -> usize {
-        match self {
-            &TopLevel::Declaration(_) => 0,
-            &TopLevel::Fact(ref term) => term.arity(),
-            &TopLevel::Predicate(ref clauses) =>
-                clauses.0.first().map(|t| t.arity()).unwrap_or(0),
-            &TopLevel::Query(_) => 0,
-            &TopLevel::Rule(Rule { ref head, .. }) => head.1.len()
-        }
-    }
-
-    pub fn as_predicate(self) -> Result<Predicate, TopLevel> {
-        match self {
-            TopLevel::Fact(term) => Ok(Predicate(vec![PredicateClause::Fact(term)])),
-            TopLevel::Rule(rule) => Ok(Predicate(vec![PredicateClause::Rule(rule)])),
-            TopLevel::Predicate(pred) => Ok(pred),
-            _ => Err(self)
-        }
-    }
-}
-
-#[derive(Clone, Copy)]
-pub enum Level {
-    Deep, Root, Shallow
-}
-
-impl Level {
-    pub fn child_level(self) -> Level {
-        match self {
-            Level::Root => Level::Shallow,
-            _ => Level::Deep
-        }
-    }
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash)]
-pub enum RegType {
-    Perm(usize),
-    Temp(usize)
-}
-
-impl Default for RegType {
-    fn default() -> Self {
-        RegType::Temp(0)
-    }
-}
-
-impl RegType {
-    pub fn reg_num(self) -> usize {
-        match self {
-            RegType::Perm(reg_num) | RegType::Temp(reg_num) => reg_num
-        }
-    }
-
-    pub fn is_perm(self) -> bool {
-        match self {
-            RegType::Perm(_) => true,
-            _ => false
-        }
-    }
-}
-
-#[derive(PartialEq, Eq, Clone, Copy)]
-pub enum VarReg {
-    ArgAndNorm(RegType, usize),
-    Norm(RegType)
-}
-
-impl VarReg {
-    pub fn norm(self) -> RegType {
-        match self {
-            VarReg::ArgAndNorm(reg, _) | VarReg::Norm(reg) => reg
-        }
-    }
-}
-
-impl Default for VarReg {
-    fn default() -> Self {
-        VarReg::Norm(RegType::default())
-    }
-}
-
-// labeled with chunk numbers.
-pub enum VarStatus {
-    Perm(usize), Temp(usize, TempVarData) // Perm(chunk_num) | Temp(chunk_num, _)
-}
-
-pub type OccurrenceSet = BTreeSet<(GenContext, usize)>;
-
-// Perm: 0 initially, a stack register once processed.
-// Temp: labeled with chunk_num and temp offset (unassigned if 0).
-pub enum VarData {
-    Perm(usize), Temp(usize, usize, TempVarData)
-}
-
-pub struct TempVarData {
-    pub last_term_arity: usize,
-    pub use_set: OccurrenceSet,
-    pub no_use_set: BTreeSet<usize>,
-    pub conflict_set: BTreeSet<usize>
-}
-
-pub type HeapVarDict  = HashMap<Rc<Var>, Addr>;
-pub type AllocVarDict = HashMap<Rc<Var>, VarData>;
-
-pub enum SessionError {
-    ImpermissibleEntry(String),
-    ModuleDoesNotContainExport,
-    ModuleNotFound,
-    NamelessEntry,
-    OpIsInfixAndPostFix,
-    ParserError(ParserError),
-    QueryFailure,
-    QueryFailureWithException(String)
-}
-
-pub enum EvalSession {
-    EntrySuccess,
-    Error(SessionError),
-    InitialQuerySuccess(AllocVarDict, HeapVarDict),
-    SubsequentQuerySuccess,
-}
-
-impl From<SessionError> for EvalSession {
-    fn from(err: SessionError) -> Self {
-        EvalSession::Error(err)
-    }
-}
-
-impl From<ParserError> for SessionError {
-    fn from(err: ParserError) -> Self {
-        SessionError::ParserError(err)
-    }
-}
-
-impl From<ParserError> for EvalSession {
-    fn from(err: ParserError) -> Self {
-        EvalSession::from(SessionError::ParserError(err))
-    }
-}
-
-pub struct OpDecl(pub usize, pub Specifier, pub ClauseName);
-
-impl OpDecl {
-    pub fn submit(&self, module: ClauseName, op_dir: &mut OpDir) -> Result<(), SessionError>
-    {
-        let (prec, spec, name) = (self.0, self.1, self.2.clone());
-
-        if is_infix!(spec) {
-            match op_dir.get(&(name.clone(), Fixity::Post)) {
-                Some(_) => return Err(SessionError::OpIsInfixAndPostFix),
-                _ => {}
-            };
-        }
-
-        if is_postfix!(spec) {
-            match op_dir.get(&(name.clone(), Fixity::In)) {
-                Some(_) => return Err(SessionError::OpIsInfixAndPostFix),
-                _ => {}
-            };
-        }
-
-        if prec > 0 {
-            match spec {
-                XFY | XFX | YFX => op_dir.insert((name.clone(), Fixity::In),
-                                                 (spec, prec, module.clone())),
-                XF | YF => op_dir.insert((name.clone(), Fixity::Post), (spec, prec, module.clone())),
-                FX | FY => op_dir.insert((name.clone(), Fixity::Pre), (spec, prec, module.clone())),
-                _ => None
-            };
-        } else {
-            op_dir.remove(&(name.clone(), Fixity::Pre));
-            op_dir.remove(&(name.clone(), Fixity::In));
-            op_dir.remove(&(name.clone(), Fixity::Post));
-        }
-
-        Ok(())
-    }
-}
-
-#[derive(Debug, Clone, Copy)]
-pub enum ArithmeticError {
-    InvalidAtom,
-    InvalidOp,
-    InvalidTerm,
-    NoRoots,
-    UninstantiatedVar
-}
-
-#[derive(Debug)]
-pub enum ParserError
-{
-    Arithmetic(ArithmeticError),
-    BackQuotedString,
-    // BuiltInArityMismatch(&'static str),
-    UnexpectedChar(char),
-    UnexpectedEOF,
-    IO(IOError),
-    ExpectedRel,
-    InadmissibleFact,
-    InadmissibleQueryTerm,
-    IncompleteReduction,
-    InconsistentEntry,
-    InvalidModuleDecl,
-    InvalidModuleExport,
-    InvalidRuleHead,
-    InvalidUseModuleDecl,
-    InvalidModuleResolution,
-    MissingQuote,
-    NonPrologChar,
-    ParseBigInt,
-    ParseFloat,
-    Utf8Conversion(Utf8Error)
-}
-
-impl From<ArithmeticError> for ParserError {
-    fn from(err: ArithmeticError) -> ParserError {
-        ParserError::Arithmetic(err)
-    }
-}
-
-impl From<IOError> for ParserError {
-    fn from(err: IOError) -> ParserError {
-        ParserError::IO(err)
-    }
-}
-
-impl From<Utf8Error> for ParserError {
-    fn from(err: Utf8Error) -> ParserError {
-        ParserError::Utf8Conversion(err)
-    }
-}
-
-#[derive(Clone, Copy, Eq, Hash, PartialEq)]
-pub enum Fixity {
-    In, Post, Pre
-}
-
-#[derive(Clone, Hash)]
-pub enum Constant {
-    Atom(ClauseName),
-    Char(char),
-    Number(Number),
-    String(StringList),
-    Usize(usize),
-    EmptyList
-}
-
-impl PartialEq for Constant {
-    fn eq(&self, other: &Constant) -> bool {
-        match (self, other) {
-            (&Constant::Atom(ref atom), &Constant::Char(c))
-          | (&Constant::Char(c), &Constant::Atom(ref atom)) => {
-              let s = atom.as_str();
-              c.len_utf8() == s.len() && Some(c) == s.chars().next()
-            },
-            (&Constant::Atom(ref a1), &Constant::Atom(ref a2)) =>
-                a1.as_str() == a2.as_str(),
-            (&Constant::Char(c1), &Constant::Char(c2)) =>
-                c1 == c2,
-            (&Constant::Number(ref n1), &Constant::Number(ref n2)) =>
-                n1 == n2,
-            (&Constant::String(ref s1), &Constant::String(ref s2)) =>
-                s1 == s2,
-            (&Constant::EmptyList, &Constant::EmptyList) =>
-                true,
-            (&Constant::Usize(u1), &Constant::Usize(u2)) =>
-                u1 == u2,
-            _ => false
-        }
-    }
-}
-
-impl Eq for Constant {}
-
-impl Constant {
-    pub fn to_atom(self) -> Option<ClauseName> {
-        match self {
-            Constant::Atom(a) => Some(a.defrock_brackets()),
-            _ => None
-        }
-    }
-
-    pub fn to_integer(self) -> Option<Rc<BigInt>> {
-        match self {
-            Constant::Number(Number::Integer(b)) => Some(b),
-            _ => None
-        }
-    }
-}
-
-#[derive(PartialEq, Eq, Clone)]
-pub enum Term {
-    AnonVar,
-    Clause(Cell<RegType>, ClauseName, Vec<Box<Term>>, Option<Fixity>),
-    Cons(Cell<RegType>, Box<Term>, Box<Term>),
-    Constant(Cell<RegType>, Constant),
-    Var(Cell<VarReg>, Rc<Var>)
-}
-
-#[derive(Clone, PartialEq)]
-pub enum InlinedClauseType {
-    CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),    
-    IsAtom(RegType),
-    IsAtomic(RegType),
-    IsCompound(RegType),
-    IsInteger(RegType),
-    IsRational(RegType),
-    IsString(RegType),
-    IsFloat(RegType),
-    IsNonVar(RegType),
-    IsPartialString(RegType),
-    IsVar(RegType)
-}
-
-impl InlinedClauseType {
-    pub fn name(&self) -> &'static str {
-        match self {
-            &InlinedClauseType::CompareNumber(qt, ..) => qt.name(),
-            &InlinedClauseType::IsAtom(..) => "atom",
-            &InlinedClauseType::IsAtomic(..) => "atomic",
-            &InlinedClauseType::IsCompound(..) => "compound",
-            &InlinedClauseType::IsInteger (..) => "integer",
-            &InlinedClauseType::IsRational(..) => "rational",
-            &InlinedClauseType::IsString(..) => "string",
-            &InlinedClauseType::IsFloat (..) => "float",
-            &InlinedClauseType::IsNonVar(..) => "nonvar",
-            &InlinedClauseType::IsPartialString(..) => "partial_string",
-            &InlinedClauseType::IsVar(..) => "var",            
-        }
-    }
-
-    pub fn from(name: &str, arity: usize) -> Option<Self> {
-        let r1 = temp_v!(1);
-        let r2 = temp_v!(2);
-
-        let a1 = ArithmeticTerm::Reg(r1);
-        let a2 = ArithmeticTerm::Reg(r2);
-
-        match (name, arity) {
-            (">", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan, a1, a2)),
-            ("<", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan, a1, a2)),
-            (">=", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual,a1, a2)),
-            ("=<", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual, a1, a2)),
-            ("=\\=", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual, a1, a2)),
-            ("=:=", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal, a1, a2)),
-            ("atom", 1) => Some(InlinedClauseType::IsAtom(r1)),
-            ("atomic", 1) => Some(InlinedClauseType::IsAtomic(r1)),
-            ("compound", 1) => Some(InlinedClauseType::IsCompound(r1)),
-            ("integer", 1) => Some(InlinedClauseType::IsInteger(r1)),
-            ("rational", 1) => Some(InlinedClauseType::IsRational(r1)),
-            ("string", 1) => Some(InlinedClauseType::IsString(r1)),
-            ("float", 1) => Some(InlinedClauseType::IsFloat(r1)),
-            ("nonvar", 1) => Some(InlinedClauseType::IsNonVar(r1)),
-            ("var", 1) => Some(InlinedClauseType::IsVar(r1)),
-            ("is_partial_string", 1) => Some(InlinedClauseType::IsPartialString(r1)),
-            _ => None
-        }
-    }
-}
-
-#[derive(Clone, Copy, PartialEq)]
-pub enum CompareNumberQT {
-    GreaterThan,
-    LessThan,
-    GreaterThanOrEqual,
-    LessThanOrEqual,
-    NotEqual,
-    Equal
-}
-
-impl CompareNumberQT {
-    fn name(self) -> &'static str {
-        match self {
-            CompareNumberQT::GreaterThan => ">",
-            CompareNumberQT::LessThan => "<",
-            CompareNumberQT::GreaterThanOrEqual => ">=",
-            CompareNumberQT::LessThanOrEqual => "=<",
-            CompareNumberQT::NotEqual => "=\\=",
-            CompareNumberQT::Equal => "=:="
-        }
-    }
-}
-
-#[derive(Clone, Copy, PartialEq)]
-pub enum CompareTermQT {
-    LessThan,
-    LessThanOrEqual,
-    Equal,
-    GreaterThanOrEqual,
-    GreaterThan,
-    NotEqual,
-}
-
-impl CompareTermQT {
-    fn name<'a>(self) -> &'a str {
-        match self {
-            CompareTermQT::GreaterThan => "@>",
-            CompareTermQT::LessThan => "@<",
-            CompareTermQT::GreaterThanOrEqual => "@>=",
-            CompareTermQT::LessThanOrEqual => "@=<",
-            CompareTermQT::NotEqual => "\\=@=",
-            CompareTermQT::Equal => "=@="
-        }
-    }
-}
-
-// vars of predicate, toplevel offset.  Vec<Term> is always a vector
-// of vars (we get their adjoining cells this way).
-pub type JumpStub = Vec<Term>;
-
-pub enum QueryTerm {
-    // register, clause type, subterms, use default call policy.
-    Clause(Cell<RegType>, ClauseType, Vec<Box<Term>>, bool),
-    BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q.
-    UnblockedCut(Cell<VarReg>),
-    GetLevelAndUnify(Cell<VarReg>, Rc<Var>),
-    Jump(JumpStub)
-}
-
-impl QueryTerm {
-    pub fn set_default_caller(&mut self) {
-        match self {
-            &mut QueryTerm::Clause(_, _, _, ref mut use_default_cp) => *use_default_cp = true,
-            _ => {}
-        };
-    }
-
-    pub fn arity(&self) -> usize {
-        match self {
-            &QueryTerm::Clause(_, _, ref subterms, ..) => subterms.len(),
-            &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => 0,
-            &QueryTerm::Jump(ref vars) => vars.len(),
-            &QueryTerm::GetLevelAndUnify(..) => 1,
-        }
-    }
-}
-
-pub struct Rule {
-    pub head: (ClauseName, Vec<Box<Term>>, QueryTerm),
-    pub clauses: Vec<QueryTerm>
-}
-
-#[derive(Copy, Clone, PartialEq)]
-pub enum SystemClauseType {
-    CheckCutPoint,
-    GetBValue,
-    GetSCCCleaner,
-    InstallSCCCleaner,
-    InstallInferenceCounter,
-    RemoveCallPolicyCheck,
-    RemoveInferenceCounter,
-    RestoreCutPolicy,
-    SetCutPoint(RegType),
-    InferenceLevel,
-    CleanUpBlock,
-    EraseBall,
-    Fail,
-    GetBall,
-    GetCurrentBlock,
-    GetCutPoint,
-    GetDoubleQuotes,
-    InstallNewBlock,
-    ResetBlock,
-    SetBall,
-    SetCutPointByDefault(RegType),
-    SetDoubleQuotes,
-    SkipMaxList,
-    Succeed,
-    UnwindStack
-}
-
-impl SystemClauseType {
-    pub fn fixity(&self) -> Option<Fixity> {
-        None
-    }
-
-    pub fn name(&self) -> ClauseName {
-        match self {
-            &SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
-            &SystemClauseType::GetBValue => clause_name!("$get_b_value"),
-            &SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
-            &SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
-            &SystemClauseType::InstallSCCCleaner => clause_name!("$install_scc_cleaner"),
-            &SystemClauseType::InstallInferenceCounter =>
-                clause_name!("$install_inference_counter"),
-            &SystemClauseType::RemoveCallPolicyCheck =>
-                clause_name!("$remove_call_policy_check"),
-            &SystemClauseType::RemoveInferenceCounter =>
-                clause_name!("$remove_inference_counter"),
-            &SystemClauseType::RestoreCutPolicy => clause_name!("$restore_cut_policy"),
-            &SystemClauseType::SetCutPoint(_) => clause_name!("$set_cp"),
-            &SystemClauseType::InferenceLevel => clause_name!("$inference_level"),
-            &SystemClauseType::CleanUpBlock => clause_name!("$clean_up_block"),
-            &SystemClauseType::EraseBall => clause_name!("$erase_ball"),
-            &SystemClauseType::Fail => clause_name!("$fail"),
-            &SystemClauseType::GetBall => clause_name!("$get_ball"),
-            &SystemClauseType::GetCutPoint => clause_name!("$get_cp"),
-            &SystemClauseType::GetCurrentBlock => clause_name!("$get_current_block"),
-            &SystemClauseType::InstallNewBlock => clause_name!("$install_new_block"),
-            &SystemClauseType::ResetBlock => clause_name!("$reset_block"),
-            &SystemClauseType::SetBall => clause_name!("$set_ball"),
-            &SystemClauseType::SetCutPointByDefault(_) => clause_name!("$set_cp_by_default"),
-            &SystemClauseType::SetDoubleQuotes => clause_name!("$set_double_quotes"),
-            &SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
-            &SystemClauseType::Succeed => clause_name!("$succeed"),
-            &SystemClauseType::UnwindStack => clause_name!("$unwind_stack"),
-        }
-    }
-
-    pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
-        match (name, arity) {
-            ("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
-            ("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
-            ("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
-            ("$get_scc_cleaner", 1) => Some(SystemClauseType::GetSCCCleaner),
-            ("$install_scc_cleaner", 2) =>
-                Some(SystemClauseType::InstallSCCCleaner),
-            ("$install_inference_counter", 3) =>
-                Some(SystemClauseType::InstallInferenceCounter),
-            ("$remove_call_policy_check", 1) =>
-                Some(SystemClauseType::RemoveCallPolicyCheck),
-            ("$remove_inference_counter", 2) =>
-                Some(SystemClauseType::RemoveInferenceCounter),
-            ("$restore_cut_policy", 0) => Some(SystemClauseType::RestoreCutPolicy),
-            ("$set_cp", 1) => Some(SystemClauseType::SetCutPoint(temp_v!(1))),
-            ("$inference_level", 2) => Some(SystemClauseType::InferenceLevel),
-            ("$clean_up_block", 1) => Some(SystemClauseType::CleanUpBlock),
-            ("$erase_ball", 0) => Some(SystemClauseType::EraseBall),
-            ("$fail", 0) => Some(SystemClauseType::Fail),
-            ("$get_ball", 1) => Some(SystemClauseType::GetBall),
-            ("$get_current_block", 1) => Some(SystemClauseType::GetCurrentBlock),
-            ("$get_cp", 1) => Some(SystemClauseType::GetCutPoint),
-            ("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
-            ("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
-            ("$set_ball", 1) => Some(SystemClauseType::SetBall),
-            ("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))),
-            ("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
-            ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
-            ("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
-            _ => None
-        }
-    }
+    pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
+        match (name, arity) {
+            ("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
+            ("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
+            ("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
+            ("$get_scc_cleaner", 1) => Some(SystemClauseType::GetSCCCleaner),
+            ("$install_scc_cleaner", 2) =>
+                Some(SystemClauseType::InstallSCCCleaner),
+            ("$install_inference_counter", 3) =>
+                Some(SystemClauseType::InstallInferenceCounter),
+            ("$remove_call_policy_check", 1) =>
+                Some(SystemClauseType::RemoveCallPolicyCheck),
+            ("$remove_inference_counter", 2) =>
+                Some(SystemClauseType::RemoveInferenceCounter),
+            ("$restore_cut_policy", 0) => Some(SystemClauseType::RestoreCutPolicy),
+            ("$set_cp", 1) => Some(SystemClauseType::SetCutPoint(temp_v!(1))),
+            ("$inference_level", 2) => Some(SystemClauseType::InferenceLevel),
+            ("$clean_up_block", 1) => Some(SystemClauseType::CleanUpBlock),
+            ("$erase_ball", 0) => Some(SystemClauseType::EraseBall),
+            ("$fail", 0) => Some(SystemClauseType::Fail),
+            ("$get_ball", 1) => Some(SystemClauseType::GetBall),
+            ("$get_current_block", 1) => Some(SystemClauseType::GetCurrentBlock),
+            ("$get_cp", 1) => Some(SystemClauseType::GetCutPoint),
+            ("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
+            ("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
+            ("$set_ball", 1) => Some(SystemClauseType::SetBall),
+            ("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))),
+            ("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
+            ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
+            ("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
+            _ => None
+        }
+    }
 }
 
 #[derive(Clone, PartialEq)]
@@ -872,70 +344,6 @@ pub enum ClauseType {
     System(SystemClauseType)
 }
 
-#[derive(Clone)]
-pub enum ClauseName {
-    BuiltIn(&'static str),
-    User(TabledRc<Atom>)
-}
-
-impl Hash for ClauseName {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        (*self.as_str()).hash(state)
-    }
-}
-
-impl PartialEq for ClauseName {
-    fn eq(&self, other: &ClauseName) -> bool {
-        *self.as_str() == *other.as_str()
-    }
-}
-
-impl Eq for ClauseName {}
-
-impl Ord for ClauseName {
-    fn cmp(&self, other: &ClauseName) -> Ordering {
-        (*self.as_str()).cmp(other.as_str())
-    }
-}
-
-impl PartialOrd for ClauseName {
-    fn partial_cmp(&self, other: &ClauseName) -> Option<Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-impl<'a> From<&'a TabledRc<Atom>> for ClauseName {
-    fn from(name: &'a TabledRc<Atom>) -> ClauseName {
-        ClauseName::User(name.clone())
-    }
-}
-
-impl ClauseName {
-    pub fn as_str(&self) -> &str {
-        match self {
-            &ClauseName::BuiltIn(s) => s,
-            &ClauseName::User(ref name) => name.as_ref()
-        }
-    }
-
-    pub fn defrock_brackets(self) -> Self {
-        fn defrock_brackets(s: &str) -> &str {
-            if s.starts_with('(') && s.ends_with(')') {
-                &s[1 .. s.len() - 1]
-            } else {
-                s
-            }
-        }
-
-        match self {
-            ClauseName::BuiltIn(s) =>
-                ClauseName::BuiltIn(defrock_brackets(s)),
-            ClauseName::User(s) =>
-                ClauseName::User(tabled_rc!(defrock_brackets(s.as_str()).to_owned(), s.table()))
-        }
-    }
-}
-
 impl BuiltInClauseType {
     fn fixity(&self) -> Option<Fixity> {
         match self {
@@ -1061,428 +469,50 @@ impl ClauseType {
 }
 
 impl From<InlinedClauseType> for ClauseType {
-    fn from(inlined_ct: InlinedClauseType) -> Self {
-        ClauseType::Inlined(inlined_ct)
-    }
-}
-
-#[derive(Clone)]
-pub enum TermRef<'a> {
-    AnonVar(Level),
-    Cons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
-    Constant(Level, &'a Cell<RegType>, &'a Constant),
-    Clause(Level, &'a Cell<RegType>, ClauseType, &'a Vec<Box<Term>>),
-    Var(Level, &'a Cell<VarReg>, Rc<Var>)
-}
-
-impl<'a> TermRef<'a> {
-    pub fn level(self) -> Level {
-        match self {
-            TermRef::AnonVar(lvl)
-          | TermRef::Cons(lvl, ..)
-          | TermRef::Constant(lvl, ..)
-          | TermRef::Var(lvl, ..)
-          | TermRef::Clause(lvl, ..) => lvl
-        }
-    }
-}
-
-#[derive(Clone)]
-pub enum ChoiceInstruction {
-    DefaultRetryMeElse(usize),
-    DefaultTrustMe,
-    RetryMeElse(usize),
-    TrustMe,
-    TryMeElse(usize)
-}
-
-#[derive(Clone)]
-pub enum CutInstruction {
-    Cut(RegType),
-    GetLevel(RegType),
-    GetLevelAndUnify(RegType),
-    NeckCut
-}
-
-#[derive(Clone)]
-pub enum IndexedChoiceInstruction {
-    Retry(usize),
-    Trust(usize),
-    Try(usize)
-}
-
-impl From<IndexedChoiceInstruction> for Line {
-    fn from(i: IndexedChoiceInstruction) -> Self {
-        Line::IndexedChoice(i)
-    }
-}
-
-impl IndexedChoiceInstruction {
-    pub fn offset(&self) -> usize {
-        match self {
-            &IndexedChoiceInstruction::Retry(offset) => offset,
-            &IndexedChoiceInstruction::Trust(offset) => offset,
-            &IndexedChoiceInstruction::Try(offset)   => offset
-        }
-    }
-}
-
-#[derive(Clone, PartialEq, Eq, Hash)]
-pub enum Number {
-    Float(OrderedFloat<f64>),
-    Integer(Rc<BigInt>),
-    Rational(Rc<Ratio<BigInt>>)
-}
-
-impl PartialOrd for Number {
-    fn partial_cmp(&self, other: &Number) -> Option<Ordering> {
-        match NumberPair::from(self.clone(), other.clone()) {
-            NumberPair::Integer(n1, n2) =>
-                Some(n1.cmp(&n2)),
-            NumberPair::Float(n1, n2) =>
-                Some(n1.cmp(&n2)),
-            NumberPair::Rational(n1, n2) =>
-                Some(n1.cmp(&n2))
-        }
-    }
-}
-
-impl Ord for Number {
-    fn cmp(&self, other: &Number) -> Ordering {
-        match NumberPair::from(self.clone(), other.clone()) {
-            NumberPair::Integer(n1, n2) =>
-                n1.cmp(&n2),
-            NumberPair::Float(n1, n2) =>
-                n1.cmp(&n2),
-            NumberPair::Rational(n1, n2) =>
-                n1.cmp(&n2)
-        }
-    }
-}
-
-impl fmt::Display for Number {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match self {
-            &Number::Float(fl) => write!(f, "{}", fl),
-            &Number::Integer(ref bi) => write!(f, "{}", bi),
-            &Number::Rational(ref r) => write!(f, "{}", r)
-        }
-    }
-}
-
-impl Default for Number {
-    fn default() -> Self {
-        Number::Float(OrderedFloat(0f64))
-    }
-}
-
-fn binary_pow<T>(mut n: T, mut power: BigUint) -> T
-    where T: Clone + Mul + One,
-    for<'a> T: MulAssign<&'a T>
-{
-    if power.is_zero() {
-        return T::one();
-    }
-
-    let mut oddand = T::one();
-    let one = BigUint::one();
-
-    while power > one {
-        if power.is_odd() {
-            oddand *= &n;
-        }
-
-        n = n.clone() * n;
-        power >>= 1;
-    }
-
-    n * oddand
-}
-
-fn rational_pow(r1: BigRational, r2: BigRational) -> Result<BigRational, ArithmeticError>
-{
-    #[inline]
-    fn to_unsigned(n: &BigInt) -> Result<BigUint, ArithmeticError> {
-        n.abs().to_biguint().ok_or(ArithmeticError::NoRoots)
-    };
-
-    #[inline]
-    fn to_big_rational(n: BigUint) -> BigRational {
-        BigRational::from_integer(BigInt::from(n))
-    };
-
-    let r2 = r2.reduced(); // so that gcd(numer, denom) = 1
-    let n = to_unsigned(r2.denom())?;
-
-    if n == BigUint::one() {
-        return if r2.is_positive() {
-            Ok(binary_pow(r1, to_unsigned(&r2.numer())?))
-        } else if r2.is_negative() {
-            Ok(binary_pow(r1, to_unsigned(&r2.numer())?).recip())
-        } else {
-            Ok(BigRational::one())
-        };
-    }
-
-    if (n.is_even() && r1.is_negative()) || (r2.is_negative() && r1.is_zero()) {
-        return Err(ArithmeticError::NoRoots);
-    }
-
-    let sgn = r1.signum();
-    let r1 = r1 * &sgn; // set r1 to its absolute value.
-
-    let epsilon = BigRational::new_raw(BigInt::one(), BigInt::from(10000));
-    let n1      = n.clone() - BigUint::one(); // n -1
-
-    // 1 + r1 / (n-1) is a good initial point.
-    let mut x_i = BigRational::one() + r1.clone() / to_big_rational(n1.clone());
-    let mut x_i_n1 = binary_pow(x_i.clone(), n1.clone()); // x_i^{n-1}
-    let mut delta_x_i = BigRational::one();
-
-    while delta_x_i.abs() > epsilon {
-        x_i = x_i.reduced();
-        x_i_n1 = x_i_n1.reduced();
-
-        let r_quot = r1.clone() / &x_i_n1; // r1 / x_i^{n-1}
-        let r_n    = to_big_rational(n.clone());
-
-        delta_x_i = ( r_quot - &x_i ) / &r_n;
-
-        x_i += &delta_x_i;
-        x_i_n1 = binary_pow(x_i.clone(), n1.clone());
-    }
-
-    if r2.is_positive() {
-        Ok(binary_pow(sgn * x_i, to_unsigned(r2.numer())?))
-    } else {
-        Ok(binary_pow(sgn * x_i, to_unsigned(r2.numer())?).recip())
-    }
-}
-
-fn pow_float(f1: f64, f2: f64) -> Result<Number, ArithmeticError> {
-    let result = OrderedFloat(f1.powf(f2));
-
-    if result.is_finite() {
-        Ok(Number::Float(result))
-    } else {
-        Err(ArithmeticError::NoRoots)
-    }
-}
-
-fn rational_to_f64(r: &BigRational) -> Option<f64> {
-    match (r.numer().to_f64(), r.denom().to_f64()) {
-        (Some(ref f1), Some(ref f2)) if f2.is_normal() => Some(*f1 / *f2),
-        _ => None
-    }
-}
-
-impl Number {
-    pub fn pow(self, other: Number) -> Result<Self, ArithmeticError> {
-        match NumberPair::from(self, other) {
-            NumberPair::Integer(n1, n2) =>
-                if let Some(n2) = n2.to_biguint() {
-                    Ok(Number::Integer(Rc::new(binary_pow((*n1).clone(), n2))))
-                } else if n1.is_zero() {
-                    Err(ArithmeticError::NoRoots)
-                } else {
-                    let r1 = Ratio::new(BigInt::one(), (*n1).clone());
-                    let n2 = n2.abs().to_biguint().unwrap();
-
-                    Ok(Number::Rational(Rc::new(binary_pow(r1, n2))))
-                },
-            NumberPair::Float(n1, n2) =>
-                pow_float(n1.into_inner(), n2.into_inner()),
-            NumberPair::Rational(r1, r2) => {
-                if let (Some(f1), Some(f2)) = (rational_to_f64(&r1), rational_to_f64(&r2)) {
-                    if let Ok(result) = pow_float(f1, f2) {
-                        return Ok(result);
-                    }
-                }
-
-                let root = rational_pow((*r1).clone(), (*r2).clone())?;
-                Ok(Number::Rational(Rc::new(root)))
-            }
-        }
-    }
-
-    #[inline]
-    pub fn is_zero(&self) -> bool {
-        match self {
-            &Number::Float(fl)       => fl.into_inner().is_zero(),
-            &Number::Integer(ref bi) => bi.is_zero(),
-            &Number::Rational(ref r) => r.is_zero()
-        }
-    }
-
-    #[inline]
-    pub fn abs(&self) -> Self {
-        match self {
-            &Number::Float(ref fl)   => Number::Float(OrderedFloat(fl.into_inner().abs())),
-            &Number::Integer(ref n)  => Number::Integer(Rc::new((*n).clone().abs())),
-            &Number::Rational(ref r) => Number::Rational(Rc::new((*r).clone().abs()))
-        }
-    }
-}
-
-pub enum NumberPair {
-    Float(OrderedFloat<f64>, OrderedFloat<f64>),
-    Integer(Rc<BigInt>, Rc<BigInt>),
-    Rational(Rc<Ratio<BigInt>>, Rc<Ratio<BigInt>>)
-}
-
-impl NumberPair {
-    fn flip(self) -> NumberPair {
-        match self {
-            NumberPair::Float(f1, f2)    => NumberPair::Float(f2, f1),
-            NumberPair::Integer(n1, n2)  => NumberPair::Integer(n2, n1),
-            NumberPair::Rational(r1, r2) => NumberPair::Rational(r2, r1)
-        }
-    }
-
-    fn integer_float_pair(n1: Rc<BigInt>, n2: OrderedFloat<f64>) -> NumberPair {
-        match n1.to_f64() {
-            Some(f1) => NumberPair::Float(OrderedFloat(f1), n2),
-            None => if let Some(r) = Ratio::from_float(n2.into_inner()) {
-                NumberPair::Rational(Rc::new(Ratio::from_integer((*n1).clone())),
-                                     Rc::new(r))
-            } else if n2.into_inner().is_sign_positive() {
-                NumberPair::Float(OrderedFloat(f64::infinity()),
-                                  OrderedFloat(f64::infinity()))
-            } else {
-                NumberPair::Float(OrderedFloat(f64::neg_infinity()),
-                                  OrderedFloat(f64::neg_infinity()))
-            }
-        }
-    }
-
-    fn float_rational_pair(n1: OrderedFloat<f64>, n2: Rc<Ratio<BigInt>>) -> NumberPair {
-        match (n2.numer().to_f64(), n2.denom().to_f64()) {
-            (Some(num), Some(denom)) =>
-                NumberPair::Float(n1, OrderedFloat(num / denom)),
-            _ => if let Some(r) = Ratio::from_float(n1.into_inner()) {
-                NumberPair::Rational(Rc::new(r), n2)
-            } else if n1.into_inner().is_sign_positive() {
-                NumberPair::Float(OrderedFloat(f64::infinity()),
-                                  OrderedFloat(f64::infinity()))
-            } else {
-                NumberPair::Float(OrderedFloat(f64::neg_infinity()),
-                                  OrderedFloat(f64::neg_infinity()))
-            }
-        }
-    }
-
-    pub fn from(n1: Number, n2: Number) -> NumberPair
-    {
-        match (n1, n2) {
-            (Number::Integer(n1), Number::Integer(n2)) =>
-                NumberPair::Integer(n1, n2),
-            (Number::Float(n1), Number::Float(n2)) =>
-                NumberPair::Float(n1, n2),
-            (Number::Rational(n1), Number::Rational(n2)) =>
-                NumberPair::Rational(n1, n2),
-            (Number::Integer(n1), Number::Float(n2)) =>
-                Self::integer_float_pair(n1, n2),
-            (Number::Float(n1), Number::Integer(n2)) =>
-                Self::integer_float_pair(n2, n1).flip(),
-            (Number::Float(n1), Number::Rational(n2)) =>
-                Self::float_rational_pair(n1, n2),
-            (Number::Rational(n1), Number::Float(n2)) =>
-                Self::float_rational_pair(n2, n1).flip(),
-            (Number::Rational(n1), Number::Integer(n2)) =>
-                NumberPair::Rational(n1, Rc::new(Ratio::from_integer((*n2).clone()))),
-            (Number::Integer(n1), Number::Rational(n2)) =>
-                NumberPair::Rational(Rc::new(Ratio::from_integer((*n1).clone())), n2)
-        }
-    }
-}
-
-impl Add<Number> for Number {
-    type Output = Number;
-
-    fn add(self, rhs: Number) -> Self::Output {
-        match NumberPair::from(self, rhs) {
-            NumberPair::Float(f1, f2) =>
-                Number::Float(OrderedFloat(f1.into_inner() + f2.into_inner())),
-            NumberPair::Integer(n1, n2) =>
-                Number::Integer(Rc::new(&*n1 + &*n2)),
-            NumberPair::Rational(r1, r2) =>
-                Number::Rational(Rc::new(&*r1 + &*r2))
-        }
-    }
-}
-
-impl Sub<Number> for Number {
-    type Output = Number;
-
-    fn sub(self, rhs: Number) -> Self::Output {
-        match NumberPair::from(self, rhs) {
-            NumberPair::Float(f1, f2) =>
-                Number::Float(OrderedFloat(f1.into_inner() - f2.into_inner())),
-            NumberPair::Integer(n1, n2) =>
-                Number::Integer(Rc::new(&*n1 - &*n2)),
-            NumberPair::Rational(r1, r2) =>
-                Number::Rational(Rc::new(&*r1 - &*r2))
-        }
-    }
-}
-
-impl Mul<Number> for Number {
-    type Output = Number;
-
-    fn mul(self, rhs: Number) -> Self::Output {
-        match NumberPair::from(self, rhs) {
-            NumberPair::Float(f1, f2) =>
-                Number::Float(OrderedFloat(f1.into_inner() * f2.into_inner())),
-            NumberPair::Integer(n1, n2) =>
-                Number::Integer(Rc::new(&*n1 * &*n2)),
-            NumberPair::Rational(r1, r2) =>
-                Number::Rational(Rc::new(&*r1 * &*r2))
-        }
+    fn from(inlined_ct: InlinedClauseType) -> Self {
+        ClauseType::Inlined(inlined_ct)
     }
 }
 
-impl Div<Number> for Number {
-    type Output = Number;
+#[derive(Clone)]
+pub enum ChoiceInstruction {
+    DefaultRetryMeElse(usize),
+    DefaultTrustMe,
+    RetryMeElse(usize),
+    TrustMe,
+    TryMeElse(usize)
+}
 
-    fn div(self, rhs: Number) -> Self::Output {
-        match NumberPair::from(self, rhs) {
-            NumberPair::Float(f1, f2) =>
-                Number::Float(OrderedFloat(f1.into_inner() / f2.into_inner())),
-            NumberPair::Integer(n1, n2) =>
-                match n1.to_f64() {
-                    Some(f1) => if let Some(f2) = n2.to_f64() {
-                        Number::Float(OrderedFloat(f1 / f2))
-                    } else {
-                        let r1 = Ratio::from_integer((*n1).clone());
-                        let r2 = Ratio::from_integer((*n2).clone());
+#[derive(Clone)]
+pub enum CutInstruction {
+    Cut(RegType),
+    GetLevel(RegType),
+    GetLevelAndUnify(RegType),
+    NeckCut
+}
 
-                        Number::Rational(Rc::new(r1 / r2))
-                    },
-                    None => {
-                        let r1 = Ratio::from_integer((*n1).clone());
-                        let r2 = Ratio::from_integer((*n2).clone());
+#[derive(Clone)]
+pub enum IndexedChoiceInstruction {
+    Retry(usize),
+    Trust(usize),
+    Try(usize)
+}
 
-                        Number::Rational(Rc::new(r1 / r2))
-                    },
-                },
-            NumberPair::Rational(r1, r2) =>
-                Number::Rational(Rc::new(&*r1 / &*r2))
-        }
+impl From<IndexedChoiceInstruction> for Line {
+    fn from(i: IndexedChoiceInstruction) -> Self {
+        Line::IndexedChoice(i)
     }
 }
 
-impl Neg for Number {
-    type Output = Number;
-
-    fn neg(self) -> Self::Output {
+impl IndexedChoiceInstruction {
+    pub fn offset(&self) -> usize {
         match self {
-            Number::Integer(n) => Number::Integer(Rc::new(-&*n)),
-            Number::Float(f) => Number::Float(OrderedFloat(-1.0 * f.into_inner())),
-            Number::Rational(r) => Number::Rational(Rc::new(- &*r))
+            &IndexedChoiceInstruction::Retry(offset) => offset,
+            &IndexedChoiceInstruction::Trust(offset) => offset,
+            &IndexedChoiceInstruction::Try(offset)   => offset
         }
     }
 }
-
 #[derive(Clone, PartialEq)]
 pub enum ArithmeticTerm {
     Reg(RegType),
@@ -1827,188 +857,447 @@ impl PartialOrd<CodePtr> for CodePtr {
             _ => Some(Ordering::Greater)
         }
     }
-}
+}
+
+impl PartialOrd<LocalCodePtr> for LocalCodePtr {
+    fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
+        match (self, other) {
+            (&LocalCodePtr::DirEntry(p1, _), &LocalCodePtr::DirEntry(p2, _)) =>
+                p1.partial_cmp(&p2),
+            (&LocalCodePtr::DirEntry(..), &LocalCodePtr::TopLevel(_, _)) =>
+                Some(Ordering::Less),
+            (&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) =>
+                p1.partial_cmp(p2),
+            _ => Some(Ordering::Greater)
+        }
+    }
+}
+
+impl Default for CodePtr {
+    fn default() -> Self {
+        CodePtr::Local(LocalCodePtr::default())
+    }
+}
+
+impl Default for LocalCodePtr {
+    fn default() -> Self {
+        LocalCodePtr::TopLevel(0, 0)
+    }
+}
+
+impl Add<usize> for LocalCodePtr {
+    type Output = LocalCodePtr;
+
+    fn add(self, rhs: usize) -> Self::Output {
+        match self {
+            LocalCodePtr::DirEntry(p, name) => LocalCodePtr::DirEntry(p + rhs, name),
+            LocalCodePtr::TopLevel(cn, p) => LocalCodePtr::TopLevel(cn, p + rhs)
+        }
+    }
+}
+
+impl AddAssign<usize> for LocalCodePtr {
+    fn add_assign(&mut self, rhs: usize) {
+        match self {
+            &mut LocalCodePtr::DirEntry(ref mut p, _) |
+            &mut LocalCodePtr::TopLevel(_, ref mut p) => *p += rhs
+        }
+    }
+}
+
+impl Add<usize> for CodePtr {
+    type Output = CodePtr;
+
+    fn add(self, rhs: usize) -> Self::Output {
+        match self {
+            CodePtr::Local(local) => CodePtr::Local(local + rhs),
+            CodePtr::CallN(_, local) | CodePtr::BuiltInClause(_, local) => CodePtr::Local(local + rhs),
+        }
+    }
+}
+
+impl AddAssign<usize> for CodePtr {
+    fn add_assign(&mut self, rhs: usize) {
+        match self {
+            &mut CodePtr::Local(ref mut local) => *local += rhs,
+            _ => *self = CodePtr::Local(self.local() + rhs)
+        }
+    }
+}
+
+pub struct Heap {
+    heap: Vec<HeapCellValue>,
+    pub h: usize
+}
+
+impl Heap {
+    pub fn with_capacity(cap: usize) -> Self {
+        Heap { heap: Vec::with_capacity(cap), h: 0 }
+    }
+
+    pub fn push(&mut self, val: HeapCellValue) {
+        self.heap.push(val);
+        self.h += 1;
+    }
+
+    pub fn truncate(&mut self, h: usize) {
+        self.h = h;
+        self.heap.truncate(h);
+    }
+
+    pub fn len(&self) -> usize {
+        self.heap.len()
+    }
+
+    pub fn append(&mut self, vals: Vec<HeapCellValue>) {
+        let n = vals.len();
+
+        self.heap.extend(vals.into_iter());
+        self.h += n;
+    }
+
+    pub fn clear(&mut self) {
+        self.heap.clear();
+        self.h = 0;
+    }
+}
+
+impl Index<usize> for Heap {
+    type Output = HeapCellValue;
+
+    fn index(&self, index: usize) -> &Self::Output {
+        &self.heap[index]
+    }
+}
+
+impl IndexMut<usize> for Heap {
+    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
+        &mut self.heap[index]
+    }
+}
+
+pub type Registers = Vec<Addr>;
+
+pub enum TermIterState<'a> {
+    AnonVar(Level),
+    Constant(Level, &'a Cell<RegType>, &'a Constant),
+    Clause(Level, usize, &'a Cell<RegType>, ClauseType, &'a Vec<Box<Term>>),
+    InitialCons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
+    FinalCons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
+    Var(Level, &'a Cell<VarReg>, Rc<Var>)
+}
+
+impl<'a> TermIterState<'a> {
+    pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> {
+        match term {
+            &Term::AnonVar =>
+                TermIterState::AnonVar(lvl),
+            &Term::Clause(ref cell, ref name, ref subterms, fixity) => {
+                let ct = if let Some(fixity) = fixity {
+                    ClauseType::Op(name.clone(), fixity, CodeIndex::default())
+                } else {
+                    ClauseType::Named(name.clone(), CodeIndex::default())
+                };
+
+                TermIterState::Clause(lvl, 0, cell, ct, subterms)
+            },
+            &Term::Cons(ref cell, ref head, ref tail) =>
+                TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref()),
+            &Term::Constant(ref cell, ref constant) =>
+                TermIterState::Constant(lvl, cell, constant),
+            &Term::Var(ref cell, ref var) =>
+                TermIterState::Var(lvl, cell, var.clone())
+        }
+    }
+}
+
+impl Module {
+    pub fn new(module_decl: ModuleDecl) -> Self {
+        Module { module_decl,
+                 code_dir: ModuleCodeDir::new(),
+                 op_dir: default_op_dir() }
+    }
+}
+
+pub fn as_module_code_dir(code_dir: CodeDir) -> ModuleCodeDir {
+    code_dir.into_iter()
+        .map(|(k, code_idx)| {
+            let (idx, module_name) = code_idx.0.borrow().clone();
+            (k, ModuleCodeIndex(idx, module_name))
+        })
+        .collect()
+}
+
+impl SubModuleUser for Module {
+    fn op_dir(&mut self) -> &mut OpDir {
+        &mut self.op_dir
+    }
+
+    fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex) {
+        self.code_dir.insert((name, arity), idx);
+    }
+}
+
+pub trait SubModuleUser {
+    fn op_dir(&mut self) -> &mut OpDir;
+    fn insert_dir_entry(&mut self, ClauseName, usize, ModuleCodeIndex);
+
+    // returns true on successful import.
+    fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool {
+        let name = name.defrock_brackets();
+        let mut found_op = false;
+
+        {
+            let mut insert_op_dir = |fix| {
+                if let Some(op_data) = submodule.op_dir.get(&(name.clone(), fix)) {
+                    self.op_dir().insert((name.clone(), fix), op_data.clone());
+                    found_op = true;
+                }
+            };
+
+            if arity == 1 {
+                insert_op_dir(Fixity::Pre);
+                insert_op_dir(Fixity::Post);
+            } else if arity == 2 {
+                insert_op_dir(Fixity::In);
+            }
+        }
+
+        if let Some(code_data) = submodule.code_dir.get(&(name.clone(), arity)) {
+            self.insert_dir_entry(name, arity, code_data.clone());
+            true
+        } else {
+            found_op
+        }
+    }
+
+    fn use_qualified_module(&mut self, submodule: &Module, exports: &Vec<PredicateKey>) -> EvalSession
+    {
+        for (name, arity) in exports.iter().cloned() {
+            if !submodule.module_decl.exports.contains(&(name.clone(), arity)) {
+                continue;
+            }
+
+            if !self.import_decl(name, arity, submodule) {
+                return EvalSession::from(SessionError::ModuleDoesNotContainExport);
+            }
+        }
+
+        EvalSession::EntrySuccess
+    }
 
-impl PartialOrd<LocalCodePtr> for LocalCodePtr {
-    fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
-        match (self, other) {
-            (&LocalCodePtr::DirEntry(p1, _), &LocalCodePtr::DirEntry(p2, _)) =>
-                p1.partial_cmp(&p2),
-            (&LocalCodePtr::DirEntry(..), &LocalCodePtr::TopLevel(_, _)) =>
-                Some(Ordering::Less),
-            (&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) =>
-                p1.partial_cmp(p2),
-            _ => Some(Ordering::Greater)
+    fn use_module(&mut self, submodule: &Module) -> EvalSession {
+        for (name, arity) in submodule.module_decl.exports.iter().cloned() {
+            if !self.import_decl(name, arity, submodule) {
+                return EvalSession::from(SessionError::ModuleDoesNotContainExport);
+            }
         }
+
+        EvalSession::EntrySuccess
     }
 }
 
-impl Default for CodePtr {
-    fn default() -> Self {
-        CodePtr::Local(LocalCodePtr::default())
-    }
+pub enum Declaration {
+    NonCountedBacktracking(ClauseName, usize), // name, arity
+    Module(ModuleDecl),
+    Op(OpDecl),
+    UseModule(ClauseName),
+    UseQualifiedModule(ClauseName, Vec<PredicateKey>)
 }
 
-impl Default for LocalCodePtr {
-    fn default() -> Self {
-        LocalCodePtr::TopLevel(0, 0)
-    }
+pub enum TopLevel {
+    Declaration(Declaration),
+    Fact(Term),
+    Predicate(Predicate),
+    Query(Vec<QueryTerm>),
+    Rule(Rule)
 }
 
-impl Add<usize> for LocalCodePtr {
-    type Output = LocalCodePtr;
+impl TopLevel {
+    pub fn name(&self) -> Option<ClauseName> {
+        match self {
+            &TopLevel::Declaration(_) => None,
+            &TopLevel::Fact(ref term) => term.name(),
+            &TopLevel::Predicate(ref clauses) =>
+                clauses.0.first().and_then(|ref term| term.name()),
+            &TopLevel::Query(_) => None,
+            &TopLevel::Rule(Rule { ref head, .. }) =>
+                Some(head.0.clone())
+        }
+    }
 
-    fn add(self, rhs: usize) -> Self::Output {
+    pub fn arity(&self) -> usize {
         match self {
-            LocalCodePtr::DirEntry(p, name) => LocalCodePtr::DirEntry(p + rhs, name),
-            LocalCodePtr::TopLevel(cn, p) => LocalCodePtr::TopLevel(cn, p + rhs)
+            &TopLevel::Declaration(_) => 0,
+            &TopLevel::Fact(ref term) => term.arity(),
+            &TopLevel::Predicate(ref clauses) =>
+                clauses.0.first().map(|t| t.arity()).unwrap_or(0),
+            &TopLevel::Query(_) => 0,
+            &TopLevel::Rule(Rule { ref head, .. }) => head.1.len()
         }
     }
-}
 
-impl AddAssign<usize> for LocalCodePtr {
-    fn add_assign(&mut self, rhs: usize) {
+    pub fn as_predicate(self) -> Result<Predicate, TopLevel> {
         match self {
-            &mut LocalCodePtr::DirEntry(ref mut p, _) |
-            &mut LocalCodePtr::TopLevel(_, ref mut p) => *p += rhs
+            TopLevel::Fact(term) => Ok(Predicate(vec![PredicateClause::Fact(term)])),
+            TopLevel::Rule(rule) => Ok(Predicate(vec![PredicateClause::Rule(rule)])),
+            TopLevel::Predicate(pred) => Ok(pred),
+            _ => Err(self)
         }
     }
 }
 
-impl Add<usize> for CodePtr {
-    type Output = CodePtr;
+#[derive(Clone, Copy)]
+pub enum Level {
+    Deep, Root, Shallow
+}
 
-    fn add(self, rhs: usize) -> Self::Output {
+impl Level {
+    pub fn child_level(self) -> Level {
         match self {
-            CodePtr::Local(local) => CodePtr::Local(local + rhs),
-            CodePtr::CallN(_, local) | CodePtr::BuiltInClause(_, local) => CodePtr::Local(local + rhs),
+            Level::Root => Level::Shallow,
+            _ => Level::Deep
         }
     }
 }
 
-impl AddAssign<usize> for CodePtr {
-    fn add_assign(&mut self, rhs: usize) {
+// labeled with chunk numbers.
+pub enum VarStatus {
+    Perm(usize), Temp(usize, TempVarData) // Perm(chunk_num) | Temp(chunk_num, _)
+}
+
+pub type OccurrenceSet = BTreeSet<(GenContext, usize)>;
+
+// Perm: 0 initially, a stack register once processed.
+// Temp: labeled with chunk_num and temp offset (unassigned if 0).
+pub enum VarData {
+    Perm(usize), Temp(usize, usize, TempVarData)
+}
+
+impl VarData {
+    pub fn as_reg_type(&self) -> RegType {
         match self {
-            &mut CodePtr::Local(ref mut local) => *local += rhs,
-            _ => *self = CodePtr::Local(self.local() + rhs)
+            &VarData::Temp(_, r, _) => RegType::Temp(r),
+            &VarData::Perm(r) => RegType::Perm(r)
         }
     }
 }
 
-pub struct Heap {
-    heap: Vec<HeapCellValue>,
-    pub h: usize
+pub struct TempVarData {
+    pub last_term_arity: usize,
+    pub use_set: OccurrenceSet,
+    pub no_use_set: BTreeSet<usize>,
+    pub conflict_set: BTreeSet<usize>
 }
 
-impl Heap {
-    pub fn with_capacity(cap: usize) -> Self {
-        Heap { heap: Vec::with_capacity(cap), h: 0 }
+impl TempVarData {
+    pub fn new(last_term_arity: usize) -> Self {
+        TempVarData {
+            last_term_arity: last_term_arity,
+            use_set: BTreeSet::new(),
+            no_use_set: BTreeSet::new(),
+            conflict_set: BTreeSet::new()
+        }
     }
 
-    pub fn push(&mut self, val: HeapCellValue) {
-        self.heap.push(val);
-        self.h += 1;
-    }
+    pub fn uses_reg(&self, reg: usize) -> bool {
+        for &(_, nreg) in self.use_set.iter() {
+            if reg == nreg {
+                return true;
+            }
+        }
 
-    pub fn truncate(&mut self, h: usize) {
-        self.h = h;
-        self.heap.truncate(h);
+        return false;
     }
 
-    pub fn len(&self) -> usize {
-        self.heap.len()
-    }
+    pub fn populate_conflict_set(&mut self) {
+        if self.last_term_arity > 0 {
+            let arity = self.last_term_arity;
+            let mut conflict_set : BTreeSet<usize> = (1..arity).collect();
 
-    pub fn append(&mut self, vals: Vec<HeapCellValue>) {
-        let n = vals.len();
+            for &(_, reg) in self.use_set.iter() {
+                conflict_set.remove(&reg);
+            }
 
-        self.heap.extend(vals.into_iter());
-        self.h += n;
+            self.conflict_set = conflict_set;
+        }
     }
+}
 
-    pub fn clear(&mut self) {
-        self.heap.clear();
-        self.h = 0;
-    }
+pub type HeapVarDict  = HashMap<Rc<Var>, Addr>;
+pub type AllocVarDict = HashMap<Rc<Var>, VarData>;
+
+pub enum SessionError {
+    ImpermissibleEntry(String),
+    ModuleDoesNotContainExport,
+    ModuleNotFound,
+    NamelessEntry,
+    OpIsInfixAndPostFix,
+    ParserError(ParserError),
+    QueryFailure,
+    QueryFailureWithException(String)
 }
 
-impl Index<usize> for Heap {
-    type Output = HeapCellValue;
+pub enum EvalSession {
+    EntrySuccess,
+    Error(SessionError),
+    InitialQuerySuccess(AllocVarDict, HeapVarDict),
+    SubsequentQuerySuccess,
+}
 
-    fn index(&self, index: usize) -> &Self::Output {
-        &self.heap[index]
+impl From<SessionError> for EvalSession {
+    fn from(err: SessionError) -> Self {
+        EvalSession::Error(err)
     }
 }
 
-impl IndexMut<usize> for Heap {
-    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
-        &mut self.heap[index]
+impl From<ParserError> for SessionError {
+    fn from(err: ParserError) -> Self {
+        SessionError::ParserError(err)
     }
 }
 
-pub type Registers = Vec<Addr>;
-
-impl Term {
-    pub fn to_constant(self) -> Option<Constant> {
-        match self {
-            Term::Constant(_, c) => Some(c),
-            _ => None
-        }
+impl From<ParserError> for EvalSession {
+    fn from(err: ParserError) -> Self {
+        EvalSession::from(SessionError::ParserError(err))
     }
+}
 
-    pub fn first_arg(&self) -> Option<&Term> {
-        match self {
-            &Term::Clause(_, _, ref terms, _) =>
-                terms.first().map(|bt| bt.as_ref()),
-            _ => None
-        }
-    }
+pub struct OpDecl(pub usize, pub Specifier, pub ClauseName);
 
-    pub fn name(&self) -> Option<ClauseName> {
-        match self {
-            &Term::Constant(_, Constant::Atom(ref atom))
-          | &Term::Clause(_, ref atom, ..) => Some(atom.clone()),
-            _ => None
-        }
-    }
+impl OpDecl {
+    pub fn submit(&self, module: ClauseName, op_dir: &mut OpDir) -> Result<(), SessionError>
+    {
+        let (prec, spec, name) = (self.0, self.1, self.2.clone());
 
-    pub fn arity(&self) -> usize {
-        match self {
-            &Term::Clause(_, _, ref child_terms, ..) => child_terms.len(),
-            _ => 0
+        if is_infix!(spec) {
+            match op_dir.get(&(name.clone(), Fixity::Post)) {
+                Some(_) => return Err(SessionError::OpIsInfixAndPostFix),
+                _ => {}
+            };
         }
-    }
-}
 
-pub enum TermIterState<'a> {
-    AnonVar(Level),
-    Constant(Level, &'a Cell<RegType>, &'a Constant),
-    Clause(Level, usize, &'a Cell<RegType>, ClauseType, &'a Vec<Box<Term>>),
-    InitialCons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
-    FinalCons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
-    Var(Level, &'a Cell<VarReg>, Rc<Var>)
-}
-
-impl<'a> TermIterState<'a> {
-    pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> {
-        match term {
-            &Term::AnonVar =>
-                TermIterState::AnonVar(lvl),
-            &Term::Clause(ref cell, ref name, ref subterms, fixity) => {
-                let ct = if let Some(fixity) = fixity {
-                    ClauseType::Op(name.clone(), fixity, CodeIndex::default())
-                } else {
-                    ClauseType::Named(name.clone(), CodeIndex::default())
-                };
+        if is_postfix!(spec) {
+            match op_dir.get(&(name.clone(), Fixity::In)) {
+                Some(_) => return Err(SessionError::OpIsInfixAndPostFix),
+                _ => {}
+            };
+        }
 
-                TermIterState::Clause(lvl, 0, cell, ct, subterms)
-            },
-            &Term::Cons(ref cell, ref head, ref tail) =>
-                TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref()),
-            &Term::Constant(ref cell, ref constant) =>
-                TermIterState::Constant(lvl, cell, constant),
-            &Term::Var(ref cell, ref var) =>
-                TermIterState::Var(lvl, cell, var.clone())
+        if prec > 0 {
+            match spec {
+                XFY | XFX | YFX => op_dir.insert((name.clone(), Fixity::In),
+                                                 (spec, prec, module.clone())),
+                XF | YF => op_dir.insert((name.clone(), Fixity::Post), (spec, prec, module.clone())),
+                FX | FY => op_dir.insert((name.clone(), Fixity::Pre), (spec, prec, module.clone())),
+                _ => None
+            };
+        } else {
+            op_dir.remove(&(name.clone(), Fixity::Pre));
+            op_dir.remove(&(name.clone(), Fixity::In));
+            op_dir.remove(&(name.clone(), Fixity::Post));
         }
+
+        Ok(())
     }
 }
index 3c8d40a768eab50f687065a03fd9a933e50045a1..becf6e714f02b44e2795006f1dd26874739bbfba 100644 (file)
@@ -1,10 +1,11 @@
+use prolog_parser::ast::*;
+
+use prolog::ast::*;
 use prolog::allocator::*;
 use prolog::arithmetic::*;
-use prolog::ast::*;
 use prolog::fixtures::*;
 use prolog::indexing::*;
 use prolog::iterators::*;
-use prolog::machine::machine_state::MachineFlags;
 use prolog::targets::*;
 
 use std::cell::Cell;
@@ -596,10 +597,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
 
     pub fn compile_fact<'b: 'a>(&mut self, term: &'b Term) -> Code
     {
-        self.update_var_count(term.post_order_iter());
+        self.update_var_count(post_order_iter(term));
 
         let mut vs = VariableFixtures::new();
-        vs.mark_vars_in_chunk(term.post_order_iter(), term.arity(), GenContext::Head);
+        vs.mark_vars_in_chunk(post_order_iter(term), term.arity(), GenContext::Head);
 
         vs.populate_restricting_sets();
         self.marker.drain_var_data(vs);
@@ -628,7 +629,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
     {
         self.marker.reset_arg(term.arity());
 
-        let iter  = term.post_order_iter();
+        let iter  = query_term_post_order_iter(term);
         let query = self.compile_target(iter, term_loc, is_exposed);
 
         if !query.is_empty() {
index f0bb298660a859b1e4fc0ef9965ccfc7a1ef54c0..ca151441c56441971017f5b7a5e0c721a0030433 100644 (file)
@@ -1,8 +1,9 @@
+use prolog_parser::ast::*;
+
 use prolog::ast::*;
 use prolog::debray_allocator::*;
 use prolog::codegen::*;
 use prolog::machine::*;
-use prolog::machine::machine_state::MachineFlags;
 use prolog::toplevel::*;
 
 use std::collections::{HashMap, HashSet, VecDeque};
index 0595678d592b62b261a06ddeb69349b8e1fef703..6ac18b6ae3f8d47e4ca7074acce21557dc249142 100644 (file)
@@ -1,5 +1,5 @@
-use prolog::and_stack::*;
 use prolog::ast::*;
+use prolog::and_stack::*;
 
 use std::ops::IndexMut;
 
index 2ded88f8bc299a340305b12a6183de1cdd6db70a..88a40a02d0f36f8f429aaf848f8107555d2142be 100644 (file)
@@ -1,5 +1,7 @@
-use prolog::allocator::*;
+use prolog_parser::ast::*;
+
 use prolog::ast::*;
+use prolog::allocator::*;
 use prolog::targets::*;
 
 use std::cell::Cell;
index 00590e54808787e0a79c6827bfc5617f86698fbb..c2ee7e3fae00bea968d3aa37d108ceedf953e09f 100644 (file)
@@ -1,56 +1,15 @@
-use prolog::ast::*;
+use prolog_parser::ast::*;
+
 use prolog::iterators::*;
 
+use prolog::ast::*;
 use std::cell::Cell;
-use std::collections::{BTreeMap, BTreeSet, HashMap};
+use std::collections::{BTreeMap, HashMap};
 use std::collections::btree_map::{IntoIter, IterMut, Values};
 use std::mem::swap;
 use std::rc::Rc;
 use std::vec::Vec;
 
-impl VarData {
-    pub fn as_reg_type(&self) -> RegType {
-        match self {
-            &VarData::Temp(_, r, _) => RegType::Temp(r),
-            &VarData::Perm(r) => RegType::Perm(r)
-        }
-    }
-}
-
-impl TempVarData {
-    fn new(last_term_arity: usize) -> Self {
-        TempVarData {
-            last_term_arity: last_term_arity,
-            use_set: BTreeSet::new(),
-            no_use_set: BTreeSet::new(),
-            conflict_set: BTreeSet::new()
-        }
-    }
-
-    fn uses_reg(&self, reg: usize) -> bool {
-        for &(_, nreg) in self.use_set.iter() {
-            if reg == nreg {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    fn populate_conflict_set(&mut self) {
-        if self.last_term_arity > 0 {
-            let arity = self.last_term_arity;
-            let mut conflict_set : BTreeSet<usize> = (1..arity).collect();
-
-            for &(_, reg) in self.use_set.iter() {
-                conflict_set.remove(&reg);
-            }
-
-            self.conflict_set = conflict_set;
-        }
-    }
-}
-
 type VariableFixture<'a> = (VarStatus, Vec<&'a Cell<VarReg>>);
 pub struct VariableFixtures<'a>(BTreeMap<Rc<Var>, VariableFixture<'a>>);
 
index 992065781f4d2444699a6e5cdfd8b6cd86aeb288..5ce1c54344a9dc670c04684a1b18c0377cd212b9 100644 (file)
@@ -1,5 +1,7 @@
+use prolog_parser::ast::*;
+
 use prolog::ast::*;
-use prolog::machine::machine_state::MachineState;
+use prolog::machine::machine_state::*;
 
 use std::collections::HashSet;
 use std::vec::Vec;
index 06e9acf8789e256d90af29097c0eeaabc870c19b..4af86934a152aec86179a0377238f3feae8bb6a4 100644 (file)
@@ -1,7 +1,9 @@
+use prolog_parser::ast::*;
+
 use prolog::ast::*;
+use prolog::machine::machine_state::*;
 use prolog::num::*;
 use prolog::heap_iter::*;
-use prolog::machine::machine_state::MachineState;
 use prolog::ordered_float::OrderedFloat;
 
 use std::cell::Cell;
index 84fbb8f34fccb55d5d47926f1cc651f7c5ff2801..2da720587a8c76ce25a57a8f1e74cb5f7bd9391a 100644 (file)
@@ -1,6 +1,6 @@
-use prolog::ast::*;
-use prolog::machine::machine_state::MachineFlags;
+use prolog_parser::ast::*;
 
+use prolog::ast::*;
 use std::collections::{HashMap, VecDeque};
 use std::hash::Hash;
 use std::rc::Rc;
index ccd05857daa553932e5f9316ce444efa964f8361..f1ff550e9e9c5397fe88921b6a575e5cea9a6c95 100644 (file)
@@ -9,6 +9,10 @@ use termion::event::Key;
 use std::io::{Write, stdin, stdout};
 use std::fmt;
 
+fn error_string(e: &String) -> String {
+    format!("error: exception thrown: {}", e)
+}
+
 impl fmt::Display for IndexPtr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -22,35 +26,6 @@ impl fmt::Display for IndexPtr {
     }
 }
 
-impl fmt::Display for ClauseName {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", self.as_str())
-    }
-}
-
-impl fmt::Display for Constant {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match self {
-            &Constant::Atom(ref atom) =>
-                if atom.as_str().chars().any(|c| "`.$'\" ".contains(c)) {
-                    write!(f, "'{}'", atom.as_str())
-                } else {
-                    write!(f, "{}", atom.as_str())
-                },
-            &Constant::Char(c) =>
-                write!(f, "'{}'", c as u8),
-            &Constant::EmptyList =>
-                write!(f, "[]"),
-            &Constant::Number(ref n) =>
-                write!(f, "{}", n),
-            &Constant::String(ref s) =>
-                write!(f, "\"{}\"", s.borrow()),
-            &Constant::Usize(integer) =>
-                write!(f, "u{}", integer)
-        }
-    }
-}
-
 impl fmt::Display for FactInstruction {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -306,28 +281,6 @@ impl fmt::Display for Level {
     }
 }
 
-impl fmt::Display for VarReg {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match self {
-            &VarReg::Norm(RegType::Perm(reg)) => write!(f, "Y{}", reg),
-            &VarReg::Norm(RegType::Temp(reg)) => write!(f, "X{}", reg),
-            &VarReg::ArgAndNorm(RegType::Perm(reg), arg) =>
-                write!(f, "Y{} A{}", reg, arg),
-            &VarReg::ArgAndNorm(RegType::Temp(reg), arg) =>
-                write!(f, "X{} A{}", reg, arg)
-        }
-    }
-}
-
-impl fmt::Display for RegType {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match self {
-            &RegType::Perm(val) => write!(f, "Y{}", val),
-            &RegType::Temp(val) => write!(f, "X{}", val)
-        }
-    }
-}
-
 pub enum Input {
     Quit,
     Clear,
@@ -367,10 +320,6 @@ pub fn read() -> Input {
     }
 }
 
-fn error_string(e: &String) -> String {
-    format!("error: exception thrown: {}", e)
-}
-
 pub fn print(wam: &mut Machine, result: EvalSession) {
     match result {
         EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
index feb8603800c5c729383e8390dd69c3ebab10e201..1eff90f90f69acb22871cf5136456c86436b9900 100644 (file)
@@ -1,10 +1,33 @@
-use prolog::ast::*;
+use prolog_parser::ast::*;
 
+use prolog::ast::*;
+use std::cell::Cell;
 use std::collections::VecDeque;
 use std::iter::*;
 use std::rc::Rc;
 use std::vec::Vec;
 
+#[derive(Clone)]
+pub enum TermRef<'a> {
+    AnonVar(Level),
+    Cons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
+    Constant(Level, &'a Cell<RegType>, &'a Constant),
+    Clause(Level, &'a Cell<RegType>, ClauseType, &'a Vec<Box<Term>>),
+    Var(Level, &'a Cell<VarReg>, Rc<Var>)
+}
+
+impl<'a> TermRef<'a> {
+    pub fn level(self) -> Level {
+        match self {
+            TermRef::AnonVar(lvl)
+          | TermRef::Cons(lvl, ..)
+          | TermRef::Constant(lvl, ..)
+          | TermRef::Var(lvl, ..)
+          | TermRef::Clause(lvl, ..) => lvl
+        }
+    }
+}
+
 pub struct QueryIterator<'a> {
     state_stack: Vec<TermIterState<'a>>,
 }
@@ -192,14 +215,12 @@ impl<'a> Iterator for FactIterator<'a> {
     }
 }
 
-impl Term {
-    pub fn post_order_iter(&self) -> QueryIterator {
-        QueryIterator::from_term(self)
-    }
+pub fn post_order_iter(term: &Term) -> QueryIterator {
+    QueryIterator::from_term(term)
+}
 
-    pub fn breadth_first_iter(&self, iterable_root: bool) -> FactIterator {
-        FactIterator::new(self, iterable_root)
-    }
+pub fn breadth_first_iter(term: &Term, iterable_root: bool) -> FactIterator {
+    FactIterator::new(term, iterable_root)
 }
 
 pub enum ChunkedTerm<'a> {
@@ -207,10 +228,8 @@ pub enum ChunkedTerm<'a> {
     BodyTerm(&'a QueryTerm)
 }
 
-impl QueryTerm {
-    pub fn post_order_iter<'a>(&'a self) -> QueryIterator<'a> {
-        QueryIterator::new(self)
-    }
+pub fn query_term_post_order_iter<'a>(query_term: &'a QueryTerm) -> QueryIterator<'a> {
+    QueryIterator::new(query_term)
 }
 
 impl<'a> ChunkedTerm<'a> {
index 797dd220aa4af9382eab866b8329d13cd6391081..d5907b7f3761f72067f32fc66d5a65541b86f01f 100644 (file)
@@ -1,3 +1,5 @@
+use prolog_parser::ast::*;
+
 use prolog::ast::*;
 use prolog::machine::machine_state::*;
 use prolog::num::bigint::BigInt;
index f7c4c1cde30de016e7506cc7dfdd41dc3f5c3431..7432e5997cdf99c59b0e4e245e0633cf90e81627 100644 (file)
@@ -1,12 +1,14 @@
-use prolog::and_stack::*;
+use prolog_parser::ast::*;
+use prolog_parser::tabled_rc::*;
+
 use prolog::ast::*;
+use prolog::and_stack::*;
 use prolog::copier::*;
 use prolog::heap_print::*;
 use prolog::machine::machine_errors::*;
 use prolog::num::{BigInt, BigUint, Zero, One};
 use prolog::or_stack::*;
 use prolog::read::*;
-use prolog::tabled_rc::*;
 
 use downcast::Any;
 
@@ -264,38 +266,6 @@ pub(super) enum MachineMode {
     Write
 }
 
-#[derive(Clone, Copy)]
-pub enum DoubleQuotes {
-    Atom, Chars, // Codes
-}
-
-impl DoubleQuotes {
-    pub fn is_chars(self) -> bool {
-        if let DoubleQuotes::Chars = self {
-            true
-        } else {
-            false
-        }
-    }
-}
-
-impl Default for DoubleQuotes {
-    fn default() -> Self {
-        DoubleQuotes::Chars
-    }
-}
-
-#[derive(Clone, Copy)]
-pub struct MachineFlags {
-    pub double_quotes: DoubleQuotes
-}
-
-impl Default for MachineFlags {
-    fn default() -> Self {
-        MachineFlags { double_quotes: DoubleQuotes::default() }
-    }
-}
-
 pub struct MachineState {
     pub(crate) atom_tbl: TabledData<Atom>,
     pub(super) s: usize,
index b0f8a5799a8de7a3cf28aa819b0ed0e20b707681..942b491ccfb53dc7d16764e86a209574d40bf6d2 100644 (file)
@@ -1,5 +1,8 @@
-use prolog::and_stack::*;
+use prolog_parser::ast::*;
+use prolog_parser::string_list::StringList;
+
 use prolog::ast::*;
+use prolog::and_stack::*;
 use prolog::copier::*;
 use prolog::heap_iter::*;
 use prolog::heap_print::*;
@@ -9,7 +12,6 @@ use prolog::num::{Integer, Signed, ToPrimitive, Zero};
 use prolog::num::bigint::{BigInt, BigUint};
 use prolog::num::rational::Ratio;
 use prolog::or_stack::*;
-use prolog::string_list::StringList;
 
 use std::cell::RefCell;
 use std::cmp::{max, Ordering};
index 508eb9049c9dbb1ed21475bbf26fb17a49e94f4e..7cf011fe6681c5c30c3180326673496cdabf648d 100644 (file)
@@ -1,12 +1,14 @@
+use prolog_parser::ast::*;
+use prolog_parser::tabled_rc::*;
+
 use prolog::ast::*;
 use prolog::compile::*;
 use prolog::heap_print::*;
-use prolog::tabled_rc::*;
 
 mod machine_errors;
 pub(super) mod machine_state;
-#[macro_use]
-mod machine_state_impl;
+
+#[macro_use] mod machine_state_impl;
 mod system_calls;
 
 use prolog::machine::machine_state::*;
@@ -16,6 +18,8 @@ use std::mem::swap;
 use std::ops::Index;
 use std::rc::Rc;
 
+static BUILTINS: &str = include_str!("../lib/builtins.pl");
+
 pub struct MachineCodeIndices<'a> {
     pub(super) code_dir: &'a mut CodeDir,
     pub(super) op_dir: &'a mut OpDir,
index e99d70015bc40bf286b126179b7a04b2c2189fc2..451c99e6b517359bf38e77de8c95357cb53d710a 100644 (file)
@@ -1,3 +1,5 @@
+use prolog_parser::ast::*;
+
 use prolog::ast::*;
 use prolog::machine::machine_errors::*;
 use prolog::machine::machine_state::*;
index da53a665edb994a5137f0c0cbafa90b841cb6144..f348ed0d0a4c67ddc94d70bf1b594622c7907eaf 100644 (file)
@@ -1,27 +1,3 @@
-macro_rules! clause_name {
-    ($name: expr, $tbl: expr) => (
-        ClauseName::User(TabledRc::new($name, $tbl.clone()))
-    ) ;
-    ($name: expr) => (
-        ClauseName::BuiltIn($name)
-    )
-}
-
-macro_rules! tabled_rc {
-    ($e:expr, $tbl:expr) => (
-        TabledRc::new(String::from($e), $tbl.clone())
-    )
-}
-
-macro_rules! atom {
-    ($e:expr, $tbl:expr) => (
-        Constant::Atom(ClauseName::User(tabled_rc!($e, $tbl)))
-    );
-    ($e:expr) => (
-        Constant::Atom(clause_name!($e))
-    )
-}
-
 macro_rules! interm {
     ($n: expr) => (
         ArithmeticTerm::Interm($n)
@@ -76,18 +52,6 @@ macro_rules! functor {
     );
 }
 
-macro_rules! temp_v {
-    ($x:expr) => (
-        RegType::Temp($x)
-    )
-}
-
-macro_rules! perm_v {
-    ($x:expr) => (
-        RegType::Perm($x)
-    )
-}
-
 macro_rules! is_atom {
     ($r:expr) => (
         call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtom($r)), 1, 0)
@@ -191,18 +155,6 @@ macro_rules! set_cp {
     )
 }
 
-macro_rules! integer {
-    ($i:expr) => (
-        Constant::Number(Number::Integer(Rc::new(BigInt::from($i))))
-    )
-}
-
-macro_rules! rc_atom {
-    ($e:expr) => (
-        Rc::new(String::from($e))
-    )
-}
-
 macro_rules! succeed {
     () => (
         call_clause!(ClauseType::System(SystemClauseType::Succeed), 0, 0)
index eb4e57f4c55a1d370f410ad4f75c41fd3eb46f71..ffc4de438a2da0a8453b9a772b6692425c3d643c 100644 (file)
@@ -1,13 +1,11 @@
 extern crate num;
 extern crate ordered_float;
+extern crate prolog_parser;
 
+#[macro_use] pub mod ast;
 pub mod and_stack;
-#[macro_use]
-pub mod macros;
-#[macro_use]
-pub mod ast;
-#[macro_use]
-pub mod allocator;
+#[macro_use] pub mod macros;
+#[macro_use] pub mod allocator;
 pub mod toplevel;
 pub mod machine;
 pub mod compile;
@@ -21,10 +19,6 @@ pub mod indexing;
 pub mod io;
 pub mod iterators;
 pub mod or_stack;
-#[macro_use]
-pub mod parser;
 pub mod heap_print;
 pub mod targets;
-pub mod tabled_rc;
 pub mod read;
-pub mod string_list;
diff --git a/src/prolog/parser b/src/prolog/parser
deleted file mode 160000 (submodule)
index 4881465..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 48814651b857b2fd55149320f1ea71d0571b442e
index b6e942a43ccdec1f1a93294719bc78f4e9067082..1f4bd4eb0156cc2badb3df50973095655b6aa603 100644 (file)
@@ -1,6 +1,9 @@
+use prolog_parser::ast::*;
+use prolog_parser::parser::*;
+
 use prolog::ast::*;
+use prolog::iterators::*;
 use prolog::machine::machine_state::*;
-use prolog::parser::parser::*;
 
 use std::collections::VecDeque;
 use std::io::stdin;
@@ -70,7 +73,7 @@ impl<'a> Reader<'a> {
         let mut queue = SubtermDeque::new();
         let mut var_dict = HeapVarDict::new();
 
-        for term in term.breadth_first_iter(true) {
+        for term in breadth_first_iter(&term, true) {
             let h = self.machine_st.heap.h;
 
             match &term {
index f6d1fb3637aa0a32f755cfedd6b713b7477cc204..9eaa2a34dd214351a7d35f093b9a4cc5e2b385e1 100644 (file)
@@ -1,3 +1,5 @@
+use prolog_parser::ast::*;
+
 use prolog::ast::*;
 use prolog::iterators::*;
 
@@ -32,7 +34,7 @@ impl<'a> CompilationTarget<'a> for FactInstruction {
     type Iterator = FactIterator<'a>;
 
     fn iter(term: &'a Term) -> Self::Iterator {
-        term.breadth_first_iter(false) // do not iterate over the root clause if one exists.
+        breadth_first_iter(term, false) // do not iterate over the root clause if one exists.
     }
 
     fn to_constant(lvl: Level, constant: Constant, reg: RegType) -> Self {
@@ -99,7 +101,7 @@ impl<'a> CompilationTarget<'a> for QueryInstruction {
     type Iterator = QueryIterator<'a>;
 
     fn iter(term: &'a Term) -> Self::Iterator {
-        term.post_order_iter()
+        post_order_iter(term)
     }
 
     fn to_structure(ct: ClauseType, arity: usize, r: RegType) -> Self
index 1f3919c4d74589a884e0cda7530593d84d87495a..266b153f9b525ec33088adc31558edff0bf567c7 100644 (file)
@@ -1,9 +1,11 @@
+use prolog_parser::ast::*;
+use prolog_parser::parser::*;
+use prolog_parser::tabled_rc::*;
+
 use prolog::ast::*;
+use prolog::iterators::*;
 use prolog::machine::*;
-use prolog::machine::machine_state::MachineFlags;
 use prolog::num::*;
-use prolog::parser::parser::*;
-use prolog::tabled_rc::*;
 
 use std::collections::{HashSet, VecDeque};
 use std::cell::{Cell, RefCell};
@@ -322,7 +324,7 @@ impl RelationWorker {
     {
         let mut vars = HashSet::new();
 
-        for term in term.post_order_iter() {
+        for term in post_order_iter(term) {
             if let TermRef::Var(_, _, v) = term {
                 vars.insert(v.clone());
             }
index b59abfa7e63c66b627abeb56a80028a14fd50c7b..aef15b7e972c9e20dccee98c870e0e2657e3ed6d 100644 (file)
@@ -1,3 +1,5 @@
+use prolog_parser::ast::*;
+
 use prolog::ast::*;
 use prolog::heap_print::*;
 use prolog::compile::*;