#ifndef __AST_HPP__ #define __AST_HPP__ 1 /* http://llvm.org/docs/tutorial/ */ #include #include #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/TargetSelect.h" #include "KaleidoscopeJIT.h" using namespace std; using namespace llvm; using namespace llvm::orc; /* bazna klasa apstraktnog stabla */ class ExprAST { public: virtual Value* codegen() const = 0; virtual ~ExprAST() {} }; /* brojevna konstanta */ class NumberExprAST : public ExprAST { public: NumberExprAST(double val) :_val(val) {} Value* codegen() const; private: double _val; }; /* promenljiva */ class VariableExprAST : public ExprAST { public: VariableExprAST(string name) :_name(name) {} Value* codegen() const; string getName() const { return _name; } private: string _name; }; /* binarni izraz */ class BinaryExprAST : public ExprAST { public: BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) :_op(op), _lhs(lhs), _rhs(rhs) {} Value* codegen() const; ~BinaryExprAST() { delete _lhs; delete _rhs; } private: BinaryExprAST(const BinaryExprAST&); BinaryExprAST& operator=(const BinaryExprAST&); char _op; ExprAST *_lhs, *_rhs; }; /* poziv funkcije */ class CallExprAST : public ExprAST { public: CallExprAST(string name, vector exps) :_name(name), _exps(exps) {} ~CallExprAST() { for (auto e : _exps) delete e; } Value* codegen() const; private: CallExprAST(const CallExprAST&); CallExprAST& operator=(const CallExprAST&); string _name; vector _exps; }; /* if-else izraz */ class IfExprAST : public ExprAST { public: IfExprAST(ExprAST *c, ExprAST *t, ExprAST *e) : _cond(c), _then(t), _else(e) {} Value* codegen() const; ~IfExprAST() { delete _cond; delete _then; delete _else; } private: IfExprAST(const IfExprAST&); IfExprAST& operator=(const IfExprAST&); ExprAST *_cond, *_then, *_else; }; /* for-in izraz */ class ForExprAST : public ExprAST { public: ForExprAST(string varName, ExprAST *e1, ExprAST *e2, ExprAST *e3, ExprAST *e4) :_varName(varName), _start(e1), _stop(e2), _step(e3), _body(e4) {} ~ForExprAST() { delete _start; delete _stop; delete _step; delete _body; } Value* codegen() const; private: ForExprAST(const ForExprAST&); ForExprAST& operator=(const ForExprAST&); string _varName; ExprAST* _start; ExprAST* _stop; ExprAST* _step; ExprAST* _body; }; /* var-in izraz */ class VarExprAST : public ExprAST { public: VarExprAST(vector< pair > &v, ExprAST *e) :_list(v), _body(e) {} ~VarExprAST() { for (unsigned i = 0; i < _list.size(); i++) delete _list[i].second; delete _body; } Value* codegen() const; private: VarExprAST(const VarExprAST&); VarExprAST& operator=(const VarExprAST&); vector< pair > _list; ExprAST* _body; }; /* klasa koja predstavlja prototip funkcije */ class PrototypeAST { public: PrototypeAST(string name, vector args) :_name(name), _args(args) {} string getName() const { return _name; } Function* codegen() const; private: string _name; vector _args; }; /* klasa koja predstavlja funkciju */ class FunctionAST { public: FunctionAST(PrototypeAST proto, ExprAST* definition) : _proto(proto), _definition(definition) { } ~FunctionAST() { delete _definition; } Function* codegen() const; private: FunctionAST(const FunctionAST&); FunctionAST& operator=(const FunctionAST&); PrototypeAST _proto; ExprAST* _definition; }; /* inicijalizacija modula i pass-manager-a */ void initializeModuleAndPassManager(); /* geter za funkciju */ Function* getFunction(string s); /* kreiranje alokatora promenljive */ AllocaInst* createEntryBlockAlloca(Function* TheFunction, const string& name); #endif