#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 "Nije dozvoljeno redefinisanje fje" + _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 idx = 0; for (auto &arg : theFunction->args()) arg.setName(_args[idx++]); if (!theFunction) return nullptr; BasicBlock *BB = BasicBlock::Create(theContext, "entry", theFunction); builder.SetInsertPoint(BB); namedValues.clear(); for (auto &arg : theFunction->args()) { AllocaInst* alloca = createEntryBlockAlloca(theFunction, arg.getName()); builder.CreateStore(&arg, alloca); namedValues[arg.getName()] = alloca; } if (_code->Codegen()) { if (HasReturn()) { AllocaInst* alloca = namedValues[_result]; if (alloca == nullptr) throw "Nije postavljen rezultat " + _result + " fje " + _name; Value *v = builder.CreateLoad(alloca, _result); builder.CreateRet(v); } else builder.CreateRetVoid(); verifyFunction(*theFunction); theFPM->run(*theFunction); return theFunction; } theFunction->eraseFromParent(); return nullptr; }