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 387a7b43cbe06349a4e5d9beb05c4bb9d4268b26..921d6836dc307039a9cc25e375475477d42b4416 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)->GetIntField(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 8a20c51ac76eff298aeccb3fd7e90617401a557e..a8d153d4a0c39265d82c94e63c739c61e1c7a777 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 ee28f6641bec22efe5eef49b6ec13435b46e6e3a..ee157855cde1a4692e6383e7cca5b585db966eae 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 6e757481983688e1068f7792b648627fd80c6453..e5e02b266d4d031727dfda40dd92b8bef722b343 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");