#include "ast.hpp" #include LLVMContext TheContext; map NamedValues; IRBuilder<> Builder(TheContext); Module* TheModule; FunctionPassManager *TheFPM; ExprAST::~ExprAST() { } InnerExprAST::InnerExprAST(ExprAST* a) { _nodes.resize(0); _nodes.push_back(a); } InnerExprAST::InnerExprAST(ExprAST* a, ExprAST* b) { _nodes.resize(0); _nodes.push_back(a); _nodes.push_back(b); } InnerExprAST::InnerExprAST(ExprAST* a, ExprAST* b, ExprAST* c) { _nodes.resize(0); _nodes.push_back(a); _nodes.push_back(b); _nodes.push_back(c); } InnerExprAST::InnerExprAST(ExprAST* a, ExprAST* b, ExprAST* c, ExprAST* d) { _nodes.resize(0); _nodes.push_back(a); _nodes.push_back(b); _nodes.push_back(c); _nodes.push_back(d); } InnerExprAST::InnerExprAST(vector a) { _nodes = a; } InnerExprAST::~InnerExprAST() { for (unsigned i = 0; i < _nodes.size(); i++) delete _nodes[i]; } FunctionAST::~FunctionAST() { delete Body; } Value* NumberExprAST::codegen() const { return ConstantFP::get(TheContext, APFloat(Val)); } Value* VariableExprAST::codegen() const { Value* tmp = NamedValues[Name]; if (tmp == NULL) { cerr << "Promenljiva " << Name << " nije prethodno definisana" << endl; return NULL; } return tmp; } Value* AddExprAST::codegen() const { Value* l = _nodes[0]->codegen(); Value* d = _nodes[1]->codegen(); if (l == NULL || d == NULL) { return NULL; } return Builder.CreateFAdd(l, d, "addtmp"); } Value* SubExprAST::codegen() const { Value* l = _nodes[0]->codegen(); Value* d = _nodes[1]->codegen(); if (l == NULL || d == NULL) { return NULL; } return Builder.CreateFSub(l, d, "subtmp"); } Value* MulExprAST::codegen() const { Value* l = _nodes[0]->codegen(); Value* d = _nodes[1]->codegen(); if (l == NULL || d == NULL) { return NULL; } return Builder.CreateFMul(l, d, "multmp"); } Value* DivExprAST::codegen() const { Value* l = _nodes[0]->codegen(); Value* d = _nodes[1]->codegen(); if (l == NULL || d == NULL) { return NULL; } return Builder.CreateFDiv(l, d, "divtmp"); } Value* LtExprAST::codegen() const { Value* l = _nodes[0]->codegen(); Value* d = _nodes[1]->codegen(); if (l == NULL || d == NULL) { return NULL; } l = Builder.CreateFCmpULT(l, d, "lttmp"); return Builder.CreateUIToFP(l, Type::getDoubleTy(TheContext), "booltmp"); } Value* GtExprAST::codegen() const { Value* l = _nodes[0]->codegen(); Value* d = _nodes[1]->codegen(); if (l == NULL || d == NULL) { return NULL; } l = Builder.CreateFCmpUGT(l, d, "gttmp"); return Builder.CreateUIToFP(l, Type::getDoubleTy(TheContext), "booltmp"); } Value* SeqExprAST::codegen() const { Value* l = _nodes[0]->codegen(); Value* d = _nodes[1]->codegen(); if (l == NULL || d == NULL) { return NULL; } return d; } Value* CallExprAST::codegen() const { // Look up the name in the global module table. Function *CalleeF = TheModule->getFunction(Callee); if (!CalleeF) { cerr << "Poziv fje " << Callee << " koja nije definisana" << endl; return NULL; } // If argument mismatch error. if (CalleeF->arg_size() != _nodes.size()) { cerr << "Pogresan broj argumenata fje " << Callee << endl; return NULL; } vector ArgsV; for (unsigned i = 0, e = _nodes.size(); i != e; ++i) { ArgsV.push_back(_nodes[i]->codegen()); if (!ArgsV.back()) return NULL; } return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } Value* IfExprAST::codegen() const { Value *CondV = _nodes[0]->codegen(); if (CondV == NULL) return NULL; CondV = Builder.CreateFCmpONE(CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond"); Function *TheFunction = Builder.GetInsertBlock()->getParent(); BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction); BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else"); BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont"); Builder.CreateCondBr(CondV, ThenBB, ElseBB); Builder.SetInsertPoint(ThenBB); Value *Then = _nodes[1]->codegen(); if (Then == NULL) return NULL; Builder.CreateBr(MergeBB); ThenBB = Builder.GetInsertBlock(); TheFunction->getBasicBlockList().push_back(ElseBB); Builder.SetInsertPoint(ElseBB); Value *Else = _nodes[2]->codegen(); if (Else == NULL) return NULL; Builder.CreateBr(MergeBB); ElseBB = Builder.GetInsertBlock(); TheFunction->getBasicBlockList().push_back(MergeBB); Builder.SetInsertPoint(MergeBB); PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp"); PN->addIncoming(Then, ThenBB); PN->addIncoming(Else, ElseBB); return PN; } Value* ForExprAST::codegen() const { Value* StartVal = _nodes[0]->codegen(); if (StartVal == NULL) return NULL; Function* TheFunction = Builder.GetInsertBlock()->getParent(); BasicBlock* LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction); Builder.CreateBr(LoopBB); BasicBlock* EntryBB = Builder.GetInsertBlock(); Builder.SetInsertPoint(LoopBB); PHINode* Variable = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, VarName); Variable->addIncoming(StartVal, EntryBB); Value* OldVal = NamedValues[VarName]; NamedValues[VarName] = Variable; Value* Body = _nodes[3]->codegen(); if (Body == NULL) return NULL; Value* StepVal = NULL; if (_nodes[2] != NULL) StepVal = _nodes[2]->codegen(); else StepVal = ConstantFP::get(TheContext, APFloat(1.0)); if (StepVal == NULL) return NULL; Value *NextVar = Builder.CreateFAdd(Variable, StepVal, "nextvar"); BasicBlock* EndLoopBB = Builder.GetInsertBlock(); Variable->addIncoming(NextVar, EndLoopBB); Value *CondVal = _nodes[1]->codegen(); if (CondVal == NULL) return NULL; CondVal = Builder.CreateFCmpONE(CondVal, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond"); BasicBlock* AfterLoopBB = BasicBlock::Create(TheContext, "afterloop", TheFunction); Builder.CreateCondBr(CondVal, LoopBB, AfterLoopBB); Builder.SetInsertPoint(AfterLoopBB); if (OldVal != NULL) NamedValues[VarName] = OldVal; else NamedValues.erase(VarName); return ConstantFP::get(TheContext, APFloat(0.0)); } Value* VarExprAST::codegen() const { vector OldValues; for (unsigned i = 0; i < V.size(); i++) { Value* Tmp = NULL; if (V[i].second != NULL) Tmp = V[i].second->codegen(); else Tmp = ConstantFP::get(TheContext, APFloat(0.0)); if (Tmp == NULL) return NULL; OldValues.push_back(NamedValues[V[i].first]); NamedValues[V[i].first] = Tmp; } Value *Body = _nodes[0]->codegen(); if (Body == NULL) return NULL; for (unsigned i = 0; i < V.size(); i++) if (OldValues[i] != NULL) NamedValues[V[i].first] = OldValues[i]; else NamedValues.erase(V[i].first); return Body; } VarExprAST::~VarExprAST() { for (unsigned i = 0; i < V.size(); i++) delete V[i].second; } Function* PrototypeAST::codegen() const { vector Doubles(Args.size(), Type::getDoubleTy(TheContext)); FunctionType *FT = FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false); Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule); unsigned Idx = 0; for (auto &Arg : F->args()) Arg.setName(Args[Idx++]); return F; } Function* FunctionAST::codegen() const { // First, check for an existing function from a previous 'extern' declaration. Function *TheFunction = TheModule->getFunction(Proto.getName()); if (!TheFunction) TheFunction = Proto.codegen(); if (!TheFunction) return NULL; if (!TheFunction->empty()) { cerr << "Nije dozvoljena redefinicija fje " << Proto.getName() << endl; return NULL; } // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction); Builder.SetInsertPoint(BB); // Record the function arguments in the NamedValues map. NamedValues.clear(); for (auto &Arg : TheFunction->args()) NamedValues[Arg.getName()] = &Arg; if (Value *RetVal = Body->codegen()) { // Finish off the function. Builder.CreateRet(RetVal); // Validate the generated code, checking for consistency. verifyFunction(*TheFunction); TheFPM->run(*TheFunction); return TheFunction; } // Error reading body, remove function. TheFunction->eraseFromParent(); return NULL; } void InitializeModuleAndPassManager() { TheModule = new Module("my_module", TheContext); TheFPM = new FunctionPassManager(TheModule); // Eliminate Common SubExpressions. TheFPM->add(createGVNPass()); TheFPM->doInitialization(); }