#include "funct.hpp" #include "syntree.hpp" //Destruktor Funct::~Funct() { delete _code; } // Registar funkcija map Funct::_functions; // Poziv funkcije za date vrednosti argumenata int Funct::Call(const vector& values) { // Proveravamo korektnost broja argumenata if (values.size() != _args.size()) throw "Wrong number of arguments in function call"; // Formalnim argumentima dodeljujemo lokalne promenljive map variables; for (size_t i = 0; iInterpret(variables); // Rezultat se nalazi u promenljivoj sa imenom _result return variables[_result]; } Function* Funct::Codegen() const { Function* TheFunction = theModule->getFunction(_name); if (TheFunction != nullptr) throw "Ne moguce je redefinisanti fju " + _name; vector ints(_args.size(), Type::getInt32Ty(theContext)); FunctionType* FT; if (HasReturn()) FT = FunctionType::get(Type::getInt32Ty(theContext), ints, false); else FT = FunctionType::get(Type::getVoidTy(theContext), ints, false); TheFunction = Function::Create(FT, Function::ExternalLinkage, _name, theModule); unsigned i = 0; for (auto &arg : TheFunction->args()) arg.setName(_args[i++]); BasicBlock* BB = BasicBlock::Create(theContext, "entry", TheFunction); builder.SetInsertPoint(BB); namedValues.clear(); for (auto &arg : TheFunction->args()) { AllocaInst* tmp = createEntryBlockAlloca(TheFunction, arg.getName()); namedValues[arg.getName()] = tmp; builder.CreateStore(&arg, tmp); } if (Value *V = _code->Codegen()) { if (HasReturn()) { AllocaInst* alloca = namedValues[_result]; if (alloca == nullptr) return nullptr; Value* Val = builder.CreateLoad(alloca, _result); builder.CreateRet(Val); } else builder.CreateRetVoid(); verifyFunction(*TheFunction); theFPM->run(*TheFunction); return TheFunction; } TheFunction->eraseFromParent(); return nullptr; }