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