aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/c.cpp2
-rw-r--r--src/compile.cpp4
-rw-r--r--src/constrain.cpp12
-rw-r--r--src/lift.cpp7
-rw-r--r--src/llvm.cpp2
-rw-r--r--src/parse.cpp2
-rw-r--r--src/pprint.cpp4
-rw-r--r--src/resp.cpp4
-rw-r--r--src/resp.hpp127
9 files changed, 87 insertions, 77 deletions
diff --git a/src/c.cpp b/src/c.cpp
index 5d5ddd3..3ebd608 100644
--- a/src/c.cpp
+++ b/src/c.cpp
@@ -184,7 +184,7 @@ CEngine::startFn(CEnv& cenv, const std::string& name, const ATuple* args, const
for (; ai != argsT->end(); ++ai, ++ni) {
if (ai != argsT->begin())
f->text += ", ";
- f->text += *llType((*ai)->as_type()) + " " + (*ni)->as_symbol()->cppstr;
+ f->text += *llType((*ai)->as_type()) + " " + (*ni)->as_symbol()->sym();
}
f->text += ")\n{\n";
diff --git a/src/compile.cpp b/src/compile.cpp
index 8cde2e8..127a981 100644
--- a/src/compile.cpp
+++ b/src/compile.cpp
@@ -27,7 +27,7 @@ static CVal
compile_symbol(CEnv& cenv, const ASymbol* sym) throw()
{
if (cenv.vals.topLevel(sym) && cenv.type(sym)->head()->str() != "Fn") {
- return cenv.engine()->compileGlobalGet(cenv, sym->cppstr, *cenv.vals.ref(sym));
+ return cenv.engine()->compileGlobalGet(cenv, sym->sym(), *cenv.vals.ref(sym));
} else {
return *cenv.vals.ref(sym);
}
@@ -193,7 +193,7 @@ resp_compile(CEnv& cenv, const AST* ast) throw()
{
const ATuple* const call = ast->as_tuple();
const ASymbol* const sym = call->head()->to_symbol();
- const std::string form = sym ? sym->cppstr : "";
+ const std::string form = sym ? sym->sym() : "";
if (is_primitive(cenv.penv, call))
return cenv.engine()->compilePrimitive(cenv, ast->as_tuple());
else if (form == "fn")
diff --git a/src/constrain.cpp b/src/constrain.cpp
index e97bcc3..7b437c8 100644
--- a/src/constrain.cpp
+++ b/src/constrain.cpp
@@ -26,7 +26,7 @@ static void
constrain_symbol(TEnv& tenv, Constraints& c, const ASymbol* sym) throw(Error)
{
const AType** ref = tenv.ref(sym);
- THROW_IF(!ref, sym->loc, (format("undefined symbol `%1%'") % sym->cppstr).str());
+ THROW_IF(!ref, sym->loc, (format("undefined symbol `%1%'") % sym->sym()).str());
c.constrain(tenv, sym, *ref);
}
@@ -47,7 +47,7 @@ constrain_fn(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
(format("duplicate parameter `%1%'") % sym->str()).str());
defs.insert(sym);
const AType* tvar = tenv.fresh(sym);
- frame.push_back(make_pair(sym, tvar));
+ frame.push_back(make_pair(sym->sym(), tvar));
protT.push_back(tvar);
}
protT.head->loc = call->loc;
@@ -64,7 +64,7 @@ constrain_fn(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
THROW_IF(defs.count(sym) != 0, call->loc,
(format("`%1%' defined twice") % sym->str()).str());
defs.insert(sym);
- frame.push_back(make_pair(sym, (AType*)NULL));
+ frame.push_back(make_pair(sym->sym(), (AType*)NULL));
}
}
@@ -190,7 +190,7 @@ constrain_cons(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
for (ATuple::const_iterator i = call->iter_at(1); i != call->end(); ++i)
resp_constrain(tenv, c, *i);
- if (sym->cppstr == "Tup") {
+ if (!strcmp(sym->sym(), "Tup")) {
TList tupT(new AType(tenv.Tup, NULL, call->loc));
for (ATuple::const_iterator i = call->iter_at(1); i != call->end(); ++i) {
tupT.push_back(tenv.var(*i));
@@ -199,7 +199,7 @@ constrain_cons(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
} else {
const AType** consTRef = tenv.ref(sym);
THROW_IF(!consTRef, call->loc,
- (format("call to undefined constructor `%1%'") % sym->cppstr).str());
+ (format("call to undefined constructor `%1%'") % sym->sym()).str());
const AType* consT = *consTRef;
type = new AType(consT->head()->as_type(), 0, call->loc);
}
@@ -323,7 +323,7 @@ constrain_tuple(TEnv& tenv, Constraints& c, const ATuple* tup) throw(Error)
return;
}
- const std::string form = sym->cppstr;
+ const std::string form = sym->sym();
if (is_primitive(tenv.penv, tup))
constrain_primitive(tenv, c, tup);
else if (form == "fn")
diff --git a/src/lift.cpp b/src/lift.cpp
index e0a5b5a..5ac3816 100644
--- a/src/lift.cpp
+++ b/src/lift.cpp
@@ -30,8 +30,7 @@ using namespace std;
static const AST*
lift_symbol(CEnv& cenv, Code& code, const ASymbol* sym) throw()
{
- const std::string& cppstr = sym->cppstr;
- if (!cenv.liftStack.empty() && cppstr == cenv.name(cenv.liftStack.top().fn)) {
+ if (!cenv.liftStack.empty() && cenv.name(cenv.liftStack.top().fn) == sym->sym()) {
return cenv.penv.sym("_me"); // Reference to innermost function
} else if (!cenv.code.innermost(sym)) {
@@ -145,7 +144,7 @@ lift_call(CEnv& cenv, Code& code, const ATuple* call) throw()
const AType* copyT = NULL;
const ASymbol* sym = call->head()->to_symbol();
- if (sym && !cenv.liftStack.empty() && sym->cppstr == cenv.name(cenv.liftStack.top().fn)) {
+ if (sym && !cenv.liftStack.empty() && sym->sym() == cenv.name(cenv.liftStack.top().fn)) {
/* Recursive call to innermost function, call implementation directly,
* reusing the current "_me" closure parameter (no cons or .).
*/
@@ -234,7 +233,7 @@ resp_lift(CEnv& cenv, Code& code, const AST* ast) throw()
const ATuple* const call = ast->to_tuple();
if (call) {
const ASymbol* const sym = call->head()->to_symbol();
- const std::string form = sym ? sym->cppstr : "";
+ const std::string form = sym ? sym->sym() : "";
if (is_primitive(cenv.penv, call))
return lift_builtin_call(cenv, code, call);
else if (form == "fn")
diff --git a/src/llvm.cpp b/src/llvm.cpp
index be57e25..391c9dd 100644
--- a/src/llvm.cpp
+++ b/src/llvm.cpp
@@ -284,7 +284,7 @@ LLVMEngine::startFn(
// Set argument names in generated code
Function::arg_iterator a = f->arg_begin();
for (ATuple::const_iterator i = args->begin(); i != args->end(); ++a, ++i)
- a->setName((*i)->as_symbol()->cppstr);
+ a->setName((*i)->as_symbol()->sym());
BasicBlock* bb = BasicBlock::Create(context, "entry", f);
builder.SetInsertPoint(bb);
diff --git a/src/parse.cpp b/src/parse.cpp
index 43fb681..e0948fe 100644
--- a/src/parse.cpp
+++ b/src/parse.cpp
@@ -151,7 +151,7 @@ read_symbol(PEnv& penv, Cursor& cur, istream& in)
break;
}
- return penv.sym(str);
+ return penv.sym(str, cur);
}
/// Read an expression from @a in
diff --git a/src/pprint.cpp b/src/pprint.cpp
index 5d2cd5f..d082b5d 100644
--- a/src/pprint.cpp
+++ b/src/pprint.cpp
@@ -84,7 +84,7 @@ print_to(ostream& out, const AST* ast, unsigned indent, CEnv* cenv, bool types)
if (i != tup->end()) {
const ASymbol* sym = (*i)->to_symbol();
if (sym) {
- form = sym->cppstr;
+ form = sym->sym();
}
}
@@ -155,7 +155,7 @@ print_to(ostream& out, const AST* ast, unsigned indent, CEnv* cenv, bool types)
case T_STRING:
return out << '"' << ((const AString*)ast)->cppstr << '"';
case T_SYMBOL:
- return out << ((const ASymbol*)ast)->cppstr;
+ return out << ((const ASymbol*)ast)->sym();
}
return out << "?";
diff --git a/src/resp.cpp b/src/resp.cpp
index e745455..cef2d0c 100644
--- a/src/resp.cpp
+++ b/src/resp.cpp
@@ -39,7 +39,7 @@ is_form(const AST* ast, const std::string& form)
if (!sym)
return false;
- return sym->cppstr == form;
+ return form == sym->sym();
}
bool
@@ -53,7 +53,7 @@ is_primitive(const PEnv& penv, const AST* ast)
if (!sym)
return false;
- return penv.primitives.find(sym->cppstr) != penv.primitives.end();
+ return penv.primitives.find(sym->sym()) != penv.primitives.end();
}
int
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;