#ifndef _AST_H #define _AST_H //LLVM includes #include "llvm/ADT/STLExtras.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" using namespace llvm; //===----------------------------------------------------------------------===// // Abstract Syntax Tree (aka Parse Tree) //===----------------------------------------------------------------------===// namespace ast{ // struct instantiated by the 'main' to access data structures if llvm IR. struct AstObjects { public: static std::unique_ptr TheModule; static IRBuilder<> Builder; static std::map NamedValues; }; /// ExprAST - Base class for all expression nodes. class ExprAST { public: virtual ~ExprAST() {} virtual llvm::Value *codegen() = 0; }; /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { double Val; public: NumberExprAST(double Val) : Val(Val) {} Value *codegen() override; }; /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { std::string Name; public: VariableExprAST(const std::string &Name) : Name(Name) {} const std::string &getName() const { return Name; } Value *codegen() override; }; /// UnaryExprAST - Expression class for a unary operator. class UnaryExprAST : public ExprAST { char Opcode; std::unique_ptr Operand; public: UnaryExprAST(char Opcode, std::unique_ptr Operand) : Opcode(Opcode), Operand(std::move(Operand)) {} Value *codegen() override; }; /// BinaryExprAST - Expression class for a binary operator. class BinaryExprAST : public ExprAST { char Op; std::unique_ptr LHS, RHS; public: BinaryExprAST(char Op, std::unique_ptr LHS, std::unique_ptr RHS) : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} Value *codegen() override; }; /// ExprAST - Base class for all expression nodes. /// CallExprAST - Expression class for function calls. class CallExprAST : public ExprAST { std::string Callee; std::vector> Args; public: CallExprAST(const std::string &Callee, std::vector> Args) : Callee(Callee), Args(std::move(Args)) {} Value *codegen() override; }; /// IfExprAST - Expression class for if/then/else. class IfExprAST : public ExprAST { std::unique_ptr Cond, Then, Else; public: IfExprAST(std::unique_ptr Cond, std::unique_ptr Then, std::unique_ptr Else) : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {} virtual Value *codegen(); }; /// ForExprAST - Expression class for for/in. class ForExprAST : public ExprAST { std::string VarName; std::unique_ptr Start, End, Step, Body; public: ForExprAST(const std::string &VarName, std::unique_ptr Start, std::unique_ptr End, std::unique_ptr Step, std::unique_ptr Body) : VarName(VarName), Start(std::move(Start)), End(std::move(End)), Step(std::move(Step)), Body(std::move(Body)) {} virtual Value *codegen(); }; /// VarExprAST - Expression class for var/in class VarExprAST : public ExprAST { std::vector>> VarNames; std::unique_ptr Body; public: VarExprAST( std::vector>> VarNames, std::unique_ptr Body) : VarNames(std::move(VarNames)), Body(std::move(Body)) {} Value *codegen() override; }; /// 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 { std::string Name; std::vector Args; bool IsOperator; unsigned Precedence; // Precedence if a binary op. public: PrototypeAST(const std::string &Name, std::vector Args, bool IsOperator = false, unsigned Prec = 0) : Name(Name), Args(std::move(Args)), IsOperator(IsOperator), Precedence(Prec) {} Function *codegen(); const std::string &getName() const { return Name; } bool isUnaryOp() const { return IsOperator && Args.size() == 1; } bool isBinaryOp() const { return IsOperator && Args.size() == 2; } char getOperatorName() const { assert(isUnaryOp() || isBinaryOp()); return Name[Name.size() - 1]; } unsigned getBinaryPrecedence() const { return Precedence; } void CreateArgumentAllocas(Function *F); }; /// FunctionAST - This class represents a function definition itself. class FunctionAST { std::unique_ptr Proto; std::unique_ptr Body; public: FunctionAST(std::unique_ptr Proto, std::unique_ptr Body) : Proto(std::move(Proto)), Body(std::move(Body)) {} Function *codegen(); }; llvm::Value *ErrorV(const char *Str); static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, const std::string &VarName); } #endif