toy.cpp revision 9d7c776d32c8a4d64b37a91c2d627629cf1498ef
14ca7e09b7c1e41535f2a1bd86915375d023daf27Chandler Carruth#include "llvm/Analysis/Passes.h" 24ca7e09b7c1e41535f2a1bd86915375d023daf27Chandler Carruth#include "llvm/Analysis/Verifier.h" 39f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky#include "llvm/ExecutionEngine/ExecutionEngine.h" 46ce6daae38c5dd95e7daa5790d97398343564588Xerxes Ranby#include "llvm/ExecutionEngine/JIT.h" 50a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/DataLayout.h" 60a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/DerivedTypes.h" 70a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/IRBuilder.h" 80a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/LLVMContext.h" 90a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/Module.h" 109f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky#include "llvm/PassManager.h" 113e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetSelect.h" 124ca7e09b7c1e41535f2a1bd86915375d023daf27Chandler Carruth#include "llvm/Transforms/Scalar.h" 13e3ba15c794839abe076e3e2bdf6c626396a19d4dWill Dietz#include <cctype> 149f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky#include <cstdio> 159f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky#include <map> 164ca7e09b7c1e41535f2a1bd86915375d023daf27Chandler Carruth#include <string> 179f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky#include <vector> 189f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyusing namespace llvm; 199f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 209f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 219f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky// Lexer 229f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 239f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 249f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky// The lexer returns tokens [0-255] if it is an unknown character, otherwise one 259f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky// of these for known things. 269f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyenum Token { 279f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky tok_eof = -1, 289f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 299f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // commands 309f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky tok_def = -2, tok_extern = -3, 319f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 329f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // primary 339f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky tok_identifier = -4, tok_number = -5, 349f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 359f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // control 369f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky tok_if = -6, tok_then = -7, tok_else = -8, 379f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky tok_for = -9, tok_in = -10, 389f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 399f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // operators 409f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky tok_binary = -11, tok_unary = -12, 419f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 429f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // var definition 439f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky tok_var = -13 449f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky}; 459f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 469f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic std::string IdentifierStr; // Filled in if tok_identifier 479f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic double NumVal; // Filled in if tok_number 489f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 499f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// gettok - Return the next token from standard input. 509f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic int gettok() { 519f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky static int LastChar = ' '; 529f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 539f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Skip any whitespace. 549f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky while (isspace(LastChar)) 559f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky LastChar = getchar(); 569f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 579f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]* 589f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky IdentifierStr = LastChar; 599f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky while (isalnum((LastChar = getchar()))) 609f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky IdentifierStr += LastChar; 619f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 629f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (IdentifierStr == "def") return tok_def; 639f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (IdentifierStr == "extern") return tok_extern; 649f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (IdentifierStr == "if") return tok_if; 659f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (IdentifierStr == "then") return tok_then; 669f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (IdentifierStr == "else") return tok_else; 679f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (IdentifierStr == "for") return tok_for; 689f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (IdentifierStr == "in") return tok_in; 699f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (IdentifierStr == "binary") return tok_binary; 709f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (IdentifierStr == "unary") return tok_unary; 719f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (IdentifierStr == "var") return tok_var; 729f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return tok_identifier; 739f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 749f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 759f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ 769f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::string NumStr; 779f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky do { 789f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky NumStr += LastChar; 799f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky LastChar = getchar(); 809f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } while (isdigit(LastChar) || LastChar == '.'); 819f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 829f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky NumVal = strtod(NumStr.c_str(), 0); 839f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return tok_number; 849f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 859f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 869f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (LastChar == '#') { 879f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Comment until end of line. 889f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky do LastChar = getchar(); 899f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); 909f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 919f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (LastChar != EOF) 929f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return gettok(); 939f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 949f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 959f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Check for end of file. Don't eat the EOF. 969f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (LastChar == EOF) 979f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return tok_eof; 989f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 999f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Otherwise, just return the character as its ascii value. 1009f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky int ThisChar = LastChar; 1019f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky LastChar = getchar(); 1029f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ThisChar; 1039f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 1049f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 1059f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 1069f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky// Abstract Syntax Tree (aka Parse Tree) 1079f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 1089d7c776d32c8a4d64b37a91c2d627629cf1498efBill Wendlingnamespace { 1099f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ExprAST - Base class for all expression nodes. 1109f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyclass ExprAST { 1119f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckypublic: 1129d7c776d32c8a4d64b37a91c2d627629cf1498efBill Wendling virtual ~ExprAST() {} 1139f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky virtual Value *Codegen() = 0; 1149f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky}; 1159f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 1169f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// NumberExprAST - Expression class for numeric literals like "1.0". 1179f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyclass NumberExprAST : public ExprAST { 1189f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky double Val; 1199f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckypublic: 1209f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky NumberExprAST(double val) : Val(val) {} 1219f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky virtual Value *Codegen(); 1229f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky}; 1239f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 1249f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// VariableExprAST - Expression class for referencing a variable, like "a". 1259f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyclass VariableExprAST : public ExprAST { 1269f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::string Name; 1279f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckypublic: 1289f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky VariableExprAST(const std::string &name) : Name(name) {} 1299f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky const std::string &getName() const { return Name; } 1309f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky virtual Value *Codegen(); 1319f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky}; 1329f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 1339f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// UnaryExprAST - Expression class for a unary operator. 1349f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyclass UnaryExprAST : public ExprAST { 1359f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky char Opcode; 1369f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Operand; 1379f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckypublic: 1389f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky UnaryExprAST(char opcode, ExprAST *operand) 1399f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky : Opcode(opcode), Operand(operand) {} 1409f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky virtual Value *Codegen(); 1419f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky}; 1429f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 1439f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// BinaryExprAST - Expression class for a binary operator. 1449f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyclass BinaryExprAST : public ExprAST { 1459f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky char Op; 1469f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *LHS, *RHS; 1479f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckypublic: 1489f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) 1499f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky : Op(op), LHS(lhs), RHS(rhs) {} 1509f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky virtual Value *Codegen(); 1519f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky}; 1529f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 1539f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// CallExprAST - Expression class for function calls. 1549f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyclass CallExprAST : public ExprAST { 1559f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::string Callee; 1569f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::vector<ExprAST*> Args; 1579f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckypublic: 1589f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky CallExprAST(const std::string &callee, std::vector<ExprAST*> &args) 1599f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky : Callee(callee), Args(args) {} 1609f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky virtual Value *Codegen(); 1619f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky}; 1629f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 1639f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// IfExprAST - Expression class for if/then/else. 1649f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyclass IfExprAST : public ExprAST { 1659f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Cond, *Then, *Else; 1669f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckypublic: 1679f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else) 1689f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky : Cond(cond), Then(then), Else(_else) {} 1699f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky virtual Value *Codegen(); 1709f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky}; 1719f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 1729f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ForExprAST - Expression class for for/in. 1739f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyclass ForExprAST : public ExprAST { 1749f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::string VarName; 1759f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Start, *End, *Step, *Body; 1769f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckypublic: 1779f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end, 1789f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *step, ExprAST *body) 1799f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky : VarName(varname), Start(start), End(end), Step(step), Body(body) {} 1809f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky virtual Value *Codegen(); 1819f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky}; 1829f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 1839f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// VarExprAST - Expression class for var/in 1849f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyclass VarExprAST : public ExprAST { 1859f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::vector<std::pair<std::string, ExprAST*> > VarNames; 1869f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Body; 1879f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckypublic: 1889f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky VarExprAST(const std::vector<std::pair<std::string, ExprAST*> > &varnames, 1899f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *body) 1909f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky : VarNames(varnames), Body(body) {} 1919f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 1929f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky virtual Value *Codegen(); 1939f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky}; 1949f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 1959f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// PrototypeAST - This class represents the "prototype" for a function, 1969f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// which captures its argument names as well as if it is an operator. 1979f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyclass PrototypeAST { 1989f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::string Name; 1999f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::vector<std::string> Args; 2009f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky bool isOperator; 2019f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky unsigned Precedence; // Precedence if a binary op. 2029f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckypublic: 2039f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky PrototypeAST(const std::string &name, const std::vector<std::string> &args, 2049f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky bool isoperator = false, unsigned prec = 0) 2059f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky : Name(name), Args(args), isOperator(isoperator), Precedence(prec) {} 2069f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2079f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky bool isUnaryOp() const { return isOperator && Args.size() == 1; } 2089f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky bool isBinaryOp() const { return isOperator && Args.size() == 2; } 2099f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2109f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky char getOperatorName() const { 2119f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky assert(isUnaryOp() || isBinaryOp()); 2129f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Name[Name.size()-1]; 2139f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 2149f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2159f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky unsigned getBinaryPrecedence() const { return Precedence; } 2169f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2179f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Function *Codegen(); 2189f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2199f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky void CreateArgumentAllocas(Function *F); 2209f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky}; 2219f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2229f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// FunctionAST - This class represents a function definition itself. 2239f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyclass FunctionAST { 2249f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky PrototypeAST *Proto; 2259f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Body; 2269f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckypublic: 2279f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky FunctionAST(PrototypeAST *proto, ExprAST *body) 2289f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky : Proto(proto), Body(body) {} 2299f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2309f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Function *Codegen(); 2319f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky}; 2329d7c776d32c8a4d64b37a91c2d627629cf1498efBill Wendling} // end anonymous namespace 2339f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2349f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 2359f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky// Parser 2369f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 2379f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2389f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current 239fd1ec5e68b593a4f4d5497b150e677ebef36c231Erick Tryzelaar/// token the parser is looking at. getNextToken reads another token from the 2409f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// lexer and updates CurTok with its results. 2419f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic int CurTok; 2429f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic int getNextToken() { 2439f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return CurTok = gettok(); 2449f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 2459f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2469f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// BinopPrecedence - This holds the precedence for each binary operator that is 2479f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// defined. 2489f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic std::map<char, int> BinopPrecedence; 2499f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2509f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// GetTokPrecedence - Get the precedence of the pending binary operator token. 2519f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic int GetTokPrecedence() { 2529f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (!isascii(CurTok)) 2539f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return -1; 2549f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2559f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Make sure it's a declared binop. 2569f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky int TokPrec = BinopPrecedence[CurTok]; 2579f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (TokPrec <= 0) return -1; 2589f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return TokPrec; 2599f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 2609f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2619f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// Error* - These are little helper functions for error handling. 2629f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;} 2639f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyPrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; } 2649f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyFunctionAST *ErrorF(const char *Str) { Error(Str); return 0; } 2659f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2669f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic ExprAST *ParseExpression(); 2679f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2689f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// identifierexpr 2699f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= identifier 2709f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= identifier '(' expression* ')' 2719f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic ExprAST *ParseIdentifierExpr() { 2729f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::string IdName = IdentifierStr; 2739f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2749f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat identifier. 2759f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2769f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != '(') // Simple variable ref. 2779f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return new VariableExprAST(IdName); 2789f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2799f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Call. 2809f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat ( 2819f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::vector<ExprAST*> Args; 2829f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != ')') { 2839f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky while (1) { 2849f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Arg = ParseExpression(); 2859f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (!Arg) return 0; 2869f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Args.push_back(Arg); 287fd1ec5e68b593a4f4d5497b150e677ebef36c231Erick Tryzelaar 2889f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok == ')') break; 289fd1ec5e68b593a4f4d5497b150e677ebef36c231Erick Tryzelaar 2909f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != ',') 2919f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Error("Expected ')' or ',' in argument list"); 2929f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 2939f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 2949f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 2959f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2969f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Eat the ')'. 2979f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 2989f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 2999f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return new CallExprAST(IdName, Args); 3009f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 3019f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3029f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// numberexpr ::= number 3039f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic ExprAST *ParseNumberExpr() { 3049f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Result = new NumberExprAST(NumVal); 3059f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // consume the number 3069f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Result; 3079f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 3089f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3099f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// parenexpr ::= '(' expression ')' 3109f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic ExprAST *ParseParenExpr() { 3119f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat (. 3129f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *V = ParseExpression(); 3139f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (!V) return 0; 3149f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3159f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != ')') 3169f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Error("expected ')'"); 3179f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat ). 3189f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return V; 3199f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 3209f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3219f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ifexpr ::= 'if' expression 'then' expression 'else' expression 3229f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic ExprAST *ParseIfExpr() { 3239f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat the if. 3249f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3259f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // condition. 3269f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Cond = ParseExpression(); 3279f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (!Cond) return 0; 3289f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3299f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != tok_then) 3309f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Error("expected then"); 3319f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat the then 3329f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3339f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Then = ParseExpression(); 3349f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Then == 0) return 0; 3359f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3369f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != tok_else) 3379f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Error("expected else"); 3389f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3399f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 3409f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3419f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Else = ParseExpression(); 3429f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (!Else) return 0; 3439f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3449f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return new IfExprAST(Cond, Then, Else); 3459f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 3469f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3479f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression 3489f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic ExprAST *ParseForExpr() { 3499f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat the for. 3509f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3519f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != tok_identifier) 3529f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Error("expected identifier after for"); 3539f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3549f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::string IdName = IdentifierStr; 3559f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat identifier. 3569f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3579f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != '=') 3589f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Error("expected '=' after for"); 3599f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat '='. 3609f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3619f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3629f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Start = ParseExpression(); 3639f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Start == 0) return 0; 3649f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != ',') 3659f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Error("expected ',' after for start value"); 3669f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 3679f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3689f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *End = ParseExpression(); 3699f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (End == 0) return 0; 3709f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3719f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // The step value is optional. 3729f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Step = 0; 3739f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok == ',') { 3749f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 3759f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Step = ParseExpression(); 3769f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Step == 0) return 0; 3779f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 3789f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3799f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != tok_in) 3809f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Error("expected 'in' after for"); 3819f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat 'in'. 3829f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3839f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Body = ParseExpression(); 3849f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Body == 0) return 0; 3859f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3869f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return new ForExprAST(IdName, Start, End, Step, Body); 3879f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 3889f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3899f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// varexpr ::= 'var' identifier ('=' expression)? 3909f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky// (',' identifier ('=' expression)?)* 'in' expression 3919f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic ExprAST *ParseVarExpr() { 3929f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat the var. 3939f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3949f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::vector<std::pair<std::string, ExprAST*> > VarNames; 3959f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 3969f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // At least one variable name is required. 3979f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != tok_identifier) 3989f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Error("expected identifier after var"); 3999f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4009f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky while (1) { 4019f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::string Name = IdentifierStr; 4029f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat identifier. 4039f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4049f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Read the optional initializer. 4059f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Init = 0; 4069f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok == '=') { 4079f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat the '='. 4089f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4099f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Init = ParseExpression(); 4109f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Init == 0) return 0; 4119f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 4129f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4139f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky VarNames.push_back(std::make_pair(Name, Init)); 4149f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4159f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // End of var list, exit loop. 4169f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != ',') break; 4179f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat the ','. 4189f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4199f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != tok_identifier) 4209f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Error("expected identifier list after var"); 4219f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 4229f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4239f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // At this point, we have to have 'in'. 4249f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != tok_in) 4259f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Error("expected 'in' keyword after 'var'"); 4269f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat 'in'. 4279f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4289f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Body = ParseExpression(); 4299f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Body == 0) return 0; 4309f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4319f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return new VarExprAST(VarNames, Body); 4329f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 4339f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4349f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// primary 4359f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= identifierexpr 4369f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= numberexpr 4379f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= parenexpr 4389f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= ifexpr 4399f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= forexpr 4409f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= varexpr 4419f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic ExprAST *ParsePrimary() { 4429f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky switch (CurTok) { 4439f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky default: return Error("unknown token when expecting an expression"); 4449f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case tok_identifier: return ParseIdentifierExpr(); 4459f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case tok_number: return ParseNumberExpr(); 4469f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case '(': return ParseParenExpr(); 4479f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case tok_if: return ParseIfExpr(); 4489f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case tok_for: return ParseForExpr(); 4499f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case tok_var: return ParseVarExpr(); 4509f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 4519f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 4529f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4539f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// unary 4549f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= primary 4559f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= '!' unary 4569f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic ExprAST *ParseUnary() { 4579f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // If the current token is not an operator, it must be a primary expr. 4589f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (!isascii(CurTok) || CurTok == '(' || CurTok == ',') 4599f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ParsePrimary(); 4609f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4619f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // If this is a unary operator, read it. 4629f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky int Opc = CurTok; 4639f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 4649f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (ExprAST *Operand = ParseUnary()) 4659f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return new UnaryExprAST(Opc, Operand); 4669f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return 0; 4679f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 4689f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4699f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// binoprhs 4709f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= ('+' unary)* 4719f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { 4729f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // If this is a binop, find its precedence. 4739f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky while (1) { 4749f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky int TokPrec = GetTokPrecedence(); 4759f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4769f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // If this is a binop that binds at least as tightly as the current binop, 4779f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // consume it, otherwise we are done. 4789f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (TokPrec < ExprPrec) 4799f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return LHS; 4809f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4819f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Okay, we know this is a binop. 4829f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky int BinOp = CurTok; 4839f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat binop 4849f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4859f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Parse the unary expression after the binary operator. 4869f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *RHS = ParseUnary(); 4879f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (!RHS) return 0; 4889f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4899f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // If BinOp binds less tightly with RHS than the operator after RHS, let 4909f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // the pending operator take RHS as its LHS. 4919f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky int NextPrec = GetTokPrecedence(); 4929f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (TokPrec < NextPrec) { 4939f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky RHS = ParseBinOpRHS(TokPrec+1, RHS); 4949f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (RHS == 0) return 0; 4959f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 4969f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 4979f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Merge LHS/RHS. 4989f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky LHS = new BinaryExprAST(BinOp, LHS, RHS); 4999f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 5009f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 5019f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5029f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// expression 5039f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= unary binoprhs 5049f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// 5059f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic ExprAST *ParseExpression() { 5069f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *LHS = ParseUnary(); 5079f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (!LHS) return 0; 5089f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5099f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ParseBinOpRHS(0, LHS); 5109f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 5119f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5129f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// prototype 5139f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= id '(' id* ')' 5149f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= binary LETTER number? (id, id) 5159f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// ::= unary LETTER (id) 5169f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic PrototypeAST *ParsePrototype() { 5179f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::string FnName; 5189f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 519fd1ec5e68b593a4f4d5497b150e677ebef36c231Erick Tryzelaar unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. 5209f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky unsigned BinaryPrecedence = 30; 5219f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5229f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky switch (CurTok) { 5239f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky default: 5249f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ErrorP("Expected function name in prototype"); 5259f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case tok_identifier: 5269f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky FnName = IdentifierStr; 5279f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Kind = 0; 5289f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 5299f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky break; 5309f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case tok_unary: 5319f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 5329f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (!isascii(CurTok)) 5339f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ErrorP("Expected unary operator"); 5349f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky FnName = "unary"; 5359f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky FnName += (char)CurTok; 5369f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Kind = 1; 5379f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 5389f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky break; 5399f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case tok_binary: 5409f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 5419f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (!isascii(CurTok)) 5429f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ErrorP("Expected binary operator"); 5439f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky FnName = "binary"; 5449f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky FnName += (char)CurTok; 5459f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Kind = 2; 5469f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 5479f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5489f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Read the precedence if present. 5499f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok == tok_number) { 5509f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (NumVal < 1 || NumVal > 100) 5519f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ErrorP("Invalid precedecnce: must be 1..100"); 5529f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky BinaryPrecedence = (unsigned)NumVal; 5539f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 5549f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 5559f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky break; 5569f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 5579f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5589f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != '(') 5599f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ErrorP("Expected '(' in prototype"); 5609f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5619f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::vector<std::string> ArgNames; 5629f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky while (getNextToken() == tok_identifier) 5639f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ArgNames.push_back(IdentifierStr); 5649f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CurTok != ')') 5659f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ErrorP("Expected ')' in prototype"); 5669f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5679f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // success. 5689f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat ')'. 5699f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5709f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Verify right number of names for operator. 5719f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Kind && ArgNames.size() != Kind) 5729f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ErrorP("Invalid number of operands for operator"); 5739f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5749f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return new PrototypeAST(FnName, ArgNames, Kind != 0, BinaryPrecedence); 5759f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 5769f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5779f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// definition ::= 'def' prototype expression 5789f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic FunctionAST *ParseDefinition() { 5799f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat def. 5809f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky PrototypeAST *Proto = ParsePrototype(); 5819f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Proto == 0) return 0; 5829f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5839f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (ExprAST *E = ParseExpression()) 5849f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return new FunctionAST(Proto, E); 5859f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return 0; 5869f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 5879f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5889f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// toplevelexpr ::= expression 5899f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic FunctionAST *ParseTopLevelExpr() { 5909f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (ExprAST *E = ParseExpression()) { 5919f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Make an anonymous proto. 5929f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); 5939f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return new FunctionAST(Proto, E); 5949f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 5959f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return 0; 5969f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 5979f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 5989f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// external ::= 'extern' prototype 5999f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic PrototypeAST *ParseExtern() { 6009f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); // eat extern. 6019f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ParsePrototype(); 6029f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 6039f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6049f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 6059f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky// Code Generation 6069f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 6079f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6089f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic Module *TheModule; 609d1fbd142945f5ef0c273c3d756431f8cb9d25dedOwen Andersonstatic IRBuilder<> Builder(getGlobalContext()); 6109f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic std::map<std::string, AllocaInst*> NamedValues; 6119f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic FunctionPassManager *TheFPM; 6129f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6139f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyValue *ErrorV(const char *Str) { Error(Str); return 0; } 6149f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6159f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of 6169f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// the function. This is used for mutable variables etc. 6179f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, 6189f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky const std::string &VarName) { 6199f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky IRBuilder<> TmpB(&TheFunction->getEntryBlock(), 6209f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky TheFunction->getEntryBlock().begin()); 6211d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0, 6221d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson VarName.c_str()); 6239f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 6249f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6259f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyValue *NumberExprAST::Codegen() { 6266f83c9c6ef0e7f79825a0a8f22941815e4b684c7Owen Anderson return ConstantFP::get(getGlobalContext(), APFloat(Val)); 6279f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 6289f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6299f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyValue *VariableExprAST::Codegen() { 6309f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Look this variable up in the function. 6319f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *V = NamedValues[Name]; 6329f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (V == 0) return ErrorV("Unknown variable name"); 6339f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6349f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Load the value. 6359f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Builder.CreateLoad(V, Name.c_str()); 6369f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 6379f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6389f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyValue *UnaryExprAST::Codegen() { 6399f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *OperandV = Operand->Codegen(); 6409f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (OperandV == 0) return 0; 6419f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6429f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Function *F = TheModule->getFunction(std::string("unary")+Opcode); 6439f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (F == 0) 6449f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ErrorV("Unknown unary operator"); 6459f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6469f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Builder.CreateCall(F, OperandV, "unop"); 6479f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 6489f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6499f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyValue *BinaryExprAST::Codegen() { 6509f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Special case '=' because we don't want to emit the LHS as an expression. 6519f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Op == '=') { 6529f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Assignment requires the LHS to be an identifier. 6539f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky VariableExprAST *LHSE = dynamic_cast<VariableExprAST*>(LHS); 6549f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (!LHSE) 6559f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ErrorV("destination of '=' must be a variable"); 6569f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Codegen the RHS. 6579f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *Val = RHS->Codegen(); 6589f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Val == 0) return 0; 6599f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6609f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Look up the name. 6619f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *Variable = NamedValues[LHSE->getName()]; 6629f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Variable == 0) return ErrorV("Unknown variable name"); 6639f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6649f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.CreateStore(Val, Variable); 6659f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return Val; 6669f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 6679f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6689f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *L = LHS->Codegen(); 6699f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *R = RHS->Codegen(); 6709f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (L == 0 || R == 0) return 0; 6719f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6729f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky switch (Op) { 6732632bbf0de4637e02f333952991263d526976fafEric Christopher case '+': return Builder.CreateFAdd(L, R, "addtmp"); 6742632bbf0de4637e02f333952991263d526976fafEric Christopher case '-': return Builder.CreateFSub(L, R, "subtmp"); 6752632bbf0de4637e02f333952991263d526976fafEric Christopher case '*': return Builder.CreateFMul(L, R, "multmp"); 6769f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case '<': 6779f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky L = Builder.CreateFCmpULT(L, R, "cmptmp"); 6789f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Convert bool 0/1 to double 0.0 or 1.0 6791d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), 6801d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson "booltmp"); 6819f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky default: break; 6829f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 6839f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6849f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // If it wasn't a builtin binary operator, it must be a user defined one. Emit 6859f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // a call to it. 6869f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Function *F = TheModule->getFunction(std::string("binary")+Op); 6879f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky assert(F && "binary operator not found!"); 6889f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6899f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *Ops[] = { L, R }; 6900bd9d3af54b62152355525bea7914bdef4600371Francois Pichet return Builder.CreateCall(F, Ops, "binop"); 6919f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 6929f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6939f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyValue *CallExprAST::Codegen() { 6949f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Look up the name in the global module table. 6959f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Function *CalleeF = TheModule->getFunction(Callee); 6969f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CalleeF == 0) 6979f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ErrorV("Unknown function referenced"); 6989f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 6999f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // If argument mismatch error. 7009f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CalleeF->arg_size() != Args.size()) 7019f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return ErrorV("Incorrect # arguments passed"); 7029f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7039f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::vector<Value*> ArgsV; 7049f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky for (unsigned i = 0, e = Args.size(); i != e; ++i) { 7059f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ArgsV.push_back(Args[i]->Codegen()); 7069f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (ArgsV.back() == 0) return 0; 7079f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 7089f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7090bd9d3af54b62152355525bea7914bdef4600371Francois Pichet return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); 7109f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 7119f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7129f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyValue *IfExprAST::Codegen() { 7139f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *CondV = Cond->Codegen(); 7149f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (CondV == 0) return 0; 7159f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7169f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Convert condition to a bool by comparing equal to 0.0. 7179f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky CondV = Builder.CreateFCmpONE(CondV, 7186f83c9c6ef0e7f79825a0a8f22941815e4b684c7Owen Anderson ConstantFP::get(getGlobalContext(), APFloat(0.0)), 7199f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky "ifcond"); 7209f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7219f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Function *TheFunction = Builder.GetInsertBlock()->getParent(); 7229f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7239f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Create blocks for the then and else cases. Insert the 'then' block at the 7249f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // end of the function. 7251d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *ThenBB = BasicBlock::Create(getGlobalContext(), "then", TheFunction); 7261d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else"); 7271d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont"); 7289f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7299f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.CreateCondBr(CondV, ThenBB, ElseBB); 7309f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7319f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Emit then value. 7329f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.SetInsertPoint(ThenBB); 7339f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7349f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *ThenV = Then->Codegen(); 7359f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (ThenV == 0) return 0; 7369f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7379f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.CreateBr(MergeBB); 7389f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Codegen of 'Then' can change the current block, update ThenBB for the PHI. 7399f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ThenBB = Builder.GetInsertBlock(); 7409f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7419f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Emit else block. 7429f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky TheFunction->getBasicBlockList().push_back(ElseBB); 7439f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.SetInsertPoint(ElseBB); 7449f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7459f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *ElseV = Else->Codegen(); 7469f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (ElseV == 0) return 0; 7479f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7489f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.CreateBr(MergeBB); 7499f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Codegen of 'Else' can change the current block, update ElseBB for the PHI. 7509f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ElseBB = Builder.GetInsertBlock(); 7519f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7529f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Emit merge block. 7539f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky TheFunction->getBasicBlockList().push_back(MergeBB); 7549f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.SetInsertPoint(MergeBB); 7553ecfc861b4365f341c5c969b40e1afccde676e6fJay Foad PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, 7561d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson "iftmp"); 7579f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7589f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky PN->addIncoming(ThenV, ThenBB); 7599f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky PN->addIncoming(ElseV, ElseBB); 7609f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return PN; 7619f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 7629f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7639f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyValue *ForExprAST::Codegen() { 7649f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Output this as: 7659f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // var = alloca double 7669f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // ... 7679f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // start = startexpr 7689f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // store start -> var 7699f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // goto loop 7709f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // loop: 7719f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // ... 7729f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // bodyexpr 7739f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // ... 7749f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // loopend: 7759f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // step = stepexpr 7769f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // endcond = endexpr 7779f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // 7789f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // curvar = load var 7799f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // nextvar = curvar + step 7809f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // store nextvar -> var 7819f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // br endcond, loop, endloop 7829f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // outloop: 7839f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7849f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Function *TheFunction = Builder.GetInsertBlock()->getParent(); 7859f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7869f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Create an alloca for the variable in the entry block. 7879f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); 7889f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7899f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Emit the start code first, without 'variable' in scope. 7909f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *StartVal = Start->Codegen(); 7919f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (StartVal == 0) return 0; 7929f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7939f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Store the value into the alloca. 7949f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.CreateStore(StartVal, Alloca); 7959f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 7969f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Make the new basic block for the loop header, inserting after current 7979f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // block. 7981d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction); 7999f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8009f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Insert an explicit fall through from the current block to the LoopBB. 8019f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.CreateBr(LoopBB); 8029f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8039f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Start insertion in LoopBB. 8049f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.SetInsertPoint(LoopBB); 8059f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8069f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Within the loop, the variable is defined equal to the PHI node. If it 8079f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // shadows an existing variable, we have to restore it, so save it now. 8089f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky AllocaInst *OldVal = NamedValues[VarName]; 8099f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky NamedValues[VarName] = Alloca; 8109f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8119f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Emit the body of the loop. This, like any other expr, can change the 8129f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // current BB. Note that we ignore the value computed by the body, but don't 8139f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // allow an error. 8149f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Body->Codegen() == 0) 8159f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return 0; 8169f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8179f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Emit the step value. 8189f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *StepVal; 8199f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Step) { 8209f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky StepVal = Step->Codegen(); 8219f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (StepVal == 0) return 0; 8229f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } else { 8239f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // If not specified, use 1.0. 8246f83c9c6ef0e7f79825a0a8f22941815e4b684c7Owen Anderson StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0)); 8259f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 8269f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8279f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Compute the end condition. 8289f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *EndCond = End->Codegen(); 8299f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (EndCond == 0) return EndCond; 8309f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8319f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Reload, increment, and restore the alloca. This handles the case where 8329f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // the body of the loop mutates the variable. 8339f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str()); 834b0e9eada32faf9218352f0893841e6839e1c586cChris Lattner Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar"); 8359f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.CreateStore(NextVar, Alloca); 8369f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8379f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Convert condition to a bool by comparing equal to 0.0. 8389f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky EndCond = Builder.CreateFCmpONE(EndCond, 8396f83c9c6ef0e7f79825a0a8f22941815e4b684c7Owen Anderson ConstantFP::get(getGlobalContext(), APFloat(0.0)), 8409f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky "loopcond"); 8419f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8429f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Create the "after loop" block and insert it. 8431d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction); 8449f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8459f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Insert the conditional branch into the end of LoopEndBB. 8469f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.CreateCondBr(EndCond, LoopBB, AfterBB); 8479f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8489f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Any new code will be inserted in AfterBB. 8499f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.SetInsertPoint(AfterBB); 8509f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8519f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Restore the unshadowed variable. 8529f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (OldVal) 8539f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky NamedValues[VarName] = OldVal; 8549f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky else 8559f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky NamedValues.erase(VarName); 8569f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8579f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8589f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // for expr always returns 0.0. 8591d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson return Constant::getNullValue(Type::getDoubleTy(getGlobalContext())); 8609f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 8619f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8629f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyValue *VarExprAST::Codegen() { 8639f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky std::vector<AllocaInst *> OldBindings; 8649f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8659f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Function *TheFunction = Builder.GetInsertBlock()->getParent(); 8669f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8679f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Register all variables and emit their initializer. 8689f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky for (unsigned i = 0, e = VarNames.size(); i != e; ++i) { 8699f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky const std::string &VarName = VarNames[i].first; 8709f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ExprAST *Init = VarNames[i].second; 8719f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8729f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Emit the initializer before adding the variable to scope, this prevents 8739f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // the initializer from referencing the variable itself, and permits stuff 8749f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // like this: 8759f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // var a = 1 in 8769f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // var a = a in ... # refers to outer 'a'. 8779f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *InitVal; 8789f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Init) { 8799f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky InitVal = Init->Codegen(); 8809f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (InitVal == 0) return 0; 8819f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } else { // If not specified, use 0.0. 8826f83c9c6ef0e7f79825a0a8f22941815e4b684c7Owen Anderson InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0)); 8839f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 8849f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8859f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); 8869f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.CreateStore(InitVal, Alloca); 8879f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8889f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Remember the old variable binding so that we can restore the binding when 8899f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // we unrecurse. 8909f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky OldBindings.push_back(NamedValues[VarName]); 8919f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8929f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Remember this binding. 8939f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky NamedValues[VarName] = Alloca; 8949f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 8959f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 8969f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Codegen the body, now that all vars are in scope. 8979f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Value *BodyVal = Body->Codegen(); 8989f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (BodyVal == 0) return 0; 8999f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9009f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Pop all our variables from scope. 9019f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky for (unsigned i = 0, e = VarNames.size(); i != e; ++i) 9029f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky NamedValues[VarNames[i].first] = OldBindings[i]; 9039f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9049f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Return the body computation. 9059f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return BodyVal; 9069f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 9079f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9089f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyFunction *PrototypeAST::Codegen() { 9099f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Make the function type: double(double,double) etc. 910d1c2bd8e6e37e08393f7c4980efc5bcb66b6f0d0John Wiegley std::vector<Type*> Doubles(Args.size(), 911d1c2bd8e6e37e08393f7c4980efc5bcb66b6f0d0John Wiegley Type::getDoubleTy(getGlobalContext())); 9121d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), 9131d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Doubles, false); 9149f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9159f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule); 9169f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9179f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // If F conflicted, there was already something named 'Name'. If it has a 9189f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // body, don't allow redefinition or reextern. 9199f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (F->getName() != Name) { 9209f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Delete the one we just made and get the existing one. 9219f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky F->eraseFromParent(); 9229f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky F = TheModule->getFunction(Name); 9239f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9249f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // If F already has a body, reject this. 9259f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (!F->empty()) { 9269f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ErrorF("redefinition of function"); 9279f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return 0; 9289f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 9299f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9309f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // If F took a different number of args, reject. 9319f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (F->arg_size() != Args.size()) { 9329f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ErrorF("redefinition of function with different # args"); 9339f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return 0; 9349f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 9359f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 9369f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9379f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Set names for all arguments. 9389f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky unsigned Idx = 0; 9399f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); 9409f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky ++AI, ++Idx) 9419f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky AI->setName(Args[Idx]); 9429f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9439f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return F; 9449f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 9459f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9469f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// CreateArgumentAllocas - Create an alloca for each argument and register the 9479f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// argument in the symbol table so that references to it will succeed. 9489f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyvoid PrototypeAST::CreateArgumentAllocas(Function *F) { 9499f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Function::arg_iterator AI = F->arg_begin(); 9509f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) { 9519f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Create an alloca for this variable. 9529f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]); 9539f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9549f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Store the initial value into the alloca. 9559f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.CreateStore(AI, Alloca); 9569f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9579f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Add arguments to variable symbol table. 9589f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky NamedValues[Args[Idx]] = Alloca; 9599f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 9609f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 9619f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9629f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick LewyckyFunction *FunctionAST::Codegen() { 9639f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky NamedValues.clear(); 9649f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9659f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Function *TheFunction = Proto->Codegen(); 9669f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (TheFunction == 0) 9679f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return 0; 9689f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9699f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // If this is an operator, install it. 9709f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Proto->isBinaryOp()) 9719f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence(); 9729f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9739f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Create a new basic block to start insertion into. 9741d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); 9759f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.SetInsertPoint(BB); 9769f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9779f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Add all arguments to the symbol table and create their allocas. 9789f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Proto->CreateArgumentAllocas(TheFunction); 979fd1ec5e68b593a4f4d5497b150e677ebef36c231Erick Tryzelaar 9809f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Value *RetVal = Body->Codegen()) { 9819f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Finish off the function. 9829f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky Builder.CreateRet(RetVal); 9839f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9849f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Validate the generated code, checking for consistency. 9859f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky verifyFunction(*TheFunction); 9869f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9879f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Optimize the function. 9889f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky TheFPM->run(*TheFunction); 9899f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9909f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return TheFunction; 9919f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 9929f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9939f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Error reading body, remove function. 9949f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky TheFunction->eraseFromParent(); 9959f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 9969f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Proto->isBinaryOp()) 9979f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky BinopPrecedence.erase(Proto->getOperatorName()); 9989f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return 0; 9999f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 10009f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10019f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 10029f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky// Top-Level parsing and JIT Driver 10039f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 10049f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10059f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic ExecutionEngine *TheExecutionEngine; 10069f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10079f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic void HandleDefinition() { 10089f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (FunctionAST *F = ParseDefinition()) { 10099f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Function *LF = F->Codegen()) { 10109f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky fprintf(stderr, "Read function definition:"); 10119f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky LF->dump(); 10129f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 10139f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } else { 10149f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Skip token for error recovery. 10159f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 10169f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 10179f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 10189f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10199f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic void HandleExtern() { 10209f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (PrototypeAST *P = ParseExtern()) { 10219f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Function *F = P->Codegen()) { 10229f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky fprintf(stderr, "Read extern: "); 10239f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky F->dump(); 10249f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 10259f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } else { 10269f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Skip token for error recovery. 10279f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 10289f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 10299f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 10309f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10319f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic void HandleTopLevelExpression() { 1032fd1ec5e68b593a4f4d5497b150e677ebef36c231Erick Tryzelaar // Evaluate a top-level expression into an anonymous function. 10339f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (FunctionAST *F = ParseTopLevelExpr()) { 10349f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky if (Function *LF = F->Codegen()) { 10359f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // JIT the function, returning a function pointer. 10369f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky void *FPtr = TheExecutionEngine->getPointerToFunction(LF); 10379f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10389f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Cast it to the right type (takes no arguments, returns a double) so we 10399f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // can call it as a native function. 1040d25bff6d528e86683f7c3aed1b630776c33a3c71Chris Lattner double (*FP)() = (double (*)())(intptr_t)FPtr; 10419f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky fprintf(stderr, "Evaluated to %f\n", FP()); 10429f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 10439f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } else { 10449f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Skip token for error recovery. 10459f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 10469f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 10479f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 10489f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10499f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// top ::= definition | external | expression | ';' 10509f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckystatic void MainLoop() { 10519f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky while (1) { 10529f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky fprintf(stderr, "ready> "); 10539f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky switch (CurTok) { 10549f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case tok_eof: return; 1055fd1ec5e68b593a4f4d5497b150e677ebef36c231Erick Tryzelaar case ';': getNextToken(); break; // ignore top-level semicolons. 10569f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case tok_def: HandleDefinition(); break; 10579f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky case tok_extern: HandleExtern(); break; 10589f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky default: HandleTopLevelExpression(); break; 10599f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 10609f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky } 10619f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 10629f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10639f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 10649f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky// "Library" functions that can be "extern'd" from user code. 10659f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 10669f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10679f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// putchard - putchar that takes a double and returns 0. 10689f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyextern "C" 10699f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckydouble putchard(double X) { 10709f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky putchar((char)X); 10719f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return 0; 10729f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 10739f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10749f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky/// printd - printf that takes a double prints it as "%f\n", returning 0. 10759f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyextern "C" 10769f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckydouble printd(double X) { 10779f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky printf("%f\n", X); 10789f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return 0; 10799f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 10809f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10819f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 10829f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky// Main driver code. 10839f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky//===----------------------------------------------------------------------===// 10849f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10859f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewyckyint main() { 1086da06288aeb28393b937e17dcd180658c3737a6e5Chris Lattner InitializeNativeTarget(); 1087914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson LLVMContext &Context = getGlobalContext(); 1088fd1ec5e68b593a4f4d5497b150e677ebef36c231Erick Tryzelaar 10899f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Install standard binary operators. 10909f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // 1 is lowest precedence. 10919f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky BinopPrecedence['='] = 2; 10929f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky BinopPrecedence['<'] = 10; 10939f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky BinopPrecedence['+'] = 20; 10949f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky BinopPrecedence['-'] = 20; 10959f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky BinopPrecedence['*'] = 40; // highest. 10969f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 10979f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Prime the first token. 10989f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky fprintf(stderr, "ready> "); 10999f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky getNextToken(); 11009f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 11019f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky // Make the module, which holds all the code. 110231895e73591d3c9ceae731a1274c8f56194b9616Owen Anderson TheModule = new Module("my cool jit", Context); 11039f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky 1104f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin // Create the JIT. This takes ownership of the module. 110542fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin std::string ErrStr; 110642fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create(); 110742fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin if (!TheExecutionEngine) { 110842fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); 110942fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin exit(1); 111042fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin } 11119e6f3f2f14d46cfd12e01221a6f3229852001e40Reid Kleckner 1112f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin FunctionPassManager OurFPM(TheModule); 111360130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner 111460130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner // Set up the optimizer pipeline. Start with registering info about how the 111560130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner // target lays out data structures. 11162b4b44e0d2e95fc695eafcc4d192fe1ae261e01eMicah Villmow OurFPM.add(new DataLayout(*TheExecutionEngine->getDataLayout())); 1117dfa1a79b0c2f09349b6cd451198781a3ced48cb8Dan Gohman // Provide basic AliasAnalysis support for GVN. 1118dfa1a79b0c2f09349b6cd451198781a3ced48cb8Dan Gohman OurFPM.add(createBasicAliasAnalysisPass()); 111960130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner // Promote allocas to registers. 112060130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner OurFPM.add(createPromoteMemoryToRegisterPass()); 112160130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner // Do simple "peephole" optimizations and bit-twiddling optzns. 112260130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner OurFPM.add(createInstructionCombiningPass()); 112360130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner // Reassociate expressions. 112460130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner OurFPM.add(createReassociatePass()); 112560130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner // Eliminate Common SubExpressions. 112660130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner OurFPM.add(createGVNPass()); 112760130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner // Simplify the control flow graph (deleting unreachable blocks, etc). 112860130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner OurFPM.add(createCFGSimplificationPass()); 112960130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner 113060130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner OurFPM.doInitialization(); 113160130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner 113260130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner // Set the global so the code gen can use this. 113360130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner TheFPM = &OurFPM; 113460130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner 113560130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner // Run the main "interpreter loop" now. 113660130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner MainLoop(); 113760130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner 113860130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner TheFPM = 0; 113960130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner 114060130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner // Print out all of the generated code. 114160130f0e90d69dc3022878bfe4508dae81f911ebReid Kleckner TheModule->dump(); 11429e6f3f2f14d46cfd12e01221a6f3229852001e40Reid Kleckner 11439f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky return 0; 11449f85634bd2fccd2f366b7ce9048f6c9f95ebba18Nick Lewycky} 1145