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