8 #include <llvm/ADT/STLExtras.h>
9 #include <llvm/Support/raw_ostream.h>
10 #include <llvm/ExecutionEngine/ExecutionEngine.h>
11 #include <llvm/ExecutionEngine/GenericValue.h>
12 #include <llvm/Support/TargetSelect.h>
13 //Needed to force linking interpreter
14 #include <llvm/ExecutionEngine/MCJIT.h>
17 #include "codegen.hpp"
20 static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
21 std::unique_ptr<ExprAST> LHS);
22 static std::unique_ptr<ExprAST> ParseExpression();
24 static ExecutionEngine* TheEngine;
26 std::unique_ptr<Module> TheModule;
28 constexpr auto ANON_EXPR_FUNC_NAME = "__anon_expr";
40 static std::string IdentifierStr;
43 ///Returns the next token from stdin
45 static int LastChar = ' ';
47 while(isspace(LastChar))
50 if(isalpha(LastChar)) {
51 IdentifierStr = LastChar;
52 while(isalnum((LastChar = getchar())))
53 IdentifierStr += LastChar;
55 if(IdentifierStr == "def")
57 if(IdentifierStr == "extern")
59 return tok_identifier;
62 if(isdigit(LastChar) || LastChar == '.') {
67 } while (isdigit(LastChar) || LastChar == '.');
69 NumVal = strtod(NumStr.c_str(), 0);
74 //Coment until the end of the line
77 while(LastChar != EOF && LastChar != '\n' && LastChar != 'r');
83 //Check for end of file
87 int ThisChar = LastChar;
94 static int getNextToken() {
95 return CurTok = gettok();
98 std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
103 static std::unique_ptr<ExprAST> ParseNumberExpr() {
104 auto Result = llvm::make_unique<NumberExprAST>(NumVal);
105 getNextToken(); // consume the number
106 return std::move(Result);
109 static std::unique_ptr<ExprAST> ParseParenExpr() {
111 auto V = ParseExpression();
116 return LogError("expected ')'");
121 static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
122 std::string IdName = IdentifierStr;
127 return llvm::make_unique<VariableExprAST>(IdName);
131 std::vector<std::unique_ptr<ExprAST>> Args;
134 if (auto Arg = ParseExpression())
135 Args.push_back(std::move(Arg));
143 return LogError("Expected ')' or ',' in argument list");
149 return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
152 static std::unique_ptr<ExprAST> ParsePrimary() {
155 return LogError("Unknown token when expected an expression");
157 return ParseIdentifierExpr();
159 return ParseNumberExpr();
161 return ParseParenExpr();
165 static std::map<char, int> BinopPrecedence;
167 static int GetTokPrecedence() {
168 if (!isascii(CurTok))
171 int TokPrec = BinopPrecedence[CurTok];
172 if (TokPrec <= 0) return -1;
176 static std::unique_ptr<ExprAST> ParseExpression() {
177 auto LHS = ParsePrimary();
180 return ParseBinOpRHS(0, std::move(LHS));
183 static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
184 std::unique_ptr<ExprAST> LHS) {
186 int TokPrec = GetTokPrecedence();
187 if (TokPrec < ExprPrec)
191 getNextToken(); // eat binop
193 auto RHS = ParsePrimary();
197 int NextPrec = GetTokPrecedence();
198 if (TokPrec < NextPrec) {
199 RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
204 LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
208 static std::unique_ptr<PrototypeAST> ParsePrototype() {
209 if (CurTok != tok_identifier)
210 return LogErrorP("Expected function name in prototype");
212 std::string FnName = IdentifierStr;
216 return LogErrorP("Expected '(' in prototype");
218 std::vector<std::string> ArgNames;
219 while (getNextToken() == tok_identifier)
220 ArgNames.push_back(IdentifierStr);
222 return LogErrorP("Expected ')' in prototype");
224 getNextToken(); // eat ')'
226 return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
229 static std::unique_ptr<FunctionAST> ParseDefinition() {
231 auto Proto = ParsePrototype();
232 if (!Proto) return nullptr;
234 if (auto E = ParseExpression())
235 return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
239 static std::unique_ptr<PrototypeAST> ParseExtern() {
241 return ParsePrototype();
244 static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
245 if (auto e = ParseExpression()) {
246 // make an anonymous prototype
247 auto proto = llvm::make_unique<PrototypeAST>(ANON_EXPR_FUNC_NAME, std::vector<std::string>());
248 return llvm::make_unique<FunctionAST>(std::move(proto), std::move(e));
253 static void HandleDefinition() {
254 if (auto def = ParseDefinition()) {
255 if (auto gen = def->codegen()) {
256 std::cerr << "Read function defintion:";
260 TheEngine->addModule(std::move(TheModule));
261 InitializeModuleAndPassManager();
265 getNextToken(); // skip token for error recovery
268 static void HandleExtern() {
269 if (auto externProto = ParseExtern()) {
270 if (auto gen = externProto->codegen()) {
271 std::cerr << "Read an extern:\n";
274 functionProtos[externProto->getName()] = std::move(externProto);
278 getNextToken(); // skip token for error recovery
281 static void HandleTopLevelExpr() {
282 if (auto expr = ParseTopLevelExpr()) {
283 if (auto gen = expr->codegen()) {
286 auto module = TheModule.get();
287 TheEngine->addModule(std::move(TheModule));
288 InitializeModuleAndPassManager();
290 auto func = TheEngine->FindFunctionNamed(ANON_EXPR_FUNC_NAME);
291 GenericValue gv = TheEngine->runFunction(func, std::vector<GenericValue>());
292 std::cerr << "Evaluated to " << std::fixed << std::setw(5) << gv.DoubleVal << std::endl;
294 TheEngine->removeModule(module);
298 getNextToken(); // skip token for error recovery
303 fprintf(stderr, "ready> ");
317 HandleTopLevelExpr();
324 InitializeNativeTarget();
325 InitializeNativeTargetAsmPrinter();
326 InitializeNativeTargetAsmParser();
328 BinopPrecedence['<'] = 10;
329 BinopPrecedence['+'] = 20;
330 BinopPrecedence['-'] = 20;
331 BinopPrecedence['*'] = 40;
333 InitializeModuleAndPassManager();
335 std::string engineError;
336 TheEngine = EngineBuilder(std::move(TheModule)).setErrorStr(&engineError).create();
337 if (!engineError.empty())
338 std::cout << engineError << "\n";
340 InitializeModuleAndPassManager();
342 // prime the first token
343 std::cerr << "ready> ";