aboutsummaryrefslogtreecommitdiffstats
path: root/src/llvm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/llvm.cpp')
-rw-r--r--src/llvm.cpp35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/llvm.cpp b/src/llvm.cpp
index e4d7c07..043b5fc 100644
--- a/src/llvm.cpp
+++ b/src/llvm.cpp
@@ -93,6 +93,7 @@ struct LLVMEngine : public Engine {
if (t->head()->str() == "Bool") return Type::getInt1Ty(context);
if (t->head()->str() == "Int") return Type::getInt32Ty(context);
if (t->head()->str() == "Float") return Type::getFloatTy(context);
+ if (t->head()->str() == "String") return PointerType::get(Type::getInt8Ty(context), NULL);
throw Error(t->loc, string("Unknown primitive type `") + t->str() + "'");
} else if (t->kind == AType::EXPR && t->head()->str() == "Fn") {
AType::const_iterator i = t->begin();
@@ -188,6 +189,7 @@ struct LLVMEngine : public Engine {
CVal compileTup(CEnv& cenv, const AType* type, const vector<CVal>& fields);
CVal compileDot(CEnv& cenv, CVal tup, int32_t index);
CVal compileLiteral(CEnv& cenv, AST* lit);
+ CVal compileString(CEnv& cenv, const char* str);
CVal compilePrimitive(CEnv& cenv, APrimitive* prim);
CVal compileIf(CEnv& cenv, AIf* aif);
CVal compileGlobal(CEnv& cenv, const AType* type, const string& sym, CVal val);
@@ -206,16 +208,33 @@ struct LLVMEngine : public Engine {
THROW_IF(!t, Cursor(), "function with non-concrete return type called");
std::stringstream ss;
- if (t == Type::getInt32Ty(context))
+ if (t == Type::getInt32Ty(context)) {
ss << ((int32_t (*)())fp)();
- else if (t == Type::getFloatTy(context))
+ } else if (t == Type::getFloatTy(context)) {
ss << showpoint << ((float (*)())fp)();
- else if (t == Type::getInt1Ty(context))
+ } else if (t == Type::getInt1Ty(context)) {
ss << (((bool (*)())fp)() ? "#t" : "#f");
- else if (t != Type::getVoidTy(context))
+ } else if (retT->head()->str() == "String") {
+ const std::string s(((char* (*)())fp)());
+ ss << "\"";
+ for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
+ switch (*i) {
+ case '\"':
+ case '\\':
+ ss << '\\';
+ default:
+ ss << *i;
+ break;
+ }
+ }
+ ss << "\"";
+ } else if (retT->head()->str() == "Lexeme") {
+ ss << ((char* (*)())fp)();
+ } else if (t != Type::getVoidTy(context)) {
ss << ((void* (*)())fp)();
- else
+ } else {
((void (*)())fp)();
+ }
return ss.str();
}
@@ -293,6 +312,12 @@ LLVMEngine::compileLiteral(CEnv& cenv, AST* lit)
throw Error(lit->loc, "Unknown literal type");
}
+CVal
+LLVMEngine::compileString(CEnv& cenv, const char* str)
+{
+ return builder.CreateGlobalStringPtr(str);
+}
+
CFunc
LLVMEngine::compileFunction(CEnv& cenv, AFn* fn, const AType* type)
{