WIP
[kaleidoscope.git] / Kaleidoscope / ast.hpp
1 #include <string>
2 #include <vector>
3 #include "llvm/IR/Value.h"
4 #include "llvm/IR/Function.h"
5
6 using namespace llvm;
7
8 class ExprAST {
9 public:
10         virtual ~ExprAST() = default;
11         virtual Value *codegen() = 0;
12 };
13
14 std::unique_ptr<ExprAST> LogError(std::string str);
15
16 class NumberExprAST: public ExprAST {
17         double Val;
18         
19 public:
20         NumberExprAST(double Val): Val(Val) {}
21         virtual Value *codegen();
22 };
23
24 class VariableExprAST: public ExprAST {
25         std::string Name;
26         
27 public:
28         VariableExprAST(const std::string &Name): Name(Name) {}
29         virtual Value *codegen();
30 };
31
32 class BinaryExprAST: public ExprAST {
33         char Op;
34         std::unique_ptr<ExprAST> LHS, RHS;
35         
36 public:
37         BinaryExprAST(char op, std::unique_ptr<ExprAST> LHS,
38                                   std::unique_ptr<ExprAST> RHS)
39         : Op(op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
40         virtual Value *codegen();
41 };
42
43 class CallExprAST: public ExprAST {
44         std::string Callee;
45         std::vector<std::unique_ptr<ExprAST>> Args;
46         
47 public:
48         CallExprAST(std::string &Callee, std::vector<std::unique_ptr<ExprAST>> Args)
49         : Callee(Callee), Args(std::move(Args)) {}
50         virtual Value *codegen();
51 };
52
53 /**
54  Captures the prototype for a function
55  which is basically its name and arguments
56  */
57 class PrototypeAST {
58         std::string Name;
59         std::vector<std::string> Args;
60         bool IsOperator;
61         unsigned Precedence;
62         
63 public:
64         virtual ~PrototypeAST() = default;
65         PrototypeAST(std::string Name, std::vector<std::string> Args,
66                                 bool IsOperator = false, unsigned Prec = 0)
67         : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
68       Precedence(Prec) {}
69         
70         const std::string &getName() const { return Name; }
71         virtual Function *codegen();
72
73         bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
74         bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
75
76         char getOperatorName() const {
77                 assert(isUnaryOp() || isBinaryOp());
78                 return Name[Name.size() - 1];
79         }
80
81         unsigned getBinaryPrecedence() const { return Precedence; }
82 };
83
84 class FunctionAST {
85         std::unique_ptr<PrototypeAST> Prototype;
86         std::unique_ptr<ExprAST> Body;
87         
88 public:
89         virtual ~FunctionAST() = default;
90         FunctionAST(std::unique_ptr<PrototypeAST> Prototype, std::unique_ptr<ExprAST> Body)
91         : Prototype(std::move(Prototype)), Body(std::move(Body)) {}
92         virtual Function *codegen();
93 };
94
95 /// An expression for an if/then/else combo
96 class IfExprAST: public ExprAST {
97         std::unique_ptr<ExprAST> Cond, Then, Else;
98         
99 public:
100         IfExprAST(std::unique_ptr<ExprAST> Cond,
101                           std::unique_ptr<ExprAST> Then,
102                           std::unique_ptr<ExprAST> Else)
103         : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
104         
105         Value *codegen() override;
106 };
107
108 /// An expression for a for loop
109 class ForExprAST: public ExprAST {
110         std::string VarName;
111         std::unique_ptr<ExprAST> Start, End, Step, Body;
112         
113 public:
114         ForExprAST(const std::string &VarName,
115                            std::unique_ptr<ExprAST> Start,
116                            std::unique_ptr<ExprAST> End,
117                            std::unique_ptr<ExprAST> Step,
118                            std::unique_ptr<ExprAST> Body)
119         : VarName(VarName),
120         Start(std::move(Start)),
121         End(std::move(End)),
122         Step(std::move(Step)),
123         Body(std::move(Body)) {}
124         
125         Value *codegen() override;
126 };