From 653bb73ce350640c7dd5bc4c92e244e957c65483 Mon Sep 17 00:00:00 2001 From: Mick Jordan <mick.jordan@oracle.com> Date: Wed, 22 Jun 2016 16:22:10 -0700 Subject: [PATCH] implement R_ParseVector --- .../fficall/src/jni/Parse.c | 20 +++++++++-- .../fficall/src/jni/rfficall.c | 1 + .../fficall/src/jni/rffiutils.h | 1 + .../r/runtime/ffi/jnr/CallRFFIHelper.java | 36 +++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Parse.c b/com.oracle.truffle.r.native/fficall/src/jni/Parse.c index 387a7b43cb..c1b33f9e43 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Parse.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Parse.c @@ -23,6 +23,22 @@ #include <rffiutils.h> #include <R_ext/Parse.h> -SEXP R_ParseVector(SEXP x, int y, ParseStatus *z, SEXP w) { - return unimplemented("R_ParseVector"); +static jmethodID parseMethodID; +static jclass parseResultClass; +static jfieldID parseStatusFieldID; +static jfieldID parseExprFieldID; + + +void init_parse(JNIEnv *env) { + parseMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_ParseVector", "(Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;", 1); + parseResultClass = checkFindClass(env, "com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper$ParseResult"); + parseStatusFieldID = checkGetFieldID(env, parseResultClass, "parseStatus", "I", 0); + parseExprFieldID = checkGetFieldID(env, parseResultClass, "expr", "Ljava/lang/Object;", 0); +} + +SEXP R_ParseVector(SEXP text, int n, ParseStatus *z, SEXP srcfile) { + JNIEnv *env = getEnv(); + jobject result = (*env)->CallStaticObjectMethod(env, CallRFFIHelperClass, parseMethodID, text, n, srcfile); + *z = (*env)->GetObjectField(env, result, parseStatusFieldID); + return (*env)->GetObjectField(env, result, parseExprFieldID); } diff --git a/com.oracle.truffle.r.native/fficall/src/jni/rfficall.c b/com.oracle.truffle.r.native/fficall/src/jni/rfficall.c index 8a20c51ac7..a8d153d4a0 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/rfficall.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/rfficall.c @@ -34,6 +34,7 @@ Java_com_oracle_truffle_r_runtime_ffi_jnr_JNI_1CallRFFI_initialize(JNIEnv *env, init_internals(env); init_rmath(env); init_random(env); + init_parse(env); } JNIEXPORT void JNICALL diff --git a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.h b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.h index ee28f6641b..ee157855cd 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.h +++ b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.h @@ -74,6 +74,7 @@ void init_dynload(JNIEnv *env); void init_internals(JNIEnv *env); void init_random(JNIEnv *env); void init_utils(JNIEnv *env); +void init_parse(JNIEnv *env); void setTempDir(JNIEnv *, jstring tempDir); diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper.java index 6e75748198..e5e02b266d 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper.java @@ -876,6 +876,42 @@ public class CallRFFIHelper { return result; } + private enum ParseStatus { + PARSE_NULL, + PARSE_OK, + PARSE_INCOMPLETE, + PARSE_ERROR, + PARSE_EOF + } + + private static class ParseResult { + @SuppressWarnings("unused") private final int parseStatus; + @SuppressWarnings("unused") private final Object expr; + + private ParseResult(int parseStatus, Object expr) { + this.parseStatus = parseStatus; + this.expr = expr; + } + } + + public static Object R_ParseVector(Object text, int n, Object srcFile) { + // TODO general case + assert n == 1; + assert srcFile == RNull.instance; + String textString = RRuntime.asString(text); + assert textString != null; + + try { + Source source = Source.fromText(textString, "<R_ParseVector>"); + RExpression exprs = RContext.getEngine().parse(null, source); + return new ParseResult(ParseStatus.PARSE_OK.ordinal(), exprs); + } catch (ParseException ex) { + // TODO incomplete + return new ParseResult(ParseStatus.PARSE_ERROR.ordinal(), RNull.instance); + } + + } + @SuppressWarnings("unused") private static String R_HomeDir() { RFFIUtils.traceUpCall("R_HomeDir"); -- GitLab