#include "ast.hpp" #include #include LLVMContext TheContext; Module *TheModule; IRBuilder<> Builder(TheContext); map NamedValues; ExprAST::~ExprAST() { } InnerExprAST::InnerExprAST(ExprAST *e1) { _v.resize(0); _v.push_back(e1); } InnerExprAST::InnerExprAST(ExprAST *e1, ExprAST *e2) { _v.resize(0); _v.push_back(e1); _v.push_back(e2); } InnerExprAST::InnerExprAST(ExprAST *e1, ExprAST *e2, ExprAST *e3) { _v.resize(0); _v.push_back(e1); _v.push_back(e2); _v.push_back(e3); } InnerExprAST::~InnerExprAST() { for(auto e : _v) delete e; } FunctionAST::~FunctionAST() { delete _e; } Value* VariableExprAST::codegen() const { Value *v = NamedValues[_v]; if (!v) { cerr << "Nepostojeca promenljiva " << _v << endl; exit(EXIT_FAILURE); } return v; } Value* NumberExprAST::codegen() const { return ConstantFP::get(TheContext, APFloat(_d)); } Value* AddExprAST::codegen() const { Value* l = _v[0]->codegen(); Value* d = _v[1]->codegen(); if (!l || !d) return NULL; return Builder.CreateFAdd(l, d, "addtmp"); } Value* SubExprAST::codegen() const { Value* l = _v[0]->codegen(); Value* d = _v[1]->codegen(); if (!l || !d) return NULL; return Builder.CreateFSub(l, d, "subtmp"); } Value* MulExprAST::codegen() const { Value* l = _v[0]->codegen(); Value* d = _v[1]->codegen(); if (!l || !d) return NULL; return Builder.CreateFMul(l, d, "multmp"); } Value* DivExprAST::codegen() const { Value* l = _v[0]->codegen(); Value* d = _v[1]->codegen(); if (!l || !d) return NULL; return Builder.CreateFDiv(l, d, "divtmp"); } Value* CallExprAST::codegen() const { return NULL; } Function* PrototypeAST::codegen() const { vector v(_args.size(), Type::getDoubleTy(TheContext)); FunctionType* FT = FunctionType::get(Type::getDoubleTy(TheContext), v, false); Function* F = Function::Create(FT, Function::ExternalLinkage, _f, TheModule); unsigned i = 0; for (auto &Arg : F->args()) Arg.setName(_args[i++]); return F; } Function* FunctionAST::codegen() const { Function* F = TheModule->getFunction(_p.getName()); if (!F) { F = _p.codegen(); } if (!F) { cerr << "Nemoguce je generisati funkciju " << _p.getName() << endl; exit(EXIT_FAILURE); } if (!F->empty()) { cerr << "Nemoguce je predefinisati fju " << _p.getName() << endl; exit(EXIT_FAILURE); } BasicBlock* BB = BasicBlock::Create(TheContext, "entry", F); Builder.SetInsertPoint(BB); NamedValues.clear(); for (auto &Arg : F->args()) NamedValues[Arg.getName()] = &Arg; Value* RetVal = _e->codegen(); if (RetVal) { Builder.CreateRet(RetVal); verifyFunction(*F); return F; } else { F->eraseFromParent(); return NULL; } }