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