14c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ADT/STLExtras.h" 2ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/ADT/Triple.h" 3ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Analysis/Passes.h" 4ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/ExecutionEngine/ExecutionEngine.h" 5ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/ExecutionEngine/MCJIT.h" 6ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/ExecutionEngine/SectionMemoryManager.h" 7ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/DIBuilder.h" 8ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/DataLayout.h" 9ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/DerivedTypes.h" 10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/IRBuilder.h" 11ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/LLVMContext.h" 12ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/LegacyPassManager.h" 13ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/Module.h" 14ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/Verifier.h" 15ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/Host.h" 16ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/TargetSelect.h" 17ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Transforms/Scalar.h" 18ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include <cctype> 19ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include <cstdio> 20ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include <iostream> 21ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include <map> 22ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include <string> 23ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include <vector> 24ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesusing namespace llvm; 25ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 26ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 27ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Lexer 28ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 29ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 30ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// The lexer returns tokens [0-255] if it is an unknown character, otherwise one 31ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// of these for known things. 32ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesenum Token { 33ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_eof = -1, 34ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 35ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // commands 36ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_def = -2, 37ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_extern = -3, 38ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 39ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // primary 40ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_identifier = -4, 41ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_number = -5, 42ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 43ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // control 44ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_if = -6, 45ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_then = -7, 46ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_else = -8, 47ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_for = -9, 48ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_in = -10, 49ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 50ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // operators 51ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_binary = -11, 52ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_unary = -12, 53ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 54ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // var definition 55ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tok_var = -13 56ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 57ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 58ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstd::string getTokName(int Tok) { 59ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines switch (Tok) { 60ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_eof: 61ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "eof"; 62ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_def: 63ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "def"; 64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_extern: 65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "extern"; 66ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_identifier: 67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "identifier"; 68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_number: 69ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "number"; 70ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_if: 71ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "if"; 72ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_then: 73ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "then"; 74ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_else: 75ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "else"; 76ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_for: 77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "for"; 78ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_in: 79ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "in"; 80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_binary: 81ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "binary"; 82ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_unary: 83ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "unary"; 84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_var: 85ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return "var"; 86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return std::string(1, (char)Tok); 88ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 89ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 90ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace { 91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass PrototypeAST; 92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass ExprAST; 93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 94ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic IRBuilder<> Builder(getGlobalContext()); 95ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstruct DebugInfo { 96ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DICompileUnit TheCU; 97ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DIType DblTy; 98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<DIScope *> LexicalBlocks; 99ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::map<const PrototypeAST *, DIScope> FnScopeMap; 100ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void emitLocation(ExprAST *AST); 102ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DIType getDoubleTy(); 103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} KSDbgInfo; 104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic std::string IdentifierStr; // Filled in if tok_identifier 106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic double NumVal; // Filled in if tok_number 107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstruct SourceLocation { 108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int Line; 109ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int Col; 110ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 111ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic SourceLocation CurLoc; 112ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic SourceLocation LexLoc = { 1, 0 }; 113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic int advance() { 115ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int LastChar = getchar(); 116ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (LastChar == '\n' || LastChar == '\r') { 118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LexLoc.Line++; 119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LexLoc.Col = 0; 120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else 121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LexLoc.Col++; 122ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return LastChar; 123ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 124ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// gettok - Return the next token from standard input. 126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic int gettok() { 127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines static int LastChar = ' '; 128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Skip any whitespace. 130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (isspace(LastChar)) 131ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LastChar = advance(); 132ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 133ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CurLoc = LexLoc; 134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]* 136ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IdentifierStr = LastChar; 137ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (isalnum((LastChar = advance()))) 138ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IdentifierStr += LastChar; 139ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 140ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (IdentifierStr == "def") 141ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_def; 142ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (IdentifierStr == "extern") 143ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_extern; 144ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (IdentifierStr == "if") 145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_if; 146ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (IdentifierStr == "then") 147ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_then; 148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (IdentifierStr == "else") 149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_else; 150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (IdentifierStr == "for") 151ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_for; 152ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (IdentifierStr == "in") 153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_in; 154ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (IdentifierStr == "binary") 155ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_binary; 156ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (IdentifierStr == "unary") 157ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_unary; 158ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (IdentifierStr == "var") 159ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_var; 160ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_identifier; 161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 163ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ 164ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string NumStr; 165ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines do { 166ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NumStr += LastChar; 167ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LastChar = advance(); 168ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } while (isdigit(LastChar) || LastChar == '.'); 169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 170ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NumVal = strtod(NumStr.c_str(), 0); 171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_number; 172ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 173ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 174ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (LastChar == '#') { 175ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Comment until end of line. 176ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines do 177ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LastChar = advance(); 178ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); 179ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 180ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (LastChar != EOF) 181ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return gettok(); 182ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 183ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 184ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Check for end of file. Don't eat the EOF. 185ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (LastChar == EOF) 186ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return tok_eof; 187ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 188ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Otherwise, just return the character as its ascii value. 189ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int ThisChar = LastChar; 190ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LastChar = advance(); 191ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ThisChar; 192ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 193ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 194ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Abstract Syntax Tree (aka Parse Tree) 196ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace { 198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstd::ostream &indent(std::ostream &O, int size) { 200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return O << std::string(size, ' '); 201ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 202ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 203ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ExprAST - Base class for all expression nodes. 204ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass ExprAST { 205ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SourceLocation Loc; 206ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 207ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 208ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int getLine() const { return Loc.Line; } 209ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int getCol() const { return Loc.Col; } 210ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {} 211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines virtual std::ostream &dump(std::ostream &out, int ind) { 212ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return out << ':' << getLine() << ':' << getCol() << '\n'; 213ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines virtual ~ExprAST() {} 215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines virtual Value *Codegen() = 0; 216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 217ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 218ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// NumberExprAST - Expression class for numeric literals like "1.0". 219ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass NumberExprAST : public ExprAST { 220ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines double Val; 221ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 222ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 223ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NumberExprAST(double val) : Val(val) {} 2242c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar std::ostream &dump(std::ostream &out, int ind) override { 225ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ExprAST::dump(out << Val, ind); 226ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2272c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar Value *Codegen() override; 228ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 229ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 230ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// VariableExprAST - Expression class for referencing a variable, like "a". 231ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass VariableExprAST : public ExprAST { 232ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string Name; 233ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 234ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 235ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines VariableExprAST(SourceLocation Loc, const std::string &name) 236ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : ExprAST(Loc), Name(name) {} 237ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const std::string &getName() const { return Name; } 2382c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar std::ostream &dump(std::ostream &out, int ind) override { 239ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ExprAST::dump(out << Name, ind); 240ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2412c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar Value *Codegen() override; 242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 244ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// UnaryExprAST - Expression class for a unary operator. 245ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass UnaryExprAST : public ExprAST { 246ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines char Opcode; 247ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Operand; 248ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 249ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 250ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines UnaryExprAST(char opcode, ExprAST *operand) 251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : Opcode(opcode), Operand(operand) {} 2522c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar std::ostream &dump(std::ostream &out, int ind) override { 253ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST::dump(out << "unary" << Opcode, ind); 254ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Operand->dump(out, ind + 1); 255ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return out; 256ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2572c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar Value *Codegen() override; 258ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 259ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 260ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// BinaryExprAST - Expression class for a binary operator. 261ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass BinaryExprAST : public ExprAST { 262ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines char Op; 263ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *LHS, *RHS; 264ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 265ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 266ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BinaryExprAST(SourceLocation Loc, char op, ExprAST *lhs, ExprAST *rhs) 267ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : ExprAST(Loc), Op(op), LHS(lhs), RHS(rhs) {} 2682c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar std::ostream &dump(std::ostream &out, int ind) override { 269ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST::dump(out << "binary" << Op, ind); 270ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LHS->dump(indent(out, ind) << "LHS:", ind + 1); 271ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines RHS->dump(indent(out, ind) << "RHS:", ind + 1); 272ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return out; 273ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2742c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar Value *Codegen() override; 275ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 276ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 277ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// CallExprAST - Expression class for function calls. 278ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass CallExprAST : public ExprAST { 279ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string Callee; 280ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<ExprAST *> Args; 281ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 282ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 283ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CallExprAST(SourceLocation Loc, const std::string &callee, 284ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<ExprAST *> &args) 285ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : ExprAST(Loc), Callee(callee), Args(args) {} 2862c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar std::ostream &dump(std::ostream &out, int ind) override { 287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST::dump(out << "call " << Callee, ind); 288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (ExprAST *Arg : Args) 289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Arg->dump(indent(out, ind + 1), ind + 1); 290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return out; 291ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2922c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar Value *Codegen() override; 293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 295ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// IfExprAST - Expression class for if/then/else. 296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass IfExprAST : public ExprAST { 297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Cond, *Then, *Else; 298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IfExprAST(SourceLocation Loc, ExprAST *cond, ExprAST *then, ExprAST *_else) 301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : ExprAST(Loc), Cond(cond), Then(then), Else(_else) {} 3022c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar std::ostream &dump(std::ostream &out, int ind) override { 303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST::dump(out << "if", ind); 304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Cond->dump(indent(out, ind) << "Cond:", ind + 1); 305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Then->dump(indent(out, ind) << "Then:", ind + 1); 306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Else->dump(indent(out, ind) << "Else:", ind + 1); 307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return out; 308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 3092c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar Value *Codegen() override; 310ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ForExprAST - Expression class for for/in. 313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass ForExprAST : public ExprAST { 314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string VarName; 315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Start, *End, *Step, *Body; 316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end, 319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *step, ExprAST *body) 320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : VarName(varname), Start(start), End(end), Step(step), Body(body) {} 3212c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar std::ostream &dump(std::ostream &out, int ind) override { 322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST::dump(out << "for", ind); 323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Start->dump(indent(out, ind) << "Cond:", ind + 1); 324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines End->dump(indent(out, ind) << "End:", ind + 1); 325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Step->dump(indent(out, ind) << "Step:", ind + 1); 326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Body->dump(indent(out, ind) << "Body:", ind + 1); 327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return out; 328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 3292c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar Value *Codegen() override; 330ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// VarExprAST - Expression class for var/in 333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass VarExprAST : public ExprAST { 334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<std::pair<std::string, ExprAST *> > VarNames; 335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Body; 336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 337ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 338ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines VarExprAST(const std::vector<std::pair<std::string, ExprAST *> > &varnames, 339ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *body) 340ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : VarNames(varnames), Body(body) {} 341ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 3422c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar std::ostream &dump(std::ostream &out, int ind) override { 343ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST::dump(out << "var", ind); 344ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (const auto &NamedVar : VarNames) 345ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NamedVar.second->dump(indent(out, ind) << NamedVar.first << ':', ind + 1); 346ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Body->dump(indent(out, ind) << "Body:", ind + 1); 347ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return out; 348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 3492c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar Value *Codegen() override; 350ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 351ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 352ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// PrototypeAST - This class represents the "prototype" for a function, 353ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// which captures its argument names as well as if it is an operator. 354ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass PrototypeAST { 355ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string Name; 356ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<std::string> Args; 357ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool isOperator; 358ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Precedence; // Precedence if a binary op. 359ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int Line; 360ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 361ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 362ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PrototypeAST(SourceLocation Loc, const std::string &name, 363ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const std::vector<std::string> &args, bool isoperator = false, 364ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned prec = 0) 365ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : Name(name), Args(args), isOperator(isoperator), Precedence(prec), 366ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Line(Loc.Line) {} 367ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 368ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool isUnaryOp() const { return isOperator && Args.size() == 1; } 369ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool isBinaryOp() const { return isOperator && Args.size() == 2; } 370ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 371ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines char getOperatorName() const { 372ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(isUnaryOp() || isBinaryOp()); 373ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Name[Name.size() - 1]; 374ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 375ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 376ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned getBinaryPrecedence() const { return Precedence; } 377ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 378ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *Codegen(); 379ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 380ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void CreateArgumentAllocas(Function *F); 381ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const std::vector<std::string> &getArgs() const { return Args; } 382ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 383ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 384ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// FunctionAST - This class represents a function definition itself. 385ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass FunctionAST { 386ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PrototypeAST *Proto; 387ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Body; 388ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 389ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 390ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {} 391ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 392ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::ostream &dump(std::ostream &out, int ind) { 393ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines indent(out, ind) << "FunctionAST\n"; 394ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ++ind; 395ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines indent(out, ind) << "Body:"; 396ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Body ? Body->dump(out, ind) : out << "null\n"; 397ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 398ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 399ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *Codegen(); 400ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 401ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} // end anonymous namespace 402ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 403ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 404ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Parser 405ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 406ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 407ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current 408ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// token the parser is looking at. getNextToken reads another token from the 409ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// lexer and updates CurTok with its results. 410ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic int CurTok; 411ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic int getNextToken() { return CurTok = gettok(); } 412ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 413ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// BinopPrecedence - This holds the precedence for each binary operator that is 414ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// defined. 415ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic std::map<char, int> BinopPrecedence; 416ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 417ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// GetTokPrecedence - Get the precedence of the pending binary operator token. 418ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic int GetTokPrecedence() { 419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!isascii(CurTok)) 420ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return -1; 421ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Make sure it's a declared binop. 423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int TokPrec = BinopPrecedence[CurTok]; 424ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (TokPrec <= 0) 425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return -1; 426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return TokPrec; 427ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 428ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 429ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Error* - These are little helper functions for error handling. 430ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesExprAST *Error(const char *Str) { 431ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines fprintf(stderr, "Error: %s\n", Str); 432ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 433ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 434ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesPrototypeAST *ErrorP(const char *Str) { 435ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Error(Str); 436ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 437ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 438ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesFunctionAST *ErrorF(const char *Str) { 439ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Error(Str); 440ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 441ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 442ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 443ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ExprAST *ParseExpression(); 444ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 445ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// identifierexpr 446ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= identifier 447ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= identifier '(' expression* ')' 448ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ExprAST *ParseIdentifierExpr() { 449ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string IdName = IdentifierStr; 450ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 451ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SourceLocation LitLoc = CurLoc; 452ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 453ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat identifier. 454ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 455ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != '(') // Simple variable ref. 456ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return new VariableExprAST(LitLoc, IdName); 457ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 458ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Call. 459ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat ( 460ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<ExprAST *> Args; 461ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != ')') { 462ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (1) { 463ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Arg = ParseExpression(); 464ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Arg) 465ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 466ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Args.push_back(Arg); 467ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 468ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok == ')') 469ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 470ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 471ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != ',') 472ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Error("Expected ')' or ',' in argument list"); 473ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 474ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 475ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 476ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 477ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Eat the ')'. 478ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 479ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 480ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return new CallExprAST(LitLoc, IdName, Args); 481ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 482ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 483ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// numberexpr ::= number 484ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ExprAST *ParseNumberExpr() { 485ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Result = new NumberExprAST(NumVal); 486ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // consume the number 487ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Result; 488ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 489ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 490ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// parenexpr ::= '(' expression ')' 491ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ExprAST *ParseParenExpr() { 492ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat (. 493ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *V = ParseExpression(); 494ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!V) 495ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 496ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 497ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != ')') 498ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Error("expected ')'"); 499ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat ). 500ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return V; 501ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 502ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 503ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ifexpr ::= 'if' expression 'then' expression 'else' expression 504ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ExprAST *ParseIfExpr() { 505ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SourceLocation IfLoc = CurLoc; 506ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 507ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat the if. 508ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 509ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // condition. 510ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Cond = ParseExpression(); 511ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Cond) 512ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 513ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 514ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != tok_then) 515ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Error("expected then"); 516ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat the then 517ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 518ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Then = ParseExpression(); 519ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Then == 0) 520ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 521ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 522ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != tok_else) 523ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Error("expected else"); 524ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 525ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 526ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 527ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Else = ParseExpression(); 528ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Else) 529ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 530ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 531ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return new IfExprAST(IfLoc, Cond, Then, Else); 532ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 533ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 534ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression 535ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ExprAST *ParseForExpr() { 536ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat the for. 537ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 538ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != tok_identifier) 539ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Error("expected identifier after for"); 540ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 541ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string IdName = IdentifierStr; 542ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat identifier. 543ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 544ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != '=') 545ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Error("expected '=' after for"); 546ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat '='. 547ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 548ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Start = ParseExpression(); 549ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Start == 0) 550ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 551ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != ',') 552ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Error("expected ',' after for start value"); 553ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 554ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 555ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *End = ParseExpression(); 556ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (End == 0) 557ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 558ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 559ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // The step value is optional. 560ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Step = 0; 561ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok == ',') { 562ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 563ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Step = ParseExpression(); 564ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Step == 0) 565ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 566ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 567ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 568ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != tok_in) 569ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Error("expected 'in' after for"); 570ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat 'in'. 571ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 572ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Body = ParseExpression(); 573ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Body == 0) 574ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 575ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 576ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return new ForExprAST(IdName, Start, End, Step, Body); 577ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 578ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 579ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// varexpr ::= 'var' identifier ('=' expression)? 580ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// (',' identifier ('=' expression)?)* 'in' expression 581ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ExprAST *ParseVarExpr() { 582ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat the var. 583ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 584ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<std::pair<std::string, ExprAST *> > VarNames; 585ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 586ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // At least one variable name is required. 587ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != tok_identifier) 588ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Error("expected identifier after var"); 589ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 590ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (1) { 591ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string Name = IdentifierStr; 592ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat identifier. 593ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 594ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Read the optional initializer. 595ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Init = 0; 596ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok == '=') { 597ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat the '='. 598ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 599ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Init = ParseExpression(); 600ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Init == 0) 601ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 602ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 603ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 604ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines VarNames.push_back(std::make_pair(Name, Init)); 605ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 606ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // End of var list, exit loop. 607ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != ',') 608ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 609ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat the ','. 610ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 611ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != tok_identifier) 612ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Error("expected identifier list after var"); 613ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 614ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 615ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // At this point, we have to have 'in'. 616ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != tok_in) 617ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Error("expected 'in' keyword after 'var'"); 618ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat 'in'. 619ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 620ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Body = ParseExpression(); 621ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Body == 0) 622ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 623ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 624ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return new VarExprAST(VarNames, Body); 625ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 626ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 627ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// primary 628ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= identifierexpr 629ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= numberexpr 630ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= parenexpr 631ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= ifexpr 632ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= forexpr 633ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= varexpr 634ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ExprAST *ParsePrimary() { 635ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines switch (CurTok) { 636ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines default: 637ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Error("unknown token when expecting an expression"); 638ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_identifier: 639ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ParseIdentifierExpr(); 640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_number: 641ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ParseNumberExpr(); 642ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case '(': 643ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ParseParenExpr(); 644ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_if: 645ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ParseIfExpr(); 646ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_for: 647ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ParseForExpr(); 648ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_var: 649ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ParseVarExpr(); 650ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 651ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 652ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 653ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// unary 654ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= primary 655ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= '!' unary 656ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ExprAST *ParseUnary() { 657ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If the current token is not an operator, it must be a primary expr. 658ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!isascii(CurTok) || CurTok == '(' || CurTok == ',') 659ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ParsePrimary(); 660ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 661ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If this is a unary operator, read it. 662ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int Opc = CurTok; 663ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 664ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ExprAST *Operand = ParseUnary()) 665ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return new UnaryExprAST(Opc, Operand); 666ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 667ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 668ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 669ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// binoprhs 670ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= ('+' unary)* 671ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { 672ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If this is a binop, find its precedence. 673ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (1) { 674ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int TokPrec = GetTokPrecedence(); 675ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 676ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If this is a binop that binds at least as tightly as the current binop, 677ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // consume it, otherwise we are done. 678ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (TokPrec < ExprPrec) 679ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return LHS; 680ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 681ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Okay, we know this is a binop. 682ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int BinOp = CurTok; 683ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SourceLocation BinLoc = CurLoc; 684ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat binop 685ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 686ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Parse the unary expression after the binary operator. 687ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *RHS = ParseUnary(); 688ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!RHS) 689ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 690ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 691ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If BinOp binds less tightly with RHS than the operator after RHS, let 692ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // the pending operator take RHS as its LHS. 693ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int NextPrec = GetTokPrecedence(); 694ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (TokPrec < NextPrec) { 695ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines RHS = ParseBinOpRHS(TokPrec + 1, RHS); 696ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (RHS == 0) 697ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 698ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 699ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 700ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Merge LHS/RHS. 701ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LHS = new BinaryExprAST(BinLoc, BinOp, LHS, RHS); 702ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 703ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 704ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 705ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// expression 706ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= unary binoprhs 707ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 708ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ExprAST *ParseExpression() { 709ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *LHS = ParseUnary(); 710ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!LHS) 711ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 712ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 713ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ParseBinOpRHS(0, LHS); 714ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 715ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 716ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// prototype 717ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= id '(' id* ')' 718ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= binary LETTER number? (id, id) 719ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ::= unary LETTER (id) 720ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic PrototypeAST *ParsePrototype() { 721ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string FnName; 722ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 723ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SourceLocation FnLoc = CurLoc; 724ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 725ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. 726ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned BinaryPrecedence = 30; 727ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 728ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines switch (CurTok) { 729ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines default: 730ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorP("Expected function name in prototype"); 731ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_identifier: 732ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FnName = IdentifierStr; 733ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Kind = 0; 734ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 735ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 736ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_unary: 737ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 738ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!isascii(CurTok)) 739ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorP("Expected unary operator"); 740ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FnName = "unary"; 741ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FnName += (char)CurTok; 742ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Kind = 1; 743ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 744ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 745ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_binary: 746ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 747ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!isascii(CurTok)) 748ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorP("Expected binary operator"); 749ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FnName = "binary"; 750ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FnName += (char)CurTok; 751ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Kind = 2; 752ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 753ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 754ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Read the precedence if present. 755ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok == tok_number) { 756ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (NumVal < 1 || NumVal > 100) 757ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorP("Invalid precedecnce: must be 1..100"); 758ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BinaryPrecedence = (unsigned)NumVal; 759ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 760ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 761ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 762ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 763ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 764ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != '(') 765ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorP("Expected '(' in prototype"); 766ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 767ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<std::string> ArgNames; 768ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (getNextToken() == tok_identifier) 769ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ArgNames.push_back(IdentifierStr); 770ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurTok != ')') 771ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorP("Expected ')' in prototype"); 772ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 773ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // success. 774ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat ')'. 775ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 776ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Verify right number of names for operator. 777ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Kind && ArgNames.size() != Kind) 778ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorP("Invalid number of operands for operator"); 779ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 780ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return new PrototypeAST(FnLoc, FnName, ArgNames, Kind != 0, BinaryPrecedence); 781ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 782ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 783ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// definition ::= 'def' prototype expression 784ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic FunctionAST *ParseDefinition() { 785ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat def. 786ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PrototypeAST *Proto = ParsePrototype(); 787ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Proto == 0) 788ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 789ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 790ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ExprAST *E = ParseExpression()) 791ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return new FunctionAST(Proto, E); 792ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 793ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 794ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 795ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// toplevelexpr ::= expression 796ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic FunctionAST *ParseTopLevelExpr() { 797ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SourceLocation FnLoc = CurLoc; 798ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ExprAST *E = ParseExpression()) { 799ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Make an anonymous proto. 800ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PrototypeAST *Proto = 801ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines new PrototypeAST(FnLoc, "main", std::vector<std::string>()); 802ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return new FunctionAST(Proto, E); 803ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 804ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 805ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 806ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 807ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// external ::= 'extern' prototype 808ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic PrototypeAST *ParseExtern() { 809ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); // eat extern. 810ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ParsePrototype(); 811ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 812ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 813ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 814ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Debug Info Support 815ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 816ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 817ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic DIBuilder *DBuilder; 818ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 819ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesDIType DebugInfo::getDoubleTy() { 8202c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar if (DblTy) 821ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return DblTy; 822ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 823ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DblTy = DBuilder->createBasicType("double", 64, 64, dwarf::DW_ATE_float); 824ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return DblTy; 825ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 826ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 827ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid DebugInfo::emitLocation(ExprAST *AST) { 828ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!AST) 829ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Builder.SetCurrentDebugLocation(DebugLoc()); 8302c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar MDScope *Scope; 831ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (LexicalBlocks.empty()) 8322c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar Scope = TheCU; 833ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else 8342c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar Scope = *LexicalBlocks.back(); 835ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.SetCurrentDebugLocation( 8362c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar DebugLoc::get(AST->getLine(), AST->getCol(), Scope)); 837ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 838ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 8392c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainarstatic MDSubroutineType *CreateFunctionType(unsigned NumArgs, DIFile Unit) { 840ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallVector<Metadata *, 8> EltTys; 841ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DIType DblTy = KSDbgInfo.getDoubleTy(); 842ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 843ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Add the result type. 844ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EltTys.push_back(DblTy); 845ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 846ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned i = 0, e = NumArgs; i != e; ++i) 847ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EltTys.push_back(DblTy); 848ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 849ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DITypeArray EltTypeArray = DBuilder->getOrCreateTypeArray(EltTys); 850ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return DBuilder->createSubroutineType(Unit, EltTypeArray); 851ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 852ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 853ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 854ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Code Generation 855ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 856ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 857ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic Module *TheModule; 858ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic std::map<std::string, AllocaInst *> NamedValues; 859ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic legacy::FunctionPassManager *TheFPM; 860ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 861ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *ErrorV(const char *Str) { 862ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Error(Str); 863ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 864ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 865ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 866ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of 867ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// the function. This is used for mutable variables etc. 868ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, 869ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const std::string &VarName) { 870ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> TmpB(&TheFunction->getEntryBlock(), 871ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheFunction->getEntryBlock().begin()); 872ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0, 873ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines VarName.c_str()); 874ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 875ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 876ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *NumberExprAST::Codegen() { 877ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.emitLocation(this); 878ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ConstantFP::get(getGlobalContext(), APFloat(Val)); 879ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 880ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 881ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *VariableExprAST::Codegen() { 882ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Look this variable up in the function. 883ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *V = NamedValues[Name]; 884ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (V == 0) 885ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorV("Unknown variable name"); 886ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 887ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.emitLocation(this); 888ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Load the value. 889ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Builder.CreateLoad(V, Name.c_str()); 890ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 891ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 892ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *UnaryExprAST::Codegen() { 893ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *OperandV = Operand->Codegen(); 894ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (OperandV == 0) 895ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 896ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 897ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *F = TheModule->getFunction(std::string("unary") + Opcode); 898ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (F == 0) 899ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorV("Unknown unary operator"); 900ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 901ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.emitLocation(this); 902ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Builder.CreateCall(F, OperandV, "unop"); 903ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 904ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 905ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *BinaryExprAST::Codegen() { 906ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.emitLocation(this); 907ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 908ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Special case '=' because we don't want to emit the LHS as an expression. 909ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Op == '=') { 910ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Assignment requires the LHS to be an identifier. 911ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines VariableExprAST *LHSE = dynamic_cast<VariableExprAST *>(LHS); 912ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!LHSE) 913ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorV("destination of '=' must be a variable"); 914ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Codegen the RHS. 915ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Val = RHS->Codegen(); 916ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Val == 0) 917ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 918ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 919ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Look up the name. 920ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Variable = NamedValues[LHSE->getName()]; 921ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Variable == 0) 922ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorV("Unknown variable name"); 923ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 924ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.CreateStore(Val, Variable); 925ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Val; 926ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 927ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 928ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *L = LHS->Codegen(); 929ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *R = RHS->Codegen(); 930ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (L == 0 || R == 0) 931ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 932ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 933ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines switch (Op) { 934ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case '+': 935ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Builder.CreateFAdd(L, R, "addtmp"); 936ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case '-': 937ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Builder.CreateFSub(L, R, "subtmp"); 938ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case '*': 939ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Builder.CreateFMul(L, R, "multmp"); 940ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case '<': 941ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines L = Builder.CreateFCmpULT(L, R, "cmptmp"); 942ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Convert bool 0/1 to double 0.0 or 1.0 943ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), 944ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "booltmp"); 945ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines default: 946ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 947ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 948ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 949ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If it wasn't a builtin binary operator, it must be a user defined one. Emit 950ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // a call to it. 951ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *F = TheModule->getFunction(std::string("binary") + Op); 952ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(F && "binary operator not found!"); 953ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 954ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Ops[] = { L, R }; 955ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Builder.CreateCall(F, Ops, "binop"); 956ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 957ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 958ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *CallExprAST::Codegen() { 959ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.emitLocation(this); 960ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 961ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Look up the name in the global module table. 962ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *CalleeF = TheModule->getFunction(Callee); 963ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CalleeF == 0) 964ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorV("Unknown function referenced"); 965ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 966ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If argument mismatch error. 967ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CalleeF->arg_size() != Args.size()) 968ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ErrorV("Incorrect # arguments passed"); 969ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 970ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<Value *> ArgsV; 971ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned i = 0, e = Args.size(); i != e; ++i) { 972ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ArgsV.push_back(Args[i]->Codegen()); 973ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ArgsV.back() == 0) 974ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 975ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 976ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 977ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); 978ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 979ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 980ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *IfExprAST::Codegen() { 981ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.emitLocation(this); 982ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 983ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *CondV = Cond->Codegen(); 984ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CondV == 0) 985ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 986ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 987ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Convert condition to a bool by comparing equal to 0.0. 988ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CondV = Builder.CreateFCmpONE( 989ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CondV, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "ifcond"); 990ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 991ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *TheFunction = Builder.GetInsertBlock()->getParent(); 992ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 993ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Create blocks for the then and else cases. Insert the 'then' block at the 994ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // end of the function. 995ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *ThenBB = 996ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock::Create(getGlobalContext(), "then", TheFunction); 997ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else"); 998ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont"); 999ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1000ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.CreateCondBr(CondV, ThenBB, ElseBB); 1001ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1002ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Emit then value. 1003ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.SetInsertPoint(ThenBB); 1004ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1005ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *ThenV = Then->Codegen(); 1006ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ThenV == 0) 1007ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1008ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1009ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.CreateBr(MergeBB); 1010ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Codegen of 'Then' can change the current block, update ThenBB for the PHI. 1011ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ThenBB = Builder.GetInsertBlock(); 1012ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1013ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Emit else block. 1014ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheFunction->getBasicBlockList().push_back(ElseBB); 1015ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.SetInsertPoint(ElseBB); 1016ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1017ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *ElseV = Else->Codegen(); 1018ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ElseV == 0) 1019ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1020ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1021ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.CreateBr(MergeBB); 1022ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Codegen of 'Else' can change the current block, update ElseBB for the PHI. 1023ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ElseBB = Builder.GetInsertBlock(); 1024ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1025ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Emit merge block. 1026ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheFunction->getBasicBlockList().push_back(MergeBB); 1027ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.SetInsertPoint(MergeBB); 1028ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHINode *PN = 1029ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); 1030ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1031ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PN->addIncoming(ThenV, ThenBB); 1032ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PN->addIncoming(ElseV, ElseBB); 1033ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return PN; 1034ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1035ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1036ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *ForExprAST::Codegen() { 1037ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Output this as: 1038ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // var = alloca double 1039ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // ... 1040ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // start = startexpr 1041ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // store start -> var 1042ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // goto loop 1043ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // loop: 1044ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // ... 1045ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // bodyexpr 1046ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // ... 1047ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // loopend: 1048ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // step = stepexpr 1049ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // endcond = endexpr 1050ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 1051ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // curvar = load var 1052ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // nextvar = curvar + step 1053ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // store nextvar -> var 1054ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // br endcond, loop, endloop 1055ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // outloop: 1056ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1057ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *TheFunction = Builder.GetInsertBlock()->getParent(); 1058ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1059ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Create an alloca for the variable in the entry block. 1060ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); 1061ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1062ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.emitLocation(this); 1063ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1064ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Emit the start code first, without 'variable' in scope. 1065ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *StartVal = Start->Codegen(); 1066ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (StartVal == 0) 1067ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1068ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1069ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Store the value into the alloca. 1070ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.CreateStore(StartVal, Alloca); 1071ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1072ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Make the new basic block for the loop header, inserting after current 1073ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // block. 1074ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *LoopBB = 1075ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock::Create(getGlobalContext(), "loop", TheFunction); 1076ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1077ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Insert an explicit fall through from the current block to the LoopBB. 1078ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.CreateBr(LoopBB); 1079ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1080ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Start insertion in LoopBB. 1081ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.SetInsertPoint(LoopBB); 1082ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1083ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Within the loop, the variable is defined equal to the PHI node. If it 1084ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // shadows an existing variable, we have to restore it, so save it now. 1085ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *OldVal = NamedValues[VarName]; 1086ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NamedValues[VarName] = Alloca; 1087ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1088ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Emit the body of the loop. This, like any other expr, can change the 1089ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // current BB. Note that we ignore the value computed by the body, but don't 1090ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // allow an error. 1091ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Body->Codegen() == 0) 1092ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1093ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1094ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Emit the step value. 1095ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *StepVal; 1096ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Step) { 1097ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StepVal = Step->Codegen(); 1098ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (StepVal == 0) 1099ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1100ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 1101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If not specified, use 1.0. 1102ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0)); 1103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Compute the end condition. 1106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *EndCond = End->Codegen(); 1107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (EndCond == 0) 1108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return EndCond; 1109ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1110ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Reload, increment, and restore the alloca. This handles the case where 1111ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // the body of the loop mutates the variable. 1112ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str()); 1113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar"); 1114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.CreateStore(NextVar, Alloca); 1115ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1116ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Convert condition to a bool by comparing equal to 0.0. 1117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EndCond = Builder.CreateFCmpONE( 1118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EndCond, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "loopcond"); 1119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Create the "after loop" block and insert it. 1121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *AfterBB = 1122ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction); 1123ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1124ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Insert the conditional branch into the end of LoopEndBB. 1125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.CreateCondBr(EndCond, LoopBB, AfterBB); 1126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Any new code will be inserted in AfterBB. 1128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.SetInsertPoint(AfterBB); 1129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Restore the unshadowed variable. 1131ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (OldVal) 1132ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NamedValues[VarName] = OldVal; 1133ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else 1134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NamedValues.erase(VarName); 1135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1136ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // for expr always returns 0.0. 1137ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Constant::getNullValue(Type::getDoubleTy(getGlobalContext())); 1138ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1139ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1140ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *VarExprAST::Codegen() { 1141ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<AllocaInst *> OldBindings; 1142ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1143ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *TheFunction = Builder.GetInsertBlock()->getParent(); 1144ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Register all variables and emit their initializer. 1146ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned i = 0, e = VarNames.size(); i != e; ++i) { 1147ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const std::string &VarName = VarNames[i].first; 1148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExprAST *Init = VarNames[i].second; 1149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Emit the initializer before adding the variable to scope, this prevents 1151ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // the initializer from referencing the variable itself, and permits stuff 1152ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // like this: 1153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // var a = 1 in 1154ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // var a = a in ... # refers to outer 'a'. 1155ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *InitVal; 1156ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Init) { 1157ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines InitVal = Init->Codegen(); 1158ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (InitVal == 0) 1159ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1160ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { // If not specified, use 0.0. 1161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0)); 1162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1163ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1164ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); 1165ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.CreateStore(InitVal, Alloca); 1166ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1167ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Remember the old variable binding so that we can restore the binding when 1168ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // we unrecurse. 1169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OldBindings.push_back(NamedValues[VarName]); 1170ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Remember this binding. 1172ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NamedValues[VarName] = Alloca; 1173ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1174ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1175ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.emitLocation(this); 1176ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1177ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Codegen the body, now that all vars are in scope. 1178ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *BodyVal = Body->Codegen(); 1179ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (BodyVal == 0) 1180ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1181ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1182ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Pop all our variables from scope. 1183ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned i = 0, e = VarNames.size(); i != e; ++i) 1184ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NamedValues[VarNames[i].first] = OldBindings[i]; 1185ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1186ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Return the body computation. 1187ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return BodyVal; 1188ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1189ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1190ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesFunction *PrototypeAST::Codegen() { 1191ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Make the function type: double(double,double) etc. 1192ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<Type *> Doubles(Args.size(), 1193ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Type::getDoubleTy(getGlobalContext())); 1194ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FunctionType *FT = 1195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); 1196ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *F = 1198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function::Create(FT, Function::ExternalLinkage, Name, TheModule); 1199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If F conflicted, there was already something named 'Name'. If it has a 1201ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // body, don't allow redefinition or reextern. 1202ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (F->getName() != Name) { 1203ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Delete the one we just made and get the existing one. 1204ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines F->eraseFromParent(); 1205ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines F = TheModule->getFunction(Name); 1206ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1207ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If F already has a body, reject this. 1208ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!F->empty()) { 1209ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ErrorF("redefinition of function"); 1210ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1212ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1213ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If F took a different number of args, reject. 1214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (F->arg_size() != Args.size()) { 1215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ErrorF("redefinition of function with different # args"); 1216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1217ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1218ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1219ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1220ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Set names for all arguments. 1221ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Idx = 0; 1222ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); 1223ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ++AI, ++Idx) 1224ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AI->setName(Args[Idx]); 1225ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1226ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Create a subprogram DIE for this function. 12272c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar DIFile Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(), 12282c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar KSDbgInfo.TheCU->getDirectory()); 12292c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar MDScope *FContext = Unit; 1230ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned LineNo = Line; 1231ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned ScopeLine = Line; 1232ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DISubprogram SP = DBuilder->createFunction( 1233ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FContext, Name, StringRef(), Unit, LineNo, 1234ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CreateFunctionType(Args.size(), Unit), false /* internal linkage */, 12352c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar true /* definition */, ScopeLine, DebugNode::FlagPrototyped, false, F); 1236ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1237ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.FnScopeMap[this] = SP; 1238ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return F; 1239ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1240ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1241ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// CreateArgumentAllocas - Create an alloca for each argument and register the 1242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// argument in the symbol table so that references to it will succeed. 1243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid PrototypeAST::CreateArgumentAllocas(Function *F) { 1244ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function::arg_iterator AI = F->arg_begin(); 1245ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) { 1246ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Create an alloca for this variable. 1247ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]); 1248ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1249ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Create a debug descriptor for the variable. 1250ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DIScope *Scope = KSDbgInfo.LexicalBlocks.back(); 12512c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar DIFile Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(), 12522c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar KSDbgInfo.TheCU->getDirectory()); 1253ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DIVariable D = DBuilder->createLocalVariable(dwarf::DW_TAG_arg_variable, 1254ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines *Scope, Args[Idx], Unit, Line, 1255ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.getDoubleTy(), Idx); 1256ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 12572c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(), 12582c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar DebugLoc::get(Line, 0, *Scope), 12592c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar Builder.GetInsertBlock()); 1260ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1261ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Store the initial value into the alloca. 1262ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.CreateStore(AI, Alloca); 1263ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1264ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Add arguments to variable symbol table. 1265ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NamedValues[Args[Idx]] = Alloca; 1266ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1267ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1268ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1269ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesFunction *FunctionAST::Codegen() { 1270ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NamedValues.clear(); 1271ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1272ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *TheFunction = Proto->Codegen(); 1273ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (TheFunction == 0) 1274ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1275ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1276ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Push the current scope. 1277ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.LexicalBlocks.push_back(&KSDbgInfo.FnScopeMap[Proto]); 1278ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1279ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Unset the location for the prologue emission (leading instructions with no 1280ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // location in a function are considered part of the prologue and the debugger 1281ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // will run past them when breaking on a function) 1282ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.emitLocation(nullptr); 1283ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1284ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If this is an operator, install it. 1285ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Proto->isBinaryOp()) 1286ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence(); 1287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Create a new basic block to start insertion into. 1289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); 1290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.SetInsertPoint(BB); 1291ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Add all arguments to the symbol table and create their allocas. 1293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Proto->CreateArgumentAllocas(TheFunction); 1294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1295ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.emitLocation(Body); 1296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Value *RetVal = Body->Codegen()) { 1298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Finish off the function. 1299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Builder.CreateRet(RetVal); 1300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Pop off the lexical block for the function. 1302ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.LexicalBlocks.pop_back(); 1303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Validate the generated code, checking for consistency. 1305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines verifyFunction(*TheFunction); 1306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Optimize the function. 1308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheFPM->run(*TheFunction); 1309ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1310ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return TheFunction; 1311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Error reading body, remove function. 1314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheFunction->eraseFromParent(); 1315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Proto->isBinaryOp()) 1317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BinopPrecedence.erase(Proto->getOperatorName()); 1318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Pop off the lexical block for the function since we added it 1320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // unconditionally. 1321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.LexicalBlocks.pop_back(); 1322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 1327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Top-Level parsing and JIT Driver 1328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 1329ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1330ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ExecutionEngine *TheExecutionEngine; 1331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void HandleDefinition() { 1333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (FunctionAST *F = ParseDefinition()) { 1334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!F->Codegen()) { 1335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines fprintf(stderr, "Error reading function definition:"); 1336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1337ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 1338ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Skip token for error recovery. 1339ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 1340ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1341ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1342ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1343ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void HandleExtern() { 1344ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (PrototypeAST *P = ParseExtern()) { 1345ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!P->Codegen()) { 1346ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines fprintf(stderr, "Error reading extern"); 1347ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 1349ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Skip token for error recovery. 1350ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 1351ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1352ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1353ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1354ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void HandleTopLevelExpression() { 1355ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Evaluate a top-level expression into an anonymous function. 1356ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (FunctionAST *F = ParseTopLevelExpr()) { 1357ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!F->Codegen()) { 1358ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines fprintf(stderr, "Error generating code for top level expr"); 1359ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1360ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 1361ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Skip token for error recovery. 1362ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 1363ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1364ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1365ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1366ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// top ::= definition | external | expression | ';' 1367ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void MainLoop() { 1368ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (1) { 1369ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines switch (CurTok) { 1370ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_eof: 1371ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 1372ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case ';': 1373ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 1374ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; // ignore top-level semicolons. 1375ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_def: 1376ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines HandleDefinition(); 1377ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 1378ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case tok_extern: 1379ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines HandleExtern(); 1380ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 1381ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines default: 1382ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines HandleTopLevelExpression(); 1383ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 1384ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1385ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1386ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1387ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1388ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 1389ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// "Library" functions that can be "extern'd" from user code. 1390ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 1391ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1392ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// putchard - putchar that takes a double and returns 0. 1393ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesextern "C" double putchard(double X) { 1394ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines putchar((char)X); 1395ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1396ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1397ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1398ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// printd - printf that takes a double prints it as "%f\n", returning 0. 1399ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesextern "C" double printd(double X) { 1400ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines printf("%f\n", X); 1401ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1402ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1403ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1404ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 1405ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Main driver code. 1406ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 1407ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1408ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesint main() { 1409ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines InitializeNativeTarget(); 1410ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines InitializeNativeTargetAsmPrinter(); 1411ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines InitializeNativeTargetAsmParser(); 1412ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LLVMContext &Context = getGlobalContext(); 1413ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1414ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Install standard binary operators. 1415ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 1 is lowest precedence. 1416ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BinopPrecedence['='] = 2; 1417ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BinopPrecedence['<'] = 10; 1418ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BinopPrecedence['+'] = 20; 1419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BinopPrecedence['-'] = 20; 1420ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BinopPrecedence['*'] = 40; // highest. 1421ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Prime the first token. 1423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getNextToken(); 1424ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Make the module, which holds all the code. 1426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::unique_ptr<Module> Owner = make_unique<Module>("my cool jit", Context); 1427ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheModule = Owner.get(); 1428ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1429ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Add the current debug info version into the module. 1430ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheModule->addModuleFlag(Module::Warning, "Debug Info Version", 1431ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG_METADATA_VERSION); 1432ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1433ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Darwin only supports dwarf2. 1434ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Triple(sys::getProcessTriple()).isOSDarwin()) 1435ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheModule->addModuleFlag(llvm::Module::Warning, "Dwarf Version", 2); 1436ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1437ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Construct the DIBuilder, we do this here because we need the module. 1438ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DBuilder = new DIBuilder(*TheModule); 1439ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1440ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Create the compile unit for the module. 1441ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Currently down as "fib.ks" as a filename since we're redirecting stdin 1442ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // but we'd like actual source locations. 1443ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines KSDbgInfo.TheCU = DBuilder->createCompileUnit( 1444ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines dwarf::DW_LANG_C, "fib.ks", ".", "Kaleidoscope Compiler", 0, "", 0); 1445ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1446ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Create the JIT. This takes ownership of the module. 1447ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string ErrStr; 1448ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheExecutionEngine = 1449ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EngineBuilder(std::move(Owner)) 1450ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines .setErrorStr(&ErrStr) 1451ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines .setMCJITMemoryManager(llvm::make_unique<SectionMemoryManager>()) 1452ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines .create(); 1453ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!TheExecutionEngine) { 1454ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); 1455ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines exit(1); 1456ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1457ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1458ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines legacy::FunctionPassManager OurFPM(TheModule); 1459ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1460ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Set up the optimizer pipeline. Start with registering info about how the 1461ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // target lays out data structures. 14624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar TheModule->setDataLayout(*TheExecutionEngine->getDataLayout()); 1463ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#if 0 1464ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Provide basic AliasAnalysis support for GVN. 1465ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OurFPM.add(createBasicAliasAnalysisPass()); 1466ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Promote allocas to registers. 1467ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OurFPM.add(createPromoteMemoryToRegisterPass()); 1468ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Do simple "peephole" optimizations and bit-twiddling optzns. 1469ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OurFPM.add(createInstructionCombiningPass()); 1470ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Reassociate expressions. 1471ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OurFPM.add(createReassociatePass()); 1472ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Eliminate Common SubExpressions. 1473ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OurFPM.add(createGVNPass()); 1474ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Simplify the control flow graph (deleting unreachable blocks, etc). 1475ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OurFPM.add(createCFGSimplificationPass()); 1476ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines #endif 1477ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OurFPM.doInitialization(); 1478ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1479ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Set the global so the code gen can use this. 1480ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheFPM = &OurFPM; 1481ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1482ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Run the main "interpreter loop" now. 1483ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MainLoop(); 1484ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1485ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheFPM = 0; 1486ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1487ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Finalize the debug info. 1488ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DBuilder->finalize(); 1489ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1490ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Print out all of the generated code. 1491ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheModule->dump(); 1492ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1493ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 1494ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1495