#include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" #include "llvm/IR/Verifier.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Target/TargetMachine.h" #include "KaleidoscopeJIT.h" #include <algorithm> #include <cassert> #include <cctype> #include <cstdint> #include <cstdio> #include <cstdlib> #include <map> #include <memory> #include <string> #include <utility> #include <vector> usingnamespacellvm; usingnamespacellvm::orc; //===----------------------------------------------------------------------===// // Lexer //===----------------------------------------------------------------------===// // The lexer returns tokens [0-255] if it is an unknown character, otherwise one // of these for known things. enum Token { … }; static std::string IdentifierStr; // Filled in if tok_identifier static double NumVal; // Filled in if tok_number /// gettok - Return the next token from standard input. static int gettok() { … } //===----------------------------------------------------------------------===// // Abstract Syntax Tree (aka Parse Tree) //===----------------------------------------------------------------------===// /// ExprAST - Base class for all expression nodes. class ExprAST { … }; /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { … }; /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { … }; /// UnaryExprAST - Expression class for a unary operator. class UnaryExprAST : public ExprAST { … }; /// BinaryExprAST - Expression class for a binary operator. class BinaryExprAST : public ExprAST { … }; /// CallExprAST - Expression class for function calls. class CallExprAST : public ExprAST { … }; /// IfExprAST - Expression class for if/then/else. class IfExprAST : public ExprAST { … }; /// ForExprAST - Expression class for for/in. class ForExprAST : public ExprAST { … }; /// VarExprAST - Expression class for var/in class VarExprAST : public ExprAST { … }; /// PrototypeAST - This class represents the "prototype" for a function, /// which captures its name, and its argument names (thus implicitly the number /// of arguments the function takes), as well as if it is an operator. class PrototypeAST { … }; //===----------------------------------------------------------------------===// // Parser //===----------------------------------------------------------------------===// /// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current /// token the parser is looking at. getNextToken reads another token from the /// lexer and updates CurTok with its results. static int CurTok; static int getNextToken() { … } /// BinopPrecedence - This holds the precedence for each binary operator that is /// defined. static std::map<char, int> BinopPrecedence; /// GetTokPrecedence - Get the precedence of the pending binary operator token. static int GetTokPrecedence() { … } /// LogError* - These are little helper functions for error handling. std::unique_ptr<ExprAST> LogError(const char *Str) { … } std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) { … } static std::unique_ptr<ExprAST> ParseExpression(); /// numberexpr ::= number static std::unique_ptr<ExprAST> ParseNumberExpr() { … } /// parenexpr ::= '(' expression ')' static std::unique_ptr<ExprAST> ParseParenExpr() { … } /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' static std::unique_ptr<ExprAST> ParseIdentifierExpr() { … } /// ifexpr ::= 'if' expression 'then' expression 'else' expression static std::unique_ptr<ExprAST> ParseIfExpr() { … } /// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression static std::unique_ptr<ExprAST> ParseForExpr() { … } /// varexpr ::= 'var' identifier ('=' expression)? // (',' identifier ('=' expression)?)* 'in' expression static std::unique_ptr<ExprAST> ParseVarExpr() { … } /// primary /// ::= identifierexpr /// ::= numberexpr /// ::= parenexpr /// ::= ifexpr /// ::= forexpr /// ::= varexpr static std::unique_ptr<ExprAST> ParsePrimary() { … } /// unary /// ::= primary /// ::= '!' unary static std::unique_ptr<ExprAST> ParseUnary() { … } /// binoprhs /// ::= ('+' unary)* static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS) { … } /// expression /// ::= unary binoprhs /// static std::unique_ptr<ExprAST> ParseExpression() { … } /// prototype /// ::= id '(' id* ')' /// ::= binary LETTER number? (id, id) /// ::= unary LETTER (id) static std::unique_ptr<PrototypeAST> ParsePrototype() { … } /// definition ::= 'def' prototype expression static std::unique_ptr<FunctionAST> ParseDefinition() { … } /// toplevelexpr ::= expression static std::unique_ptr<FunctionAST> ParseTopLevelExpr() { … } /// external ::= 'extern' prototype static std::unique_ptr<PrototypeAST> ParseExtern() { … } //===----------------------------------------------------------------------===// // Code Generation //===----------------------------------------------------------------------===// static std::unique_ptr<KaleidoscopeJIT> TheJIT; static std::unique_ptr<LLVMContext> TheContext; static std::unique_ptr<IRBuilder<>> Builder; static std::unique_ptr<Module> TheModule; static std::map<std::string, AllocaInst *> NamedValues; static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos; static ExitOnError ExitOnErr; Value *LogErrorV(const char *Str) { … } Function *getFunction(std::string Name) { … } /// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of /// the function. This is used for mutable variables etc. static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, StringRef VarName) { … } Value *NumberExprAST::codegen() { … } Value *VariableExprAST::codegen() { … } Value *UnaryExprAST::codegen() { … } Value *BinaryExprAST::codegen() { … } Value *CallExprAST::codegen() { … } Value *IfExprAST::codegen() { … } // Output for-loop as: // var = alloca double // ... // start = startexpr // store start -> var // goto loop // loop: // ... // bodyexpr // ... // loopend: // step = stepexpr // endcond = endexpr // // curvar = load var // nextvar = curvar + step // store nextvar -> var // br endcond, loop, endloop // outloop: Value *ForExprAST::codegen() { … } Value *VarExprAST::codegen() { … } Function *PrototypeAST::codegen() { … } const PrototypeAST& FunctionAST::getProto() const { … } const std::string& FunctionAST::getName() const { … } Function *FunctionAST::codegen() { … } //===----------------------------------------------------------------------===// // Top-Level parsing and JIT Driver //===----------------------------------------------------------------------===// static void InitializeModule() { … } ThreadSafeModule irgenAndTakeOwnership(FunctionAST &FnAST, const std::string &Suffix) { … } static void HandleDefinition() { … } static void HandleExtern() { … } static void HandleTopLevelExpression() { … } /// top ::= definition | external | expression | ';' static void MainLoop() { … } //===----------------------------------------------------------------------===// // "Library" functions that can be "extern'd" from user code. //===----------------------------------------------------------------------===// /// putchard - putchar that takes a double and returns 0. extern "C" double putchard(double X) { … } /// printd - printf that takes a double prints it as "%f\n", returning 0. extern "C" double printd(double X) { … } //===----------------------------------------------------------------------===// // Main driver code. //===----------------------------------------------------------------------===// int main() { … }