Rcpp Version 0.9.10
Evaluator.cpp
Go to the documentation of this file.
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
00002 //
00003 // Evaluator.cpp: Rcpp R/C++ interface class library -- evaluator
00004 //
00005 // Copyright (C) 2009 - 2012  Dirk Eddelbuettel and Romain Francois
00006 //
00007 // This file is part of Rcpp.
00008 //
00009 // Rcpp is free software: you can redistribute it and/or modify it
00010 // under the terms of the GNU General Public License as published by
00011 // the Free Software Foundation, either version 2 of the License, or
00012 // (at your option) any later version.
00013 //
00014 // Rcpp is distributed in the hope that it will be useful, but
00015 // WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with Rcpp.  If not, see <http://www.gnu.org/licenses/>.
00021 
00022 #include <Rcpp/Evaluator.h>
00023 
00024 void maybe_init() ;
00025 
00026 namespace Rcpp {
00027 
00028     SEXP Evaluator::run(SEXP expr, SEXP env) {
00029         PROTECT(expr);
00030 
00031         maybe_init() ;
00032         reset_current_error() ; 
00033 
00034         Environment RCPP = Environment::Rcpp_namespace(); 
00035         static SEXP rcpp_tryCatchSym = NULL, evalqSym, errorOccuredSym, getCurrentErrorMessageSym;
00036         if (!rcpp_tryCatchSym) {
00037             rcpp_tryCatchSym          = ::Rf_install("rcpp_tryCatch");
00038             evalqSym                  = ::Rf_install("evalq");
00039             errorOccuredSym           = ::Rf_install("errorOccured");
00040             getCurrentErrorMessageSym = ::Rf_install("getCurrentErrorMessage");
00041         }
00042 
00043         SEXP call = PROTECT(::Rf_lang2(rcpp_tryCatchSym, PROTECT(::Rf_lang3(evalqSym, expr, env))));
00044         /* call the tryCatch call */
00045         SEXP res  = PROTECT(::Rf_eval( call, RCPP ) );
00046         
00047         /* was there an error ? */
00048         int error = ::Rf_asLogical(PROTECT(::Rf_eval(PROTECT(::Rf_lang1(errorOccuredSym)), RCPP)));
00049         UNPROTECT(2) ;
00050         
00051         if( error ) {
00052             std::string 
00053                 message(CHAR(::Rf_asChar(PROTECT(::Rf_eval(
00054                                                      PROTECT(::Rf_lang1(getCurrentErrorMessageSym)),
00055                                                      RCPP)))));
00056             UNPROTECT( 6 ) ;
00057             throw eval_error(message) ;
00058         }
00059 
00060         UNPROTECT(4) ;
00061         return res ;
00062     }
00063 
00064     
00065     SEXP Evaluator::run( SEXP expr) {
00066         return run(expr, R_GlobalEnv );
00067     }
00068     
00069     namespace internal{
00070         /* this is defined here because we need to be sure that Evaluator is defined */
00071         SEXP convert_using_rfunction(SEXP x, const char* const fun) {
00072             SEXP res = R_NilValue ;
00073             try{
00074                 SEXP funSym = Rf_install(fun);
00075                 res = Evaluator::run( Rf_lang2( funSym, x ) ) ;
00076             } catch( eval_error& e){
00077                 throw ::Rcpp::not_compatible( std::string("could not convert using R function : ") + fun  ) ;
00078             }
00079             return res;
00080         }
00081     
00082         SEXP try_catch( SEXP expr, SEXP env ) {
00083             return Evaluator::run(expr, env) ;
00084         }
00085         SEXP try_catch( SEXP expr ) {
00086             return Evaluator::run(expr) ;
00087         }
00088     
00089     } // namespace internal
00090     
00091 } // namespace Rcpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines