本文整理汇总了C++中ExprAST类的典型用法代码示例。如果您正苦于以下问题:C++ ExprAST类的具体用法?C++ ExprAST怎么用?C++ ExprAST使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了ExprAST类的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: APFloat
Value *VarExprAST::codegen() {
std::vector<AllocaInst *> OldBindings;
Function *TheFunction = Builder->GetInsertBlock()->getParent();
// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
const std::string &VarName = VarNames[i].first;
ExprAST *Init = VarNames[i].second.get();
// Emit the initializer before adding the variable to scope, this prevents
// the initializer from referencing the variable itself, and permits stuff
// like this:
// var a = 1 in
// var a = a in ... # refers to outer 'a'.
Value *InitVal;
if (Init) {
InitVal = Init->codegen();
if (!InitVal)
return nullptr;
} else { // If not specified, use 0.0.
InitVal = ConstantFP::get(*TheContext, APFloat(0.0));
}
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
Builder->CreateStore(InitVal, Alloca);
// Remember the old variable binding so that we can restore the binding when
// we unrecurse.
OldBindings.push_back(NamedValues[VarName]);
// Remember this binding.
NamedValues[VarName] = Alloca;
}
// Codegen the body, now that all vars are in scope.
Value *BodyVal = Body->codegen();
if (!BodyVal)
return nullptr;
// Pop all our variables from scope.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
NamedValues[VarNames[i].first] = OldBindings[i];
// Return the body computation.
return BodyVal;
}
示例2: switch
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
if (L == 0 || R == 0) return 0;
switch (Op) {
case '+': return Builder.CreateFAdd(L, R, "addtmp");
case '-': return Builder.CreateFSub(L, R, "subtmp");
case '*': return Builder.CreateFMul(L, R, "multmp");
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
"booltmp");
default: return ErrorV("invalid binary operator");
}
}
示例3: APFloat
Value *LetExprAST::Codegen() {
AllocaInst * OldBinding;
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Register all variables and emit their initializer.
const std::string &VarName = VarNameValue.first;
ExprAST *Init = VarNameValue.second;
// Emit the initializer before adding the variable to scope, this prevents
// the initializer from referencing the variable itself, and permits stuff
// like this:
// var a = 1 in
// var a = a in ... # refers to outer 'a'.
Value *InitVal;
if (Init) {
InitVal = Init->Codegen();
if (InitVal == 0)
return 0;
} else { // If not specified, use 0.0.
InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
}
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
Builder.CreateStore(InitVal, Alloca);
// Remember the old variable binding so that we can restore the binding when
// we unrecurse.
OldBinding = NamedValues[VarName];
// Remember this binding.
NamedValues[VarName] = Alloca;
// Codegen the body, now that all vars are in scope.
Value *BodyVal = Body->Codegen();
if (BodyVal == 0)
return 0;
// Pop all our variables from scope.
NamedValues[VarNameValue.first] = OldBinding;
// Return the body computation.
return BodyVal;
}
示例4: ErrorV
Value *BinaryExprAST::Codegen() {
// Special case '=' because we don't want to emit the LHS as an expression.
if (Op == '=') {
// Assignment requires the LHS to be an identifier.
VariableExprAST *LHSE = dynamic_cast<VariableExprAST*>(LHS);
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
Value *Val = RHS->Codegen();
if (Val == 0) return 0;
// Look up the name.
Value *Variable = NamedValues[LHSE->getName()];
if (Variable == 0) return ErrorV("Unknown variable name");
Builder.CreateStore(Val, Variable);
return Val;
}
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
if (L == 0 || R == 0) return 0;
switch (Op) {
case '+': return Builder.CreateAdd(L, R, "addtmp");
case '-': return Builder.CreateSub(L, R, "subtmp");
case '*': return Builder.CreateMul(L, R, "multmp");
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
"booltmp");
default: break;
}
// If it wasn't a builtin binary operator, it must be a user defined one. Emit
// a call to it.
Function *F = TheModule->getFunction(std::string("binary")+Op);
assert(F && "binary operator not found!");
Value *Ops[] = { L, R };
return Builder.CreateCall(F, Ops, Ops+2, "binop");
}
示例5: ErrorV
Value *UnaryExprAST::Codegen() {
Value *OperandV = Operand->Codegen();
if (OperandV == 0) return 0;
Function *F = TheModule->getFunction(std::string("unary")+Opcode);
if (F == 0)
return ErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
}
示例6: ErrorV
Value *UnaryExprAST::Codegen() {
Value *OperandV = Operand->Codegen();
if (OperandV == 0) return 0;
#ifdef USE_MCJIT
Function *F = TheHelper->getFunction(MakeLegalFunctionName(std::string("unary")+Opcode));
#else
Function *F = TheModule->getFunction(std::string("unary")+Opcode);
#endif
if (F == 0)
return ErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
}
示例7: switch
StatementAST* Parser::statement() {
switch(this->_tok.type()){
case TokenType::IF:
return this->ifstatement();
case TokenType::FOR:
return this->forstatement();
case TokenType::WHILE:
return this->whilestatement();
case TokenType::REPEAT:
return this->repeatstatement();
//AFFECTATION OR EXPRESSION STATEMENTS
default:
ExprAST* expr = this->expression();
if(!expr) return nullptr;
if(this->_tok == TokenType::AFFECT){
//verifie que expr est une variable.
if (!expr->isVar()) {
Logger::error << this->getErrorHeader() << *expr
<< this->getErrorHeader() << " is not a variable." << std::endl;
exit(EXIT_FAILURE);
}
// On consumme l'affectation
this->eatToken();
ExprAST* affectedExpr = this->expression();
if(!affectedExpr) return nullptr;
return new AffectationAST((VariableAST*) expr, affectedExpr);
}
//sinon l'expression doit se terminer a la fin de la ligne ou du fichier
if(this->_tok!=TokenType::ENDF && !this->eatToken(TokenType::ENDL)) return nullptr;
return new StatementExprAST(expr);
}
}
示例8: getNullValue
Value *ForExprAST::Codegen() {
// Output this as:
// ...
// start = startexpr
// goto loop
// loop:
// variable = phi [start, loopheader], [nextvariable, loopend]
// ...
// bodyexpr
// ...
// loopend:
// step = stepexpr
// nextvariable = variable + step
// endcond = endexpr
// br endcond, loop, endloop
// outloop:
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
if (StartVal == 0) return 0;
// Make the new basic block for the loop header, inserting after current
// block.
Function *TheFunction = Builder.GetInsertBlock()->getParent();
BasicBlock *PreheaderBB = Builder.GetInsertBlock();
BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
// Start insertion in LoopBB.
Builder.SetInsertPoint(LoopBB);
// Start the PHI node with an entry for Start.
PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), VarName.c_str());
Variable->addIncoming(StartVal, PreheaderBB);
// Within the loop, the variable is defined equal to the PHI node. If it
// shadows an existing variable, we have to restore it, so save it now.
Value *OldVal = NamedValues[VarName];
NamedValues[VarName] = Variable;
// Emit the body of the loop. This, like any other expr, can change the
// current BB. Note that we ignore the value computed by the body, but don't
// allow an error.
if (Body->Codegen() == 0)
return 0;
// Emit the step value.
Value *StepVal;
if (Step) {
StepVal = Step->Codegen();
if (StepVal == 0) return 0;
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
}
Value *NextVar = Builder.CreateAdd(Variable, StepVal, "nextvar");
// Compute the end condition.
Value *EndCond = End->Codegen();
if (EndCond == 0) return EndCond;
// Convert condition to a bool by comparing equal to 0.0.
EndCond = Builder.CreateFCmpONE(EndCond,
ConstantFP::get(getGlobalContext(), APFloat(0.0)),
"loopcond");
// Create the "after loop" block and insert it.
BasicBlock *LoopEndBB = Builder.GetInsertBlock();
BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
// Any new code will be inserted in AfterBB.
Builder.SetInsertPoint(AfterBB);
// Add a new entry to the PHI node for the backedge.
Variable->addIncoming(NextVar, LoopEndBB);
// Restore the unshadowed variable.
if (OldVal)
NamedValues[VarName] = OldVal;
else
NamedValues.erase(VarName);
// for expr always returns 0.0.
return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
}
示例9: transform_to_lambda_calculus
ExprAST* transform_to_lambda_calculus(ExprAST* expr)
{
switch(expr->getAST_Type())
{
//Non-Lambda
case ExprAST::Function:
{
FunctionAST* func = (FunctionAST*)expr;
std::cout << "Before Lambda-Calculus Conversion: " << std::endl;
func->print();
LambdaAST* lambda;
std::vector<PrototypeAST*> protos;
if(func->proto->args.size()>0)
{
for(int i=0;i<func->proto->args.size();++i)
{
std::vector<std::string> args;
args.push_back(func->proto->args.at(i));
PrototypeAST* proto = new PrototypeAST("",args);
proto = new PrototypeAST("",args);
protos.push_back(proto);
}
for(int i=protos.size()-1;i>=0;i-=1)
{
if(i<protos.size()-1)
{
lambda = new LambdaAST(protos.at(i),lambda);
}
else
{
ExprAST* lambda_body = transform_to_lambda_calculus(func->body);
lambda = new LambdaAST(protos.at(i),lambda_body);
}
}
}
else
{
std::vector<std::string> args;
PrototypeAST* proto = new PrototypeAST("",args);
ExprAST* lambda_body = transform_to_lambda_calculus(func->body);
lambda = new LambdaAST(proto,lambda_body);
}
LetAST* let = new LetAST(func->proto->name,lambda);
std::cout << "After Lambda-Calculus Conversion: " << std::endl;
let->print();
return let;
}
break;
case ExprAST::FunctionCall:
{
CallExprAST* func_call = (CallExprAST*)expr;
std::cout << "Before Lambda-Calculus Conversion: " << std::endl;
func_call->print();
std::cout << std::endl;
ExprAST* apply = new VariableExprAST(func_call->callee);
for(int i=0;i<func_call->args.size();++i)
{
ExprAST* transformed_arg = transform_to_lambda_calculus(func_call->args.at(i));
apply = new ApplyAST(apply,transformed_arg);
}
std::cout << "After Lambda-Calculus Conversion: " << std::endl;
apply->print();
std::cout << std::endl;
return apply;
}
break;
case ExprAST::BinaryOp:
{
BinaryExprAST* bin_op = (BinaryExprAST*)expr;
ExprAST* lhs = transform_to_lambda_calculus(bin_op->lhs);
ExprAST* rhs = transform_to_lambda_calculus(bin_op->rhs);
return new BinaryExprAST(bin_op->op,lhs,rhs);
}
case ExprAST::Number:
case ExprAST::Char:
case ExprAST::True:
case ExprAST::False:
case ExprAST::Variable:
//Lambda
case ExprAST::Lambda:
case ExprAST::Let:
case ExprAST::LetRec:
case ExprAST::Apply:
return expr;
case ExprAST::Prototype:
out() << "Error Parsing AST, received PrototypeExprAST in lambda calculus conversion." << std::endl;
correct_parsing = false;
return expr;
//.........这里部分代码省略.........
示例10: getNullValue
Value *ForExprAST::Codegen() {
// Output this as:
// var = alloca double
// ...
// start = startexpr
// store start -> var
// goto loop
// loop:
// ...
// bodyexpr
// ...
// loopend:
// step = stepexpr
// endcond = endexpr
//
// curvar = load var
// nextvar = curvar + step
// store nextvar -> var
// br endcond, loop, endloop
// outloop:
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create an alloca for the variable in the entry block.
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
if (StartVal == 0) return 0;
// Store the value into the alloca.
Builder.CreateStore(StartVal, Alloca);
// Make the new basic block for the loop header, inserting after current
// block.
BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
// Start insertion in LoopBB.
Builder.SetInsertPoint(LoopBB);
// Within the loop, the variable is defined equal to the PHI node. If it
// shadows an existing variable, we have to restore it, so save it now.
AllocaInst *OldVal = NamedValues[VarName];
NamedValues[VarName] = Alloca;
// Emit the body of the loop. This, like any other expr, can change the
// current BB. Note that we ignore the value computed by the body, but don't
// allow an error.
if (Body->Codegen() == 0)
return 0;
// Emit the step value.
Value *StepVal;
if (Step) {
StepVal = Step->Codegen();
if (StepVal == 0) return 0;
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(TheContext, APFloat(1.0));
}
// Compute the end condition.
Value *EndCond = End->Codegen();
if (EndCond == 0) return EndCond;
// Reload, increment, and restore the alloca. This handles the case where
// the body of the loop mutates the variable.
Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
Builder.CreateStore(NextVar, Alloca);
// Convert condition to a bool by comparing equal to 0.0.
EndCond = Builder.CreateFCmpONE(
EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
// Create the "after loop" block and insert it.
BasicBlock *AfterBB =
BasicBlock::Create(TheContext, "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
// Any new code will be inserted in AfterBB.
Builder.SetInsertPoint(AfterBB);
// Restore the unshadowed variable.
if (OldVal)
NamedValues[VarName] = OldVal;
else
NamedValues.erase(VarName);
// for expr always returns 0.0.
return Constant::getNullValue(Type::getDoubleTy(TheContext));
}
示例11: ParseExpression
int FAO::Compute()
{
ExprAST * tree = ParseExpression();
return tree->GetValue();
}
示例12: verifyFunction
Function *FunctionAST::Codegen() {
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
if (TheFunction == 0)
return 0;
// If this is an operator, install it.
if (Proto->isBinaryOp())
BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence();
// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Add all arguments to the symbol table and create their allocas.
Proto->CreateArgumentAllocas(TheFunction);
if (Value *RetVal = Body->Codegen()) {
// Finish off the function.
Builder.CreateRet(RetVal);
// Validate the generated code, checking for consistency.
verifyFunction(*TheFunction);
return TheFunction;
}
// Error reading body, remove function.
TheFunction->eraseFromParent();
if (Proto->isBinaryOp())
BinopPrecedence.erase(Proto->getOperatorName());
return 0;
}