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";
51 static std::string IdentifierStr;
54 ///Returns the next token from stdin
56 static int LastChar = ' ';
58 while (isspace(LastChar))
61 if (isalpha(LastChar)) {
62 IdentifierStr = LastChar;
63 while (isalnum((LastChar = getchar())))
64 IdentifierStr += LastChar;
66 if (IdentifierStr == "def") return tok_def;
67 if (IdentifierStr == "extern") return tok_extern;
68 if (IdentifierStr == "if") return tok_if;
69 if (IdentifierStr == "then") return tok_then;
70 if (IdentifierStr == "else") return tok_else;
71 if (IdentifierStr == "binary") return tok_binary;
72 if (IdentifierStr == "unary") return tok_unary;
74 return tok_identifier;
77 if (isdigit(LastChar) || LastChar == '.') {
82 } while (isdigit(LastChar) || LastChar == '.');
84 NumVal = strtod(NumStr.c_str(), 0);
88 if (LastChar == '#') {
89 //Coment until the end of the line
92 while(LastChar != EOF && LastChar != '\n' && LastChar != '\r');
98 //Check for end of file
102 int ThisChar = LastChar;
103 LastChar = getchar();
109 static int getNextToken() {
110 return CurTok = gettok();
113 std::unique_ptr<PrototypeAST> LogErrorP(std::string str) {
118 static std::unique_ptr<ExprAST> ParseNumberExpr() {
119 auto Result = llvm::make_unique<NumberExprAST>(NumVal);
120 getNextToken(); // consume the number
121 return std::move(Result);
124 static std::unique_ptr<ExprAST> ParseParenExpr() {
126 auto V = ParseExpression();
131 return LogError("expected ')'");
136 static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
137 std::string IdName = IdentifierStr;
142 return llvm::make_unique<VariableExprAST>(IdName);
146 std::vector<std::unique_ptr<ExprAST>> Args;
149 if (auto Arg = ParseExpression())
150 Args.push_back(std::move(Arg));
158 return LogError("Expected ')' or ',' in argument list");
164 return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
167 static std::unique_ptr<ExprAST> ParseIfExpr() {
168 getNextToken(); // eat the if
170 auto condExpr = ParseExpression();
171 if (!condExpr) return nullptr;
173 if (CurTok != tok_then)
174 return LogError("Expected then");
175 getNextToken(); // eat the then
177 auto thenExpr = ParseExpression();
178 if (!thenExpr) return nullptr;
180 if (CurTok != tok_else)
181 return LogError("Expected else");
182 getNextToken(); // eat the else
184 auto elseExpr = ParseExpression();
185 if (!elseExpr) return nullptr;
187 return llvm::make_unique<IfExprAST>(std::move(condExpr),
189 std::move(elseExpr));
192 static std::unique_ptr<ExprAST> ParseForExpr() {
193 getNextToken(); // eat the for
195 if (CurTok != tok_identifier)
196 return LogError("Expected identifier after for");
198 std::string id = IdentifierStr;
199 getNextToken(); // eat the identifier
202 return LogError("Expected = after for");
203 getNextToken(); // eat the =
205 auto start = ParseExpression();
206 if (!start) return nullptr;
209 return LogError("Expected , after for start value");
210 getNextToken(); // eat the ,
212 auto end = ParseExpression();
216 // optional step value
217 std::unique_ptr<ExprAST> step;
219 getNextToken(); // eat the ,
220 step = ParseExpression();
221 if (!step) return nullptr;
224 if (CurTok != tok_in)
225 return LogError("Expected in after for");
226 getNextToken(); // eat the in
228 auto body = ParseExpression();
229 if (!body) return nullptr;
231 return llvm::make_unique<ForExprAST>(id,
238 static std::unique_ptr<ExprAST> ParsePrimary() {
241 return LogError(std::string("Unknown token when expected an expression: ")
242 + std::to_string(CurTok));
244 return ParseIdentifierExpr();
246 return ParseNumberExpr();
248 return ParseParenExpr();
250 return ParseIfExpr();
252 return ParseForExpr();
256 static int GetTokPrecedence() {
257 if (!isascii(CurTok))
260 int TokPrec = BinopPrecedence[CurTok];
261 if (TokPrec <= 0) return -1;
265 static std::unique_ptr<ExprAST> ParseExpression() {
266 auto LHS = ParsePrimary();
269 return ParseBinOpRHS(0, std::move(LHS));
272 static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
273 std::unique_ptr<ExprAST> LHS) {
275 int TokPrec = GetTokPrecedence();
276 if (TokPrec < ExprPrec)
280 getNextToken(); // eat binop
282 auto RHS = ParsePrimary();
286 int NextPrec = GetTokPrecedence();
287 if (TokPrec < NextPrec) {
288 RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
293 LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
297 static std::unique_ptr<PrototypeAST> ParsePrototype() {
300 unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary
301 unsigned BinaryPrecedence = 30;
305 return LogErrorP("Expected function name in prototype");
307 FnName = IdentifierStr;
313 if (!isascii(CurTok)) return LogErrorP("Expected binary operator");
315 FnName += (char)CurTok;
318 if (CurTok == tok_number) {
319 if (NumVal < 1 || NumVal > 100)
320 return LogErrorP("Invalid precedence: must be 1..100");
321 BinaryPrecedence = (unsigned)NumVal;
328 return LogErrorP("Expected '(' in prototype");
330 std::vector<std::string> ArgNames;
331 while (getNextToken() == tok_identifier)
332 ArgNames.push_back(IdentifierStr);
334 return LogErrorP("Expected ')' in prototype");
336 getNextToken(); // eat ')'
338 if (Kind && ArgNames.size() != Kind)
339 return LogErrorP("Invalid number of of arguments for operator");
341 return llvm::make_unique<PrototypeAST>(FnName,
347 static std::unique_ptr<FunctionAST> ParseDefinition() {
349 auto Proto = ParsePrototype();
350 if (!Proto) return nullptr;
352 if (auto E = ParseExpression())
353 return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
357 static std::unique_ptr<PrototypeAST> ParseExtern() {
359 return ParsePrototype();
362 static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
363 if (auto e = ParseExpression()) {
364 // make an anonymous prototype
365 auto proto = llvm::make_unique<PrototypeAST>(ANON_EXPR_FUNC_NAME, std::vector<std::string>());
366 return llvm::make_unique<FunctionAST>(std::move(proto), std::move(e));
371 static void HandleDefinition() {
372 if (auto def = ParseDefinition()) {
373 if (auto gen = def->codegen()) {
374 std::cerr << "Read function defintion:";
378 TheEngine->addModule(std::move(TheModule));
379 InitializeModuleAndPassManager();
383 getNextToken(); // skip token for error recovery
386 static void HandleExtern() {
387 if (auto externProto = ParseExtern()) {
388 if (auto gen = externProto->codegen()) {
389 std::cerr << "Read an extern:\n";
392 functionProtos[externProto->getName()] = std::move(externProto);
396 getNextToken(); // skip token for error recovery
399 static void HandleTopLevelExpr() {
400 if (auto expr = ParseTopLevelExpr()) {
401 if (auto gen = expr->codegen()) {
402 auto module = TheModule.get();
403 TheEngine->addModule(std::move(TheModule));
404 InitializeModuleAndPassManager();
406 auto func = TheEngine->FindFunctionNamed(ANON_EXPR_FUNC_NAME);
407 GenericValue gv = TheEngine->runFunction(func, std::vector<GenericValue>());
408 std::cerr << "Evaluated to " << std::fixed << std::setw(5) << gv.DoubleVal << std::endl;
410 TheEngine->removeModule(module);
414 getNextToken(); // skip token for error recovery
419 fprintf(stderr, "ready> ");
433 HandleTopLevelExpr();
440 InitializeNativeTarget();
441 InitializeNativeTargetAsmPrinter();
442 InitializeNativeTargetAsmParser();
444 BinopPrecedence['<'] = 10;
445 BinopPrecedence['>'] = 10;
446 BinopPrecedence['|'] = 5;
447 BinopPrecedence['+'] = 20;
448 BinopPrecedence['-'] = 20;
449 BinopPrecedence['*'] = 40;
451 InitializeModuleAndPassManager();
453 std::string engineError;
454 TheEngine = EngineBuilder(std::move(TheModule)).setEngineKind(EngineKind::JIT).setErrorStr(&engineError).create();
455 if (!engineError.empty())
456 std::cout << engineError << "\n";
458 InitializeModuleAndPassManager();
460 // prime the first token
461 std::cerr << "ready> ";