aboutsummaryrefslogtreecommitdiff
path: root/src/include/open-axiom/sexpr
diff options
context:
space:
mode:
authorGabriel Dos Reis <gdr@axiomatics.org>2015-12-23 12:50:54 -0800
committerGabriel Dos Reis <gdr@axiomatics.org>2015-12-23 12:50:54 -0800
commit72bbd833136a8a36eab1597c2f32f0890caeade8 (patch)
tree135f7a7cf53266aa8addd3aa47e07f94bf93c112 /src/include/open-axiom/sexpr
parent33a5d910f263ad94cec761e0d93c11acfa6b7ccd (diff)
downloadopen-axiom-72bbd833136a8a36eab1597c2f32f0890caeade8.tar.gz
Arrange the source include director to mirror expected build structure instead of creating links.
Diffstat (limited to 'src/include/open-axiom/sexpr')
-rw-r--r--src/include/open-axiom/sexpr419
1 files changed, 419 insertions, 0 deletions
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