14ca7e09b7c1e41535f2a1bd86915375d023daf27Chandler Carruth#include "llvm/Analysis/Passes.h" 231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar#include "llvm/ExecutionEngine/ExecutionEngine.h" 331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar#include "llvm/ExecutionEngine/JIT.h" 40a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/DataLayout.h" 50a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/DerivedTypes.h" 60a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/IRBuilder.h" 70a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/LLVMContext.h" 80a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/Module.h" 936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Verifier.h" 1031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar#include "llvm/PassManager.h" 113e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetSelect.h" 124ca7e09b7c1e41535f2a1bd86915375d023daf27Chandler Carruth#include "llvm/Transforms/Scalar.h" 13e3ba15c794839abe076e3e2bdf6c626396a19d4dWill Dietz#include <cctype> 1431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar#include <cstdio> 1531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar#include <map> 164ca7e09b7c1e41535f2a1bd86915375d023daf27Chandler Carruth#include <string> 1731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar#include <vector> 1831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarusing namespace llvm; 1931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 2031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 2131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// Lexer 2231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 2331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 2431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// The lexer returns tokens [0-255] if it is an unknown character, otherwise one 2531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// of these for known things. 2631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarenum Token { 2731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar tok_eof = -1, 2831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 2931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // commands 3031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar tok_def = -2, tok_extern = -3, 3131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 3231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // primary 3331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar tok_identifier = -4, tok_number = -5 3431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}; 3531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 3631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic std::string IdentifierStr; // Filled in if tok_identifier 3731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic double NumVal; // Filled in if tok_number 3831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 3931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// gettok - Return the next token from standard input. 4031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic int gettok() { 4131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar static int LastChar = ' '; 4231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 4331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Skip any whitespace. 4431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar while (isspace(LastChar)) 4531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar LastChar = getchar(); 4631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 4731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]* 4831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar IdentifierStr = LastChar; 4931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar while (isalnum((LastChar = getchar()))) 5031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar IdentifierStr += LastChar; 5131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 5231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (IdentifierStr == "def") return tok_def; 5331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (IdentifierStr == "extern") return tok_extern; 5431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return tok_identifier; 5531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 5631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 5731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ 5831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar std::string NumStr; 5931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar do { 6031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar NumStr += LastChar; 6131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar LastChar = getchar(); 6231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } while (isdigit(LastChar) || LastChar == '.'); 6331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 6431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar NumVal = strtod(NumStr.c_str(), 0); 6531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return tok_number; 6631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 6731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 6831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (LastChar == '#') { 6931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Comment until end of line. 7031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar do LastChar = getchar(); 7131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); 7231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 7331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (LastChar != EOF) 7431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return gettok(); 7531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 7631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 7731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Check for end of file. Don't eat the EOF. 7831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (LastChar == EOF) 7931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return tok_eof; 8031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 8131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Otherwise, just return the character as its ascii value. 8231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar int ThisChar = LastChar; 8331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar LastChar = getchar(); 8431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return ThisChar; 8531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 8631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 8731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 8831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// Abstract Syntax Tree (aka Parse Tree) 8931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 909d7c776d32c8a4d64b37a91c2d627629cf1498efBill Wendlingnamespace { 9131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// ExprAST - Base class for all expression nodes. 9231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass ExprAST { 9331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic: 949d7c776d32c8a4d64b37a91c2d627629cf1498efBill Wendling virtual ~ExprAST() {} 9531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar virtual Value *Codegen() = 0; 9631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}; 9731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 9831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// NumberExprAST - Expression class for numeric literals like "1.0". 9931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass NumberExprAST : public ExprAST { 10031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar double Val; 10131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic: 10231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar NumberExprAST(double val) : Val(val) {} 10331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar virtual Value *Codegen(); 10431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}; 10531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 10631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// VariableExprAST - Expression class for referencing a variable, like "a". 10731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass VariableExprAST : public ExprAST { 10831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar std::string Name; 10931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic: 11031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar VariableExprAST(const std::string &name) : Name(name) {} 11131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar virtual Value *Codegen(); 11231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}; 11331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 11431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// BinaryExprAST - Expression class for a binary operator. 11531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass BinaryExprAST : public ExprAST { 11631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar char Op; 11731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar ExprAST *LHS, *RHS; 11831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic: 11931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) 12031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar : Op(op), LHS(lhs), RHS(rhs) {} 12131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar virtual Value *Codegen(); 12231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}; 12331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 12431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// CallExprAST - Expression class for function calls. 12531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass CallExprAST : public ExprAST { 12631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar std::string Callee; 12731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar std::vector<ExprAST*> Args; 12831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic: 12931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar CallExprAST(const std::string &callee, std::vector<ExprAST*> &args) 13031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar : Callee(callee), Args(args) {} 13131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar virtual Value *Codegen(); 13231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}; 13331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 13431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// PrototypeAST - This class represents the "prototype" for a function, 13531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// which captures its name, and its argument names (thus implicitly the number 13631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// of arguments the function takes). 13731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass PrototypeAST { 13831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar std::string Name; 13931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar std::vector<std::string> Args; 14031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic: 14131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar PrototypeAST(const std::string &name, const std::vector<std::string> &args) 14231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar : Name(name), Args(args) {} 14331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 14431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar Function *Codegen(); 14531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}; 14631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 14731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// FunctionAST - This class represents a function definition itself. 14831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass FunctionAST { 14931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar PrototypeAST *Proto; 15031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar ExprAST *Body; 15131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic: 15231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar FunctionAST(PrototypeAST *proto, ExprAST *body) 15331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar : Proto(proto), Body(body) {} 15431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 15531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar Function *Codegen(); 15631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}; 1579d7c776d32c8a4d64b37a91c2d627629cf1498efBill Wendling} // end anonymous namespace 15831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 15931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 16031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// Parser 16131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 16231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 16331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current 16431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// token the parser is looking at. getNextToken reads another token from the 16531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// lexer and updates CurTok with its results. 16631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic int CurTok; 16731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic int getNextToken() { 16831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return CurTok = gettok(); 16931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 17031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 17131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// BinopPrecedence - This holds the precedence for each binary operator that is 17231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// defined. 17331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic std::map<char, int> BinopPrecedence; 17431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 17531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// GetTokPrecedence - Get the precedence of the pending binary operator token. 17631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic int GetTokPrecedence() { 17731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (!isascii(CurTok)) 17831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return -1; 17931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 18031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Make sure it's a declared binop. 18131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar int TokPrec = BinopPrecedence[CurTok]; 18231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (TokPrec <= 0) return -1; 18331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return TokPrec; 18431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 18531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 18631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// Error* - These are little helper functions for error handling. 18731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;} 18831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarPrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; } 18931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarFunctionAST *ErrorF(const char *Str) { Error(Str); return 0; } 19031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 19131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParseExpression(); 19231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 19331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// identifierexpr 19431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// ::= identifier 19531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// ::= identifier '(' expression* ')' 19631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParseIdentifierExpr() { 19731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar std::string IdName = IdentifierStr; 19831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 19931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); // eat identifier. 20031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 20131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (CurTok != '(') // Simple variable ref. 20231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return new VariableExprAST(IdName); 20331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 20431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Call. 20531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); // eat ( 20631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar std::vector<ExprAST*> Args; 20731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (CurTok != ')') { 20831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar while (1) { 20931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar ExprAST *Arg = ParseExpression(); 21031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (!Arg) return 0; 21131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar Args.push_back(Arg); 21231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 21331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (CurTok == ')') break; 21431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 21531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (CurTok != ',') 21631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return Error("Expected ')' or ',' in argument list"); 21731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); 21831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 21931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 22031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 22131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Eat the ')'. 22231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); 22331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 22431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return new CallExprAST(IdName, Args); 22531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 22631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 22731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// numberexpr ::= number 22831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParseNumberExpr() { 22931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar ExprAST *Result = new NumberExprAST(NumVal); 23031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); // consume the number 23131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return Result; 23231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 23331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 23431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// parenexpr ::= '(' expression ')' 23531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParseParenExpr() { 23631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); // eat (. 23731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar ExprAST *V = ParseExpression(); 23831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (!V) return 0; 23931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 24031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (CurTok != ')') 24131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return Error("expected ')'"); 24231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); // eat ). 24331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return V; 24431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 24531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 24631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// primary 24731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// ::= identifierexpr 24831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// ::= numberexpr 24931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// ::= parenexpr 25031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParsePrimary() { 25131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar switch (CurTok) { 25231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar default: return Error("unknown token when expecting an expression"); 25331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar case tok_identifier: return ParseIdentifierExpr(); 25431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar case tok_number: return ParseNumberExpr(); 25531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar case '(': return ParseParenExpr(); 25631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 25731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 25831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 25931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// binoprhs 26031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// ::= ('+' primary)* 26131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { 26231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // If this is a binop, find its precedence. 26331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar while (1) { 26431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar int TokPrec = GetTokPrecedence(); 26531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 26631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // If this is a binop that binds at least as tightly as the current binop, 26731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // consume it, otherwise we are done. 26831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (TokPrec < ExprPrec) 26931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return LHS; 27031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 27131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Okay, we know this is a binop. 27231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar int BinOp = CurTok; 27331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); // eat binop 27431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 27531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Parse the primary expression after the binary operator. 27631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar ExprAST *RHS = ParsePrimary(); 27731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (!RHS) return 0; 27831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 27931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // If BinOp binds less tightly with RHS than the operator after RHS, let 28031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // the pending operator take RHS as its LHS. 28131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar int NextPrec = GetTokPrecedence(); 28231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (TokPrec < NextPrec) { 28331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar RHS = ParseBinOpRHS(TokPrec+1, RHS); 28431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (RHS == 0) return 0; 28531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 28631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 28731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Merge LHS/RHS. 28831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar LHS = new BinaryExprAST(BinOp, LHS, RHS); 28931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 29031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 29131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 29231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// expression 29331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// ::= primary binoprhs 29431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// 29531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParseExpression() { 29631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar ExprAST *LHS = ParsePrimary(); 29731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (!LHS) return 0; 29831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 29931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return ParseBinOpRHS(0, LHS); 30031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 30131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 30231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// prototype 30331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// ::= id '(' id* ')' 30431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic PrototypeAST *ParsePrototype() { 30531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (CurTok != tok_identifier) 30631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return ErrorP("Expected function name in prototype"); 30731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 30831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar std::string FnName = IdentifierStr; 30931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); 31031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 31131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (CurTok != '(') 31231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return ErrorP("Expected '(' in prototype"); 31331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 31431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar std::vector<std::string> ArgNames; 31531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar while (getNextToken() == tok_identifier) 31631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar ArgNames.push_back(IdentifierStr); 31731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (CurTok != ')') 31831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return ErrorP("Expected ')' in prototype"); 31931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 32031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // success. 32131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); // eat ')'. 32231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 32331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return new PrototypeAST(FnName, ArgNames); 32431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 32531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 32631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// definition ::= 'def' prototype expression 32731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic FunctionAST *ParseDefinition() { 32831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); // eat def. 32931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar PrototypeAST *Proto = ParsePrototype(); 33031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (Proto == 0) return 0; 33131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 33231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (ExprAST *E = ParseExpression()) 33331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return new FunctionAST(Proto, E); 33431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return 0; 33531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 33631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 33731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// toplevelexpr ::= expression 33831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic FunctionAST *ParseTopLevelExpr() { 33931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (ExprAST *E = ParseExpression()) { 34031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Make an anonymous proto. 34131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); 34231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return new FunctionAST(Proto, E); 34331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 34431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return 0; 34531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 34631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 34731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// external ::= 'extern' prototype 34831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic PrototypeAST *ParseExtern() { 34931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); // eat extern. 35031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return ParsePrototype(); 35131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 35231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 35331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 35431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// Code Generation 35531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 35631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 35731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic Module *TheModule; 35831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic IRBuilder<> Builder(getGlobalContext()); 35931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic std::map<std::string, Value*> NamedValues; 36031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic FunctionPassManager *TheFPM; 36131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 36231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarValue *ErrorV(const char *Str) { Error(Str); return 0; } 36331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 36431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarValue *NumberExprAST::Codegen() { 36531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return ConstantFP::get(getGlobalContext(), APFloat(Val)); 36631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 36731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 36831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarValue *VariableExprAST::Codegen() { 36931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Look this variable up in the function. 37031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar Value *V = NamedValues[Name]; 37131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return V ? V : ErrorV("Unknown variable name"); 37231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 37331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 37431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarValue *BinaryExprAST::Codegen() { 37531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar Value *L = LHS->Codegen(); 37631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar Value *R = RHS->Codegen(); 37731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (L == 0 || R == 0) return 0; 37831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 37931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar switch (Op) { 3802632bbf0de4637e02f333952991263d526976fafEric Christopher case '+': return Builder.CreateFAdd(L, R, "addtmp"); 3812632bbf0de4637e02f333952991263d526976fafEric Christopher case '-': return Builder.CreateFSub(L, R, "subtmp"); 3822632bbf0de4637e02f333952991263d526976fafEric Christopher case '*': return Builder.CreateFMul(L, R, "multmp"); 38331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar case '<': 38431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar L = Builder.CreateFCmpULT(L, R, "cmptmp"); 38531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Convert bool 0/1 to double 0.0 or 1.0 38631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), 38731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar "booltmp"); 38831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar default: return ErrorV("invalid binary operator"); 38931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 39031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 39131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 39231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarValue *CallExprAST::Codegen() { 39331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Look up the name in the global module table. 39431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar Function *CalleeF = TheModule->getFunction(Callee); 39531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (CalleeF == 0) 39631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return ErrorV("Unknown function referenced"); 39731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 39831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // If argument mismatch error. 39931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (CalleeF->arg_size() != Args.size()) 40031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return ErrorV("Incorrect # arguments passed"); 40131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 40231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar std::vector<Value*> ArgsV; 40331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar for (unsigned i = 0, e = Args.size(); i != e; ++i) { 40431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar ArgsV.push_back(Args[i]->Codegen()); 40531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (ArgsV.back() == 0) return 0; 40631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 40731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 4080bd9d3af54b62152355525bea7914bdef4600371Francois Pichet return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); 40931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 41031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 41131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarFunction *PrototypeAST::Codegen() { 41231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Make the function type: double(double,double) etc. 413d1c2bd8e6e37e08393f7c4980efc5bcb66b6f0d0John Wiegley std::vector<Type*> Doubles(Args.size(), 414d1c2bd8e6e37e08393f7c4980efc5bcb66b6f0d0John Wiegley Type::getDoubleTy(getGlobalContext())); 41531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), 41631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar Doubles, false); 41731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 41831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule); 41931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 42031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // If F conflicted, there was already something named 'Name'. If it has a 42131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // body, don't allow redefinition or reextern. 42231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (F->getName() != Name) { 42331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Delete the one we just made and get the existing one. 42431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar F->eraseFromParent(); 42531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar F = TheModule->getFunction(Name); 42631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 42731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // If F already has a body, reject this. 42831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (!F->empty()) { 42931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar ErrorF("redefinition of function"); 43031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return 0; 43131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 43231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 43331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // If F took a different number of args, reject. 43431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (F->arg_size() != Args.size()) { 43531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar ErrorF("redefinition of function with different # args"); 43631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return 0; 43731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 43831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 43931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 44031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Set names for all arguments. 44131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar unsigned Idx = 0; 44231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); 44331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar ++AI, ++Idx) { 44431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar AI->setName(Args[Idx]); 44531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 44631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Add arguments to variable symbol table. 44731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar NamedValues[Args[Idx]] = AI; 44831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 44931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 45031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return F; 45131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 45231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 45331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarFunction *FunctionAST::Codegen() { 45431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar NamedValues.clear(); 45531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 45631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar Function *TheFunction = Proto->Codegen(); 45731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (TheFunction == 0) 45831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return 0; 45931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 46031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Create a new basic block to start insertion into. 46131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); 46231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar Builder.SetInsertPoint(BB); 46331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 46431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (Value *RetVal = Body->Codegen()) { 46531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Finish off the function. 46631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar Builder.CreateRet(RetVal); 46731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 46831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Validate the generated code, checking for consistency. 46931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar verifyFunction(*TheFunction); 47031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 47131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Optimize the function. 47231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar TheFPM->run(*TheFunction); 47331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 47431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return TheFunction; 47531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 47631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 47731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Error reading body, remove function. 47831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar TheFunction->eraseFromParent(); 47931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return 0; 48031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 48131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 48231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 48331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// Top-Level parsing and JIT Driver 48431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 48531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 48631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExecutionEngine *TheExecutionEngine; 48731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 48831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic void HandleDefinition() { 48931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (FunctionAST *F = ParseDefinition()) { 49031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (Function *LF = F->Codegen()) { 49131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar fprintf(stderr, "Read function definition:"); 49231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar LF->dump(); 49331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 49431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } else { 49531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Skip token for error recovery. 49631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); 49731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 49831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 49931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 50031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic void HandleExtern() { 50131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (PrototypeAST *P = ParseExtern()) { 50231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (Function *F = P->Codegen()) { 50331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar fprintf(stderr, "Read extern: "); 50431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar F->dump(); 50531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 50631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } else { 50731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Skip token for error recovery. 50831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); 50931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 51031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 51131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 51231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic void HandleTopLevelExpression() { 51331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Evaluate a top-level expression into an anonymous function. 51431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (FunctionAST *F = ParseTopLevelExpr()) { 51531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar if (Function *LF = F->Codegen()) { 51631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // JIT the function, returning a function pointer. 51731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar void *FPtr = TheExecutionEngine->getPointerToFunction(LF); 51831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 51931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Cast it to the right type (takes no arguments, returns a double) so we 52031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // can call it as a native function. 52131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar double (*FP)() = (double (*)())(intptr_t)FPtr; 52231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar fprintf(stderr, "Evaluated to %f\n", FP()); 52331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 52431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } else { 52531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Skip token for error recovery. 52631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); 52731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 52831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 52931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 53031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// top ::= definition | external | expression | ';' 53131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic void MainLoop() { 53231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar while (1) { 53331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar fprintf(stderr, "ready> "); 53431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar switch (CurTok) { 53531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar case tok_eof: return; 53631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar case ';': getNextToken(); break; // ignore top-level semicolons. 53731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar case tok_def: HandleDefinition(); break; 53831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar case tok_extern: HandleExtern(); break; 53931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar default: HandleTopLevelExpression(); break; 54031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 54131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar } 54231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 54331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 54431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 54531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// "Library" functions that can be "extern'd" from user code. 54631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 54731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 54831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// putchard - putchar that takes a double and returns 0. 54931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarextern "C" 55031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaardouble putchard(double X) { 55131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar putchar((char)X); 55231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return 0; 55331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 55431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 55531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 55631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// Main driver code. 55731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===// 55831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 55931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarint main() { 56031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar InitializeNativeTarget(); 56131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar LLVMContext &Context = getGlobalContext(); 56231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 56331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Install standard binary operators. 56431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // 1 is lowest precedence. 56531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar BinopPrecedence['<'] = 10; 56631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar BinopPrecedence['+'] = 20; 56731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar BinopPrecedence['-'] = 20; 56831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar BinopPrecedence['*'] = 40; // highest. 56931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 57031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Prime the first token. 57131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar fprintf(stderr, "ready> "); 57231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar getNextToken(); 57331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 57431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Make the module, which holds all the code. 57531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar TheModule = new Module("my cool jit", Context); 57631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 577f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin // Create the JIT. This takes ownership of the module. 57842fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin std::string ErrStr; 57942fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create(); 58042fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin if (!TheExecutionEngine) { 58142fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); 58242fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin exit(1); 58342fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin } 58431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 585f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin FunctionPassManager OurFPM(TheModule); 58631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 58731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Set up the optimizer pipeline. Start with registering info about how the 58831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // target lays out data structures. 58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TheModule->setDataLayout(TheExecutionEngine->getDataLayout()); 59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OurFPM.add(new DataLayoutPass(TheModule)); 591dfa1a79b0c2f09349b6cd451198781a3ced48cb8Dan Gohman // Provide basic AliasAnalysis support for GVN. 592dfa1a79b0c2f09349b6cd451198781a3ced48cb8Dan Gohman OurFPM.add(createBasicAliasAnalysisPass()); 59331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Do simple "peephole" optimizations and bit-twiddling optzns. 59431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar OurFPM.add(createInstructionCombiningPass()); 59531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Reassociate expressions. 59631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar OurFPM.add(createReassociatePass()); 59731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Eliminate Common SubExpressions. 59831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar OurFPM.add(createGVNPass()); 59931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Simplify the control flow graph (deleting unreachable blocks, etc). 60031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar OurFPM.add(createCFGSimplificationPass()); 60131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 60231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar OurFPM.doInitialization(); 60331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 60431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Set the global so the code gen can use this. 60531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar TheFPM = &OurFPM; 60631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 60731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Run the main "interpreter loop" now. 60831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar MainLoop(); 60931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 61031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar TheFPM = 0; 61131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 61231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar // Print out all of the generated code. 61331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar TheModule->dump(); 61431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar 61531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar return 0; 61631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar} 617