llvm::Value * CodeGen::generateCodeValue(ValueAST *ast) { addScope(ast->name); llvm::Value * exprCode = generateCodeExpr(ast->expr.get()); removeScope(); addScopedValue(ast->name, exprCode); return exprCode; }
/** Destrutor da classe. */ SymbolTable::~SymbolTable() { list<IdentifierInformation*>::const_iterator it = identifierInfoList_.begin(); while(it != identifierInfoList_.end()) { // Desaloca objetos de informações (Information) armazenados na Tabela de Símbolos. delete (*it); it++; } while(!scopeList_.empty()) { delete removeScope(); } }
llvm::Function * CodeGen::generateCodeDef(DefAST *ast) { // add def name to scope addScope(ast->name); // argument types vector<llvm::Type*> args(ast->args.size(), llvm::Type::getDoubleTy(context)); // return type auto retType = llvm::Type::getDoubleTy(context); // complete function type llvm::FunctionType *funcType = llvm::FunctionType::get(retType, args, false); llvm::Function * func = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, ast->name, module.get()); unsigned i = 0; for (auto funcarg = func->arg_begin(); i != ast->args.size(); ++funcarg, ++i) { funcarg->setName(ast->args[i]); addScopedValue(ast->args[i], funcarg); } llvm::BasicBlock *block = llvm::BasicBlock::Create(context, "entry", func); Builder.SetInsertPoint(block); if (llvm::Value * result = generateCodeExpr(ast->body.get())) { Builder.CreateRet(result); string verifyS; llvm::raw_string_ostream verifyE(verifyS); if (verifyFunction(*func, &verifyE)) { func->eraseFromParent(); error = "something wrong with function \"" + ast->name + "\": " + verifyS; return nullptr; } // remove the def name scope removeScope(); return func; } else { func->eraseFromParent(); error = "error creating function body: " + error; return nullptr; } }
/** Removes the group from a specific scope **/ bool LithneClass::removeScope( String _group ) { return removeScope( hash(_group) ); }
bool CodeGen::wrapTopLevelBlockInMain(BlockAST *ast) { // add main to scope addScope("main"); vector<unique_ptr<ASTNode> > * body = ast->body.get(); // generate void main() llvm::FunctionType *voidType = llvm::FunctionType::get(Builder.getVoidTy(), false); llvm::Function *mainFunc = llvm::Function::Create(voidType, llvm::Function::ExternalLinkage, "main", module.get()); // basic block for the top level block llvm::BasicBlock *MainBlock = llvm::BasicBlock::Create(context, "entry", mainFunc); Builder.SetInsertPoint(MainBlock); llvm::Value * lastExpr; for (auto it = body->begin() ; it != body->end(); ++it) { ASTNode * node = it->get(); if (auto x = dynamic_cast<ValueAST*>(node)) { auto code = generateCodeValue(x); if (!code) return false; } else if (auto x = dynamic_cast<DefAST*>(node)) { generateCodeDef(x); Builder.SetInsertPoint(MainBlock); } else if (auto x = dynamic_cast<NumberExprAST*>(node)) { auto code = generateCodeNumber(x); if (!code) return false; lastExpr = code; } else if (auto x = dynamic_cast<BinaryExprAST*>(node)) { auto code = generateCodeBinOp(x); if (!code) return false; lastExpr = code; } else if (auto x = dynamic_cast<CallAST*>(node)) { auto code = generateCodeCall(x); if (!code) return false; lastExpr = code; } else { error = "can't handle ast"; return false; } } llvm::Value *fmt = Builder.CreateGlobalStringPtr("%lg\n"); vector<llvm::Type *> putsArgs; putsArgs.push_back(Builder.getInt8Ty()->getPointerTo()); llvm::ArrayRef<llvm::Type*> argsRef(putsArgs); llvm::FunctionType *putsType = llvm::FunctionType::get(Builder.getInt32Ty(), argsRef, true); llvm::Constant *putsFunc = module->getOrInsertFunction("printf", putsType); vector<llvm::Value *> CallArgs; CallArgs.push_back(fmt); CallArgs.push_back(lastExpr); Builder.CreateCall(putsFunc, CallArgs); Builder.CreateRetVoid(); string verifyS; llvm::raw_string_ostream verifyE(verifyS); if (verifyFunction(*mainFunc, &verifyE)) { mainFunc->eraseFromParent(); error = "something wrong with auto-generated main function: " + verifyS; return false; } // remove the main scope removeScope(); return true; }