diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
index 737f8b3c1547a86c4344402613d31458db012c13..98fb2f8d2753965bc23da337adaac3fe3bf3805e 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
@@ -302,12 +302,12 @@ final class REngine implements Engine {
         }
     }
 
-    public Object eval(RExpression exprs, REnvironment envir, REnvironment enclos, int depth) {
+    public Object eval(RExpression exprs, REnvironment envir, int depth) {
         Object result = RNull.instance;
         for (int i = 0; i < exprs.getLength(); i++) {
             Object obj = RASTUtils.checkForRSymbol(exprs.getDataAt(i));
             if (obj instanceof RLanguage) {
-                result = evalNode((RNode) ((RLanguage) obj).getRep(), envir, enclos, depth);
+                result = evalNode((RNode) ((RLanguage) obj).getRep(), envir, depth);
             } else {
                 result = obj;
             }
@@ -315,8 +315,8 @@ final class REngine implements Engine {
         return result;
     }
 
-    public Object eval(RLanguage expr, REnvironment envir, REnvironment enclos, int depth) {
-        return evalNode((RNode) expr.getRep(), envir, enclos, depth);
+    public Object eval(RLanguage expr, REnvironment envir, int depth) {
+        return evalNode((RNode) expr.getRep(), envir, depth);
     }
 
     public Object eval(RExpression expr, MaterializedFrame frame) {
@@ -350,11 +350,11 @@ final class REngine implements Engine {
         return func.getTarget().call(rArgs);
     }
 
-    private Object evalNode(RNode exprRep, REnvironment envir, REnvironment enclos, int depth) {
+    private Object evalNode(RNode exprRep, REnvironment envir, int depth) {
         RNode n = exprRep;
         RootCallTarget callTarget = doMakeCallTarget(n, EVAL_FUNCTION_NAME);
         RCaller call = RArguments.getCall(envir.getFrame());
-        return evalTarget(callTarget, call, envir, enclos, depth);
+        return evalTarget(callTarget, call, envir, depth);
     }
 
     /**
@@ -367,7 +367,7 @@ final class REngine implements Engine {
      * inefficient. In particular, in the case where a {@link VirtualFrame} is available, then the
      * {@code eval} methods that take such a {@link VirtualFrame} should be used in preference.
      */
-    private Object evalTarget(RootCallTarget callTarget, RCaller call, REnvironment envir, @SuppressWarnings("unused") REnvironment enclos, int depth) {
+    private Object evalTarget(RootCallTarget callTarget, RCaller call, REnvironment envir, int depth) {
         MaterializedFrame envFrame = envir.getFrame();
         // Here we create fake frame that wraps the original frame's context and has an only
         // slightly changed arguments array (function and callSrc).
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java
index 790ff3db820762373764493107fab58f06337d16..8cc1665cb385d281583cfa8569d2254f9a134ce5 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java
@@ -37,19 +37,17 @@ import com.oracle.truffle.r.runtime.nodes.*;
 
 /**
  * The {@code eval} {@code .Internal} and the {@code withVisible} {@code .Primitive}.
- *
- * TODO the {@code list} variants and the interpretation of the {@code enclos} argument.
  */
 public class EvalFunctions {
     public abstract static class EvalAdapter extends RBuiltinNode {
         @TruffleBoundary
-        protected Object doEvalBody(int depth, Object exprArg, REnvironment envir, REnvironment enclos) {
+        protected Object doEvalBody(int depth, Object exprArg, REnvironment envir) {
             Object expr = RASTUtils.checkForRSymbol(exprArg);
 
             if (expr instanceof RExpression) {
-                return RContext.getEngine().eval((RExpression) expr, envir, enclos, depth);
+                return RContext.getEngine().eval((RExpression) expr, envir, depth);
             } else if (expr instanceof RLanguage) {
-                return RContext.getEngine().eval((RLanguage) expr, envir, enclos, depth);
+                return RContext.getEngine().eval((RLanguage) expr, envir, depth);
             } else {
                 // just return value
                 return expr;
@@ -62,23 +60,45 @@ public class EvalFunctions {
 
         public abstract Object execute(VirtualFrame frame, Object expr, REnvironment envir, REnvironment enclos);
 
+        private final RAttributeProfiles attributeProfiles = RAttributeProfiles.create();
+
         @Specialization
-        protected Object doEval(VirtualFrame frame, Object expr, REnvironment envir, REnvironment enclos) {
+        protected Object doEval(VirtualFrame frame, Object expr, REnvironment envir, @SuppressWarnings("unused") REnvironment enclos) {
             controlVisibility();
-            return doEvalBody(RArguments.getDepth(frame) + 1, expr, envir, enclos);
+            return doEvalBody(RArguments.getDepth(frame) + 1, expr, envir);
         }
 
         @Specialization
         protected Object doEval(VirtualFrame frame, Object expr, @SuppressWarnings("unused") RNull envir, REnvironment enclos) {
             controlVisibility();
-            return doEvalBody(RArguments.getDepth(frame) + 1, expr, REnvironment.emptyEnv(), enclos);
+            return doEvalBody(RArguments.getDepth(frame) + 1, expr, enclos);
+        }
+
+        @Specialization
+        protected Object doEval(VirtualFrame frame, Object expr, RList list, REnvironment enclos) {
+            return doEvalBody(RArguments.getDepth(frame) + 1, expr, REnvironment.createFromList(attributeProfiles, list, enclos));
+        }
+
+        @Specialization
+        protected Object doEval(VirtualFrame frame, Object expr, RPairList list, REnvironment enclos) {
+            return doEvalBody(RArguments.getDepth(frame) + 1, expr, REnvironment.createFromList(attributeProfiles, list.toRList(), enclos));
+        }
+
+        @Specialization
+        protected Object doEval(VirtualFrame frame, Object expr, RDataFrame dataFrame, REnvironment enclos) {
+            RVector vector = dataFrame.getVector();
+            if (vector instanceof RList) {
+                return doEvalBody(RArguments.getDepth(frame) + 1, expr, REnvironment.createFromList(attributeProfiles, (RList) vector, enclos));
+            } else {
+                throw RError.nyi(this, "eval on non-list dataframe");
+            }
         }
 
         @SuppressWarnings("unused")
         @Fallback
         @TruffleBoundary
         protected Object doEval(Object expr, Object envir, Object enclos) {
-            throw RError.nyi(this, "eval arg type");
+            throw RError.error(this, RError.Message.INVALID_OR_UNIMPLEMENTED_ARGUMENTS);
         }
     }
 
@@ -89,8 +109,7 @@ public class EvalFunctions {
         @Specialization
         protected RList withVisible(VirtualFrame frame, RPromise expr) {
             controlVisibility();
-            Object result = doEvalBody(RArguments.getDepth(frame) + 1, RDataFactory.createLanguage((RNode) expr.getRep()), REnvironment.frameToEnvironment(frame.materialize()),
-                            REnvironment.emptyEnv());
+            Object result = doEvalBody(RArguments.getDepth(frame) + 1, RDataFactory.createLanguage((RNode) expr.getRep()), REnvironment.frameToEnvironment(frame.materialize()));
             Object[] data = new Object[]{result, RRuntime.asLogical(RContext.getInstance().isVisible())};
             // Visibility is changed by the evaluation (else this code would not work),
             // so we have to force it back on.
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java
index 29b959bdebd85b255166ce77fe660aed6074b77b..b83c11e6e09e75f6d1692bf33257d3d43d60af85 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java
@@ -128,27 +128,12 @@ public interface Engine {
     /**
      * Support for the {@code eval} {@code .Internal}.
      */
-    Object eval(RExpression expr, REnvironment envir, REnvironment enclos, int depth);
+    Object eval(RExpression expr, REnvironment envir, int depth);
 
     /**
-     * Convenience method for common case.
+     * Variant of {@link #eval(RExpression, REnvironment, int)} for a single language element.
      */
-    default Object eval(RExpression expr, REnvironment envir, int depth) {
-        return eval(expr, envir, null, depth);
-    }
-
-    /**
-     * Variant of {@link #eval(RExpression, REnvironment, REnvironment, int)} for a single language
-     * element.
-     */
-    Object eval(RLanguage expr, REnvironment envir, REnvironment enclos, int depth);
-
-    /**
-     * Convenience method for common case.
-     */
-    default Object eval(RLanguage expr, REnvironment envir, int depth) {
-        return eval(expr, envir, null, depth);
-    }
+    Object eval(RLanguage expr, REnvironment envir, int depth);
 
     /**
      * Evaluate {@code expr} in {@code frame}.
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index 316598fa646c1eb0922db6f1c303439e8ee6bf34..b7578a1d7e1897e255c3f779dbde3e0918f5ad99 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -17371,6 +17371,10 @@ x
 #{ g<-function(y) { f<-function(x) { x }; substitute(f(y)) } ; eval(g(42)) }
 [1] 42
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_eval.testEval
+#{ l <- list(a=1, b=2); eval(quote(a), l)}
+[1] 1
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_eval.testEval
 #{ ne <- new.env(); eval(x <- 1, ne); ls() }
 [1] "ne" "x"
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java
index 2d228ab03fe97770ab0a02e3df3e7b005f1ec889..02b466ede4ef00055977bbcd27c6cf9e5be61ac0 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java
@@ -43,5 +43,8 @@ public class TestBuiltin_eval extends TestBase {
 
         // should print two values, xx^2 and xx
         assertEval(Ignored.Unknown, "eval({ xx <- pi; xx^2}) ; xx");
+
+        // lists
+        assertEval("{ l <- list(a=1, b=2); eval(quote(a), l)}");
     }
 }