From 72bbd833136a8a36eab1597c2f32f0890caeade8 Mon Sep 17 00:00:00 2001
From: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Wed, 23 Dec 2015 12:50:54 -0800
Subject: Arrange the source include director to mirror expected build
 structure instead of creating links.

---
 src/include/Charset.H                |  49 ---
 src/include/Constructor.H            |  80 -----
 src/include/Database.H               |  54 ---
 src/include/FileMapping.H            |  66 ----
 src/include/Input.H                  | 108 ------
 src/include/InputFragment.h          |  90 -----
 src/include/Lisp.H                   | 128 -------
 src/include/SourceFile.H             |  53 ---
 src/include/defaults.H               |  64 ----
 src/include/diagnostics.H            |  63 ----
 src/include/dialect.H                |  47 ---
 src/include/iterator.H               |  83 -----
 src/include/open-axiom/Charset       |  49 +++
 src/include/open-axiom/Constructor   |  80 +++++
 src/include/open-axiom/Database      |  54 +++
 src/include/open-axiom/FileMapping   |  66 ++++
 src/include/open-axiom/Input         | 108 ++++++
 src/include/open-axiom/InputFragment |  90 +++++
 src/include/open-axiom/Lisp          | 128 +++++++
 src/include/open-axiom/SourceFile    |  53 +++
 src/include/open-axiom/defaults      |  64 ++++
 src/include/open-axiom/diagnostics   |  63 ++++
 src/include/open-axiom/dialect       |  47 +++
 src/include/open-axiom/hash-table    |  85 +++++
 src/include/open-axiom/iterator      |  83 +++++
 src/include/open-axiom/sexpr         | 419 ++++++++++++++++++++++
 src/include/open-axiom/storage       | 299 ++++++++++++++++
 src/include/open-axiom/string-pool   |  85 +++++
 src/include/open-axiom/structure     |  75 ++++
 src/include/open-axiom/token         | 670 +++++++++++++++++++++++++++++++++++
 src/include/open-axiom/token-value   | 145 ++++++++
 src/include/open-axiom/vm            | 606 +++++++++++++++++++++++++++++++
 src/include/sexpr.H                  | 419 ----------------------
 src/include/storage.H                | 299 ----------------
 src/include/structure.H              |  75 ----
 src/include/token-value.def          | 145 --------
 src/include/token.H                  | 670 -----------------------------------
 src/include/vm.H                     | 606 -------------------------------
 src/utils/Makefile.in                |   3 +-
 src/utils/hash-table.H               |  85 -----
 src/utils/string-pool.H              |  85 -----
 41 files changed, 3270 insertions(+), 3271 deletions(-)
 delete mode 100644 src/include/Charset.H
 delete mode 100644 src/include/Constructor.H
 delete mode 100644 src/include/Database.H
 delete mode 100644 src/include/FileMapping.H
 delete mode 100644 src/include/Input.H
 delete mode 100644 src/include/InputFragment.h
 delete mode 100644 src/include/Lisp.H
 delete mode 100644 src/include/SourceFile.H
 delete mode 100644 src/include/defaults.H
 delete mode 100644 src/include/diagnostics.H
 delete mode 100644 src/include/dialect.H
 delete mode 100644 src/include/iterator.H
 create mode 100644 src/include/open-axiom/Charset
 create mode 100644 src/include/open-axiom/Constructor
 create mode 100644 src/include/open-axiom/Database
 create mode 100644 src/include/open-axiom/FileMapping
 create mode 100644 src/include/open-axiom/Input
 create mode 100644 src/include/open-axiom/InputFragment
 create mode 100644 src/include/open-axiom/Lisp
 create mode 100644 src/include/open-axiom/SourceFile
 create mode 100644 src/include/open-axiom/defaults
 create mode 100644 src/include/open-axiom/diagnostics
 create mode 100644 src/include/open-axiom/dialect
 create mode 100644 src/include/open-axiom/hash-table
 create mode 100644 src/include/open-axiom/iterator
 create mode 100644 src/include/open-axiom/sexpr
 create mode 100644 src/include/open-axiom/storage
 create mode 100644 src/include/open-axiom/string-pool
 create mode 100644 src/include/open-axiom/structure
 create mode 100644 src/include/open-axiom/token
 create mode 100644 src/include/open-axiom/token-value
 create mode 100644 src/include/open-axiom/vm
 delete mode 100644 src/include/sexpr.H
 delete mode 100644 src/include/storage.H
 delete mode 100644 src/include/structure.H
 delete mode 100644 src/include/token-value.def
 delete mode 100644 src/include/token.H
 delete mode 100644 src/include/vm.H
 delete mode 100644 src/utils/hash-table.H
 delete mode 100644 src/utils/string-pool.H

(limited to 'src')

diff --git a/src/include/Charset.H b/src/include/Charset.H
deleted file mode 100644
index 58fa9ea8..00000000
--- a/src/include/Charset.H
+++ /dev/null
@@ -1,49 +0,0 @@
-// -*- C++ -*-
-// Copyright (C) 2013, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom, nor the names of its contributors may
-//       be used to endorse or promote products derived from this software
-//       without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_CHARSET_included
-#define OPENAXIOM_CHARSET_included
-
-#include <stdint.h>
-
-namespace OpenAxiom {
-   // Code point value of a UCS member.
-   using Codepoint = uint32_t;
-
-   // Unicode character type.
-   enum class Character : Codepoint {
-      NUL = Codepoint()         // The NUL character 
-   };
-}
-
-#endif  // OPENAXIOM_CHARSET_included
diff --git a/src/include/Constructor.H b/src/include/Constructor.H
deleted file mode 100644
index bfab3940..00000000
--- a/src/include/Constructor.H
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (C) 2013, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom. nor the names of its contributors
-//       may be used to endorse or promote products derived from this
-//       software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_CONSTRUCTOR_included
-#define OPENAXIOM_CONSTRUCTOR_included
-
-#include <open-axiom/string-pool>
-
-namespace OpenAxiom {
-   namespace VM {
-      // -- identifier
-      using Identifier = String;
-
-      // -- A constructor kind.
-      enum class ConstructorKind { category, domain, package };
-      
-      // -- Data structure for a constructor.
-      struct Constructor {
-         Identifier name;
-         Identifier abbrev;
-         String source_file;
-         String object_file;
-         ConstructorKind kind;
-      };
-   }
-}
-
-// -- specialize helper function objects
-namespace std {
-   template<>
-   struct hash<OpenAxiom::VM::Constructor> {
-      using H = hash<OpenAxiom::VM::Identifier>;
-      H::result_type operator()(const Constructor& c) const {
-         return h(c.name);
-      }
-
-      H h;
-   };
-
-   template<>
-   struct equal_to<OpenAxiom::VM::Constructor> {
-      using E = equal_to<OpenAxiom::VM::Identifier>;
-      using arg_type = OpenAxiom::VM::Constructor;
-      bool operator()(const arg_type& x, const arg_type& y) const {
-         return e(x.name, y.name);
-      }
-      E e;
-   };
-}
-
-#endif  // OPENAXIOM_CONSTRUCTOR_included
diff --git a/src/include/Database.H b/src/include/Database.H
deleted file mode 100644
index cea082c8..00000000
--- a/src/include/Database.H
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (C) 2013, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom. nor the names of its contributors
-//       may be used to endorse or promote products derived from this
-//       software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_DATABASE_included
-#define OPENAXIOM_DATABASE_included
-
-#include <open-axiom/FileMapping>
-#include <open-axiom/sexpr>
-#include <open-axiom/Lisp>
-
-namespace OpenAxiom {
-   namespace VM {
-      struct Database {
-         explicit Database(const std::string&);
-         Value find_with(Value, Lisp::Evaluator&);
-      private:
-         Memory::FileMapping file;
-         Sexpr::Reader reader;
-         Pair toc;
-         std::map<Value, Value> dict;
-      };
-   }
-}
-
-#endif  // OPENAXIOM_DATABASE_included
diff --git a/src/include/FileMapping.H b/src/include/FileMapping.H
deleted file mode 100644
index 0c836efb..00000000
--- a/src/include/FileMapping.H
+++ /dev/null
@@ -1,66 +0,0 @@
-// -*- C++ -*-
-// Copyright (C) 2010-2014, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom. nor the names of its contributors
-//       may be used to endorse or promote products derived from this
-//       software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// --% Author: Gabriel Dos Reis
-// --% Description:
-// --%   Provide random access read to files through file mapping.
-
-#ifndef OPENAXIOM_FILEMAPPING_included
-#define OPENAXIOM_FILEMAPPING_included
-
-#include <open-axiom/storage>
-
-namespace OpenAxiom {
-   namespace Memory {
-      // -----------------
-      // -- FileMapping --
-      // -----------------
-      struct FileMapping {
-         explicit FileMapping(std::string);
-         FileMapping(FileMapping&&);
-         ~FileMapping();
-         const Byte* begin() const { return start; }
-         const Byte* end() const { return begin() + extent; }
-         std::size_t size() const { return extent; }
-      protected:
-         Byte* start;           // address at the mapped storage
-         size_t extent;         // length (in bytes) of the storage
-      private:
-         FileMapping(const FileMapping&) = delete;
-         FileMapping& operator=(const FileMapping&) = delete;
-      };
-   }      
-}
-
-#endif  // OPENAXIOM_FILEMAPPING_included
-
diff --git a/src/include/Input.H b/src/include/Input.H
deleted file mode 100644
index fa4555b8..00000000
--- a/src/include/Input.H
+++ /dev/null
@@ -1,108 +0,0 @@
-// -*- C++ -*-
-// Copyright (C) 2013, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom, nor the names of its contributors may
-//       be used to endorse or promote products derived from this software
-//       without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_INPUT_included
-#define OPENAXIOM_INPUT_included
-
-#include <iterator>
-#include <string>
-#include <vector>
-#include "open-axiom.h"
-#include <open-axiom/structure>
-#include <open-axiom/iterator>
-
-namespace OpenAxiom {
-   namespace Input {
-      // -- Input text data
-      using Text = std::string;
-
-      // -- Type of Thingies that iterate over text values
-      using TextIterator = Text::const_iterator;
-
-      // -- Position of an input source line.
-      using LineNumber = Ordinal;
-      
-      // -- We keep info only for non-empty input lines.
-      struct NonEmptyLine : private structure::binary<LineNumber, Text> {
-         NonEmptyLine(LineNumber, const Text&);
-         LineNumber number() const { return first(); }
-         const Text& text() const { return second(); }
-         TextIterator begin() const { return text().begin(); }
-         TextIterator end() const { return text().end(); }
-         std::size_t size() const { return text().size(); }
-      };
-
-      struct Source;
-      // -- Index into input source lines --
-      using Index = std::size_t;
-
-      // -- Line --
-      struct Line : private structure::binary<const Source*, Index> {
-         using value_type = Text::value_type;
-         using const_reference = Text::const_reference;
-         using const_pointer = Text::const_pointer;
-         using difference_type = Text::difference_type;
-         using iterator = iterator::basic<Line>;
-         const NonEmptyLine& get() const;
-         const Text& text() const { return get().text(); }
-         LineNumber number() const { return get().number(); }
-         iterator begin() const { return { this, 0 }; }
-         iterator end() const { return { this, size() }; }
-         Cardinal size() const { return text().size(); }
-         const_reference at(Ordinal n) const { return text().at(n); }
-      private:
-         constexpr Line(const Source* s, Index i)
-               : structure::binary<const Source*, Index>(s, i)
-         { }
-         const Source* source() const { return first(); }
-         Index index() const { return second(); }
-         
-         friend Source;
-      };
-
-      // -- LineIterator --
-      using LineIterator = Line::iterator;
-
-      // -- Source --
-      struct Source : std::vector<NonEmptyLine> {
-         using iterator = OpenAxiom::iterator::basic<Source>;
-         using Index = Ordinal; // line index
-         Line line(Index i) const { return { this, i }; }
-         iterator begin() const { return { this, 0 }; }
-         iterator end() const { return { this, size() }; }
-         Line line(LineNumber, const Text&);
-      };
-   }
-}
-
-#endif  // OPENAXIOM_INPUT_included
diff --git a/src/include/InputFragment.h b/src/include/InputFragment.h
deleted file mode 100644
index 7f317973..00000000
--- a/src/include/InputFragment.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// -*- C++ -*-
-// Copyright (C) 2014, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom. nor the names of its contributors
-//       may be used to endorse or promote products derived from this
-//       software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// --% Author: Gabriel Dos Reis
-
-#ifndef OPENAXIOM_INPUTFRAGMENT_included
-#define OPENAXIOM_INPUTFRAGMENT_included
-
-#include <open-axiom/token>
-
-namespace OpenAxiom {
-   // A physical line is just raw text, coupled with location
-   // information such as line and indentation column.
-   struct Line : std::string {
-      LineNumber number;
-      ColumnIndex indent;
-      Line() : number(), indent() { }
-      
-      std::string sub_string(ColumnIndex s, ColumnIndex e) const {
-         return substr(s, e - s);
-      }
-   };
-
-   // A program fragment is a logical line, composed of possibly
-   // several physical lines subject to the off-side rule.  As a
-   // special case, a line ending with the underbar character
-   // continues to the next line with disregard to the off-side rule.
-   struct Fragment : std::vector<Line> {
-      explicit operator bool() const { return not empty(); }
-      // Holds if the last physical line ends with line continuation marker.
-      bool line_continuation() const {
-         return not empty() and back().back() == '_';
-      }
-      // Return the indentation of the last physical line of this fragment.
-      ColumnIndex last_indent() const {
-         return empty() ? 0 : back().indent;
-      }
-      using std::vector<Line>::operator[];
-      // Reference a line given by a position into this fragment.
-      const Line& operator()(const OpenAxiom::FragmentCursor& pos) const {
-         return (*this)[pos.line];
-      }
-      // Reference a character code unit at the position into this fragment.
-      uint8_t operator[](const OpenAxiom::FragmentCursor& pos) const {
-         return (*this)[pos.line][pos.column];
-      }
-      // Advance the cursor position to the next character code unit.
-      uint8_t advance(OpenAxiom::FragmentCursor& pos) const {
-         return (*this)[pos.line][pos.column++];
-      }
-      // This predicate holds if this fragment covers the cursor position.
-      bool covering(const OpenAxiom::FragmentCursor& pos) const {
-         return pos.column < (*this)[pos.line].size();
-      }
-   };
-
-   std::ostream& operator<<(std::ostream&, const Fragment&);
-}
-
-#endif  // OPENAXIOM_INPUTFRAGMENT_included
diff --git a/src/include/Lisp.H b/src/include/Lisp.H
deleted file mode 100644
index a189dd38..00000000
--- a/src/include/Lisp.H
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (C) 2013-2014, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom nor the names of its contributors
-//       may be used to endorse or promote products derived from this
-//       software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// --% Author: Gabriel Dos Reis
-// --% Abstract:
-// --%    Very simple support for some core Lisp-like operations.
-
-#ifndef OPENAXIOM_LISP_included
-#define OPENAXIOM_LISP_included
-
-#include <list>
-#include <open-axiom/sexpr>
-#include <open-axiom/vm>
-#include <map>
-#include <open-axiom/diagnostics>
-#include <iosfwd>
-#include <unordered_set>
-
-namespace std {
-   template<>
-   struct hash<OpenAxiom::VM::Package>  {
-      hash<OpenAxiom::VM::String>::result_type
-      operator()(const OpenAxiom::VM::Package& s) const {
-         return h(s.name);
-      }
-      hash<OpenAxiom::VM::String> h;
-   };
-
-   template<>
-   struct equal_to<OpenAxiom::VM::Package> {
-      using arg_type = OpenAxiom::VM::Package;
-      bool operator()(const arg_type& x, const arg_type& y) const {
-         constexpr equal_to<OpenAxiom::VM::String> eq { };
-         return eq(x.name, y.name);
-      }
-   };
-}
-
-namespace OpenAxiom {
-   namespace Lisp {
-      using namespace VM;
-
-      // -- Unimplemented features
-      struct Unimplemented : Diagnostics::BasicError {
-         explicit Unimplemented(const std::string&);
-      };
-
-      // -- Integer overflow
-      struct IntegerOverflow : Diagnostics::BasicError {
-         explicit IntegerOverflow(const std::string&);
-      };
-
-      // -- Unbound symbol
-      struct UnboundSymbol : Diagnostics::BasicError {
-         explicit UnboundSymbol(const std::string&);
-      };
-
-      // -- Unbound functiom symbol
-      struct UnboundFunctionSymbol : Diagnostics::BasicError {
-         explicit UnboundFunctionSymbol(const std::string&);
-      };
-      
-      // -- Anchor maps
-      using AnchorTable = std::map<Ordinal, Value>;
-
-      // -- Evaluator --
-      struct Evaluator : VM::BasicContext {
-         Evaluator();
-         Value eval(const Sexpr::Syntax*);
-         Package* core_package() { return core; }
-         Package* current_package() { return ns; }
-         Value toplevel_form(const Sexpr::Syntax*);
-         Value make_value(const Sexpr::Syntax*);
-         Value* lexical_binding(String);
-         Environment* global_environment();
-      private:
-         Package* core;
-         Package* ns;
-         Symbol* feature_list;
-         std::list<Environment> env_stack;
-         AnchorTable anchor_map;
-      };
-
-      // -- Format a value onto an output stream.
-      void format(Value, std::ostream&);
-      std::string show(Value);
-
-      // -- Retracts
-      Fixnum retract_to_fixnum(Value);
-      Pair retract_to_pair(Value);
-      Symbol* retract_to_symbol(Value);
-
-      // -- Alist functions
-      Value assoc(Value, Pair);
-   }
-}
-
-#endif  // OPENAXIOM_LISP_included
-
diff --git a/src/include/SourceFile.H b/src/include/SourceFile.H
deleted file mode 100644
index 41b085a3..00000000
--- a/src/include/SourceFile.H
+++ /dev/null
@@ -1,53 +0,0 @@
-// -*- C++ -*-
-// Copyright (C) 2013, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom, nor the names of its contributors may
-//       be used to endorse or promote products derived from this software
-//       without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_SOURCEFILE_included
-#define OPENAXIOM_SOURCEFILE_included
-
-#include <open-axiom/FileMapping>
-
-namespace OpenAxiom {
-   namespace Input {
-      // -- SourceFile --
-      struct SourceFile : Memory::FileMapping {
-         explicit SourceFile(const std::string&);
-         const std::string& pathname() const { return path; }
-      private:
-         std::string path;
-         SourceFile(const SourceFile&) = delete;
-         SourceFile& operator=(const SourceFile&) = delete;
-      }
-   }
-}
-
-#endif  // OPENAXIOM_SOURCEFILE_included
diff --git a/src/include/defaults.H b/src/include/defaults.H
deleted file mode 100644
index db399419..00000000
--- a/src/include/defaults.H
+++ /dev/null
@@ -1,64 +0,0 @@
-// -*- C++ -*-
-// Copyright (C) 2013, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom, nor the names of its contributors may
-//       be used to endorse or promote products derived from this software
-//       without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_DEFAULTS_included
-#define OPENAXIOM_DEFAULTS_included
-
-namespace OpenAxiom {
-   // -- The sole purpose of classes defines in this header is to
-   // -- provoke the automatic generation of definitions for functions
-   // -- defined within.  These functions are not really friend.  The
-   // -- friendship is such a mechanism to convince the C++ compiler
-   // -- to do something else.  This is standard technique, also
-   // -- known as `based class parameterized by derived classes', or
-   // -- `curiously recurring pattern'.
-   namespace defaults {
-      // generate definition for != assuming existence of ==.
-      template<typename t>
-      struct neq {
-         friend bool operator!=(t x, t y) { return not(x == y); }
-      };
-
-      // generate definitions for ordering functions assuming <.
-      template<typename t>
-      struct ordering {
-         friend bool operator<=(t x, t y) { return not(y < x); }
-         friend bool operator>(t x, t y) { return y < x; }
-         friend bool operator>=(t x, t y) { return not(x < y); }
-      };
-   }
-}
-
-#endif  // OPENAXIOM_DEFAULTS_included
-
-
diff --git a/src/include/diagnostics.H b/src/include/diagnostics.H
deleted file mode 100644
index 9cb0fce1..00000000
--- a/src/include/diagnostics.H
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2013, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom. nor the names of its contributors
-//       may be used to endorse or promote products derived from this
-//       software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_DIAGNOSTICS_included
-#define OPENAXIOM_DIAGNOSTICS_included
-
-#include <string>
-#include <iostream>
-
-namespace OpenAxiom {
-   namespace Diagnostics {
-      struct StandardStream {
-         StandardStream(std::ostream& = std::cout, std::ostream& = std::cerr);
-         ~StandardStream();
-
-         std::ostream& output() const { return *out; }
-         std::ostream& error() const { return *err; }
-         std::ostream& set_output(std::ostream&);
-         std::ostream& set_error(std::ostream&);
-      private:
-         std::ostream* out;
-         std::ostream* err;
-      };
-      
-      struct BasicError {
-         explicit BasicError(const std::string& s) : msg(s) { }
-         const std::string& message() const { return msg; }
-      protected:
-         std::string msg;
-      };
-   }
-}
-
-#endif
diff --git a/src/include/dialect.H b/src/include/dialect.H
deleted file mode 100644
index bcfddd04..00000000
--- a/src/include/dialect.H
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (C) 2013-2014, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom. nor the names of its contributors
-//       may be used to endorse or promote products derived from this
-//       software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_DIALECT_included
-#define OPENAXIOM_DIALECT_included
-
-namespace OpenAxiom {
-   // Languages for which we have parsers.
-   enum class Language {
-      Spad = 0x1,
-      Boot = 0x2,
-      Lisp = 0x4,
-      BootSpad = Spad | Boot,
-      All = Spad | Boot | Lisp,
-   };
-}
-
-#endif  // OPENAXIOM_DIALECT_included
diff --git a/src/include/iterator.H b/src/include/iterator.H
deleted file mode 100644
index 048dc67c..00000000
--- a/src/include/iterator.H
+++ /dev/null
@@ -1,83 +0,0 @@
-// -*- C++ -*-
-// Copyright (C) 2013, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom, nor the names of its contributors may
-//       be used to endorse or promote products derived from this software
-//       without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_ITERATOR_included
-#define OPENAXIOM_ITERATOR_included
-
-#include <iterator>
-#include <open-axiom/defaults>
-#include "open-axiom.h"
-
-namespace OpenAxiom {
-   // -- Read-only iterator over a sequence with random access capabilities.
-   namespace iterator {
-      template<typename Seq>
-      struct basic
-         : std::iterator<std::random_access_iterator_tag,
-                         const typename Seq::value_type>,
-         defaults::neq<basic<Seq>>, defaults::ordering<basic<Seq>> {
-         using reference = typename Seq::const_reference;
-         using pointer = typename Seq::const_pointer;
-         using difference_type = typename Seq::difference_type;
-
-         reference operator*() const { return seq->at(idx); }
-         pointer operator->() const { return &seq->at(idx); }
-         reference operator[](Ordinal i) const { return seq->at(idx + i); }
-
-         basic& operator++() { ++idx; return *this; }
-         basic operator++(int) { auto t = *this; ++idx; return t; }
-         basic& operator--() { --idx; return *this; }
-         basic operator--(int) { auto t = *this; --idx; return t; }
-
-         basic& operator+=(Cardinal n) { idx += n; return *this; }
-         basic& operator-=(Cardinal n) { idx -= n; return *this; }
-         basic operator+(Cardinal n) const { return { seq, idx + n }; }
-         basic operator-(Cardinal n) const { return { seq, idx - n }; }
-         difference_type operator-(basic that) const { return idx - that.idx; }
-         
-
-         bool operator==(basic that) const { return idx == that.idx; }
-         bool operator<(basic that) const { return idx < that.idx; }
-         
-      private:
-         friend Seq;
-         const Seq* seq;
-         Ordinal idx;
-         constexpr basic(const Seq* s, Cardinal i) : seq(s), idx(i) { }
-      };
-   }
-}
-
-
-#endif  // OPENAXIOM_ITERATOR_included
-
diff --git a/src/include/open-axiom/Charset b/src/include/open-axiom/Charset
new file mode 100644
index 00000000..58fa9ea8
--- /dev/null
+++ b/src/include/open-axiom/Charset
@@ -0,0 +1,49 @@
+// -*- C++ -*-
+// Copyright (C) 2013, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom, nor the names of its contributors may
+//       be used to endorse or promote products derived from this software
+//       without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_CHARSET_included
+#define OPENAXIOM_CHARSET_included
+
+#include <stdint.h>
+
+namespace OpenAxiom {
+   // Code point value of a UCS member.
+   using Codepoint = uint32_t;
+
+   // Unicode character type.
+   enum class Character : Codepoint {
+      NUL = Codepoint()         // The NUL character 
+   };
+}
+
+#endif  // OPENAXIOM_CHARSET_included
diff --git a/src/include/open-axiom/Constructor b/src/include/open-axiom/Constructor
new file mode 100644
index 00000000..bfab3940
--- /dev/null
+++ b/src/include/open-axiom/Constructor
@@ -0,0 +1,80 @@
+// Copyright (C) 2013, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom. nor the names of its contributors
+//       may be used to endorse or promote products derived from this
+//       software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_CONSTRUCTOR_included
+#define OPENAXIOM_CONSTRUCTOR_included
+
+#include <open-axiom/string-pool>
+
+namespace OpenAxiom {
+   namespace VM {
+      // -- identifier
+      using Identifier = String;
+
+      // -- A constructor kind.
+      enum class ConstructorKind { category, domain, package };
+      
+      // -- Data structure for a constructor.
+      struct Constructor {
+         Identifier name;
+         Identifier abbrev;
+         String source_file;
+         String object_file;
+         ConstructorKind kind;
+      };
+   }
+}
+
+// -- specialize helper function objects
+namespace std {
+   template<>
+   struct hash<OpenAxiom::VM::Constructor> {
+      using H = hash<OpenAxiom::VM::Identifier>;
+      H::result_type operator()(const Constructor& c) const {
+         return h(c.name);
+      }
+
+      H h;
+   };
+
+   template<>
+   struct equal_to<OpenAxiom::VM::Constructor> {
+      using E = equal_to<OpenAxiom::VM::Identifier>;
+      using arg_type = OpenAxiom::VM::Constructor;
+      bool operator()(const arg_type& x, const arg_type& y) const {
+         return e(x.name, y.name);
+      }
+      E e;
+   };
+}
+
+#endif  // OPENAXIOM_CONSTRUCTOR_included
diff --git a/src/include/open-axiom/Database b/src/include/open-axiom/Database
new file mode 100644
index 00000000..cea082c8
--- /dev/null
+++ b/src/include/open-axiom/Database
@@ -0,0 +1,54 @@
+// Copyright (C) 2013, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom. nor the names of its contributors
+//       may be used to endorse or promote products derived from this
+//       software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_DATABASE_included
+#define OPENAXIOM_DATABASE_included
+
+#include <open-axiom/FileMapping>
+#include <open-axiom/sexpr>
+#include <open-axiom/Lisp>
+
+namespace OpenAxiom {
+   namespace VM {
+      struct Database {
+         explicit Database(const std::string&);
+         Value find_with(Value, Lisp::Evaluator&);
+      private:
+         Memory::FileMapping file;
+         Sexpr::Reader reader;
+         Pair toc;
+         std::map<Value, Value> dict;
+      };
+   }
+}
+
+#endif  // OPENAXIOM_DATABASE_included
diff --git a/src/include/open-axiom/FileMapping b/src/include/open-axiom/FileMapping
new file mode 100644
index 00000000..0c836efb
--- /dev/null
+++ b/src/include/open-axiom/FileMapping
@@ -0,0 +1,66 @@
+// -*- C++ -*-
+// Copyright (C) 2010-2014, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom. nor the names of its contributors
+//       may be used to endorse or promote products derived from this
+//       software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// --% Author: Gabriel Dos Reis
+// --% Description:
+// --%   Provide random access read to files through file mapping.
+
+#ifndef OPENAXIOM_FILEMAPPING_included
+#define OPENAXIOM_FILEMAPPING_included
+
+#include <open-axiom/storage>
+
+namespace OpenAxiom {
+   namespace Memory {
+      // -----------------
+      // -- FileMapping --
+      // -----------------
+      struct FileMapping {
+         explicit FileMapping(std::string);
+         FileMapping(FileMapping&&);
+         ~FileMapping();
+         const Byte* begin() const { return start; }
+         const Byte* end() const { return begin() + extent; }
+         std::size_t size() const { return extent; }
+      protected:
+         Byte* start;           // address at the mapped storage
+         size_t extent;         // length (in bytes) of the storage
+      private:
+         FileMapping(const FileMapping&) = delete;
+         FileMapping& operator=(const FileMapping&) = delete;
+      };
+   }      
+}
+
+#endif  // OPENAXIOM_FILEMAPPING_included
+
diff --git a/src/include/open-axiom/Input b/src/include/open-axiom/Input
new file mode 100644
index 00000000..fa4555b8
--- /dev/null
+++ b/src/include/open-axiom/Input
@@ -0,0 +1,108 @@
+// -*- C++ -*-
+// Copyright (C) 2013, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom, nor the names of its contributors may
+//       be used to endorse or promote products derived from this software
+//       without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_INPUT_included
+#define OPENAXIOM_INPUT_included
+
+#include <iterator>
+#include <string>
+#include <vector>
+#include "open-axiom.h"
+#include <open-axiom/structure>
+#include <open-axiom/iterator>
+
+namespace OpenAxiom {
+   namespace Input {
+      // -- Input text data
+      using Text = std::string;
+
+      // -- Type of Thingies that iterate over text values
+      using TextIterator = Text::const_iterator;
+
+      // -- Position of an input source line.
+      using LineNumber = Ordinal;
+      
+      // -- We keep info only for non-empty input lines.
+      struct NonEmptyLine : private structure::binary<LineNumber, Text> {
+         NonEmptyLine(LineNumber, const Text&);
+         LineNumber number() const { return first(); }
+         const Text& text() const { return second(); }
+         TextIterator begin() const { return text().begin(); }
+         TextIterator end() const { return text().end(); }
+         std::size_t size() const { return text().size(); }
+      };
+
+      struct Source;
+      // -- Index into input source lines --
+      using Index = std::size_t;
+
+      // -- Line --
+      struct Line : private structure::binary<const Source*, Index> {
+         using value_type = Text::value_type;
+         using const_reference = Text::const_reference;
+         using const_pointer = Text::const_pointer;
+         using difference_type = Text::difference_type;
+         using iterator = iterator::basic<Line>;
+         const NonEmptyLine& get() const;
+         const Text& text() const { return get().text(); }
+         LineNumber number() const { return get().number(); }
+         iterator begin() const { return { this, 0 }; }
+         iterator end() const { return { this, size() }; }
+         Cardinal size() const { return text().size(); }
+         const_reference at(Ordinal n) const { return text().at(n); }
+      private:
+         constexpr Line(const Source* s, Index i)
+               : structure::binary<const Source*, Index>(s, i)
+         { }
+         const Source* source() const { return first(); }
+         Index index() const { return second(); }
+         
+         friend Source;
+      };
+
+      // -- LineIterator --
+      using LineIterator = Line::iterator;
+
+      // -- Source --
+      struct Source : std::vector<NonEmptyLine> {
+         using iterator = OpenAxiom::iterator::basic<Source>;
+         using Index = Ordinal; // line index
+         Line line(Index i) const { return { this, i }; }
+         iterator begin() const { return { this, 0 }; }
+         iterator end() const { return { this, size() }; }
+         Line line(LineNumber, const Text&);
+      };
+   }
+}
+
+#endif  // OPENAXIOM_INPUT_included
diff --git a/src/include/open-axiom/InputFragment b/src/include/open-axiom/InputFragment
new file mode 100644
index 00000000..7f317973
--- /dev/null
+++ b/src/include/open-axiom/InputFragment
@@ -0,0 +1,90 @@
+// -*- C++ -*-
+// Copyright (C) 2014, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom. nor the names of its contributors
+//       may be used to endorse or promote products derived from this
+//       software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// --% Author: Gabriel Dos Reis
+
+#ifndef OPENAXIOM_INPUTFRAGMENT_included
+#define OPENAXIOM_INPUTFRAGMENT_included
+
+#include <open-axiom/token>
+
+namespace OpenAxiom {
+   // A physical line is just raw text, coupled with location
+   // information such as line and indentation column.
+   struct Line : std::string {
+      LineNumber number;
+      ColumnIndex indent;
+      Line() : number(), indent() { }
+      
+      std::string sub_string(ColumnIndex s, ColumnIndex e) const {
+         return substr(s, e - s);
+      }
+   };
+
+   // A program fragment is a logical line, composed of possibly
+   // several physical lines subject to the off-side rule.  As a
+   // special case, a line ending with the underbar character
+   // continues to the next line with disregard to the off-side rule.
+   struct Fragment : std::vector<Line> {
+      explicit operator bool() const { return not empty(); }
+      // Holds if the last physical line ends with line continuation marker.
+      bool line_continuation() const {
+         return not empty() and back().back() == '_';
+      }
+      // Return the indentation of the last physical line of this fragment.
+      ColumnIndex last_indent() const {
+         return empty() ? 0 : back().indent;
+      }
+      using std::vector<Line>::operator[];
+      // Reference a line given by a position into this fragment.
+      const Line& operator()(const OpenAxiom::FragmentCursor& pos) const {
+         return (*this)[pos.line];
+      }
+      // Reference a character code unit at the position into this fragment.
+      uint8_t operator[](const OpenAxiom::FragmentCursor& pos) const {
+         return (*this)[pos.line][pos.column];
+      }
+      // Advance the cursor position to the next character code unit.
+      uint8_t advance(OpenAxiom::FragmentCursor& pos) const {
+         return (*this)[pos.line][pos.column++];
+      }
+      // This predicate holds if this fragment covers the cursor position.
+      bool covering(const OpenAxiom::FragmentCursor& pos) const {
+         return pos.column < (*this)[pos.line].size();
+      }
+   };
+
+   std::ostream& operator<<(std::ostream&, const Fragment&);
+}
+
+#endif  // OPENAXIOM_INPUTFRAGMENT_included
diff --git a/src/include/open-axiom/Lisp b/src/include/open-axiom/Lisp
new file mode 100644
index 00000000..a189dd38
--- /dev/null
+++ b/src/include/open-axiom/Lisp
@@ -0,0 +1,128 @@
+// Copyright (C) 2013-2014, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom nor the names of its contributors
+//       may be used to endorse or promote products derived from this
+//       software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// --% Author: Gabriel Dos Reis
+// --% Abstract:
+// --%    Very simple support for some core Lisp-like operations.
+
+#ifndef OPENAXIOM_LISP_included
+#define OPENAXIOM_LISP_included
+
+#include <list>
+#include <open-axiom/sexpr>
+#include <open-axiom/vm>
+#include <map>
+#include <open-axiom/diagnostics>
+#include <iosfwd>
+#include <unordered_set>
+
+namespace std {
+   template<>
+   struct hash<OpenAxiom::VM::Package>  {
+      hash<OpenAxiom::VM::String>::result_type
+      operator()(const OpenAxiom::VM::Package& s) const {
+         return h(s.name);
+      }
+      hash<OpenAxiom::VM::String> h;
+   };
+
+   template<>
+   struct equal_to<OpenAxiom::VM::Package> {
+      using arg_type = OpenAxiom::VM::Package;
+      bool operator()(const arg_type& x, const arg_type& y) const {
+         constexpr equal_to<OpenAxiom::VM::String> eq { };
+         return eq(x.name, y.name);
+      }
+   };
+}
+
+namespace OpenAxiom {
+   namespace Lisp {
+      using namespace VM;
+
+      // -- Unimplemented features
+      struct Unimplemented : Diagnostics::BasicError {
+         explicit Unimplemented(const std::string&);
+      };
+
+      // -- Integer overflow
+      struct IntegerOverflow : Diagnostics::BasicError {
+         explicit IntegerOverflow(const std::string&);
+      };
+
+      // -- Unbound symbol
+      struct UnboundSymbol : Diagnostics::BasicError {
+         explicit UnboundSymbol(const std::string&);
+      };
+
+      // -- Unbound functiom symbol
+      struct UnboundFunctionSymbol : Diagnostics::BasicError {
+         explicit UnboundFunctionSymbol(const std::string&);
+      };
+      
+      // -- Anchor maps
+      using AnchorTable = std::map<Ordinal, Value>;
+
+      // -- Evaluator --
+      struct Evaluator : VM::BasicContext {
+         Evaluator();
+         Value eval(const Sexpr::Syntax*);
+         Package* core_package() { return core; }
+         Package* current_package() { return ns; }
+         Value toplevel_form(const Sexpr::Syntax*);
+         Value make_value(const Sexpr::Syntax*);
+         Value* lexical_binding(String);
+         Environment* global_environment();
+      private:
+         Package* core;
+         Package* ns;
+         Symbol* feature_list;
+         std::list<Environment> env_stack;
+         AnchorTable anchor_map;
+      };
+
+      // -- Format a value onto an output stream.
+      void format(Value, std::ostream&);
+      std::string show(Value);
+
+      // -- Retracts
+      Fixnum retract_to_fixnum(Value);
+      Pair retract_to_pair(Value);
+      Symbol* retract_to_symbol(Value);
+
+      // -- Alist functions
+      Value assoc(Value, Pair);
+   }
+}
+
+#endif  // OPENAXIOM_LISP_included
+
diff --git a/src/include/open-axiom/SourceFile b/src/include/open-axiom/SourceFile
new file mode 100644
index 00000000..41b085a3
--- /dev/null
+++ b/src/include/open-axiom/SourceFile
@@ -0,0 +1,53 @@
+// -*- C++ -*-
+// Copyright (C) 2013, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom, nor the names of its contributors may
+//       be used to endorse or promote products derived from this software
+//       without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_SOURCEFILE_included
+#define OPENAXIOM_SOURCEFILE_included
+
+#include <open-axiom/FileMapping>
+
+namespace OpenAxiom {
+   namespace Input {
+      // -- SourceFile --
+      struct SourceFile : Memory::FileMapping {
+         explicit SourceFile(const std::string&);
+         const std::string& pathname() const { return path; }
+      private:
+         std::string path;
+         SourceFile(const SourceFile&) = delete;
+         SourceFile& operator=(const SourceFile&) = delete;
+      }
+   }
+}
+
+#endif  // OPENAXIOM_SOURCEFILE_included
diff --git a/src/include/open-axiom/defaults b/src/include/open-axiom/defaults
new file mode 100644
index 00000000..db399419
--- /dev/null
+++ b/src/include/open-axiom/defaults
@@ -0,0 +1,64 @@
+// -*- C++ -*-
+// Copyright (C) 2013, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom, nor the names of its contributors may
+//       be used to endorse or promote products derived from this software
+//       without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_DEFAULTS_included
+#define OPENAXIOM_DEFAULTS_included
+
+namespace OpenAxiom {
+   // -- The sole purpose of classes defines in this header is to
+   // -- provoke the automatic generation of definitions for functions
+   // -- defined within.  These functions are not really friend.  The
+   // -- friendship is such a mechanism to convince the C++ compiler
+   // -- to do something else.  This is standard technique, also
+   // -- known as `based class parameterized by derived classes', or
+   // -- `curiously recurring pattern'.
+   namespace defaults {
+      // generate definition for != assuming existence of ==.
+      template<typename t>
+      struct neq {
+         friend bool operator!=(t x, t y) { return not(x == y); }
+      };
+
+      // generate definitions for ordering functions assuming <.
+      template<typename t>
+      struct ordering {
+         friend bool operator<=(t x, t y) { return not(y < x); }
+         friend bool operator>(t x, t y) { return y < x; }
+         friend bool operator>=(t x, t y) { return not(x < y); }
+      };
+   }
+}
+
+#endif  // OPENAXIOM_DEFAULTS_included
+
+
diff --git a/src/include/open-axiom/diagnostics b/src/include/open-axiom/diagnostics
new file mode 100644
index 00000000..9cb0fce1
--- /dev/null
+++ b/src/include/open-axiom/diagnostics
@@ -0,0 +1,63 @@
+// Copyright (C) 2013, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom. nor the names of its contributors
+//       may be used to endorse or promote products derived from this
+//       software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_DIAGNOSTICS_included
+#define OPENAXIOM_DIAGNOSTICS_included
+
+#include <string>
+#include <iostream>
+
+namespace OpenAxiom {
+   namespace Diagnostics {
+      struct StandardStream {
+         StandardStream(std::ostream& = std::cout, std::ostream& = std::cerr);
+         ~StandardStream();
+
+         std::ostream& output() const { return *out; }
+         std::ostream& error() const { return *err; }
+         std::ostream& set_output(std::ostream&);
+         std::ostream& set_error(std::ostream&);
+      private:
+         std::ostream* out;
+         std::ostream* err;
+      };
+      
+      struct BasicError {
+         explicit BasicError(const std::string& s) : msg(s) { }
+         const std::string& message() const { return msg; }
+      protected:
+         std::string msg;
+      };
+   }
+}
+
+#endif
diff --git a/src/include/open-axiom/dialect b/src/include/open-axiom/dialect
new file mode 100644
index 00000000..bcfddd04
--- /dev/null
+++ b/src/include/open-axiom/dialect
@@ -0,0 +1,47 @@
+// Copyright (C) 2013-2014, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom. nor the names of its contributors
+//       may be used to endorse or promote products derived from this
+//       software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_DIALECT_included
+#define OPENAXIOM_DIALECT_included
+
+namespace OpenAxiom {
+   // Languages for which we have parsers.
+   enum class Language {
+      Spad = 0x1,
+      Boot = 0x2,
+      Lisp = 0x4,
+      BootSpad = Spad | Boot,
+      All = Spad | Boot | Lisp,
+   };
+}
+
+#endif  // OPENAXIOM_DIALECT_included
diff --git a/src/include/open-axiom/hash-table b/src/include/open-axiom/hash-table
new file mode 100644
index 00000000..d74c7760
--- /dev/null
+++ b/src/include/open-axiom/hash-table
@@ -0,0 +1,85 @@
+// Copyright (C) 2010, Gabriel Dos Reis.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of The Numerical Algorithms Group Ltd. nor the
+//       names of its contributors may be used to endorse or promote products
+//       derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_HASH_TABLE_INCLUDED
+#define OPENAXIOM_HASH_TABLE_INCLUDED
+
+// --% Author: Gabriel Dos Reis.
+// --% Description:
+// --%   Simple hash table facility.  To be replaced by C++0x
+// --%   hash tables when C++0x compilers become common place.
+
+#include <open-axiom/storage>
+
+namespace OpenAxiom {
+   // --------------------
+   // -- HashTableEntry --
+   // --------------------
+   // Datatype for entries in a parameterized hash table.
+   // The type parameter is required to be a value-construcitble datatype.
+   // A table bucket entry is required to be at least 8-byte aligned
+   // so that an instance of it can be used directly as a VM value.
+   // See <open-axiom/vm> for more description.
+   template<typename T>
+   struct alignas(8) HashTableEntry : T {
+      HashTableEntry* chain;   // previous item in the same bucket chain
+      size_t hash;             // hash code of stored data
+   };
+
+   // --------------------
+   // -- BasicHashTable --
+   // --------------------
+   // A simple hash table data structure.  Ideally, we would like to use
+   // standard C++ types, but hash tables were only in a C++ 2003 TR,
+   // officially part of C++0x standard library.  We still don't have
+   // wide-spread C++0x compilers.
+   template<typename T>
+   struct BasicHashTable : private Memory::Arena<HashTableEntry<T> > {
+      typedef HashTableEntry<T> EntryType;
+      explicit BasicHashTable(size_t n)
+            : Memory::Arena<HashTableEntry<T> >(n),
+              buckets(this->allocate(n)), nbuckets(n) { }
+
+      EntryType* hash_chain(size_t h) const {
+         return buckets + (h % nbuckets);
+      }
+
+      EntryType* new_bucket() {
+         return this->allocate(1);
+      }
+
+   private:
+      HashTableEntry<T>* const buckets;
+      const size_t nbuckets;
+   };
+}
+
+#endif  // OPENAXIOM_HASH_TABLE_INCLUDED
diff --git a/src/include/open-axiom/iterator b/src/include/open-axiom/iterator
new file mode 100644
index 00000000..048dc67c
--- /dev/null
+++ b/src/include/open-axiom/iterator
@@ -0,0 +1,83 @@
+// -*- C++ -*-
+// Copyright (C) 2013, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom, nor the names of its contributors may
+//       be used to endorse or promote products derived from this software
+//       without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_ITERATOR_included
+#define OPENAXIOM_ITERATOR_included
+
+#include <iterator>
+#include <open-axiom/defaults>
+#include "open-axiom.h"
+
+namespace OpenAxiom {
+   // -- Read-only iterator over a sequence with random access capabilities.
+   namespace iterator {
+      template<typename Seq>
+      struct basic
+         : std::iterator<std::random_access_iterator_tag,
+                         const typename Seq::value_type>,
+         defaults::neq<basic<Seq>>, defaults::ordering<basic<Seq>> {
+         using reference = typename Seq::const_reference;
+         using pointer = typename Seq::const_pointer;
+         using difference_type = typename Seq::difference_type;
+
+         reference operator*() const { return seq->at(idx); }
+         pointer operator->() const { return &seq->at(idx); }
+         reference operator[](Ordinal i) const { return seq->at(idx + i); }
+
+         basic& operator++() { ++idx; return *this; }
+         basic operator++(int) { auto t = *this; ++idx; return t; }
+         basic& operator--() { --idx; return *this; }
+         basic operator--(int) { auto t = *this; --idx; return t; }
+
+         basic& operator+=(Cardinal n) { idx += n; return *this; }
+         basic& operator-=(Cardinal n) { idx -= n; return *this; }
+         basic operator+(Cardinal n) const { return { seq, idx + n }; }
+         basic operator-(Cardinal n) const { return { seq, idx - n }; }
+         difference_type operator-(basic that) const { return idx - that.idx; }
+         
+
+         bool operator==(basic that) const { return idx == that.idx; }
+         bool operator<(basic that) const { return idx < that.idx; }
+         
+      private:
+         friend Seq;
+         const Seq* seq;
+         Ordinal idx;
+         constexpr basic(const Seq* s, Cardinal i) : seq(s), idx(i) { }
+      };
+   }
+}
+
+
+#endif  // OPENAXIOM_ITERATOR_included
+
diff --git a/src/include/open-axiom/sexpr b/src/include/open-axiom/sexpr
new file mode 100644
index 00000000..6920e436
--- /dev/null
+++ b/src/include/open-axiom/sexpr
@@ -0,0 +1,419 @@
+// Copyright (C) 2010-2014, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of The Numerical Algorithms Group Ltd. nor the
+//       names of its contributors may be used to endorse or promote products
+//       derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_SEXPR_included
+#define OPENAXIOM_SEXPR_included
+
+// --% Author: Gabriel Dos Reis.
+// --% Description:
+// --%   A simple support for s-expressions.  By design, no ambition
+// --%   for full-fledged Common Lisp reader capability.  Rather,
+// --%   the aim is a simple data structure for exchanging data
+// --%   between several components of the OpenAxiom system.
+// --%   Users interested in fullblown Lisp syntax should seek
+// --%   to acquire Lisp systems, many of which are freely available.
+
+#include <iosfwd>
+#include <vector>
+#include <open-axiom/storage>
+#include <open-axiom/token>
+
+namespace OpenAxiom {
+   namespace Sexpr {
+      // ------------
+      // -- Lexeme --
+      // ------------
+      struct Lexeme {
+         enum Type {
+            unknown,                 // unidentified token
+            semicolon,               // ";" for comment
+            dot,                     // "."
+            comma,                   // ","
+            open_paren,              // "("
+            close_paren,             // ")"
+            apostrophe,              // "'"
+            backquote,               // "`"
+            backslash,               // "\\"
+            sharp_open_paren ,       // "#("
+            sharp_apostrophe,        // "#'"
+            sharp_colon,             // "#:"
+            sharp_plus,              // "#+"
+            sharp_minus,             // "#-"
+            sharp_dot,               // "#."
+            comma_at,                // ",@"
+            integer,                 // integer literal
+            character,               // character literal
+            string,                  // string literal
+            identifier,              // plain identifier
+            sharp_integer_equal,     // anchor definition, #n=<form>
+            sharp_integer_sharp      // back reference, #n#
+         };
+
+         std::pair<const Byte*, const Byte*> boundary;
+         Ordinal line;
+         const Byte* begin() const { return boundary.first; }
+         const Byte* end() const { return boundary.second; }
+         Ordinal size() const { return end() - begin(); }
+      };
+
+      // ------------
+      // -- Syntax --
+      // ------------
+      // Base class of syntax object classes.
+      struct Syntax {
+         struct Visitor;        // base class of syntax visitors
+         virtual void accept(Visitor&) const = 0;
+      };
+
+      // ----------------
+      // -- AtomSyntax --
+      // ----------------
+      // An atom is a syntax object consisting of exatly one token.
+      // This should not be confused with the notion of atom
+      // in Lisp languages. 
+      struct AtomSyntax : Syntax {
+         const Lexeme& lexeme() const { return lex; }
+      protected:
+         Lexeme lex;
+         explicit AtomSyntax(const Lexeme&);
+      };
+
+      // -------------------
+      // -- IntegerSyntax --
+      // -------------------
+      // Integer literal syntax objects
+      struct IntegerSyntax : AtomSyntax {
+         explicit IntegerSyntax(const Lexeme&);
+         void accept(Visitor&) const;
+      };
+
+      // ---------------------
+      // -- CharacterSyntax --
+      // ---------------------
+      // Character literal syntax objects.
+      struct CharacterSyntax : AtomSyntax {
+         explicit CharacterSyntax(const Lexeme&);
+         void accept(Visitor&) const;
+      };
+
+      // ------------------
+      // -- StringSyntax --
+      // ------------------
+      // Striing literal syntax objjects.
+      struct StringSyntax : AtomSyntax {
+         explicit StringSyntax(const Lexeme&);
+         void accept(Visitor&) const;
+      };
+
+      // ------------------
+      // -- SymbolSyntax --
+      // ------------------
+      struct SymbolSyntax : AtomSyntax {
+         enum Kind {
+            ordinary   = 0x0,   // an interned symbol
+            uninterned = 0x1,   // uninterned symbol
+            absolute   = 0x2,   // case-sensitive symbol
+            keyword    = 0x4,   // a keyword symbol
+         };
+         SymbolSyntax(const Lexeme&, Kind);
+         Kind kind() const { return sort; }
+         const Byte* begin() const { return lexeme().begin(); }
+         const Byte* end() const { return lexeme().end(); }
+         std::size_t size() const { return lexeme().size(); }
+         Byte operator[](std::size_t i) const { return begin()[i]; }
+         void accept(Visitor&) const;
+      private:
+         const Kind sort;
+      };
+
+      // ---------------------
+      // -- ReferenceSyntax --
+      // ---------------------
+      // Back reference object to a syntax object.
+      struct ReferenceSyntax : AtomSyntax {
+         ReferenceSyntax(const Lexeme&, Ordinal);
+         size_t tag() const { return pos; }
+         void accept(Visitor&) const;
+      private:
+         Ordinal pos;
+      };
+
+      // ------------------
+      // -- AnchorSyntax --
+      // ------------------
+      // Base anchor syntax object.
+      struct AnchorSyntax : Syntax {
+         AnchorSyntax(size_t, const Syntax*);
+         size_t ref() const { return tag; }
+         const Syntax* value() const { return val; }
+         void accept(Visitor&) const;
+      private:
+         const size_t tag;
+         const Syntax* const val;
+      };
+
+      // -- Abstract over common implementation of unary special operators.
+      template<typename T>
+      struct unary_form : Syntax {
+         const Syntax* body() const { return form; }
+         void accept(Visitor&) const;
+      protected:
+         unary_form(const Syntax* f) : form(f) { }
+      private:
+         const Syntax* const form;
+      };
+
+      template<typename T>
+      struct binary_form : Syntax {
+         const Syntax* first() const { return rep.first; }
+         const Syntax* second() const { return rep.second; }
+         void accept(Visitor&) const;
+      protected:
+         binary_form(const Syntax* f, const Syntax* s) : rep(f, s) { }
+      private:
+         std::pair<const Syntax*, const Syntax*> rep;
+      };
+
+      // -----------------
+      // -- QuoteSyntax --
+      // -----------------
+      // Quotation syntax object.
+      struct QuoteSyntax : unary_form<QuoteSyntax> {
+         explicit QuoteSyntax(const Syntax*);
+      };
+      
+      // ---------------------
+      // -- AntiquoteSyntax --
+      // ---------------------
+      // Quasi-quotation syntax object.
+      struct AntiquoteSyntax : unary_form<AntiquoteSyntax> {
+         explicit AntiquoteSyntax(const Syntax*);
+      };
+      
+      // ------------
+      // -- Expand --
+      // ------------
+      // Expansion request inside a quasi-quotation.
+      struct Expand : unary_form<Expand> {
+         explicit Expand(const Syntax*);
+      };
+      
+      // ----------
+      // -- Eval --
+      // ----------
+      // Read-time evaluation request syntax object.
+      struct Eval : unary_form<Eval> {
+         explicit Eval(const Syntax*);
+      };
+      
+      // ------------
+      // -- Splice --
+      // ------------
+      // Splice request syntax object inside a quasi-quotation.
+      struct Splice : unary_form<Splice> {
+         explicit Splice(const Syntax*);
+      };
+      
+      // --------------
+      // -- Function --
+      // --------------
+      // Function literal syntax object.
+      struct Function : unary_form<Function> {
+         explicit Function(const Syntax*);
+      };
+
+      // -------------
+      // -- Include --
+      // -------------
+      // Conditional inclusion syntax object
+      struct Include : binary_form<Include> {
+         Include(const Syntax*, const Syntax*);
+      };
+
+      // -------------
+      // -- Exclude --
+      // -------------
+      // Conditional exclusion syntax object
+      struct Exclude : binary_form<Exclude> {
+         Exclude(const Syntax*, const Syntax*);
+      };
+
+      // ----------------
+      // -- ListSyntax --
+      // ----------------
+      // List syntax objects.
+      struct ListSyntax : Syntax, private std::vector<const Syntax*> {
+         typedef std::vector<const Syntax*> base;
+         using base::const_iterator;
+         using base::begin;
+         using base::end;
+         using base::rbegin;
+         using base::rend;
+         using base::size;
+         using base::empty;
+         using base::front;
+
+         ListSyntax();
+         ListSyntax(const base&, bool);
+         ~ListSyntax();
+         void accept(Visitor&) const;
+         bool dotted() const { return dot; }
+      private:
+         bool dot;
+      };
+      
+      // ------------------
+      // -- VectorSyntax --
+      // ------------------
+      // VectorSyntax syntax objects.
+      struct VectorSyntax : Syntax, private std::vector<const Syntax*> {
+         typedef std::vector<const Syntax*> base;
+         using base::const_iterator;
+         using base::begin;
+         using base::end;
+         using base::size;
+         using base::operator[];
+         using base::empty;
+
+         VectorSyntax();
+         explicit VectorSyntax(const base&);
+         ~VectorSyntax();
+         void accept(Visitor&) const;
+      };
+
+      // ---------------------
+      // -- Syntax::Visitor --
+      // ---------------------
+      struct Syntax::Visitor {
+         virtual void visit(const IntegerSyntax&) = 0;
+         virtual void visit(const CharacterSyntax&) = 0;
+         virtual void visit(const StringSyntax&) = 0;
+         virtual void visit(const SymbolSyntax&) = 0;
+         virtual void visit(const ReferenceSyntax&) = 0;
+         virtual void visit(const AnchorSyntax&) = 0;
+         virtual void visit(const QuoteSyntax&) = 0;
+         virtual void visit(const AntiquoteSyntax&) = 0;
+         virtual void visit(const Expand&) = 0;
+         virtual void visit(const Eval&) = 0;
+         virtual void visit(const Splice&) = 0;
+         virtual void visit(const Function&) = 0;
+         virtual void visit(const Include&) = 0;
+         virtual void visit(const Exclude&) = 0;
+         virtual void visit(const ListSyntax&) = 0;
+         virtual void visit(const VectorSyntax&) = 0;
+      };
+
+      template<typename T>
+      void
+      unary_form<T>::accept(Visitor& v) const {
+         v.visit(static_cast<const T&>(*this));
+      }
+
+      template<typename T>
+      void
+      binary_form<T>::accept(Visitor& v) const {
+         v.visit(static_cast<const T&>(*this));
+      }
+
+      // ---------------
+      // -- Allocator --
+      // ---------------
+      // Allocator of syntax objects.
+      struct Allocator {
+         Allocator();
+         ~Allocator();
+
+         const IntegerSyntax* make_integer(const Lexeme&);
+         const CharacterSyntax* make_character(const Lexeme&);
+         const StringSyntax* make_string(const Lexeme&);
+         const SymbolSyntax* make_symbol(SymbolSyntax::Kind, const Lexeme&);
+         const ReferenceSyntax* make_reference(size_t, const Lexeme&);
+         const AnchorSyntax* make_anchor(size_t, const Syntax*);
+         const QuoteSyntax* make_quote(const Syntax*);
+         const AntiquoteSyntax* make_antiquote(const Syntax*);
+         const Expand* make_expand(const Syntax*);
+         const Eval* make_eval(const Syntax*);
+         const Splice* make_splice(const Syntax*);
+         const Function* make_function(const Syntax*);
+         const Include* make_include(const Syntax*, const Syntax*);
+         const Exclude* make_exclude(const Syntax*, const Syntax*);
+         const ListSyntax* make_list(const std::vector<const Syntax*>&, bool = false);
+         const VectorSyntax* make_vector(const std::vector<const Syntax*>&);
+         
+      private:
+         Memory::Factory<IntegerSyntax> ints;
+         Memory::Factory<CharacterSyntax> chars;
+         Memory::Factory<StringSyntax> strs;
+         Memory::Factory<SymbolSyntax> syms;
+         Memory::Factory<AnchorSyntax> ancs;
+         Memory::Factory<ReferenceSyntax> refs;
+         Memory::Factory<QuoteSyntax> quotes;
+         Memory::Factory<AntiquoteSyntax> antis;
+         Memory::Factory<Expand> exps;
+         Memory::Factory<Function> funs;
+         Memory::Factory<Include> incs;
+         Memory::Factory<Exclude> excs;
+         Memory::Factory<Eval> evls;
+         Memory::Factory<Splice> spls;
+         Memory::Factory<ListSyntax> lists;
+         Memory::Factory<VectorSyntax> vectors;
+         ListSyntax empty_list;
+         VectorSyntax empty_vector;
+      };
+
+      // -- Reader --
+      struct RawInput {
+         const Byte* start;
+         const Byte* end;
+         Ordinal lineno;
+      };
+
+      struct Reader {
+         struct State {
+            RawInput bytes;
+            const Byte* cur;
+            const Byte* line;
+            Allocator alloc;
+         };
+
+         explicit Reader(const RawInput&);
+         Reader(const Byte*, const Byte*);
+         const Byte* position(Ordinal);
+         bool at_start() const { return st.cur == st.bytes.start; }
+         const Syntax* read();
+      private:
+         State st;
+      };
+   }
+}
+
+#endif  // OPENAXIOM_SEXPR_included
diff --git a/src/include/open-axiom/storage b/src/include/open-axiom/storage
new file mode 100644
index 00000000..e414dec2
--- /dev/null
+++ b/src/include/open-axiom/storage
@@ -0,0 +1,299 @@
+// Copyright (C) 2010-2013, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom. nor the names of its contributors
+//       may be used to endorse or promote products derived from this
+//       software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// --% Author: Gabriel Dos Reis
+// --% Description:
+// --%   Memory management facility.  Acquire raw memory directly
+// --%   from the host OS.  Provide random access read to
+// --%   files through file mapping.
+
+#ifndef OPENAXIOM_STORAGE_included
+#define OPENAXIOM_STORAGE_included
+
+#include <open-axiom/config>
+#include <stddef.h>
+#include <new>
+#include <cmath>
+#include <string>
+
+namespace OpenAxiom {
+   // Datatype for the unit of storage.
+   using Byte = unsigned char;
+
+   // -----------------
+   // -- SystemError --
+   // -----------------
+   // Objects of (type derived from) this type are used to report
+   // error orignating from the OpenAxiom core system.
+   struct SystemError {
+      explicit SystemError(const std::string&);
+      virtual ~SystemError();
+      // Return the text of the diagnostic message.
+      virtual const std::string& message() const;
+   protected:
+      const std::string text;
+   };
+
+   // Report a file system error
+   void filesystem_error(const std::string&);
+   
+   namespace Memory {
+      // Datatype for pointers to data.
+      using Pointer = void*;
+
+      // Precision of the host OS storage page unit in byte count
+      size_t page_size();
+
+      // Acquire raw memory from the host OS.
+      Pointer os_acquire_raw_memory(size_t);
+
+      // Release raw storage to the hosting OS.  The first operand must
+      // be a pointer value previously returned by `os_acquire_raw_memory'.
+      // Otherwise, the result is undefined.
+      void os_release_raw_memory(Pointer, size_t);
+
+      // Acquire `n' pages of memory storage from the host OS.
+      inline Pointer
+      acquire_raw_pages(size_t n) {
+         return os_acquire_raw_memory(n * page_size());
+      }
+
+      // Release `n' pages of storage starting the location `p'.
+      inline void
+      release_raw_pages(Pointer p, size_t n) {
+         os_release_raw_memory(p, n * page_size());
+      }
+      
+      // -------------
+      // -- Storage --
+      // -------------
+      // This class provides low-level abstractions intented for use
+      // to implement higher level storage abstractions.
+      struct Storage {
+         // Objects of this abstract datatype hold storage objects.
+         struct Handle;
+         
+         // Return the storage pointed to by the operand.  It
+         // must be a pointer value previously returned by `acquire'.
+         // Otherwise, the result is undefined.
+         static void release(Handle*);
+         
+         // Return the start address of storage area.  Clients would
+         // want to add padding bytes necessary to accomodate alignment
+         // requirements.  
+         // Note: this should not be confused with the address of
+         // the handle object.
+         static Pointer begin(Handle*);
+
+         // Courtesy conversion function from pointer to byte address.
+         static Byte* byte_address(Pointer h) {
+            return static_cast<Byte*>(h);
+         }
+
+         // Round up `n' to a multiple of `a', a power of 2.
+         static size_t
+         round_up(size_t n, size_t a) {
+            return (n + a - 1) & ~(a - 1);
+         }
+      };
+
+      // -------------------------
+      // -- SinglyLinkedStorage --
+      // -------------------------
+      // This class implements a simple single-linked list of storage
+      // objects.  Each storage object in the link is created with
+      // a specific starting alignment requirements.
+      struct SinglyLinkedStorage : Storage {
+         // Return the previous handle in the link chain.
+         static Handle*& previous(Handle*);
+      };
+
+      // -------------------------
+      // -- DoublyLinkedStorage --
+      // -------------------------
+      // Like SinglyLinkedStorage, except that the chain of storage
+      // object supports bidirectional travervsal.
+      struct DoublyLinkedStorage : Storage {
+         // Same as Storage::acquire, except that begin(h) returns an
+         // address that satisfies the alignment requirement `a'.
+         static Handle* acquire(size_t n, size_t a);
+         
+         // Return the previous handle in the link chain.
+         static Handle*& previous(Handle*);
+         
+         // Return the next handle in the link chain.
+         static Handle*& next(Handle*);
+      };
+
+      // ------------------
+      // -- BlockStorage --
+      // ------------------
+      // This class implements a simple single-linked list of block storage.
+      // Each block maintains information about the next allocatable
+      // address within that block.
+      struct BlockStorage : SinglyLinkedStorage {
+         // Same as SinglyLinkedStorage::acquire(); initialize internal
+         // bookkeepking machinery.
+         static Handle* acquire(size_t n, size_t a);
+
+         // Return the next allocatable address within the given block.
+         static Pointer next_address(Handle*);
+
+         // Return the amount of allocatable byte in the given block.
+         static size_t room(Handle*);
+
+         // Set `n' bytes aside with the given storage block.
+         static Pointer book(Handle*, size_t);
+      };
+
+      // -----------
+      // -- Arena --
+      // -----------
+      // Extensible storage holding objects of a given type.
+      // The totality of all objects held in such a storage does not
+      // necessarily constitute a contiguous block.  However,
+      // it is guaranteed that objects allocated in a single call
+      // to `allocate()' occupy a contiguous block of storage.
+      template<typename T>
+      struct Arena : protected BlockStorage {
+         // Acquire storage capable of holding `n' objects of type `T'.
+         explicit Arena(size_t);
+         // Release all storage acquired by this object, upon end of life.
+         ~Arena();
+         // allocate storage for `n' more objects of type `T'.
+         T* allocate(size_t);
+         // Number of objects of type `T' allocated in this storage.
+         size_t population() const;
+
+      protected:
+         // Address of the first object of type `T' in a storage.
+         static T* first_object(Handle* h) {
+            return static_cast<T*>(BlockStorage::begin(h));
+         }
+
+         // Address of one-past-the-end object of type `T' in this storage.
+         static T* last_object(Handle* h) {
+            return static_cast<T*>(BlockStorage::next_address(h));
+         }
+
+         // Number of objects allocated in a storage.
+         static size_t object_count(Handle* h) {
+            return last_object(h) - first_object(h);
+         }
+
+         BlockStorage::Handle* store; // active storage to allocate from
+      };
+
+      template<typename T>
+      size_t
+      Arena<T>::population() const {
+         size_t n = 0;
+         for (Handle* h = store; h != nullptr; h = previous(h))
+            n += object_count(h);
+         return n;
+      }
+
+      template<typename T>
+      T*
+      Arena<T>::allocate(size_t n) {
+         const size_t sz = n * sizeof(T);
+         if (BlockStorage::room(store) < sz) {
+            // Not enough room left.  Make sure we allocate storage
+            // at least as big as the current.
+            Handle* h = acquire(std::max(n, object_count(store)), alignof(T));
+            previous(h) = store;
+            store = h;
+         }
+         return static_cast<T*>(BlockStorage::book(store, sz));
+      }
+
+      template<typename T>
+      Arena<T>::Arena(size_t n)
+            : store(BlockStorage::acquire(n * sizeof (T), alignof (T)))
+      { }
+      
+      template<typename T>
+      Arena<T>::~Arena() {
+         // Release storage in the reverse order of their
+         // their allocation.
+         while (store != nullptr) {
+            Handle* current = store;
+            store = BlockStorage::previous(store);
+            BlockStorage::release(current);
+         }
+      }
+
+      // -------------
+      // -- Factory --
+      // -------------
+      template<typename T>
+      struct Factory : Arena<T> {
+         using Handler = typename Arena<T>::Handle;
+
+         Factory() : Arena<T>(nominal_population()) { }
+         ~Factory();
+
+         // Allocate storage and value-construct an object of type `T'.
+         T* make() {
+            return new(this->allocate(1)) T{ };
+         }
+
+         // Allocate storage and construct an object of type `T'.
+         template<typename... Args>
+         T* make(const Args&... args) {
+            return new(this->allocate(1)) T{args...};
+         }
+
+      private:
+         // Return 1 or the number of objects that can fit in a page unit.
+         static size_t nominal_population() {
+            const size_t psz = page_size();
+            if (sizeof (T) > psz)
+               return 1;
+            return psz / sizeof(T);
+         }
+      };
+
+      // Destroy objects in the reverse order of their construction.
+      template<typename T>
+      Factory<T>::~Factory() {
+         for (auto s = this->store; s != nullptr; s = Arena<T>::previous(s)) {
+            T* last = Arena<T>::last_object(s);
+            for (--last; last >= Arena<T>::first_object(s); --last)
+               last->~T();
+         }
+      }
+   }
+}
+
+#endif  // OPENAXIOM_STORAGE_included
+
diff --git a/src/include/open-axiom/string-pool b/src/include/open-axiom/string-pool
new file mode 100644
index 00000000..1f746e6d
--- /dev/null
+++ b/src/include/open-axiom/string-pool
@@ -0,0 +1,85 @@
+// Copyright (C) 2010-2015, Gabriel Dos Reis.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of The Numerical Algorithms Group Ltd. nor the
+//       names of its contributors may be used to endorse or promote products
+//       derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_STRING_POOL_INCLUDED
+#define OPENAXIOM_STRING_POOL_INCLUDED
+
+#include <open-axiom/hash-table>
+
+// --% Author: Gabriel Dos Reis.
+// --% Description:
+// --%   Basic persistent string facility.
+// --%   A stringpool for allocating long-living string objects.
+
+namespace OpenAxiom {
+   struct StringPool;
+
+   // ----------------
+   // -- StringItem --
+   // ----------------
+   // String data allocated from a stringpool.
+   struct StringItem {
+      const Byte* begin() const { return text; }
+      const Byte* end() const { return text + length; }
+      size_t size() const { return length; }
+      bool equal(const Byte*, size_t) const;
+   protected:
+      const Byte* text;         // pointer to the byte sequence
+      size_t length;            // number of bytes in this string
+      friend StringPool;
+      StringItem() : text(), length() { }
+   };
+
+   // ----------------
+   // -- StringPool --
+   // ----------------
+   // A string-pool object is a repository of long-living string objects.
+   // It contains no duplicates, therefore allows  fast equality 
+   // comparison of string objects.
+   struct StringPool : private BasicHashTable<StringItem> {
+      using BasicHashTable<StringItem>::EntryType;
+
+      StringPool();
+      // Intern a NUL-terminated sequence of characters.
+      EntryType* intern(const char*);
+
+      // Intern a sequence of characters given by its start and length.
+      EntryType* intern(const Byte*, size_t);
+   private:
+      Memory::Arena<Byte> strings; // character blub
+      // Allocate a string from the internal arena.
+      const Byte* make_copy(const Byte*, size_t);
+   };
+
+   typedef const StringPool::EntryType* InternedString;
+}
+
+#endif  // OPENAXIOM_STRING_POOL_INCLUDED
diff --git a/src/include/open-axiom/structure b/src/include/open-axiom/structure
new file mode 100644
index 00000000..33c084f2
--- /dev/null
+++ b/src/include/open-axiom/structure
@@ -0,0 +1,75 @@
+// Copyright (C) 2013, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom, nor the names of its contributors may
+//       be used to endorse or promote products derived from this software
+//       without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_STRUCTURE_included
+#define OPENAXIOM_STRUCTURE_included
+
+namespace OpenAxiom {
+   // -- helper classes for structural abstractions --
+   namespace structure {
+      // unary structures
+      template<typename T>
+      struct unary {
+         explicit constexpr unary(const T& t) : arg(t) { };
+         constexpr const T& operand() const { return arg; }
+      private:
+         const T arg;
+      };
+
+      // binary structures
+      template<typename T, typename U = T>
+      struct binary {
+         constexpr binary(const T& t, const U& u) : arg0(t), arg1(u) { };
+         constexpr const T& first() const { return arg0; }
+         constexpr const U& second() const { return arg1; }
+      private:
+         const T arg0;
+         const U arg1;
+      };
+
+      // ternary structures
+      template<typename T, typename U = T, typename V = U>
+      struct ternary {
+         constexpr ternary(const T& t, const U& u, const V& v)
+               : arg0(t), arg1(u), arg2(v) { }
+         constexpr const T& first() const { return arg0; }
+         constexpr const U& second() const { return arg1; }
+         constexpr const V& third() const { return arg2; }
+      private:
+         const T arg0;
+         const U arg1;
+         const V arg2;
+      };
+   }
+}
+
+#endif  // OPENAXIOM_STRUCTURE_included
diff --git a/src/include/open-axiom/token b/src/include/open-axiom/token
new file mode 100644
index 00000000..b57b69d6
--- /dev/null
+++ b/src/include/open-axiom/token
@@ -0,0 +1,670 @@
+// Copyright (C) 2013-2014, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom. nor the names of its contributors
+//       may be used to endorse or promote products derived from this
+//       software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_TOKEN_included
+#define OPENAXIOM_TOKEN_included
+
+#include <stdint.h>
+#include <stack>
+#include <iosfwd>
+#include <open-axiom/Input>
+#include <open-axiom/dialect>
+
+namespace OpenAxiom {
+   // Categorization of Boot and Spad tokens.
+   enum class TokenCategory : uint8_t {
+      Unclassified,             // token of unknown class
+      Whitespace,               // sequence of white-space characters
+      Comment,                  // a description of an ignorable comment
+      Punctuator,               // a punctuator character
+      Operator,                 // an operator both symbolic and alphabetic
+      Integer,                  // an integer literal
+      FloatingPoint,            // a floating-point literal
+      String,                   // a string literal
+      Keyword,                  // a reserved word both symbolic and alphabetic
+      Identifier,               // an identifier
+      Formatting,               // a layout formatting token
+      Junk,                     // invalid/malformed token
+      EOS                       // end-of-token-stream indicator
+   };
+
+   std::ostream& operator<<(std::ostream&, TokenCategory);
+
+   // The abstract value associated with a token.
+   enum class TokenValue : uint8_t {
+#undef OPENAXIOM_DEFINE_TOKEN
+#define OPENAXIOM_DEFINE_TOKEN(T, ...)  T,
+#include <open-axiom/token-value>
+#undef OPENAXIOM_DEFINE_TOKEN
+      Artificial,               // Tokens after this are artificial
+      Indent,                   // new line indentation, greater than previous
+      Unindent,                 // new line indentation, less than previous
+      Justify,                  // align indentation with preceding line.
+
+      EndOfStream               // end of token stream
+   };
+
+   std::ostream& operator<<(std::ostream&, TokenValue);
+
+   // Datatypes for locating lines and columns.
+   using LineNumber = std::size_t;
+   using ColumnIndex = std::size_t;
+
+   struct Locus {
+      LineNumber line;
+      ColumnIndex column;
+   };
+
+   std::ostream& operator<<(std::ostream&, const Locus&);
+
+   // Program text region
+   struct Region {
+      Locus start;
+      Locus end;
+   };
+
+   // Given a symbolic or alphabetic token, retrieve its category
+   // and associated abstract value.
+   struct TokenClassification {
+      TokenCategory category;
+      TokenValue value;
+
+      explicit operator bool() const {
+         return category != TokenCategory::Unclassified;
+      }
+   };
+
+   TokenClassification classify(const std::string&);
+
+   // Token data structure: a region of text with a classification.
+   struct Token : TokenClassification, Region {
+      using Location = Locus;
+   };
+
+   // Cursor into a fragment.
+   struct FragmentCursor {
+      std::size_t line;         // index of a line in a fragment
+      std::size_t column;       // column number at line.
+
+      inline FragmentCursor& operator++() {
+         ++column;
+         return *this;
+      }
+
+      inline FragmentCursor operator++(int) {
+         auto tmp = *this;
+         ++*this;
+         return tmp;
+      }
+
+      inline FragmentCursor& operator--() {
+         --column;
+         return *this;
+      }
+
+      inline FragmentCursor operator--(int) {
+         auto tmp = *this;
+         --*this;
+         return tmp;
+      }
+   };
+
+   // -- Exception types
+   struct EndOfStringUnseen {
+      LineNumber line;
+      ColumnIndex column;
+   };
+
+   struct MissingExponent {
+      LineNumber line;
+      ColumnIndex column;
+   };
+
+   // Object of this datatype decompose a program fragment into a
+   // token stream.  The tokens are of type indicated by Tok.
+   template<typename Frag, typename Tok>
+   struct Tokenizer {
+      Tokenizer(Frag& f)
+            : frag(f),
+              pos{ 0, frag.front().indent }
+      {
+         indents.push(pos.column);
+      }
+
+      bool eos() const {
+         return pos.line >= frag.size()
+            or (pos.line + 1 == frag.size() and pos.column >= frag.back().size());
+      }
+
+      Tok get(Language = Language::Spad);
+   private:
+      Frag& frag;
+      FragmentCursor pos;
+      std::stack<ColumnIndex> indents;
+
+      std::size_t line_length() const { return frag(pos).size(); }
+      LineNumber next_line_number() const {
+         return pos.line + 1 < frag.size()
+            ? frag[pos.line + 1].number
+            : frag.back().number + 1;
+      }
+      ColumnIndex next_indentation() const {
+         return pos.line + 1 < frag.size() ? frag[pos.line + 1].indent : 0;
+      }
+
+      LineNumber line_number() const {
+         return pos.line < frag.size()
+            ? frag(pos).number
+            : frag.back().number + 1;
+      }
+
+      ColumnIndex column_number() const {
+         return pos.line < frag.size() ? pos.column : 0;
+      }
+
+      using Locus = typename Tok::Location;
+      Locus current_locus() {
+         return { line_number(), column_number() };
+      }
+   };
+
+   bool separator_or_punctuator(uint8_t);
+
+   template<typename T>
+   inline void comment_token(T& t, TokenValue v) {
+      t.category = TokenCategory::Comment;
+      t.value = v;
+   }
+
+   template<typename T>
+   inline void operator_token(T& t, TokenValue v) {
+      t.category = TokenCategory::Operator;
+      t.value = v;
+   }
+
+   template<typename T>
+   inline void punctuator_token(T& t, TokenValue v) {
+      t.category = TokenCategory::Punctuator;
+      t.value = v;
+   }
+
+   template<typename L, typename T>
+   static void junk(L& line, ColumnIndex& idx, T& t) {
+      while (idx < line.size() and not separator_or_punctuator(line[idx]))
+         ++idx;
+      t.category = TokenCategory::Junk;
+   }
+
+   template<typename L>
+   inline void
+   skip_whitespace(L& line, ColumnIndex& idx) {
+      while (idx < line.size() and isspace(line[idx]))
+         ++idx;
+   }
+
+   template<typename Frag, typename Tok>
+   void string_literal(Frag& frag, FragmentCursor& pos, Tok& t) {
+      bool done = false;
+      bool escape = false;
+      while (frag.covering(pos) && not done) {
+         switch (frag(pos)[pos.column++]) {
+         case '"': done = !escape;
+            // fallthrough
+         default: escape = false; break;
+         case '_':
+            if (pos.column == frag(pos).size()
+                and pos.line < frag.size() - 1) {
+               ++pos.line;
+               pos.column = 0;
+            }
+            else
+               escape = !escape;
+            break;
+         }
+      }
+      if (not done)
+         throw EndOfStringUnseen{ frag(pos).number, pos.column };
+      t.category = TokenCategory::String;
+   }
+
+   template<typename L>
+   void skip_to_end_of_integer(L& line, ColumnIndex& idx) {
+      while (idx < line.size() and isdigit(line[idx]))
+         ++idx;
+   }
+   
+   template<typename L, typename T>
+   void integer(L& line, ColumnIndex& idx, T& t) {
+      skip_to_end_of_integer(line, idx);
+      t.category = TokenCategory::Integer;
+   }
+
+   template<typename L, typename T>
+   T& number(L& line, ColumnIndex& idx, T& t) {
+      integer(line, idx, t);
+      if (idx >= line.size() or line[idx] != '.')
+         return t;
+      if (++idx >= line.size() or not isdigit(line[idx])) {
+         --idx;
+         return t;
+      }
+
+      t.category = TokenCategory::FloatingPoint;
+      skip_to_end_of_integer(line, idx);
+      if (idx >= line.size() or (line[idx] != 'e' and line[idx] != 'E'))
+         return t;
+      if (++idx < line.size() and (line[idx] == '+' or line[idx] == '-'))
+         ++idx;
+      if (idx >= line.size() or not isdigit(line[idx]))
+         throw MissingExponent{ line.number, idx };
+      skip_to_end_of_integer(line, idx);
+      return t;
+   }
+
+   inline bool
+   identifier_head(uint8_t c) {
+      return isalpha(c) or c == '%' or c == '_';
+   }
+
+   inline bool
+   identifier_part(uint8_t c) {
+      return identifier_head(c) or isdigit(c);
+   }
+
+   inline bool
+   identifier_suffix(uint8_t c) {
+      return c == '!' or c == '?';
+   }
+
+   inline bool internal_prefix(uint8_t c) {
+      return c == '%' or c == '$';
+   }
+
+   template<typename L>
+   inline void
+   skip_prefix(L& line, ColumnIndex& idx, uint8_t c) {
+      while (idx < line.size() and line[idx] == c)
+         ++idx;
+   }
+
+   template<typename L, typename T>
+   T& identifier(L& line, ColumnIndex& idx, T& t, Language dialect) {
+      t.category = TokenCategory::Identifier;
+
+      ColumnIndex start = --idx; // idx was ahead by 1.
+      if (dialect == Language::Boot and internal_prefix(line[idx]))
+         skip_prefix(line, idx, line[idx]);
+      bool saw_escape = false;
+      while (idx < line.size()) {
+         if (not identifier_part(line[idx]) and line[idx - 1] != '_')
+            break;
+         else if (line[idx] == '_')
+            saw_escape = true;
+         ++idx;
+      }
+      while (idx < line.size() and identifier_suffix(line[idx]))
+         ++idx;
+
+      if (saw_escape)
+         t.category = TokenCategory::Identifier;
+      else if (auto info = classify(line.sub_string(start, idx))) {
+         t.category = info.category;
+         t.value = info.value;
+      }
+      return t;
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   left_paren_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      punctuator_token(t, TokenValue::OpenParen);
+      if (frag.covering(pos) and frag[pos] == '|') {
+         ++pos;
+         t.value = TokenValue::OpenMetaParen;
+      }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   left_brace_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      punctuator_token(t, TokenValue::OpenBrace);
+      if (frag.covering(pos) and frag[pos] == '|') {
+         ++pos;
+         t.value = TokenValue::OpenMetaBrace;
+      }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   left_bracket_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      punctuator_token(t, TokenValue::OpenBracket);
+      if (frag.covering(pos) and frag[pos] == '|') {
+         ++pos;
+         t.value = TokenValue::OpenMetaBracket;
+      }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   colon_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      operator_token(t, TokenValue::Colon);
+      if (frag.covering(pos))
+         switch (frag[pos]) {
+         case ':': t.value = TokenValue::ColonColon; ++pos; break;
+         case '=': t.value = TokenValue::ColonEq; ++pos; break;
+         case '-': t.value = TokenValue::ColonDash; ++pos; break;
+         default: break;
+         }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   star_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      operator_token(t, TokenValue::Star);
+      if (frag.covering(pos) and frag[pos] == '*') {
+         t.value = TokenValue::StarStar;
+         ++pos;
+      }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   slash_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      operator_token(t, TokenValue::Slash);
+      if (frag.covering(pos))
+         switch (frag[pos]) {
+         case '/': t.value = TokenValue::SlashSlash; ++pos; break;
+         case '\\': t.value = TokenValue::SlashBackslash; ++pos; break;
+         default: break;
+         }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   backslash_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      operator_token(t, TokenValue::Backslash);
+      if (frag.covering(pos))
+         switch (frag[pos]) {
+         case '\\': t.value = TokenValue::BackslashBackslash; ++pos; break;
+         case '/': t.value = TokenValue::BackslashSlash; ++pos; break;
+         default: break;
+         }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   less_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      operator_token(t, TokenValue::Less);
+      if (frag.covering(pos))
+         switch (frag[pos]) {
+         case '-': t.value = TokenValue::LeftArrow; ++pos; break;
+         case '<': t.value = TokenValue::OpenChevron; ++pos; break;
+         case '=':
+            t.value = TokenValue::LessEq;
+            if (frag.covering(++pos) and frag[pos] == '>') {
+               t.value = TokenValue::Equiv;
+               ++pos;
+            }
+            break;
+         default: break;
+         }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   equal_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      operator_token(t, TokenValue::Eq);
+      if (frag.covering(pos))
+         switch (frag[pos]) {
+         case '>': t.value = TokenValue::Implies; ++pos; break;
+         case '=':
+            t.value = TokenValue::EqEq;
+            if (frag.covering(++pos) and frag[pos] == '>') {
+               t.value = TokenValue::FatArrow;
+               ++pos;
+            }
+            break;
+         default: break;
+         }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   tilde_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      operator_token(t, TokenValue::Tilde);
+      if (frag.covering(pos) and frag[pos] == '=') {
+         t.value = TokenValue::TildeEq;
+         ++pos;
+      }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   greater_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      operator_token(t, TokenValue::Greater);
+      if (frag.covering(pos))
+         switch (frag[pos]) {
+         case '=': t.value = TokenValue::GreaterEq; ++pos; break;
+         case '>': t.value = TokenValue::CloseChevron; ++pos; break;
+         }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   bar_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      punctuator_token(t, TokenValue::Bar);
+      if (frag.covering(pos))
+         switch (frag[pos]) {
+         case ']': t.value = TokenValue::CloseMetaBracket; ++pos; break;
+         case '}': t.value = TokenValue::CloseMetaBrace; ++pos; break;
+         case ')': t.value = TokenValue::CloseMetaParen; ++pos; break;
+         default: break;
+         }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   minus_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      operator_token(t, TokenValue::Minus); 
+      if (frag.covering(pos))
+         switch (frag[pos]) {
+         case '>': t.value = TokenValue::RightArrow; ++pos; break;
+         case '-':
+            comment_token(t, TokenValue::Wisecrack);
+            pos.column = frag(pos).size();
+            break;
+         }
+   }
+
+
+   template<typename Frag, typename Tok>
+   static void
+   plus_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      operator_token(t, TokenValue::Plus);
+      if (frag.covering(pos))
+         switch (frag[pos]) {
+         case '+':
+            comment_token(t, TokenValue::Commentary);
+            pos.column = frag(pos).size();
+            break;
+         case '-':
+            if (pos.column + 1 < frag(pos).size()
+                and frag(pos)[pos.column + 1] == '>') {
+               t.value = TokenValue::MapsTo;
+               pos.column += 2;
+            }
+            break;
+         default: break;
+         }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   dot_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
+      operator_token(t, TokenValue::Dot);
+      if (frag.covering(pos) and frag[pos] == '.') {
+         t.value = TokenValue::DotDot;
+         ++pos;
+      }
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   dollar_et_al(Frag& frag, FragmentCursor& pos, Tok& t, Language dialect) {
+      if (dialect != Language::Boot or not frag.covering(pos)
+          or separator_or_punctuator(frag[pos]))
+         operator_token(t, TokenValue::Dollar);
+      else
+         identifier(frag(pos), pos.column, t, dialect);
+   }
+
+   template<typename Frag, typename Tok>
+   static void
+   sharp_et_al(Frag& frag, FragmentCursor& pos, Tok& t, Language dialect) {
+      if (dialect != Language::Lisp)
+         operator_token(t, TokenValue::Sharp);
+      else if (frag.covering(pos))
+         switch (frag[pos++]) {
+         case '(': punctuator_token(t, TokenValue::SharpLeftParen); break;
+         case '\'': operator_token(t, TokenValue::SharpApostrophe); break;
+         case ':': operator_token(t, TokenValue::SharpColon); break;
+         case '+': punctuator_token(t, TokenValue::SharpPlus); break;
+         case '-': punctuator_token(t, TokenValue::SharpMinus); break;
+         case '.': operator_token(t, TokenValue::SharpDot); break;
+         default: --pos; break;
+         }
+   }
+
+
+   template<typename Frag, typename Tok>
+   Tok Tokenizer<Frag, Tok>::get(Language dialect) {
+      Tok t { };
+      t.start = current_locus();
+      
+      if (eos()) {
+         t.category = TokenCategory::EOS;
+         t.end = current_locus();
+         return t;
+      }
+      else if (isspace(frag[pos])) {
+         skip_whitespace(frag(pos), pos.column);
+         t.category = TokenCategory::Whitespace;
+         t.end = current_locus();
+         return t;
+      }
+      else if (pos.column == line_length() - 1 and frag(pos).back() == '_') {
+         ++pos.line;
+         pos.column = frag(pos).indent;
+      }
+      else if (pos.column == line_length()) {
+         auto indent = indents.top();
+         auto next_indent = next_indentation();
+         t.start = t.end = { next_line_number(), next_indent };
+         if (indent < next_indent) {
+            indents.push(next_indent);
+            ++pos.line;
+            pos.column = next_indent;
+            t.category = TokenCategory::Formatting;
+            t.value = TokenValue::Indent;
+         }
+         else if (indent > next_indent) {
+            indents.pop();
+            t.category = TokenCategory::Formatting;
+            t.value = TokenValue::Unindent;
+         }
+         else {
+            ++pos.line;
+            pos.column = next_indent;
+            t.category = TokenCategory::Formatting;
+            t.value = TokenValue::Justify;
+         }
+         return t;
+      }
+
+      switch (auto c = frag.advance(pos)) {
+      case '#': sharp_et_al(frag, pos, t, dialect); break;
+      case '@': operator_token(t, TokenValue::At); break;
+      case '^': operator_token(t, TokenValue::Caret); break;
+      case '&': punctuator_token(t, TokenValue::Ampersand); break;         
+      case '!': punctuator_token(t, TokenValue::Exclamation); break;
+      case '\'': punctuator_token(t, TokenValue::Apostrophe); break;
+      case ',': punctuator_token(t, TokenValue::Comma); break;
+      case ';': punctuator_token(t, TokenValue::Semicolon); break;
+      case '`': punctuator_token(t, TokenValue::Backquote); break;
+      case '(': left_paren_et_al(frag, pos, t); break;
+      case ')': punctuator_token(t, TokenValue::CloseParen); break;
+      case '{': left_brace_et_al(frag, pos, t); break;
+      case '}': punctuator_token(t, TokenValue::CloseBrace); break;
+      case '[': left_bracket_et_al(frag, pos, t); break;
+      case ']': punctuator_token(t, TokenValue::CloseBracket); break;
+      case ':': colon_et_al(frag, pos, t); break;
+      case '*': star_et_al(frag, pos, t); break;
+      case '/': slash_et_al(frag, pos, t); break;
+      case '\\': backslash_et_al(frag, pos, t); break;
+      case '<': less_et_al(frag, pos, t); break;
+      case '=': equal_et_al(frag, pos, t); break;
+      case '~': tilde_et_al(frag, pos, t); break;
+      case '>': greater_et_al(frag, pos, t); break;
+      case '|': bar_et_al(frag, pos, t); break;
+      case '-': minus_et_al(frag, pos, t); break;
+      case '+': plus_et_al(frag, pos, t); break;
+      case '.': dot_et_al(frag, pos, t); break;
+      case '"': string_literal(frag, pos, t); break;
+      case '$': dollar_et_al(frag, pos, t, dialect); break;
+
+      default:
+         if (isdigit(c))
+            number(frag(pos), pos.column, t);
+         else if (identifier_head(c))
+            identifier(frag(pos), pos.column, t, dialect);
+         else
+            junk(frag(pos), pos.column, t);
+         break;
+      }
+
+      t.end = { frag(pos).number, pos.column };
+      return t;
+   }
+
+   // -- Token streams.
+   template<typename T>
+   struct TokenStream : std::vector<T> {
+      template<typename Frag>
+      explicit TokenStream(Frag& f, Language dialect = Language::Spad) {
+         Tokenizer<Frag, T> lex { f };
+         while (auto t = lex.get(dialect))
+            this->push_back(t);
+      }
+   };
+}
+
+#endif  // OPENAXIOM_TOKEN_included
diff --git a/src/include/open-axiom/token-value b/src/include/open-axiom/token-value
new file mode 100644
index 00000000..9a949b86
--- /dev/null
+++ b/src/include/open-axiom/token-value
@@ -0,0 +1,145 @@
+// Copyright (C) 2014, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom. nor the names of its contributors
+//       may be used to endorse or promote products derived from this
+//       software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+OPENAXIOM_DEFINE_TOKEN(Unknown, "<unknown>", Unclassified, Language::All)
+OPENAXIOM_DEFINE_TOKEN(Apostrophe, "'", Punctuator, Language::All)
+OPENAXIOM_DEFINE_TOKEN(Backquote, "`", Punctuator, Language::All)
+OPENAXIOM_DEFINE_TOKEN(Bar, "|", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Dot, ".", Punctuator, Language::All)
+OPENAXIOM_DEFINE_TOKEN(DotDot, "..", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Colon, ":", Punctuator, Language::All)
+OPENAXIOM_DEFINE_TOKEN(ColonColon, "::", Operator, Language::All)
+OPENAXIOM_DEFINE_TOKEN(ColonDash, ":-", Operator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(ColonEq, ":=", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(At, "@", Operator, Language::All)
+OPENAXIOM_DEFINE_TOKEN(Exclamation, "!", Punctuator, Language::Boot)
+OPENAXIOM_DEFINE_TOKEN(Comma, ",", Punctuator, Language::All)
+OPENAXIOM_DEFINE_TOKEN(CommaAt, ",@", Operator, Language::Lisp)
+OPENAXIOM_DEFINE_TOKEN(Semicolon, ";", Punctuator, Language::All)
+OPENAXIOM_DEFINE_TOKEN(Star, "*", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(StarStar, "**", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Plus, "+", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Minus, "-", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Slash, "/", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(SlashSlash, "//", Operator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(SlashBackslash, "/\\", Operator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(Backslash, "\\", Operator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(BackslashSlash, "\\/", Operator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(BackslashBackslash, "\\\\", Operator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(Less, "<", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(LessEq, "<=", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Greater, ">", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(GreaterEq, ">=", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Eq, "=", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(EqEq, "==", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Tilde, "~", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(TildeEq, "~=", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Caret, "^", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Sharp, "#", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(SharpLeftParen, "#(", Punctuator, Language::Lisp)
+OPENAXIOM_DEFINE_TOKEN(SharpApostrophe, "#'", Operator, Language::Lisp)
+OPENAXIOM_DEFINE_TOKEN(SharpColon, "#:", Operator, Language::Lisp)
+OPENAXIOM_DEFINE_TOKEN(SharpPlus, "#+", Punctuator, Language::Lisp)
+OPENAXIOM_DEFINE_TOKEN(SharpMinus, "#-", Punctuator, Language::Lisp)
+OPENAXIOM_DEFINE_TOKEN(SharpDot, "#.", Operator, Language::Lisp)
+OPENAXIOM_DEFINE_TOKEN(Dollar, "$", Operator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(Ampersand, "&", Operator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(RightArrow, "->", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(LeftArrow, "<-", Operator, Language::Boot)
+OPENAXIOM_DEFINE_TOKEN(Implies, "=>", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Equiv, "<=>", Keyword, Language::Boot)
+OPENAXIOM_DEFINE_TOKEN(MapsTo, "+->", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(FatArrow, "==>", Keyword, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(OpenParen, "(", Punctuator, Language::All)
+OPENAXIOM_DEFINE_TOKEN(CloseParen, ")", Punctuator, Language::All)
+OPENAXIOM_DEFINE_TOKEN(OpenMetaParen, "(|", Punctuator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(CloseMetaParen, "|)", Punctuator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(OpenBracket, "[", Punctuator, Language::All)
+OPENAXIOM_DEFINE_TOKEN(CloseBracket, "]", Punctuator, Language::All)
+OPENAXIOM_DEFINE_TOKEN(OpenMetaBracket, "[|", Punctuator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(CloseMetaBracket, "|]", Punctuator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(OpenBrace, "{", Punctuator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(CloseBrace, "}", Punctuator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(OpenMetaBrace, "{|", Punctuator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(CloseMetaBrace, "|}", Punctuator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(OpenChevron, "<<", Operator, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(CloseChevron, ">>", Operator, Language::Spad)
+
+OPENAXIOM_DEFINE_TOKEN(Wisecrack, "--", Comment, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Commentary, "++", Comment, Language::BootSpad)
+
+OPENAXIOM_DEFINE_TOKEN(Add, "add", Keyword, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(And, "and", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Assume, "assume", Keyword, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(Break, "break", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(By, "by", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Case, "case", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Catch, "catch", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Cross, "cross", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Do, "do", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Else, "else", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Exists, "exists", Keyword, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(Finally, "finally", Keyword, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(For, "for", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Forall, "forall", Keyword, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(From, "from", Keyword, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(Function, "function", Keyword, Language::Boot)
+OPENAXIOM_DEFINE_TOKEN(Has, "has", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(If, "if", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Import, "import", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(In, "in", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Inline, "inline", Keyword, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(Is, "is", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Isnt, "isnt", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Iterate, "iterate", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Leave, "leave", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Macro, "macro", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Mod, "mod", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Namespace, "namespace", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Of, "of", Keyword, Language::Boot)
+OPENAXIOM_DEFINE_TOKEN(Or, "or", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Pretend, "pretend", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Quo, "quo", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Rem, "rem", Operator, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Repeat, "repeat", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Return, "return", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Rule, "rule", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Structure, "structure", Keyword, Language::Boot)
+OPENAXIOM_DEFINE_TOKEN(Then, "then", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(Throw, "throw", Keyword, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(Try, "try", Keyword, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(Until, "until", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(With, "with", Keyword, Language::Spad)
+OPENAXIOM_DEFINE_TOKEN(Where, "where", Keyword, Language::BootSpad)
+OPENAXIOM_DEFINE_TOKEN(While, "while", Keyword, Language::BootSpad)
diff --git a/src/include/open-axiom/vm b/src/include/open-axiom/vm
new file mode 100644
index 00000000..3bb62250
--- /dev/null
+++ b/src/include/open-axiom/vm
@@ -0,0 +1,606 @@
+// Copyright (C) 2011-2014, Gabriel Dos Reis.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     - Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//
+//     - Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in
+//       the documentation and/or other materials provided with the
+//       distribution.
+//
+//     - Neither the name of OpenAxiom nor the names of its contributors
+//       may be used to endorse or promote products derived from this
+//       software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// --% Author: Gabriel Dos Reis
+// --% Description:
+// --%   Interface and implementation of basic services of the 
+// --%   OpenAxiom Virtual Machine.
+
+#ifndef OPENAXIOM_VM_included
+#define OPENAXIOM_VM_included
+
+#include <open-axiom/storage>
+#include <open-axiom/string-pool>
+#include <stdint.h>
+#include <utility>
+#include <set>
+#include <vector>
+#include <type_traits>
+
+#define internal_type struct alignas(16)
+#define internal_data alignas(16)
+
+namespace OpenAxiom {
+   namespace VM {
+      // --%
+      // --% Value representation
+      // --%
+      // A far reaching design decision is that of providing a uniform
+      // representation for values.  That is all values, irrespective
+      // of type have fit in a fixed format, i.e. a scalar register.
+      // This means that values that are more complicated than a scalar,
+      // i.e. the vast majority and most interesting values, have to
+      // be stored in allocated objects and addresses of their container
+      // objects used in place of the actual values.  This is folklore
+      // in the communities of garbage collected languages.
+      // 
+      // An unfortunate but widely held belief is that AXIOM-based
+      // systems (and computer algebra systems in general) are
+      // Lisp-based systems.  Nothing could be further from the truth
+      // for OpenAxiom.  The type system is believed to support
+      // erasure semantics, at least for values.
+      //
+      // However the current implementation, being Lisp-based,
+      // unwittingly makes use of some Lisp features that are not
+      // strictly necessary.  It would take a certain amount of effort
+      // to get rid of them.  Consequently, we must cope -- at least
+      // for now -- with the notion of uniform value representation and
+      // use runtime predicates to descriminate between values.
+      // On the other hand, we do not want to carry an unduly expensive
+      // abstraction penalty for perfectly well behaved and well
+      // disciplined programs.  So, here are a few constraints:
+      //   1. Small integers should represent themselves -- not allocated.
+      //      Furthermore, the maximum range should be sought where possible.
+      //   2. Since we have to deal with characters, they should be
+      //      directly represented -- not allocated.
+      //   3. List values and list manipulation should be efficient.
+      //      Ideally, a pair should occupy no more than what it
+      //      takes to store two values in a type-erasure semantics.
+      //   4. Idealy, pointers to foreign objects (at least) should be
+      //      left unmolested.
+      //   5. Ideally, we want efficient access to string literals
+      // 
+      // * Assumptions:
+      //     (a) the host machine has sizeof(Value) quo 4 = 0.
+      //     (b) allocated objects can be aligned on sizeof(Value) boundary.
+      //     (c) the host machine has 2's complement arithmetic.
+      //
+      // If:
+      //   -- we use a dedicated allocation pool for cons cells
+      //   -- we allocate the first cell in each cons-storage arena
+      //      on a 8-byte boundary
+      //   -- we use exactly 2 * sizeof(Value) to store a cons cell
+      //      therefore realizing constraint (3)
+      // then:
+      //   every pointer to a cons cell will have its last 3 bits cleared.
+      //
+      // Therefore, we can use the last 3 bits to tag a cons value, instead
+      // of storing the tag inside the cons cell.  We can't leave those
+      // bits cleared for we would not be able to easily and cheaply
+      // distinguish a pointer to a cons cell from a pointer to other
+      // objects, in particular foreign objects.
+      //
+      // To meet constraint (1), we must logically use at least one bit
+      // to distinguish a small integer from a pointer to a cons cell.
+      // The good news is that we need no more than that if pointers
+      // to foreign pointers do not have the last bit set.  Which is
+      // the case with assumption (a).  Furthermore, if we align all
+      // other internal data on 16 byte boundary, then we have 4 spare bits
+      // for use to categorize values.
+      // Therefore we arrive at the first design:
+      //    I. the value representation of a small integer always has the
+      //       the least significant bit set.  All other bits are
+      //       significant.  In other words, the last four bits of a small
+      //       integer are 0bxxx1
+      // 
+      // As a consequence, the last bit of all other values must be cleared.
+      //
+      // Next,
+      //   II. All foreign pointers that are aligned on 8-boundary are
+      //       directly represented.  Any foreign pointer not meeting
+      //       this condition is stored in an internal object.  As a
+      //       consequence, the last four bits of all foreign addresses 
+      //       directly represented follow the pattern 0bx000.
+      // 
+      //  III. Cons cells are represented by their addresses with the
+      //       last 4 bits matching the pattern 0bx010.
+      //
+      //   IV. All internal objects are allocated on 16-byte boundary.
+      //       Their last 4 bits are set to the pattern 0b0110.
+      //
+      //    V. String literals are represented by their addressed with
+      //       the last four bits following the pattern 0bx100..
+      //
+      // Finally:
+      //   IV. The representation of a character shall have the last four
+      //       bits set to 0b1110.
+      //
+      // Note: These choices do not fully satisfy constraint 4.  This is 
+      //     because we restrict foreign pointers to address aligned
+      //     to 8-byte boundaries.  A modest constraint.
+      //
+      // Special Constants:
+      //     NIL    0x00
+      //     T      0x10
+
+
+      // -----------
+      // -- Value --
+      // -----------
+      // All VM values fit in a universal value datatype.
+      using ValueBits = uintptr_t;
+      using ValueMask = ValueBits;
+      enum class Value : ValueBits {
+         nil = 0x00,            // distinguished NIL value
+         t   = 0x10,            // distinguished T value
+      };
+
+      // -- Testing for nil value.
+      constexpr Value null(Value v) {
+         return v == Value::nil ? Value::t : Value::nil;
+      }
+
+      // -- Convert VM Boolean value to C++ view
+      constexpr bool to_bool(Value v) { return v != Value::nil; }
+
+      // -- Convert a C++ Boolean value to VM view.
+      constexpr Value to_value(bool b) {
+         return b ? Value::t : Value::nil;
+      }
+
+      // -- Identity equality.
+      constexpr Value eq(Value x, Value y) { return to_value(x == y); }
+
+      template<typename>
+      struct ValueTrait {
+      };
+
+      // Return the tag of an abstract value, when viewed as a potential
+      // T-value.
+      template<typename T>
+      constexpr ValueBits tag(Value v) {
+         return ValueBits(v) & ValueTrait<T>::tag_mask;
+      }
+
+      // Return true if the abstract value is, in fact, a T-value.
+      template<typename T>
+      constexpr bool is(Value v) {
+         return tag<T>(v) == ValueTrait<T>::tag;
+      }
+
+      // Return the pristine bits of an abstract value without its tag.
+      template<typename T>
+      constexpr ValueBits native(Value v) {
+         return ValueBits(v) & ~ValueTrait<T>::tag_mask;
+      }
+
+      // -- Arity: number of arguments or forms taken by a function
+      //           or a special operator.
+      enum class Arity : intptr_t {
+         variable = -1,         // Any number of arguments.
+         zero     = 0,          // Exactly no argument.
+         one      = 1,          // Exactly one argument.
+         two      = 2,          // Exactly two arguments.
+         three    = 3,          // Exactly three arguments.
+      };
+
+      // -------------
+      // -- Dynamic --
+      // -------------
+      // Any internal value is of a class derived from this.
+      internal_type Dynamic {
+         struct Visitor;
+         virtual ~Dynamic();
+         virtual void accept(Visitor&) const = 0;
+      };
+
+      // Provide an S-view of a T-typed expression, assuming the type T
+      // derives from S.
+      template<typename S, typename T>
+      inline const S& as(const T& t) { return t; }
+
+      template<>
+      struct ValueTrait<Dynamic> {
+         enum Tag : ValueBits { tag = 0x6 };
+         enum Mask : ValueBits { tag_mask = 0xF };
+      };
+
+      inline Dynamic* to_dynamic(Value v) {
+         return reinterpret_cast<Dynamic*>(native<Dynamic>(v));
+      }
+
+      inline Dynamic* to_dynamic_if_can(Value v) {
+         return is<Dynamic>(v) ? to_dynamic(v) : nullptr;
+      }
+
+      template<typename T>
+      using IfDynamic = typename
+         std::enable_if<std::is_base_of<Dynamic, T>::value, Value>::type;
+
+      template<typename T>
+      inline IfDynamic<T> to_value(const T* o) {
+         return Value(ValueBits(o) | ValueTrait<Dynamic>::tag);
+      }
+
+      // -- Callable --
+      struct Callable : Dynamic {
+      };
+      
+      // -------------
+      // -- Fixnum ---
+      // -------------
+      // VM integers are divided into classes: small numbers,
+      // and large numbers.  A small number fits entirely in a register.
+      // A large number is allocated and represented by its address.
+      using FixnumBits = intptr_t;
+      enum class Fixnum : FixnumBits {
+         minimum = FixnumBits(~(~ValueBits() >> 2)),
+         zero = FixnumBits(0),
+         one = FixnumBits(1),
+         maximum = FixnumBits(~ValueBits() >> 2),
+      };
+
+      template<>
+      struct ValueTrait<Fixnum> {
+         enum Tag : ValueBits { tag = 0x1  };
+         enum Mask : ValueBits { tag_mask = 0x1 };
+      };
+
+      constexpr Fixnum to_fixnum(Value v) {
+         return Fixnum(FixnumBits(v) >> 1);
+      }
+
+      constexpr Value from_fixnum(Fixnum i) {
+         return Value((ValueBits(i) << 1 ) | ValueTrait<Fixnum>::tag);
+      }
+
+      // ------------
+      // -- String --
+      // ------------
+      using String = InternedString;
+
+      template<>
+      struct ValueTrait<String> {
+         enum Tag : ValueBits { tag = 0x4 };
+         enum Mask : ValueBits { tag_mask = 0x7 };
+      };
+
+      inline InternedString to_string(Value v) {
+         return reinterpret_cast<String>(native<String>(v));
+      }
+
+      inline Value from_string(InternedString s) {
+         return Value(ValueBits(s) | ValueTrait<String>::tag);
+      }
+
+      inline InternedString to_string_if_can(Value v) {
+         return is<String>(v) ? to_string(v) : nullptr;
+      }
+
+      // -------------
+      // -- Pointer --
+      // -------------
+      // Allocated objects are represented by their addresses.
+      using Memory::Pointer;
+
+      template<>
+      struct ValueTrait<Memory::Pointer> {
+         enum Tag : ValueBits { tag = 0x0 };
+         enum Mask : ValueBits { tag_mask = 0x7 };
+      };
+
+      inline Pointer to_pointer(Value v) {
+         return Pointer(ValueBits(v));
+      }
+
+      inline Value from_pointer(Pointer p) {
+         return Value(ValueBits(p) | ValueTrait<Memory::Pointer>::tag);
+      }
+
+      // ----------
+      // -- Pair --
+      // ----------
+      struct alignas(8) ConsCell {
+         Value head;
+         Value tail;
+      };
+
+      using Pair = ConsCell*;
+
+      template<>
+      struct ValueTrait<Pair> {
+         enum Tag : ValueBits { tag = 0x2 };
+         enum Mask : ValueBits { tag_mask = 0x7 };
+      };
+
+      inline Pair to_pair(Value v) {
+         return reinterpret_cast<Pair>(native<Pair>(v));
+      }
+
+      inline Value from_pair(Pair p) {
+         return Value(ValueBits(p) | ValueTrait<Pair>::tag);
+      }
+
+      // Return true if argument designates a pair.
+      constexpr Value consp(Value v) {
+         return to_value(v != Value::nil and v != Value::t and is<Pair>(v));
+      }
+
+      inline Value atom(Value v) {
+         return null(consp(v));
+      }
+
+      // If `v' designates a pair, return a pointer to its
+      // concrete representation.
+      inline Pair to_pair_if_can(Value v) {
+         return consp(v) == Value::t ? to_pair(v) : nullptr;
+      }
+
+      Fixnum count_nodes(Pair);
+      inline Fixnum count_nodes(Value v) {
+         if (auto p = to_pair_if_can(v))
+            return count_nodes(p);
+         return Fixnum::zero;
+      }
+
+      // ---------------
+      // -- Character --
+      // ---------------
+      // This datatype is prepared for Uncode characters even if
+      // we do not handle UCN characters at the moment.
+      enum class Character : ValueBits { };
+
+      template<>
+      struct ValueTrait<Character> {
+         enum Tag : ValueBits { tag = 0xE };
+         enum Mask : ValueBits { tag_mask = 0xF };
+      };
+
+      constexpr Character to_character(Value v) {
+         return Character(ValueBits(v) >> 4);
+      }
+
+      constexpr Value from_character(Character c) {
+         return Value((ValueBits(c) << 4) | ValueTrait<Character>::tag);
+      }
+
+      // -- Object --
+      // An object is a typed value.
+      struct Type;
+      struct Object {
+         Value value;
+         const Type* type;
+      };
+
+      struct Package;
+
+      enum class SymbolAttribute : ValueBits {
+         None             = 0x0,    // No particular attribute.
+         Constant         = 0x1,    // Symbol defined constant.
+         Special          = 0x2,    // Symbol declared special.
+         Keyword          = 0x4,    // A keyword symbol.
+         SpecialConstant  = Constant | Special,
+      };
+
+      constexpr SymbolAttribute
+      operator&(SymbolAttribute x, SymbolAttribute y) {
+         return SymbolAttribute(ValueBits(x) & ValueBits(y));
+      }
+
+      // ------------
+      // -- Symbol --
+      // ------------
+      struct Symbol : Dynamic {
+         const InternedString name;
+         Value value;
+         const Callable* function;
+         Pair properties;
+         Package* package;
+         SymbolAttribute attributes;
+         explicit Symbol(InternedString);
+         void accept(Visitor&) const override;
+         bool has(SymbolAttribute x) const { return (attributes & x) == x; }
+      };
+
+      inline Symbol* to_symbol_if_can(Value v) {
+         return dynamic_cast<Symbol*>(to_dynamic_if_can(v));
+      }
+
+      inline bool is_symbol(Value v) {
+         return to_symbol_if_can(v) != nullptr;
+      }
+
+      // -- Test if a value is a symbol.
+      inline Value symbolp(Value v) {
+         return to_value(v == Value::nil or v == Value::t or is_symbol(v));
+      }
+
+      // -- Test if a value is a keyword symbol.
+      inline Value keywordp(Value v) {
+         if (auto sym = to_symbol_if_can(v))
+            return to_value(sym->has(SymbolAttribute::Keyword));
+         return Value::nil;
+      }
+
+      struct CmpByName {
+         template<typename T>
+         bool operator()(const T& x, const T& y) const {
+            return std::less<String>()(x.name, y.name);
+         }
+      };
+
+      template<typename T>
+      inline const T* setf_symbol_function(Symbol* sym, const T* fun) {
+         sym->function = fun;
+         return fun;
+      }
+
+      // -- Argument binding as value.
+      // Binding a parameter to a value in a call.
+      struct Binding : Dynamic {
+         Symbol* symbol;
+         Value value;
+         void accept(Visitor&) const override;
+      };
+      
+      // -- Environments.
+      struct Environment {
+         struct Binding {
+            Symbol* symbol;
+            Value value;
+         };
+
+         Environment();
+         ~Environment();
+
+         void bind(Symbol*, Value);
+         Binding* lookup(InternedString);
+      private:
+         std::vector<Binding> lexical;
+         std::vector<Binding> dynamic;
+      };
+
+      // -------------
+      // -- Package --
+      // -------------
+      struct Package : Dynamic {
+         const InternedString name;
+         std::set<Symbol, CmpByName> symbols;
+
+         explicit Package(InternedString);
+         void accept(Visitor&) const override;
+         Symbol* make_symbol(InternedString);
+         Symbol* find_symbol(InternedString);
+      };
+
+      // --------------
+      // -- Function --
+      // --------------
+      struct FunctionBase : Callable {
+         const Symbol* name;
+         Value type;
+         FunctionBase(const Symbol* n, Value t = Value::nil)
+               : name(n), type(t) { }
+         void accept(Visitor&) const override;
+      };
+
+      // ------------------------
+      // -- Builtin Operations --
+      // ------------------------
+      // Types for native implementation of builtin operators.
+      struct BasicContext;
+
+      template<typename... Ts>
+      using RuntimeOperation = Value(*)(BasicContext*, Ts...);
+      using NullaryCode = RuntimeOperation<>;
+      using UnaryCode = RuntimeOperation<Value>;
+      using BinaryCode = RuntimeOperation<Value, Value>;
+      using TernaryCode = RuntimeOperation<Value, Value, Value>;
+
+      template<typename Code>
+      struct BuiltinFunction : FunctionBase {
+         Code code;
+         BuiltinFunction(const Symbol* n, Code c)
+               : FunctionBase(n), code(c)
+         { }
+         void accept(Visitor&) const override;
+      };
+
+      using NullaryOperator = BuiltinFunction<NullaryCode>;
+      using UnaryOperator = BuiltinFunction<UnaryCode>;
+      using BinaryOperator = BuiltinFunction<BinaryCode>;
+      using TernaryOperator = BuiltinFunction<TernaryCode>;
+
+      // -- Operand stack.
+      struct OperandStack : private std::vector<Value> {
+         using super = std::vector<Value>;
+         using iterator = std::reverse_iterator<super::iterator>;
+         using super::size;
+         using super::empty;
+         iterator begin() { return rbegin(); }
+         iterator end() { return rend(); }
+         Value top() { return back(); }
+         void push(Value v) { push_back(v); }
+         Value pop() { auto v = back(); pop_back(); return v; }
+         void operator-=(std::size_t i) { resize(size() - i); }
+         Value operator[](std::size_t i) {
+            return super::operator[](size() - i - 1);
+         }
+      };
+
+      // -- Dynamic::Visitor --
+      struct Dynamic::Visitor {
+         virtual void visit(const Symbol&) = 0;
+         virtual void visit(const Binding&) = 0;
+         virtual void visit(const Package&) = 0;
+         virtual void visit(const FunctionBase&) = 0;
+         virtual void visit(const NullaryOperator&);
+         virtual void visit(const UnaryOperator&);
+         virtual void visit(const BinaryOperator&);
+      };
+
+      template<typename Code>
+      void BuiltinFunction<Code>::accept(Visitor& v) const { v.visit(*this); }
+
+      // ------------------
+      // -- BasicContext --
+      // ------------------
+      // Provides basic evaluation services.
+      struct BasicContext : StringPool {
+         BasicContext();
+         ~BasicContext();
+
+         Package* make_package(InternedString);
+         Symbol* make_keyword(InternedString);
+         Pair make_pair(Value, Value);
+         const NullaryOperator* make_operator(Symbol*, NullaryCode);
+         const UnaryOperator* make_operator(Symbol*, UnaryCode);
+         const BinaryOperator* make_operator(Symbol*, BinaryCode);
+         const TernaryOperator* make_operator(Symbol*, TernaryCode);
+
+         Package* keyword_package() const { return keywords; }
+         Package* homeless_package() const { return homeless; }
+
+      protected:
+         std::set<Package, CmpByName> packages;
+         Memory::Factory<ConsCell> conses;
+         Memory::Factory<NullaryOperator> nullaries;
+         Memory::Factory<UnaryOperator> unaries;
+         Memory::Factory<BinaryOperator> binaries;
+         Memory::Factory<TernaryOperator> ternaries;
+         Package* keywords;
+         Package* homeless;
+      };
+   };
+}
+
+#endif  // OPENAXIOM_VM_INCLUDED
+
diff --git a/src/include/sexpr.H b/src/include/sexpr.H
deleted file mode 100644
index 6920e436..00000000
--- a/src/include/sexpr.H
+++ /dev/null
@@ -1,419 +0,0 @@
-// Copyright (C) 2010-2014, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of The Numerical Algorithms Group Ltd. nor the
-//       names of its contributors may be used to endorse or promote products
-//       derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_SEXPR_included
-#define OPENAXIOM_SEXPR_included
-
-// --% Author: Gabriel Dos Reis.
-// --% Description:
-// --%   A simple support for s-expressions.  By design, no ambition
-// --%   for full-fledged Common Lisp reader capability.  Rather,
-// --%   the aim is a simple data structure for exchanging data
-// --%   between several components of the OpenAxiom system.
-// --%   Users interested in fullblown Lisp syntax should seek
-// --%   to acquire Lisp systems, many of which are freely available.
-
-#include <iosfwd>
-#include <vector>
-#include <open-axiom/storage>
-#include <open-axiom/token>
-
-namespace OpenAxiom {
-   namespace Sexpr {
-      // ------------
-      // -- Lexeme --
-      // ------------
-      struct Lexeme {
-         enum Type {
-            unknown,                 // unidentified token
-            semicolon,               // ";" for comment
-            dot,                     // "."
-            comma,                   // ","
-            open_paren,              // "("
-            close_paren,             // ")"
-            apostrophe,              // "'"
-            backquote,               // "`"
-            backslash,               // "\\"
-            sharp_open_paren ,       // "#("
-            sharp_apostrophe,        // "#'"
-            sharp_colon,             // "#:"
-            sharp_plus,              // "#+"
-            sharp_minus,             // "#-"
-            sharp_dot,               // "#."
-            comma_at,                // ",@"
-            integer,                 // integer literal
-            character,               // character literal
-            string,                  // string literal
-            identifier,              // plain identifier
-            sharp_integer_equal,     // anchor definition, #n=<form>
-            sharp_integer_sharp      // back reference, #n#
-         };
-
-         std::pair<const Byte*, const Byte*> boundary;
-         Ordinal line;
-         const Byte* begin() const { return boundary.first; }
-         const Byte* end() const { return boundary.second; }
-         Ordinal size() const { return end() - begin(); }
-      };
-
-      // ------------
-      // -- Syntax --
-      // ------------
-      // Base class of syntax object classes.
-      struct Syntax {
-         struct Visitor;        // base class of syntax visitors
-         virtual void accept(Visitor&) const = 0;
-      };
-
-      // ----------------
-      // -- AtomSyntax --
-      // ----------------
-      // An atom is a syntax object consisting of exatly one token.
-      // This should not be confused with the notion of atom
-      // in Lisp languages. 
-      struct AtomSyntax : Syntax {
-         const Lexeme& lexeme() const { return lex; }
-      protected:
-         Lexeme lex;
-         explicit AtomSyntax(const Lexeme&);
-      };
-
-      // -------------------
-      // -- IntegerSyntax --
-      // -------------------
-      // Integer literal syntax objects
-      struct IntegerSyntax : AtomSyntax {
-         explicit IntegerSyntax(const Lexeme&);
-         void accept(Visitor&) const;
-      };
-
-      // ---------------------
-      // -- CharacterSyntax --
-      // ---------------------
-      // Character literal syntax objects.
-      struct CharacterSyntax : AtomSyntax {
-         explicit CharacterSyntax(const Lexeme&);
-         void accept(Visitor&) const;
-      };
-
-      // ------------------
-      // -- StringSyntax --
-      // ------------------
-      // Striing literal syntax objjects.
-      struct StringSyntax : AtomSyntax {
-         explicit StringSyntax(const Lexeme&);
-         void accept(Visitor&) const;
-      };
-
-      // ------------------
-      // -- SymbolSyntax --
-      // ------------------
-      struct SymbolSyntax : AtomSyntax {
-         enum Kind {
-            ordinary   = 0x0,   // an interned symbol
-            uninterned = 0x1,   // uninterned symbol
-            absolute   = 0x2,   // case-sensitive symbol
-            keyword    = 0x4,   // a keyword symbol
-         };
-         SymbolSyntax(const Lexeme&, Kind);
-         Kind kind() const { return sort; }
-         const Byte* begin() const { return lexeme().begin(); }
-         const Byte* end() const { return lexeme().end(); }
-         std::size_t size() const { return lexeme().size(); }
-         Byte operator[](std::size_t i) const { return begin()[i]; }
-         void accept(Visitor&) const;
-      private:
-         const Kind sort;
-      };
-
-      // ---------------------
-      // -- ReferenceSyntax --
-      // ---------------------
-      // Back reference object to a syntax object.
-      struct ReferenceSyntax : AtomSyntax {
-         ReferenceSyntax(const Lexeme&, Ordinal);
-         size_t tag() const { return pos; }
-         void accept(Visitor&) const;
-      private:
-         Ordinal pos;
-      };
-
-      // ------------------
-      // -- AnchorSyntax --
-      // ------------------
-      // Base anchor syntax object.
-      struct AnchorSyntax : Syntax {
-         AnchorSyntax(size_t, const Syntax*);
-         size_t ref() const { return tag; }
-         const Syntax* value() const { return val; }
-         void accept(Visitor&) const;
-      private:
-         const size_t tag;
-         const Syntax* const val;
-      };
-
-      // -- Abstract over common implementation of unary special operators.
-      template<typename T>
-      struct unary_form : Syntax {
-         const Syntax* body() const { return form; }
-         void accept(Visitor&) const;
-      protected:
-         unary_form(const Syntax* f) : form(f) { }
-      private:
-         const Syntax* const form;
-      };
-
-      template<typename T>
-      struct binary_form : Syntax {
-         const Syntax* first() const { return rep.first; }
-         const Syntax* second() const { return rep.second; }
-         void accept(Visitor&) const;
-      protected:
-         binary_form(const Syntax* f, const Syntax* s) : rep(f, s) { }
-      private:
-         std::pair<const Syntax*, const Syntax*> rep;
-      };
-
-      // -----------------
-      // -- QuoteSyntax --
-      // -----------------
-      // Quotation syntax object.
-      struct QuoteSyntax : unary_form<QuoteSyntax> {
-         explicit QuoteSyntax(const Syntax*);
-      };
-      
-      // ---------------------
-      // -- AntiquoteSyntax --
-      // ---------------------
-      // Quasi-quotation syntax object.
-      struct AntiquoteSyntax : unary_form<AntiquoteSyntax> {
-         explicit AntiquoteSyntax(const Syntax*);
-      };
-      
-      // ------------
-      // -- Expand --
-      // ------------
-      // Expansion request inside a quasi-quotation.
-      struct Expand : unary_form<Expand> {
-         explicit Expand(const Syntax*);
-      };
-      
-      // ----------
-      // -- Eval --
-      // ----------
-      // Read-time evaluation request syntax object.
-      struct Eval : unary_form<Eval> {
-         explicit Eval(const Syntax*);
-      };
-      
-      // ------------
-      // -- Splice --
-      // ------------
-      // Splice request syntax object inside a quasi-quotation.
-      struct Splice : unary_form<Splice> {
-         explicit Splice(const Syntax*);
-      };
-      
-      // --------------
-      // -- Function --
-      // --------------
-      // Function literal syntax object.
-      struct Function : unary_form<Function> {
-         explicit Function(const Syntax*);
-      };
-
-      // -------------
-      // -- Include --
-      // -------------
-      // Conditional inclusion syntax object
-      struct Include : binary_form<Include> {
-         Include(const Syntax*, const Syntax*);
-      };
-
-      // -------------
-      // -- Exclude --
-      // -------------
-      // Conditional exclusion syntax object
-      struct Exclude : binary_form<Exclude> {
-         Exclude(const Syntax*, const Syntax*);
-      };
-
-      // ----------------
-      // -- ListSyntax --
-      // ----------------
-      // List syntax objects.
-      struct ListSyntax : Syntax, private std::vector<const Syntax*> {
-         typedef std::vector<const Syntax*> base;
-         using base::const_iterator;
-         using base::begin;
-         using base::end;
-         using base::rbegin;
-         using base::rend;
-         using base::size;
-         using base::empty;
-         using base::front;
-
-         ListSyntax();
-         ListSyntax(const base&, bool);
-         ~ListSyntax();
-         void accept(Visitor&) const;
-         bool dotted() const { return dot; }
-      private:
-         bool dot;
-      };
-      
-      // ------------------
-      // -- VectorSyntax --
-      // ------------------
-      // VectorSyntax syntax objects.
-      struct VectorSyntax : Syntax, private std::vector<const Syntax*> {
-         typedef std::vector<const Syntax*> base;
-         using base::const_iterator;
-         using base::begin;
-         using base::end;
-         using base::size;
-         using base::operator[];
-         using base::empty;
-
-         VectorSyntax();
-         explicit VectorSyntax(const base&);
-         ~VectorSyntax();
-         void accept(Visitor&) const;
-      };
-
-      // ---------------------
-      // -- Syntax::Visitor --
-      // ---------------------
-      struct Syntax::Visitor {
-         virtual void visit(const IntegerSyntax&) = 0;
-         virtual void visit(const CharacterSyntax&) = 0;
-         virtual void visit(const StringSyntax&) = 0;
-         virtual void visit(const SymbolSyntax&) = 0;
-         virtual void visit(const ReferenceSyntax&) = 0;
-         virtual void visit(const AnchorSyntax&) = 0;
-         virtual void visit(const QuoteSyntax&) = 0;
-         virtual void visit(const AntiquoteSyntax&) = 0;
-         virtual void visit(const Expand&) = 0;
-         virtual void visit(const Eval&) = 0;
-         virtual void visit(const Splice&) = 0;
-         virtual void visit(const Function&) = 0;
-         virtual void visit(const Include&) = 0;
-         virtual void visit(const Exclude&) = 0;
-         virtual void visit(const ListSyntax&) = 0;
-         virtual void visit(const VectorSyntax&) = 0;
-      };
-
-      template<typename T>
-      void
-      unary_form<T>::accept(Visitor& v) const {
-         v.visit(static_cast<const T&>(*this));
-      }
-
-      template<typename T>
-      void
-      binary_form<T>::accept(Visitor& v) const {
-         v.visit(static_cast<const T&>(*this));
-      }
-
-      // ---------------
-      // -- Allocator --
-      // ---------------
-      // Allocator of syntax objects.
-      struct Allocator {
-         Allocator();
-         ~Allocator();
-
-         const IntegerSyntax* make_integer(const Lexeme&);
-         const CharacterSyntax* make_character(const Lexeme&);
-         const StringSyntax* make_string(const Lexeme&);
-         const SymbolSyntax* make_symbol(SymbolSyntax::Kind, const Lexeme&);
-         const ReferenceSyntax* make_reference(size_t, const Lexeme&);
-         const AnchorSyntax* make_anchor(size_t, const Syntax*);
-         const QuoteSyntax* make_quote(const Syntax*);
-         const AntiquoteSyntax* make_antiquote(const Syntax*);
-         const Expand* make_expand(const Syntax*);
-         const Eval* make_eval(const Syntax*);
-         const Splice* make_splice(const Syntax*);
-         const Function* make_function(const Syntax*);
-         const Include* make_include(const Syntax*, const Syntax*);
-         const Exclude* make_exclude(const Syntax*, const Syntax*);
-         const ListSyntax* make_list(const std::vector<const Syntax*>&, bool = false);
-         const VectorSyntax* make_vector(const std::vector<const Syntax*>&);
-         
-      private:
-         Memory::Factory<IntegerSyntax> ints;
-         Memory::Factory<CharacterSyntax> chars;
-         Memory::Factory<StringSyntax> strs;
-         Memory::Factory<SymbolSyntax> syms;
-         Memory::Factory<AnchorSyntax> ancs;
-         Memory::Factory<ReferenceSyntax> refs;
-         Memory::Factory<QuoteSyntax> quotes;
-         Memory::Factory<AntiquoteSyntax> antis;
-         Memory::Factory<Expand> exps;
-         Memory::Factory<Function> funs;
-         Memory::Factory<Include> incs;
-         Memory::Factory<Exclude> excs;
-         Memory::Factory<Eval> evls;
-         Memory::Factory<Splice> spls;
-         Memory::Factory<ListSyntax> lists;
-         Memory::Factory<VectorSyntax> vectors;
-         ListSyntax empty_list;
-         VectorSyntax empty_vector;
-      };
-
-      // -- Reader --
-      struct RawInput {
-         const Byte* start;
-         const Byte* end;
-         Ordinal lineno;
-      };
-
-      struct Reader {
-         struct State {
-            RawInput bytes;
-            const Byte* cur;
-            const Byte* line;
-            Allocator alloc;
-         };
-
-         explicit Reader(const RawInput&);
-         Reader(const Byte*, const Byte*);
-         const Byte* position(Ordinal);
-         bool at_start() const { return st.cur == st.bytes.start; }
-         const Syntax* read();
-      private:
-         State st;
-      };
-   }
-}
-
-#endif  // OPENAXIOM_SEXPR_included
diff --git a/src/include/storage.H b/src/include/storage.H
deleted file mode 100644
index e414dec2..00000000
--- a/src/include/storage.H
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright (C) 2010-2013, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom. nor the names of its contributors
-//       may be used to endorse or promote products derived from this
-//       software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// --% Author: Gabriel Dos Reis
-// --% Description:
-// --%   Memory management facility.  Acquire raw memory directly
-// --%   from the host OS.  Provide random access read to
-// --%   files through file mapping.
-
-#ifndef OPENAXIOM_STORAGE_included
-#define OPENAXIOM_STORAGE_included
-
-#include <open-axiom/config>
-#include <stddef.h>
-#include <new>
-#include <cmath>
-#include <string>
-
-namespace OpenAxiom {
-   // Datatype for the unit of storage.
-   using Byte = unsigned char;
-
-   // -----------------
-   // -- SystemError --
-   // -----------------
-   // Objects of (type derived from) this type are used to report
-   // error orignating from the OpenAxiom core system.
-   struct SystemError {
-      explicit SystemError(const std::string&);
-      virtual ~SystemError();
-      // Return the text of the diagnostic message.
-      virtual const std::string& message() const;
-   protected:
-      const std::string text;
-   };
-
-   // Report a file system error
-   void filesystem_error(const std::string&);
-   
-   namespace Memory {
-      // Datatype for pointers to data.
-      using Pointer = void*;
-
-      // Precision of the host OS storage page unit in byte count
-      size_t page_size();
-
-      // Acquire raw memory from the host OS.
-      Pointer os_acquire_raw_memory(size_t);
-
-      // Release raw storage to the hosting OS.  The first operand must
-      // be a pointer value previously returned by `os_acquire_raw_memory'.
-      // Otherwise, the result is undefined.
-      void os_release_raw_memory(Pointer, size_t);
-
-      // Acquire `n' pages of memory storage from the host OS.
-      inline Pointer
-      acquire_raw_pages(size_t n) {
-         return os_acquire_raw_memory(n * page_size());
-      }
-
-      // Release `n' pages of storage starting the location `p'.
-      inline void
-      release_raw_pages(Pointer p, size_t n) {
-         os_release_raw_memory(p, n * page_size());
-      }
-      
-      // -------------
-      // -- Storage --
-      // -------------
-      // This class provides low-level abstractions intented for use
-      // to implement higher level storage abstractions.
-      struct Storage {
-         // Objects of this abstract datatype hold storage objects.
-         struct Handle;
-         
-         // Return the storage pointed to by the operand.  It
-         // must be a pointer value previously returned by `acquire'.
-         // Otherwise, the result is undefined.
-         static void release(Handle*);
-         
-         // Return the start address of storage area.  Clients would
-         // want to add padding bytes necessary to accomodate alignment
-         // requirements.  
-         // Note: this should not be confused with the address of
-         // the handle object.
-         static Pointer begin(Handle*);
-
-         // Courtesy conversion function from pointer to byte address.
-         static Byte* byte_address(Pointer h) {
-            return static_cast<Byte*>(h);
-         }
-
-         // Round up `n' to a multiple of `a', a power of 2.
-         static size_t
-         round_up(size_t n, size_t a) {
-            return (n + a - 1) & ~(a - 1);
-         }
-      };
-
-      // -------------------------
-      // -- SinglyLinkedStorage --
-      // -------------------------
-      // This class implements a simple single-linked list of storage
-      // objects.  Each storage object in the link is created with
-      // a specific starting alignment requirements.
-      struct SinglyLinkedStorage : Storage {
-         // Return the previous handle in the link chain.
-         static Handle*& previous(Handle*);
-      };
-
-      // -------------------------
-      // -- DoublyLinkedStorage --
-      // -------------------------
-      // Like SinglyLinkedStorage, except that the chain of storage
-      // object supports bidirectional travervsal.
-      struct DoublyLinkedStorage : Storage {
-         // Same as Storage::acquire, except that begin(h) returns an
-         // address that satisfies the alignment requirement `a'.
-         static Handle* acquire(size_t n, size_t a);
-         
-         // Return the previous handle in the link chain.
-         static Handle*& previous(Handle*);
-         
-         // Return the next handle in the link chain.
-         static Handle*& next(Handle*);
-      };
-
-      // ------------------
-      // -- BlockStorage --
-      // ------------------
-      // This class implements a simple single-linked list of block storage.
-      // Each block maintains information about the next allocatable
-      // address within that block.
-      struct BlockStorage : SinglyLinkedStorage {
-         // Same as SinglyLinkedStorage::acquire(); initialize internal
-         // bookkeepking machinery.
-         static Handle* acquire(size_t n, size_t a);
-
-         // Return the next allocatable address within the given block.
-         static Pointer next_address(Handle*);
-
-         // Return the amount of allocatable byte in the given block.
-         static size_t room(Handle*);
-
-         // Set `n' bytes aside with the given storage block.
-         static Pointer book(Handle*, size_t);
-      };
-
-      // -----------
-      // -- Arena --
-      // -----------
-      // Extensible storage holding objects of a given type.
-      // The totality of all objects held in such a storage does not
-      // necessarily constitute a contiguous block.  However,
-      // it is guaranteed that objects allocated in a single call
-      // to `allocate()' occupy a contiguous block of storage.
-      template<typename T>
-      struct Arena : protected BlockStorage {
-         // Acquire storage capable of holding `n' objects of type `T'.
-         explicit Arena(size_t);
-         // Release all storage acquired by this object, upon end of life.
-         ~Arena();
-         // allocate storage for `n' more objects of type `T'.
-         T* allocate(size_t);
-         // Number of objects of type `T' allocated in this storage.
-         size_t population() const;
-
-      protected:
-         // Address of the first object of type `T' in a storage.
-         static T* first_object(Handle* h) {
-            return static_cast<T*>(BlockStorage::begin(h));
-         }
-
-         // Address of one-past-the-end object of type `T' in this storage.
-         static T* last_object(Handle* h) {
-            return static_cast<T*>(BlockStorage::next_address(h));
-         }
-
-         // Number of objects allocated in a storage.
-         static size_t object_count(Handle* h) {
-            return last_object(h) - first_object(h);
-         }
-
-         BlockStorage::Handle* store; // active storage to allocate from
-      };
-
-      template<typename T>
-      size_t
-      Arena<T>::population() const {
-         size_t n = 0;
-         for (Handle* h = store; h != nullptr; h = previous(h))
-            n += object_count(h);
-         return n;
-      }
-
-      template<typename T>
-      T*
-      Arena<T>::allocate(size_t n) {
-         const size_t sz = n * sizeof(T);
-         if (BlockStorage::room(store) < sz) {
-            // Not enough room left.  Make sure we allocate storage
-            // at least as big as the current.
-            Handle* h = acquire(std::max(n, object_count(store)), alignof(T));
-            previous(h) = store;
-            store = h;
-         }
-         return static_cast<T*>(BlockStorage::book(store, sz));
-      }
-
-      template<typename T>
-      Arena<T>::Arena(size_t n)
-            : store(BlockStorage::acquire(n * sizeof (T), alignof (T)))
-      { }
-      
-      template<typename T>
-      Arena<T>::~Arena() {
-         // Release storage in the reverse order of their
-         // their allocation.
-         while (store != nullptr) {
-            Handle* current = store;
-            store = BlockStorage::previous(store);
-            BlockStorage::release(current);
-         }
-      }
-
-      // -------------
-      // -- Factory --
-      // -------------
-      template<typename T>
-      struct Factory : Arena<T> {
-         using Handler = typename Arena<T>::Handle;
-
-         Factory() : Arena<T>(nominal_population()) { }
-         ~Factory();
-
-         // Allocate storage and value-construct an object of type `T'.
-         T* make() {
-            return new(this->allocate(1)) T{ };
-         }
-
-         // Allocate storage and construct an object of type `T'.
-         template<typename... Args>
-         T* make(const Args&... args) {
-            return new(this->allocate(1)) T{args...};
-         }
-
-      private:
-         // Return 1 or the number of objects that can fit in a page unit.
-         static size_t nominal_population() {
-            const size_t psz = page_size();
-            if (sizeof (T) > psz)
-               return 1;
-            return psz / sizeof(T);
-         }
-      };
-
-      // Destroy objects in the reverse order of their construction.
-      template<typename T>
-      Factory<T>::~Factory() {
-         for (auto s = this->store; s != nullptr; s = Arena<T>::previous(s)) {
-            T* last = Arena<T>::last_object(s);
-            for (--last; last >= Arena<T>::first_object(s); --last)
-               last->~T();
-         }
-      }
-   }
-}
-
-#endif  // OPENAXIOM_STORAGE_included
-
diff --git a/src/include/structure.H b/src/include/structure.H
deleted file mode 100644
index 33c084f2..00000000
--- a/src/include/structure.H
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (C) 2013, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom, nor the names of its contributors may
-//       be used to endorse or promote products derived from this software
-//       without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_STRUCTURE_included
-#define OPENAXIOM_STRUCTURE_included
-
-namespace OpenAxiom {
-   // -- helper classes for structural abstractions --
-   namespace structure {
-      // unary structures
-      template<typename T>
-      struct unary {
-         explicit constexpr unary(const T& t) : arg(t) { };
-         constexpr const T& operand() const { return arg; }
-      private:
-         const T arg;
-      };
-
-      // binary structures
-      template<typename T, typename U = T>
-      struct binary {
-         constexpr binary(const T& t, const U& u) : arg0(t), arg1(u) { };
-         constexpr const T& first() const { return arg0; }
-         constexpr const U& second() const { return arg1; }
-      private:
-         const T arg0;
-         const U arg1;
-      };
-
-      // ternary structures
-      template<typename T, typename U = T, typename V = U>
-      struct ternary {
-         constexpr ternary(const T& t, const U& u, const V& v)
-               : arg0(t), arg1(u), arg2(v) { }
-         constexpr const T& first() const { return arg0; }
-         constexpr const U& second() const { return arg1; }
-         constexpr const V& third() const { return arg2; }
-      private:
-         const T arg0;
-         const U arg1;
-         const V arg2;
-      };
-   }
-}
-
-#endif  // OPENAXIOM_STRUCTURE_included
diff --git a/src/include/token-value.def b/src/include/token-value.def
deleted file mode 100644
index 9a949b86..00000000
--- a/src/include/token-value.def
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (C) 2014, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom. nor the names of its contributors
-//       may be used to endorse or promote products derived from this
-//       software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-
-OPENAXIOM_DEFINE_TOKEN(Unknown, "<unknown>", Unclassified, Language::All)
-OPENAXIOM_DEFINE_TOKEN(Apostrophe, "'", Punctuator, Language::All)
-OPENAXIOM_DEFINE_TOKEN(Backquote, "`", Punctuator, Language::All)
-OPENAXIOM_DEFINE_TOKEN(Bar, "|", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Dot, ".", Punctuator, Language::All)
-OPENAXIOM_DEFINE_TOKEN(DotDot, "..", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Colon, ":", Punctuator, Language::All)
-OPENAXIOM_DEFINE_TOKEN(ColonColon, "::", Operator, Language::All)
-OPENAXIOM_DEFINE_TOKEN(ColonDash, ":-", Operator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(ColonEq, ":=", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(At, "@", Operator, Language::All)
-OPENAXIOM_DEFINE_TOKEN(Exclamation, "!", Punctuator, Language::Boot)
-OPENAXIOM_DEFINE_TOKEN(Comma, ",", Punctuator, Language::All)
-OPENAXIOM_DEFINE_TOKEN(CommaAt, ",@", Operator, Language::Lisp)
-OPENAXIOM_DEFINE_TOKEN(Semicolon, ";", Punctuator, Language::All)
-OPENAXIOM_DEFINE_TOKEN(Star, "*", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(StarStar, "**", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Plus, "+", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Minus, "-", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Slash, "/", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(SlashSlash, "//", Operator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(SlashBackslash, "/\\", Operator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(Backslash, "\\", Operator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(BackslashSlash, "\\/", Operator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(BackslashBackslash, "\\\\", Operator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(Less, "<", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(LessEq, "<=", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Greater, ">", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(GreaterEq, ">=", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Eq, "=", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(EqEq, "==", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Tilde, "~", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(TildeEq, "~=", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Caret, "^", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Sharp, "#", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(SharpLeftParen, "#(", Punctuator, Language::Lisp)
-OPENAXIOM_DEFINE_TOKEN(SharpApostrophe, "#'", Operator, Language::Lisp)
-OPENAXIOM_DEFINE_TOKEN(SharpColon, "#:", Operator, Language::Lisp)
-OPENAXIOM_DEFINE_TOKEN(SharpPlus, "#+", Punctuator, Language::Lisp)
-OPENAXIOM_DEFINE_TOKEN(SharpMinus, "#-", Punctuator, Language::Lisp)
-OPENAXIOM_DEFINE_TOKEN(SharpDot, "#.", Operator, Language::Lisp)
-OPENAXIOM_DEFINE_TOKEN(Dollar, "$", Operator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(Ampersand, "&", Operator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(RightArrow, "->", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(LeftArrow, "<-", Operator, Language::Boot)
-OPENAXIOM_DEFINE_TOKEN(Implies, "=>", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Equiv, "<=>", Keyword, Language::Boot)
-OPENAXIOM_DEFINE_TOKEN(MapsTo, "+->", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(FatArrow, "==>", Keyword, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(OpenParen, "(", Punctuator, Language::All)
-OPENAXIOM_DEFINE_TOKEN(CloseParen, ")", Punctuator, Language::All)
-OPENAXIOM_DEFINE_TOKEN(OpenMetaParen, "(|", Punctuator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(CloseMetaParen, "|)", Punctuator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(OpenBracket, "[", Punctuator, Language::All)
-OPENAXIOM_DEFINE_TOKEN(CloseBracket, "]", Punctuator, Language::All)
-OPENAXIOM_DEFINE_TOKEN(OpenMetaBracket, "[|", Punctuator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(CloseMetaBracket, "|]", Punctuator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(OpenBrace, "{", Punctuator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(CloseBrace, "}", Punctuator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(OpenMetaBrace, "{|", Punctuator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(CloseMetaBrace, "|}", Punctuator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(OpenChevron, "<<", Operator, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(CloseChevron, ">>", Operator, Language::Spad)
-
-OPENAXIOM_DEFINE_TOKEN(Wisecrack, "--", Comment, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Commentary, "++", Comment, Language::BootSpad)
-
-OPENAXIOM_DEFINE_TOKEN(Add, "add", Keyword, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(And, "and", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Assume, "assume", Keyword, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(Break, "break", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(By, "by", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Case, "case", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Catch, "catch", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Cross, "cross", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Do, "do", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Else, "else", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Exists, "exists", Keyword, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(Finally, "finally", Keyword, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(For, "for", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Forall, "forall", Keyword, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(From, "from", Keyword, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(Function, "function", Keyword, Language::Boot)
-OPENAXIOM_DEFINE_TOKEN(Has, "has", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(If, "if", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Import, "import", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(In, "in", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Inline, "inline", Keyword, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(Is, "is", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Isnt, "isnt", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Iterate, "iterate", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Leave, "leave", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Macro, "macro", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Mod, "mod", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Namespace, "namespace", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Of, "of", Keyword, Language::Boot)
-OPENAXIOM_DEFINE_TOKEN(Or, "or", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Pretend, "pretend", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Quo, "quo", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Rem, "rem", Operator, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Repeat, "repeat", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Return, "return", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Rule, "rule", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Structure, "structure", Keyword, Language::Boot)
-OPENAXIOM_DEFINE_TOKEN(Then, "then", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(Throw, "throw", Keyword, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(Try, "try", Keyword, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(Until, "until", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(With, "with", Keyword, Language::Spad)
-OPENAXIOM_DEFINE_TOKEN(Where, "where", Keyword, Language::BootSpad)
-OPENAXIOM_DEFINE_TOKEN(While, "while", Keyword, Language::BootSpad)
diff --git a/src/include/token.H b/src/include/token.H
deleted file mode 100644
index b57b69d6..00000000
--- a/src/include/token.H
+++ /dev/null
@@ -1,670 +0,0 @@
-// Copyright (C) 2013-2014, Gabriel Dos Reis.
-// All rights reserved.
-// Written by Gabriel Dos Reis.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom. nor the names of its contributors
-//       may be used to endorse or promote products derived from this
-//       software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_TOKEN_included
-#define OPENAXIOM_TOKEN_included
-
-#include <stdint.h>
-#include <stack>
-#include <iosfwd>
-#include <open-axiom/Input>
-#include <open-axiom/dialect>
-
-namespace OpenAxiom {
-   // Categorization of Boot and Spad tokens.
-   enum class TokenCategory : uint8_t {
-      Unclassified,             // token of unknown class
-      Whitespace,               // sequence of white-space characters
-      Comment,                  // a description of an ignorable comment
-      Punctuator,               // a punctuator character
-      Operator,                 // an operator both symbolic and alphabetic
-      Integer,                  // an integer literal
-      FloatingPoint,            // a floating-point literal
-      String,                   // a string literal
-      Keyword,                  // a reserved word both symbolic and alphabetic
-      Identifier,               // an identifier
-      Formatting,               // a layout formatting token
-      Junk,                     // invalid/malformed token
-      EOS                       // end-of-token-stream indicator
-   };
-
-   std::ostream& operator<<(std::ostream&, TokenCategory);
-
-   // The abstract value associated with a token.
-   enum class TokenValue : uint8_t {
-#undef OPENAXIOM_DEFINE_TOKEN
-#define OPENAXIOM_DEFINE_TOKEN(T, ...)  T,
-#include <open-axiom/token-value>
-#undef OPENAXIOM_DEFINE_TOKEN
-      Artificial,               // Tokens after this are artificial
-      Indent,                   // new line indentation, greater than previous
-      Unindent,                 // new line indentation, less than previous
-      Justify,                  // align indentation with preceding line.
-
-      EndOfStream               // end of token stream
-   };
-
-   std::ostream& operator<<(std::ostream&, TokenValue);
-
-   // Datatypes for locating lines and columns.
-   using LineNumber = std::size_t;
-   using ColumnIndex = std::size_t;
-
-   struct Locus {
-      LineNumber line;
-      ColumnIndex column;
-   };
-
-   std::ostream& operator<<(std::ostream&, const Locus&);
-
-   // Program text region
-   struct Region {
-      Locus start;
-      Locus end;
-   };
-
-   // Given a symbolic or alphabetic token, retrieve its category
-   // and associated abstract value.
-   struct TokenClassification {
-      TokenCategory category;
-      TokenValue value;
-
-      explicit operator bool() const {
-         return category != TokenCategory::Unclassified;
-      }
-   };
-
-   TokenClassification classify(const std::string&);
-
-   // Token data structure: a region of text with a classification.
-   struct Token : TokenClassification, Region {
-      using Location = Locus;
-   };
-
-   // Cursor into a fragment.
-   struct FragmentCursor {
-      std::size_t line;         // index of a line in a fragment
-      std::size_t column;       // column number at line.
-
-      inline FragmentCursor& operator++() {
-         ++column;
-         return *this;
-      }
-
-      inline FragmentCursor operator++(int) {
-         auto tmp = *this;
-         ++*this;
-         return tmp;
-      }
-
-      inline FragmentCursor& operator--() {
-         --column;
-         return *this;
-      }
-
-      inline FragmentCursor operator--(int) {
-         auto tmp = *this;
-         --*this;
-         return tmp;
-      }
-   };
-
-   // -- Exception types
-   struct EndOfStringUnseen {
-      LineNumber line;
-      ColumnIndex column;
-   };
-
-   struct MissingExponent {
-      LineNumber line;
-      ColumnIndex column;
-   };
-
-   // Object of this datatype decompose a program fragment into a
-   // token stream.  The tokens are of type indicated by Tok.
-   template<typename Frag, typename Tok>
-   struct Tokenizer {
-      Tokenizer(Frag& f)
-            : frag(f),
-              pos{ 0, frag.front().indent }
-      {
-         indents.push(pos.column);
-      }
-
-      bool eos() const {
-         return pos.line >= frag.size()
-            or (pos.line + 1 == frag.size() and pos.column >= frag.back().size());
-      }
-
-      Tok get(Language = Language::Spad);
-   private:
-      Frag& frag;
-      FragmentCursor pos;
-      std::stack<ColumnIndex> indents;
-
-      std::size_t line_length() const { return frag(pos).size(); }
-      LineNumber next_line_number() const {
-         return pos.line + 1 < frag.size()
-            ? frag[pos.line + 1].number
-            : frag.back().number + 1;
-      }
-      ColumnIndex next_indentation() const {
-         return pos.line + 1 < frag.size() ? frag[pos.line + 1].indent : 0;
-      }
-
-      LineNumber line_number() const {
-         return pos.line < frag.size()
-            ? frag(pos).number
-            : frag.back().number + 1;
-      }
-
-      ColumnIndex column_number() const {
-         return pos.line < frag.size() ? pos.column : 0;
-      }
-
-      using Locus = typename Tok::Location;
-      Locus current_locus() {
-         return { line_number(), column_number() };
-      }
-   };
-
-   bool separator_or_punctuator(uint8_t);
-
-   template<typename T>
-   inline void comment_token(T& t, TokenValue v) {
-      t.category = TokenCategory::Comment;
-      t.value = v;
-   }
-
-   template<typename T>
-   inline void operator_token(T& t, TokenValue v) {
-      t.category = TokenCategory::Operator;
-      t.value = v;
-   }
-
-   template<typename T>
-   inline void punctuator_token(T& t, TokenValue v) {
-      t.category = TokenCategory::Punctuator;
-      t.value = v;
-   }
-
-   template<typename L, typename T>
-   static void junk(L& line, ColumnIndex& idx, T& t) {
-      while (idx < line.size() and not separator_or_punctuator(line[idx]))
-         ++idx;
-      t.category = TokenCategory::Junk;
-   }
-
-   template<typename L>
-   inline void
-   skip_whitespace(L& line, ColumnIndex& idx) {
-      while (idx < line.size() and isspace(line[idx]))
-         ++idx;
-   }
-
-   template<typename Frag, typename Tok>
-   void string_literal(Frag& frag, FragmentCursor& pos, Tok& t) {
-      bool done = false;
-      bool escape = false;
-      while (frag.covering(pos) && not done) {
-         switch (frag(pos)[pos.column++]) {
-         case '"': done = !escape;
-            // fallthrough
-         default: escape = false; break;
-         case '_':
-            if (pos.column == frag(pos).size()
-                and pos.line < frag.size() - 1) {
-               ++pos.line;
-               pos.column = 0;
-            }
-            else
-               escape = !escape;
-            break;
-         }
-      }
-      if (not done)
-         throw EndOfStringUnseen{ frag(pos).number, pos.column };
-      t.category = TokenCategory::String;
-   }
-
-   template<typename L>
-   void skip_to_end_of_integer(L& line, ColumnIndex& idx) {
-      while (idx < line.size() and isdigit(line[idx]))
-         ++idx;
-   }
-   
-   template<typename L, typename T>
-   void integer(L& line, ColumnIndex& idx, T& t) {
-      skip_to_end_of_integer(line, idx);
-      t.category = TokenCategory::Integer;
-   }
-
-   template<typename L, typename T>
-   T& number(L& line, ColumnIndex& idx, T& t) {
-      integer(line, idx, t);
-      if (idx >= line.size() or line[idx] != '.')
-         return t;
-      if (++idx >= line.size() or not isdigit(line[idx])) {
-         --idx;
-         return t;
-      }
-
-      t.category = TokenCategory::FloatingPoint;
-      skip_to_end_of_integer(line, idx);
-      if (idx >= line.size() or (line[idx] != 'e' and line[idx] != 'E'))
-         return t;
-      if (++idx < line.size() and (line[idx] == '+' or line[idx] == '-'))
-         ++idx;
-      if (idx >= line.size() or not isdigit(line[idx]))
-         throw MissingExponent{ line.number, idx };
-      skip_to_end_of_integer(line, idx);
-      return t;
-   }
-
-   inline bool
-   identifier_head(uint8_t c) {
-      return isalpha(c) or c == '%' or c == '_';
-   }
-
-   inline bool
-   identifier_part(uint8_t c) {
-      return identifier_head(c) or isdigit(c);
-   }
-
-   inline bool
-   identifier_suffix(uint8_t c) {
-      return c == '!' or c == '?';
-   }
-
-   inline bool internal_prefix(uint8_t c) {
-      return c == '%' or c == '$';
-   }
-
-   template<typename L>
-   inline void
-   skip_prefix(L& line, ColumnIndex& idx, uint8_t c) {
-      while (idx < line.size() and line[idx] == c)
-         ++idx;
-   }
-
-   template<typename L, typename T>
-   T& identifier(L& line, ColumnIndex& idx, T& t, Language dialect) {
-      t.category = TokenCategory::Identifier;
-
-      ColumnIndex start = --idx; // idx was ahead by 1.
-      if (dialect == Language::Boot and internal_prefix(line[idx]))
-         skip_prefix(line, idx, line[idx]);
-      bool saw_escape = false;
-      while (idx < line.size()) {
-         if (not identifier_part(line[idx]) and line[idx - 1] != '_')
-            break;
-         else if (line[idx] == '_')
-            saw_escape = true;
-         ++idx;
-      }
-      while (idx < line.size() and identifier_suffix(line[idx]))
-         ++idx;
-
-      if (saw_escape)
-         t.category = TokenCategory::Identifier;
-      else if (auto info = classify(line.sub_string(start, idx))) {
-         t.category = info.category;
-         t.value = info.value;
-      }
-      return t;
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   left_paren_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      punctuator_token(t, TokenValue::OpenParen);
-      if (frag.covering(pos) and frag[pos] == '|') {
-         ++pos;
-         t.value = TokenValue::OpenMetaParen;
-      }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   left_brace_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      punctuator_token(t, TokenValue::OpenBrace);
-      if (frag.covering(pos) and frag[pos] == '|') {
-         ++pos;
-         t.value = TokenValue::OpenMetaBrace;
-      }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   left_bracket_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      punctuator_token(t, TokenValue::OpenBracket);
-      if (frag.covering(pos) and frag[pos] == '|') {
-         ++pos;
-         t.value = TokenValue::OpenMetaBracket;
-      }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   colon_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      operator_token(t, TokenValue::Colon);
-      if (frag.covering(pos))
-         switch (frag[pos]) {
-         case ':': t.value = TokenValue::ColonColon; ++pos; break;
-         case '=': t.value = TokenValue::ColonEq; ++pos; break;
-         case '-': t.value = TokenValue::ColonDash; ++pos; break;
-         default: break;
-         }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   star_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      operator_token(t, TokenValue::Star);
-      if (frag.covering(pos) and frag[pos] == '*') {
-         t.value = TokenValue::StarStar;
-         ++pos;
-      }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   slash_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      operator_token(t, TokenValue::Slash);
-      if (frag.covering(pos))
-         switch (frag[pos]) {
-         case '/': t.value = TokenValue::SlashSlash; ++pos; break;
-         case '\\': t.value = TokenValue::SlashBackslash; ++pos; break;
-         default: break;
-         }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   backslash_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      operator_token(t, TokenValue::Backslash);
-      if (frag.covering(pos))
-         switch (frag[pos]) {
-         case '\\': t.value = TokenValue::BackslashBackslash; ++pos; break;
-         case '/': t.value = TokenValue::BackslashSlash; ++pos; break;
-         default: break;
-         }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   less_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      operator_token(t, TokenValue::Less);
-      if (frag.covering(pos))
-         switch (frag[pos]) {
-         case '-': t.value = TokenValue::LeftArrow; ++pos; break;
-         case '<': t.value = TokenValue::OpenChevron; ++pos; break;
-         case '=':
-            t.value = TokenValue::LessEq;
-            if (frag.covering(++pos) and frag[pos] == '>') {
-               t.value = TokenValue::Equiv;
-               ++pos;
-            }
-            break;
-         default: break;
-         }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   equal_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      operator_token(t, TokenValue::Eq);
-      if (frag.covering(pos))
-         switch (frag[pos]) {
-         case '>': t.value = TokenValue::Implies; ++pos; break;
-         case '=':
-            t.value = TokenValue::EqEq;
-            if (frag.covering(++pos) and frag[pos] == '>') {
-               t.value = TokenValue::FatArrow;
-               ++pos;
-            }
-            break;
-         default: break;
-         }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   tilde_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      operator_token(t, TokenValue::Tilde);
-      if (frag.covering(pos) and frag[pos] == '=') {
-         t.value = TokenValue::TildeEq;
-         ++pos;
-      }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   greater_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      operator_token(t, TokenValue::Greater);
-      if (frag.covering(pos))
-         switch (frag[pos]) {
-         case '=': t.value = TokenValue::GreaterEq; ++pos; break;
-         case '>': t.value = TokenValue::CloseChevron; ++pos; break;
-         }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   bar_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      punctuator_token(t, TokenValue::Bar);
-      if (frag.covering(pos))
-         switch (frag[pos]) {
-         case ']': t.value = TokenValue::CloseMetaBracket; ++pos; break;
-         case '}': t.value = TokenValue::CloseMetaBrace; ++pos; break;
-         case ')': t.value = TokenValue::CloseMetaParen; ++pos; break;
-         default: break;
-         }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   minus_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      operator_token(t, TokenValue::Minus); 
-      if (frag.covering(pos))
-         switch (frag[pos]) {
-         case '>': t.value = TokenValue::RightArrow; ++pos; break;
-         case '-':
-            comment_token(t, TokenValue::Wisecrack);
-            pos.column = frag(pos).size();
-            break;
-         }
-   }
-
-
-   template<typename Frag, typename Tok>
-   static void
-   plus_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      operator_token(t, TokenValue::Plus);
-      if (frag.covering(pos))
-         switch (frag[pos]) {
-         case '+':
-            comment_token(t, TokenValue::Commentary);
-            pos.column = frag(pos).size();
-            break;
-         case '-':
-            if (pos.column + 1 < frag(pos).size()
-                and frag(pos)[pos.column + 1] == '>') {
-               t.value = TokenValue::MapsTo;
-               pos.column += 2;
-            }
-            break;
-         default: break;
-         }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   dot_et_al(Frag& frag, FragmentCursor& pos, Tok& t) {
-      operator_token(t, TokenValue::Dot);
-      if (frag.covering(pos) and frag[pos] == '.') {
-         t.value = TokenValue::DotDot;
-         ++pos;
-      }
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   dollar_et_al(Frag& frag, FragmentCursor& pos, Tok& t, Language dialect) {
-      if (dialect != Language::Boot or not frag.covering(pos)
-          or separator_or_punctuator(frag[pos]))
-         operator_token(t, TokenValue::Dollar);
-      else
-         identifier(frag(pos), pos.column, t, dialect);
-   }
-
-   template<typename Frag, typename Tok>
-   static void
-   sharp_et_al(Frag& frag, FragmentCursor& pos, Tok& t, Language dialect) {
-      if (dialect != Language::Lisp)
-         operator_token(t, TokenValue::Sharp);
-      else if (frag.covering(pos))
-         switch (frag[pos++]) {
-         case '(': punctuator_token(t, TokenValue::SharpLeftParen); break;
-         case '\'': operator_token(t, TokenValue::SharpApostrophe); break;
-         case ':': operator_token(t, TokenValue::SharpColon); break;
-         case '+': punctuator_token(t, TokenValue::SharpPlus); break;
-         case '-': punctuator_token(t, TokenValue::SharpMinus); break;
-         case '.': operator_token(t, TokenValue::SharpDot); break;
-         default: --pos; break;
-         }
-   }
-
-
-   template<typename Frag, typename Tok>
-   Tok Tokenizer<Frag, Tok>::get(Language dialect) {
-      Tok t { };
-      t.start = current_locus();
-      
-      if (eos()) {
-         t.category = TokenCategory::EOS;
-         t.end = current_locus();
-         return t;
-      }
-      else if (isspace(frag[pos])) {
-         skip_whitespace(frag(pos), pos.column);
-         t.category = TokenCategory::Whitespace;
-         t.end = current_locus();
-         return t;
-      }
-      else if (pos.column == line_length() - 1 and frag(pos).back() == '_') {
-         ++pos.line;
-         pos.column = frag(pos).indent;
-      }
-      else if (pos.column == line_length()) {
-         auto indent = indents.top();
-         auto next_indent = next_indentation();
-         t.start = t.end = { next_line_number(), next_indent };
-         if (indent < next_indent) {
-            indents.push(next_indent);
-            ++pos.line;
-            pos.column = next_indent;
-            t.category = TokenCategory::Formatting;
-            t.value = TokenValue::Indent;
-         }
-         else if (indent > next_indent) {
-            indents.pop();
-            t.category = TokenCategory::Formatting;
-            t.value = TokenValue::Unindent;
-         }
-         else {
-            ++pos.line;
-            pos.column = next_indent;
-            t.category = TokenCategory::Formatting;
-            t.value = TokenValue::Justify;
-         }
-         return t;
-      }
-
-      switch (auto c = frag.advance(pos)) {
-      case '#': sharp_et_al(frag, pos, t, dialect); break;
-      case '@': operator_token(t, TokenValue::At); break;
-      case '^': operator_token(t, TokenValue::Caret); break;
-      case '&': punctuator_token(t, TokenValue::Ampersand); break;         
-      case '!': punctuator_token(t, TokenValue::Exclamation); break;
-      case '\'': punctuator_token(t, TokenValue::Apostrophe); break;
-      case ',': punctuator_token(t, TokenValue::Comma); break;
-      case ';': punctuator_token(t, TokenValue::Semicolon); break;
-      case '`': punctuator_token(t, TokenValue::Backquote); break;
-      case '(': left_paren_et_al(frag, pos, t); break;
-      case ')': punctuator_token(t, TokenValue::CloseParen); break;
-      case '{': left_brace_et_al(frag, pos, t); break;
-      case '}': punctuator_token(t, TokenValue::CloseBrace); break;
-      case '[': left_bracket_et_al(frag, pos, t); break;
-      case ']': punctuator_token(t, TokenValue::CloseBracket); break;
-      case ':': colon_et_al(frag, pos, t); break;
-      case '*': star_et_al(frag, pos, t); break;
-      case '/': slash_et_al(frag, pos, t); break;
-      case '\\': backslash_et_al(frag, pos, t); break;
-      case '<': less_et_al(frag, pos, t); break;
-      case '=': equal_et_al(frag, pos, t); break;
-      case '~': tilde_et_al(frag, pos, t); break;
-      case '>': greater_et_al(frag, pos, t); break;
-      case '|': bar_et_al(frag, pos, t); break;
-      case '-': minus_et_al(frag, pos, t); break;
-      case '+': plus_et_al(frag, pos, t); break;
-      case '.': dot_et_al(frag, pos, t); break;
-      case '"': string_literal(frag, pos, t); break;
-      case '$': dollar_et_al(frag, pos, t, dialect); break;
-
-      default:
-         if (isdigit(c))
-            number(frag(pos), pos.column, t);
-         else if (identifier_head(c))
-            identifier(frag(pos), pos.column, t, dialect);
-         else
-            junk(frag(pos), pos.column, t);
-         break;
-      }
-
-      t.end = { frag(pos).number, pos.column };
-      return t;
-   }
-
-   // -- Token streams.
-   template<typename T>
-   struct TokenStream : std::vector<T> {
-      template<typename Frag>
-      explicit TokenStream(Frag& f, Language dialect = Language::Spad) {
-         Tokenizer<Frag, T> lex { f };
-         while (auto t = lex.get(dialect))
-            this->push_back(t);
-      }
-   };
-}
-
-#endif  // OPENAXIOM_TOKEN_included
diff --git a/src/include/vm.H b/src/include/vm.H
deleted file mode 100644
index 3bb62250..00000000
--- a/src/include/vm.H
+++ /dev/null
@@ -1,606 +0,0 @@
-// Copyright (C) 2011-2014, Gabriel Dos Reis.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of OpenAxiom nor the names of its contributors
-//       may be used to endorse or promote products derived from this
-//       software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// --% Author: Gabriel Dos Reis
-// --% Description:
-// --%   Interface and implementation of basic services of the 
-// --%   OpenAxiom Virtual Machine.
-
-#ifndef OPENAXIOM_VM_included
-#define OPENAXIOM_VM_included
-
-#include <open-axiom/storage>
-#include <open-axiom/string-pool>
-#include <stdint.h>
-#include <utility>
-#include <set>
-#include <vector>
-#include <type_traits>
-
-#define internal_type struct alignas(16)
-#define internal_data alignas(16)
-
-namespace OpenAxiom {
-   namespace VM {
-      // --%
-      // --% Value representation
-      // --%
-      // A far reaching design decision is that of providing a uniform
-      // representation for values.  That is all values, irrespective
-      // of type have fit in a fixed format, i.e. a scalar register.
-      // This means that values that are more complicated than a scalar,
-      // i.e. the vast majority and most interesting values, have to
-      // be stored in allocated objects and addresses of their container
-      // objects used in place of the actual values.  This is folklore
-      // in the communities of garbage collected languages.
-      // 
-      // An unfortunate but widely held belief is that AXIOM-based
-      // systems (and computer algebra systems in general) are
-      // Lisp-based systems.  Nothing could be further from the truth
-      // for OpenAxiom.  The type system is believed to support
-      // erasure semantics, at least for values.
-      //
-      // However the current implementation, being Lisp-based,
-      // unwittingly makes use of some Lisp features that are not
-      // strictly necessary.  It would take a certain amount of effort
-      // to get rid of them.  Consequently, we must cope -- at least
-      // for now -- with the notion of uniform value representation and
-      // use runtime predicates to descriminate between values.
-      // On the other hand, we do not want to carry an unduly expensive
-      // abstraction penalty for perfectly well behaved and well
-      // disciplined programs.  So, here are a few constraints:
-      //   1. Small integers should represent themselves -- not allocated.
-      //      Furthermore, the maximum range should be sought where possible.
-      //   2. Since we have to deal with characters, they should be
-      //      directly represented -- not allocated.
-      //   3. List values and list manipulation should be efficient.
-      //      Ideally, a pair should occupy no more than what it
-      //      takes to store two values in a type-erasure semantics.
-      //   4. Idealy, pointers to foreign objects (at least) should be
-      //      left unmolested.
-      //   5. Ideally, we want efficient access to string literals
-      // 
-      // * Assumptions:
-      //     (a) the host machine has sizeof(Value) quo 4 = 0.
-      //     (b) allocated objects can be aligned on sizeof(Value) boundary.
-      //     (c) the host machine has 2's complement arithmetic.
-      //
-      // If:
-      //   -- we use a dedicated allocation pool for cons cells
-      //   -- we allocate the first cell in each cons-storage arena
-      //      on a 8-byte boundary
-      //   -- we use exactly 2 * sizeof(Value) to store a cons cell
-      //      therefore realizing constraint (3)
-      // then:
-      //   every pointer to a cons cell will have its last 3 bits cleared.
-      //
-      // Therefore, we can use the last 3 bits to tag a cons value, instead
-      // of storing the tag inside the cons cell.  We can't leave those
-      // bits cleared for we would not be able to easily and cheaply
-      // distinguish a pointer to a cons cell from a pointer to other
-      // objects, in particular foreign objects.
-      //
-      // To meet constraint (1), we must logically use at least one bit
-      // to distinguish a small integer from a pointer to a cons cell.
-      // The good news is that we need no more than that if pointers
-      // to foreign pointers do not have the last bit set.  Which is
-      // the case with assumption (a).  Furthermore, if we align all
-      // other internal data on 16 byte boundary, then we have 4 spare bits
-      // for use to categorize values.
-      // Therefore we arrive at the first design:
-      //    I. the value representation of a small integer always has the
-      //       the least significant bit set.  All other bits are
-      //       significant.  In other words, the last four bits of a small
-      //       integer are 0bxxx1
-      // 
-      // As a consequence, the last bit of all other values must be cleared.
-      //
-      // Next,
-      //   II. All foreign pointers that are aligned on 8-boundary are
-      //       directly represented.  Any foreign pointer not meeting
-      //       this condition is stored in an internal object.  As a
-      //       consequence, the last four bits of all foreign addresses 
-      //       directly represented follow the pattern 0bx000.
-      // 
-      //  III. Cons cells are represented by their addresses with the
-      //       last 4 bits matching the pattern 0bx010.
-      //
-      //   IV. All internal objects are allocated on 16-byte boundary.
-      //       Their last 4 bits are set to the pattern 0b0110.
-      //
-      //    V. String literals are represented by their addressed with
-      //       the last four bits following the pattern 0bx100..
-      //
-      // Finally:
-      //   IV. The representation of a character shall have the last four
-      //       bits set to 0b1110.
-      //
-      // Note: These choices do not fully satisfy constraint 4.  This is 
-      //     because we restrict foreign pointers to address aligned
-      //     to 8-byte boundaries.  A modest constraint.
-      //
-      // Special Constants:
-      //     NIL    0x00
-      //     T      0x10
-
-
-      // -----------
-      // -- Value --
-      // -----------
-      // All VM values fit in a universal value datatype.
-      using ValueBits = uintptr_t;
-      using ValueMask = ValueBits;
-      enum class Value : ValueBits {
-         nil = 0x00,            // distinguished NIL value
-         t   = 0x10,            // distinguished T value
-      };
-
-      // -- Testing for nil value.
-      constexpr Value null(Value v) {
-         return v == Value::nil ? Value::t : Value::nil;
-      }
-
-      // -- Convert VM Boolean value to C++ view
-      constexpr bool to_bool(Value v) { return v != Value::nil; }
-
-      // -- Convert a C++ Boolean value to VM view.
-      constexpr Value to_value(bool b) {
-         return b ? Value::t : Value::nil;
-      }
-
-      // -- Identity equality.
-      constexpr Value eq(Value x, Value y) { return to_value(x == y); }
-
-      template<typename>
-      struct ValueTrait {
-      };
-
-      // Return the tag of an abstract value, when viewed as a potential
-      // T-value.
-      template<typename T>
-      constexpr ValueBits tag(Value v) {
-         return ValueBits(v) & ValueTrait<T>::tag_mask;
-      }
-
-      // Return true if the abstract value is, in fact, a T-value.
-      template<typename T>
-      constexpr bool is(Value v) {
-         return tag<T>(v) == ValueTrait<T>::tag;
-      }
-
-      // Return the pristine bits of an abstract value without its tag.
-      template<typename T>
-      constexpr ValueBits native(Value v) {
-         return ValueBits(v) & ~ValueTrait<T>::tag_mask;
-      }
-
-      // -- Arity: number of arguments or forms taken by a function
-      //           or a special operator.
-      enum class Arity : intptr_t {
-         variable = -1,         // Any number of arguments.
-         zero     = 0,          // Exactly no argument.
-         one      = 1,          // Exactly one argument.
-         two      = 2,          // Exactly two arguments.
-         three    = 3,          // Exactly three arguments.
-      };
-
-      // -------------
-      // -- Dynamic --
-      // -------------
-      // Any internal value is of a class derived from this.
-      internal_type Dynamic {
-         struct Visitor;
-         virtual ~Dynamic();
-         virtual void accept(Visitor&) const = 0;
-      };
-
-      // Provide an S-view of a T-typed expression, assuming the type T
-      // derives from S.
-      template<typename S, typename T>
-      inline const S& as(const T& t) { return t; }
-
-      template<>
-      struct ValueTrait<Dynamic> {
-         enum Tag : ValueBits { tag = 0x6 };
-         enum Mask : ValueBits { tag_mask = 0xF };
-      };
-
-      inline Dynamic* to_dynamic(Value v) {
-         return reinterpret_cast<Dynamic*>(native<Dynamic>(v));
-      }
-
-      inline Dynamic* to_dynamic_if_can(Value v) {
-         return is<Dynamic>(v) ? to_dynamic(v) : nullptr;
-      }
-
-      template<typename T>
-      using IfDynamic = typename
-         std::enable_if<std::is_base_of<Dynamic, T>::value, Value>::type;
-
-      template<typename T>
-      inline IfDynamic<T> to_value(const T* o) {
-         return Value(ValueBits(o) | ValueTrait<Dynamic>::tag);
-      }
-
-      // -- Callable --
-      struct Callable : Dynamic {
-      };
-      
-      // -------------
-      // -- Fixnum ---
-      // -------------
-      // VM integers are divided into classes: small numbers,
-      // and large numbers.  A small number fits entirely in a register.
-      // A large number is allocated and represented by its address.
-      using FixnumBits = intptr_t;
-      enum class Fixnum : FixnumBits {
-         minimum = FixnumBits(~(~ValueBits() >> 2)),
-         zero = FixnumBits(0),
-         one = FixnumBits(1),
-         maximum = FixnumBits(~ValueBits() >> 2),
-      };
-
-      template<>
-      struct ValueTrait<Fixnum> {
-         enum Tag : ValueBits { tag = 0x1  };
-         enum Mask : ValueBits { tag_mask = 0x1 };
-      };
-
-      constexpr Fixnum to_fixnum(Value v) {
-         return Fixnum(FixnumBits(v) >> 1);
-      }
-
-      constexpr Value from_fixnum(Fixnum i) {
-         return Value((ValueBits(i) << 1 ) | ValueTrait<Fixnum>::tag);
-      }
-
-      // ------------
-      // -- String --
-      // ------------
-      using String = InternedString;
-
-      template<>
-      struct ValueTrait<String> {
-         enum Tag : ValueBits { tag = 0x4 };
-         enum Mask : ValueBits { tag_mask = 0x7 };
-      };
-
-      inline InternedString to_string(Value v) {
-         return reinterpret_cast<String>(native<String>(v));
-      }
-
-      inline Value from_string(InternedString s) {
-         return Value(ValueBits(s) | ValueTrait<String>::tag);
-      }
-
-      inline InternedString to_string_if_can(Value v) {
-         return is<String>(v) ? to_string(v) : nullptr;
-      }
-
-      // -------------
-      // -- Pointer --
-      // -------------
-      // Allocated objects are represented by their addresses.
-      using Memory::Pointer;
-
-      template<>
-      struct ValueTrait<Memory::Pointer> {
-         enum Tag : ValueBits { tag = 0x0 };
-         enum Mask : ValueBits { tag_mask = 0x7 };
-      };
-
-      inline Pointer to_pointer(Value v) {
-         return Pointer(ValueBits(v));
-      }
-
-      inline Value from_pointer(Pointer p) {
-         return Value(ValueBits(p) | ValueTrait<Memory::Pointer>::tag);
-      }
-
-      // ----------
-      // -- Pair --
-      // ----------
-      struct alignas(8) ConsCell {
-         Value head;
-         Value tail;
-      };
-
-      using Pair = ConsCell*;
-
-      template<>
-      struct ValueTrait<Pair> {
-         enum Tag : ValueBits { tag = 0x2 };
-         enum Mask : ValueBits { tag_mask = 0x7 };
-      };
-
-      inline Pair to_pair(Value v) {
-         return reinterpret_cast<Pair>(native<Pair>(v));
-      }
-
-      inline Value from_pair(Pair p) {
-         return Value(ValueBits(p) | ValueTrait<Pair>::tag);
-      }
-
-      // Return true if argument designates a pair.
-      constexpr Value consp(Value v) {
-         return to_value(v != Value::nil and v != Value::t and is<Pair>(v));
-      }
-
-      inline Value atom(Value v) {
-         return null(consp(v));
-      }
-
-      // If `v' designates a pair, return a pointer to its
-      // concrete representation.
-      inline Pair to_pair_if_can(Value v) {
-         return consp(v) == Value::t ? to_pair(v) : nullptr;
-      }
-
-      Fixnum count_nodes(Pair);
-      inline Fixnum count_nodes(Value v) {
-         if (auto p = to_pair_if_can(v))
-            return count_nodes(p);
-         return Fixnum::zero;
-      }
-
-      // ---------------
-      // -- Character --
-      // ---------------
-      // This datatype is prepared for Uncode characters even if
-      // we do not handle UCN characters at the moment.
-      enum class Character : ValueBits { };
-
-      template<>
-      struct ValueTrait<Character> {
-         enum Tag : ValueBits { tag = 0xE };
-         enum Mask : ValueBits { tag_mask = 0xF };
-      };
-
-      constexpr Character to_character(Value v) {
-         return Character(ValueBits(v) >> 4);
-      }
-
-      constexpr Value from_character(Character c) {
-         return Value((ValueBits(c) << 4) | ValueTrait<Character>::tag);
-      }
-
-      // -- Object --
-      // An object is a typed value.
-      struct Type;
-      struct Object {
-         Value value;
-         const Type* type;
-      };
-
-      struct Package;
-
-      enum class SymbolAttribute : ValueBits {
-         None             = 0x0,    // No particular attribute.
-         Constant         = 0x1,    // Symbol defined constant.
-         Special          = 0x2,    // Symbol declared special.
-         Keyword          = 0x4,    // A keyword symbol.
-         SpecialConstant  = Constant | Special,
-      };
-
-      constexpr SymbolAttribute
-      operator&(SymbolAttribute x, SymbolAttribute y) {
-         return SymbolAttribute(ValueBits(x) & ValueBits(y));
-      }
-
-      // ------------
-      // -- Symbol --
-      // ------------
-      struct Symbol : Dynamic {
-         const InternedString name;
-         Value value;
-         const Callable* function;
-         Pair properties;
-         Package* package;
-         SymbolAttribute attributes;
-         explicit Symbol(InternedString);
-         void accept(Visitor&) const override;
-         bool has(SymbolAttribute x) const { return (attributes & x) == x; }
-      };
-
-      inline Symbol* to_symbol_if_can(Value v) {
-         return dynamic_cast<Symbol*>(to_dynamic_if_can(v));
-      }
-
-      inline bool is_symbol(Value v) {
-         return to_symbol_if_can(v) != nullptr;
-      }
-
-      // -- Test if a value is a symbol.
-      inline Value symbolp(Value v) {
-         return to_value(v == Value::nil or v == Value::t or is_symbol(v));
-      }
-
-      // -- Test if a value is a keyword symbol.
-      inline Value keywordp(Value v) {
-         if (auto sym = to_symbol_if_can(v))
-            return to_value(sym->has(SymbolAttribute::Keyword));
-         return Value::nil;
-      }
-
-      struct CmpByName {
-         template<typename T>
-         bool operator()(const T& x, const T& y) const {
-            return std::less<String>()(x.name, y.name);
-         }
-      };
-
-      template<typename T>
-      inline const T* setf_symbol_function(Symbol* sym, const T* fun) {
-         sym->function = fun;
-         return fun;
-      }
-
-      // -- Argument binding as value.
-      // Binding a parameter to a value in a call.
-      struct Binding : Dynamic {
-         Symbol* symbol;
-         Value value;
-         void accept(Visitor&) const override;
-      };
-      
-      // -- Environments.
-      struct Environment {
-         struct Binding {
-            Symbol* symbol;
-            Value value;
-         };
-
-         Environment();
-         ~Environment();
-
-         void bind(Symbol*, Value);
-         Binding* lookup(InternedString);
-      private:
-         std::vector<Binding> lexical;
-         std::vector<Binding> dynamic;
-      };
-
-      // -------------
-      // -- Package --
-      // -------------
-      struct Package : Dynamic {
-         const InternedString name;
-         std::set<Symbol, CmpByName> symbols;
-
-         explicit Package(InternedString);
-         void accept(Visitor&) const override;
-         Symbol* make_symbol(InternedString);
-         Symbol* find_symbol(InternedString);
-      };
-
-      // --------------
-      // -- Function --
-      // --------------
-      struct FunctionBase : Callable {
-         const Symbol* name;
-         Value type;
-         FunctionBase(const Symbol* n, Value t = Value::nil)
-               : name(n), type(t) { }
-         void accept(Visitor&) const override;
-      };
-
-      // ------------------------
-      // -- Builtin Operations --
-      // ------------------------
-      // Types for native implementation of builtin operators.
-      struct BasicContext;
-
-      template<typename... Ts>
-      using RuntimeOperation = Value(*)(BasicContext*, Ts...);
-      using NullaryCode = RuntimeOperation<>;
-      using UnaryCode = RuntimeOperation<Value>;
-      using BinaryCode = RuntimeOperation<Value, Value>;
-      using TernaryCode = RuntimeOperation<Value, Value, Value>;
-
-      template<typename Code>
-      struct BuiltinFunction : FunctionBase {
-         Code code;
-         BuiltinFunction(const Symbol* n, Code c)
-               : FunctionBase(n), code(c)
-         { }
-         void accept(Visitor&) const override;
-      };
-
-      using NullaryOperator = BuiltinFunction<NullaryCode>;
-      using UnaryOperator = BuiltinFunction<UnaryCode>;
-      using BinaryOperator = BuiltinFunction<BinaryCode>;
-      using TernaryOperator = BuiltinFunction<TernaryCode>;
-
-      // -- Operand stack.
-      struct OperandStack : private std::vector<Value> {
-         using super = std::vector<Value>;
-         using iterator = std::reverse_iterator<super::iterator>;
-         using super::size;
-         using super::empty;
-         iterator begin() { return rbegin(); }
-         iterator end() { return rend(); }
-         Value top() { return back(); }
-         void push(Value v) { push_back(v); }
-         Value pop() { auto v = back(); pop_back(); return v; }
-         void operator-=(std::size_t i) { resize(size() - i); }
-         Value operator[](std::size_t i) {
-            return super::operator[](size() - i - 1);
-         }
-      };
-
-      // -- Dynamic::Visitor --
-      struct Dynamic::Visitor {
-         virtual void visit(const Symbol&) = 0;
-         virtual void visit(const Binding&) = 0;
-         virtual void visit(const Package&) = 0;
-         virtual void visit(const FunctionBase&) = 0;
-         virtual void visit(const NullaryOperator&);
-         virtual void visit(const UnaryOperator&);
-         virtual void visit(const BinaryOperator&);
-      };
-
-      template<typename Code>
-      void BuiltinFunction<Code>::accept(Visitor& v) const { v.visit(*this); }
-
-      // ------------------
-      // -- BasicContext --
-      // ------------------
-      // Provides basic evaluation services.
-      struct BasicContext : StringPool {
-         BasicContext();
-         ~BasicContext();
-
-         Package* make_package(InternedString);
-         Symbol* make_keyword(InternedString);
-         Pair make_pair(Value, Value);
-         const NullaryOperator* make_operator(Symbol*, NullaryCode);
-         const UnaryOperator* make_operator(Symbol*, UnaryCode);
-         const BinaryOperator* make_operator(Symbol*, BinaryCode);
-         const TernaryOperator* make_operator(Symbol*, TernaryCode);
-
-         Package* keyword_package() const { return keywords; }
-         Package* homeless_package() const { return homeless; }
-
-      protected:
-         std::set<Package, CmpByName> packages;
-         Memory::Factory<ConsCell> conses;
-         Memory::Factory<NullaryOperator> nullaries;
-         Memory::Factory<UnaryOperator> unaries;
-         Memory::Factory<BinaryOperator> binaries;
-         Memory::Factory<TernaryOperator> ternaries;
-         Package* keywords;
-         Package* homeless;
-      };
-   };
-}
-
-#endif  // OPENAXIOM_VM_INCLUDED
-
diff --git a/src/utils/Makefile.in b/src/utils/Makefile.in
index 18806e1d..cde398ed 100644
--- a/src/utils/Makefile.in
+++ b/src/utils/Makefile.in
@@ -220,8 +220,7 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/hash-table.H \
-	$(srcdir)/string-pool.H $(top_srcdir)/config/depcomp \
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \
 	$(top_srcdir)/config/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
diff --git a/src/utils/hash-table.H b/src/utils/hash-table.H
deleted file mode 100644
index d74c7760..00000000
--- a/src/utils/hash-table.H
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (C) 2010, Gabriel Dos Reis.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of The Numerical Algorithms Group Ltd. nor the
-//       names of its contributors may be used to endorse or promote products
-//       derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_HASH_TABLE_INCLUDED
-#define OPENAXIOM_HASH_TABLE_INCLUDED
-
-// --% Author: Gabriel Dos Reis.
-// --% Description:
-// --%   Simple hash table facility.  To be replaced by C++0x
-// --%   hash tables when C++0x compilers become common place.
-
-#include <open-axiom/storage>
-
-namespace OpenAxiom {
-   // --------------------
-   // -- HashTableEntry --
-   // --------------------
-   // Datatype for entries in a parameterized hash table.
-   // The type parameter is required to be a value-construcitble datatype.
-   // A table bucket entry is required to be at least 8-byte aligned
-   // so that an instance of it can be used directly as a VM value.
-   // See <open-axiom/vm> for more description.
-   template<typename T>
-   struct alignas(8) HashTableEntry : T {
-      HashTableEntry* chain;   // previous item in the same bucket chain
-      size_t hash;             // hash code of stored data
-   };
-
-   // --------------------
-   // -- BasicHashTable --
-   // --------------------
-   // A simple hash table data structure.  Ideally, we would like to use
-   // standard C++ types, but hash tables were only in a C++ 2003 TR,
-   // officially part of C++0x standard library.  We still don't have
-   // wide-spread C++0x compilers.
-   template<typename T>
-   struct BasicHashTable : private Memory::Arena<HashTableEntry<T> > {
-      typedef HashTableEntry<T> EntryType;
-      explicit BasicHashTable(size_t n)
-            : Memory::Arena<HashTableEntry<T> >(n),
-              buckets(this->allocate(n)), nbuckets(n) { }
-
-      EntryType* hash_chain(size_t h) const {
-         return buckets + (h % nbuckets);
-      }
-
-      EntryType* new_bucket() {
-         return this->allocate(1);
-      }
-
-   private:
-      HashTableEntry<T>* const buckets;
-      const size_t nbuckets;
-   };
-}
-
-#endif  // OPENAXIOM_HASH_TABLE_INCLUDED
diff --git a/src/utils/string-pool.H b/src/utils/string-pool.H
deleted file mode 100644
index 1f746e6d..00000000
--- a/src/utils/string-pool.H
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (C) 2010-2015, Gabriel Dos Reis.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     - Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//
-//     - Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in
-//       the documentation and/or other materials provided with the
-//       distribution.
-//
-//     - Neither the name of The Numerical Algorithms Group Ltd. nor the
-//       names of its contributors may be used to endorse or promote products
-//       derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef OPENAXIOM_STRING_POOL_INCLUDED
-#define OPENAXIOM_STRING_POOL_INCLUDED
-
-#include <open-axiom/hash-table>
-
-// --% Author: Gabriel Dos Reis.
-// --% Description:
-// --%   Basic persistent string facility.
-// --%   A stringpool for allocating long-living string objects.
-
-namespace OpenAxiom {
-   struct StringPool;
-
-   // ----------------
-   // -- StringItem --
-   // ----------------
-   // String data allocated from a stringpool.
-   struct StringItem {
-      const Byte* begin() const { return text; }
-      const Byte* end() const { return text + length; }
-      size_t size() const { return length; }
-      bool equal(const Byte*, size_t) const;
-   protected:
-      const Byte* text;         // pointer to the byte sequence
-      size_t length;            // number of bytes in this string
-      friend StringPool;
-      StringItem() : text(), length() { }
-   };
-
-   // ----------------
-   // -- StringPool --
-   // ----------------
-   // A string-pool object is a repository of long-living string objects.
-   // It contains no duplicates, therefore allows  fast equality 
-   // comparison of string objects.
-   struct StringPool : private BasicHashTable<StringItem> {
-      using BasicHashTable<StringItem>::EntryType;
-
-      StringPool();
-      // Intern a NUL-terminated sequence of characters.
-      EntryType* intern(const char*);
-
-      // Intern a sequence of characters given by its start and length.
-      EntryType* intern(const Byte*, size_t);
-   private:
-      Memory::Arena<Byte> strings; // character blub
-      // Allocate a string from the internal arena.
-      const Byte* make_copy(const Byte*, size_t);
-   };
-
-   typedef const StringPool::EntryType* InternedString;
-}
-
-#endif  // OPENAXIOM_STRING_POOL_INCLUDED
-- 
cgit v1.2.3