diff options
author | David Robillard <d@drobilla.net> | 2010-08-19 03:25:43 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-08-19 03:25:43 +0000 |
commit | 9a1c3c7cfc96cb6ee1c9f7bc103b99b89da43d6e (patch) | |
tree | 3c0f7348198b9c722c67ed6f2e819fa8e8150767 /src/llvm.cpp | |
parent | 1bc26254cf83449017b24afd90420916d8f512aa (diff) | |
download | resp-9a1c3c7cfc96cb6ee1c9f7bc103b99b89da43d6e.tar.gz resp-9a1c3c7cfc96cb6ee1c9f7bc103b99b89da43d6e.tar.bz2 resp-9a1c3c7cfc96cb6ee1c9f7bc103b99b89da43d6e.zip |
Coherent AString and Lexeme implementation.
A Lexeme is any "token" read from input, a lexeme has not yet beeen parsed
and could parse to anything, e.g. a string, an expression, a number, etc.
Lexemes are not (yet?) exposed to the language or ever compiled.
A String is a string literal, which can contain any character directly
except " and \. There are two special escapes: \" and \\, any other
character following a \ is a syntax error.
Fix garbage collection of REPL objects, leading to type errors from
type variable re-use because a type variable for a given AST's /address/
exists, but that address has actually been deleted and reused by new
(i.e. make top level REPL expressions and types be GC roots).
git-svn-id: http://svn.drobilla.net/resp/resp@261 ad02d1e2-f140-0410-9f75-f8b11f17cedd
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) { |