Example #1
0
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;
}
Example #2
0
File: toy.cpp Project: MatzeB/llvm
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;
}
Example #3
0
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");
  }
}
Example #4
0
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;
}
Example #5
0
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");
}
Example #6
0
File: toy.cpp Project: aaasz/SHP
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");
}
Example #7
0
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");
}
Example #8
0
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);
  }
}
Example #9
0
File: toy.cpp Project: aaasz/SHP
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()));
}
Example #10
0
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;


    }
}
Example #11
0
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));
}
Example #12
0
int FAO::Compute()
{
	ExprAST * tree = ParseExpression();
	return tree->GetValue();
}