From 18138dc48ed88a134b5ebca48e3b3261dc54e12d Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Sat, 6 Jun 2015 14:03:13 -0700
Subject: [PATCH] add rd parser

---
 .../truffle/r/library/tools/C_ParseRd.java    |   22 +-
 .../truffle/r/library/tools/ToolsNative.java  |   46 +
 .../fficall/jni/src/externalptr.c             |    9 +-
 .../fficall/jni/src/listaccess.c              |  125 +
 .../fficall/jni/src/rf_functions.c            |  156 +-
 .../fficall/jni/src/rfficall.c                |   12 +-
 .../fficall/jni/src/rffiutils.c               |   60 +-
 .../fficall/jni/src/rffiutils.h               |    9 +-
 .../fficall/jni/src/typecoerce.c              |    9 +-
 .../fficall/jni/src/variables.c               |  126 +
 .../fficall/jni/src/vectoraccess.c            |   40 +-
 .../library/tools/src/gramRd.c                | 4309 +++++++++++++++++
 .../truffle/r/nodes/unary/CastListNode.java   |   27 +-
 .../r/nodes/unary/CastToVectorNode.java       |    5 +
 .../{BuiltinLibPath.java => LibPaths.java}    |   15 +-
 .../r/runtime/ffi/jnr/CallRFFIHelper.java     |  157 +
 .../r/runtime/ffi/jnr/CallRFFIWithJNI.java    |   16 +-
 .../r/runtime/ffi/jnr/JNR_RFFIFactory.java    |    2 +-
 .../oracle/truffle/r/runtime/RSerialize.java  |   19 +-
 .../truffle/r/runtime/data/RDataFactory.java  |    4 +
 .../truffle/r/runtime/data/RIntVector.java    |    6 +
 .../oracle/truffle/r/runtime/data/RList.java  |    6 +
 .../truffle/r/runtime/data/RPairList.java     |   50 +
 mx.fastr/suite.py                             |    1 +
 24 files changed, 5152 insertions(+), 79 deletions(-)
 create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsNative.java
 create mode 100644 com.oracle.truffle.r.native/fficall/jni/src/listaccess.c
 create mode 100644 com.oracle.truffle.r.native/fficall/jni/src/variables.c
 create mode 100644 com.oracle.truffle.r.native/library/tools/src/gramRd.c
 rename com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/{BuiltinLibPath.java => LibPaths.java} (76%)

diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java
index 2313f8e80d..dc460817b1 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java
@@ -22,11 +22,12 @@
  */
 package com.oracle.truffle.r.library.tools;
 
+import java.io.*;
+
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.conn.*;
-import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
 import com.oracle.truffle.r.runtime.env.*;
 
@@ -34,8 +35,22 @@ public abstract class C_ParseRd extends RExternalBuiltinNode.Arg7 {
 
     @SuppressWarnings("unused")
     @Specialization
-    protected Object parseRd(RConnection con, REnvironment srcfile, String encoding, byte verbose, RAbstractStringVector basename, byte fragment, byte warningCalls) {
-        return RNull.instance;
+    protected Object parseRd(RConnection con, REnvironment srcfile, String encoding, byte verboseL, RAbstractStringVector basename, byte fragmentL, byte warningCallsL) {
+        boolean verbose = RRuntime.fromLogical(verboseL);
+        boolean fragment = RRuntime.fromLogical(fragmentL);
+        if (RRuntime.isNA(warningCallsL)) {
+            throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "warningCalls");
+        }
+        boolean warningCalls = RRuntime.fromLogical(warningCallsL);
+
+        try (RConnection openConn = con.forceOpen("r")) {
+            Object result = ToolsNative.provider().cParseRd(con, srcfile, verbose, fragment, basename.getDataAt(0), warningCalls);
+            return result;
+        } catch (IOException ex) {
+            throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, ex.getMessage());
+        } catch (Throwable ex) {
+            throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, ex.getMessage());
+        }
     }
 
     @SuppressWarnings("unused")
@@ -43,4 +58,5 @@ public abstract class C_ParseRd extends RExternalBuiltinNode.Arg7 {
     public Object parseRd(Object con, Object srcfile, Object encoding, Object verbose, Object basename, Object fragment, Object warningCalls) {
         throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_OR_UNIMPLEMENTED_ARGUMENTS);
     }
+
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsNative.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsNative.java
new file mode 100644
index 0000000000..6a542e825a
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsNative.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.library.tools;
+
+import com.oracle.truffle.r.runtime.conn.*;
+import com.oracle.truffle.r.runtime.env.*;
+import com.oracle.truffle.r.runtime.ffi.*;
+
+public class ToolsNative {
+    private static ToolsNative singleton;
+
+    static ToolsNative provider() {
+        if (singleton == null) {
+            singleton = new ToolsNative();
+            System.load(LibPaths.getPackageLibPath("tools"));
+        }
+        return singleton;
+    }
+
+    Object cParseRd(RConnection con, REnvironment srcfile, boolean verbose, boolean fragment, String basename, boolean warningCalls) {
+        return cParseRdNative(con, srcfile, verbose, fragment, basename, warningCalls);
+    }
+
+    private static native Object cParseRdNative(RConnection con, REnvironment srcfile, boolean verbose, boolean fragment, String basename, boolean warningCalls);
+
+}
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/externalptr.c b/com.oracle.truffle.r.native/fficall/jni/src/externalptr.c
index 1c2203ff84..79943a7a6f 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/externalptr.c
+++ b/com.oracle.truffle.r.native/fficall/jni/src/externalptr.c
@@ -45,7 +45,8 @@ void init_externalptr(JNIEnv *env) {
 
 SEXP R_MakeExternalPtr(void *p, SEXP tag, SEXP prot) {
 	JNIEnv *thisenv = getEnv();
-	return (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, createExternalPtrMethodID, (jlong) p, tag, prot);
+	SEXP result =  (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, createExternalPtrMethodID, (jlong) p, tag, prot);
+    return mkGlobalRef(thisenv, result);
 }
 
 void *R_ExternalPtrAddr(SEXP s) {
@@ -55,12 +56,14 @@ void *R_ExternalPtrAddr(SEXP s) {
 
 SEXP R_ExternalPtrTag(SEXP s) {
 	JNIEnv *thisenv = getEnv();
-	return (*thisenv)->CallObjectMethod(thisenv, s, externalPtrGetTagMethodID);
+	SEXP result =  (*thisenv)->CallObjectMethod(thisenv, s, externalPtrGetTagMethodID);
+    return mkGlobalRef(thisenv, result);
 }
 
 SEXP R_ExternalPtrProt(SEXP s) {
 	JNIEnv *thisenv = getEnv();
-	return (*thisenv)->CallObjectMethod(thisenv, s, externalPtrGetProtMethodID);
+	SEXP result =  (*thisenv)->CallObjectMethod(thisenv, s, externalPtrGetProtMethodID);
+    return mkGlobalRef(thisenv, result);
 }
 
 void R_SetExternalPtrAddr(SEXP s, void *p) {
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/listaccess.c b/com.oracle.truffle.r.native/fficall/jni/src/listaccess.c
new file mode 100644
index 0000000000..e185d60f9e
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/jni/src/listaccess.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "rffiutils.h"
+
+static jmethodID CADR_MethodID;
+static jmethodID CAR_MethodID;
+static jmethodID CDR_MethodID;
+static jmethodID SETCAR_MethodID;
+static jmethodID SETCDR_MethodID;
+
+void init_listaccess(JNIEnv *env) {
+	CADR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "CADR", "(Ljava/lang/Object;)Ljava/lang/Object;", 1);
+	CAR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "CAR", "(Ljava/lang/Object;)Ljava/lang/Object;", 1);
+	CDR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "CDR", "(Ljava/lang/Object;)Ljava/lang/Object;", 1);
+	SETCAR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SETCAR", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1);
+	SETCDR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SETCDR", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1);
+}
+
+SEXP TAG(SEXP e) {
+    unimplemented("TAG");
+}
+
+SEXP CAR(SEXP e) {
+	JNIEnv *thisenv = getEnv();
+    SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, CAR_MethodID, e);
+    return mkGlobalRef(thisenv, result);
+}
+
+SEXP CDR(SEXP e) {
+	JNIEnv *thisenv = getEnv();
+    SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, CDR_MethodID, e);
+    return mkGlobalRef(thisenv, result);
+}
+
+SEXP CAAR(SEXP e) {
+    unimplemented("CAAR");
+}
+
+SEXP CDAR(SEXP e) {
+    unimplemented("CDAR");
+}
+
+SEXP CADR(SEXP e) {
+	JNIEnv *thisenv = getEnv();
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, CADR_MethodID, e);
+    return mkGlobalRef(thisenv, result);
+}
+
+SEXP CDDR(SEXP e) {
+    unimplemented("CDDR");
+}
+
+SEXP CADDR(SEXP e) {
+    unimplemented("CADDR");
+}
+
+SEXP CADDDR(SEXP e) {
+    unimplemented("CADDDR");
+}
+
+SEXP CAD4R(SEXP e) {
+    unimplemented("CAD4R");
+}
+
+int MISSING(SEXP x){
+    unimplemented("MISSING");
+}
+
+void SET_MISSING(SEXP x, int v) {
+    unimplemented("SET_MISSING");
+}
+
+void SET_TAG(SEXP x, SEXP y) {
+    unimplemented("SET_TAG");
+}
+
+SEXP SETCAR(SEXP x, SEXP y) {
+	JNIEnv *thisenv = getEnv();
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, SETCAR_MethodID, x, y);
+    return mkGlobalRef(thisenv, result);
+}
+
+SEXP SETCDR(SEXP x, SEXP y) {
+	JNIEnv *thisenv = getEnv();
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, SETCDR_MethodID, x, y);
+    return mkGlobalRef(thisenv, result);
+}
+
+SEXP SETCADR(SEXP x, SEXP y) {
+    unimplemented("SETCADR");
+}
+
+SEXP SETCADDR(SEXP x, SEXP y) {
+    unimplemented("SETCADDR");
+}
+
+SEXP SETCADDDR(SEXP x, SEXP y) {
+    unimplemented("SETCADDDR");
+}
+
+SEXP SETCAD4R(SEXP e, SEXP y) {
+    unimplemented("SETCAD4R");
+}
+
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/rf_functions.c b/com.oracle.truffle.r.native/fficall/jni/src/rf_functions.c
index bc5ad202fe..b48dedce91 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/rf_functions.c
+++ b/com.oracle.truffle.r.native/fficall/jni/src/rf_functions.c
@@ -25,71 +25,162 @@
 // Most of the functions with a Rf_ prefix
 // TODO Lots missing yet
 
-static jmethodID Rf_scalarIntegerMethodID;
-static jmethodID Rf_scalarDoubleMethodID;
+static jmethodID Rf_ScalarIntegerMethodID;
+static jmethodID Rf_ScalarDoubleMethodID;
+static jmethodID Rf_ScalarStringMethodID;
 static jmethodID createIntArrayMethodID;
 static jmethodID createDoubleArrayMethodID;
 static jmethodID createStringArrayMethodID;
+static jmethodID createListMethodID;
 static jmethodID Rf_duplicateMethodID;
-static jmethodID createSymbolMethodID;
+static jmethodID Rf_consMethodID;
+static jmethodID Rf_defineVarMethodID;
+static jmethodID Rf_findVarMethodID;
+static jmethodID Rf_getAttribMethodID;
+static jmethodID Rf_setAttribMethodID;
+static jmethodID Rf_isStringMethodID;
+static jmethodID Rf_isNullMethodID;
+static jmethodID Rf_NewHashedEnvMethodID;
 
 void init_rf_functions(JNIEnv *env) {
-	Rf_scalarIntegerMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarInteger", "(I)Lcom/oracle/truffle/r/runtime/data/RIntVector;", 1);
-	Rf_scalarDoubleMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarDouble", "(D)Lcom/oracle/truffle/r/runtime/data/RDoubleVector;", 1);
+	Rf_ScalarIntegerMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarInteger", "(I)Lcom/oracle/truffle/r/runtime/data/RIntVector;", 1);
+	Rf_ScalarDoubleMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarDouble", "(D)Lcom/oracle/truffle/r/runtime/data/RDoubleVector;", 1);
+	Rf_ScalarStringMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarString", "(Ljava/lang/String;)Lcom/oracle/truffle/r/runtime/data/RStringVector;", 1);
+	Rf_consMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_cons", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1);
+	Rf_defineVarMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_defineVar", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V", 1);
+	Rf_findVarMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_findVar", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1);
+	Rf_getAttribMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_getAttrib", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1);
+	Rf_setAttribMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_setAttrib", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V", 1);
+	Rf_isStringMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_isString", "(Ljava/lang/Object;)I", 1);
+	Rf_isNullMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_isNull", "(Ljava/lang/Object;)I", 1);
 	createIntArrayMethodID = checkGetMethodID(env, RDataFactoryClass, "createIntVector", "(I)Lcom/oracle/truffle/r/runtime/data/RIntVector;", 1);
 	createDoubleArrayMethodID = checkGetMethodID(env, RDataFactoryClass, "createDoubleVector", "(I)Lcom/oracle/truffle/r/runtime/data/RDoubleVector;", 1);
 	createStringArrayMethodID = checkGetMethodID(env, RDataFactoryClass, "createStringVector", "(I)Lcom/oracle/truffle/r/runtime/data/RStringVector;", 1);
+	createListMethodID = checkGetMethodID(env, RDataFactoryClass, "createList", "(I)Lcom/oracle/truffle/r/runtime/data/RList;", 1);
 	Rf_duplicateMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_duplicate", "(Ljava/lang/Object;)Ljava/lang/Object;", 1);
-	createSymbolMethodID = checkGetMethodID(env, RDataFactoryClass, "createSymbol", "(Ljava/lang/String;)Lcom/oracle/truffle/r/runtime/data/RSymbol;", 1);
+	Rf_NewHashedEnvMethodID = checkGetMethodID(env, RDataFactoryClass, "createNewEnv", "(Lcom/oracle/truffle/r/runtime/env/REnvironment;Ljava/lang/String;ZI)Lcom/oracle/truffle/r/runtime/env/REnvironment;", 1);
 }
 
 SEXP Rf_ScalarInteger(int value) {
 	JNIEnv *thisenv = getEnv();
-	return (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_scalarIntegerMethodID, value);
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_ScalarIntegerMethodID, value);
+    return mkGlobalRef(thisenv, result);
 }
 
 SEXP Rf_ScalarReal(double value) {
 	JNIEnv *thisenv = getEnv();
-	return (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_scalarDoubleMethodID, value);
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_ScalarDoubleMethodID, value);
+    return mkGlobalRef(thisenv, result);
+}
+
+SEXP Rf_ScalarString(SEXP value) {
+	JNIEnv *thisenv = getEnv();
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_ScalarStringMethodID, value);
+    return mkGlobalRef(thisenv, result);
 }
 
 SEXP Rf_allocVector(SEXPTYPE t, R_xlen_t len) {
 	JNIEnv *thisenv = getEnv();
+	SEXP result;
 	switch (t) {
 	case INTSXP: {
-		return (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, createIntArrayMethodID, len);
+		result = (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, createIntArrayMethodID, len);
+		break;
 	}
 	case REALSXP: {
-		return (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, createDoubleArrayMethodID, len);
+		result = (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, createDoubleArrayMethodID, len);
+		break;
 	}
 	case STRSXP: {
-		return (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, createStringArrayMethodID, len);
+		result = (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, createStringArrayMethodID, len);
+		break;
+	}
+	case VECSXP: {
+		result = (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, createListMethodID, len);
+		break;
 	}
 	default:
+		printf("t=%d\n", t);
 		unimplemented("vector type not handled");
 		return NULL;
 	}
+	return mkGlobalRef(thisenv, result);
 }
 
-SEXP Rf_duplicate(SEXP x) {
+SEXP Rf_cons(SEXP car, SEXP cdr) {
 	JNIEnv *thisenv = getEnv();
-	return (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_duplicateMethodID, x);
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_consMethodID, car, cdr);
+    return mkGlobalRef(thisenv, result);
 }
 
-void Rf_error(const char *msg, ...) {
-	unimplemented("Rf_error");
+void Rf_defineVar(SEXP symbol, SEXP value, SEXP rho) {
+	JNIEnv *thisenv = getEnv();
+	(*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_defineVarMethodID, symbol, value, rho);
+}
+
+SEXP Rf_findVar(SEXP symbol, SEXP rho) {
+	JNIEnv *thisenv = getEnv();
+	SEXP result =(*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_findVarMethodID, symbol, rho);
+    return mkGlobalRef(thisenv, result);
+}
+
+SEXP Rf_getAttrib(SEXP vec, SEXP name) {
+	JNIEnv *thisenv = getEnv();
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_getAttribMethodID, vec, name);
+	return mkGlobalRef(thisenv, result);
+}
+
+SEXP Rf_setAttrib(SEXP vec, SEXP name, SEXP val) {
+	JNIEnv *thisenv = getEnv();
+	(*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_setAttribMethodID, vec, name, val);
+	return val;
+}
+
+SEXP Rf_duplicate(SEXP x) {
+	JNIEnv *thisenv = getEnv();
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_duplicateMethodID, x);
+	return mkGlobalRef(thisenv, result);
 }
 
 SEXP Rf_install(const char *name) {
 	JNIEnv *thisenv = getEnv();
 	jstring string = (*thisenv)->NewStringUTF(thisenv, name);
-	return (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, createSymbolMethodID, string);
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, createSymbolMethodID, string);
+	return mkGlobalRef(thisenv, result);
+}
+
+Rboolean Rf_isNull(SEXP s) {
+	JNIEnv *thisenv = getEnv();
+	return (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_isNullMethodID, s);
+}
+
+Rboolean Rf_isString(SEXP s) {
+	JNIEnv *thisenv = getEnv();
+	return (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_isStringMethodID, s);
+
 }
 
 SEXP Rf_mkChar(const char *x) {
 	JNIEnv *thisenv = getEnv();
 	// TODO encoding, assume UTF for now
-	return (*thisenv)->NewStringUTF(thisenv, x);
+	SEXP result = (*thisenv)->NewStringUTF(thisenv, x);
+	return mkGlobalRef(thisenv, result);
+}
+
+SEXP Rf_mkCharLenCE(const char *x, int len, cetype_t enc) {
+	JNIEnv *thisenv = getEnv();
+	char buf[len + 1];
+	memcpy(buf, x, len);
+	buf[len] = 0;
+	// TODO encoding, assume UTF for now, zero terminated
+	SEXP result = (*thisenv)->NewStringUTF(thisenv, buf);
+	return mkGlobalRef(thisenv, result);
+}
+
+SEXP Rf_mkString(const char *s) {
+	JNIEnv *thisenv = getEnv();
+	jstring string = (*thisenv)->NewStringUTF(thisenv, s);
+	return ScalarString(string);
 }
 
 SEXP Rf_protect(SEXP x) {
@@ -99,3 +190,34 @@ SEXP Rf_protect(SEXP x) {
 void Rf_unprotect(int x) {
 	// TODO perhaps we can use this
 }
+
+void Rf_unprotect_ptr(SEXP x) {
+	// TODO perhaps we can use this
+}
+
+void Rf_error(const char *msg, ...) {
+	unimplemented("Rf_error");
+}
+
+void Rf_warningcall(SEXP x, const char *msg, ...) {
+	unimplemented("Rf_warningcall");
+}
+
+void Rf_warning(const char *msg, ...) {
+	unimplemented("Rf_warning");
+}
+
+void Rprintf(const char *msg, ...) {
+	va_list argptr;
+	va_start(argptr, msg);
+	vprintf(msg, argptr);
+}
+
+// Tools package support, not in public API
+
+SEXP R_NewHashedEnv(SEXP parent, SEXP size) {
+	JNIEnv *thisenv = getEnv();
+	int sizeAsInt = Rf_asInteger(size);
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, Rf_NewHashedEnvMethodID, parent, NULL, JNI_TRUE, sizeAsInt);
+	return mkGlobalRef(thisenv, result);
+}
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/rfficall.c b/com.oracle.truffle.r.native/fficall/jni/src/rfficall.c
index 12ab0a1f83..3d466017f1 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/rfficall.c
+++ b/com.oracle.truffle.r.native/fficall/jni/src/rfficall.c
@@ -24,14 +24,11 @@
 #include "rffiutils.h"
 #include <string.h>
 
-SEXP R_NilValue;
-
 JNIEXPORT void JNICALL
-Java_com_oracle_truffle_r_runtime_ffi_jnr_CallRFFIWithJNI_initialize(JNIEnv *env, jclass c, jobject RNullInstance) {
-	init_utils(env);
-
-	R_NilValue = RNullInstance;
-
+Java_com_oracle_truffle_r_runtime_ffi_jnr_CallRFFIWithJNI_initialize(JNIEnv *env, jclass c,
+		jobjectArray initialValues) {
+	init_utils(env); // must be first
+	init_variables(env, initialValues);
 	init_register(env);
 	init_rf_functions(env);
 	init_externalptr(env);
@@ -39,6 +36,7 @@ Java_com_oracle_truffle_r_runtime_ffi_jnr_CallRFFIWithJNI_initialize(JNIEnv *env
 	init_attrib(env);
 	init_misc(env);
 	init_vectoraccess(env);
+	init_listaccess(env);
 }
 
 
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.c b/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.c
index 8f8493efe0..9f8a8d5dc0 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.c
+++ b/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.c
@@ -33,15 +33,68 @@ jclass RDataFactoryClass;
 
 static jclass RInternalErrorClass;
 static jmethodID unimplementedMethodID;
+jmethodID createSymbolMethodID;
+static jmethodID validateMethodID;
 
 JNIEnv *curenv = NULL;
 
+//#define DEBUG_CACHE 1
+#define CACHED_GLOBALREFS_TABLE_SIZE 100
+static SEXP cachedGlobalRefs[CACHED_GLOBALREFS_TABLE_SIZE];
+static SEXP checkCachedGlobalRef(JNIEnv *env, SEXP obj);
+
 void init_utils(JNIEnv *env) {
 	curenv = env;
 	RDataFactoryClass = checkFindClass(env, "com/oracle/truffle/r/runtime/data/RDataFactory");
 	CallRFFIHelperClass = checkFindClass(env, "com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper");
 	RInternalErrorClass = checkFindClass(env, "com/oracle/truffle/r/runtime/RInternalError");
 	unimplementedMethodID = checkGetMethodID(env, RInternalErrorClass, "unimplemented", "(Ljava/lang/String;)Ljava/lang/RuntimeException;", 1);
+	createSymbolMethodID = checkGetMethodID(env, RDataFactoryClass, "createSymbol", "(Ljava/lang/String;)Lcom/oracle/truffle/r/runtime/data/RSymbol;", 1);
+    validateMethodID = checkGetMethodID(env, CallRFFIHelperClass, "validate", "(Ljava/lang/Object;)Ljava/lang/Object;", 1);
+    for (int i = 0; i < CACHED_GLOBALREFS_TABLE_SIZE; i++) {
+    	cachedGlobalRefs[i] = NULL;
+    }
+}
+
+SEXP mkGlobalRef(JNIEnv *env, SEXP obj) {
+	SEXP result = checkCachedGlobalRef(env, obj);
+	return result;
+}
+
+SEXP mkNamedGlobalRef(JNIEnv *env, int index, SEXP obj) {
+	SEXP result = (*env)->NewGlobalRef(env, obj);
+	if (cachedGlobalRefs[index] != NULL) {
+		fatalError("duplicate named global ref index\n");
+	}
+	cachedGlobalRefs[index] = result;
+#if DEBUG_CACHE
+	printf("gref: %d=%p\n", index, result);
+#endif
+	return result;
+}
+
+static SEXP checkCachedGlobalRef(JNIEnv *env, SEXP obj) {
+    for (int i = 0; i < CACHED_GLOBALREFS_TABLE_SIZE; i++) {
+    	SEXP ref = cachedGlobalRefs[i];
+    	if (ref == NULL) {
+    		break;
+    	}
+    	if ((*env)->IsSameObject(env, ref, obj)) {
+#if DEBUG_CACHE
+    		printf("gref: cache hit: %d\n", i);
+#endif
+    		return ref;
+    	}
+    }
+    SEXP result = (*env)->NewGlobalRef(env, obj);
+#if DEBUG_CACHE
+	printf("gref: new=%p\n", result);
+#endif
+	return result;
+}
+
+void validate(SEXP x) {
+	(*curenv)->CallStaticObjectMethod(curenv, CallRFFIHelperClass, validateMethodID, x);
 }
 
 JNIEnv *getEnv() {
@@ -59,6 +112,11 @@ void unimplemented(char *msg) {
 	(*thisenv)->FatalError(thisenv, msg);
 }
 
+void fatalError(char *msg) {
+	JNIEnv *thisenv = getEnv();
+	(*thisenv)->FatalError(thisenv, msg);
+}
+
 // Class/method search
 jclass checkFindClass(JNIEnv *env, const char *name) {
 	jclass klass = (*env)->FindClass(env, name);
@@ -68,7 +126,7 @@ jclass checkFindClass(JNIEnv *env, const char *name) {
 		strcat(buf, name);
 		(*env)->FatalError(env, buf);
 	}
-	return klass;
+	return mkGlobalRef(env, klass);
 }
 
 jmethodID checkGetMethodID(JNIEnv *env, jclass klass, const char *name, const char *sig, int isStatic) {
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h b/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h
index c932e29e06..9dfcd2cd8d 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h
+++ b/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h
@@ -31,8 +31,15 @@ void setEnv(JNIEnv *env);
 
 jclass checkFindClass(JNIEnv *env, const char *name);
 jmethodID checkGetMethodID(JNIEnv *env, jclass klass, const char *name, const char *sig, int isStatic);
+extern jmethodID createSymbolMethodID;
+
 void unimplemented(char *msg);
+void fatalError(char *msg);
+void validate(SEXP x);
+SEXP mkGlobalRef(JNIEnv *env, SEXP);
+SEXP mkNamedGlobalRef(JNIEnv *env, int index, SEXP);
 
+void init_variables(JNIEnv *env, jobjectArray initialValues);
 void init_register(JNIEnv *env);
 void init_rf_functions(JNIEnv *env);
 void init_externalptr(JNIEnv *env);
@@ -43,7 +50,5 @@ void init_vectoraccess(JNIEnv *env);
 
 extern jclass RDataFactoryClass;
 extern jclass CallRFFIHelperClass;
-extern SEXP R_NilValue;
-
 
 #endif /* RFFIUTILS_H */
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/typecoerce.c b/com.oracle.truffle.r.native/fficall/jni/src/typecoerce.c
index f5c9f53a7e..047414ba87 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/typecoerce.c
+++ b/com.oracle.truffle.r.native/fficall/jni/src/typecoerce.c
@@ -25,16 +25,19 @@
 static jmethodID Rf_asIntegerMethodID;
 static jmethodID Rf_asRealMethodID;
 static jmethodID Rf_asCharMethodID;
+static jmethodID Rf_PairToVectorListMethodID;
 
 void init_typecoerce(JNIEnv *env) {
 	Rf_asIntegerMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_asInteger", "(Ljava/lang/Object;)I", 1);
 	Rf_asRealMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_asReal", "(Ljava/lang/Object;)D", 1);
 	Rf_asCharMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_asChar", "(Ljava/lang/Object;)Ljava/lang/String;", 1);
+	Rf_PairToVectorListMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_PairToVectorList", "(Ljava/lang/Object;)Ljava/lang/Object;", 1);
 }
 
 SEXP Rf_asChar(SEXP x){
 	JNIEnv *thisenv = getEnv();
-	return (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_asCharMethodID, x);
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_asCharMethodID, x);
+	return mkGlobalRef(thisenv, result);
 }
 
 SEXP Rf_coerceVector(SEXP x, SEXPTYPE t){
@@ -42,7 +45,9 @@ SEXP Rf_coerceVector(SEXP x, SEXPTYPE t){
 }
 
 SEXP Rf_PairToVectorList(SEXP x){
-	unimplemented("Rf_PairToVectorList");
+	JNIEnv *thisenv = getEnv();
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_PairToVectorListMethodID, x);
+	return mkGlobalRef(thisenv, result);
 }
 
 SEXP Rf_VectorToPairList(SEXP x){
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/variables.c b/com.oracle.truffle.r.native/fficall/jni/src/variables.c
new file mode 100644
index 0000000000..ecfe5a553e
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/jni/src/variables.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// Rinternals defines lots of extern variables that we set here (eventually)
+// Everything here must be a JNI Global Reference, and must be canonical because
+// C code compares then with "==" (a JNI no-no really).
+
+#include <jni.h>
+#include <Rinternals.h>
+#include "rffiutils.h"
+
+static int R_NilValue_Index = 0;
+static int R_UnboundValue_Index = 1;
+static int R_MissingArg_Index = 2;
+static int R_GlobalEnv_Index = 3;
+static int R_EmptyEnv_Index = 4;
+static int R_BaseEnv_Index = 5;
+static int R_BaseNamespace_Index = 6;
+static int R_NamespaceRegistry_Index = 7;
+static int R_Srcref_Index = 8;
+static int R_Bracket2Symbol_Index = 8;
+static int R_BracketSymbol_Index = 10;
+static int R_BraceSymbol_Index = 11;
+static int R_ClassSymbol_Index = 12;
+static int R_DeviceSymbol_Index = 12;
+static int R_DimNamesSymbol_Index = 14;
+static int R_DimSymbol_Index = 15;
+static int R_DollarSymbol_Index = 16;
+static int R_DotsSymbol_Index = 17;
+static int R_DropSymbol_Index = 18;
+static int R_LastvalueSymbol_Index = 19;
+static int R_LevelsSymbol_Index = 20;
+static int R_ModeSymbol_Index = 21;
+static int R_NameSymbol_Index = 22;
+static int R_NamesSymbol_Index = 23;
+static int R_NaRmSymbol_Index = 24;
+static int R_PackageSymbol_Index = 25;
+static int R_QuoteSymbol_Index = 26;
+static int R_RowNamesSymbol_Index = 27;
+static int R_SeedsSymbol_Index = 28;
+static int R_SourceSymbol_Index = 29;
+static int R_TspSymbol_Index = 30;
+static int R_dot_defined_Index = 31;
+static int R_dot_Method_Index = 32;
+static int R_dot_target_Index = 33;
+static int R_SrcrefSymbol_Index = 34;
+static int R_SrcfileSymbol_Index = 35;
+
+/* Evaluation Environment */
+//SEXP R_GlobalEnv;
+SEXP R_EmptyEnv;
+//SEXP R_BaseEnv;
+//SEXP R_BaseNamespace;
+//SEXP R_NamespaceRegistry;
+
+//SEXP R_Srcref;
+
+/* Special Values */
+SEXP R_NilValue;
+SEXP R_UnboundValue;
+SEXP R_MissingArg;
+
+/* Symbol Table Shortcuts */
+//SEXP R_Bracket2Symbol;   /* "[[" */
+//SEXP R_BracketSymbol;    /* "[" */
+//SEXP R_BraceSymbol;      /* "{" */
+SEXP R_ClassSymbol;     /* "class" */
+//SEXP R_DeviceSymbol;     /* ".Device" */
+//SEXP R_DimNamesSymbol;   /* "dimnames" */
+//SEXP R_DimSymbol;     /* "dim" */
+//SEXP R_DollarSymbol;     /* "$" */
+//SEXP R_DotsSymbol;     /* "..." */
+//SEXP R_DropSymbol;     /* "drop" */
+//SEXP R_LastvalueSymbol;  /* ".Last.value" */
+//SEXP R_LevelsSymbol;     /* "levels" */
+//SEXP R_ModeSymbol;     /* "mode" */
+//SEXP R_NameSymbol;     /* "name" */
+//SEXP R_NamesSymbol;     /* "names" */
+//SEXP R_NaRmSymbol;     /* "na.rm" */
+//SEXP R_PackageSymbol;    /* "package" */
+//SEXP R_QuoteSymbol;     /* "quote" */
+//SEXP R_RowNamesSymbol;   /* "row.names" */
+//SEXP R_SeedsSymbol;     /* ".Random.seed" */
+//SEXP R_SourceSymbol;     /* "source" */
+//SEXP R_TspSymbol;     /* "tsp" */
+
+//SEXP  R_dot_defined;      /* ".defined" */
+//SEXP  R_dot_Method;       /* ".Method" */
+//SEXP  R_dot_target;       /* ".target" */
+
+// Symbols not part of public API but used in FastR tools implementation
+SEXP R_SrcrefSymbol;
+SEXP R_SrcfileSymbol;
+
+void init_variables(JNIEnv *env, jobjectArray initialValues) {
+	R_EmptyEnv = mkNamedGlobalRef(env, R_EmptyEnv_Index, (*env)->GetObjectArrayElement(env, initialValues, 0));
+    R_NilValue = mkNamedGlobalRef(env, R_NilValue_Index, (*env)->GetObjectArrayElement(env, initialValues, 1));
+    R_UnboundValue = mkNamedGlobalRef(env, R_UnboundValue_Index, (*env)->GetObjectArrayElement(env, initialValues, 2));
+    R_MissingArg = mkNamedGlobalRef(env, R_MissingArg_Index, (*env)->GetObjectArrayElement(env, initialValues, 3));
+    R_ClassSymbol = mkNamedGlobalRef(env, R_ClassSymbol_Index, (*env)->GetObjectArrayElement(env, initialValues, 4));
+	jstring name = (*env)->NewStringUTF(env, "srcfile");
+	R_SrcfileSymbol = mkNamedGlobalRef(env, R_SrcfileSymbol_Index, (*env)->CallStaticObjectMethod(env, CallRFFIHelperClass, createSymbolMethodID, name));
+	name = (*env)->NewStringUTF(env, "srcref");
+	R_SrcrefSymbol = mkNamedGlobalRef(env, R_SrcrefSymbol_Index, (*env)->CallStaticObjectMethod(env, CallRFFIHelperClass, createSymbolMethodID, name));
+}
+
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/vectoraccess.c b/com.oracle.truffle.r.native/fficall/jni/src/vectoraccess.c
index f975e54f3e..771eb9d446 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/vectoraccess.c
+++ b/com.oracle.truffle.r.native/fficall/jni/src/vectoraccess.c
@@ -25,12 +25,22 @@
 #include <string.h>
 
 jmethodID SET_STRING_ELT_MethodID;
+jmethodID SET_INTEGER_ELT_MethodID;
+jmethodID SET_VECTOR_ELT_MethodID;
 jmethodID RAW_MethodID;
+jmethodID INTEGER_MethodID;
+jmethodID STRING_ELT_MethodID;
+jmethodID VECTOR_ELT_MethodID;
 jmethodID LENGTH_MethodID;
 
 void init_vectoraccess(JNIEnv *env) {
 	SET_STRING_ELT_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SET_STRING_ELT", "(Ljava/lang/Object;ILjava/lang/Object;)V", 1);
+	SET_INTEGER_ELT_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SET_INTEGER_ELT", "(Ljava/lang/Object;II)V", 1);
+	SET_VECTOR_ELT_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SET_VECTOR_ELT", "(Ljava/lang/Object;ILjava/lang/Object;)V", 1);
 	RAW_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "RAW", "(Ljava/lang/Object;)[B", 1);
+	INTEGER_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "INTEGER", "(Ljava/lang/Object;)[I", 1);
+	STRING_ELT_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "STRING_ELT", "(Ljava/lang/Object;I)Ljava/lang/String;", 1);
+	VECTOR_ELT_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "VECTOR_ELT", "(Ljava/lang/Object;I)Ljava/lang/Object;", 1);
 	LENGTH_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "LENGTH", "(Ljava/lang/Object;)I", 1);
 }
 
@@ -45,7 +55,6 @@ R_len_t  Rf_length(SEXP x) {
 }
 
 
-
 int TRUELENGTH(SEXP x){
 	unimplemented("unimplemented");
 }
@@ -93,17 +102,27 @@ int *LOGICAL(SEXP x){
 
 
 int *INTEGER(SEXP x){
-	unimplemented("INTEGER");
+	// TODO This does not support write access, e.g. INTEGER(x)[i]
+	JNIEnv *thisenv = getEnv();
+	jintArray intarray = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, INTEGER_MethodID, x);
+	int len = (*thisenv)->GetArrayLength(thisenv, intarray);
+	jint *data = (*thisenv)->GetIntArrayElements(thisenv, intarray, NULL);
+	void *result = malloc(len * 4);
+	memcpy(result, data, len * 4);
+	(*thisenv)->ReleaseIntArrayElements(thisenv, intarray, data, JNI_ABORT);
+	return (int *) result;
 }
 
 
 Rbyte *RAW(SEXP x){
+	// TODO This does not support write access, e.g. RAW(x)[i]
 	JNIEnv *thisenv = getEnv();
 	jbyteArray bytearray = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, RAW_MethodID, x);
 	int len = (*thisenv)->GetArrayLength(thisenv, bytearray);
 	jbyte *data = (*thisenv)->GetByteArrayElements(thisenv, bytearray, NULL);
 	void *result = malloc(len);
 	memcpy(result, data, len);
+	(*thisenv)->ReleaseByteArrayElements(thisenv, bytearray, data, JNI_ABORT);
 	return (Rbyte *) result;
 }
 
@@ -119,14 +138,23 @@ Rcomplex *COMPLEX(SEXP x){
 
 
 SEXP STRING_ELT(SEXP x, R_xlen_t i){
-	unimplemented("STRING_ELT");
+	JNIEnv *thisenv = getEnv();
+    SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, STRING_ELT_MethodID, x, i);
+    return mkGlobalRef(thisenv, result);
 }
 
 
 SEXP VECTOR_ELT(SEXP x, R_xlen_t i){
-	unimplemented("VECTOR_ELT");
+	JNIEnv *thisenv = getEnv();
+    SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, VECTOR_ELT_MethodID, x, i);
+    return mkGlobalRef(thisenv, result);
 }
 
+void SET_INTEGER_ELT(SEXP x, R_xlen_t i, int v) {
+	JNIEnv *thisenv = getEnv();
+	(*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, SET_INTEGER_ELT_MethodID, x, i, v);
+
+}
 
 void SET_STRING_ELT(SEXP x, R_xlen_t i, SEXP v){
 	JNIEnv *thisenv = getEnv();
@@ -135,7 +163,9 @@ void SET_STRING_ELT(SEXP x, R_xlen_t i, SEXP v){
 
 
 SEXP SET_VECTOR_ELT(SEXP x, R_xlen_t i, SEXP v){
-	unimplemented("SET_VECTOR_ELT");
+	JNIEnv *thisenv = getEnv();
+	(*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, SET_VECTOR_ELT_MethodID, x, i, v);
+	return v;
 }
 
 
diff --git a/com.oracle.truffle.r.native/library/tools/src/gramRd.c b/com.oracle.truffle.r.native/library/tools/src/gramRd.c
new file mode 100644
index 0000000000..02a87523d0
--- /dev/null
+++ b/com.oracle.truffle.r.native/library/tools/src/gramRd.c
@@ -0,0 +1,4309 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 1
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     END_OF_INPUT = 258,
+     ERROR = 259,
+     SECTIONHEADER = 260,
+     RSECTIONHEADER = 261,
+     VSECTIONHEADER = 262,
+     SECTIONHEADER2 = 263,
+     RCODEMACRO = 264,
+     SEXPR = 265,
+     RDOPTS = 266,
+     LATEXMACRO = 267,
+     VERBMACRO = 268,
+     OPTMACRO = 269,
+     ESCAPE = 270,
+     LISTSECTION = 271,
+     ITEMIZE = 272,
+     DESCRIPTION = 273,
+     NOITEM = 274,
+     LATEXMACRO2 = 275,
+     VERBMACRO2 = 276,
+     VERBLATEX = 277,
+     LATEXMACRO3 = 278,
+     NEWCOMMAND = 279,
+     USERMACRO = 280,
+     USERMACRO1 = 281,
+     USERMACRO2 = 282,
+     USERMACRO3 = 283,
+     USERMACRO4 = 284,
+     USERMACRO5 = 285,
+     USERMACRO6 = 286,
+     USERMACRO7 = 287,
+     USERMACRO8 = 288,
+     USERMACRO9 = 289,
+     IFDEF = 290,
+     ENDIF = 291,
+     TEXT = 292,
+     RCODE = 293,
+     VERB = 294,
+     COMMENT = 295,
+     UNKNOWN = 296,
+     STARTFILE = 297,
+     STARTFRAGMENT = 298
+   };
+#endif
+/* Tokens.  */
+#define END_OF_INPUT 258
+#define ERROR 259
+#define SECTIONHEADER 260
+#define RSECTIONHEADER 261
+#define VSECTIONHEADER 262
+#define SECTIONHEADER2 263
+#define RCODEMACRO 264
+#define SEXPR 265
+#define RDOPTS 266
+#define LATEXMACRO 267
+#define VERBMACRO 268
+#define OPTMACRO 269
+#define ESCAPE 270
+#define LISTSECTION 271
+#define ITEMIZE 272
+#define DESCRIPTION 273
+#define NOITEM 274
+#define LATEXMACRO2 275
+#define VERBMACRO2 276
+#define VERBLATEX 277
+#define LATEXMACRO3 278
+#define NEWCOMMAND 279
+#define USERMACRO 280
+#define USERMACRO1 281
+#define USERMACRO2 282
+#define USERMACRO3 283
+#define USERMACRO4 284
+#define USERMACRO5 285
+#define USERMACRO6 286
+#define USERMACRO7 287
+#define USERMACRO8 288
+#define USERMACRO9 289
+#define IFDEF 290
+#define ENDIF 291
+#define TEXT 292
+#define RCODE 293
+#define VERB 294
+#define COMMENT 295
+#define UNKNOWN 296
+#define STARTFILE 297
+#define STARTFRAGMENT 298
+
+
+
+
+/* Copy the first part of user declarations.  */
+
+
+/*
+ *  R : A Computer Langage for Statistical Data Analysis
+ *  Copyright (C) 1995, 1996, 1997  Robert Gentleman and Ross Ihaka
+ *  Copyright (C) 1997--2013  The R Core Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, a copy is available at
+ *  http://www.r-project.org/Licenses/
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define R_USE_SIGNALS 1
+//#include <Defn.h>
+#include <Rinternals.h>
+#include <R_ext/Parse.h>
+#define STRICT_R_HEADERS
+#include <R_ext/RS.h>           /* for R_chk_* allocation */
+#include <ctype.h>
+//#include <Rmath.h> /* for imax2(.),..*/
+#include <jni.h>
+
+#undef _
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#define _(String) dgettext ("tools", String)
+#else
+#define _(String) (String)
+#endif
+
+extern SEXP R_SrcrefSymbol;
+extern SEXP R_SrcfileSymbol;
+extern int R_ParseContextLast;
+#define R_EOF -1
+#define PARSE_ERROR_SIZE 256
+#define PARSE_CONTEXT_SIZE 256
+static char	R_ParseErrorMsg[PARSE_ERROR_SIZE];
+static char	R_ParseContext[PARSE_CONTEXT_SIZE];
+int	R_ParseContextLast;
+int	R_ParseContextLine;
+int R_ParseError;
+extern SEXP R_EmptyEnv;
+extern SEXP R_NewHashedEnv(SEXP a, SEXP b);
+
+char *dgettext(const char *p, const char *msgid) {
+	return msgid;
+}
+
+int imax2(int x, int y)
+{
+    return (x < y) ? y : x;
+}
+
+/* bison creates a non-static symbol yylloc in both gramLatex.o and gramRd.o,
+   so remap */
+
+#define yylloc yyllocR
+
+#define DEBUGVALS 0		/* 1 causes detailed internal state output to R console */
+#define DEBUGMODE 0		/* 1 causes Bison output of parse state, to stdout or stderr */
+
+static Rboolean wCalls = TRUE;
+
+#define YYERROR_VERBOSE 1
+
+static void yyerror(const char *);
+static int yylex();
+static int yyparse(void);
+
+#define yyconst const
+
+typedef struct yyltype
+{
+  int first_line;
+  int first_column;
+  int first_byte;
+
+  int last_line;
+  int last_column;
+  int last_byte;
+} yyltype;
+
+# define YYLTYPE yyltype
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (YYID (N))							\
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).first_byte   = YYRHSLOC (Rhs, 1).first_byte;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	  (Current).last_byte    = YYRHSLOC (Rhs, N).last_byte;		\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	  (Current).first_byte   = (Current).last_byte =		\
+	    YYRHSLOC (Rhs, 0).last_byte;				\
+	}								\
+    while (YYID (0))
+
+/* Useful defines so editors don't get confused ... */
+
+#define LBRACE	'{'
+#define RBRACE	'}'
+
+/* Functions used in the parsing process */
+
+static SEXP	GrowList(SEXP, SEXP);
+static int	KeywordLookup(const char *);
+static SEXP	UserMacroLookup(const char *);
+static SEXP	InstallKeywords();
+static SEXP	NewList(void);
+static SEXP     makeSrcref(YYLTYPE *, SEXP);
+static int	xxgetc();
+static int	xxungetc(int);
+
+/* Flags used to mark need for postprocessing in the dynamicFlag attribute */
+
+#define STATIC 0
+#define HAS_IFDEF 1
+#define HAS_SEXPR 2
+
+/* Internal lexer / parser state variables */
+
+static char const yyunknown[] = "unknown macro"; /* our message, not bison's */
+
+
+typedef struct ParseState ParseState;
+struct ParseState {
+    int xxinRString, xxQuoteLine, xxQuoteCol;
+    int	xxinEqn;
+    int	xxNewlineInString;
+    int	xxlineno, xxbyteno, xxcolno;
+    int	xxmode, xxitemType, xxbraceDepth;  /* context for lexer */
+    int	xxDebugTokens;  /* non-zero causes debug output to R console */
+    const char* xxBasename;     /* basename of file for error messages */
+    SEXP	Value;
+    int	xxinitvalue;
+    SEXP	xxMacroList;/* A hashed environment containing all the standard and user-defined macro names */
+    ParseState *prevState;
+};
+
+static Rboolean busy = FALSE;
+static ParseState parseState;
+
+#define RLIKE 1		/* Includes R strings; xxinRString holds the opening quote char, or 0 outside a string */
+#define LATEXLIKE 2
+#define VERBATIM 3
+#define INOPTION 4
+#define COMMENTMODE 5   /* only used in deparsing */
+#define UNKNOWNMODE 6   /* ditto */
+
+static SEXP     SrcFile;  /* parse_Rd will *always* supply a srcfile */
+
+/* Routines used to build the parse tree */
+
+static SEXP	xxpushMode(int, int, int);
+static void	xxpopMode(SEXP);
+static SEXP	xxnewlist(SEXP);
+static SEXP	xxnewlist2(SEXP, SEXP);
+static SEXP	xxnewlist3(SEXP, SEXP, SEXP);
+static SEXP	xxnewlist4(SEXP, SEXP, SEXP, SEXP);
+static SEXP	xxnewlist5(SEXP, SEXP, SEXP, SEXP, SEXP);
+static SEXP	xxnewlist6(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+static SEXP	xxnewlist7(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+static SEXP	xxnewlist8(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+static SEXP	xxnewlist9(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+
+static SEXP	xxlist(SEXP, SEXP);
+static SEXP	xxmarkup(SEXP, SEXP, int, YYLTYPE *);
+static SEXP	xxmarkup2(SEXP, SEXP, SEXP, int, int, YYLTYPE *);
+static SEXP	xxmarkup3(SEXP, SEXP, SEXP, SEXP, int, YYLTYPE *);
+static SEXP	xxOptionmarkup(SEXP, SEXP, SEXP, int, YYLTYPE *);
+static SEXP	xxtag(SEXP, int, YYLTYPE *);
+static void	xxsavevalue(SEXP, YYLTYPE *);
+static void	xxWarnNewline();
+static SEXP	xxnewcommand(SEXP, SEXP, SEXP, YYLTYPE *);
+static SEXP	xxusermacro(SEXP, SEXP, YYLTYPE *);
+static int	mkMarkup(int);
+static int      mkIfdef(int);
+static int	mkCode(int);
+static int	mkText(int);
+static int	mkVerb(int);
+static int 	mkComment(int);
+
+#define YYSTYPE		SEXP
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 216 of yacc.c.  */
+
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+    int i;
+#endif
+{
+  return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined _STDLIB_H \
+       && ! ((defined YYMALLOC || defined malloc) \
+	     && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+	 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+	     && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+    YYLTYPE yyls;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+      + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  33
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   832
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  48
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  31
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  89
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  194
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   298
+
+#define YYTRANSLATE(YYX)						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,    46,     2,    47,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    44,     2,    45,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint16 yyprhs[] =
+{
+       0,     0,     3,     7,    11,    13,    16,    18,    20,    23,
+      26,    29,    32,    35,    38,    42,    47,    52,    56,    61,
+      63,    65,    67,    70,    72,    75,    77,    79,    81,    83,
+      85,    87,    89,    91,    94,    97,   101,   106,   109,   112,
+     116,   121,   124,   128,   133,   136,   139,   143,   145,   150,
+     155,   159,   163,   165,   168,   172,   177,   183,   190,   198,
+     208,   219,   231,   234,   237,   240,   243,   246,   249,   254,
+     258,   261,   264,   269,   273,   276,   277,   278,   279,   280,
+     281,   282,   283,   284,   285,   289,   292,   297,   301,   306
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      49,     0,    -1,    42,    51,     3,    -1,    43,    50,     3,
+      -1,     1,    -1,    68,    54,    -1,    52,    -1,    53,    -1,
+      52,    53,    -1,     7,    64,    -1,    11,    64,    -1,     6,
+      62,    -1,     5,    58,    -1,    16,    61,    -1,     8,    58,
+      59,    -1,    35,    67,    52,    36,    -1,    35,    67,    52,
+       1,    -1,    10,    71,    63,    -1,    10,    71,    78,    63,
+      -1,    40,    -1,    37,    -1,    57,    -1,     1,    53,    -1,
+      55,    -1,    54,    55,    -1,    37,    -1,    38,    -1,    39,
+      -1,    40,    -1,    41,    -1,    77,    -1,    56,    -1,    57,
+      -1,     1,    55,    -1,    12,    58,    -1,    20,    58,    59,
+      -1,    23,    58,    59,    59,    -1,    17,    60,    -1,    18,
+      61,    -1,    14,    71,    58,    -1,    14,    71,    78,    58,
+      -1,     9,    62,    -1,    10,    71,    63,    -1,    10,    71,
+      78,    63,    -1,    13,    64,    -1,    21,    65,    -1,    21,
+      65,    66,    -1,    15,    -1,    35,    67,    54,    36,    -1,
+      35,    67,    54,     1,    -1,    22,    64,    59,    -1,    24,
+      65,    64,    -1,    25,    -1,    26,    64,    -1,    27,    64,
+      64,    -1,    28,    64,    64,    64,    -1,    29,    64,    64,
+      64,    64,    -1,    30,    64,    64,    64,    64,    64,    -1,
+      31,    64,    64,    64,    64,    64,    64,    -1,    32,    64,
+      64,    64,    64,    64,    64,    64,    64,    -1,    33,    64,
+      64,    64,    64,    64,    64,    64,    64,    64,    -1,    34,
+      64,    64,    64,    64,    64,    64,    64,    64,    64,    64,
+      -1,    68,    77,    -1,    68,    77,    -1,    68,    37,    -1,
+      75,    77,    -1,    76,    77,    -1,    69,    77,    -1,    44,
+      70,    54,    45,    -1,    44,    70,    45,    -1,    72,    77,
+      -1,    73,    77,    -1,    44,    74,    54,    45,    -1,    44,
+      74,    45,    -1,    68,    37,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    44,    54,    45,    -1,    44,
+      45,    -1,    44,    54,     1,    45,    -1,    44,     1,    45,
+      -1,    44,    54,     1,     3,    -1,    46,    55,    47,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   213,   213,   214,   215,   218,   221,   224,   225,   227,
+     228,   229,   230,   231,   232,   233,   234,   235,   236,   237,
+     238,   239,   240,   242,   243,   245,   246,   247,   248,   249,
+     250,   251,   252,   253,   255,   256,   257,   258,   259,   260,
+     261,   262,   263,   264,   265,   266,   267,   268,   269,   270,
+     271,   273,   274,   275,   276,   278,   280,   282,   284,   286,
+     289,   292,   297,   299,   300,   309,   311,   313,   317,   318,
+     320,   322,   326,   327,   329,   332,   334,   336,   338,   340,
+     342,   344,   346,   348,   350,   351,   352,   353,   354,   356
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "END_OF_INPUT", "ERROR", "SECTIONHEADER",
+  "RSECTIONHEADER", "VSECTIONHEADER", "SECTIONHEADER2", "RCODEMACRO",
+  "SEXPR", "RDOPTS", "LATEXMACRO", "VERBMACRO", "OPTMACRO", "ESCAPE",
+  "LISTSECTION", "ITEMIZE", "DESCRIPTION", "NOITEM", "LATEXMACRO2",
+  "VERBMACRO2", "VERBLATEX", "LATEXMACRO3", "NEWCOMMAND", "USERMACRO",
+  "USERMACRO1", "USERMACRO2", "USERMACRO3", "USERMACRO4", "USERMACRO5",
+  "USERMACRO6", "USERMACRO7", "USERMACRO8", "USERMACRO9", "IFDEF", "ENDIF",
+  "TEXT", "RCODE", "VERB", "COMMENT", "UNKNOWN", "STARTFILE",
+  "STARTFRAGMENT", "'{'", "'}'", "'['", "']'", "$accept", "Init",
+  "RdFragment", "RdFile", "SectionList", "Section", "ArgItems", "Item",
+  "Markup", "UserMacro", "LatexArg", "LatexArg2", "Item0Arg", "Item2Arg",
+  "RLikeArg", "RLikeArg2", "VerbatimArg", "VerbatimArg1", "VerbatimArg2",
+  "IfDefTarget", "goLatexLike", "goRLike", "goRLike2", "goOption",
+  "goVerbatim", "goVerbatim1", "goVerbatim2", "goItem0", "goItem2", "Arg",
+  "Option", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,   298,   123,   125,    91,    93
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    48,    49,    49,    49,    50,    51,    52,    52,    53,
+      53,    53,    53,    53,    53,    53,    53,    53,    53,    53,
+      53,    53,    53,    54,    54,    55,    55,    55,    55,    55,
+      55,    55,    55,    55,    56,    56,    56,    56,    56,    56,
+      56,    56,    56,    56,    56,    56,    56,    56,    56,    56,
+      56,    57,    57,    57,    57,    57,    57,    57,    57,    57,
+      57,    57,    58,    59,    59,    60,    61,    62,    63,    63,
+      64,    65,    66,    66,    67,    68,    69,    70,    71,    72,
+      73,    74,    75,    76,    77,    77,    77,    77,    77,    78
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     3,     3,     1,     2,     1,     1,     2,     2,
+       2,     2,     2,     2,     3,     4,     4,     3,     4,     1,
+       1,     1,     2,     1,     2,     1,     1,     1,     1,     1,
+       1,     1,     1,     2,     2,     3,     4,     2,     2,     3,
+       4,     2,     3,     4,     2,     2,     3,     1,     4,     4,
+       3,     3,     1,     2,     3,     4,     5,     6,     7,     9,
+      10,    11,     2,     2,     2,     2,     2,     2,     4,     3,
+       2,     2,     4,     3,     2,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     3,     2,     4,     3,     4,     3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       0,     4,     0,    75,     0,     0,    75,    76,    79,    75,
+      78,    79,    83,    80,    52,    79,    79,    79,    79,    79,
+      79,    79,    79,    79,    75,    20,    19,     0,     0,     7,
+      21,     0,     0,     1,    22,    12,     0,    11,     0,     9,
+       0,    75,     0,    10,    13,     0,    79,     0,    53,    79,
+      79,    79,    79,    79,    79,    79,    79,     0,     0,     2,
+       8,     3,     0,    76,    78,    75,    79,    78,    47,    82,
+      83,    75,    80,    79,    75,    75,    25,    26,    27,    28,
+      29,     0,     0,    23,    31,    32,    30,    62,    67,    70,
+      14,     0,    77,     0,    17,     0,    66,    51,    71,    54,
+      79,    79,    79,    79,    79,    79,    79,     0,    74,    33,
+      41,     0,    34,    44,    75,    37,     0,    38,    75,    45,
+      75,    75,     0,     0,    85,     0,    24,    64,    63,     0,
+       0,    18,    55,    79,    79,    79,    79,    79,    79,     0,
+      15,    42,     0,    39,    75,    65,    35,    81,    46,    50,
+      75,     0,    87,     0,    84,    69,     0,    89,    56,    79,
+      79,    79,    79,    79,    43,    40,     0,    36,     0,    48,
+      88,    86,    68,    57,    79,    79,    79,    79,    73,     0,
+      58,    79,    79,    79,    72,    79,    79,    79,    59,    79,
+      79,    60,    79,    61
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int16 yydefgoto[] =
+{
+      -1,     4,    31,    27,    28,    29,    82,    83,    84,    85,
+      35,    90,   115,    44,    37,    94,    39,    46,   148,    57,
+      36,    38,   129,    42,    40,    47,   166,   116,    45,    86,
+      95
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -94
+static const yytype_int16 yypact[] =
+{
+      28,   -94,   792,   -94,    20,   792,   -94,   -94,   -94,   -94,
+     -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,
+     -94,   -94,   -94,   -94,   -94,   -94,   -94,    29,   718,   -94,
+     -94,    34,   638,   -94,   -94,   -94,   -19,   -94,   -19,   -94,
+     -19,   -94,   -30,   -94,   -94,   -19,   -94,   -19,   -94,   -94,
+     -94,   -94,   -94,   -94,   -94,   -94,   -94,   792,    -6,   -94,
+     -94,   -94,   638,   -94,   -94,   -94,   -94,   -94,   -94,   -94,
+     -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,
+     -94,   265,   556,   -94,   -94,   -94,   -94,   -94,   -94,   -94,
+     -94,   -22,   -94,   638,   -94,     2,   -94,   -94,   -94,   -94,
+     -94,   -94,   -94,   -94,   -94,   -94,   -94,   755,   -94,   -94,
+     -94,   -30,   -94,   -94,     1,   -94,   -19,   -94,   -94,     4,
+     -94,   -94,   638,   306,   -94,   347,   -94,   -94,   -94,   388,
+       7,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   680,
+     -94,   -94,     2,   -94,   -94,   -94,   -94,   -94,   -94,   -94,
+     -94,   597,   -94,   224,   -94,   -94,   429,   -94,   -94,   -94,
+     -94,   -94,   -94,   -94,   -94,   -94,   470,   -94,   179,   -94,
+     -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   511,
+     -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,
+     -94,   -94,   -94,   -94
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+     -94,   -94,   -94,   -94,     3,    -2,   -64,   -10,   -94,    22,
+      -8,   -43,   -94,    -9,    -4,   -93,   -11,    -5,   -94,    -7,
+      10,   -94,   -94,   -31,   -94,   -94,   -94,   -94,   -94,   -17,
+     -58
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -50
+static const yytype_int16 yytable[] =
+{
+      43,    41,   131,    34,    48,    49,    50,    51,    52,    53,
+      54,    55,    56,    32,    92,   127,    93,   125,   141,    87,
+      33,    88,    81,    89,    30,    81,    60,    30,    96,     1,
+      98,   108,    59,   111,    58,    97,   114,    61,    99,   100,
+     101,   102,   103,   104,   105,   106,    92,    93,   147,   164,
+      30,    91,   109,   142,   157,   113,   144,   112,   151,   110,
+     107,   117,   120,   118,     0,   156,   121,   119,   122,     0,
+       2,     3,   126,     0,   128,   146,     0,   149,   150,    30,
+       0,     0,     0,   130,     0,    58,     0,     0,     0,   132,
+     133,   134,   135,   136,   137,   138,     0,     0,     0,   145,
+       0,     0,   179,     0,     0,    60,   143,   167,     0,     0,
+       0,     0,     0,   109,     0,   126,     0,     0,     0,     0,
+       0,     0,   158,   159,   160,   161,   162,   163,    91,    30,
+      91,    91,     0,     0,     0,     0,   165,    34,     0,     0,
+       0,   126,     0,   109,     0,     0,   126,     0,   173,   174,
+     175,   176,   177,     0,     0,     0,     0,     0,   109,     0,
+      91,    30,     0,   180,   181,   182,   183,     0,     0,   126,
+     185,   186,   187,     0,   188,   189,   190,     0,   191,   192,
+      62,   193,   -49,     0,     0,     0,     0,     0,    63,    64,
+       0,    65,    66,    67,    68,     0,    69,    70,     0,    71,
+      72,    73,    74,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,    23,    75,   -49,    76,    77,    78,    79,
+      80,     0,     0,    81,   -49,    62,   -49,   170,     0,     0,
+       0,     0,     0,    63,    64,     0,    65,    66,    67,    68,
+       0,    69,    70,     0,    71,    72,    73,    74,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    75,
+       0,    76,    77,    78,    79,    80,   123,     0,    81,   171,
+       0,     0,     0,     0,    63,    64,     0,    65,    66,    67,
+      68,     0,    69,    70,     0,    71,    72,    73,    74,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,
+      75,     0,    76,    77,    78,    79,    80,    62,     0,    81,
+     124,     0,     0,     0,     0,    63,    64,     0,    65,    66,
+      67,    68,     0,    69,    70,     0,    71,    72,    73,    74,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    75,     0,    76,    77,    78,    79,    80,   153,     0,
+      81,   152,     0,     0,     0,     0,    63,    64,     0,    65,
+      66,    67,    68,     0,    69,    70,     0,    71,    72,    73,
+      74,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,    23,    75,     0,    76,    77,    78,    79,    80,    62,
+       0,    81,   154,     0,     0,     0,     0,    63,    64,     0,
+      65,    66,    67,    68,     0,    69,    70,     0,    71,    72,
+      73,    74,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    75,     0,    76,    77,    78,    79,    80,
+      62,     0,    81,   155,     0,     0,     0,     0,    63,    64,
+       0,    65,    66,    67,    68,     0,    69,    70,     0,    71,
+      72,    73,    74,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,    23,    75,     0,    76,    77,    78,    79,
+      80,    62,     0,    81,   172,     0,     0,     0,     0,    63,
+      64,     0,    65,    66,    67,    68,     0,    69,    70,     0,
+      71,    72,    73,    74,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    75,     0,    76,    77,    78,
+      79,    80,    62,     0,    81,   178,     0,     0,     0,     0,
+      63,    64,     0,    65,    66,    67,    68,     0,    69,    70,
+       0,    71,    72,    73,    74,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,    23,    75,     0,    76,    77,
+      78,    79,    80,     0,     0,    81,   184,    62,     0,    -5,
+       0,     0,     0,     0,     0,    63,    64,     0,    65,    66,
+      67,    68,     0,    69,    70,     0,    71,    72,    73,    74,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    75,     0,    76,    77,    78,    79,    80,   168,     0,
+      81,     0,     0,     0,     0,     0,    63,    64,     0,    65,
+      66,    67,    68,     0,    69,    70,     0,    71,    72,    73,
+      74,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,    23,    75,   169,    76,    77,    78,    79,    80,    62,
+       0,    81,     0,     0,     0,     0,     0,    63,    64,     0,
+      65,    66,    67,    68,     0,    69,    70,     0,    71,    72,
+      73,    74,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    75,     0,    76,    77,    78,    79,    80,
+       0,     5,    81,   -16,     0,     6,     7,     8,     9,     0,
+      10,    11,     0,     0,     0,     0,    12,     0,     0,     0,
+       0,     0,     0,     0,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,   -16,    25,     0,     5,
+      26,    -6,     0,     6,     7,     8,     9,     0,    10,    11,
+       0,     0,     0,     0,    12,     0,     0,     0,     0,     0,
+       0,     0,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,     0,    25,   139,     0,    26,     0,
+       6,     7,     8,     9,     0,    10,    11,     0,     0,     0,
+       0,    12,     0,     0,     0,     0,     0,     0,     0,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,
+      24,   140,    25,     5,     0,    26,     0,     6,     7,     8,
+       9,     0,    10,    11,     0,     0,     0,     0,    12,     0,
+       0,     0,     0,     0,     0,     0,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    23,    24,     0,    25,
+       0,     0,    26
+};
+
+static const yytype_int16 yycheck[] =
+{
+      11,     9,    95,     5,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,     3,    44,    37,    46,    81,   111,    36,
+       0,    38,    44,    40,     2,    44,    28,     5,    45,     1,
+      47,    37,     3,    64,    24,    46,    67,     3,    49,    50,
+      51,    52,    53,    54,    55,    56,    44,    46,    44,   142,
+      28,    41,    62,   111,    47,    66,   114,    65,   122,    63,
+      57,    70,    73,    71,    -1,   129,    74,    72,    75,    -1,
+      42,    43,    82,    -1,    91,   118,    -1,   120,   121,    57,
+      -1,    -1,    -1,    93,    -1,    75,    -1,    -1,    -1,   100,
+     101,   102,   103,   104,   105,   106,    -1,    -1,    -1,   116,
+      -1,    -1,   166,    -1,    -1,   107,   114,   150,    -1,    -1,
+      -1,    -1,    -1,   123,    -1,   125,    -1,    -1,    -1,    -1,
+      -1,    -1,   133,   134,   135,   136,   137,   138,   118,   107,
+     120,   121,    -1,    -1,    -1,    -1,   144,   139,    -1,    -1,
+      -1,   151,    -1,   153,    -1,    -1,   156,    -1,   159,   160,
+     161,   162,   163,    -1,    -1,    -1,    -1,    -1,   168,    -1,
+     150,   139,    -1,   174,   175,   176,   177,    -1,    -1,   179,
+     181,   182,   183,    -1,   185,   186,   187,    -1,   189,   190,
+       1,   192,     3,    -1,    -1,    -1,    -1,    -1,     9,    10,
+      -1,    12,    13,    14,    15,    -1,    17,    18,    -1,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    33,    34,    35,    36,    37,    38,    39,    40,
+      41,    -1,    -1,    44,    45,     1,    47,     3,    -1,    -1,
+      -1,    -1,    -1,     9,    10,    -1,    12,    13,    14,    15,
+      -1,    17,    18,    -1,    20,    21,    22,    23,    24,    25,
+      26,    27,    28,    29,    30,    31,    32,    33,    34,    35,
+      -1,    37,    38,    39,    40,    41,     1,    -1,    44,    45,
+      -1,    -1,    -1,    -1,     9,    10,    -1,    12,    13,    14,
+      15,    -1,    17,    18,    -1,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    -1,    37,    38,    39,    40,    41,     1,    -1,    44,
+      45,    -1,    -1,    -1,    -1,     9,    10,    -1,    12,    13,
+      14,    15,    -1,    17,    18,    -1,    20,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
+      34,    35,    -1,    37,    38,    39,    40,    41,     1,    -1,
+      44,    45,    -1,    -1,    -1,    -1,     9,    10,    -1,    12,
+      13,    14,    15,    -1,    17,    18,    -1,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      33,    34,    35,    -1,    37,    38,    39,    40,    41,     1,
+      -1,    44,    45,    -1,    -1,    -1,    -1,     9,    10,    -1,
+      12,    13,    14,    15,    -1,    17,    18,    -1,    20,    21,
+      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
+      32,    33,    34,    35,    -1,    37,    38,    39,    40,    41,
+       1,    -1,    44,    45,    -1,    -1,    -1,    -1,     9,    10,
+      -1,    12,    13,    14,    15,    -1,    17,    18,    -1,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    33,    34,    35,    -1,    37,    38,    39,    40,
+      41,     1,    -1,    44,    45,    -1,    -1,    -1,    -1,     9,
+      10,    -1,    12,    13,    14,    15,    -1,    17,    18,    -1,
+      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
+      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
+      40,    41,     1,    -1,    44,    45,    -1,    -1,    -1,    -1,
+       9,    10,    -1,    12,    13,    14,    15,    -1,    17,    18,
+      -1,    20,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    33,    34,    35,    -1,    37,    38,
+      39,    40,    41,    -1,    -1,    44,    45,     1,    -1,     3,
+      -1,    -1,    -1,    -1,    -1,     9,    10,    -1,    12,    13,
+      14,    15,    -1,    17,    18,    -1,    20,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
+      34,    35,    -1,    37,    38,    39,    40,    41,     1,    -1,
+      44,    -1,    -1,    -1,    -1,    -1,     9,    10,    -1,    12,
+      13,    14,    15,    -1,    17,    18,    -1,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      33,    34,    35,    36,    37,    38,    39,    40,    41,     1,
+      -1,    44,    -1,    -1,    -1,    -1,    -1,     9,    10,    -1,
+      12,    13,    14,    15,    -1,    17,    18,    -1,    20,    21,
+      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
+      32,    33,    34,    35,    -1,    37,    38,    39,    40,    41,
+      -1,     1,    44,     3,    -1,     5,     6,     7,     8,    -1,
+      10,    11,    -1,    -1,    -1,    -1,    16,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    24,    25,    26,    27,    28,    29,
+      30,    31,    32,    33,    34,    35,    36,    37,    -1,     1,
+      40,     3,    -1,     5,     6,     7,     8,    -1,    10,    11,
+      -1,    -1,    -1,    -1,    16,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    24,    25,    26,    27,    28,    29,    30,    31,
+      32,    33,    34,    35,    -1,    37,     1,    -1,    40,    -1,
+       5,     6,     7,     8,    -1,    10,    11,    -1,    -1,    -1,
+      -1,    16,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,     1,    -1,    40,    -1,     5,     6,     7,
+       8,    -1,    10,    11,    -1,    -1,    -1,    -1,    16,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    24,    25,    26,    27,
+      28,    29,    30,    31,    32,    33,    34,    35,    -1,    37,
+      -1,    -1,    40
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,     1,    42,    43,    49,     1,     5,     6,     7,     8,
+      10,    11,    16,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    33,    34,    35,    37,    40,    51,    52,    53,
+      57,    50,    68,     0,    53,    58,    68,    62,    69,    64,
+      72,    58,    71,    64,    61,    76,    65,    73,    64,    64,
+      64,    64,    64,    64,    64,    64,    64,    67,    68,     3,
+      53,     3,     1,     9,    10,    12,    13,    14,    15,    17,
+      18,    20,    21,    22,    23,    35,    37,    38,    39,    40,
+      41,    44,    54,    55,    56,    57,    77,    77,    77,    77,
+      59,    68,    44,    46,    63,    78,    77,    64,    77,    64,
+      64,    64,    64,    64,    64,    64,    64,    52,    37,    55,
+      62,    71,    58,    64,    71,    60,    75,    61,    58,    65,
+      64,    58,    67,     1,    45,    54,    55,    37,    77,    70,
+      55,    63,    64,    64,    64,    64,    64,    64,    64,     1,
+      36,    63,    78,    58,    78,    77,    59,    44,    66,    59,
+      59,    54,    45,     1,    45,    45,    54,    47,    64,    64,
+      64,    64,    64,    64,    63,    58,    74,    59,     1,    36,
+       3,    45,    45,    64,    64,    64,    64,    64,    45,    54,
+      64,    64,    64,    64,    45,    64,    64,    64,    64,    64,
+      64,    64,    64,    64
+};
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK (1);						\
+      goto yybackup;						\
+    }								\
+  else								\
+    {								\
+      yyerror (YY_("syntax error: cannot back up")); \
+      YYERROR;							\
+    }								\
+while (YYID (0))
+
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (YYID (N))                                                    \
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+     fprintf (File, "%d.%d-%d.%d",			\
+	      (Loc).first_line, (Loc).first_column,	\
+	      (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
+do {									  \
+  if (yydebug)								  \
+    {									  \
+      YYFPRINTF (stderr, "%s ", Title);					  \
+      yy_symbol_print (stderr,						  \
+		  Type, Value, Location); \
+      YYFPRINTF (stderr, "\n");						  \
+    }									  \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+#endif
+{
+  if (!yyvaluep)
+    return;
+  YYUSE (yylocationp);
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+	break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  YY_LOCATION_PRINT (yyoutput, *yylocationp);
+  YYFPRINTF (yyoutput, ": ");
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    yytype_int16 *bottom;
+    yytype_int16 *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule)
+    YYSTYPE *yyvsp;
+    YYLTYPE *yylsp;
+    int yyrule;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+	     yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      fprintf (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+		       &(yyvsp[(yyi + 1) - (yynrhs)])
+		       , &(yylsp[(yyi + 1) - (yynrhs)])		       );
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, yylsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+	switch (*++yyp)
+	  {
+	  case '\'':
+	  case ',':
+	    goto do_not_strip_quotes;
+
+	  case '\\':
+	    if (*++yyp != '\\')
+	      goto do_not_strip_quotes;
+	    /* Fall through.  */
+	  default:
+	    if (yyres)
+	      yyres[yyn] = *yyp;
+	    yyn++;
+	    break;
+
+	  case '"':
+	    if (yyres)
+	      yyres[yyn] = '\0';
+	    return yyn;
+	  }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+  int yyn = yypact[yystate];
+
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+	 constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+		    + sizeof yyexpecting - 1
+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+		       * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+	 YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	  {
+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+	      {
+		yycount = 1;
+		yysize = yysize0;
+		yyformat[sizeof yyunexpected - 1] = '\0';
+		break;
+	      }
+	    yyarg[yycount++] = yytname[yyx];
+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+	    yysize_overflow |= (yysize1 < yysize);
+	    yysize = yysize1;
+	    yyfmt = yystpcpy (yyfmt, yyprefix);
+	    yyprefix = yyor;
+	  }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+	{
+	  /* Avoid sprintf, as that infringes on the user's name space.
+	     Don't have undefined behavior even if the translation
+	     produced a string with the wrong number of "%s"s.  */
+	  char *yyp = yyresult;
+	  int yyi = 0;
+	  while ((*yyp = *yyf) != '\0')
+	    {
+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		{
+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
+		  yyf += 2;
+		}
+	      else
+		{
+		  yyp++;
+		  yyf++;
+		}
+	    }
+	}
+      return yysize;
+    }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    YYLTYPE *yylocationp;
+#endif
+{
+  YYUSE (yyvaluep);
+  YYUSE (yylocationp);
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+      case 5: /* "SECTIONHEADER" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 6: /* "RSECTIONHEADER" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 7: /* "VSECTIONHEADER" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 8: /* "SECTIONHEADER2" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 9: /* "RCODEMACRO" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 10: /* "SEXPR" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 12: /* "LATEXMACRO" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 13: /* "VERBMACRO" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 14: /* "OPTMACRO" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 15: /* "ESCAPE" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 16: /* "LISTSECTION" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 17: /* "ITEMIZE" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 18: /* "DESCRIPTION" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 19: /* "NOITEM" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 20: /* "LATEXMACRO2" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 21: /* "VERBMACRO2" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 22: /* "VERBLATEX" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 23: /* "LATEXMACRO3" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 24: /* "NEWCOMMAND" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 25: /* "USERMACRO" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 26: /* "USERMACRO1" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 27: /* "USERMACRO2" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 28: /* "USERMACRO3" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 29: /* "USERMACRO4" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 30: /* "USERMACRO5" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 31: /* "USERMACRO6" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 32: /* "USERMACRO7" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 33: /* "USERMACRO8" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 34: /* "USERMACRO9" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 35: /* "IFDEF" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 36: /* "ENDIF" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 37: /* "TEXT" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 38: /* "RCODE" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 39: /* "VERB" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 40: /* "COMMENT" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 41: /* "UNKNOWN" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 42: /* "STARTFILE" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 43: /* "STARTFRAGMENT" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 54: /* "ArgItems" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 58: /* "LatexArg" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 63: /* "RLikeArg2" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 65: /* "VerbatimArg1" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 66: /* "VerbatimArg2" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 67: /* "IfDefTarget" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 68: /* "goLatexLike" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 69: /* "goRLike" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 70: /* "goRLike2" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 71: /* "goOption" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 72: /* "goVerbatim" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 73: /* "goVerbatim1" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 74: /* "goVerbatim2" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 75: /* "goItem0" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 76: /* "goItem2" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+      case 78: /* "Option" */
+
+	{ UNPROTECT_PTR((*yyvaluep)); };
+
+	break;
+
+      default:
+	break;
+    }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+/* Location data for the look-ahead symbol.  */
+YYLTYPE yylloc;
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+  /* The location stack.  */
+  YYLTYPE yylsa[YYINITDEPTH];
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+  /* The locations where the error started and ended.  */
+  YYLTYPE yyerror_range[2];
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+  YYLTYPE yyloc;
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+  yylsp = yyls;
+#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+  /* Initialize the default location before parsing starts.  */
+  yylloc.first_line   = yylloc.last_line   = 1;
+  yylloc.first_column = yylloc.last_column = 0;
+#endif
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack.  Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	yytype_int16 *yyss1 = yyss;
+	YYLTYPE *yyls1 = yyls;
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow (YY_("memory exhausted"),
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+		    &yyls1, yysize * sizeof (*yylsp),
+		    &yystacksize);
+	yyls = yyls1;
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	yytype_int16 *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyexhaustedlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+	YYSTACK_RELOCATE (yyls);
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+      yylsp = yyls + yysize - 1;
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     look-ahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  yystate = yyn;
+  *++yyvsp = yylval;
+  *++yylsp = yylloc;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+  /* Default location.  */
+  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+
+    { xxsavevalue((yyvsp[(2) - (3)]), &(yyloc)); UNPROTECT_PTR((yyvsp[(1) - (3)])); return 0; }
+    break;
+
+  case 3:
+
+    { xxsavevalue((yyvsp[(2) - (3)]), &(yyloc)); UNPROTECT_PTR((yyvsp[(1) - (3)])); return 0; }
+    break;
+
+  case 4:
+
+    { PROTECT(parseState.Value = R_NilValue);  YYABORT; }
+    break;
+
+  case 5:
+
+    { (yyval) = (yyvsp[(2) - (2)]); UNPROTECT_PTR((yyvsp[(1) - (2)])); }
+    break;
+
+  case 6:
+
+    { (yyval) = (yyvsp[(1) - (1)]); }
+    break;
+
+  case 7:
+
+    { (yyval) = xxnewlist((yyvsp[(1) - (1)])); }
+    break;
+
+  case 8:
+
+    { (yyval) = xxlist((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])); }
+    break;
+
+  case 9:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]), STATIC, &(yyloc)); }
+    break;
+
+  case 10:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]), HAS_SEXPR, &(yyloc)); }
+    break;
+
+  case 11:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]), STATIC, &(yyloc)); }
+    break;
+
+  case 12:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]), STATIC, &(yyloc)); }
+    break;
+
+  case 13:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]), STATIC, &(yyloc)); }
+    break;
+
+  case 14:
+
+    { (yyval) = xxmarkup2((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), 2, STATIC, &(yyloc)); }
+    break;
+
+  case 15:
+
+    { (yyval) = xxmarkup2((yyvsp[(1) - (4)]), (yyvsp[(2) - (4)]), (yyvsp[(3) - (4)]), 2, HAS_IFDEF, &(yyloc)); UNPROTECT_PTR((yyvsp[(4) - (4)])); }
+    break;
+
+  case 16:
+
+    { (yyval) = xxmarkup2((yyvsp[(1) - (4)]), (yyvsp[(2) - (4)]), (yyvsp[(3) - (4)]), 2, HAS_IFDEF, &(yyloc)); }
+    break;
+
+  case 17:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), HAS_SEXPR, &(yyloc)); xxpopMode((yyvsp[(2) - (3)])); }
+    break;
+
+  case 18:
+
+    { (yyval) = xxOptionmarkup((yyvsp[(1) - (4)]), (yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]), HAS_SEXPR, &(yyloc)); xxpopMode((yyvsp[(2) - (4)])); }
+    break;
+
+  case 19:
+
+    { (yyval) = xxtag((yyvsp[(1) - (1)]), COMMENT, &(yyloc)); }
+    break;
+
+  case 20:
+
+    { (yyval) = xxtag((yyvsp[(1) - (1)]), TEXT, &(yyloc)); }
+    break;
+
+  case 21:
+
+    { (yyval) = (yyvsp[(1) - (1)]); }
+    break;
+
+  case 22:
+
+    { (yyval) = (yyvsp[(2) - (2)]); }
+    break;
+
+  case 23:
+
+    { (yyval) = xxnewlist((yyvsp[(1) - (1)])); }
+    break;
+
+  case 24:
+
+    { (yyval) = xxlist((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])); }
+    break;
+
+  case 25:
+
+    { (yyval) = xxtag((yyvsp[(1) - (1)]), TEXT, &(yyloc)); }
+    break;
+
+  case 26:
+
+    { (yyval) = xxtag((yyvsp[(1) - (1)]), RCODE, &(yyloc)); }
+    break;
+
+  case 27:
+
+    { (yyval) = xxtag((yyvsp[(1) - (1)]), VERB, &(yyloc)); }
+    break;
+
+  case 28:
+
+    { (yyval) = xxtag((yyvsp[(1) - (1)]), COMMENT, &(yyloc)); }
+    break;
+
+  case 29:
+
+    { (yyval) = xxtag((yyvsp[(1) - (1)]), UNKNOWN, &(yyloc)); yyerror(yyunknown); }
+    break;
+
+  case 30:
+
+    { (yyval) = xxmarkup(R_NilValue, (yyvsp[(1) - (1)]), STATIC, &(yyloc)); }
+    break;
+
+  case 31:
+
+    { (yyval) = (yyvsp[(1) - (1)]); }
+    break;
+
+  case 32:
+
+    { (yyval) = (yyvsp[(1) - (1)]); }
+    break;
+
+  case 33:
+
+    { (yyval) = (yyvsp[(2) - (2)]); }
+    break;
+
+  case 34:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]), STATIC, &(yyloc)); }
+    break;
+
+  case 35:
+
+    { (yyval) = xxmarkup2((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), 2, STATIC, &(yyloc)); }
+    break;
+
+  case 36:
+
+    { (yyval) = xxmarkup3((yyvsp[(1) - (4)]), (yyvsp[(2) - (4)]), (yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]), STATIC, &(yyloc)); }
+    break;
+
+  case 37:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]), STATIC, &(yyloc)); }
+    break;
+
+  case 38:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]), STATIC, &(yyloc)); }
+    break;
+
+  case 39:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), STATIC, &(yyloc)); xxpopMode((yyvsp[(2) - (3)])); }
+    break;
+
+  case 40:
+
+    { (yyval) = xxOptionmarkup((yyvsp[(1) - (4)]), (yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]), STATIC, &(yyloc)); xxpopMode((yyvsp[(2) - (4)])); }
+    break;
+
+  case 41:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]), STATIC, &(yyloc)); }
+    break;
+
+  case 42:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), HAS_SEXPR, &(yyloc)); xxpopMode((yyvsp[(2) - (3)])); }
+    break;
+
+  case 43:
+
+    { (yyval) = xxOptionmarkup((yyvsp[(1) - (4)]), (yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]), HAS_SEXPR, &(yyloc)); xxpopMode((yyvsp[(2) - (4)])); }
+    break;
+
+  case 44:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]), STATIC, &(yyloc)); }
+    break;
+
+  case 45:
+
+    { (yyval) = xxmarkup2((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]), R_NilValue, 1, STATIC, &(yyloc)); }
+    break;
+
+  case 46:
+
+    { (yyval) = xxmarkup2((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), 2, STATIC, &(yyloc)); }
+    break;
+
+  case 47:
+
+    { (yyval) = xxmarkup((yyvsp[(1) - (1)]), R_NilValue, STATIC, &(yyloc)); }
+    break;
+
+  case 48:
+
+    { (yyval) = xxmarkup2((yyvsp[(1) - (4)]), (yyvsp[(2) - (4)]), (yyvsp[(3) - (4)]), 2, HAS_IFDEF, &(yyloc)); UNPROTECT_PTR((yyvsp[(4) - (4)])); }
+    break;
+
+  case 49:
+
+    { (yyval) = xxmarkup2((yyvsp[(1) - (4)]), (yyvsp[(2) - (4)]), (yyvsp[(3) - (4)]), 2, HAS_IFDEF, &(yyloc)); }
+    break;
+
+  case 50:
+
+    { (yyval) = xxmarkup2((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), 2, STATIC, &(yyloc)); }
+    break;
+
+  case 51:
+
+    { (yyval) = xxnewcommand((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), &(yyloc)); }
+    break;
+
+  case 52:
+
+    { (yyval) = xxusermacro((yyvsp[(1) - (1)]), xxnewlist(NULL), &(yyloc)); }
+    break;
+
+  case 53:
+
+    { (yyval) = xxusermacro((yyvsp[(1) - (2)]), xxnewlist((yyvsp[(2) - (2)])), &(yyloc)); }
+    break;
+
+  case 54:
+
+    { (yyval) = xxusermacro((yyvsp[(1) - (3)]), xxnewlist2((yyvsp[(2) - (3)]), (yyvsp[(3) - (3)])), &(yyloc)); }
+    break;
+
+  case 55:
+
+    { (yyval) = xxusermacro((yyvsp[(1) - (4)]), xxnewlist3((yyvsp[(2) - (4)]), (yyvsp[(3) - (4)]), (yyvsp[(4) - (4)])), &(yyloc)); }
+    break;
+
+  case 56:
+
+    { (yyval) = xxusermacro((yyvsp[(1) - (5)]), xxnewlist4((yyvsp[(2) - (5)]), (yyvsp[(3) - (5)]), (yyvsp[(4) - (5)]), (yyvsp[(5) - (5)])), &(yyloc)); }
+    break;
+
+  case 57:
+
+    { (yyval) = xxusermacro((yyvsp[(1) - (6)]), xxnewlist5((yyvsp[(2) - (6)]), (yyvsp[(3) - (6)]), (yyvsp[(4) - (6)]), (yyvsp[(5) - (6)]), (yyvsp[(6) - (6)])), &(yyloc)); }
+    break;
+
+  case 58:
+
+    { (yyval) = xxusermacro((yyvsp[(1) - (7)]), xxnewlist6((yyvsp[(2) - (7)]), (yyvsp[(3) - (7)]), (yyvsp[(4) - (7)]), (yyvsp[(5) - (7)]), (yyvsp[(6) - (7)]), (yyvsp[(7) - (7)])), &(yyloc)); }
+    break;
+
+  case 59:
+
+    { (yyval) = xxusermacro((yyvsp[(1) - (9)]), xxnewlist7((yyvsp[(2) - (9)]), (yyvsp[(3) - (9)]), (yyvsp[(4) - (9)]), (yyvsp[(5) - (9)]), (yyvsp[(6) - (9)]), (yyvsp[(7) - (9)]), (yyvsp[(8) - (9)])), &(yyloc)); }
+    break;
+
+  case 60:
+
+    { (yyval) = xxusermacro((yyvsp[(1) - (10)]), xxnewlist8((yyvsp[(2) - (10)]), (yyvsp[(3) - (10)]), (yyvsp[(4) - (10)]), (yyvsp[(5) - (10)]), (yyvsp[(6) - (10)]), (yyvsp[(7) - (10)]), (yyvsp[(8) - (10)]), (yyvsp[(9) - (10)])), &(yyloc)); }
+    break;
+
+  case 61:
+
+    { (yyval) = xxusermacro((yyvsp[(1) - (11)]), xxnewlist9((yyvsp[(2) - (11)]), (yyvsp[(3) - (11)]), (yyvsp[(4) - (11)]), (yyvsp[(5) - (11)]), (yyvsp[(6) - (11)]), (yyvsp[(7) - (11)]), (yyvsp[(8) - (11)]), (yyvsp[(9) - (11)]), (yyvsp[(10) - (11)])), &(yyloc)); }
+    break;
+
+  case 62:
+
+    { xxpopMode((yyvsp[(1) - (2)])); (yyval) = (yyvsp[(2) - (2)]); }
+    break;
+
+  case 63:
+
+    { xxpopMode((yyvsp[(1) - (2)])); (yyval) = (yyvsp[(2) - (2)]); }
+    break;
+
+  case 64:
+
+    { xxpopMode((yyvsp[(1) - (2)])); (yyval) = xxnewlist((yyvsp[(2) - (2)]));
+     						  if(wCalls)
+    	    					      warning(_("bad markup (extra space?) at %s:%d:%d"),
+    	    					            parseState.xxBasename, (yylsp[(2) - (2)]).first_line, (yylsp[(2) - (2)]).first_column);
+     						  else
+    	    					      warningcall(R_NilValue, _("bad markup (extra space?) at %s:%d:%d"),
+    	    					            parseState.xxBasename, (yylsp[(2) - (2)]).first_line, (yylsp[(2) - (2)]).first_column);
+						}
+    break;
+
+  case 65:
+
+    { xxpopMode((yyvsp[(1) - (2)])); (yyval) = (yyvsp[(2) - (2)]); }
+    break;
+
+  case 66:
+
+    { xxpopMode((yyvsp[(1) - (2)])); (yyval) = (yyvsp[(2) - (2)]); }
+    break;
+
+  case 67:
+
+    { xxpopMode((yyvsp[(1) - (2)])); (yyval) = (yyvsp[(2) - (2)]); }
+    break;
+
+  case 68:
+
+    { xxpopMode((yyvsp[(2) - (4)])); (yyval) = (yyvsp[(3) - (4)]); }
+    break;
+
+  case 69:
+
+    { xxpopMode((yyvsp[(2) - (3)])); (yyval) = xxnewlist(NULL); }
+    break;
+
+  case 70:
+
+    { xxpopMode((yyvsp[(1) - (2)])); (yyval) = (yyvsp[(2) - (2)]); }
+    break;
+
+  case 71:
+
+    { xxpopMode((yyvsp[(1) - (2)])); (yyval) = (yyvsp[(2) - (2)]); }
+    break;
+
+  case 72:
+
+    { xxpopMode((yyvsp[(2) - (4)])); (yyval) = (yyvsp[(3) - (4)]); }
+    break;
+
+  case 73:
+
+    { xxpopMode((yyvsp[(2) - (3)])); (yyval) = xxnewlist(NULL); }
+    break;
+
+  case 74:
+
+    { xxpopMode((yyvsp[(1) - (2)])); (yyval) = xxnewlist(xxtag((yyvsp[(2) - (2)]), TEXT, &(yyloc))); }
+    break;
+
+  case 75:
+
+    { (yyval) = xxpushMode(LATEXLIKE, UNKNOWN, FALSE); }
+    break;
+
+  case 76:
+
+    { (yyval) = xxpushMode(RLIKE, UNKNOWN, FALSE); }
+    break;
+
+  case 77:
+
+    { parseState.xxbraceDepth--; (yyval) = xxpushMode(RLIKE, UNKNOWN, FALSE); parseState.xxbraceDepth++; }
+    break;
+
+  case 78:
+
+    { (yyval) = xxpushMode(INOPTION, UNKNOWN, FALSE); }
+    break;
+
+  case 79:
+
+    { (yyval) = xxpushMode(VERBATIM, UNKNOWN, FALSE); }
+    break;
+
+  case 80:
+
+    { (yyval) = xxpushMode(VERBATIM, UNKNOWN, TRUE); }
+    break;
+
+  case 81:
+
+    { parseState.xxbraceDepth--; (yyval) = xxpushMode(VERBATIM, UNKNOWN, FALSE); parseState.xxbraceDepth++; }
+    break;
+
+  case 82:
+
+    { (yyval) = xxpushMode(LATEXLIKE, ESCAPE, FALSE); }
+    break;
+
+  case 83:
+
+    { (yyval) = xxpushMode(LATEXLIKE, LATEXMACRO2, FALSE); }
+    break;
+
+  case 84:
+
+    { (yyval) = (yyvsp[(2) - (3)]); }
+    break;
+
+  case 85:
+
+    { (yyval) = xxnewlist(NULL); }
+    break;
+
+  case 86:
+
+    { (yyval) = (yyvsp[(2) - (4)]); }
+    break;
+
+  case 87:
+
+    { (yyval) = xxnewlist(NULL); }
+    break;
+
+  case 88:
+
+    { (yyval) = (yyvsp[(2) - (4)]); }
+    break;
+
+  case 89:
+
+    { (yyval) = (yyvsp[(2) - (3)]); }
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+  *++yylsp = yyloc;
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (YY_("syntax error"));
+#else
+      {
+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+	  {
+	    YYSIZE_T yyalloc = 2 * yysize;
+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
+	    if (yymsg != yymsgbuf)
+	      YYSTACK_FREE (yymsg);
+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+	    if (yymsg)
+	      yymsg_alloc = yyalloc;
+	    else
+	      {
+		yymsg = yymsgbuf;
+		yymsg_alloc = sizeof yymsgbuf;
+	      }
+	  }
+
+	if (0 < yysize && yysize <= yymsg_alloc)
+	  {
+	    (void) yysyntax_error (yymsg, yystate, yychar);
+	    yyerror (yymsg);
+	  }
+	else
+	  {
+	    yyerror (YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+  yyerror_range[0] = yylloc;
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse look-ahead token after an
+	 error, discard it.  */
+
+      if (yychar <= YYEOF)
+	{
+	  /* Return failure if at end of input.  */
+	  if (yychar == YYEOF)
+	    YYABORT;
+	}
+      else
+	{
+	  yydestruct ("Error: discarding",
+		      yytoken, &yylval, &yylloc);
+	  yychar = YYEMPTY;
+	}
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  yyerror_range[0] = yylsp[1-yylen];
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+      yyerror_range[0] = *yylsp;
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp, yylsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+  yyerror_range[1] = yylloc;
+  /* Using YYLLOC is tempting, but would change the location of
+     the look-ahead.  YYLOC is available though.  */
+  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
+  *++yylsp = yyloc;
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval, &yylloc);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+		  yystos[*yyssp], yyvsp, yylsp);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
+}
+
+
+
+extern void SET_INTEGER_ELT(SEXP x, R_xlen_t  i, int v);
+
+static SEXP xxpushMode(int newmode, int newitem, int neweqn)
+{
+    SEXP ans;
+    PROTECT(ans = allocVector(INTSXP, 7));
+
+    SET_INTEGER_ELT(ans, 0, parseState.xxmode);		/* Lexer mode */
+    SET_INTEGER_ELT(ans, 1, parseState.xxitemType);	/* What is \item? */
+    SET_INTEGER_ELT(ans, 2, parseState.xxbraceDepth);	/* Brace depth used in RCODE and VERBATIM */
+    SET_INTEGER_ELT(ans, 3, parseState.xxinRString);      /* Quote char that started a string */
+    SET_INTEGER_ELT(ans, 4, parseState.xxQuoteLine);      /* Where the quote was */
+    SET_INTEGER_ELT(ans, 5, parseState.xxQuoteCol);       /*           "         */
+    SET_INTEGER_ELT(ans, 6, parseState.xxinEqn);          /* In the first arg to \eqn or \deqn:  no escapes */
+
+#if DEBUGMODE
+    Rprintf("xxpushMode(%d, %s) pushes %d, %s, %d\n", newmode, yytname[YYTRANSLATE(newitem)],
+    						parseState.xxmode, yytname[YYTRANSLATE(parseState.xxitemType)], parseState.xxbraceDepth);
+#endif
+    parseState.xxmode = newmode;
+    parseState.xxitemType = newitem;
+    parseState.xxbraceDepth = 0;
+    parseState.xxinRString = 0;
+    parseState.xxinEqn = neweqn;
+
+    return ans;
+}
+
+static void xxpopMode(SEXP oldmode)
+{
+#if DEBUGVALS
+    Rprintf("xxpopMode(%d, %s, %d) replaces %d, %s, %d\n", INTEGER(oldmode)[0], yytname[YYTRANSLATE(INTEGER(oldmode)[1])], INTEGER(oldmode)[2],
+    					parseState.xxmode, yytname[YYTRANSLATE(parseState.xxitemType)], parseState.xxbraceDepth);
+#endif
+    parseState.xxmode = INTEGER(oldmode)[0];
+    parseState.xxitemType = INTEGER(oldmode)[1];
+    parseState.xxbraceDepth = INTEGER(oldmode)[2];
+    parseState.xxinRString = INTEGER(oldmode)[3];
+    parseState.xxQuoteLine = INTEGER(oldmode)[4];
+    parseState.xxQuoteCol  = INTEGER(oldmode)[5];
+    parseState.xxinEqn	= INTEGER(oldmode)[6];
+
+    UNPROTECT_PTR(oldmode);
+}
+
+static int getDynamicFlag(SEXP item)
+{
+    SEXP flag = getAttrib(item, install("dynamicFlag"));
+    if (isNull(flag)) return 0;
+    else return INTEGER(flag)[0];
+}
+
+static void setDynamicFlag(SEXP item, int flag)
+{
+    if (flag)
+    	setAttrib(item, install("dynamicFlag"), ScalarInteger(flag));
+}
+
+static SEXP xxnewlist(SEXP item)
+{
+    SEXP ans, tmp;
+#if DEBUGVALS
+    Rprintf("xxnewlist(item=%p)", item);
+#endif
+    PROTECT(tmp = NewList());
+    if (item) {
+    	int flag = getDynamicFlag(item);
+    	PROTECT(ans = GrowList(tmp, item));
+    	setDynamicFlag(ans, flag);
+    	UNPROTECT_PTR(tmp);
+    	UNPROTECT_PTR(item);
+    } else ans = tmp;
+#if DEBUGVALS
+    Rprintf(" result: %p is length %d\n", ans, length(ans));
+#endif
+    return ans;
+}
+
+static SEXP xxnewlist2(SEXP item1, SEXP item2)
+{
+    return xxlist(xxnewlist(item1), item2);
+}
+
+static SEXP xxnewlist3(SEXP item1, SEXP item2, SEXP item3)
+{
+    return xxlist(xxnewlist2(item1, item2), item3);
+}
+
+static SEXP xxnewlist4(SEXP item1, SEXP item2, SEXP item3, SEXP item4)
+{
+    return xxlist(xxnewlist3(item1, item2, item3), item4);
+}
+
+static SEXP xxnewlist5(SEXP item1, SEXP item2, SEXP item3, SEXP item4, SEXP item5)
+{
+    return xxlist(xxnewlist4(item1, item2, item3, item4), item5);
+}
+
+static SEXP xxnewlist6(SEXP item1, SEXP item2, SEXP item3, SEXP item4, SEXP item5,
+		       SEXP item6)
+{
+    return xxlist(xxnewlist5(item1, item2, item3, item4, item5), item6);
+}
+
+static SEXP xxnewlist7(SEXP item1, SEXP item2, SEXP item3, SEXP item4, SEXP item5,
+		       SEXP item6, SEXP item7)
+{
+    return xxlist(xxnewlist6(item1, item2, item3, item4, item5, item6), item7);
+}
+
+static SEXP xxnewlist8(SEXP item1, SEXP item2, SEXP item3, SEXP item4, SEXP item5,
+		       SEXP item6, SEXP item7, SEXP item8)
+{
+    return xxlist(xxnewlist7(item1, item2, item3, item4, item5, item6, item7), item8);
+}
+
+static SEXP xxnewlist9(SEXP item1, SEXP item2, SEXP item3, SEXP item4, SEXP item5,
+		       SEXP item6, SEXP item7, SEXP item8, SEXP item9)
+{
+    return xxlist(xxnewlist8(item1, item2, item3, item4, item5, item6, item7, item8),
+                  item9);
+}
+
+static SEXP xxlist(SEXP oldlist, SEXP item)
+{
+    SEXP ans;
+    int flag = getDynamicFlag(oldlist) | getDynamicFlag(item);
+#if DEBUGVALS
+    Rprintf("xxlist(oldlist=%p, item=%p)", oldlist, item);
+#endif
+    PROTECT(ans = GrowList(oldlist, item));
+    UNPROTECT_PTR(item);
+    UNPROTECT_PTR(oldlist);
+    setDynamicFlag(ans, flag);
+#if DEBUGVALS
+    Rprintf(" result: %p is length %d\n", ans, length(ans));
+#endif
+    return ans;
+}
+
+static SEXP xxmarkup(SEXP header, SEXP body, int flag, YYLTYPE *lloc)
+{
+    SEXP ans;
+#if DEBUGVALS
+    Rprintf("xxmarkup(header=%p, body=%p)", header, body);
+#endif
+    if (isNull(body))
+        PROTECT(ans = allocVector(VECSXP, 0));
+    else {
+        flag |= getDynamicFlag(body);
+	PROTECT(ans = PairToVectorList(CDR(body)));
+    	UNPROTECT_PTR(body);
+    }
+    if (isNull(header))
+    	PROTECT(header = mkString("LIST"));
+
+    setAttrib(ans, install("Rd_tag"), header);
+    setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, SrcFile));
+    UNPROTECT_PTR(header);
+    setDynamicFlag(ans, flag);
+#if DEBUGVALS
+    Rprintf(" result: %p\n", ans);
+#endif
+    return ans;
+}
+
+static SEXP xxnewcommand(SEXP cmd, SEXP name, SEXP defn, YYLTYPE *lloc)
+{
+    SEXP ans, prev, thename, thedefn;
+    char buffer[128];
+    const char *c;
+    int maxarg = 0;
+#if DEBUGVALS
+    Rprintf("xxnewcommand(cmd=%p, name=%p, defn=%p)", cmd, name, defn);
+#endif
+    thename = CADR(name);
+    thedefn = CADR(defn);
+    if (TYPEOF(thedefn) == STRSXP)
+    	PROTECT(thedefn = mkString(CHAR(STRING_ELT(thedefn,0))));
+    else
+    	PROTECT(thedefn = mkString(""));
+    prev = findVar(install(CHAR(STRING_ELT(thename, 0))), parseState.xxMacroList);
+    if (prev != R_UnboundValue && !strcmp(CHAR(STRING_ELT(cmd,0)), "\renewcommand")) {
+        snprintf(buffer, sizeof(buffer), _("Macro '%s' previously defined."),
+                 CHAR(STRING_ELT(thename, 0)));
+        yyerror(buffer);
+    }
+    for (c = CHAR(STRING_ELT(thedefn, 0)); *c; c++) {
+    	if (*c == '#' && isdigit(*(c+1)))
+    	    maxarg = imax2(maxarg, *(c+1) - '0');
+    }
+    if (maxarg > 4) {
+    	snprintf(buffer, sizeof(buffer), _("At most 4 arguments are allowed for user defined macros."));
+	yyerror(buffer);
+    }
+    PROTECT(ans = ScalarInteger(USERMACRO + maxarg));
+    setAttrib(ans, install("Rd_tag"), cmd);
+    setAttrib(ans, install("definition"), thedefn);
+    setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, SrcFile));
+    defineVar(install(CHAR(STRING_ELT(thename, 0))), ans, parseState.xxMacroList);
+
+    UNPROTECT_PTR(thedefn);
+    UNPROTECT_PTR(cmd);
+    UNPROTECT_PTR(name);
+    UNPROTECT_PTR(defn);
+    return ans;
+}
+
+#define START_MACRO -2
+#define END_MACRO -3
+
+static SEXP xxusermacro(SEXP macro, SEXP args, YYLTYPE *lloc)
+{
+    SEXP ans, value, nextarg;
+    int i,len;
+    const char *c, *start ;
+
+#if DEBUGVALS
+    Rprintf("xxusermacro(macro=%p, args=%p)", macro, args);
+#endif
+    len = length(args)-1;
+    PROTECT(ans = allocVector(STRSXP, len + 1));
+    value = UserMacroLookup(CHAR(STRING_ELT(macro,0)));
+    if (TYPEOF(value) == STRSXP)
+    	SET_STRING_ELT(ans, 0, STRING_ELT(value, 0));
+    else
+    	error(_("No macro definition for '%s'."), CHAR(STRING_ELT(macro,0)));
+/*    Rprintf("len = %d", len); */
+    for (i = 0, nextarg=args; i < len; i++, nextarg = CDR(nextarg)) {
+/*        Rprintf("arg i is");
+        PrintValue(CADR(CADR(nextarg))); */
+	SET_STRING_ELT(ans, i+1, STRING_ELT(CADR(CADR(nextarg)), 0));
+    }
+    UNPROTECT_PTR(args);
+    UNPROTECT_PTR(macro);
+    /* Now push the expanded macro onto the input stream, in reverse order */
+    xxungetc(END_MACRO);
+    start = CHAR(STRING_ELT(ans, 0));
+    for (c = start + strlen(start); c > start; c--) {
+    	if (c > start + 1 && *(c-2) == '#' && isdigit(*(c-1))) {
+    	    int which = *(c-1) - '0';
+    	    const char *arg = CHAR(STRING_ELT(ans, which));
+    	    for (size_t ii = strlen(arg); ii > 0; ii--) xxungetc(arg[ii-1]);
+    	    c--;
+    	} else {
+    	    xxungetc(*(c-1));
+    	}
+    }
+    xxungetc(START_MACRO);
+
+    setAttrib(ans, install("Rd_tag"), mkString("USERMACRO"));
+    setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, SrcFile));
+#if DEBUGVALS
+    Rprintf(" result: %p\n", ans);
+#endif
+    return ans;
+}
+
+static SEXP xxOptionmarkup(SEXP header, SEXP option, SEXP body, int flag, YYLTYPE *lloc)
+{
+    SEXP ans;
+#if DEBUGVALS
+    Rprintf("xxOptionmarkup(header=%p, option=%p, body=%p)", header, option, body);
+#endif
+    flag |= getDynamicFlag(body);
+    PROTECT(ans = PairToVectorList(CDR(body)));
+    UNPROTECT_PTR(body);
+    setAttrib(ans, install("Rd_tag"), header);
+    UNPROTECT_PTR(header);
+    flag |= getDynamicFlag(option);
+    setAttrib(ans, install("Rd_option"), option);
+    UNPROTECT_PTR(option);
+    setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, SrcFile));
+    setDynamicFlag(ans, flag);
+#if DEBUGVALS
+    Rprintf(" result: %p\n", ans);
+#endif
+    return ans;
+}
+
+static SEXP xxmarkup2(SEXP header, SEXP body1, SEXP body2, int argcount, int flag, YYLTYPE *lloc)
+{
+    SEXP ans;
+#if DEBUGVALS
+    Rprintf("xxmarkup2(header=%p, body1=%p, body2=%p)", header, body1, body2);
+#endif
+
+    PROTECT(ans = allocVector(VECSXP, argcount));
+    if (!isNull(body1)) {
+    	int flag1 = getDynamicFlag(body1);
+    	SET_VECTOR_ELT(ans, 0, PairToVectorList(CDR(body1)));
+    	UNPROTECT_PTR(body1);
+    	setDynamicFlag(VECTOR_ELT(ans, 0), flag1);
+    	flag |= flag1;
+    }
+    if (!isNull(body2)) {
+    	int flag2;
+	if (argcount < 2) error("internal error: inconsistent argument count");
+	flag2 = getDynamicFlag(body2);
+    	SET_VECTOR_ELT(ans, 1, PairToVectorList(CDR(body2)));
+    	UNPROTECT_PTR(body2);
+    	setDynamicFlag(VECTOR_ELT(ans, 1), flag2);
+    	flag |= flag2;
+    }
+    setAttrib(ans, install("Rd_tag"), header);
+    UNPROTECT_PTR(header);
+    setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, SrcFile));
+    setDynamicFlag(ans, flag);
+#if DEBUGVALS
+    Rprintf(" result: %p\n", ans);
+#endif
+    return ans;
+}
+
+static SEXP xxmarkup3(SEXP header, SEXP body1, SEXP body2, SEXP body3, int flag, YYLTYPE *lloc)
+{
+    SEXP ans;
+#if DEBUGVALS
+    Rprintf("xxmarkup2(header=%p, body1=%p, body2=%p, body3=%p)", header, body1, body2, body3);
+#endif
+
+    PROTECT(ans = allocVector(VECSXP, 3));
+    if (!isNull(body1)) {
+    	int flag1 = getDynamicFlag(body1);
+    	SET_VECTOR_ELT(ans, 0, PairToVectorList(CDR(body1)));
+    	UNPROTECT_PTR(body1);
+    	setDynamicFlag(VECTOR_ELT(ans, 0), flag1);
+    	flag |= flag1;
+    }
+    if (!isNull(body2)) {
+    	int flag2;
+	flag2 = getDynamicFlag(body2);
+    	SET_VECTOR_ELT(ans, 1, PairToVectorList(CDR(body2)));
+    	UNPROTECT_PTR(body2);
+    	setDynamicFlag(VECTOR_ELT(ans, 1), flag2);
+    	flag |= flag2;
+    }
+    if (!isNull(body3)) {
+    	int flag3;
+	flag3 = getDynamicFlag(body3);
+    	SET_VECTOR_ELT(ans, 2, PairToVectorList(CDR(body3)));
+    	UNPROTECT_PTR(body3);
+    	setDynamicFlag(VECTOR_ELT(ans, 2), flag3);
+    	flag |= flag3;
+    }
+    setAttrib(ans, install("Rd_tag"), header);
+    UNPROTECT_PTR(header);
+    setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, SrcFile));
+    setDynamicFlag(ans, flag);
+#if DEBUGVALS
+    Rprintf(" result: %p\n", ans);
+#endif
+    return ans;
+}
+
+static void xxsavevalue(SEXP Rd, YYLTYPE *lloc)
+{
+    int flag = getDynamicFlag(Rd);
+    PROTECT(parseState.Value = PairToVectorList(CDR(Rd)));
+    if (!isNull(parseState.Value)) {
+    	setAttrib(parseState.Value, R_ClassSymbol, mkString("Rd"));
+    	setAttrib(parseState.Value, R_SrcrefSymbol, makeSrcref(lloc, SrcFile));
+    	setDynamicFlag(parseState.Value, flag);
+    }
+    UNPROTECT_PTR(Rd);
+}
+
+static SEXP xxtag(SEXP item, int type, YYLTYPE *lloc)
+{
+    setAttrib(item, install("Rd_tag"), mkString(yytname[YYTRANSLATE(type)]));
+    setAttrib(item, R_SrcrefSymbol, makeSrcref(lloc, SrcFile));
+    return item;
+}
+
+static void xxWarnNewline()
+{
+    if (parseState.xxNewlineInString) {
+	if(wCalls)
+	    warning(_("newline within quoted string at %s:%d"),
+		    parseState.xxBasename, parseState.xxNewlineInString);
+	else
+	    warningcall(R_NilValue,
+			_("newline within quoted string at %s:%d"),
+			parseState.xxBasename, parseState.xxNewlineInString);
+    }
+}
+
+
+/*----------------------------------------------------------------------------*/
+
+
+static int (*ptr_getc)(void);
+
+/* Private pushback, since file ungetc only guarantees one byte.
+   We need arbitrarily large size, since this is how macros are expanded. */
+
+#define PUSH_BACK(c) do {                  \
+	if (npush >= pushsize - 1) {             \
+	    int *old = pushbase;              \
+            pushsize *= 2;                    \
+	    pushbase = malloc(pushsize*sizeof(int));         \
+	    if(!pushbase) error(_("unable to allocate buffer for long macro at line %d"), parseState.xxlineno);\
+	    memmove(pushbase, old, npush*sizeof(int));        \
+	    if(old != pushback) free(old); }	    \
+	pushbase[npush++] = (c);                        \
+} while(0)
+
+
+
+#define PUSHBACK_BUFSIZE 32
+
+static int pushback[PUSHBACK_BUFSIZE];
+static int *pushbase;
+static unsigned int npush, pushsize;
+static int macrolevel;
+static int prevpos = 0;
+static int prevlines[PUSHBACK_BUFSIZE];
+static int prevcols[PUSHBACK_BUFSIZE];
+static int prevbytes[PUSHBACK_BUFSIZE];
+
+
+static int xxgetc(void)
+{
+    int c, oldpos;
+
+    do {
+    	if(npush) {
+    	    c = pushbase[--npush];
+    	    if (c == START_MACRO) {
+    	    	macrolevel++;
+    	    	if (macrolevel > 1000)
+    	    	    error(_("macros nested too deeply: infinite recursion?"));
+    	    } else if (c == END_MACRO) macrolevel--;
+    	} else  c = ptr_getc();
+    } while (c == START_MACRO || c == END_MACRO);
+
+    if (!macrolevel) {
+	oldpos = prevpos;
+	prevpos = (prevpos + 1) % PUSHBACK_BUFSIZE;
+	prevbytes[prevpos] = parseState.xxbyteno;
+	prevlines[prevpos] = parseState.xxlineno;
+	/* We only advance the column for the 1st byte in UTF-8, so handle later bytes specially */
+	if (0x80 <= (unsigned char)c && (unsigned char)c <= 0xBF) {
+	    parseState.xxcolno--;
+	    prevcols[prevpos] = prevcols[oldpos];
+	} else
+	    prevcols[prevpos] = parseState.xxcolno;
+
+	if (c == EOF) return R_EOF;
+
+	R_ParseContextLast = (R_ParseContextLast + 1) % PARSE_CONTEXT_SIZE;
+	R_ParseContext[R_ParseContextLast] = (char) c;
+
+	if (c == '\n') {
+	    parseState.xxlineno += 1;
+	    parseState.xxcolno = 1;
+	    parseState.xxbyteno = 1;
+	} else {
+	    parseState.xxcolno++;
+	    parseState.xxbyteno++;
+	}
+
+	if (c == '\t') parseState.xxcolno = ((parseState.xxcolno + 6) & ~7) + 1;
+
+	R_ParseContextLine = parseState.xxlineno;
+    }
+    /* Rprintf("get %c\n", c); */
+    return c;
+}
+
+static int xxungetc(int c)
+{
+    /* this assumes that c was the result of xxgetc; if not, some edits will be needed */
+    if (c == END_MACRO) macrolevel++;
+    if (!macrolevel) {
+    	parseState.xxlineno = prevlines[prevpos];
+    	parseState.xxbyteno = prevbytes[prevpos];
+    	parseState.xxcolno  = prevcols[prevpos];
+    	prevpos = (prevpos + PUSHBACK_BUFSIZE - 1) % PUSHBACK_BUFSIZE;
+
+    	R_ParseContextLine = parseState.xxlineno;
+
+    	R_ParseContext[R_ParseContextLast] = '\0';
+    	/* Mac OS X requires us to keep this non-negative */
+    	R_ParseContextLast = (R_ParseContextLast + PARSE_CONTEXT_SIZE - 1)
+		% PARSE_CONTEXT_SIZE;
+    }
+    if (c == START_MACRO) macrolevel--;
+    PUSH_BACK(c);
+    /* Rprintf("unget %c;", c); */
+    return c;
+}
+
+static SEXP makeSrcref(YYLTYPE *lloc, SEXP srcfile)
+{
+    SEXP val;
+
+    PROTECT(val = allocVector(INTSXP, 6));
+    SET_INTEGER_ELT(val, 0, lloc->first_line);
+    SET_INTEGER_ELT(val, 1, lloc->first_byte);
+    SET_INTEGER_ELT(val, 2, lloc->last_line);
+    SET_INTEGER_ELT(val, 3, lloc->last_byte);
+    SET_INTEGER_ELT(val, 4, lloc->first_column);
+    SET_INTEGER_ELT(val, 5, lloc->last_column);
+    setAttrib(val, R_SrcfileSymbol, srcfile);
+    setAttrib(val, R_ClassSymbol, mkString("srcref"));
+    UNPROTECT(1);
+    return val;
+}
+
+static SEXP mkString2(const char *s, size_t len)
+{
+    SEXP t;
+    cetype_t enc = CE_UTF8;
+
+    PROTECT(t = allocVector(STRSXP, 1));
+    SET_STRING_ELT(t, 0, mkCharLenCE(s, (int) len, enc));
+    UNPROTECT(1);
+    return t;
+}
+
+
+/* Stretchy List Structures : Lists are created and grown using a special */
+/* dotted pair.  The CAR of the list points to the last cons-cell in the */
+/* list and the CDR points to the first.  The list can be extracted from */
+/* the pair by taking its CDR, while the CAR gives fast access to the end */
+/* of the list. */
+
+
+/* Create a stretchy-list dotted pair */
+
+static SEXP NewList(void)
+{
+    SEXP s = CONS(R_NilValue, R_NilValue);
+    SETCAR(s, s);
+    return s;
+}
+
+/* Add a new element at the end of a stretchy list */
+
+static SEXP GrowList(SEXP l, SEXP s)
+{
+    SEXP tmp;
+    PROTECT(s);
+    tmp = CONS(s, R_NilValue);
+    UNPROTECT(1);
+    SETCDR(CAR(l), tmp);
+    SETCAR(l, tmp);
+    return l;
+}
+
+/*--------------------------------------------------------------------------*/
+
+static SEXP ParseRd(ParseStatus *status, SEXP srcfile, Rboolean fragment)
+{
+    R_ParseContextLast = 0;
+    R_ParseContext[0] = '\0';
+
+    parseState.xxlineno = 1;
+    parseState.xxcolno = 1;
+    parseState.xxbyteno = 1;
+
+    SrcFile = srcfile;
+
+    npush = 0;
+    pushbase = pushback;
+    pushsize = PUSHBACK_BUFSIZE;
+    macrolevel = 0;
+
+    parseState.xxmode = LATEXLIKE;
+    parseState.xxitemType = UNKNOWN;
+    parseState.xxbraceDepth = 0;
+    parseState.xxinRString = 0;
+    parseState.xxNewlineInString = 0;
+    parseState.xxinEqn = 0;
+    if (fragment) parseState.xxinitvalue = STARTFRAGMENT;
+    else	  parseState.xxinitvalue = STARTFILE;
+
+    parseState.xxMacroList = InstallKeywords();
+
+    parseState.Value = R_NilValue;
+
+    if (yyparse()) *status = PARSE_ERROR;
+    else *status = PARSE_OK;
+
+#if DEBUGVALS
+    Rprintf("ParseRd result: %p\n", parseState.Value);
+#endif
+    UNPROTECT_PTR(parseState.Value);
+    UNPROTECT_PTR(parseState.xxMacroList);
+
+    if (pushbase != pushback) free(pushbase);
+
+    return parseState.Value;
+}
+
+//#include "Rconnections.h"
+typedef SEXP Rconnection;
+static int Rconn_fgetc(Rconnection con) {
+	return -1;
+}
+
+static Rconnection con_parse;
+static JNIEnv *jnienv;
+static jmethodID getcMethodID;
+
+/* need to handle incomplete last line */
+static int con_getc(void)
+{
+    int c;
+    static int last=-1000;
+
+    c = (*jnienv)->CallIntMethod(jnienv, con_parse, getcMethodID, con_parse);
+    if (c == EOF && last != '\n') c = '\n';
+    return (last = c);
+}
+
+static
+SEXP R_ParseRd(JNIEnv *env, Rconnection con, ParseStatus *status, SEXP srcfile, Rboolean fragment)
+{
+    con_parse = con;
+    jnienv = env;
+    jclass klass = (*env)->FindClass(env, "com/oracle/truffle/r/runtime/conn/RConnection");
+    getcMethodID = (*env)->GetMethodID(env, klass, "getc", "()I");
+    ptr_getc = con_getc;
+    return ParseRd(status, srcfile, fragment);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ *  The Lexical Analyzer:
+ *
+ *  Basic lexical analysis is performed by the following
+ *  routines.
+ *
+ *  The function yylex() scans the input, breaking it into
+ *  tokens which are then passed to the parser.
+ *
+ */
+
+
+/* Special Symbols */
+/* Section and R code headers */
+
+struct {
+    char *name;
+    int token;
+}
+
+/* When adding keywords here, make sure all the handlers
+   are also modified:  checkRd, Rd2HTML, Rd2latex, Rd2txt, any other new ones... */
+
+static keywords[] = {
+    /* These sections contain Latex-like text */
+
+    { "\\author",  SECTIONHEADER },
+    { "\\concept", SECTIONHEADER },
+    { "\\description",SECTIONHEADER },
+    { "\\details", SECTIONHEADER },
+    { "\\docType", SECTIONHEADER },
+
+    { "\\encoding",SECTIONHEADER },
+    { "\\format",  SECTIONHEADER },
+    { "\\keyword", SECTIONHEADER },
+    { "\\note",    SECTIONHEADER },
+    { "\\references", SECTIONHEADER },
+
+    { "\\section", SECTIONHEADER2 },
+    { "\\seealso", SECTIONHEADER },
+    { "\\source",  SECTIONHEADER },
+    { "\\title",   SECTIONHEADER },
+
+    /* These sections contain R-like text */
+
+    { "\\examples",RSECTIONHEADER },
+    { "\\usage",   RSECTIONHEADER },
+
+    /* These sections contain verbatim text */
+
+    { "\\alias",   VSECTIONHEADER },
+    { "\\name",    VSECTIONHEADER },
+    { "\\synopsis",VSECTIONHEADER },
+    { "\\Rdversion",VSECTIONHEADER },
+
+    /* These macros take no arguments.  One character non-alpha escapes get the
+       same token value */
+
+    { "\\cr",      ESCAPE },
+    { "\\dots",    ESCAPE },
+    { "\\ldots",   ESCAPE },
+    { "\\R",       ESCAPE },
+    { "\\tab",     ESCAPE },
+
+    /* These macros take one LaTeX-like argument. */
+
+    { "\\acronym", LATEXMACRO },
+    { "\\bold",    LATEXMACRO },
+    { "\\cite",    LATEXMACRO },
+    { "\\command", LATEXMACRO },
+    { "\\dfn",     LATEXMACRO },
+    { "\\dQuote",  LATEXMACRO },
+    { "\\email",   LATEXMACRO },
+
+    { "\\emph",    LATEXMACRO },
+    { "\\file",    LATEXMACRO },
+    { "\\linkS4class", LATEXMACRO },
+    { "\\pkg",	   LATEXMACRO },
+    { "\\sQuote",  LATEXMACRO },
+
+    { "\\strong",  LATEXMACRO },
+
+    { "\\var",     LATEXMACRO },
+
+    /* These are like SECTIONHEADER/LATEXMACRO, but they change the interpretation of \item */
+
+    { "\\arguments",LISTSECTION },
+    { "\\value",   LISTSECTION },
+
+    { "\\describe",DESCRIPTION },
+    { "\\enumerate",ITEMIZE },
+    { "\\itemize", ITEMIZE },
+
+    { "\\item",    NOITEM }, /* will change to UNKNOWN, ESCAPE, or LATEXMACRO2 depending on context */
+
+    /* These macros take two LaTeX-like arguments. */
+
+    { "\\enc",     LATEXMACRO2 },
+    { "\\if",      LATEXMACRO2 },
+    { "\\method",  LATEXMACRO2 },
+    { "\\S3method",LATEXMACRO2 },
+    { "\\S4method",LATEXMACRO2 },
+    { "\\tabular", LATEXMACRO2 },
+    { "\\subsection", LATEXMACRO2 },
+
+    /* This macro takes one verbatim and one LaTeX-like argument. */
+
+    { "\\href",    VERBLATEX },
+
+    /* This macro takes three LaTeX-like arguments. */
+
+    { "\\ifelse",  LATEXMACRO3 },
+
+    /* These macros take one optional bracketed option and always take
+       one LaTeX-like argument */
+
+    { "\\link",    OPTMACRO },
+
+    /* These markup macros require an R-like text argument */
+
+    { "\\code",    RCODEMACRO },
+    { "\\dontshow",RCODEMACRO },
+    { "\\donttest",RCODEMACRO },
+    { "\\testonly",RCODEMACRO },
+
+    /* This macro takes one optional bracketed option and one R-like argument */
+
+    { "\\Sexpr",   SEXPR },
+
+    /* This is just like a VSECTIONHEADER, but it needs SEXPR processing */
+
+    { "\\RdOpts",   RDOPTS },
+
+    /* These macros take one verbatim arg and ignore everything except braces */
+
+    { "\\dontrun", VERBMACRO }, /* at least for now */
+    { "\\env",     VERBMACRO },
+    { "\\kbd", 	   VERBMACRO },
+    { "\\option",  VERBMACRO },
+    { "\\out",     VERBMACRO },
+    { "\\preformatted", VERBMACRO },
+
+    { "\\samp",    VERBMACRO },
+    { "\\special", VERBMACRO },
+    { "\\url",     VERBMACRO },
+    { "\\verb",    VERBMACRO },
+
+    /* These ones take one or two verbatim args */
+
+    { "\\eqn",     VERBMACRO2 },
+    { "\\deqn",    VERBMACRO2 },
+    { "\\figure",  VERBMACRO2 },
+
+    /* We parse IFDEF/IFNDEF as markup, not as a separate preprocessor step */
+
+    { "#ifdef",    IFDEF },
+    { "#ifndef",   IFDEF },
+    { "#endif",    ENDIF },
+
+    /* These allow user defined macros */
+    { "\\newcommand", NEWCOMMAND },
+    { "\\renewcommand", NEWCOMMAND },
+
+    { 0,	   0	      }
+    /* All other markup macros are rejected. */
+};
+
+/* Record the longest # directive here */
+#define DIRECTIVE_LEN 7
+
+static SEXP InstallKeywords()
+{
+    int i, num;
+    SEXP result, name, val;
+    num = sizeof(keywords)/sizeof(keywords[0]);
+    PROTECT(result = R_NewHashedEnv(R_EmptyEnv, ScalarInteger(num)));
+    for (i = 0; keywords[i].name; i++) {
+        PROTECT(name = install(keywords[i].name));
+        PROTECT(val = ScalarInteger(keywords[i].token));
+    	defineVar(name, val, result);
+    	UNPROTECT(2);
+    }
+    return result;
+}
+
+static int KeywordLookup(const char *s)
+{
+    SEXP rec = findVar(install(s), parseState.xxMacroList);
+    if (rec == R_UnboundValue) return UNKNOWN;
+    else return INTEGER(rec)[0];
+}
+
+static SEXP UserMacroLookup(const char *s)
+{
+    SEXP rec = findVar(install(s), parseState.xxMacroList);
+    if (rec == R_UnboundValue) error(_("Unable to find macro %s"), s);
+    return getAttrib(rec, install("definition"));
+}
+
+static void yyerror(const char *s)
+{
+    static const char *const yytname_translations[] =
+    {
+    /* the left column are strings coming from bison, the right
+       column are translations for users.
+       The first YYENGLISH from the right column are English to be translated,
+       the rest are to be copied literally.  The #if 0 block below allows xgettext
+       to see these.
+    */
+#define YYENGLISH 17
+	"$undefined",	"input",
+	"SECTIONHEADER","section header",
+	"RSECTIONHEADER","section header",
+	"VSECTIONHEADER","section header",
+	"LISTSECTION",	"section header",
+
+	"LATEXMACRO",	"macro",
+	"LATEXMACRO2",  "macro",
+	"LATEXMACRO3",  "macro",
+	"RCODEMACRO",	"macro",
+	"VERBMACRO",    "macro",
+	"VERBMACRO2",	"macro",
+
+	"ESCAPE",	"macro",
+	"ITEMIZE",	"macro",
+	"IFDEF",	"conditional",
+	"SECTIONHEADER2","section header",
+	"OPTMACRO",	"macro",
+
+	"DESCRIPTION",	"macro",
+	"VERB",		"VERBATIM TEXT",
+	0,		0
+    };
+    static char const yyunexpected[] = "syntax error, unexpected ";
+    static char const yyexpecting[] = ", expecting ";
+    static char const yyshortunexpected[] = "unexpected %s";
+    static char const yylongunexpected[] = "unexpected %s '%s'";
+    char *expecting;
+    char ParseErrorMsg[PARSE_ERROR_SIZE];
+    SEXP filename;
+    char ParseErrorFilename[PARSE_ERROR_SIZE];
+
+    xxWarnNewline();	/* post newline warning if necessary */
+
+    /*
+    R_ParseError     = yylloc.first_line;
+    R_ParseErrorCol  = yylloc.first_column;
+    R_ParseErrorFile = SrcFile;
+    */
+
+    if (!strncmp(s, yyunexpected, sizeof yyunexpected -1)) {
+	int i, translated = FALSE;
+    	/* Edit the error message */
+    	expecting = strstr(s + sizeof yyunexpected -1, yyexpecting);
+    	if (expecting) *expecting = '\0';
+    	for (i = 0; yytname_translations[i]; i += 2) {
+    	    if (!strcmp(s + sizeof yyunexpected - 1, yytname_translations[i])) {
+    	    	if (yychar < 256)
+    	    	    snprintf(ParseErrorMsg, PARSE_ERROR_SIZE,
+			     _(yyshortunexpected),
+			     i/2 < YYENGLISH ? _(yytname_translations[i+1])
+			     : yytname_translations[i+1]);
+    	    	else
+    	    	    snprintf(ParseErrorMsg, PARSE_ERROR_SIZE,
+			     _(yylongunexpected),
+			     i/2 < YYENGLISH ? _(yytname_translations[i+1])
+			     : yytname_translations[i+1],
+			     CHAR(STRING_ELT(yylval, 0)));
+    	    	translated = TRUE;
+    	    	break;
+    	    }
+    	}
+    	if (!translated) {
+    	    if (yychar < 256)
+    		snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, _(yyshortunexpected),
+			s + sizeof yyunexpected - 1);
+    	    else
+    	    	snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, _(yylongunexpected),
+			 s + sizeof yyunexpected - 1, CHAR(STRING_ELT(yylval, 0)));
+	}
+    	if (expecting) {
+ 	    translated = FALSE;
+    	    for (i = 0; yytname_translations[i]; i += 2) {
+    	    	if (!strcmp(expecting + sizeof yyexpecting - 1, yytname_translations[i])) {
+    	    	    strcat(ParseErrorMsg, _(yyexpecting));
+    	    	    strcat(ParseErrorMsg, i/2 < YYENGLISH ? _(yytname_translations[i+1])
+    	    	                    : yytname_translations[i+1]);
+    	    	    translated = TRUE;
+		    break;
+		}
+	    }
+	    if (!translated) {
+	    	strcat(ParseErrorMsg, _(yyexpecting));
+	    	strcat(ParseErrorMsg, expecting + sizeof yyexpecting - 1);
+	    }
+	}
+    } else if (!strncmp(s, yyunknown, sizeof yyunknown-1)) {
+    	snprintf(ParseErrorMsg, PARSE_ERROR_SIZE,
+		"%s '%s'", s, CHAR(STRING_ELT(yylval, 0)));
+    } else {
+    	snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, "%s", s);
+    }
+    filename = findVar(install("filename"), SrcFile);
+    if (isString(filename) && length(filename))
+    	strncpy(ParseErrorFilename, CHAR(STRING_ELT(filename, 0)), PARSE_ERROR_SIZE - 1);
+    else
+        ParseErrorFilename[0] = '\0';
+    if (wCalls) {
+	if (yylloc.first_line != yylloc.last_line)
+	    warning("%s:%d-%d: %s",
+		    ParseErrorFilename, yylloc.first_line, yylloc.last_line, ParseErrorMsg);
+	else
+	    warning("%s:%d: %s",
+		    ParseErrorFilename, yylloc.first_line, ParseErrorMsg);
+    } else {
+	if (yylloc.first_line != yylloc.last_line)
+	    warningcall(R_NilValue, "%s:%d-%d: %s",
+		    ParseErrorFilename, yylloc.first_line, yylloc.last_line, ParseErrorMsg);
+	else
+	    warningcall(R_NilValue, "%s:%d: %s",
+			ParseErrorFilename, yylloc.first_line, ParseErrorMsg);
+    }
+}
+
+#define TEXT_PUSH(c) do {                  \
+	size_t nc = bp - stext;       \
+	if (nc >= nstext - 1) {             \
+	    char *old = stext;              \
+            nstext *= 2;                    \
+	    stext = malloc(nstext);         \
+	    if(!stext) error(_("unable to allocate buffer for long string at line %d"), parseState.xxlineno);\
+	    memmove(stext, old, nc);        \
+	    if(old != st0) free(old);	    \
+	    bp = stext+nc; }		    \
+	*bp++ = ((char) c);		    \
+} while(0)
+
+static void setfirstloc(void)
+{
+    yylloc.first_line = parseState.xxlineno;
+    yylloc.first_column = parseState.xxcolno;
+    yylloc.first_byte = parseState.xxbyteno;
+}
+
+static void setlastloc(void)
+{
+    yylloc.last_line = prevlines[prevpos];
+    yylloc.last_column = prevcols[prevpos];
+    yylloc.last_byte = prevbytes[prevpos];
+}
+
+/* Split the input stream into tokens. */
+/* This is the lowest of the parsing levels. */
+
+static int token(void)
+{
+    int c, lookahead;
+    int outsideLiteral = parseState.xxmode == LATEXLIKE || parseState.xxmode == INOPTION || parseState.xxbraceDepth == 0;
+
+    if (parseState.xxinitvalue) {
+        yylloc.first_line = 0;
+        yylloc.first_column = 0;
+        yylloc.first_byte = 0;
+        yylloc.last_line = 0;
+        yylloc.last_column = 0;
+        yylloc.last_byte = 0;
+    	PROTECT(yylval = mkString(""));
+        c = parseState.xxinitvalue;
+    	parseState.xxinitvalue = 0;
+    	return(c);
+    }
+
+    setfirstloc();
+    c = xxgetc();
+
+    switch (c) {
+    	case '%': if (!parseState.xxinEqn) return mkComment(c);
+    	    break;
+	case '\\':
+	    if (!parseState.xxinEqn) {
+		lookahead = xxungetc(xxgetc());
+		if (isalpha(lookahead) && parseState.xxmode != VERBATIM
+		    /* In R strings, only link or var is allowed as markup */
+		    && (lookahead == 'l' || lookahead == 'v' || !parseState.xxinRString))
+		    return mkMarkup(c);
+	    }
+	    break;
+        case R_EOF:
+            if (parseState.xxinRString) {
+       		xxWarnNewline();
+       		error(_("Unexpected end of input (in %c quoted string opened at %s:%d:%d)"),
+ 			parseState.xxinRString, parseState.xxBasename, parseState.xxQuoteLine, parseState.xxQuoteCol);
+    	    }
+    	    return END_OF_INPUT;
+    	case '#':
+    	    if (!parseState.xxinEqn && yylloc.first_column == 1) return mkIfdef(c);
+    	    break;
+    	case LBRACE:
+    	    if (!parseState.xxinRString) {
+    	    	parseState.xxbraceDepth++;
+    	    	if (outsideLiteral) return c;
+    	    }
+    	    break;
+    	case RBRACE:
+    	    if (!parseState.xxinRString) {
+    	    	parseState.xxbraceDepth--;
+    	    	if (outsideLiteral || parseState.xxbraceDepth == 0) return c;
+    	    }
+    	    break;
+    	case '[':
+    	case ']':
+    	    if (parseState.xxmode == INOPTION ) return c;
+    	    break;
+    }
+
+    switch (parseState.xxmode) {
+	case RLIKE:     return mkCode(c);
+	case INOPTION:
+	case LATEXLIKE: return mkText(c);
+	case VERBATIM:  return mkVerb(c);
+    }
+
+    return ERROR; /* We shouldn't get here. */
+}
+
+#define INITBUFSIZE 128
+
+static int mkText(int c)
+{
+    char st0[INITBUFSIZE];
+    unsigned int nstext = INITBUFSIZE;
+    char *stext = st0, *bp = st0, lookahead;
+
+    while(1) {
+    	switch (c) {
+    	case '\\':
+    	    lookahead = (char) xxgetc();
+    	    if (lookahead == LBRACE || lookahead == RBRACE ||
+    	        lookahead == '%' || lookahead == '\\') {
+    	    	c = lookahead;
+    	    	break;
+    	    }
+    	    xxungetc(lookahead);
+    	    if (isalpha(lookahead)) goto stop;
+    	case ']':
+    	    if (parseState.xxmode == INOPTION) goto stop;
+            break;
+    	case '%':
+    	case LBRACE:
+    	case RBRACE:
+    	case R_EOF:
+    	    goto stop;
+    	}
+    	TEXT_PUSH(c);
+    	if (c == '\n') goto stop;
+    	c = xxgetc();
+    };
+stop:
+    if (c != '\n') xxungetc(c); /* newline causes a break, but we keep it */
+    PROTECT(yylval = mkString2(stext, bp - stext));
+    if(stext != st0) free(stext);
+    return TEXT;
+}
+
+static int mkComment(int c)
+{
+    char st0[INITBUFSIZE];
+    unsigned int nstext = INITBUFSIZE;
+    char *stext = st0, *bp = st0;
+
+    do TEXT_PUSH(c);
+    while ((c = xxgetc()) != '\n' && c != R_EOF);
+
+    xxungetc(c);
+
+    PROTECT(yylval = mkString2(stext, bp - stext));
+    if(stext != st0) free(stext);
+    return COMMENT;
+}
+
+static int mkCode(int c)
+{
+    char st0[INITBUFSIZE];
+    unsigned int nstext = INITBUFSIZE;
+    char *stext = st0, *bp = st0;
+
+    /* Avoid double counting initial braces */
+    if (c == LBRACE && !parseState.xxinRString) parseState.xxbraceDepth--;
+    if (c == RBRACE && !parseState.xxinRString) parseState.xxbraceDepth++;
+
+    while(1) {
+	int escaped = 0;
+    	if (c == '\\') {
+    	    int lookahead = xxgetc();
+    	    if (lookahead == '\\' || lookahead == '%') {
+    	         c = lookahead;
+    	         escaped = 1;
+    	    } else xxungetc(lookahead);
+    	}
+    	if ((!escaped && c == '%') || c == R_EOF) break;
+    	if (parseState.xxinRString) {
+    	    /* This stuff is messy, because there are two levels of escaping:
+    	       The Rd escaping and the R code string escaping. */
+    	    if (c == '\\') {
+    		int lookahead = xxgetc();
+    		if (lookahead == '\\') { /* This must be the 3rd backslash */
+    		    lookahead = xxgetc();
+    		    if (lookahead == parseState.xxinRString || lookahead == '\\') {
+    	    	    	TEXT_PUSH(c);
+    	    	    	c = lookahead;
+    	    	    	escaped = 1;
+    	    	    } else {
+    	    	    	xxungetc(lookahead); /* put back the 4th char */
+    	    	    	xxungetc('\\');	     /* and the 3rd */
+    	    	    }
+    	    	} else if (lookahead == parseState.xxinRString) { /* There could be one or two before this */
+    	    	    TEXT_PUSH(c);
+    	    	    c = lookahead;
+    	    	    escaped = 1;
+    	    	} else if (!escaped && (lookahead == 'l' || lookahead == 'v')) {
+    	    	    /* assume \link or \var; this breaks vertical tab, but does anyone ever use that? */
+    	    	    xxungetc(lookahead);
+    	    	    break;
+    	    	} else xxungetc(lookahead);
+    	    }
+    	    if (!escaped && c == parseState.xxinRString)
+    	    	parseState.xxinRString = 0;
+    	} else {
+    	    if (c == '#') {
+    	    	do {
+    	    	    int escaped = 0;
+    	    	    TEXT_PUSH(c);
+    	    	    c = xxgetc();
+    	    	    if (c == '\\') {
+		        int lookahead = xxgetc();
+		        if (lookahead == '\\' || lookahead == '%' || lookahead == LBRACE || lookahead == RBRACE) {
+		            c = lookahead;
+		            escaped = 1;
+		        } else xxungetc(lookahead);
+    		    }
+    	    	    if (c == LBRACE && !escaped) parseState.xxbraceDepth++;
+    	    	    else if (c == RBRACE && !escaped) parseState.xxbraceDepth--;
+    	    	} while (c != '\n' && c != R_EOF && parseState.xxbraceDepth > 0);
+    	    	if (c == RBRACE && !escaped) parseState.xxbraceDepth++; /* avoid double counting */
+    	    }
+    	    if (c == '\'' || c == '"' || c == '`') {
+    	    	parseState.xxinRString = c;
+    	    	parseState.xxQuoteLine = parseState.xxlineno;
+    	    	parseState.xxQuoteCol  = parseState.xxcolno;
+    	    } else if (c == '\\' && !escaped) {
+    	    	int lookahead = xxgetc();
+    	    	if (lookahead == LBRACE || lookahead == RBRACE) {
+		    c = lookahead;
+		} else if (isalpha(lookahead)) {
+    	    	    xxungetc(lookahead);
+    	    	    c = '\\';
+    	    	    break;
+    	    	} else {
+    	    	    TEXT_PUSH('\\');
+    	    	    c = lookahead;
+    	    	}
+    	    } else if (c == LBRACE) {
+    	    	parseState.xxbraceDepth++;
+    	    } else if (c == RBRACE) {
+    	    	if (parseState.xxbraceDepth == 1) break;
+    	    	else parseState.xxbraceDepth--;
+    	    } else if (c == R_EOF) break;
+    	}
+    	TEXT_PUSH(c);
+    	if (c == '\n') {
+    	    if (parseState.xxinRString && !parseState.xxNewlineInString)
+    	    	parseState.xxNewlineInString = parseState.xxlineno-1;
+    	    break;
+    	}
+    	c = xxgetc();
+    }
+    if (c != '\n') xxungetc(c);
+    PROTECT(yylval = mkString2(stext, bp - stext));
+    if(stext != st0) free(stext);
+    return RCODE;
+}
+
+static int mkMarkup(int c)
+{
+    char st0[INITBUFSIZE];
+    unsigned int nstext = INITBUFSIZE;
+    char *stext = st0, *bp = st0;
+    int retval = 0, attempt = 0;
+
+    TEXT_PUSH(c);
+    while (isalnum((c = xxgetc()))) TEXT_PUSH(c);
+
+    while (attempt++ < 2) {
+    	/* character escapes are processed as text, not markup */
+    	if (bp == stext+1) {
+    	    TEXT_PUSH(c);
+    	    TEXT_PUSH('\0');
+    	    retval = TEXT;
+    	    c = xxgetc();
+    	    break;
+    	} else {
+    	    TEXT_PUSH('\0');
+    	    retval = KeywordLookup(stext);
+    	    if (retval == UNKNOWN && attempt == 1) { /* try again, non-digits only */
+    	    	bp--; 				     /* pop the \0 */
+    	        while (isdigit(*(bp-1))) {
+            	    xxungetc(c);
+    	            c = *(--bp);                     /* pop the last letter into c */
+            	}
+            } else {
+            	if (retval == NOITEM)
+    	    	    retval = parseState.xxitemType;
+    	    	break;
+    	    }
+        }
+    }
+    PROTECT(yylval = mkString2(stext, bp - stext - 1));
+    if(stext != st0) free(stext);
+    xxungetc(c);
+    return retval;
+}
+
+static int mkIfdef(int c)
+{
+    char st0[INITBUFSIZE];
+    unsigned int nstext = INITBUFSIZE;
+    char *stext = st0, *bp = st0;
+    int retval;
+
+    TEXT_PUSH(c);
+    while (isalpha((c = xxgetc())) && bp - stext <= DIRECTIVE_LEN) TEXT_PUSH(c);
+    TEXT_PUSH('\0');
+    xxungetc(c);
+
+    retval = KeywordLookup(stext);
+    PROTECT(yylval = mkString2(stext, bp - stext - 1));
+
+    switch (retval) {
+    case ENDIF:  /* eat chars to the end of the line */
+    	do { c = xxgetc(); }
+    	while (c != '\n' && c != R_EOF);
+    	break;
+    case UNKNOWN:
+    	UNPROTECT(1);
+    	bp--; bp--;
+    	for (; bp > stext; bp--)
+    	    xxungetc(*bp);
+    	switch (parseState.xxmode) {
+    	case RLIKE:
+    	    retval = mkCode(*bp);
+    	    break;
+    	case INOPTION:
+    	case LATEXLIKE:
+    	    retval = mkText(*bp);
+    	    break;
+    	case VERBATIM:
+    	    retval = mkVerb(*bp);
+    	    break;
+	}
+	break;
+    }
+    if(stext != st0) free(stext);
+    return retval;
+}
+
+static int mkVerb(int c)
+{
+    char st0[INITBUFSIZE];
+    unsigned int nstext = INITBUFSIZE;
+    char *stext = st0, *bp = st0;
+
+    /* Avoid double counting initial braces */
+    if (c == LBRACE) parseState.xxbraceDepth--;
+    if (c == RBRACE) parseState.xxbraceDepth++;
+
+    while(1) {
+    	int escaped = 0;
+        if (c == '\\') {
+            int lookahead = xxgetc();
+            if (lookahead == '\\' || lookahead == '%' || lookahead == LBRACE || lookahead == RBRACE) {
+		escaped = 1;
+		if (parseState.xxinEqn) TEXT_PUSH(c);
+		c = lookahead;
+	    } else xxungetc(lookahead);
+        }
+        if (c == R_EOF) break;
+        if (!escaped) {
+    	    if (c == '%' && !parseState.xxinEqn) break;
+	    else if (c == LBRACE) parseState.xxbraceDepth++;
+    	    else if (c == RBRACE) {
+	    	if (parseState.xxbraceDepth == 1) break;
+	    	else parseState.xxbraceDepth--;
+	    }
+	}
+    	TEXT_PUSH(c);
+    	if (c == '\n') break;
+    	c = xxgetc();
+    };
+    if (c != '\n') xxungetc(c);
+    PROTECT(yylval = mkString2(stext, bp - stext));
+    if(stext != st0) free(stext);
+    return VERB;
+}
+
+static int yylex(void)
+{
+    int tok = token();
+
+    if (parseState.xxDebugTokens) {
+        Rprintf("%d:%d: %s", yylloc.first_line, yylloc.first_column, yytname[YYTRANSLATE(tok)]);
+    	if (parseState.xxinRString) Rprintf("(in %c%c)", parseState.xxinRString, parseState.xxinRString);
+    	if (tok > 255 && tok != END_OF_INPUT)
+    	    Rprintf(": %s", CHAR(STRING_ELT(yylval, 0)));
+	Rprintf("\n");
+    }
+    setlastloc();
+    return tok;
+}
+
+static void PutState(ParseState *state) {
+    state->xxinRString = parseState.xxinRString;
+    state->xxQuoteLine = parseState.xxQuoteLine;
+    state->xxQuoteCol = parseState.xxQuoteCol;
+    state->xxinEqn = parseState.xxinEqn;
+    state->xxNewlineInString = parseState.xxNewlineInString;
+    state->xxlineno = parseState.xxlineno;
+    state->xxbyteno = parseState.xxbyteno;
+    state->xxcolno = parseState.xxcolno;
+    state->xxmode = parseState.xxmode;
+    state->xxitemType = parseState.xxitemType;
+    state->xxbraceDepth = parseState.xxbraceDepth;
+    state->xxDebugTokens = parseState.xxDebugTokens;
+    state->xxBasename = parseState.xxBasename;
+    state->Value = parseState.Value;
+    state->xxinitvalue = parseState.xxinitvalue;
+    state->xxMacroList = parseState.xxMacroList;
+    state->prevState = parseState.prevState;
+}
+
+static void UseState(ParseState *state) {
+    parseState.xxinRString = state->xxinRString;
+    parseState.xxQuoteLine = state->xxQuoteLine;
+    parseState.xxQuoteCol = state->xxQuoteCol;
+    parseState.xxinEqn = state->xxinEqn;
+    parseState.xxNewlineInString = state->xxNewlineInString;
+    parseState.xxlineno = state->xxlineno;
+    parseState.xxbyteno = state->xxbyteno;
+    parseState.xxcolno = state->xxcolno;
+    parseState.xxmode = state->xxmode;
+    parseState.xxitemType = state->xxitemType;
+    parseState.xxbraceDepth = state->xxbraceDepth;
+    parseState.xxDebugTokens = state->xxDebugTokens;
+    parseState.xxBasename = state->xxBasename;
+    parseState.Value = state->Value;
+    parseState.xxinitvalue = state->xxinitvalue;
+    parseState.xxMacroList = state->xxMacroList;
+    parseState.prevState = state->prevState;
+}
+
+static void PushState() {
+    if (busy) {
+    	ParseState *prev = malloc(sizeof(ParseState));
+    	PutState(prev);
+    	parseState.prevState = prev;
+    } else
+        parseState.prevState = NULL;
+    busy = TRUE;
+}
+
+static void PopState() {
+    if (parseState.prevState) {
+    	ParseState *prev = parseState.prevState;
+    	UseState(prev);
+    	free(prev);
+    } else
+    	busy = FALSE;
+}
+
+/* "do_parseRd"
+
+ .External2(C_parseRd,file, srcfile, encoding, verbose, basename, warningCalls)
+ If there is text then that is read and the other arguments are ignored.
+*/
+JNIEXPORT jobject JNICALL
+Java_com_oracle_truffle_r_library_tools_ToolsNative_cParseRdNative(JNIEnv *env, jclass c, jobject con,
+		jobject source, jboolean verbose, jboolean fragment, jstring basename, jboolean warningcalls)
+{
+	setEnv(env);
+	SEXP s = R_NilValue;
+	ParseStatus status;
+
+#if DEBUGMODE
+	yydebug = 1;
+#endif
+
+	R_ParseError = 0;
+	R_ParseErrorMsg[0] = '\0';
+
+	PushState();
+
+	parseState.xxBasename = basename;
+	wCalls = warningcalls;
+
+	s = R_ParseRd(env, con, &status, source, fragment);
+	PopState();
+	if (status != PARSE_OK) {
+		// TODO throw an exception
+	}
+
+    return s;
+}
+
+/* "do_deparseRd"
+
+ .External2(C_deparseRd, element, state)
+*/
+
+// TODO
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
index 2b31f7d319..f1b15659e2 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
@@ -94,32 +94,7 @@ public abstract class CastListNode extends CastNode {
     @Specialization
     @TruffleBoundary
     protected RList doPairList(RPairList pl) {
-        // One list type into another, not performance critical!
-        int length = pl.getLength();
-        if (length == 0) {
-            return RDataFactory.createList();
-        }
-        Object[] data = new Object[length];
-        String[] names = new String[length];
-        boolean complete = RDataFactory.COMPLETE_VECTOR;
-        int i = 0;
-        RPairList tpl = pl;
-        while (tpl != null) {
-            Object tag = tpl.getTag();
-            names[i] = pl.isNullTag() ? RRuntime.NAMES_ATTR_EMPTY_VALUE : (String) tag;
-            if (tag == RRuntime.STRING_NA) {
-                complete = RDataFactory.INCOMPLETE_VECTOR;
-            }
-            data[i] = tpl.car();
-            Object cdr = tpl.cdr();
-            if (RPairList.isNull(cdr)) {
-                break;
-            } else {
-                tpl = (RPairList) cdr;
-            }
-            i++;
-        }
-        return RDataFactory.createList(data, RDataFactory.createStringVector(names, complete));
+        return pl.toRList();
     }
 
     @Specialization
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java
index e20a854b46..18538e1f73 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java
@@ -66,4 +66,9 @@ public abstract class CastToVectorNode extends CastNode {
         return expression.getList();
     }
 
+    @Specialization
+    protected RAbstractVector cast(RDataFrame dataFrame) {
+        return dataFrame.getVector();
+    }
+
 }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/BuiltinLibPath.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/LibPaths.java
similarity index 76%
rename from com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/BuiltinLibPath.java
rename to com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/LibPaths.java
index 96d156d48e..d22d57de0c 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/BuiltinLibPath.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/LibPaths.java
@@ -27,17 +27,28 @@ import java.nio.file.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.RPlatform.*;
 
-public class BuiltinLibPath {
+public class LibPaths {
 
     /**
      * Returns the absolute path to the builtin library {@code libName} for use with
      * {@link System#load}.
      */
-    public static String getLibPath(String libName) {
+    public static String getBuiltinLibPath(String libName) {
         String rHome = REnvVars.rHome();
         String packageName = "com.oracle.truffle.r.native";
         OSInfo osInfo = RPlatform.getOSInfo();
         Path path = FileSystems.getDefault().getPath(rHome, packageName, "builtinlibs", "lib", "lib" + libName + "." + osInfo.libExt);
         return path.toString();
     }
+
+    /**
+     * Returns the absolute path to the shared library associated with package {@code name}. (Does
+     * not check for existence).
+     */
+    public static String getPackageLibPath(String name) {
+        String rHome = REnvVars.rHome();
+        String packageDir = "library";
+        Path path = FileSystems.getDefault().getPath(rHome, packageDir, name, "libs", name + ".so");
+        return path.toString();
+    }
 }
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 11e31868c9..1826713ff9 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
@@ -22,9 +22,12 @@
  */
 package com.oracle.truffle.r.runtime.ffi.jnr;
 
+import com.oracle.truffle.api.source.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
+import com.oracle.truffle.r.runtime.env.*;
+import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
 import com.oracle.truffle.r.runtime.ops.na.*;
 
 /**
@@ -46,6 +49,10 @@ public class CallRFFIHelper {
         return RDataFactory.createDoubleVectorFromScalar(value);
     }
 
+    static RStringVector Rf_ScalarString(String value) {
+        return RDataFactory.createStringVectorFromScalar(value);
+    }
+
     static int Rf_asInteger(Object x) {
         if (x instanceof Integer) {
             return ((Integer) x).intValue();
@@ -76,6 +83,78 @@ public class CallRFFIHelper {
         }
     }
 
+    static Object Rf_cons(Object car, Object cdr) {
+        return RDataFactory.createPairList(car, cdr);
+    }
+
+    static void Rf_defineVar(Object symbolArg, Object value, Object envArg) {
+        REnvironment env = (REnvironment) envArg;
+        RSymbol name = (RSymbol) symbolArg;
+        try {
+            env.put(name.getName(), value);
+        } catch (PutException ex) {
+            throw RError.error((SourceSection) null, ex);
+        }
+    }
+
+    static Object Rf_findVar(Object symbolArg, Object envArg) {
+        REnvironment env = (REnvironment) envArg;
+        RSymbol name = (RSymbol) symbolArg;
+        Object value = env.get(name.getName());
+        return value == null ? RUnboundValue.instance : value;
+    }
+
+    static Object Rf_getAttrib(Object obj, Object name) {
+        Object result = RNull.instance;
+        if (obj instanceof RAttributable) {
+            RAttributable attrObj = (RAttributable) obj;
+            RAttributes attrs = attrObj.getAttributes();
+            if (attrs != null) {
+                String nameAsString = ((RSymbol) name).getName().intern();
+                Object attr = attrs.get(nameAsString);
+                if (attr != null) {
+                    result = attr;
+                }
+            }
+        }
+        return result;
+    }
+
+    static void Rf_setAttrib(Object obj, Object name, Object val) {
+        if (obj instanceof RAttributable) {
+            RAttributable attrObj = (RAttributable) obj;
+            RAttributes attrs = attrObj.getAttributes();
+            if (attrs == null) {
+                attrs = attrObj.initAttributes();
+            }
+            String nameAsString;
+            if (name instanceof RSymbol) {
+                nameAsString = ((RSymbol) name).getName();
+            } else {
+                nameAsString = RRuntime.asString(name);
+                assert nameAsString != null;
+            }
+            nameAsString = nameAsString.intern();
+            attrs.put(nameAsString, val);
+        }
+    }
+
+    static int Rf_isString(Object x) {
+        return RRuntime.asString(x) == null ? 0 : 1;
+    }
+
+    static int Rf_isNull(Object x) {
+        return x == RNull.instance ? 1 : 0;
+    }
+
+    static Object Rf_PairToVectorList(Object x) {
+        if (x == RNull.instance) {
+            return RDataFactory.createList();
+        }
+        RPairList pl = (RPairList) x;
+        return pl.toRList();
+    }
+
     static int LENGTH(Object x) {
         if (x instanceof RAbstractContainer) {
             return ((RAbstractContainer) x).getLength();
@@ -92,6 +171,18 @@ public class CallRFFIHelper {
         xv.setElement(i, v);
     }
 
+    static void SET_INTEGER_ELT(Object x, int i, int v) {
+        // TODO error checks
+        RIntVector xv = (RIntVector) x;
+        xv.setElement(i, v);
+    }
+
+    static void SET_VECTOR_ELT(Object x, int i, Object v) {
+        // TODO error checks
+        RList list = (RList) x;
+        list.setElement(i, v);
+    }
+
     static byte[] RAW(Object x) {
         if (x instanceof RRawVector) {
             return ((RRawVector) x).getDataCopy();
@@ -101,6 +192,30 @@ public class CallRFFIHelper {
 
     }
 
+    static int[] INTEGER(Object x) {
+        if (x instanceof RIntVector) {
+            return ((RIntVector) x).getDataCopy();
+        } else {
+            throw RInternalError.unimplemented();
+        }
+    }
+
+    static String STRING_ELT(Object x, int i) {
+        if (x instanceof RStringVector) {
+            return ((RStringVector) x).getDataAt(i);
+        } else {
+            throw RInternalError.unimplemented();
+        }
+    }
+
+    static Object VECTOR_ELT(Object x, int i) {
+        if (x instanceof RList) {
+            return ((RList) x).getDataAt(i);
+        } else {
+            throw RInternalError.unimplemented();
+        }
+    }
+
     static int NAMED(Object x) {
         if (x instanceof RShareable) {
             return ((RShareable) x).isShared() ? 1 : 0;
@@ -116,6 +231,48 @@ public class CallRFFIHelper {
             throw RInternalError.unimplemented();
         }
     }
+
+    static Object CAR(Object e) {
+        if (e instanceof RPairList) {
+            return ((RPairList) e).car();
+        } else {
+            throw RInternalError.unimplemented();
+        }
+    }
+
+    static Object CDR(Object e) {
+        if (e instanceof RPairList) {
+            return ((RPairList) e).cdr();
+        } else {
+            throw RInternalError.unimplemented();
+        }
+    }
+
+    static Object CADR(@SuppressWarnings("unused") Object x) {
+        throw RInternalError.unimplemented();
+    }
+
+    static Object SETCAR(Object x, Object y) {
+        if (x instanceof RPairList) {
+            ((RPairList) x).setCar(y);
+            return x; // TODO check or y?
+        } else {
+            throw RInternalError.unimplemented();
+        }
+    }
+
+    static Object SETCDR(Object x, Object y) {
+        if (x instanceof RPairList) {
+            ((RPairList) x).setCdr(y);
+            return x; // TODO check or y?
+        } else {
+            throw RInternalError.unimplemented();
+        }
+    }
+
     // Checkstyle: resume method name check
 
+    static Object validate(Object x) {
+        return x;
+    }
 }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIWithJNI.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIWithJNI.java
index 1685c72188..cf053bb071 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIWithJNI.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIWithJNI.java
@@ -26,6 +26,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.source.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
+import com.oracle.truffle.r.runtime.env.*;
 import com.oracle.truffle.r.runtime.ffi.*;
 import com.oracle.truffle.r.runtime.ffi.DLL.DLLException;
 import com.oracle.truffle.r.runtime.ffi.DLL.SymbolInfo;
@@ -44,6 +45,15 @@ public class CallRFFIWithJNI implements CallRFFI {
 
     private static final boolean ForceRTLDGlobal = false;
 
+    // The order must match that expected in rfficall.c
+    // @formatter:off
+    private static final Object[] INITIALIZE_VALUES = new Object[]{
+        REnvironment.emptyEnv(),
+        RNull.instance, RUnboundValue.instance, RMissing.instance,
+        RDataFactory.createSymbol("class")
+    };
+    // @formatter:on
+
     /**
      * Load the {@code librfficall} library. N.B. this library defines some non-JNI global symbols
      * that are referenced by C code in R packages. Unfortunately, {@link System#load(String)} uses
@@ -53,14 +63,14 @@ public class CallRFFIWithJNI implements CallRFFI {
      */
     @TruffleBoundary
     private static void loadLibrary() {
-        String librffiPath = BuiltinLibPath.getLibPath("rfficall");
+        String librffiPath = LibPaths.getBuiltinLibPath("rfficall");
         try {
             DLL.load(librffiPath, ForceRTLDGlobal, false);
         } catch (DLLException ex) {
             throw RError.error((SourceSection) null, ex);
         }
         System.load(librffiPath);
-        initialize(RNull.instance);
+        initialize(INITIALIZE_VALUES);
     }
 
     // @formatter:off
@@ -87,7 +97,7 @@ public class CallRFFIWithJNI implements CallRFFI {
         return null;
     }
 
-    private static native void initialize(RNull instance);
+    private static native void initialize(Object[] initialValues);
     private static native Object call(long address, Object[] args);
     private static native Object call0(long address);
     private static native Object call1(long address, Object arg1);
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java
index db5d1e3ff3..09e818401f 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java
@@ -220,7 +220,7 @@ public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, Stat
         @TruffleBoundary
         private static OSExtras createAndLoadLib() {
             try {
-                System.load(BuiltinLibPath.getLibPath("osextras"));
+                System.load(LibPaths.getBuiltinLibPath("osextras"));
                 return new OSExtraProvider();
             } catch (UnsatisfiedLinkError ex) {
                 throw RInternalError.shouldNotReachHere("osextras");
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
index 91ec85c636..61aae06c2a 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
@@ -210,7 +210,8 @@ public class RSerialize {
     @TruffleBoundary
     public static Object unserialize(RConnection conn, int frameDepth) throws IOException {
         Input instance = trace() ? new TracingInput(conn, frameDepth) : new Input(conn, frameDepth);
-        return instance.unserialize();
+        Object result = instance.unserialize();
+        return result;
     }
 
     /**
@@ -224,7 +225,8 @@ public class RSerialize {
     public static Object unserialize(byte[] data, CallHook hook, int frameDepth, String packageName) throws IOException {
         InputStream is = new PByteArrayInputStream(data);
         Input instance = trace() ? new TracingInput(is, hook, frameDepth, packageName) : new Input(is, hook, frameDepth, packageName);
-        return instance.unserialize();
+        Object result = instance.unserialize();
+        return result;
     }
 
     private static class Input extends Common {
@@ -1195,9 +1197,7 @@ public class RSerialize {
             if ((refIndex = getRefIndex(obj)) != -1) {
                 outRefIndex(refIndex);
             } else if (type == SEXPTYPE.SYMSXP) {
-                addReadRef(obj);
-                stream.writeInt(SEXPTYPE.SYMSXP.code);
-                writeCHARSXP(((RSymbol) obj).getName());
+                writeSymbol((RSymbol) obj);
             } else if (type == SEXPTYPE.ENVSXP) {
                 REnvironment env = (REnvironment) obj;
                 addReadRef(obj);
@@ -1476,11 +1476,16 @@ public class RSerialize {
 
         private void writePairListEntry(String name, Object value) throws IOException {
             stream.writeInt(Flags.packFlags(SEXPTYPE.LISTSXP, 0, false, false, true));
-            stream.writeInt(SEXPTYPE.SYMSXP.code);
-            writeCHARSXP(name);
+            writeSymbol(RDataFactory.createSymbol(name));
             writeItem(value);
         }
 
+        private void writeSymbol(RSymbol name) throws IOException {
+            addReadRef(name);
+            stream.writeInt(SEXPTYPE.SYMSXP.code);
+            writeCHARSXP(name.getName());
+        }
+
         private void terminatePairList() throws IOException {
             stream.writeInt(Flags.packFlags(SEXPTYPE.NILVALUE_SXP, 0, false, false, false));
         }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
index a3d612a632..220e2d3b98 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
@@ -319,6 +319,10 @@ public final class RDataFactory {
         return createList(new Object[0], null, null);
     }
 
+    public static RList createList(int n) {
+        return createList(new Object[n], null, null);
+    }
+
     public static RList createList(Object[] data, int[] newDimensions, RStringVector names) {
         return traceDataCreated(new RList(data, false, newDimensions, names));
     }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java
index bb0931f993..f7d06bb413 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java
@@ -221,4 +221,10 @@ public final class RIntVector extends RVector implements RAbstractIntVector, RAc
     protected RStringVector getImplicitClassHr() {
         return getClassHierarchyHelper(implicitClassHeader, implicitClassHeaderArray, implicitClassHeaderMatrix);
     }
+
+    @Override
+    public void setElement(int i, Object value) {
+        data[i] = (int) value;
+    }
+
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
index 156ce87a31..a8fd0a1e04 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
@@ -238,4 +238,10 @@ public final class RList extends RVector implements RAbstractVector, RGPBits {
     public void setGPBits(int value) {
         gpbits = value;
     }
+
+    @Override
+    public void setElement(int i, Object value) {
+        data[i] = value;
+    }
+
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
index 3dc7b47229..69a87aff9e 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
@@ -22,8 +22,11 @@
  */
 package com.oracle.truffle.r.runtime.data;
 
+import java.util.*;
+
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute;
 import com.oracle.truffle.r.runtime.data.model.*;
 import com.oracle.truffle.r.runtime.gnur.*;
 
@@ -79,6 +82,53 @@ public class RPairList extends RAttributeStorage implements RAttributable, RAbst
         return obj == null ? "null" : obj.getClass().getSimpleName();
     }
 
+    /**
+     * Convert to a {@link RList}.
+     */
+    public RList toRList() {
+        int len = 1;
+        boolean named = false;
+        RPairList plt = this;
+        while (true) {
+            named = named | !isNullTag();
+            if (isNull(plt.cdr)) {
+                break;
+            }
+            plt = (RPairList) plt.cdr;
+            len++;
+        }
+        Object[] data = new Object[len];
+        String[] names = named ? new String[len] : null;
+        plt = this;
+        for (int i = 0; i < len; i++) {
+            data[i] = plt.car();
+            if (named) {
+                if (plt.isNullTag()) {
+                    names[i] = RRuntime.NAMES_ATTR_EMPTY_VALUE;
+                } else {
+                    names[i] = (String) plt.getTag();
+                }
+            }
+            if (i < len - 1) {
+                plt = (RPairList) plt.cdr();
+            }
+        }
+        RList result = named ? RDataFactory.createList(data, RDataFactory.createStringVector(names, RDataFactory.COMPLETE_VECTOR)) : RDataFactory.createList(data);
+        RAttributes attrs = getAttributes();
+        if (attrs != null) {
+            RAttributes resultAttrs = result.initAttributes();
+            Iterator<RAttribute> iter = attrs.iterator();
+            while (iter.hasNext()) {
+                RAttribute attr = iter.next();
+                String attrName = attr.getName();
+                if (!(attrName.equals(RRuntime.NAMES_ATTR_KEY) || attrName.equals(RRuntime.DIM_ATTR_KEY) || attrName.equals(RRuntime.DIMNAMES_ATTR_KEY))) {
+                    resultAttrs.put(attrName, attr.getValue());
+                }
+            }
+        }
+        return result;
+    }
+
     public Object car() {
         return car;
     }
diff --git a/mx.fastr/suite.py b/mx.fastr/suite.py
index 4b36b6b9d7..c1b736015f 100644
--- a/mx.fastr/suite.py
+++ b/mx.fastr/suite.py
@@ -364,6 +364,7 @@ suite = {
       "dependencies" : [
         "com.oracle.truffle.r.nodes",
         "com.oracle.truffle.r.runtime",
+        "com.oracle.truffle.r.runtime.ffi",
       ],
       "annotationProcessors" : [
           "com.oracle.truffle.dsl.processor",
-- 
GitLab