//Maybe try to use cpp stuff to get the output inside julia system (ccall,cgen and cgutils) //-| TODO: after adding in the jlapi.c jl_is_<C_type> functions replace the strcmp! SEXP jl_value_to_SEXP(jl_value_t *res) { size_t i=0,nd,d; SEXP resR; SEXPTYPE aryTyR; jl_value_t *tmp; char *resTy, *aryTy, *aryTy2; if(res!=NULL) { //=> get a result resTy=(char*)jl_typeof_str(res); //DANGEROUS?? printf("typeof=%s\n",jl_typeof_str(res)); if(strcmp(jl_typeof_str(res),"Int64")==0 || strcmp(jl_typeof_str(res),"Int32")==0) //if(jl_is_long(res)) //does not work because of DLLEXPORT { //printf("elt=%d\n",jl_unbox_long(res)); PROTECT(resR=NEW_INTEGER(1)); INTEGER_POINTER(resR)[0]=jl_unbox_long(res); UNPROTECT(1); return resR; } else if(strcmp(resTy,"Float64")==0) //if(jl_is_float64(res)) { PROTECT(resR=NEW_NUMERIC(1)); NUMERIC_POINTER(resR)[0]=jl_unbox_float64(res); UNPROTECT(1); return resR; } else if(strcmp(resTy,"Float32")==0) //if(jl_is_float64(res)) { PROTECT(resR=NEW_NUMERIC(1)); NUMERIC_POINTER(resR)[0]=jl_unbox_float32(res); UNPROTECT(1); return resR; } else if(strcmp(resTy,"Bool")==0) //if(jl_is_bool(res)) { PROTECT(resR=NEW_LOGICAL(1)); LOGICAL(resR)[0]=(jl_unbox_bool(res) ? TRUE : FALSE); UNPROTECT(1); return resR; } else if(strcmp(resTy,"DataType")==0) //if(jl_is_bool(res)) { PROTECT(resR=NEW_CHARACTER(1)); CHARACTER_POINTER(resR)[0]=mkChar(jl_typename_str(res)); UNPROTECT(1); return resR; } else if(strcmp(resTy,"Nothing")==0) //if(jl_is_bool(res)) { return R_NilValue; } else if(strcmp(resTy,"Complex")==0) //if(jl_is_bool(res)) { tmp=(jl_value_t*)jl_get_field(res, "re"); PROTECT(resR=NEW_COMPLEX(1)); if(strcmp(jl_typeof_str(tmp),"Float64")==0) { COMPLEX(resR)[0].r=jl_unbox_float64(tmp); COMPLEX(resR)[0].i=jl_unbox_float64(jl_get_field(res, "im")); } else if(strcmp(jl_typeof_str(tmp),"Int64")==0) { COMPLEX(resR)[0].r=jl_unbox_long(tmp); COMPLEX(resR)[0].i=jl_unbox_long(jl_get_field(res, "im")); } UNPROTECT(1); return resR; } else if(strcmp(resTy,"Regex")==0) //if(jl_is_bool(res)) { // call=(jl_function_t*)jl_get_global(jl_base_module, jl_symbol("show")); // printf("ici\n"); // if (call) tmp=jl_call1(call,res); // else printf("call failed!\n"); // printf("ici\n"); // resR = jl_value_to_VALUE(jl_get_field(res, "pattern")); // return resR; } else if(strcmp(resTy,"ASCIIString")==0 || strcmp(resTy,"UTF8String")==0) { PROTECT(resR=NEW_CHARACTER(1)); CHARACTER_POINTER(resR)[0]=mkChar(jl_bytestring_ptr(res)); UNPROTECT(1); return resR; } else if(strcmp(jl_typeof_str(res),"Tuple")==0 ) //if(jl_is_array(res)) { d=jl_nfields(res); //BEFORE 0.3: d=jl_tuple_len(res); PROTECT(resR=allocVector(VECSXP,d)); for(i=0;i<d;i++) { //BEFORE 0.3: SET_ELEMENT(resR,i,jl_value_to_SEXP(jl_tupleref(res,i))); SET_ELEMENT(resR,i,jl_value_to_SEXP(jl_fieldref(res,i))); } UNPROTECT(1); return resR; } if(strcmp(resTy,"Array")==0) //if(jl_is_array(res)) { nd = jl_array_rank(res); //Rprintf("array_ndims=%d\n",(int)nd); aryTy=(char*)jl_typename_str(jl_array_eltype(res)); aryTy2=(char*)jl_typeof_str(jl_array_eltype(res)); //Rprintf("type elt=%s,%s\n",aryTy,(char*)jl_typeof_str(jl_array_eltype(res))); if(strcmp(aryTy2,"DataType")!=0) return R_NilValue; if(strcmp(aryTy,"ASCIIString")==0 || strcmp(aryTy,"UTF8String")==0) aryTyR=STRSXP; else if(strcmp(aryTy,"Int64")==0 || strcmp(aryTy,"Int32")==0) aryTyR=INTSXP; else if(strcmp(aryTy,"Bool")==0) aryTyR=LGLSXP; else if(strcmp(aryTy,"Complex")==0) aryTyR=CPLXSXP; else if(strcmp(aryTy,"Float64")==0 || strcmp(aryTy,"Float32")==0) aryTyR=REALSXP; else aryTyR=VECSXP; if(nd==1) {//Vector d = jl_array_size(res, 0); //Rprintf("array_dim[1]=%d\n",(int)d); PROTECT(resR=allocVector(aryTyR,d)); for(i=0;i<d;i++) { switch(aryTyR) { case STRSXP: SET_STRING_ELT(resR,i,mkChar(jl_bytestring_ptr(jl_arrayref((jl_array_t *)res,i)))); break; case INTSXP: INTEGER(resR)[i]=jl_unbox_long(jl_arrayref((jl_array_t *)res,i)); break; case LGLSXP: LOGICAL(resR)[i]=(jl_unbox_bool(jl_arrayref((jl_array_t *)res,i)) ? TRUE : FALSE); break; case REALSXP: REAL(resR)[i]=jl_unbox_float64(jl_arrayref((jl_array_t *)res,i)); break; case CPLXSXP: tmp=(jl_value_t*)jl_get_field(jl_arrayref((jl_array_t *)res,i), "re"); if(strcmp(jl_typeof_str(tmp),"Float64")==0) { COMPLEX(resR)[i].r=jl_unbox_float64(tmp); COMPLEX(resR)[i].i=jl_unbox_float64(jl_get_field(jl_arrayref((jl_array_t *)res,i), "im")); } else if(strcmp(jl_typeof_str(tmp),"Int64")==0) { COMPLEX(resR)[i].r=jl_unbox_long(tmp); COMPLEX(resR)[i].i=jl_unbox_long(jl_get_field(jl_arrayref((jl_array_t *)res,i), "im")); } break; case VECSXP: SET_ELEMENT(resR,i,jl_value_to_SEXP(jl_arrayref((jl_array_t *)res,i))); } } UNPROTECT(1); return resR; } //TODO: multidim array ruby equivalent???? Is it necessary } return R_NilValue; /*PROTECT(resR=NEW_CHARACTER(1)); CHARACTER_POINTER(resR)[0]=mkChar(jl_typeof_str(res)); // resR=rb_str_new2("__unconverted("); // rb_str_cat2(resR, jl_typeof_str(res)); // rb_str_cat2(resR, ")__\n"); UNPROTECT(1); //printf("%s\n",jl_bytestring_ptr(jl_eval_string("\"$(ans)\""))); return resR;*/ } //=> No result (command incomplete or syntax error) // jlapi_print_stderr(); //If this happens but this is really not sure! // resR=rb_str_new2("__incomplete"); // if(jl_exception_occurred()!=NULL) { // rb_str_cat2(resR, "("); // rb_str_cat2(resR,jl_typeof_str(jl_exception_occurred())); // jl_value_t* err=jl_get_field(jl_exception_occurred(),"msg"); // if(err!=NULL) printf("%s: %s\n",jl_typeof_str(jl_exception_occurred()),jl_bytestring_ptr(err)); // jl_exception_clear(); // rb_str_cat2(resR, ")"); // } // rb_str_cat2(resR, "__"); return R_NilValue;//resR; }
static SEXP Julia_R_Scalar(jl_value_t *Var) { SEXP ans = R_NilValue; double tmpfloat; //most common type is here if (jl_is_int32(Var)) { PROTECT(ans = ScalarInteger(jl_unbox_int32(Var))); UNPROTECT(1); } else if (jl_is_int64(Var)) { tmpfloat=(double)jl_unbox_int64(Var); if (inInt32Range(tmpfloat)) PROTECT(ans = ScalarInteger((int32_t)jl_unbox_int64(Var))); else PROTECT(ans = ScalarReal(tmpfloat)); UNPROTECT(1); } //more integer type if (jl_is_uint32(Var)) { tmpfloat=(double)jl_unbox_uint32(Var); if (inInt32Range(tmpfloat)) PROTECT(ans = ScalarInteger((int32_t)jl_unbox_uint32(Var))); else PROTECT(ans = ScalarReal(tmpfloat)); UNPROTECT(1); } else if (jl_is_uint64(Var)) { tmpfloat=(double)jl_unbox_int64(Var); if (inInt32Range(tmpfloat)) PROTECT(ans = ScalarInteger((int32_t)jl_unbox_uint64(Var))); else PROTECT(ans = ScalarReal(tmpfloat)); UNPROTECT(1); } else if (jl_is_float64(Var)) { PROTECT(ans = ScalarReal(jl_unbox_float64(Var))); UNPROTECT(1); } else if (jl_is_float32(Var)) { PROTECT(ans = ScalarReal(jl_unbox_float32(Var))); UNPROTECT(1); } else if (jl_is_bool(Var)) { PROTECT(ans = ScalarLogical(jl_unbox_bool(Var))); UNPROTECT(1); } else if (jl_is_int8(Var)) { PROTECT(ans = ScalarInteger(jl_unbox_int8(Var))); UNPROTECT(1); } else if (jl_is_uint8(Var)) { PROTECT(ans = ScalarInteger(jl_unbox_uint8(Var))); UNPROTECT(1); } else if (jl_is_int16(Var)) { PROTECT(ans = ScalarInteger(jl_unbox_int16(Var))); UNPROTECT(1); } else if (jl_is_uint16(Var)) { PROTECT(ans = ScalarInteger(jl_unbox_uint16(Var))); UNPROTECT(1); } else if (jl_is_utf8_string(Var)) { PROTECT(ans = allocVector(STRSXP, 1)); SET_STRING_ELT(ans, 0, mkCharCE(jl_string_data(Var), CE_UTF8)); UNPROTECT(1); } else if (jl_is_ascii_string(Var)) { PROTECT(ans = ScalarString(mkChar(jl_string_data(Var)))); UNPROTECT(1); } return ans; }
template <> inline float unbox<float>(jl_value_t* val) { JULIACPP_ASSERT_NOMSG(jl_is_float32(val)); return jl_unbox_float32(val); }
// adapted from https://github.com/armgong/RJulia/blob/master/src/R_Julia.c SEXP jr_scalar(jl_value_t *tt) { SEXP ans = R_NilValue; double z; // float64, int64, int32 are most common, so put them in the front if (jl_is_float64(tt)) { PROTECT(ans = Rf_ScalarReal(jl_unbox_float64(tt))); UNPROTECT(1); } else if (jl_is_int32(tt)) { PROTECT(ans = Rf_ScalarInteger(jl_unbox_int32(tt))); UNPROTECT(1); } else if (jl_is_int64(tt)) { z = (double)jl_unbox_int64(tt); if (in_int32_range(z)) PROTECT(ans = Rf_ScalarInteger((int32_t)jl_unbox_int64(tt))); else PROTECT(ans = Rf_ScalarReal(z)); UNPROTECT(1); } else if (jl_is_bool(tt)) { PROTECT(ans = Rf_ScalarLogical(jl_unbox_bool(tt))); UNPROTECT(1); } else if (jl_is_int8(tt)) { PROTECT(ans = Rf_ScalarInteger(jl_unbox_int8(tt))); UNPROTECT(1); } else if (jl_is_uint8(tt)) { PROTECT(ans = Rf_ScalarInteger(jl_unbox_uint8(tt))); UNPROTECT(1); } else if (jl_is_int16(tt)) { PROTECT(ans = Rf_ScalarInteger(jl_unbox_int16(tt))); UNPROTECT(1); } else if (jl_is_uint16(tt)) { PROTECT(ans = Rf_ScalarInteger(jl_unbox_uint16(tt))); UNPROTECT(1); } else if (jl_is_uint32(tt)) { z = (double)jl_unbox_uint32(tt); if (in_int32_range(z)) PROTECT(ans = Rf_ScalarInteger((int32_t)jl_unbox_uint32(tt))); else PROTECT(ans = Rf_ScalarReal(z)); UNPROTECT(1); } else if (jl_is_uint64(tt)) { z = (double)jl_unbox_int64(tt); if (in_int32_range(z)) PROTECT(ans = Rf_ScalarInteger((int32_t)jl_unbox_uint64(tt))); else PROTECT(ans = Rf_ScalarReal(z)); UNPROTECT(1); } else if (jl_is_float32(tt)) { PROTECT(ans = Rf_ScalarReal(jl_unbox_float32(tt))); UNPROTECT(1); } else if (jl_is_utf8_string(tt)) { PROTECT(ans = Rf_allocVector(STRSXP, 1)); SET_STRING_ELT(ans, 0, Rf_mkCharCE(jl_string_data(tt), CE_UTF8)); UNPROTECT(1); } else if (jl_is_ascii_string(tt)) { PROTECT(ans = Rf_ScalarString(Rf_mkChar(jl_string_data(tt)))); UNPROTECT(1); } return ans; }
DLLEXPORT size_t jl_static_show(JL_STREAM *out, jl_value_t *v) { // mimic jl_show, but never calling a julia method size_t n = 0; if (v == NULL) { n += JL_PRINTF(out, "<null>"); } else if (jl_is_lambda_info(v)) { jl_lambda_info_t *li = (jl_lambda_info_t*)v; n += jl_static_show(out, (jl_value_t*)li->module); n += JL_PRINTF(out, ".%s", li->name->name); if (li->specTypes) { n += jl_static_show(out, (jl_value_t*)li->specTypes); } else { n += JL_PRINTF(out, "(?)"); } } else if (jl_is_tuple(v)) { n += jl_show_tuple(out, (jl_tuple_t*)v, "(", ")", 1); } else if (jl_is_vararg_type(v)) { n += jl_static_show(out, jl_tparam0(v)); n += JL_PRINTF(out, "..."); } else if (jl_is_datatype(v)) { jl_datatype_t *dv = (jl_datatype_t*)v; if (dv->name->module != jl_core_module) { n += jl_static_show(out, (jl_value_t*)dv->name->module); JL_PUTS(".", out); n += 1; } n += JL_PRINTF(out, "%s", dv->name->name->name); if (dv->parameters) { size_t j, tlen = jl_tuple_len(dv->parameters); if (tlen > 0) { n += JL_PRINTF(out, "{"); for (j = 0; j < tlen; j++) { jl_value_t *p = jl_tupleref(dv->parameters,j); n += jl_static_show(out, p); if (j != tlen-1) n += JL_PRINTF(out, ", "); } n += JL_PRINTF(out, "}"); } } } else if (jl_is_func(v)) { if (jl_is_gf(v)) { n += JL_PRINTF(out, "%s", jl_gf_name(v)->name); } else { n += JL_PRINTF(out, "<# function>"); } } else if (jl_typeis(v, jl_intrinsic_type)) { n += JL_PRINTF(out, "<# intrinsic function %d>", *(uint32_t*)jl_data_ptr(v)); } else if (jl_is_int64(v)) { n += JL_PRINTF(out, "%d", jl_unbox_int64(v)); } else if (jl_is_int32(v)) { n += JL_PRINTF(out, "%d", jl_unbox_int32(v)); } else if (jl_typeis(v,jl_int16_type)) { n += JL_PRINTF(out, "%d", jl_unbox_int16(v)); } else if (jl_typeis(v,jl_int8_type)) { n += JL_PRINTF(out, "%d", jl_unbox_int8(v)); } else if (jl_is_uint64(v)) { n += JL_PRINTF(out, "0x%016x", jl_unbox_uint64(v)); } else if (jl_is_uint32(v)) { n += JL_PRINTF(out, "0x%08x", jl_unbox_uint32(v)); } else if (jl_typeis(v,jl_uint16_type)) { n += JL_PRINTF(out, "0x%04x", jl_unbox_uint16(v)); } else if (jl_typeis(v,jl_uint8_type)) { n += JL_PRINTF(out, "0x%02x", jl_unbox_uint8(v)); } else if (jl_is_cpointer(v)) { #ifdef _P64 n += JL_PRINTF(out, "0x%016x", jl_unbox_voidpointer(v)); #else n += JL_PRINTF(out, "0x%08x", jl_unbox_voidpointer(v)); #endif } else if (jl_is_float32(v)) { n += JL_PRINTF(out, "%g", jl_unbox_float32(v)); } else if (jl_is_float64(v)) { n += JL_PRINTF(out, "%g", jl_unbox_float64(v)); } else if (v == jl_true) { n += JL_PRINTF(out, "true"); } else if (v == jl_false) { n += JL_PRINTF(out, "false"); } else if (jl_is_byte_string(v)) { n += JL_PRINTF(out, "\"%s\"", jl_iostr_data(v)); } else if (v == jl_bottom_type) { n += JL_PRINTF(out, "Void"); } else if (jl_is_uniontype(v)) { n += JL_PRINTF(out, "Union"); n += jl_static_show(out, (jl_value_t*)((jl_uniontype_t*)v)->types); } else if (jl_is_typector(v)) { n += jl_static_show(out, ((jl_typector_t*)v)->body); } else if (jl_is_typevar(v)) { n += JL_PRINTF(out, "%s", ((jl_tvar_t*)v)->name->name); } else if (jl_is_module(v)) { jl_module_t *m = (jl_module_t*)v; if (m->parent != m && m->parent != jl_main_module) { n += jl_static_show(out, (jl_value_t*)m->parent); n += JL_PRINTF(out, "."); } n += JL_PRINTF(out, "%s", m->name->name); } else if (jl_is_symbol(v)) { n += JL_PRINTF(out, ":%s", ((jl_sym_t*)v)->name); } else if (jl_is_symbolnode(v)) { n += JL_PRINTF(out, "%s::", jl_symbolnode_sym(v)->name); n += jl_static_show(out, jl_symbolnode_type(v)); } else if (jl_is_getfieldnode(v)) { n += jl_static_show(out, jl_getfieldnode_val(v)); n += JL_PRINTF(out, ".%s", jl_getfieldnode_name(v)->name); n += JL_PRINTF(out, "::"); n += jl_static_show(out, jl_getfieldnode_type(v)); } else if (jl_is_labelnode(v)) { n += JL_PRINTF(out, "%d:", jl_labelnode_label(v)); } else if (jl_is_gotonode(v)) { n += JL_PRINTF(out, "goto %d", jl_gotonode_label(v)); } else if (jl_is_quotenode(v)) { n += JL_PRINTF(out, "quote "); n += jl_static_show(out, jl_fieldref(v,0)); n += JL_PRINTF(out, " end"); } else if (jl_is_newvarnode(v)) { n += JL_PRINTF(out, "<newvar "); n += jl_static_show(out, jl_fieldref(v,0)); n += JL_PRINTF(out, ">"); } else if (jl_is_topnode(v)) { n += JL_PRINTF(out, "top("); n += jl_static_show(out, jl_fieldref(v,0)); n += JL_PRINTF(out, ")"); } else if (jl_is_linenode(v)) { n += JL_PRINTF(out, "# line %d", jl_linenode_line(v)); } else if (jl_is_expr(v)) { jl_expr_t *e = (jl_expr_t*)v; if (e->head == assign_sym && jl_array_len(e->args) == 2) { n += jl_static_show(out, jl_exprarg(e,0)); n += JL_PRINTF(out, " = "); n += jl_static_show(out, jl_exprarg(e,1)); } else { char sep = ' '; if (e->head == body_sym) sep = '\n'; n += JL_PRINTF(out, "Expr(:%s", e->head->name); size_t i, len = jl_array_len(e->args); for (i = 0; i < len; i++) { n += JL_PRINTF(out, ",%c", sep); n += jl_static_show(out, jl_exprarg(e,i)); } n += JL_PRINTF(out, ")::"); n += jl_static_show(out, e->etype); } } else if (jl_is_array(v)) { n += jl_static_show(out, jl_typeof(v)); n += JL_PRINTF(out, "["); size_t j, tlen = jl_array_len(v); for (j = 0; j < tlen; j++) { n += jl_static_show(out, jl_arrayref((jl_array_t*)v,j)); if (j != tlen-1) n += JL_PRINTF(out, ", "); } n += JL_PRINTF(out, "]"); } else if (jl_typeis(v,jl_loaderror_type)) { n += JL_PRINTF(out, "LoadError(at "); n += jl_static_show(out, jl_fieldref(v, 0)); n += JL_PRINTF(out, " line "); n += jl_static_show(out, jl_fieldref(v, 1)); n += JL_PRINTF(out, ": "); n += jl_static_show(out, jl_fieldref(v, 2)); n += JL_PRINTF(out, ")"); } else if (jl_typeis(v,jl_errorexception_type)) { n += JL_PRINTF(out, "ErrorException("); n += jl_static_show(out, jl_fieldref(v, 0)); n += JL_PRINTF(out, ")"); } else if (jl_is_datatype(jl_typeof(v))) { jl_datatype_t *t = (jl_datatype_t*)jl_typeof(v); n += jl_static_show(out, (jl_value_t*)t); n += JL_PRINTF(out, "("); size_t nb = jl_datatype_size(t); size_t tlen = jl_tuple_len(t->names); if (nb > 0 && tlen == 0) { char *data = (char*)jl_data_ptr(v); n += JL_PRINTF(out, "0x"); for(int i=nb-1; i >= 0; --i) n += JL_PRINTF(out, "%02hhx", data[i]); } else { jl_value_t *fldval=NULL; JL_GC_PUSH1(&fldval); for (size_t i = 0; i < tlen; i++) { n += JL_PRINTF(out, ((jl_sym_t*)jl_tupleref(t->names, i))->name); //jl_fielddesc_t f = t->fields[i]; n += JL_PRINTF(out, "="); fldval = jl_get_nth_field(v, i); n += jl_static_show(out, fldval); if (i != tlen-1) n += JL_PRINTF(out, ", "); } JL_GC_POP(); } n += JL_PRINTF(out, ")"); } else { n += JL_PRINTF(out, "<?::"); n += jl_static_show(out, jl_typeof(v)); n += JL_PRINTF(out, ">"); } return n; }