diff options
Diffstat (limited to 'src/resp.hpp')
-rw-r--r-- | src/resp.hpp | 127 |
1 files changed, 69 insertions, 58 deletions
diff --git a/src/resp.hpp b/src/resp.hpp index 459e923..a453b88 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -67,51 +67,6 @@ struct Error { const string msg; }; -/// Generic Lexical Environment -template<typename K, typename V> -struct Env : public list< vector< pair<K,V> > > { - typedef vector< pair<K,V> > Frame; - Env() : list<Frame>(1) {} - virtual ~Env() {} - virtual void push(Frame f=Frame()) { list<Frame>::push_front(f); } - virtual void pop() { list<Frame>::pop_front(); } - const V& def(const K& k, const V& v) { - for (typename Frame::iterator b = this->begin()->begin(); b != this->begin()->end(); ++b) - if (b->first == k) - return (b->second = v); - this->front().push_back(make_pair(k, v)); - return v; - } - V* ref(const K& key) { - for (typename Env::iterator f = this->begin(); f != this->end(); ++f) - for (typename Frame::iterator b = f->begin(); b != f->end(); ++b) - if (b->first == key) - return &b->second; - return NULL; - } - bool contains(const Frame& frame, const K& key) const { - for (typename Frame::const_iterator b = frame.begin(); b != frame.end(); ++b) - if (b->first == key) - return true; - return false; - } - bool topLevel(const K& key) const { return contains(this->back(), key); } - bool innermost(const K& key) const { return contains(this->front(), key); } -}; - -template<typename K, typename V> -ostream& operator<<(ostream& out, const Env<K,V>& env) { - out << "(Env" << endl; - for (typename Env<K,V>::const_reverse_iterator f = env.rbegin(); f != env.rend(); ++f) { - out << " (" << endl; - for (typename Env<K,V>::Frame::const_iterator b = f->begin(); b != f->end(); ++b) - cout << " " << b->first << " " << b->second << endl; - out << " )" << endl; - } - out << ")" << endl; - return out; -} - /*************************************************************************** * Lexer: Text (istream) -> S-Expressions (SExp) * @@ -271,10 +226,11 @@ struct AString : public AST { /// Symbol, e.g. "a" struct ASymbol : public AST { - const string cppstr; + const char* sym() const { return _sym; } private: friend class PEnv; - ASymbol(const string& s, Cursor c) : AST(T_SYMBOL, c), cppstr(s) {} + const char* _sym; + ASymbol(const char* s, Cursor c) : AST(T_SYMBOL, c), _sym(s) {} }; /// Tuple (heterogeneous sequence of fixed length), e.g. "(a b c)" @@ -528,20 +484,72 @@ AST::operator==(const AST& rhs) const } return false; // never reached } - case T_UNKNOWN: case T_STRING: + return ((AString*)this)->cppstr == ((AString*)&rhs)->cppstr; case T_SYMBOL: + return ((ASymbol*)this)->sym() == ((ASymbol*)&rhs)->sym(); // interned + case T_UNKNOWN: return this == &rhs; } return false; } + +/*************************************************************************** + * Lexical Environmment * + ***************************************************************************/ + +/// Lexical Environment +template<typename V> +struct Env : public list< vector< pair<const char*, V> > > { + typedef vector< pair<const char*, V> > Frame; + Env() : list<Frame>(1) {} + virtual ~Env() {} + virtual void push(Frame f=Frame()) { list<Frame>::push_front(f); } + virtual void pop() { list<Frame>::pop_front(); } + const V& def(const ASymbol* k, const V& v) { + for (typename Frame::iterator b = this->begin()->begin(); b != this->begin()->end(); ++b) + if (b->first == k->sym()) + return (b->second = v); + this->front().push_back(make_pair(k->sym(), v)); + return v; + } + V* ref(const ASymbol* key) { + for (typename Env::iterator f = this->begin(); f != this->end(); ++f) + for (typename Frame::iterator b = f->begin(); b != f->end(); ++b) + if (b->first == key->sym()) + return &b->second; + return NULL; + } + bool contains(const Frame& frame, const ASymbol* key) const { + for (typename Frame::const_iterator b = frame.begin(); b != frame.end(); ++b) + if (b->first == key->sym()) + return true; + return false; + } + bool topLevel(const ASymbol* key) const { return contains(this->back(), key); } + bool innermost(const ASymbol* key) const { return contains(this->front(), key); } +}; + +template<typename V> +ostream& operator<<(ostream& out, const Env<V>& env) { + out << "(Env" << endl; + for (typename Env<V>::const_reverse_iterator f = env.rbegin(); f != env.rend(); ++f) { + out << " (" << endl; + for (typename Env<V>::Frame::const_iterator b = f->begin(); b != f->end(); ++b) + cout << " " << b->first << " " << b->second << endl; + out << " )" << endl; + } + out << ")" << endl; + return out; +} + /*************************************************************************** * Parser: S-Expressions (SExp) -> AST Nodes (AST) * ***************************************************************************/ /// Parse Time Environment (really just a symbol table) -struct PEnv : private map<const string, ASymbol*> { +struct PEnv : private map<const string, const char*> { PEnv() : symID(0) {} string gensymstr(const char* s="_") { return (format("%s_%d") % s % symID++).str(); } ASymbol* gensym(const char* s="_") { return sym(gensymstr(s)); } @@ -549,11 +557,11 @@ struct PEnv : private map<const string, ASymbol*> { assert(s != ""); const const_iterator i = find(s); if (i != end()) { - return i->second; + return new ASymbol(i->second, c); } else { - ASymbol* sym = new ASymbol(s, c); - insert(make_pair(s, sym)); - return sym; + const char* str = strdup(s.c_str()); + insert(make_pair(s, str)); + return new ASymbol(str, c); } } const AST* expand(const AST* exp); @@ -642,7 +650,7 @@ inline ostream& operator<<(ostream& out, const Constraints& c) { } /// Type-Time Environment -struct TEnv : public Env<const ASymbol*, const AType*> { +struct TEnv : public Env<const AType*> { TEnv(PEnv& p) : penv(p) , varID(1) @@ -668,6 +676,9 @@ struct TEnv : public Env<const ASymbol*, const AType*> { return (vars[ast] = new AType(ast->loc, varID++)); } + const AType** ref(const ASymbol* sym) { + return ((Env<const AType*>*)this)->ref(sym); + } const AType* named(const string& name) { return *ref(penv.sym(name)); } @@ -743,7 +754,7 @@ struct CEnv { ~CEnv() { Object::pool.collect(GC::Roots()); } - typedef Env<const ASymbol*, CVal> Vals; + typedef Env<CVal> Vals; Engine* engine() { return _engine; } void push() { code.push(); tenv.push(); vals.push(); } @@ -755,7 +766,7 @@ struct CEnv { } const AType* resolveType(const AType* type) const { if (type->kind == AType::NAME) - return tenv.named(type->head()->to_symbol()->cppstr); + return tenv.named(type->head()->to_symbol()->sym()); return type; } const AType* type(const AST* ast, const Subst& subst = Subst(), bool resolve=true) const { @@ -781,7 +792,7 @@ struct CEnv { } const AST* resolve(const AST* ast) { const ASymbol* sym = ast->to_symbol(); - const AST** rec = code.ref(sym); + const AST** rec = code.ref(sym); return rec ? *rec : ast; } void setType(const AST* ast, const AType* type) { @@ -801,7 +812,7 @@ struct CEnv { Vals vals; Subst tsubst; - Env<const ASymbol*, const AST*> code; + Env<const AST*> code; typedef map<const ATuple*, CFunc> Impls; Impls impls; |