#include "ast.hpp" #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; } Value* NumberExprAST::codegen() const { return ConstantFP::get(TheContext, APFloat(_d)); } Value* VariableExprAST::codegen() const { Value *v = NamedValues[_v]; if (!v) { cerr << "Nepostojeca promenljiva " << _v << endl; exit(EXIT_FAILURE); } return v; } 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 d(_args.size(), Type::getDoubleTy(TheContext)); FunctionType* FT = FunctionType::get(Type::getDoubleTy(TheContext), d, false); Function *F = Function::Create(FT, Function::ExternalLinkage, _f, TheModule); unsigned i = 0; for (auto &Arg : F->args()) Arg.setName(_args[i++]); return F; } FunctionAST::~FunctionAST() { delete _e; } Function* FunctionAST::codegen() const { Function* F = TheModule->getFunction(_proto.getName()); if (!F) F = _proto.codegen(); if (!F) { cerr << "Nemoguce generisanje koda za funkciju " << _proto.getName() << endl; exit(EXIT_FAILURE); } if (!F->empty()) { cerr << "Nemoguce je predefinisati fju " << _proto.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; if ((RetVal = _e->codegen())) { Builder.CreateRet(RetVal); verifyFunction(*F); return F; } else { F->eraseFromParent(); return NULL; } }