#include "ast.hpp" #include Module *TheModule; LLVMContext TheContext; map NamedValues; IRBuilder<> Builder(TheContext); Value* NumberExprAST::codegen() const { return ConstantFP::get(TheContext, APFloat(_val)); } Value* VariableExprAST::codegen() const { Value *v = NamedValues[_name]; if (!v) { cerr << "Nepostojeca promenljiva" << endl; return nullptr; } return v; } Value* BinaryExprAST::codegen() const { Value *l = _lhs->codegen(); Value *r = _rhs->codegen(); if (!l || !r) return nullptr; switch(_op) { case '+': return Builder.CreateFAdd(l, r, "tmpadd"); case '*': return Builder.CreateFMul(l, r, "tmpmul"); case '-': return Builder.CreateFSub(l, r, "tmpsub"); default: return nullptr; } } Value* CallExprAST::codegen() const { Function *f = TheModule->getFunction(_name); if (!f) { cerr << "Funkcija " << _name << "Nije definisana" << endl; return nullptr; } if (f->arg_size() != _exps.size()) { cerr << "Poziv fje " << _name << "nema " << f->arg_size() << "argumenatar" << endl; return nullptr; } vector argV; for (auto e : _exps) { argV.push_back(e->codegen()); if (!argV.back()) return nullptr; } return Builder.CreateCall(f, argV, "calltmp"); } Value* PrototypeAST::codegen() const { vector v(_args.size(), Type::getDoubleTy(TheContext)); FunctionType* fp = FunctionType::get(Type::getDoubleTy(TheContext), v, false); Function* f = Function::Create(fp, Function::ExternalLinkage, _name, TheModule); int j = 0; for (auto &a : f->args()) a.setName(_args[j++]); return f; } Value* FunctionAST::codegen() const { Function* TheFunction = TheModule->getFunction(_proto.getName()); if (!TheFunction) TheFunction = (Function*)_proto.codegen(); if (!TheFunction) return nullptr; BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction); Builder.SetInsertPoint(BB); NamedValues.clear(); for (auto &a: TheFunction->args()) NamedValues[a.getName()] = &a; if (Value *ret = _definition->codegen()) { Builder.CreateRet(ret); verifyFunction(*TheFunction); } else { TheFunction->eraseFromParent(); return nullptr; } }