diff options
Diffstat (limited to 'src/resp.hpp')
-rw-r--r-- | src/resp.hpp | 237 |
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; } |