xref: /llvm-project/llvm/examples/Kaleidoscope/Chapter4/toy.cpp (revision 81c0f3023fc38e3ea720045407a17f47653ea2ac)
1 #include "../include/KaleidoscopeJIT.h"
2 #include "llvm/ADT/APFloat.h"
3 #include "llvm/ADT/STLExtras.h"
4 #include "llvm/IR/BasicBlock.h"
5 #include "llvm/IR/Constants.h"
6 #include "llvm/IR/DerivedTypes.h"
7 #include "llvm/IR/Function.h"
8 #include "llvm/IR/IRBuilder.h"
9 #include "llvm/IR/LLVMContext.h"
10 #include "llvm/IR/Module.h"
11 #include "llvm/IR/PassManager.h"
12 #include "llvm/IR/Type.h"
13 #include "llvm/IR/Verifier.h"
14 #include "llvm/Passes/PassBuilder.h"
15 #include "llvm/Passes/StandardInstrumentations.h"
16 #include "llvm/Support/TargetSelect.h"
17 #include "llvm/Target/TargetMachine.h"
18 #include "llvm/Transforms/InstCombine/InstCombine.h"
19 #include "llvm/Transforms/Scalar.h"
20 #include "llvm/Transforms/Scalar/GVN.h"
21 #include "llvm/Transforms/Scalar/Reassociate.h"
22 #include "llvm/Transforms/Scalar/SimplifyCFG.h"
23 #include <algorithm>
24 #include <cassert>
25 #include <cctype>
26 #include <cstdint>
27 #include <cstdio>
28 #include <cstdlib>
29 #include <map>
30 #include <memory>
31 #include <string>
32 #include <vector>
33 
34 using namespace llvm;
35 using namespace llvm::orc;
36 
37 //===----------------------------------------------------------------------===//
38 // Lexer
39 //===----------------------------------------------------------------------===//
40 
41 // The lexer returns tokens [0-255] if it is an unknown character, otherwise one
42 // of these for known things.
43 enum Token {
44   tok_eof = -1,
45 
46   // commands
47   tok_def = -2,
48   tok_extern = -3,
49 
50   // primary
51   tok_identifier = -4,
52   tok_number = -5
53 };
54 
55 static std::string IdentifierStr; // Filled in if tok_identifier
56 static double NumVal;             // Filled in if tok_number
57 
58 /// gettok - Return the next token from standard input.
59 static int gettok() {
60   static int LastChar = ' ';
61 
62   // Skip any whitespace.
63   while (isspace(LastChar))
64     LastChar = getchar();
65 
66   if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
67     IdentifierStr = LastChar;
68     while (isalnum((LastChar = getchar())))
69       IdentifierStr += LastChar;
70 
71     if (IdentifierStr == "def")
72       return tok_def;
73     if (IdentifierStr == "extern")
74       return tok_extern;
75     return tok_identifier;
76   }
77 
78   if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
79     std::string NumStr;
80     do {
81       NumStr += LastChar;
82       LastChar = getchar();
83     } while (isdigit(LastChar) || LastChar == '.');
84 
85     NumVal = strtod(NumStr.c_str(), nullptr);
86     return tok_number;
87   }
88 
89   if (LastChar == '#') {
90     // Comment until end of line.
91     do
92       LastChar = getchar();
93     while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
94 
95     if (LastChar != EOF)
96       return gettok();
97   }
98 
99   // Check for end of file.  Don't eat the EOF.
100   if (LastChar == EOF)
101     return tok_eof;
102 
103   // Otherwise, just return the character as its ascii value.
104   int ThisChar = LastChar;
105   LastChar = getchar();
106   return ThisChar;
107 }
108 
109 //===----------------------------------------------------------------------===//
110 // Abstract Syntax Tree (aka Parse Tree)
111 //===----------------------------------------------------------------------===//
112 
113 namespace {
114 
115 /// ExprAST - Base class for all expression nodes.
116 class ExprAST {
117 public:
118   virtual ~ExprAST() = default;
119 
120   virtual Value *codegen() = 0;
121 };
122 
123 /// NumberExprAST - Expression class for numeric literals like "1.0".
124 class NumberExprAST : public ExprAST {
125   double Val;
126 
127 public:
128   NumberExprAST(double Val) : Val(Val) {}
129 
130   Value *codegen() override;
131 };
132 
133 /// VariableExprAST - Expression class for referencing a variable, like "a".
134 class VariableExprAST : public ExprAST {
135   std::string Name;
136 
137 public:
138   VariableExprAST(const std::string &Name) : Name(Name) {}
139 
140   Value *codegen() override;
141 };
142 
143 /// BinaryExprAST - Expression class for a binary operator.
144 class BinaryExprAST : public ExprAST {
145   char Op;
146   std::unique_ptr<ExprAST> LHS, RHS;
147 
148 public:
149   BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
150                 std::unique_ptr<ExprAST> RHS)
151       : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
152 
153   Value *codegen() override;
154 };
155 
156 /// CallExprAST - Expression class for function calls.
157 class CallExprAST : public ExprAST {
158   std::string Callee;
159   std::vector<std::unique_ptr<ExprAST>> Args;
160 
161 public:
162   CallExprAST(const std::string &Callee,
163               std::vector<std::unique_ptr<ExprAST>> Args)
164       : Callee(Callee), Args(std::move(Args)) {}
165 
166   Value *codegen() override;
167 };
168 
169 /// PrototypeAST - This class represents the "prototype" for a function,
170 /// which captures its name, and its argument names (thus implicitly the number
171 /// of arguments the function takes).
172 class PrototypeAST {
173   std::string Name;
174   std::vector<std::string> Args;
175 
176 public:
177   PrototypeAST(const std::string &Name, std::vector<std::string> Args)
178       : Name(Name), Args(std::move(Args)) {}
179 
180   Function *codegen();
181   const std::string &getName() const { return Name; }
182 };
183 
184 /// FunctionAST - This class represents a function definition itself.
185 class FunctionAST {
186   std::unique_ptr<PrototypeAST> Proto;
187   std::unique_ptr<ExprAST> Body;
188 
189 public:
190   FunctionAST(std::unique_ptr<PrototypeAST> Proto,
191               std::unique_ptr<ExprAST> Body)
192       : Proto(std::move(Proto)), Body(std::move(Body)) {}
193 
194   Function *codegen();
195 };
196 
197 } // end anonymous namespace
198 
199 //===----------------------------------------------------------------------===//
200 // Parser
201 //===----------------------------------------------------------------------===//
202 
203 /// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current
204 /// token the parser is looking at.  getNextToken reads another token from the
205 /// lexer and updates CurTok with its results.
206 static int CurTok;
207 static int getNextToken() { return CurTok = gettok(); }
208 
209 /// BinopPrecedence - This holds the precedence for each binary operator that is
210 /// defined.
211 static std::map<char, int> BinopPrecedence;
212 
213 /// GetTokPrecedence - Get the precedence of the pending binary operator token.
214 static int GetTokPrecedence() {
215   if (!isascii(CurTok))
216     return -1;
217 
218   // Make sure it's a declared binop.
219   int TokPrec = BinopPrecedence[CurTok];
220   if (TokPrec <= 0)
221     return -1;
222   return TokPrec;
223 }
224 
225 /// LogError* - These are little helper functions for error handling.
226 std::unique_ptr<ExprAST> LogError(const char *Str) {
227   fprintf(stderr, "Error: %s\n", Str);
228   return nullptr;
229 }
230 
231 std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
232   LogError(Str);
233   return nullptr;
234 }
235 
236 static std::unique_ptr<ExprAST> ParseExpression();
237 
238 /// numberexpr ::= number
239 static std::unique_ptr<ExprAST> ParseNumberExpr() {
240   auto Result = std::make_unique<NumberExprAST>(NumVal);
241   getNextToken(); // consume the number
242   return std::move(Result);
243 }
244 
245 /// parenexpr ::= '(' expression ')'
246 static std::unique_ptr<ExprAST> ParseParenExpr() {
247   getNextToken(); // eat (.
248   auto V = ParseExpression();
249   if (!V)
250     return nullptr;
251 
252   if (CurTok != ')')
253     return LogError("expected ')'");
254   getNextToken(); // eat ).
255   return V;
256 }
257 
258 /// identifierexpr
259 ///   ::= identifier
260 ///   ::= identifier '(' expression* ')'
261 static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
262   std::string IdName = IdentifierStr;
263 
264   getNextToken(); // eat identifier.
265 
266   if (CurTok != '(') // Simple variable ref.
267     return std::make_unique<VariableExprAST>(IdName);
268 
269   // Call.
270   getNextToken(); // eat (
271   std::vector<std::unique_ptr<ExprAST>> Args;
272   if (CurTok != ')') {
273     while (true) {
274       if (auto Arg = ParseExpression())
275         Args.push_back(std::move(Arg));
276       else
277         return nullptr;
278 
279       if (CurTok == ')')
280         break;
281 
282       if (CurTok != ',')
283         return LogError("Expected ')' or ',' in argument list");
284       getNextToken();
285     }
286   }
287 
288   // Eat the ')'.
289   getNextToken();
290 
291   return std::make_unique<CallExprAST>(IdName, std::move(Args));
292 }
293 
294 /// primary
295 ///   ::= identifierexpr
296 ///   ::= numberexpr
297 ///   ::= parenexpr
298 static std::unique_ptr<ExprAST> ParsePrimary() {
299   switch (CurTok) {
300   default:
301     return LogError("unknown token when expecting an expression");
302   case tok_identifier:
303     return ParseIdentifierExpr();
304   case tok_number:
305     return ParseNumberExpr();
306   case '(':
307     return ParseParenExpr();
308   }
309 }
310 
311 /// binoprhs
312 ///   ::= ('+' primary)*
313 static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
314                                               std::unique_ptr<ExprAST> LHS) {
315   // If this is a binop, find its precedence.
316   while (true) {
317     int TokPrec = GetTokPrecedence();
318 
319     // If this is a binop that binds at least as tightly as the current binop,
320     // consume it, otherwise we are done.
321     if (TokPrec < ExprPrec)
322       return LHS;
323 
324     // Okay, we know this is a binop.
325     int BinOp = CurTok;
326     getNextToken(); // eat binop
327 
328     // Parse the primary expression after the binary operator.
329     auto RHS = ParsePrimary();
330     if (!RHS)
331       return nullptr;
332 
333     // If BinOp binds less tightly with RHS than the operator after RHS, let
334     // the pending operator take RHS as its LHS.
335     int NextPrec = GetTokPrecedence();
336     if (TokPrec < NextPrec) {
337       RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
338       if (!RHS)
339         return nullptr;
340     }
341 
342     // Merge LHS/RHS.
343     LHS =
344         std::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
345   }
346 }
347 
348 /// expression
349 ///   ::= primary binoprhs
350 ///
351 static std::unique_ptr<ExprAST> ParseExpression() {
352   auto LHS = ParsePrimary();
353   if (!LHS)
354     return nullptr;
355 
356   return ParseBinOpRHS(0, std::move(LHS));
357 }
358 
359 /// prototype
360 ///   ::= id '(' id* ')'
361 static std::unique_ptr<PrototypeAST> ParsePrototype() {
362   if (CurTok != tok_identifier)
363     return LogErrorP("Expected function name in prototype");
364 
365   std::string FnName = IdentifierStr;
366   getNextToken();
367 
368   if (CurTok != '(')
369     return LogErrorP("Expected '(' in prototype");
370 
371   std::vector<std::string> ArgNames;
372   while (getNextToken() == tok_identifier)
373     ArgNames.push_back(IdentifierStr);
374   if (CurTok != ')')
375     return LogErrorP("Expected ')' in prototype");
376 
377   // success.
378   getNextToken(); // eat ')'.
379 
380   return std::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
381 }
382 
383 /// definition ::= 'def' prototype expression
384 static std::unique_ptr<FunctionAST> ParseDefinition() {
385   getNextToken(); // eat def.
386   auto Proto = ParsePrototype();
387   if (!Proto)
388     return nullptr;
389 
390   if (auto E = ParseExpression())
391     return std::make_unique<FunctionAST>(std::move(Proto), std::move(E));
392   return nullptr;
393 }
394 
395 /// toplevelexpr ::= expression
396 static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
397   if (auto E = ParseExpression()) {
398     // Make an anonymous proto.
399     auto Proto = std::make_unique<PrototypeAST>("__anon_expr",
400                                                  std::vector<std::string>());
401     return std::make_unique<FunctionAST>(std::move(Proto), std::move(E));
402   }
403   return nullptr;
404 }
405 
406 /// external ::= 'extern' prototype
407 static std::unique_ptr<PrototypeAST> ParseExtern() {
408   getNextToken(); // eat extern.
409   return ParsePrototype();
410 }
411 
412 //===----------------------------------------------------------------------===//
413 // Code Generation
414 //===----------------------------------------------------------------------===//
415 
416 static std::unique_ptr<LLVMContext> TheContext;
417 static std::unique_ptr<Module> TheModule;
418 static std::unique_ptr<IRBuilder<>> Builder;
419 static std::map<std::string, Value *> NamedValues;
420 static std::unique_ptr<KaleidoscopeJIT> TheJIT;
421 static std::unique_ptr<FunctionPassManager> TheFPM;
422 static std::unique_ptr<LoopAnalysisManager> TheLAM;
423 static std::unique_ptr<FunctionAnalysisManager> TheFAM;
424 static std::unique_ptr<CGSCCAnalysisManager> TheCGAM;
425 static std::unique_ptr<ModuleAnalysisManager> TheMAM;
426 static std::unique_ptr<PassInstrumentationCallbacks> ThePIC;
427 static std::unique_ptr<StandardInstrumentations> TheSI;
428 static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
429 static ExitOnError ExitOnErr;
430 
431 Value *LogErrorV(const char *Str) {
432   LogError(Str);
433   return nullptr;
434 }
435 
436 Function *getFunction(std::string Name) {
437   // First, see if the function has already been added to the current module.
438   if (auto *F = TheModule->getFunction(Name))
439     return F;
440 
441   // If not, check whether we can codegen the declaration from some existing
442   // prototype.
443   auto FI = FunctionProtos.find(Name);
444   if (FI != FunctionProtos.end())
445     return FI->second->codegen();
446 
447   // If no existing prototype exists, return null.
448   return nullptr;
449 }
450 
451 Value *NumberExprAST::codegen() {
452   return ConstantFP::get(*TheContext, APFloat(Val));
453 }
454 
455 Value *VariableExprAST::codegen() {
456   // Look this variable up in the function.
457   Value *V = NamedValues[Name];
458   if (!V)
459     return LogErrorV("Unknown variable name");
460   return V;
461 }
462 
463 Value *BinaryExprAST::codegen() {
464   Value *L = LHS->codegen();
465   Value *R = RHS->codegen();
466   if (!L || !R)
467     return nullptr;
468 
469   switch (Op) {
470   case '+':
471     return Builder->CreateFAdd(L, R, "addtmp");
472   case '-':
473     return Builder->CreateFSub(L, R, "subtmp");
474   case '*':
475     return Builder->CreateFMul(L, R, "multmp");
476   case '<':
477     L = Builder->CreateFCmpULT(L, R, "cmptmp");
478     // Convert bool 0/1 to double 0.0 or 1.0
479     return Builder->CreateUIToFP(L, Type::getDoubleTy(*TheContext), "booltmp");
480   default:
481     return LogErrorV("invalid binary operator");
482   }
483 }
484 
485 Value *CallExprAST::codegen() {
486   // Look up the name in the global module table.
487   Function *CalleeF = getFunction(Callee);
488   if (!CalleeF)
489     return LogErrorV("Unknown function referenced");
490 
491   // If argument mismatch error.
492   if (CalleeF->arg_size() != Args.size())
493     return LogErrorV("Incorrect # arguments passed");
494 
495   std::vector<Value *> ArgsV;
496   for (unsigned i = 0, e = Args.size(); i != e; ++i) {
497     ArgsV.push_back(Args[i]->codegen());
498     if (!ArgsV.back())
499       return nullptr;
500   }
501 
502   return Builder->CreateCall(CalleeF, ArgsV, "calltmp");
503 }
504 
505 Function *PrototypeAST::codegen() {
506   // Make the function type:  double(double,double) etc.
507   std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(*TheContext));
508   FunctionType *FT =
509       FunctionType::get(Type::getDoubleTy(*TheContext), Doubles, false);
510 
511   Function *F =
512       Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
513 
514   // Set names for all arguments.
515   unsigned Idx = 0;
516   for (auto &Arg : F->args())
517     Arg.setName(Args[Idx++]);
518 
519   return F;
520 }
521 
522 Function *FunctionAST::codegen() {
523   // Transfer ownership of the prototype to the FunctionProtos map, but keep a
524   // reference to it for use below.
525   auto &P = *Proto;
526   FunctionProtos[Proto->getName()] = std::move(Proto);
527   Function *TheFunction = getFunction(P.getName());
528   if (!TheFunction)
529     return nullptr;
530 
531   // Create a new basic block to start insertion into.
532   BasicBlock *BB = BasicBlock::Create(*TheContext, "entry", TheFunction);
533   Builder->SetInsertPoint(BB);
534 
535   // Record the function arguments in the NamedValues map.
536   NamedValues.clear();
537   for (auto &Arg : TheFunction->args())
538     NamedValues[std::string(Arg.getName())] = &Arg;
539 
540   if (Value *RetVal = Body->codegen()) {
541     // Finish off the function.
542     Builder->CreateRet(RetVal);
543 
544     // Validate the generated code, checking for consistency.
545     verifyFunction(*TheFunction);
546 
547     // Run the optimizer on the function.
548     TheFPM->run(*TheFunction, *TheFAM);
549 
550     return TheFunction;
551   }
552 
553   // Error reading body, remove function.
554   TheFunction->eraseFromParent();
555   return nullptr;
556 }
557 
558 //===----------------------------------------------------------------------===//
559 // Top-Level parsing and JIT Driver
560 //===----------------------------------------------------------------------===//
561 
562 static void InitializeModuleAndManagers() {
563   // Open a new context and module.
564   TheContext = std::make_unique<LLVMContext>();
565   TheModule = std::make_unique<Module>("KaleidoscopeJIT", *TheContext);
566   TheModule->setDataLayout(TheJIT->getDataLayout());
567 
568   // Create a new builder for the module.
569   Builder = std::make_unique<IRBuilder<>>(*TheContext);
570 
571   // Create new pass and analysis managers.
572   TheFPM = std::make_unique<FunctionPassManager>();
573   TheLAM = std::make_unique<LoopAnalysisManager>();
574   TheFAM = std::make_unique<FunctionAnalysisManager>();
575   TheCGAM = std::make_unique<CGSCCAnalysisManager>();
576   TheMAM = std::make_unique<ModuleAnalysisManager>();
577   ThePIC = std::make_unique<PassInstrumentationCallbacks>();
578   TheSI = std::make_unique<StandardInstrumentations>(*TheContext,
579                                                      /*DebugLogging*/ true);
580   TheSI->registerCallbacks(*ThePIC, TheMAM.get());
581 
582   // Add transform passes.
583   // Do simple "peephole" optimizations and bit-twiddling optzns.
584   TheFPM->addPass(InstCombinePass());
585   // Reassociate expressions.
586   TheFPM->addPass(ReassociatePass());
587   // Eliminate Common SubExpressions.
588   TheFPM->addPass(GVNPass());
589   // Simplify the control flow graph (deleting unreachable blocks, etc).
590   TheFPM->addPass(SimplifyCFGPass());
591 
592   // Register analysis passes used in these transform passes.
593   PassBuilder PB;
594   PB.registerModuleAnalyses(*TheMAM);
595   PB.registerFunctionAnalyses(*TheFAM);
596   PB.crossRegisterProxies(*TheLAM, *TheFAM, *TheCGAM, *TheMAM);
597 }
598 
599 static void HandleDefinition() {
600   if (auto FnAST = ParseDefinition()) {
601     if (auto *FnIR = FnAST->codegen()) {
602       fprintf(stderr, "Read function definition:");
603       FnIR->print(errs());
604       fprintf(stderr, "\n");
605       ExitOnErr(TheJIT->addModule(
606           ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
607       InitializeModuleAndManagers();
608     }
609   } else {
610     // Skip token for error recovery.
611     getNextToken();
612   }
613 }
614 
615 static void HandleExtern() {
616   if (auto ProtoAST = ParseExtern()) {
617     if (auto *FnIR = ProtoAST->codegen()) {
618       fprintf(stderr, "Read extern: ");
619       FnIR->print(errs());
620       fprintf(stderr, "\n");
621       FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST);
622     }
623   } else {
624     // Skip token for error recovery.
625     getNextToken();
626   }
627 }
628 
629 static void HandleTopLevelExpression() {
630   // Evaluate a top-level expression into an anonymous function.
631   if (auto FnAST = ParseTopLevelExpr()) {
632     if (FnAST->codegen()) {
633       // Create a ResourceTracker to track JIT'd memory allocated to our
634       // anonymous expression -- that way we can free it after executing.
635       auto RT = TheJIT->getMainJITDylib().createResourceTracker();
636 
637       auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
638       ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
639       InitializeModuleAndManagers();
640 
641       // Search the JIT for the __anon_expr symbol.
642       auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
643 
644       // Get the symbol's address and cast it to the right type (takes no
645       // arguments, returns a double) so we can call it as a native function.
646       double (*FP)() = ExprSymbol.toPtr<double (*)()>();
647       fprintf(stderr, "Evaluated to %f\n", FP());
648 
649       // Delete the anonymous expression module from the JIT.
650       ExitOnErr(RT->remove());
651     }
652   } else {
653     // Skip token for error recovery.
654     getNextToken();
655   }
656 }
657 
658 /// top ::= definition | external | expression | ';'
659 static void MainLoop() {
660   while (true) {
661     fprintf(stderr, "ready> ");
662     switch (CurTok) {
663     case tok_eof:
664       return;
665     case ';': // ignore top-level semicolons.
666       getNextToken();
667       break;
668     case tok_def:
669       HandleDefinition();
670       break;
671     case tok_extern:
672       HandleExtern();
673       break;
674     default:
675       HandleTopLevelExpression();
676       break;
677     }
678   }
679 }
680 
681 //===----------------------------------------------------------------------===//
682 // "Library" functions that can be "extern'd" from user code.
683 //===----------------------------------------------------------------------===//
684 
685 #ifdef _WIN32
686 #define DLLEXPORT __declspec(dllexport)
687 #else
688 #define DLLEXPORT
689 #endif
690 
691 /// putchard - putchar that takes a double and returns 0.
692 extern "C" DLLEXPORT double putchard(double X) {
693   fputc((char)X, stderr);
694   return 0;
695 }
696 
697 /// printd - printf that takes a double prints it as "%f\n", returning 0.
698 extern "C" DLLEXPORT double printd(double X) {
699   fprintf(stderr, "%f\n", X);
700   return 0;
701 }
702 
703 //===----------------------------------------------------------------------===//
704 // Main driver code.
705 //===----------------------------------------------------------------------===//
706 
707 int main() {
708   InitializeNativeTarget();
709   InitializeNativeTargetAsmPrinter();
710   InitializeNativeTargetAsmParser();
711 
712   // Install standard binary operators.
713   // 1 is lowest precedence.
714   BinopPrecedence['<'] = 10;
715   BinopPrecedence['+'] = 20;
716   BinopPrecedence['-'] = 20;
717   BinopPrecedence['*'] = 40; // highest.
718 
719   // Prime the first token.
720   fprintf(stderr, "ready> ");
721   getNextToken();
722 
723   TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
724 
725   InitializeModuleAndManagers();
726 
727   // Run the main "interpreter loop" now.
728   MainLoop();
729 
730   return 0;
731 }
732