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