#include "ast.hpp" LLVMContext TheContext; IRBuilder<> Builder(TheContext); Module* TheModule; map NamedValues; extern void yyerror(string s); Value* NumberExprAST::codegen() const { return ConstantFP::get(TheContext, APFloat(Val)); } Value* VariableExprAST::codegen() const { Value* v = NamedValues[Name]; if (v == nullptr) yyerror("Promenljiva nije definisana"); return v; } InnerExprAST::InnerExprAST(ExprAST* e1) { Vec.push_back(e1); } InnerExprAST::InnerExprAST(ExprAST* e1, ExprAST* e2) { Vec.push_back(e1); Vec.push_back(e2); } InnerExprAST::InnerExprAST(ExprAST* e1, ExprAST* e2, ExprAST* e3) { Vec.push_back(e1); Vec.push_back(e2); Vec.push_back(e3); } InnerExprAST::~InnerExprAST() { for (auto i : Vec) delete i; } Value* AddExprAST::codegen() const { Value *l = Vec[0]->codegen(); Value *d = Vec[1]->codegen(); if (l == nullptr || d == nullptr) return nullptr; return Builder.CreateFAdd(l, d, "addtmp"); } Value* SubExprAST::codegen() const { Value *l = Vec[0]->codegen(); Value *d = Vec[1]->codegen(); if (l == nullptr || d == nullptr) return nullptr; return Builder.CreateFSub(l, d, "subtmp"); } Value* MulExprAST::codegen() const { Value *l = Vec[0]->codegen(); Value *d = Vec[1]->codegen(); if (l == nullptr || d == nullptr) return nullptr; return Builder.CreateFMul(l, d, "multmp"); } Value* DivExprAST::codegen() const { Value *l = Vec[0]->codegen(); Value *d = Vec[1]->codegen(); if (l == nullptr || d == nullptr) return nullptr; return Builder.CreateFDiv(l, d, "divtmp"); } Value* CallExprAST::codegen() const { Function *CalleeF = TheModule->getFunction(Callee); if (CalleeF == nullptr) yyerror("Funkcija " + Callee + " ne postoji"); if (CalleeF->arg_size() != Vec.size()) yyerror("Pogresan broj argumenata fje " + Callee); vector ArgsV; for (unsigned i = 0, e = Vec.size(); i != e; ++i) { ArgsV.push_back(Vec[i]->codegen()); if (!ArgsV.back()) return nullptr; } 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; } FunctionAST::~FunctionAST() { delete Proto; delete Body; } Function* FunctionAST::codegen() const { Function *TheFunction = TheModule->getFunction(Proto->getName()); if (TheFunction == nullptr) TheFunction = Proto->codegen(); if (!TheFunction) return nullptr; if (!TheFunction->empty()) yyerror("Funkcija ne moze da se redefinise"); BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction); Builder.SetInsertPoint(BB); NamedValues.clear(); for (auto &Arg : TheFunction->args()) NamedValues[Arg.getName()] = &Arg; if (Value *RetVal = Body->codegen()) { Builder.CreateRet(RetVal); verifyFunction(*TheFunction); return TheFunction; } TheFunction->eraseFromParent(); return nullptr; }