diff options
Diffstat (limited to 'src/llvm.cpp')
-rw-r--r-- | src/llvm.cpp | 35 |
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) { |