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