blob: cdf0d6c8cdb2b4e8daa1fd7e253109b3e5ae7b5a [file] [log] [blame]
Eugene Zelenkof981ec42016-05-19 01:08:04 +00001#include "llvm/ADT/APFloat.h"
Lang Hames09bf4c12015-08-18 18:11:06 +00002#include "llvm/ADT/STLExtras.h"
Eugene Zelenkof981ec42016-05-19 01:08:04 +00003#include "llvm/IR/BasicBlock.h"
4#include "llvm/IR/Constants.h"
5#include "llvm/IR/DerivedTypes.h"
6#include "llvm/IR/Function.h"
Chandler Carruth005f27a2013-01-02 11:56:33 +00007#include "llvm/IR/IRBuilder.h"
8#include "llvm/IR/LLVMContext.h"
9#include "llvm/IR/Module.h"
Eugene Zelenkof981ec42016-05-19 01:08:04 +000010#include "llvm/IR/Type.h"
Lang Hames2d789c32015-08-26 03:07:41 +000011#include "llvm/IR/Verifier.h"
Will Dietz981af002013-10-12 00:55:57 +000012#include <cctype>
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000013#include <cstdio>
Eugene Zelenkof981ec42016-05-19 01:08:04 +000014#include <cstdlib>
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000015#include <map>
Eugene Zelenkof981ec42016-05-19 01:08:04 +000016#include <memory>
Chandler Carruth605e30e2012-12-04 10:16:57 +000017#include <string>
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000018#include <vector>
Hans Wennborgcc9deb42015-09-29 18:02:48 +000019
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000020using namespace llvm;
21
22//===----------------------------------------------------------------------===//
23// Lexer
24//===----------------------------------------------------------------------===//
25
26// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
27// of these for known things.
28enum Token {
29 tok_eof = -1,
30
31 // commands
Lang Hames59b0da82015-08-19 18:15:58 +000032 tok_def = -2,
33 tok_extern = -3,
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000034
35 // primary
Lang Hames59b0da82015-08-19 18:15:58 +000036 tok_identifier = -4,
37 tok_number = -5
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000038};
39
Lang Hames59b0da82015-08-19 18:15:58 +000040static std::string IdentifierStr; // Filled in if tok_identifier
41static double NumVal; // Filled in if tok_number
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000042
43/// gettok - Return the next token from standard input.
44static int gettok() {
45 static int LastChar = ' ';
46
47 // Skip any whitespace.
48 while (isspace(LastChar))
49 LastChar = getchar();
50
51 if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
52 IdentifierStr = LastChar;
53 while (isalnum((LastChar = getchar())))
54 IdentifierStr += LastChar;
55
Lang Hames59b0da82015-08-19 18:15:58 +000056 if (IdentifierStr == "def")
57 return tok_def;
58 if (IdentifierStr == "extern")
59 return tok_extern;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000060 return tok_identifier;
61 }
62
Lang Hames59b0da82015-08-19 18:15:58 +000063 if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000064 std::string NumStr;
65 do {
66 NumStr += LastChar;
67 LastChar = getchar();
68 } while (isdigit(LastChar) || LastChar == '.');
69
Hans Wennborgcc9deb42015-09-29 18:02:48 +000070 NumVal = strtod(NumStr.c_str(), nullptr);
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000071 return tok_number;
72 }
73
74 if (LastChar == '#') {
75 // Comment until end of line.
Lang Hames59b0da82015-08-19 18:15:58 +000076 do
77 LastChar = getchar();
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000078 while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
Lang Hames59b0da82015-08-19 18:15:58 +000079
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000080 if (LastChar != EOF)
81 return gettok();
82 }
Lang Hames59b0da82015-08-19 18:15:58 +000083
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000084 // Check for end of file. Don't eat the EOF.
85 if (LastChar == EOF)
86 return tok_eof;
87
88 // Otherwise, just return the character as its ascii value.
89 int ThisChar = LastChar;
90 LastChar = getchar();
91 return ThisChar;
92}
93
94//===----------------------------------------------------------------------===//
95// Abstract Syntax Tree (aka Parse Tree)
96//===----------------------------------------------------------------------===//
Juergen Ributzka05c5a932013-11-19 03:08:35 +000097namespace {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000098/// ExprAST - Base class for all expression nodes.
99class ExprAST {
100public:
Juergen Ributzka05c5a932013-11-19 03:08:35 +0000101 virtual ~ExprAST() {}
Lang Hames2d789c32015-08-26 03:07:41 +0000102 virtual Value *codegen() = 0;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000103};
104
105/// NumberExprAST - Expression class for numeric literals like "1.0".
106class NumberExprAST : public ExprAST {
107 double Val;
Lang Hames59b0da82015-08-19 18:15:58 +0000108
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000109public:
Lang Hames09bf4c12015-08-18 18:11:06 +0000110 NumberExprAST(double Val) : Val(Val) {}
Lang Hames2d789c32015-08-26 03:07:41 +0000111 Value *codegen() override;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000112};
113
114/// VariableExprAST - Expression class for referencing a variable, like "a".
115class VariableExprAST : public ExprAST {
116 std::string Name;
Lang Hames59b0da82015-08-19 18:15:58 +0000117
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000118public:
Lang Hames09bf4c12015-08-18 18:11:06 +0000119 VariableExprAST(const std::string &Name) : Name(Name) {}
Lang Hames2d789c32015-08-26 03:07:41 +0000120 Value *codegen() override;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000121};
122
123/// BinaryExprAST - Expression class for a binary operator.
124class BinaryExprAST : public ExprAST {
125 char Op;
Lang Hames09bf4c12015-08-18 18:11:06 +0000126 std::unique_ptr<ExprAST> LHS, RHS;
Lang Hames59b0da82015-08-19 18:15:58 +0000127
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000128public:
Lang Hames09bf4c12015-08-18 18:11:06 +0000129 BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
130 std::unique_ptr<ExprAST> RHS)
Lang Hames59b0da82015-08-19 18:15:58 +0000131 : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Lang Hames2d789c32015-08-26 03:07:41 +0000132 Value *codegen() override;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000133};
134
135/// CallExprAST - Expression class for function calls.
136class CallExprAST : public ExprAST {
137 std::string Callee;
Lang Hames09bf4c12015-08-18 18:11:06 +0000138 std::vector<std::unique_ptr<ExprAST>> Args;
Lang Hames59b0da82015-08-19 18:15:58 +0000139
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000140public:
Lang Hames09bf4c12015-08-18 18:11:06 +0000141 CallExprAST(const std::string &Callee,
142 std::vector<std::unique_ptr<ExprAST>> Args)
Lang Hames59b0da82015-08-19 18:15:58 +0000143 : Callee(Callee), Args(std::move(Args)) {}
Lang Hames2d789c32015-08-26 03:07:41 +0000144 Value *codegen() override;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000145};
146
147/// PrototypeAST - This class represents the "prototype" for a function,
148/// which captures its name, and its argument names (thus implicitly the number
149/// of arguments the function takes).
150class PrototypeAST {
151 std::string Name;
152 std::vector<std::string> Args;
Lang Hames59b0da82015-08-19 18:15:58 +0000153
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000154public:
Lang Hames09bf4c12015-08-18 18:11:06 +0000155 PrototypeAST(const std::string &Name, std::vector<std::string> Args)
Lang Hames59b0da82015-08-19 18:15:58 +0000156 : Name(Name), Args(std::move(Args)) {}
Lang Hames2d789c32015-08-26 03:07:41 +0000157 Function *codegen();
158 const std::string &getName() const { return Name; }
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000159};
160
161/// FunctionAST - This class represents a function definition itself.
162class FunctionAST {
Lang Hames09bf4c12015-08-18 18:11:06 +0000163 std::unique_ptr<PrototypeAST> Proto;
164 std::unique_ptr<ExprAST> Body;
Lang Hames59b0da82015-08-19 18:15:58 +0000165
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000166public:
Lang Hames09bf4c12015-08-18 18:11:06 +0000167 FunctionAST(std::unique_ptr<PrototypeAST> Proto,
168 std::unique_ptr<ExprAST> Body)
Lang Hames59b0da82015-08-19 18:15:58 +0000169 : Proto(std::move(Proto)), Body(std::move(Body)) {}
Lang Hames2d789c32015-08-26 03:07:41 +0000170 Function *codegen();
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000171};
Juergen Ributzka05c5a932013-11-19 03:08:35 +0000172} // end anonymous namespace
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000173
174//===----------------------------------------------------------------------===//
175// Parser
176//===----------------------------------------------------------------------===//
177
178/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
179/// token the parser is looking at. getNextToken reads another token from the
180/// lexer and updates CurTok with its results.
181static int CurTok;
Lang Hames59b0da82015-08-19 18:15:58 +0000182static int getNextToken() { return CurTok = gettok(); }
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000183
184/// BinopPrecedence - This holds the precedence for each binary operator that is
185/// defined.
186static std::map<char, int> BinopPrecedence;
187
188/// GetTokPrecedence - Get the precedence of the pending binary operator token.
189static int GetTokPrecedence() {
190 if (!isascii(CurTok))
191 return -1;
Lang Hames59b0da82015-08-19 18:15:58 +0000192
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000193 // Make sure it's a declared binop.
194 int TokPrec = BinopPrecedence[CurTok];
Lang Hames59b0da82015-08-19 18:15:58 +0000195 if (TokPrec <= 0)
196 return -1;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000197 return TokPrec;
198}
199
Lang Hames5d045a92016-03-25 17:41:26 +0000200/// LogError* - These are little helper functions for error handling.
201std::unique_ptr<ExprAST> LogError(const char *Str) {
Lang Hames09bf4c12015-08-18 18:11:06 +0000202 fprintf(stderr, "Error: %s\n", Str);
203 return nullptr;
204}
Hans Wennborgcc9deb42015-09-29 18:02:48 +0000205
Lang Hames5d045a92016-03-25 17:41:26 +0000206std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
207 LogError(Str);
Lang Hames09bf4c12015-08-18 18:11:06 +0000208 return nullptr;
209}
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000210
Lang Hames09bf4c12015-08-18 18:11:06 +0000211static std::unique_ptr<ExprAST> ParseExpression();
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000212
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000213/// numberexpr ::= number
Lang Hames09bf4c12015-08-18 18:11:06 +0000214static std::unique_ptr<ExprAST> ParseNumberExpr() {
215 auto Result = llvm::make_unique<NumberExprAST>(NumVal);
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000216 getNextToken(); // consume the number
Lang Hames09bf4c12015-08-18 18:11:06 +0000217 return std::move(Result);
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000218}
219
220/// parenexpr ::= '(' expression ')'
Lang Hames09bf4c12015-08-18 18:11:06 +0000221static std::unique_ptr<ExprAST> ParseParenExpr() {
Lang Hames59b0da82015-08-19 18:15:58 +0000222 getNextToken(); // eat (.
Lang Hames09bf4c12015-08-18 18:11:06 +0000223 auto V = ParseExpression();
224 if (!V)
225 return nullptr;
Lang Hames59b0da82015-08-19 18:15:58 +0000226
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000227 if (CurTok != ')')
Lang Hames5d045a92016-03-25 17:41:26 +0000228 return LogError("expected ')'");
Lang Hames59b0da82015-08-19 18:15:58 +0000229 getNextToken(); // eat ).
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000230 return V;
231}
232
Lang Hames59b0da82015-08-19 18:15:58 +0000233/// identifierexpr
234/// ::= identifier
235/// ::= identifier '(' expression* ')'
236static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
237 std::string IdName = IdentifierStr;
238
239 getNextToken(); // eat identifier.
240
241 if (CurTok != '(') // Simple variable ref.
242 return llvm::make_unique<VariableExprAST>(IdName);
243
244 // Call.
245 getNextToken(); // eat (
246 std::vector<std::unique_ptr<ExprAST>> Args;
247 if (CurTok != ')') {
Eugene Zelenkof981ec42016-05-19 01:08:04 +0000248 while (true) {
Lang Hames59b0da82015-08-19 18:15:58 +0000249 if (auto Arg = ParseExpression())
250 Args.push_back(std::move(Arg));
251 else
252 return nullptr;
253
254 if (CurTok == ')')
255 break;
256
257 if (CurTok != ',')
Lang Hames5d045a92016-03-25 17:41:26 +0000258 return LogError("Expected ')' or ',' in argument list");
Lang Hames59b0da82015-08-19 18:15:58 +0000259 getNextToken();
260 }
261 }
262
263 // Eat the ')'.
264 getNextToken();
265
266 return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
267}
268
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000269/// primary
270/// ::= identifierexpr
271/// ::= numberexpr
272/// ::= parenexpr
Lang Hames09bf4c12015-08-18 18:11:06 +0000273static std::unique_ptr<ExprAST> ParsePrimary() {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000274 switch (CurTok) {
Lang Hames59b0da82015-08-19 18:15:58 +0000275 default:
Lang Hames5d045a92016-03-25 17:41:26 +0000276 return LogError("unknown token when expecting an expression");
Lang Hames59b0da82015-08-19 18:15:58 +0000277 case tok_identifier:
278 return ParseIdentifierExpr();
279 case tok_number:
280 return ParseNumberExpr();
281 case '(':
282 return ParseParenExpr();
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000283 }
284}
285
286/// binoprhs
287/// ::= ('+' primary)*
Lang Hames09bf4c12015-08-18 18:11:06 +0000288static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
289 std::unique_ptr<ExprAST> LHS) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000290 // If this is a binop, find its precedence.
Eugene Zelenkof981ec42016-05-19 01:08:04 +0000291 while (true) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000292 int TokPrec = GetTokPrecedence();
Lang Hames59b0da82015-08-19 18:15:58 +0000293
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000294 // If this is a binop that binds at least as tightly as the current binop,
295 // consume it, otherwise we are done.
296 if (TokPrec < ExprPrec)
297 return LHS;
Lang Hames59b0da82015-08-19 18:15:58 +0000298
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000299 // Okay, we know this is a binop.
300 int BinOp = CurTok;
Lang Hames59b0da82015-08-19 18:15:58 +0000301 getNextToken(); // eat binop
302
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000303 // Parse the primary expression after the binary operator.
Lang Hames09bf4c12015-08-18 18:11:06 +0000304 auto RHS = ParsePrimary();
Lang Hames59b0da82015-08-19 18:15:58 +0000305 if (!RHS)
306 return nullptr;
307
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000308 // If BinOp binds less tightly with RHS than the operator after RHS, let
309 // the pending operator take RHS as its LHS.
310 int NextPrec = GetTokPrecedence();
311 if (TokPrec < NextPrec) {
Lang Hames59b0da82015-08-19 18:15:58 +0000312 RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
313 if (!RHS)
314 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000315 }
Lang Hames59b0da82015-08-19 18:15:58 +0000316
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000317 // Merge LHS/RHS.
Lang Hames59b0da82015-08-19 18:15:58 +0000318 LHS =
319 llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000320 }
321}
322
323/// expression
324/// ::= primary binoprhs
325///
Lang Hames09bf4c12015-08-18 18:11:06 +0000326static std::unique_ptr<ExprAST> ParseExpression() {
327 auto LHS = ParsePrimary();
Lang Hames59b0da82015-08-19 18:15:58 +0000328 if (!LHS)
329 return nullptr;
330
Lang Hames09bf4c12015-08-18 18:11:06 +0000331 return ParseBinOpRHS(0, std::move(LHS));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000332}
333
334/// prototype
335/// ::= id '(' id* ')'
Lang Hames09bf4c12015-08-18 18:11:06 +0000336static std::unique_ptr<PrototypeAST> ParsePrototype() {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000337 if (CurTok != tok_identifier)
Lang Hames5d045a92016-03-25 17:41:26 +0000338 return LogErrorP("Expected function name in prototype");
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000339
340 std::string FnName = IdentifierStr;
341 getNextToken();
Lang Hames59b0da82015-08-19 18:15:58 +0000342
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000343 if (CurTok != '(')
Lang Hames5d045a92016-03-25 17:41:26 +0000344 return LogErrorP("Expected '(' in prototype");
Lang Hames59b0da82015-08-19 18:15:58 +0000345
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000346 std::vector<std::string> ArgNames;
347 while (getNextToken() == tok_identifier)
348 ArgNames.push_back(IdentifierStr);
349 if (CurTok != ')')
Lang Hames5d045a92016-03-25 17:41:26 +0000350 return LogErrorP("Expected ')' in prototype");
Lang Hames59b0da82015-08-19 18:15:58 +0000351
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000352 // success.
Lang Hames59b0da82015-08-19 18:15:58 +0000353 getNextToken(); // eat ')'.
354
355 return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000356}
357
358/// definition ::= 'def' prototype expression
Lang Hames09bf4c12015-08-18 18:11:06 +0000359static std::unique_ptr<FunctionAST> ParseDefinition() {
Lang Hames59b0da82015-08-19 18:15:58 +0000360 getNextToken(); // eat def.
Lang Hames09bf4c12015-08-18 18:11:06 +0000361 auto Proto = ParsePrototype();
Lang Hames59b0da82015-08-19 18:15:58 +0000362 if (!Proto)
363 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000364
Lang Hames09bf4c12015-08-18 18:11:06 +0000365 if (auto E = ParseExpression())
366 return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
367 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000368}
369
370/// toplevelexpr ::= expression
Lang Hames09bf4c12015-08-18 18:11:06 +0000371static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
372 if (auto E = ParseExpression()) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000373 // Make an anonymous proto.
Lang Hames2d789c32015-08-26 03:07:41 +0000374 auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr",
375 std::vector<std::string>());
Lang Hames09bf4c12015-08-18 18:11:06 +0000376 return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000377 }
Lang Hames09bf4c12015-08-18 18:11:06 +0000378 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000379}
380
381/// external ::= 'extern' prototype
Lang Hames09bf4c12015-08-18 18:11:06 +0000382static std::unique_ptr<PrototypeAST> ParseExtern() {
Lang Hames59b0da82015-08-19 18:15:58 +0000383 getNextToken(); // eat extern.
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000384 return ParsePrototype();
385}
386
387//===----------------------------------------------------------------------===//
388// Code Generation
389//===----------------------------------------------------------------------===//
390
Mehdi Amini03b42e42016-04-14 21:59:01 +0000391static LLVMContext TheContext;
392static IRBuilder<> Builder(TheContext);
Lang Hames24796802016-05-22 22:48:36 +0000393static std::unique_ptr<Module> TheModule;
Lang Hames2d789c32015-08-26 03:07:41 +0000394static std::map<std::string, Value *> NamedValues;
395
Lang Hames5d045a92016-03-25 17:41:26 +0000396Value *LogErrorV(const char *Str) {
397 LogError(Str);
Lang Hames59b0da82015-08-19 18:15:58 +0000398 return nullptr;
399}
400
Lang Hames2d789c32015-08-26 03:07:41 +0000401Value *NumberExprAST::codegen() {
Mehdi Amini03b42e42016-04-14 21:59:01 +0000402 return ConstantFP::get(TheContext, APFloat(Val));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000403}
404
Lang Hames2d789c32015-08-26 03:07:41 +0000405Value *VariableExprAST::codegen() {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000406 // Look this variable up in the function.
407 Value *V = NamedValues[Name];
Lang Hames596aec92015-08-19 18:32:58 +0000408 if (!V)
Lang Hames5d045a92016-03-25 17:41:26 +0000409 return LogErrorV("Unknown variable name");
Lang Hames596aec92015-08-19 18:32:58 +0000410 return V;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000411}
412
Lang Hames2d789c32015-08-26 03:07:41 +0000413Value *BinaryExprAST::codegen() {
414 Value *L = LHS->codegen();
415 Value *R = RHS->codegen();
Lang Hames59b0da82015-08-19 18:15:58 +0000416 if (!L || !R)
417 return nullptr;
418
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000419 switch (Op) {
Lang Hames59b0da82015-08-19 18:15:58 +0000420 case '+':
421 return Builder.CreateFAdd(L, R, "addtmp");
422 case '-':
423 return Builder.CreateFSub(L, R, "subtmp");
424 case '*':
425 return Builder.CreateFMul(L, R, "multmp");
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000426 case '<':
427 L = Builder.CreateFCmpULT(L, R, "cmptmp");
428 // Convert bool 0/1 to double 0.0 or 1.0
Mehdi Amini03b42e42016-04-14 21:59:01 +0000429 return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
Lang Hames59b0da82015-08-19 18:15:58 +0000430 default:
Lang Hames5d045a92016-03-25 17:41:26 +0000431 return LogErrorV("invalid binary operator");
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000432 }
433}
434
Lang Hames2d789c32015-08-26 03:07:41 +0000435Value *CallExprAST::codegen() {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000436 // Look up the name in the global module table.
437 Function *CalleeF = TheModule->getFunction(Callee);
Lang Hames09bf4c12015-08-18 18:11:06 +0000438 if (!CalleeF)
Lang Hames5d045a92016-03-25 17:41:26 +0000439 return LogErrorV("Unknown function referenced");
Lang Hames59b0da82015-08-19 18:15:58 +0000440
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000441 // If argument mismatch error.
442 if (CalleeF->arg_size() != Args.size())
Lang Hames5d045a92016-03-25 17:41:26 +0000443 return LogErrorV("Incorrect # arguments passed");
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000444
Lang Hames59b0da82015-08-19 18:15:58 +0000445 std::vector<Value *> ArgsV;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000446 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
Lang Hames2d789c32015-08-26 03:07:41 +0000447 ArgsV.push_back(Args[i]->codegen());
Lang Hames59b0da82015-08-19 18:15:58 +0000448 if (!ArgsV.back())
449 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000450 }
Lang Hames59b0da82015-08-19 18:15:58 +0000451
Francois Pichetc5d10502011-07-15 10:59:52 +0000452 return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000453}
454
Lang Hames2d789c32015-08-26 03:07:41 +0000455Function *PrototypeAST::codegen() {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000456 // Make the function type: double(double,double) etc.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000457 std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
Lang Hames59b0da82015-08-19 18:15:58 +0000458 FunctionType *FT =
Mehdi Amini03b42e42016-04-14 21:59:01 +0000459 FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
Lang Hames59b0da82015-08-19 18:15:58 +0000460
461 Function *F =
Lang Hames2d789c32015-08-26 03:07:41 +0000462 Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
Lang Hames59b0da82015-08-19 18:15:58 +0000463
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000464 // Set names for all arguments.
465 unsigned Idx = 0;
Lang Hames2d789c32015-08-26 03:07:41 +0000466 for (auto &Arg : F->args())
467 Arg.setName(Args[Idx++]);
Lang Hames59b0da82015-08-19 18:15:58 +0000468
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000469 return F;
470}
471
Lang Hames2d789c32015-08-26 03:07:41 +0000472Function *FunctionAST::codegen() {
473 // First, check for an existing function from a previous 'extern' declaration.
474 Function *TheFunction = TheModule->getFunction(Proto->getName());
Lang Hames59b0da82015-08-19 18:15:58 +0000475
Lang Hames2d789c32015-08-26 03:07:41 +0000476 if (!TheFunction)
477 TheFunction = Proto->codegen();
478
Lang Hames09bf4c12015-08-18 18:11:06 +0000479 if (!TheFunction)
480 return nullptr;
Lang Hames59b0da82015-08-19 18:15:58 +0000481
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000482 // Create a new basic block to start insertion into.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000483 BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000484 Builder.SetInsertPoint(BB);
Lang Hames59b0da82015-08-19 18:15:58 +0000485
Lang Hames2d789c32015-08-26 03:07:41 +0000486 // Record the function arguments in the NamedValues map.
487 NamedValues.clear();
488 for (auto &Arg : TheFunction->args())
489 NamedValues[Arg.getName()] = &Arg;
490
491 if (Value *RetVal = Body->codegen()) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000492 // Finish off the function.
493 Builder.CreateRet(RetVal);
494
495 // Validate the generated code, checking for consistency.
496 verifyFunction(*TheFunction);
497
498 return TheFunction;
499 }
Lang Hames59b0da82015-08-19 18:15:58 +0000500
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000501 // Error reading body, remove function.
502 TheFunction->eraseFromParent();
Lang Hames09bf4c12015-08-18 18:11:06 +0000503 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000504}
505
506//===----------------------------------------------------------------------===//
507// Top-Level parsing and JIT Driver
508//===----------------------------------------------------------------------===//
509
510static void HandleDefinition() {
Lang Hames09bf4c12015-08-18 18:11:06 +0000511 if (auto FnAST = ParseDefinition()) {
Lang Hames2d789c32015-08-26 03:07:41 +0000512 if (auto *FnIR = FnAST->codegen()) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000513 fprintf(stderr, "Read function definition:");
Lang Hames09bf4c12015-08-18 18:11:06 +0000514 FnIR->dump();
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000515 }
516 } else {
517 // Skip token for error recovery.
518 getNextToken();
519 }
520}
521
522static void HandleExtern() {
Lang Hames09bf4c12015-08-18 18:11:06 +0000523 if (auto ProtoAST = ParseExtern()) {
Lang Hames2d789c32015-08-26 03:07:41 +0000524 if (auto *FnIR = ProtoAST->codegen()) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000525 fprintf(stderr, "Read extern: ");
Lang Hames09bf4c12015-08-18 18:11:06 +0000526 FnIR->dump();
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000527 }
528 } else {
529 // Skip token for error recovery.
530 getNextToken();
531 }
532}
533
534static void HandleTopLevelExpression() {
535 // Evaluate a top-level expression into an anonymous function.
Lang Hames09bf4c12015-08-18 18:11:06 +0000536 if (auto FnAST = ParseTopLevelExpr()) {
Lang Hames2d789c32015-08-26 03:07:41 +0000537 if (auto *FnIR = FnAST->codegen()) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000538 fprintf(stderr, "Read top-level expression:");
Lang Hames09bf4c12015-08-18 18:11:06 +0000539 FnIR->dump();
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000540 }
541 } else {
542 // Skip token for error recovery.
543 getNextToken();
544 }
545}
546
547/// top ::= definition | external | expression | ';'
548static void MainLoop() {
Eugene Zelenkof981ec42016-05-19 01:08:04 +0000549 while (true) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000550 fprintf(stderr, "ready> ");
551 switch (CurTok) {
Lang Hames59b0da82015-08-19 18:15:58 +0000552 case tok_eof:
553 return;
554 case ';': // ignore top-level semicolons.
555 getNextToken();
556 break;
557 case tok_def:
558 HandleDefinition();
559 break;
560 case tok_extern:
561 HandleExtern();
562 break;
563 default:
564 HandleTopLevelExpression();
565 break;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000566 }
567 }
568}
569
570//===----------------------------------------------------------------------===//
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000571// Main driver code.
572//===----------------------------------------------------------------------===//
573
574int main() {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000575 // Install standard binary operators.
576 // 1 is lowest precedence.
577 BinopPrecedence['<'] = 10;
578 BinopPrecedence['+'] = 20;
579 BinopPrecedence['-'] = 20;
Lang Hames59b0da82015-08-19 18:15:58 +0000580 BinopPrecedence['*'] = 40; // highest.
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000581
582 // Prime the first token.
583 fprintf(stderr, "ready> ");
584 getNextToken();
585
586 // Make the module, which holds all the code.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000587 TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000588
589 // Run the main "interpreter loop" now.
590 MainLoop();
591
592 // Print out all of the generated code.
593 TheModule->dump();
594
595 return 0;
596}