diff options
author | David Robillard <d@drobilla.net> | 2009-03-12 05:59:32 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-03-12 05:59:32 +0000 |
commit | 22b5ef111e00af6c1b3c56283b71337d2fda351b (patch) | |
tree | 944981e315eed7aa65d451b5e1b55a9035f655fb /tuplr.hpp | |
parent | ad582fa2ba18ca4391c3d6c084d902d3b1fd5ca5 (diff) | |
download | resp-22b5ef111e00af6c1b3c56283b71337d2fda351b.tar.gz resp-22b5ef111e00af6c1b3c56283b71337d2fda351b.tar.bz2 resp-22b5ef111e00af6c1b3c56283b71337d2fda351b.zip |
Tidy.
git-svn-id: http://svn.drobilla.net/resp/tuplr@85 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'tuplr.hpp')
-rw-r--r-- | tuplr.hpp | 80 |
1 files changed, 28 insertions, 52 deletions
@@ -37,6 +37,7 @@ using boost::format; * Basic Utility Classes * ***************************************************************************/ +/// Location in textual code struct Cursor { Cursor(const string& n="", unsigned l=1, unsigned c=0) : name(n), line(l), col(c) {} operator bool() const { return !(line == 1 && col == 0); } @@ -46,6 +47,7 @@ struct Cursor { unsigned col; }; +/// Compiler error struct Error { Error(const string& m, Cursor c=Cursor()) : msg(m), loc(c) {} const string what() const { return (loc ? loc.str() + ": " : "") + "error: " + msg; } @@ -53,12 +55,14 @@ struct Error { Cursor loc; }; +/// Output streams (standard and error) struct Log { Log(ostream& o, ostream& e) : out(o), err(e) {} ostream& out; ostream& err; }; +/// Expression ::= Atom | (Expression*) template<typename Atom> struct Exp { Exp(Cursor c) : type(LIST), loc(c) {} @@ -70,6 +74,28 @@ struct Exp { List list; }; +/// Generic Lexical Environment +template<typename K, typename V> +struct Env : public list< map<K,V> > { + typedef map<K,V> Frame; + Env() : list<Frame>(1) {} + void push() { list<Frame>::push_front(Frame()); } + void pop() { assert(!this->empty()); list<Frame>::pop_front(); } + const V& def(const K& k, const V& v) { + typename Frame::iterator existing = this->front().find(k); + if (existing != this->front().end() && existing->second != v) + throw Error("redefinition"); + return (this->front()[k] = v); + } + V* ref(const K& name) { + typename Frame::iterator s; + for (typename Env::iterator i = this->begin(); i != this->end(); ++i) + if ((s = i ->find(name)) != i->end()) + return &s->second; + return 0; + } +}; + /*************************************************************************** * Lexer: Text (istream) -> S-Expressions (SExp) * @@ -81,7 +107,7 @@ SExp readExpression(Cursor& cur, std::istream& in); /*************************************************************************** - * Backend * + * Backend Types * ***************************************************************************/ typedef void* CValue; ///< Compiled value (opaque) @@ -90,7 +116,7 @@ typedef void* CEngine; ///< Compiler Engine (opaque) /*************************************************************************** - * Abstract Syntax Tree (Prefix A for Abstract) * + * Abstract Syntax Tree * ***************************************************************************/ struct TEnv; ///< Type-Time Environment @@ -352,56 +378,6 @@ struct PEnv : private map<const string, ASymbol*> { }; -template<typename C> -inline AST* -parseCall(PEnv& penv, const SExp& exp, void* arg) -{ - return new C(exp, penv.parseTuple(exp)); -} - -template<typename T> -inline AST* -parseLiteral(PEnv& penv, const SExp& exp, void* arg) -{ - return new ALiteral<T>(*reinterpret_cast<T*>(arg), exp.loc); -} - -inline AST* -parseFn(PEnv& penv, const SExp& exp, void* arg) -{ - SExp::List::const_iterator a = exp.list.begin(); ++a; - return new AClosure(exp.loc, penv.sym("fn"), - new ATuple(penv.parseTuple(*a++)), - penv.parse(*a++)); -} - - -/*************************************************************************** - * Generic Lexical Environment * - ***************************************************************************/ - -template<typename K, typename V> -struct Env : public list< map<K,V> > { - typedef map<K,V> Frame; - Env() : list<Frame>(1) {} - void push() { list<Frame>::push_front(Frame()); } - void pop() { assert(!this->empty()); list<Frame>::pop_front(); } - const V& def(const K& k, const V& v) { - typename Frame::iterator existing = this->front().find(k); - if (existing != this->front().end() && existing->second != v) - throw Error("redefinition"); - return (this->front()[k] = v); - } - V* ref(const K& name) { - typename Frame::iterator s; - for (typename Env::iterator i = this->begin(); i != this->end(); ++i) - if ((s = i ->find(name)) != i->end()) - return &s->second; - return 0; - } -}; - - /*************************************************************************** * Typing * ***************************************************************************/ |