aboutsummaryrefslogtreecommitdiffstats
path: root/src/resp.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/resp.hpp')
-rw-r--r--src/resp.hpp237
1 files changed, 106 insertions, 131 deletions
diff --git a/src/resp.hpp b/src/resp.hpp
index bc8c9ae..f601ac7 100644
--- a/src/resp.hpp
+++ b/src/resp.hpp
@@ -90,7 +90,7 @@ enum Tag {
T_STRING = 10,
T_SYMBOL = 12,
T_TUPLE = 14,
- T_TYPE = 16
+ T_TVAR = 16
};
/// Garbage collector
@@ -148,7 +148,6 @@ struct TEnv; ///< Type-Time Environment
struct CEnv; ///< Compile-Time Environment
struct ATuple;
struct ASymbol;
-struct AType;
class AST;
extern ostream& operator<<(ostream& out, const AST* ast);
@@ -162,12 +161,12 @@ struct AST : public Object {
string str() const { ostringstream ss; ss << this; return ss.str(); }
const ATuple* as_tuple() const {
- assert(tag() == T_TUPLE || tag() == T_TYPE);
+ assert(tag() == T_TUPLE);
return (ATuple*)this;
}
const ATuple* to_tuple() const {
- if (tag() == T_TUPLE || tag() == T_TYPE)
+ if (tag() == T_TUPLE)
return (const ATuple*)this;
return NULL;
}
@@ -187,22 +186,10 @@ struct AST : public Object {
const ASymbol* as_symbol() const { return as_a<const ASymbol>(T_SYMBOL); }
const ASymbol* to_symbol() const { return to_a<const ASymbol>(T_SYMBOL); }
- const AType* as_type() const { return as_a<const AType>(T_TYPE); }
- const AType* to_type() const { return to_a<const AType>(T_TYPE); }
Cursor loc;
};
-template<typename T>
-static T* tup(Cursor c, AST* ast, ...)
-{
- va_list args;
- va_start(args, ast);
- T* ret = new T(c, ast, args);
- va_end(args);
- return ret;
-}
-
/// Literal value
template<typename T>
struct ALiteral : public AST {
@@ -334,8 +321,19 @@ private:
const AST** _vec;
};
+inline ATuple* tup(Cursor c, AST* ast, ...) {
+ va_list args;
+ va_start(args, ast);
+ ATuple* ret = new ATuple(c, ast, args);
+ va_end(args);
+ return ret;
+}
+
static bool
list_contains(const ATuple* head, const AST* child) {
+ if (!head)
+ return false;
+
if (*head == *child)
return true;
@@ -351,70 +349,62 @@ list_contains(const ATuple* head, const AST* child) {
return false;
}
-/// Type Expression, e.g. "Int", "(Fn (Int Int) Float)"
-struct AType : public ATuple {
- enum Kind { VAR, NAME, EXPR };
- AType(const ASymbol* s, Kind k) : ATuple(s, NULL, s->loc), kind(k), id(0) { tag(T_TYPE); }
- AType(Cursor c, unsigned i) : ATuple(c), kind(VAR), id(i) { tag(T_TYPE); }
- AType(Cursor c, Kind k=EXPR) : ATuple(c), kind(k), id(0) { tag(T_TYPE); }
- AType(Cursor c, AST* ast, va_list args) : ATuple(c, ast, args), kind(EXPR), id(0) { tag(T_TYPE); }
- AType(const AST* first, const AST* rest, Cursor c) : ATuple(first, rest, c), kind(EXPR), id(0) { tag(T_TYPE); }
- AType(const AType& copy, Cursor cur) : ATuple(copy), kind(copy.kind), id(copy.id) {
- tag(T_TYPE);
- loc = cur;
- }
- Kind kind;
- unsigned id;
+inline bool
+list_equals(const ATuple* lhs, const ATuple* rhs)
+{
+ if (!rhs || rhs->tup_len() != lhs->tup_len()) return false;
+ ATuple::const_iterator l = lhs->begin();
+ FOREACHP(ATuple::const_iterator, r, rhs)
+ if (!(*(*l++) == *(*r)))
+ return false;
+ return true;
+}
+
+struct AType {
+ static inline bool is_var(const AST* type) { return type->tag() == T_TVAR; }
+ static inline bool is_name(const AST* type) { return type->tag() == T_SYMBOL; }
+ static inline bool is_expr(const AST* type) { return type->tag() == T_TUPLE; }
+
+ static inline uint32_t var_id(const AST* type) {
+ assert(is_var(type));
+ return ((ALiteral<int32_t>*)type)->val;
+ }
};
// Utility class for easily building lists from left to right
-template<typename CT, typename ET> // ConsType, ElementType
struct List {
- explicit List(CT* h=0) : head(h), tail(0) {}
- List(Cursor c, ET* ast, ...) : head(0), tail(0) {
+ explicit List(ATuple* h=0) : head(h), tail(0) {}
+ List(Cursor c, const AST* ast, ...) : head(0), tail(0) {
push_back(ast);
assert(*head->begin() == ast);
head->loc = c;
va_list args;
va_start(args, ast);
- for (ET* a = va_arg(args, ET*); a; a = va_arg(args, ET*))
+ for (const AST* a = va_arg(args, const AST*); a; a = va_arg(args, const AST*))
push_back(a);
va_end(args);
}
- void push_back(ET* ast) {
+ void push_back(const AST* ast) {
if (!head) {
- head = new CT(ast, NULL, Cursor());
+ head = new ATuple(ast, NULL, Cursor());
} else if (!tail) {
- CT* node = new CT(ast, NULL, Cursor());
+ ATuple* node = new ATuple(ast, NULL, Cursor());
head->last(node);
tail = node;
} else {
- CT* node = new CT(ast, NULL, Cursor());
+ ATuple* node = new ATuple(ast, NULL, Cursor());
tail->last(node);
tail = node;
}
}
- void push_front(ET* ast) {
- head = new CT(ast, head, Cursor());
+ void push_front(const AST* ast) {
+ head = new ATuple(ast, head, Cursor());
}
- operator CT*() const { return head; }
- CT* head;
- CT* tail;
+ operator ATuple*() const { return head; }
+ ATuple* head;
+ ATuple* tail;
};
-typedef List<AType, const AType> TList;
-
-inline bool
-list_equals(const ATuple* lhs, const ATuple* rhs)
-{
- if (!rhs || rhs->tup_len() != lhs->tup_len()) return false;
- ATuple::const_iterator l = lhs->begin();
- FOREACHP(ATuple::const_iterator, r, rhs)
- if (!(*(*l++) == *(*r)))
- return false;
- return true;
-}
-
template<typename T>
inline bool
literal_equals(const ALiteral<T>* lhs, const ALiteral<T>* rhs)
@@ -422,6 +412,7 @@ literal_equals(const ALiteral<T>* lhs, const ALiteral<T>* rhs)
return lhs && rhs && lhs->val == rhs->val;
}
+
inline bool
AST::operator==(const AST& rhs) const
{
@@ -435,6 +426,7 @@ AST::operator==(const AST& rhs) const
case T_FLOAT:
return literal_equals((const ALiteral<float>*)this, (const ALiteral<float>*)&rhs);
case T_INT32:
+ case T_TVAR:
return literal_equals((const ALiteral<int32_t>*)this, (const ALiteral<int32_t>*)&rhs);
case T_TUPLE:
{
@@ -442,22 +434,6 @@ AST::operator==(const AST& rhs) const
const ATuple* rt = rhs.to_tuple();
return list_equals(me, rt);
}
- case T_TYPE:
- {
- const AType* me = this->as_type();
- const AType* rt = rhs.to_type();
- if (!rt || me->kind != rt->kind) {
- assert(str() != rt->str());
- return false;
- } else {
- switch (me->kind) {
- case AType::VAR: return me->id == rt->id;
- case AType::NAME: return me->head()->str() == rt->head()->str();
- case AType::EXPR: return list_equals(me, rt);
- }
- }
- return false; // never reached
- }
case T_STRING:
return ((AString*)this)->cppstr == ((AString*)&rhs)->cppstr;
case T_SYMBOL:
@@ -557,39 +533,39 @@ struct PEnv : private map<const string, const char*> {
***************************************************************************/
/// Type constraint
-struct Constraint : public pair<const AType*,const AType*> {
- Constraint(const AType* a, const AType* b)
- : pair<const AType*, const AType*>(a, b) {}
+struct Constraint : public pair<const AST*,const AST*> {
+ Constraint(const AST* a, const AST* b)
+ : pair<const AST*, const AST*>(a, b) {}
};
/// Type substitution
struct Subst : public list<Constraint> {
- Subst(const AType* s=0, const AType* t=0) {
+ Subst(const AST* s=0, const AST* t=0) {
if (s && t) { assert(s != t); push_back(Constraint(s, t)); }
}
static Subst compose(const Subst& delta, const Subst& gamma);
- void add(const AType* from, const AType* to) {
+ void add(const AST* from, const AST* to) {
assert(from && to);
push_back(Constraint(from, to));
}
- const_iterator find(const AType* t) const {
+ const_iterator find(const AST* t) const {
for (const_iterator j = begin(); j != end(); ++j)
if (*j->first == *t)
return j;
return end();
}
- const AType* apply(const AType* in) const {
- if (in->kind == AType::EXPR) {
- TList out;
- for (ATuple::const_iterator i = in->begin(); i != in->end(); ++i)
- out.push_back(apply((*i)->as_type()));
+ const AST* apply(const AST* in) const {
+ if (AType::is_expr(in)) {
+ List out;
+ for (ATuple::const_iterator i = in->as_tuple()->begin(); i != in->as_tuple()->end(); ++i)
+ out.push_back(apply((*i)));
out.head->loc = in->loc;
return out.head;
} else {
const_iterator i = find(in);
if (i != end()) {
- const AType* out = i->second->as_type();
- if (out->kind == AType::EXPR)
+ const AST* out = i->second;
+ if (AType::is_expr(out))
out = apply(out);
return out;
} else {
@@ -597,11 +573,12 @@ struct Subst : public list<Constraint> {
}
}
}
- bool contains(const AType* type) const {
+ bool contains(const AST* type) const {
if (find(type) != end())
return true;
FOREACHP(const_iterator, j, this)
- if (*j->second == *type || list_contains(j->second, type))
+ if (*j->second == *type
+ || (AType::is_expr(j->second) && list_contains(j->second->as_tuple(), type)))
return true;
return false;
}
@@ -621,8 +598,8 @@ struct Constraints : public list<Constraint> {
push_back(Constraint(i->first, i->second));
}
Constraints(const_iterator begin, const_iterator end) : list<Constraint>(begin, end) {}
- void constrain(TEnv& tenv, const AST* o, const AType* t);
- Constraints& replace(const AType* s, const AType* t);
+ void constrain(TEnv& tenv, const AST* o, const AST* t);
+ Constraints& replace(const AST* s, const AST* t);
};
inline ostream& operator<<(ostream& out, const Constraints& c) {
@@ -632,51 +609,51 @@ inline ostream& operator<<(ostream& out, const Constraints& c) {
}
/// Type-Time Environment
-struct TEnv : public Env<const AType*> {
+struct TEnv : public Env<const AST*> {
explicit TEnv(PEnv& p)
: penv(p)
, varID(1)
- , Closure(new AType(penv.sym("Closure"), AType::NAME))
- , Dots(new AType(penv.sym("..."), AType::NAME))
- , Fn(new AType(penv.sym("Fn"), AType::NAME))
- , Tup(new AType(penv.sym("Tup"), AType::NAME))
- , U(new AType(penv.sym("U"), AType::NAME))
+ , Closure(penv.sym("Closure"))
+ , Dots(penv.sym("..."))
+ , Fn(penv.sym("Fn"))
+ , Tup(penv.sym("Tup"))
+ , U(penv.sym("U"))
{
Object::pool.addRoot(Fn);
}
- const AType* fresh(const ASymbol* sym) {
- return def(sym, new AType(sym->loc, varID++));
+ const AST* fresh(const ASymbol* sym) {
+ return def(sym, new ALiteral<int32_t>(T_TVAR, varID++, sym->loc));
}
- const AType* var(const AST* ast=0) {
+ const AST* var(const AST* ast=0) {
if (!ast)
- return new AType(Cursor(), varID++);
+ return new ALiteral<int32_t>(T_TVAR, varID++, Cursor());
- assert(!ast->to_type());
+ assert(!AType::is_var(ast));
Vars::iterator v = vars.find(ast);
if (v != vars.end())
return v->second;
- return (vars[ast] = new AType(ast->loc, varID++));
+ return (vars[ast] = new ALiteral<int32_t>(T_TVAR, varID++, ast->loc));
}
- const AType** ref(const ASymbol* sym) {
- return ((Env<const AType*>*)this)->ref(sym);
+ const AST** ref(const ASymbol* sym) {
+ return ((Env<const AST*>*)this)->ref(sym);
}
- const AType* named(const string& name) {
+ const AST* named(const string& name) {
return *ref(penv.sym(name));
}
- static Subst buildSubst(const AType* fnT, const AType& argsT);
+ static Subst buildSubst(const AST* fnT, const AST& argsT);
- typedef map<const AST*, const AType*> Vars;
+ typedef map<const AST*, const AST*> Vars;
Vars vars;
PEnv& penv;
unsigned varID;
- AType* Closure;
- AType* Dots;
- AType* Fn;
- AType* Tup;
- AType* U;
+ ASymbol* Closure;
+ ASymbol* Dots;
+ ASymbol* Fn;
+ ASymbol* Tup;
+ ASymbol* U;
};
Subst unify(const Constraints& c);
@@ -686,8 +663,6 @@ Subst unify(const Constraints& c);
* Code Generation *
***************************************************************************/
-typedef void* IfState;
-
/// Compiler backend
struct Engine {
virtual ~Engine() {}
@@ -697,30 +672,30 @@ struct Engine {
virtual CFunc startFn(CEnv& cenv,
const std::string& name,
const ATuple* args,
- const AType* type) = 0;
+ const ATuple* type) = 0;
virtual void pushFnArgs(CEnv& cenv,
const ATuple* prot,
- const AType* type,
+ const ATuple* type,
CFunc f) = 0;
virtual void finishFn(CEnv& cenv, CFunc f, CVal ret) = 0;
virtual void eraseFn(CEnv& cenv, CFunc f) = 0;
- virtual CVal compileCall(CEnv& cenv, CFunc f, const AType* fT, CVals& args) = 0;
- virtual CVal compileCons(CEnv& cenv, const AType* t, CVal rtti, CVals& f) = 0;
+ virtual CVal compileCall(CEnv& cenv, CFunc f, const ATuple* fT, CVals& args) = 0;
+ virtual CVal compileCons(CEnv& cenv, const ATuple* t, CVal rtti, CVals& f) = 0;
virtual CVal compileDot(CEnv& cenv, CVal tup, int32_t index) = 0;
- virtual CVal compileGlobalSet(CEnv& cenv, const string& s, CVal v, const AType* t) = 0;
+ virtual CVal compileGlobalSet(CEnv& cenv, const string& s, CVal v, const AST* t) = 0;
virtual CVal compileGlobalGet(CEnv& cenv, const string& s, CVal v) = 0;
virtual CVal compileIf(CEnv& cenv, const AST* cond, const AST* then, const AST* aelse) = 0;
- virtual CVal compileIsA(CEnv& cenv, CVal rtti, const ASymbol* tag) = 0;
+ virtual CVal compileIsA(CEnv& cenv, CVal rtti, CVal tag) = 0;
virtual CVal compileLiteral(CEnv& cenv, const AST* lit) = 0;
virtual CVal compilePrimitive(CEnv& cenv, const ATuple* prim) = 0;
virtual CVal compileString(CEnv& cenv, const char* str) = 0;
virtual void writeModule(CEnv& cenv, std::ostream& os) = 0;
- virtual const string call(CEnv& cenv, CFunc f, const AType* retT) = 0;
+ virtual const string call(CEnv& cenv, CFunc f, const AST* retT) = 0;
};
Engine* resp_new_llvm_engine();
@@ -744,28 +719,28 @@ struct CEnv {
if (type(ast))
Object::pool.addRoot(type(ast));
}
- const AType* resolveType(const AType* type) const {
- if (type->kind == AType::NAME)
- return tenv.named(type->head()->to_symbol()->sym());
+ const AST* resolveType(const AST* type) const {
+ if (AType::is_name(type))
+ return tenv.named(type->as_symbol()->sym());
return type;
}
- const AType* type(const AST* ast, const Subst& subst = Subst(), bool resolve=true) const {
- const AType* ret = NULL;
+ const AST* type(const AST* ast, const Subst& subst = Subst(), bool resolve=true) const {
+ const AST* ret = NULL;
const ASymbol* sym = ast->to_symbol();
if (sym) {
- const AType** rec = tenv.ref(sym);
+ const AST** rec = tenv.ref(sym);
if (rec)
ret = *rec;
}
if (!ret)
ret = tenv.vars[ast];
if (ret)
- ret = tsubst.apply(subst.apply(ret))->to_type();
+ ret = tsubst.apply(subst.apply(ret));
if (resolve && ret)
ret = this->resolveType(ret);
return ret;
}
- void def(const ASymbol* sym, const AST* c, const AType* t, CVal v) {
+ void def(const ASymbol* sym, const AST* c, const AST* t, CVal v) {
code.def(sym, c);
tenv.def(sym, t);
vals.def(sym, v);
@@ -775,9 +750,9 @@ struct CEnv {
const AST** rec = code.ref(sym);
return rec ? *rec : ast;
}
- void setType(const AST* ast, const AType* type) {
+ void setType(const AST* ast, const AST* type) {
assert(!ast->to_symbol());
- const AType* tvar = tenv.var();
+ const AST* tvar = tenv.var();
tenv.vars.insert(make_pair(ast, tvar));
tsubst.add(tvar, type);
}
@@ -797,7 +772,7 @@ struct CEnv {
typedef map<const ATuple*, CFunc> Impls;
Impls impls;
- CFunc findImpl(const ATuple* fn, const AType* type) {
+ CFunc findImpl(const ATuple* fn, const AST* type) {
Impls::const_iterator i = impls.find(fn);
return (i != impls.end()) ? i->second : NULL;
}