#include "ast.hpp" #include LLVMContext TheContext; map NamedValues; IRBuilder<> Builder(TheContext); Module* TheModule; 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(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* 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"); } 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); return TheFunction; } // Error reading body, remove function. TheFunction->eraseFromParent(); return NULL; }