1#include "llvm/Analysis/Passes.h" 2#include "llvm/ExecutionEngine/ExecutionEngine.h" 3#include "llvm/ExecutionEngine/MCJIT.h" 4#include "llvm/ExecutionEngine/SectionMemoryManager.h" 5#include "llvm/IR/DataLayout.h" 6#include "llvm/IR/DerivedTypes.h" 7#include "llvm/IR/IRBuilder.h" 8#include "llvm/IR/LLVMContext.h" 9#include "llvm/IR/LegacyPassManager.h" 10#include "llvm/IR/Module.h" 11#include "llvm/IR/Verifier.h" 12#include "llvm/Support/TargetSelect.h" 13#include "llvm/Transforms/Scalar.h" 14#include <cctype> 15#include <cstdio> 16#include <map> 17#include <string> 18#include <vector> 19using namespace llvm; 20 21//===----------------------------------------------------------------------===// 22// Lexer 23//===----------------------------------------------------------------------===// 24 25// The lexer returns tokens [0-255] if it is an unknown character, otherwise one 26// of these for known things. 27enum Token { 28 tok_eof = -1, 29 30 // commands 31 tok_def = -2, 32 tok_extern = -3, 33 34 // primary 35 tok_identifier = -4, 36 tok_number = -5 37}; 38 39static std::string IdentifierStr; // Filled in if tok_identifier 40static double NumVal; // Filled in if tok_number 41 42/// gettok - Return the next token from standard input. 43static int gettok() { 44 static int LastChar = ' '; 45 46 // Skip any whitespace. 47 while (isspace(LastChar)) 48 LastChar = getchar(); 49 50 if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]* 51 IdentifierStr = LastChar; 52 while (isalnum((LastChar = getchar()))) 53 IdentifierStr += LastChar; 54 55 if (IdentifierStr == "def") 56 return tok_def; 57 if (IdentifierStr == "extern") 58 return tok_extern; 59 return tok_identifier; 60 } 61 62 if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ 63 std::string NumStr; 64 do { 65 NumStr += LastChar; 66 LastChar = getchar(); 67 } while (isdigit(LastChar) || LastChar == '.'); 68 69 NumVal = strtod(NumStr.c_str(), 0); 70 return tok_number; 71 } 72 73 if (LastChar == '#') { 74 // Comment until end of line. 75 do 76 LastChar = getchar(); 77 while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); 78 79 if (LastChar != EOF) 80 return gettok(); 81 } 82 83 // Check for end of file. Don't eat the EOF. 84 if (LastChar == EOF) 85 return tok_eof; 86 87 // Otherwise, just return the character as its ascii value. 88 int ThisChar = LastChar; 89 LastChar = getchar(); 90 return ThisChar; 91} 92 93//===----------------------------------------------------------------------===// 94// Abstract Syntax Tree (aka Parse Tree) 95//===----------------------------------------------------------------------===// 96namespace { 97/// ExprAST - Base class for all expression nodes. 98class ExprAST { 99public: 100 virtual ~ExprAST() {} 101 virtual Value *Codegen() = 0; 102}; 103 104/// NumberExprAST - Expression class for numeric literals like "1.0". 105class NumberExprAST : public ExprAST { 106 double Val; 107 108public: 109 NumberExprAST(double val) : Val(val) {} 110 Value *Codegen() override; 111}; 112 113/// VariableExprAST - Expression class for referencing a variable, like "a". 114class VariableExprAST : public ExprAST { 115 std::string Name; 116 117public: 118 VariableExprAST(const std::string &name) : Name(name) {} 119 Value *Codegen() override; 120}; 121 122/// BinaryExprAST - Expression class for a binary operator. 123class BinaryExprAST : public ExprAST { 124 char Op; 125 ExprAST *LHS, *RHS; 126 127public: 128 BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) 129 : Op(op), LHS(lhs), RHS(rhs) {} 130 Value *Codegen() override; 131}; 132 133/// CallExprAST - Expression class for function calls. 134class CallExprAST : public ExprAST { 135 std::string Callee; 136 std::vector<ExprAST *> Args; 137 138public: 139 CallExprAST(const std::string &callee, std::vector<ExprAST *> &args) 140 : Callee(callee), Args(args) {} 141 Value *Codegen() override; 142}; 143 144/// PrototypeAST - This class represents the "prototype" for a function, 145/// which captures its name, and its argument names (thus implicitly the number 146/// of arguments the function takes). 147class PrototypeAST { 148 std::string Name; 149 std::vector<std::string> Args; 150 151public: 152 PrototypeAST(const std::string &name, const std::vector<std::string> &args) 153 : Name(name), Args(args) {} 154 155 Function *Codegen(); 156}; 157 158/// FunctionAST - This class represents a function definition itself. 159class FunctionAST { 160 PrototypeAST *Proto; 161 ExprAST *Body; 162 163public: 164 FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {} 165 166 Function *Codegen(); 167}; 168} // end anonymous namespace 169 170//===----------------------------------------------------------------------===// 171// Parser 172//===----------------------------------------------------------------------===// 173 174/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current 175/// token the parser is looking at. getNextToken reads another token from the 176/// lexer and updates CurTok with its results. 177static int CurTok; 178static int getNextToken() { return CurTok = gettok(); } 179 180/// BinopPrecedence - This holds the precedence for each binary operator that is 181/// defined. 182static std::map<char, int> BinopPrecedence; 183 184/// GetTokPrecedence - Get the precedence of the pending binary operator token. 185static int GetTokPrecedence() { 186 if (!isascii(CurTok)) 187 return -1; 188 189 // Make sure it's a declared binop. 190 int TokPrec = BinopPrecedence[CurTok]; 191 if (TokPrec <= 0) 192 return -1; 193 return TokPrec; 194} 195 196/// Error* - These are little helper functions for error handling. 197ExprAST *Error(const char *Str) { 198 fprintf(stderr, "Error: %s\n", Str); 199 return 0; 200} 201PrototypeAST *ErrorP(const char *Str) { 202 Error(Str); 203 return 0; 204} 205FunctionAST *ErrorF(const char *Str) { 206 Error(Str); 207 return 0; 208} 209 210static ExprAST *ParseExpression(); 211 212/// identifierexpr 213/// ::= identifier 214/// ::= identifier '(' expression* ')' 215static ExprAST *ParseIdentifierExpr() { 216 std::string IdName = IdentifierStr; 217 218 getNextToken(); // eat identifier. 219 220 if (CurTok != '(') // Simple variable ref. 221 return new VariableExprAST(IdName); 222 223 // Call. 224 getNextToken(); // eat ( 225 std::vector<ExprAST *> Args; 226 if (CurTok != ')') { 227 while (1) { 228 ExprAST *Arg = ParseExpression(); 229 if (!Arg) 230 return 0; 231 Args.push_back(Arg); 232 233 if (CurTok == ')') 234 break; 235 236 if (CurTok != ',') 237 return Error("Expected ')' or ',' in argument list"); 238 getNextToken(); 239 } 240 } 241 242 // Eat the ')'. 243 getNextToken(); 244 245 return new CallExprAST(IdName, Args); 246} 247 248/// numberexpr ::= number 249static ExprAST *ParseNumberExpr() { 250 ExprAST *Result = new NumberExprAST(NumVal); 251 getNextToken(); // consume the number 252 return Result; 253} 254 255/// parenexpr ::= '(' expression ')' 256static ExprAST *ParseParenExpr() { 257 getNextToken(); // eat (. 258 ExprAST *V = ParseExpression(); 259 if (!V) 260 return 0; 261 262 if (CurTok != ')') 263 return Error("expected ')'"); 264 getNextToken(); // eat ). 265 return V; 266} 267 268/// primary 269/// ::= identifierexpr 270/// ::= numberexpr 271/// ::= parenexpr 272static ExprAST *ParsePrimary() { 273 switch (CurTok) { 274 default: 275 return Error("unknown token when expecting an expression"); 276 case tok_identifier: 277 return ParseIdentifierExpr(); 278 case tok_number: 279 return ParseNumberExpr(); 280 case '(': 281 return ParseParenExpr(); 282 } 283} 284 285/// binoprhs 286/// ::= ('+' primary)* 287static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { 288 // If this is a binop, find its precedence. 289 while (1) { 290 int TokPrec = GetTokPrecedence(); 291 292 // If this is a binop that binds at least as tightly as the current binop, 293 // consume it, otherwise we are done. 294 if (TokPrec < ExprPrec) 295 return LHS; 296 297 // Okay, we know this is a binop. 298 int BinOp = CurTok; 299 getNextToken(); // eat binop 300 301 // Parse the primary expression after the binary operator. 302 ExprAST *RHS = ParsePrimary(); 303 if (!RHS) 304 return 0; 305 306 // If BinOp binds less tightly with RHS than the operator after RHS, let 307 // the pending operator take RHS as its LHS. 308 int NextPrec = GetTokPrecedence(); 309 if (TokPrec < NextPrec) { 310 RHS = ParseBinOpRHS(TokPrec + 1, RHS); 311 if (RHS == 0) 312 return 0; 313 } 314 315 // Merge LHS/RHS. 316 LHS = new BinaryExprAST(BinOp, LHS, RHS); 317 } 318} 319 320/// expression 321/// ::= primary binoprhs 322/// 323static ExprAST *ParseExpression() { 324 ExprAST *LHS = ParsePrimary(); 325 if (!LHS) 326 return 0; 327 328 return ParseBinOpRHS(0, LHS); 329} 330 331/// prototype 332/// ::= id '(' id* ')' 333static PrototypeAST *ParsePrototype() { 334 if (CurTok != tok_identifier) 335 return ErrorP("Expected function name in prototype"); 336 337 std::string FnName = IdentifierStr; 338 getNextToken(); 339 340 if (CurTok != '(') 341 return ErrorP("Expected '(' in prototype"); 342 343 std::vector<std::string> ArgNames; 344 while (getNextToken() == tok_identifier) 345 ArgNames.push_back(IdentifierStr); 346 if (CurTok != ')') 347 return ErrorP("Expected ')' in prototype"); 348 349 // success. 350 getNextToken(); // eat ')'. 351 352 return new PrototypeAST(FnName, ArgNames); 353} 354 355/// definition ::= 'def' prototype expression 356static FunctionAST *ParseDefinition() { 357 getNextToken(); // eat def. 358 PrototypeAST *Proto = ParsePrototype(); 359 if (Proto == 0) 360 return 0; 361 362 if (ExprAST *E = ParseExpression()) 363 return new FunctionAST(Proto, E); 364 return 0; 365} 366 367/// toplevelexpr ::= expression 368static FunctionAST *ParseTopLevelExpr() { 369 if (ExprAST *E = ParseExpression()) { 370 // Make an anonymous proto. 371 PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); 372 return new FunctionAST(Proto, E); 373 } 374 return 0; 375} 376 377/// external ::= 'extern' prototype 378static PrototypeAST *ParseExtern() { 379 getNextToken(); // eat extern. 380 return ParsePrototype(); 381} 382 383//===----------------------------------------------------------------------===// 384// Quick and dirty hack 385//===----------------------------------------------------------------------===// 386 387// FIXME: Obviously we can do better than this 388std::string GenerateUniqueName(const char *root) { 389 static int i = 0; 390 char s[16]; 391 sprintf(s, "%s%d", root, i++); 392 std::string S = s; 393 return S; 394} 395 396std::string MakeLegalFunctionName(std::string Name) { 397 std::string NewName; 398 if (!Name.length()) 399 return GenerateUniqueName("anon_func_"); 400 401 // Start with what we have 402 NewName = Name; 403 404 // Look for a numberic first character 405 if (NewName.find_first_of("0123456789") == 0) { 406 NewName.insert(0, 1, 'n'); 407 } 408 409 // Replace illegal characters with their ASCII equivalent 410 std::string legal_elements = 411 "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 412 size_t pos; 413 while ((pos = NewName.find_first_not_of(legal_elements)) != 414 std::string::npos) { 415 char old_c = NewName.at(pos); 416 char new_str[16]; 417 sprintf(new_str, "%d", (int)old_c); 418 NewName = NewName.replace(pos, 1, new_str); 419 } 420 421 return NewName; 422} 423 424//===----------------------------------------------------------------------===// 425// MCJIT helper class 426//===----------------------------------------------------------------------===// 427 428class MCJITHelper { 429public: 430 MCJITHelper(LLVMContext &C) : Context(C), OpenModule(NULL) {} 431 ~MCJITHelper(); 432 433 Function *getFunction(const std::string FnName); 434 Module *getModuleForNewFunction(); 435 void *getPointerToFunction(Function *F); 436 void *getSymbolAddress(const std::string &Name); 437 void dump(); 438 439private: 440 typedef std::vector<Module *> ModuleVector; 441 typedef std::vector<ExecutionEngine *> EngineVector; 442 443 LLVMContext &Context; 444 Module *OpenModule; 445 ModuleVector Modules; 446 EngineVector Engines; 447}; 448 449class HelpingMemoryManager : public SectionMemoryManager { 450 HelpingMemoryManager(const HelpingMemoryManager &) = delete; 451 void operator=(const HelpingMemoryManager &) = delete; 452 453public: 454 HelpingMemoryManager(MCJITHelper *Helper) : MasterHelper(Helper) {} 455 ~HelpingMemoryManager() override {} 456 457 /// This method returns the address of the specified symbol. 458 /// Our implementation will attempt to find symbols in other 459 /// modules associated with the MCJITHelper to cross link symbols 460 /// from one generated module to another. 461 uint64_t getSymbolAddress(const std::string &Name) override; 462 463private: 464 MCJITHelper *MasterHelper; 465}; 466 467uint64_t HelpingMemoryManager::getSymbolAddress(const std::string &Name) { 468 uint64_t FnAddr = SectionMemoryManager::getSymbolAddress(Name); 469 if (FnAddr) 470 return FnAddr; 471 472 uint64_t HelperFun = (uint64_t)MasterHelper->getSymbolAddress(Name); 473 if (!HelperFun) 474 report_fatal_error("Program used extern function '" + Name + 475 "' which could not be resolved!"); 476 477 return HelperFun; 478} 479 480MCJITHelper::~MCJITHelper() { 481 if (OpenModule) 482 delete OpenModule; 483 EngineVector::iterator begin = Engines.begin(); 484 EngineVector::iterator end = Engines.end(); 485 EngineVector::iterator it; 486 for (it = begin; it != end; ++it) 487 delete *it; 488} 489 490Function *MCJITHelper::getFunction(const std::string FnName) { 491 ModuleVector::iterator begin = Modules.begin(); 492 ModuleVector::iterator end = Modules.end(); 493 ModuleVector::iterator it; 494 for (it = begin; it != end; ++it) { 495 Function *F = (*it)->getFunction(FnName); 496 if (F) { 497 if (*it == OpenModule) 498 return F; 499 500 assert(OpenModule != NULL); 501 502 // This function is in a module that has already been JITed. 503 // We need to generate a new prototype for external linkage. 504 Function *PF = OpenModule->getFunction(FnName); 505 if (PF && !PF->empty()) { 506 ErrorF("redefinition of function across modules"); 507 return 0; 508 } 509 510 // If we don't have a prototype yet, create one. 511 if (!PF) 512 PF = Function::Create(F->getFunctionType(), Function::ExternalLinkage, 513 FnName, OpenModule); 514 return PF; 515 } 516 } 517 return NULL; 518} 519 520Module *MCJITHelper::getModuleForNewFunction() { 521 // If we have a Module that hasn't been JITed, use that. 522 if (OpenModule) 523 return OpenModule; 524 525 // Otherwise create a new Module. 526 std::string ModName = GenerateUniqueName("mcjit_module_"); 527 Module *M = new Module(ModName, Context); 528 Modules.push_back(M); 529 OpenModule = M; 530 return M; 531} 532 533void *MCJITHelper::getPointerToFunction(Function *F) { 534 // See if an existing instance of MCJIT has this function. 535 EngineVector::iterator begin = Engines.begin(); 536 EngineVector::iterator end = Engines.end(); 537 EngineVector::iterator it; 538 for (it = begin; it != end; ++it) { 539 void *P = (*it)->getPointerToFunction(F); 540 if (P) 541 return P; 542 } 543 544 // If we didn't find the function, see if we can generate it. 545 if (OpenModule) { 546 std::string ErrStr; 547 ExecutionEngine *NewEngine = 548 EngineBuilder(std::unique_ptr<Module>(OpenModule)) 549 .setErrorStr(&ErrStr) 550 .setMCJITMemoryManager(std::unique_ptr<HelpingMemoryManager>( 551 new HelpingMemoryManager(this))) 552 .create(); 553 if (!NewEngine) { 554 fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); 555 exit(1); 556 } 557 558 // Create a function pass manager for this engine 559 auto *FPM = new legacy::FunctionPassManager(OpenModule); 560 561 // Set up the optimizer pipeline. Start with registering info about how the 562 // target lays out data structures. 563 OpenModule->setDataLayout(*NewEngine->getDataLayout()); 564 // Provide basic AliasAnalysis support for GVN. 565 FPM->add(createBasicAliasAnalysisPass()); 566 // Promote allocas to registers. 567 FPM->add(createPromoteMemoryToRegisterPass()); 568 // Do simple "peephole" optimizations and bit-twiddling optzns. 569 FPM->add(createInstructionCombiningPass()); 570 // Reassociate expressions. 571 FPM->add(createReassociatePass()); 572 // Eliminate Common SubExpressions. 573 FPM->add(createGVNPass()); 574 // Simplify the control flow graph (deleting unreachable blocks, etc). 575 FPM->add(createCFGSimplificationPass()); 576 FPM->doInitialization(); 577 578 // For each function in the module 579 Module::iterator it; 580 Module::iterator end = OpenModule->end(); 581 for (it = OpenModule->begin(); it != end; ++it) { 582 // Run the FPM on this function 583 FPM->run(*it); 584 } 585 586 // We don't need this anymore 587 delete FPM; 588 589 OpenModule = NULL; 590 Engines.push_back(NewEngine); 591 NewEngine->finalizeObject(); 592 return NewEngine->getPointerToFunction(F); 593 } 594 return NULL; 595} 596 597void *MCJITHelper::getSymbolAddress(const std::string &Name) { 598 // Look for the symbol in each of our execution engines. 599 EngineVector::iterator begin = Engines.begin(); 600 EngineVector::iterator end = Engines.end(); 601 EngineVector::iterator it; 602 for (it = begin; it != end; ++it) { 603 uint64_t FAddr = (*it)->getFunctionAddress(Name); 604 if (FAddr) { 605 return (void *)FAddr; 606 } 607 } 608 return NULL; 609} 610 611void MCJITHelper::dump() { 612 ModuleVector::iterator begin = Modules.begin(); 613 ModuleVector::iterator end = Modules.end(); 614 ModuleVector::iterator it; 615 for (it = begin; it != end; ++it) 616 (*it)->dump(); 617} 618//===----------------------------------------------------------------------===// 619// Code Generation 620//===----------------------------------------------------------------------===// 621 622static MCJITHelper *JITHelper; 623static IRBuilder<> Builder(getGlobalContext()); 624static std::map<std::string, Value *> NamedValues; 625 626Value *ErrorV(const char *Str) { 627 Error(Str); 628 return 0; 629} 630 631Value *NumberExprAST::Codegen() { 632 return ConstantFP::get(getGlobalContext(), APFloat(Val)); 633} 634 635Value *VariableExprAST::Codegen() { 636 // Look this variable up in the function. 637 Value *V = NamedValues[Name]; 638 return V ? V : ErrorV("Unknown variable name"); 639} 640 641Value *BinaryExprAST::Codegen() { 642 Value *L = LHS->Codegen(); 643 Value *R = RHS->Codegen(); 644 if (L == 0 || R == 0) 645 return 0; 646 647 switch (Op) { 648 case '+': 649 return Builder.CreateFAdd(L, R, "addtmp"); 650 case '-': 651 return Builder.CreateFSub(L, R, "subtmp"); 652 case '*': 653 return Builder.CreateFMul(L, R, "multmp"); 654 case '<': 655 L = Builder.CreateFCmpULT(L, R, "cmptmp"); 656 // Convert bool 0/1 to double 0.0 or 1.0 657 return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), 658 "booltmp"); 659 default: 660 return ErrorV("invalid binary operator"); 661 } 662} 663 664Value *CallExprAST::Codegen() { 665 // Look up the name in the global module table. 666 Function *CalleeF = JITHelper->getFunction(Callee); 667 if (CalleeF == 0) 668 return ErrorV("Unknown function referenced"); 669 670 // If argument mismatch error. 671 if (CalleeF->arg_size() != Args.size()) 672 return ErrorV("Incorrect # arguments passed"); 673 674 std::vector<Value *> ArgsV; 675 for (unsigned i = 0, e = Args.size(); i != e; ++i) { 676 ArgsV.push_back(Args[i]->Codegen()); 677 if (ArgsV.back() == 0) 678 return 0; 679 } 680 681 return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); 682} 683 684Function *PrototypeAST::Codegen() { 685 // Make the function type: double(double,double) etc. 686 std::vector<Type *> Doubles(Args.size(), 687 Type::getDoubleTy(getGlobalContext())); 688 FunctionType *FT = 689 FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); 690 691 std::string FnName = MakeLegalFunctionName(Name); 692 693 Module *M = JITHelper->getModuleForNewFunction(); 694 695 Function *F = Function::Create(FT, Function::ExternalLinkage, FnName, M); 696 697 // If F conflicted, there was already something named 'Name'. If it has a 698 // body, don't allow redefinition or reextern. 699 if (F->getName() != FnName) { 700 // Delete the one we just made and get the existing one. 701 F->eraseFromParent(); 702 F = JITHelper->getFunction(Name); 703 // If F already has a body, reject this. 704 if (!F->empty()) { 705 ErrorF("redefinition of function"); 706 return 0; 707 } 708 709 // If F took a different number of args, reject. 710 if (F->arg_size() != Args.size()) { 711 ErrorF("redefinition of function with different # args"); 712 return 0; 713 } 714 } 715 716 // Set names for all arguments. 717 unsigned Idx = 0; 718 for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); 719 ++AI, ++Idx) { 720 AI->setName(Args[Idx]); 721 722 // Add arguments to variable symbol table. 723 NamedValues[Args[Idx]] = AI; 724 } 725 726 return F; 727} 728 729Function *FunctionAST::Codegen() { 730 NamedValues.clear(); 731 732 Function *TheFunction = Proto->Codegen(); 733 if (TheFunction == 0) 734 return 0; 735 736 // Create a new basic block to start insertion into. 737 BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); 738 Builder.SetInsertPoint(BB); 739 740 if (Value *RetVal = Body->Codegen()) { 741 // Finish off the function. 742 Builder.CreateRet(RetVal); 743 744 // Validate the generated code, checking for consistency. 745 verifyFunction(*TheFunction); 746 747 return TheFunction; 748 } 749 750 // Error reading body, remove function. 751 TheFunction->eraseFromParent(); 752 return 0; 753} 754 755//===----------------------------------------------------------------------===// 756// Top-Level parsing and JIT Driver 757//===----------------------------------------------------------------------===// 758 759static void HandleDefinition() { 760 if (FunctionAST *F = ParseDefinition()) { 761 if (Function *LF = F->Codegen()) { 762 fprintf(stderr, "Read function definition:"); 763 LF->dump(); 764 } 765 } else { 766 // Skip token for error recovery. 767 getNextToken(); 768 } 769} 770 771static void HandleExtern() { 772 if (PrototypeAST *P = ParseExtern()) { 773 if (Function *F = P->Codegen()) { 774 fprintf(stderr, "Read extern: "); 775 F->dump(); 776 } 777 } else { 778 // Skip token for error recovery. 779 getNextToken(); 780 } 781} 782 783static void HandleTopLevelExpression() { 784 // Evaluate a top-level expression into an anonymous function. 785 if (FunctionAST *F = ParseTopLevelExpr()) { 786 if (Function *LF = F->Codegen()) { 787 // JIT the function, returning a function pointer. 788 void *FPtr = JITHelper->getPointerToFunction(LF); 789 790 // Cast it to the right type (takes no arguments, returns a double) so we 791 // can call it as a native function. 792 double (*FP)() = (double (*)())(intptr_t)FPtr; 793 fprintf(stderr, "Evaluated to %f\n", FP()); 794 } 795 } else { 796 // Skip token for error recovery. 797 getNextToken(); 798 } 799} 800 801/// top ::= definition | external | expression | ';' 802static void MainLoop() { 803 while (1) { 804 fprintf(stderr, "ready> "); 805 switch (CurTok) { 806 case tok_eof: 807 return; 808 case ';': 809 getNextToken(); 810 break; // ignore top-level semicolons. 811 case tok_def: 812 HandleDefinition(); 813 break; 814 case tok_extern: 815 HandleExtern(); 816 break; 817 default: 818 HandleTopLevelExpression(); 819 break; 820 } 821 } 822} 823 824//===----------------------------------------------------------------------===// 825// "Library" functions that can be "extern'd" from user code. 826//===----------------------------------------------------------------------===// 827 828/// putchard - putchar that takes a double and returns 0. 829extern "C" double putchard(double X) { 830 putchar((char)X); 831 return 0; 832} 833 834//===----------------------------------------------------------------------===// 835// Main driver code. 836//===----------------------------------------------------------------------===// 837 838int main() { 839 InitializeNativeTarget(); 840 InitializeNativeTargetAsmPrinter(); 841 InitializeNativeTargetAsmParser(); 842 LLVMContext &Context = getGlobalContext(); 843 JITHelper = new MCJITHelper(Context); 844 845 // Install standard binary operators. 846 // 1 is lowest precedence. 847 BinopPrecedence['<'] = 10; 848 BinopPrecedence['+'] = 20; 849 BinopPrecedence['-'] = 20; 850 BinopPrecedence['*'] = 40; // highest. 851 852 // Prime the first token. 853 fprintf(stderr, "ready> "); 854 getNextToken(); 855 856 // Run the main "interpreter loop" now. 857 MainLoop(); 858 859 // Print out all of the generated code. 860 JITHelper->dump(); 861 862 return 0; 863} 864