llvm::BasicBlock* SwitchExpression::HandleDefault(std::map<std::string, llvm::BasicBlock*>& association, WasmFunction* fct, llvm::IRBuilder<>& builder) const {
    // So the default block can be defined by a case node or an expression node.

    VariableCaseDefinition* variable_def = dynamic_cast<VariableCaseDefinition*>(default_);

    if (variable_def != nullptr) {
        // Then return the pointer from the association, it should have been created.
        return association[variable_def->GetString()];
    }

    // Otherwise we have a ExpressionCaseDefinition.
    ExpressionCaseDefinition* expr_case = dynamic_cast<ExpressionCaseDefinition*>(default_);
    assert(expr_case != nullptr);

    Expression* expr = expr_case->GetExpression();

    // Create a block for it.
    BasicBlock* default_code  = BasicBlock::Create(llvm::getGlobalContext(), "default", fct->GetFunction());
    builder.SetInsertPoint(default_code);

    // Now generate the code.
    expr->Codegen(fct, builder);

    // Now return the block.
    return default_code;
}
llvm::Value* BlockExpression::Codegen(WasmFunction* fct, llvm::IRBuilder<>& builder) {
  // For now, there is no reason to really care about block.
  for (std::list<Expression*>::const_iterator it = list_->begin(); it != list_->end(); it++) {
    Expression* expr = *it;
    expr->Codegen(fct, builder);
  }

  return nullptr;
}
void WasmScript::GenerateGeneralScriptCalls(WasmFile* file) {
  // Now generate this function prototype: execute_script:
    // Returns a integer is the result of all script.
    //  If successful, returns -1.
    //  It will fail otherwise and return the line number of the failure.

  // This method has no parameters.
  std::vector<llvm::Type*> params;

  // Then get the result: integer.
  llvm::Type* result_type = llvm::Type::getInt32Ty(llvm::getGlobalContext());
  WasmModule* wasm_module = file->GetAssertModule();
  llvm::Module* module = wasm_module->GetModule();

  // Finally, create the function type.
  llvm::FunctionType* fct_type = llvm::FunctionType::get(result_type, params, false);
  const char* name = "execute_script";
  llvm::Function* fct = llvm::Function::Create(fct_type, Function::ExternalLinkage, name, module);

  // Now create the first bb.
  llvm::BasicBlock* bb = llvm::BasicBlock::Create(getGlobalContext(), "entry", fct);
  llvm::IRBuilder<> builder(getGlobalContext());
  builder.SetInsertPoint(bb);

  WasmFunction* wasm_fct = new WasmFunction(nullptr, name, fct, wasm_module, INT_32);
  const char* result_name = "result";
  Variable* result = new Variable(result_name);
  wasm_fct->Allocate(result_name,
                         llvm::Type::getInt32Ty(llvm::getGlobalContext()),
                         builder);

  // Now generate our IR and then use our codegen for it.
  for (auto elem : script_elems_) {
    Expression* expr = nullptr;

    if (dynamic_cast<WasmInvoke*>(elem) != nullptr) {
      expr = HandleInvoke(elem);
    } else {
      CallExpression* call = HandleAssert(wasm_module, elem);

      // Set the value in a local.
      SetLocal* set = new SetLocal(result, call);

      // In the assert_return case, we want to compare this to -1.
      Const* minus_one = new Const(INT_32, new ValueHolder(-1));
      Operation* op = new Operation(NE_OPER, INT_32);
      Binop* cmp = new Binop(op, set, minus_one);

      // Now we can generate the return 0;
      GetLocal* get = new GetLocal(result);
      ReturnExpression* return_expr = new ReturnExpression(get);

      // Finally, generate the AST for this assert.
      IfExpression* inst = new IfExpression(cmp, return_expr);

      expr = inst;
    }

    // Now we can generate it.
    expr->Codegen(wasm_fct, builder);

    delete expr, expr = nullptr;
  }

  Const* one = new Const(INT_32,
      new ValueHolder(-1));
  ReturnExpression* return_expr = new ReturnExpression(one);

  return_expr->Codegen(wasm_fct, builder);

  delete return_expr, return_expr = nullptr;
}