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");