aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-03-06 22:33:58 +0000
committerDavid Robillard <d@drobilla.net>2009-03-06 22:33:58 +0000
commit77162da0f773b8e79939491aca4e0232c62c255c (patch)
treec9618c6b9b52a20a9bf9830d9da69bd6ff732fbc
parentecef8f697c66e15b85beb934d2b617b915a97aab (diff)
downloadresp-77162da0f773b8e79939491aca4e0232c62c255c.tar.gz
resp-77162da0f773b8e79939491aca4e0232c62c255c.tar.bz2
resp-77162da0f773b8e79939491aca4e0232c62c255c.zip
Remove low level type stuff completely from core code (let the backend deal with conversion of abstract types to compiled types).
git-svn-id: http://svn.drobilla.net/resp/tuplr@65 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--llvm.cpp73
-rw-r--r--tuplr.cpp6
-rw-r--r--tuplr.hpp32
3 files changed, 58 insertions, 53 deletions
diff --git a/llvm.cpp b/llvm.cpp
index 03c49f9..b981d7d 100644
--- a/llvm.cpp
+++ b/llvm.cpp
@@ -35,9 +35,8 @@ using namespace llvm;
using namespace std;
using boost::format;
-inline Value* LLVal(CValue v) { return static_cast<Value*>(v); }
-inline const Type* LLType(CType t) { return static_cast<const Type*>(t); }
-inline Function* LLFunc(CFunction f) { return static_cast<Function*>(f); }
+inline Value* LLVal(CValue v) { return static_cast<Value*>(v); }
+inline Function* LLFunc(CFunction f) { return static_cast<Function*>(f); }
struct CEngine {
CEngine();
@@ -51,19 +50,28 @@ struct CEngine {
* Typing *
***************************************************************************/
-CType
-AType::ctype()
+const Type*
+lltype(AType* t)
{
- if (at(0)->str() == "Pair") {
- vector<const Type*> types;
- for (size_t i = 1; i < size(); ++i) {
- assert(dynamic_cast<AType*>(at(i)));
- types.push_back(LLType(((AType*)at(i))->ctype()));
+ switch (t->kind) {
+ case AType::VAR:
+ return NULL;
+ case AType::PRIM:
+ if (t->at(0)->str() == "Bool") return Type::Int1Ty;
+ if (t->at(0)->str() == "Int") return Type::Int32Ty;
+ if (t->at(0)->str() == "Float") return Type::FloatTy;
+ throw Error(string("Unknown primitive type `") + t->str() + "'");
+ case AType::EXPR:
+ if (t->at(0)->str() == "Pair") {
+ vector<const Type*> types;
+ for (size_t i = 1; i < t->size(); ++i)
+ types.push_back(lltype(dynamic_cast<AType*>(t->at(i))));
+ return PointerType::get(StructType::get(types, false), 0);
+ } else {
+ throw Error(string("Unknown composite type `") + t->str() + "'");
}
- return PointerType::get(StructType::get(types, false), 0);
- } else {
- return _ctype;
}
+ return NULL; // not reached
}
@@ -141,7 +149,7 @@ LITERAL(float, "Float", ConstantFP::get(Type::FloatTy, val))
LITERAL(bool, "Bool", ConstantInt::get(Type::Int1Ty, val, false))
static Function*
-compileFunction(CEnv& cenv, const std::string& name, CType retT, const ASTTuple& prot,
+compileFunction(CEnv& cenv, const std::string& name, const Type* retT, const ASTTuple& prot,
const vector<string> argNames=vector<string>())
{
Function::LinkageTypes linkage = Function::ExternalLinkage;
@@ -149,8 +157,8 @@ compileFunction(CEnv& cenv, const std::string& name, CType retT, const ASTTuple&
vector<const Type*> cprot;
for (size_t i = 0; i < prot.size(); ++i) {
AType* at = cenv.tenv.type(prot.at(i));
- if (!at->ctype() || at->var()) throw Error("function parameter is untyped");
- cprot.push_back(LLType(at->ctype()));
+ if (!lltype(at)) throw Error("function parameter is untyped");
+ cprot.push_back(lltype(at));
}
if (!retT) throw Error("function return is untyped");
@@ -201,7 +209,7 @@ ASTClosure::lift(CEnv& cenv)
// Write function declaration
string name = this->name == "" ? cenv.gensym("_fn") : this->name;
- Function* f = compileFunction(cenv, name, cenv.tenv.type(at(2))->ctype(), *prot());
+ Function* f = compileFunction(cenv, name, lltype(cenv.tenv.type(at(2))), *prot());
// Bind argument values in CEnv
vector<Value*> args;
@@ -330,7 +338,7 @@ ASTIf::compile(CEnv& cenv)
// Emit merge block (Phi node)
parent->getBasicBlockList().push_back(mergeBB);
cenv.engine.builder.SetInsertPoint(mergeBB);
- PHINode* pn = cenv.engine.builder.CreatePHI(LLType(cenv.tenv.type(this)->ctype()), "ifval");
+ PHINode* pn = cenv.engine.builder.CreatePHI(lltype(cenv.tenv.type(this)), "ifval");
FOREACH(Branches::iterator, i, branches)
pn->addIncoming(i->first, i->second);
@@ -404,7 +412,7 @@ ASTConsCall::lift(CEnv& cenv)
vector<const Type*> types;
size_t sz = 0;
for (size_t i = 1; i < size(); ++i) {
- const Type* t = LLType(cenv.tenv.type(at(i))->ctype());
+ const Type* t = lltype(cenv.tenv.type(at(i)));
types.push_back(t);
sz += t->getPrimitiveSizeInBits();
}
@@ -471,19 +479,6 @@ ASTCdrCall::compile(CEnv& cenv)
/***************************************************************************
- * Standard Definitions *
- ***************************************************************************/
-
-void
-initTypes(PEnv& penv, TEnv& tenv)
-{
- tenv.def(penv.sym("Bool"), new AType(penv.sym("Bool"), Type::Int1Ty));
- tenv.def(penv.sym("Int"), new AType(penv.sym("Int"), Type::Int32Ty));
- tenv.def(penv.sym("Float"), new AType(penv.sym("Float"), Type::FloatTy));
-}
-
-
-/***************************************************************************
* EVAL/REPL *
***************************************************************************/
@@ -491,11 +486,11 @@ const string
call(AType* retT, void* fp)
{
std::stringstream ss;
- if (retT->ctype() == Type::Int32Ty)
+ if (lltype(retT) == Type::Int32Ty)
ss << ((int32_t (*)())fp)();
- else if (retT->ctype() == Type::FloatTy)
+ else if (lltype(retT) == Type::FloatTy)
ss << ((float (*)())fp)();
- else if (retT->ctype() == Type::Int1Ty)
+ else if (lltype(retT) == Type::Int1Ty)
ss << ((bool (*)())fp)();
else
ss << ((void* (*)())fp)();
@@ -525,8 +520,8 @@ eval(CEnv& cenv, const string& name, istream& is)
if (!resultType || resultType->var()) throw Error("body is undefined/untyped", cursor);
- CType ctype = resultType->ctype();
- if (!ctype) throw Error("body has no system type", cursor);
+ const Type* ctype = lltype(resultType);
+ if (!ctype) throw Error("body has non-compilable type", cursor);
// Create function for top-level of program
Function* f = compileFunction(cenv, "main", ctype, ASTTuple());
@@ -570,9 +565,9 @@ repl(CEnv& cenv)
body->lift(cenv);
- if (bodyT->ctype()) {
+ if (lltype(bodyT)) {
// Create anonymous function to insert code into
- Function* f = compileFunction(cenv, cenv.gensym("_repl"), bodyT->ctype(), ASTTuple());
+ Function* f = compileFunction(cenv, cenv.gensym("_repl"), lltype(bodyT), ASTTuple());
try {
Value* retVal = LLVal(cenv.compile(body));
cenv.engine.builder.CreateRet(retVal); // Finish function
diff --git a/tuplr.cpp b/tuplr.cpp
index 580416c..0200a36 100644
--- a/tuplr.cpp
+++ b/tuplr.cpp
@@ -100,6 +100,11 @@ readExpression(Cursor& cur, std::istream& in)
void
initLang(PEnv& penv, TEnv& tenv)
{
+ // Types
+ tenv.def(penv.sym("Bool"), new AType(penv.sym("Bool")));
+ tenv.def(penv.sym("Int"), new AType(penv.sym("Int")));
+ tenv.def(penv.sym("Float"), new AType(penv.sym("Float")));
+
// Literals
static bool trueVal = true;
static bool falseVal = false;
@@ -155,7 +160,6 @@ main(int argc, char** argv)
{
PEnv penv;
TEnv tenv(penv);
- initTypes(penv, tenv);
initLang(penv, tenv);
CEnv* cenv = newCenv(penv, tenv);
diff --git a/tuplr.hpp b/tuplr.hpp
index 0bfb5c1..489868a 100644
--- a/tuplr.hpp
+++ b/tuplr.hpp
@@ -26,17 +26,26 @@
#include <vector>
#include <boost/format.hpp>
-typedef void* CValue; ///< Compiled value (opaque)
-typedef const void* CType; ///< Compiled type (opaque)
-typedef void* CFunction; ///< Compiled function (opaque)
-
-struct CEngine; ///< Backend data (opaque)
-
#define FOREACH(IT, i, c) for (IT i = (c).begin(); i != (c).end(); ++i)
using namespace std;
using boost::format;
+
+/***************************************************************************
+ * Backend *
+ ***************************************************************************/
+
+typedef void* CValue; ///< Compiled value (opaque)
+typedef void* CFunction; ///< Compiled function (opaque)
+
+struct CEngine; ///< Backend data (opaque)
+
+
+/***************************************************************************
+ * Basic Utility Classes *
+ ***************************************************************************/
+
extern std::ostream& err;
extern std::ostream& out;
@@ -56,7 +65,7 @@ struct Error {
};
template<typename Atom>
-struct Exp { // ::= Atom | (Exp*)
+struct Exp {
Exp(Cursor c) : type(LIST), loc(c) {}
Exp(Cursor c, const Atom& a) : type(ATOM), loc(c), atom(a) {}
typedef std::vector< Exp<Atom> > List;
@@ -164,9 +173,9 @@ struct ASTTuple : public AST, public vector<AST*> {
/// Type Expression, e.g. "Int", "(Fn (Int Int) Float)"
struct AType : public ASTTuple {
- AType(const ASTTuple& t) : ASTTuple(t), kind(EXPR), _ctype(0) {}
- AType(unsigned i) : kind(VAR), id(i), _ctype(0) {}
- AType(ASTSymbol* n, CType t) : kind(PRIM), _ctype(t) { push_back(n); }
+ AType(unsigned i) : kind(VAR), id(i) {}
+ AType(ASTSymbol* s) : kind(PRIM), id(0) { push_back(s); }
+ AType(const ASTTuple& t) : ASTTuple(t), kind(EXPR), id(0) {}
string str() const {
switch (kind) {
case VAR: return (format("?%1%") % id).str();
@@ -203,11 +212,8 @@ struct AType : public ASTTuple {
}
return false; // never reached
}
- CType ctype();
enum { VAR, PRIM, EXPR } kind;
unsigned id;
-private:
- const CType _ctype;
};
/// Lifted system functions (of various types) for a single Tuplr function