From 2357ad1c0678dc3a4af45c0faac92663d480ab75 Mon Sep 17 00:00:00 2001
From: Adam Welc <adam.welc@oracle.com>
Date: Tue, 28 Jan 2014 19:00:08 -0800
Subject: [PATCH] Cleaned up implementations of integer, double, string and
 logical casts, as well as implementations of the respective conversion
 builtins. Introduced new tests and enabled additional ones fixed by previous
 modifications.

---
 .../r/nodes/access/WriteVariableNode.java     |   2 +-
 .../r/nodes/builtin/base/AsCharacter.java     |  50 +--
 .../r/nodes/builtin/base/AsDouble.java        |  67 +--
 .../r/nodes/builtin/base/AsInteger.java       |  63 +--
 .../r/nodes/builtin/base/AsLogical.java       |  53 +--
 .../truffle/r/nodes/builtin/base/Combine.java |   8 +-
 .../truffle/r/nodes/unary/CastDoubleNode.java | 184 +++++---
 .../r/nodes/unary/CastIntegerNode.java        | 155 +++----
 .../r/nodes/unary/CastLogicalNode.java        | 113 +++--
 .../truffle/r/nodes/unary/CastStringNode.java | 114 +++--
 .../oracle/truffle/r/runtime/RRuntime.java    | 417 ++++++++++++------
 .../truffle/r/runtime/ops/na/NACheck.java     | 123 +++---
 .../truffle/r/test/ExpectedTestOutput.test    | 186 +++++++-
 .../oracle/truffle/r/test/all/AllTests.java   | 117 ++++-
 .../truffle/r/test/failing/FailingTests.java  |  60 +--
 .../r/test/simple/TestSimpleBuiltins.java     |  57 +--
 16 files changed, 1040 insertions(+), 729 deletions(-)

diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java
index 34708faa34..6e61e77231 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java
@@ -49,7 +49,7 @@ public abstract class WriteVariableNode extends RNode {
 
     // the toBeCopied parameter is meant to prevent creation of the shared/non-temp vector; this
     // needed for the implementation of the replacement forms of builtin functions as their last
-    // argument can be mutaded; for example, in "dimnames(x)<-list(1)", the assigned value list(1)
+    // argument can be mutated; for example, in "dimnames(x)<-list(1)", the assigned value list(1)
     // must become list("1"), with the latter value returned as a result of the call
     protected void writeObjectValue(@SuppressWarnings("unused") VirtualFrame virtualFrame, Frame frame, FrameSlot frameSlot, Object value, boolean toBeCopied) {
         Object newValue = value;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
index c2fea86ab7..17707ee6d3 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
@@ -35,37 +35,37 @@ import com.oracle.truffle.r.runtime.ops.na.*;
 @SuppressWarnings("unused")
 public abstract class AsCharacter extends RBuiltinNode {
 
-    private final NACheck check;
+    @Child CastStringNode castStringNode;
 
-    @Child CastStringNode castCharacterNode;
-
-    protected AsCharacter() {
-        this.check = NACheck.create();
+    private String castString(VirtualFrame frame, Object o) {
+        if (castStringNode == null) {
+            CompilerDirectives.transferToInterpreter();
+            castStringNode = adoptChild(CastStringNodeFactory.create(null, false, false, false));
+        }
+        return (String) castStringNode.executeString(frame, o);
     }
 
-    protected AsCharacter(AsCharacter other) {
-        this.check = other.check;
+    private RStringVector castStringVector(VirtualFrame frame, Object o) {
+        if (castStringNode == null) {
+            CompilerDirectives.transferToInterpreter();
+            castStringNode = adoptChild(CastStringNodeFactory.create(null, false, false, false));
+        }
+        return (RStringVector) castStringNode.executeStringVector(frame, o);
     }
 
     @Specialization
     public String doInt(VirtualFrame frame, int value) {
-        if (castCharacterNode == null) {
-            CompilerDirectives.transferToInterpreter();
-            castCharacterNode = adoptChild(CastStringNodeFactory.create(null, false, false, false));
-        }
-        return (String) castCharacterNode.executeString(frame, value);
+        return castString(frame, value);
     }
 
     @Specialization
-    public String doDouble(double value) {
-        check.enable(value);
-        return check.convertDoubleToString(value);
+    public String doDouble(VirtualFrame frame, double value) {
+        return castString(frame, value);
     }
 
     @Specialization
-    public String doLogical(byte value) {
-        check.enable(value);
-        return check.convertLogicalToString(value);
+    public String doLogical(VirtualFrame frame, byte value) {
+        return castString(frame, value);
     }
 
     @Specialization
@@ -80,16 +80,16 @@ public abstract class AsCharacter extends RBuiltinNode {
 
     @Specialization
     public RStringVector doStringVector(VirtualFrame frame, RStringVector vector) {
-        return vector;
+        return RDataFactory.createStringVector(vector.getDataCopy(), vector.isComplete());
+    }
+
+    @Specialization
+    public RStringVector doList(VirtualFrame frame, RList list) {
+        throw new UnsupportedOperationException("list type not supported for as.character - requires deparsing");
     }
 
     @Specialization
     public RStringVector doVector(VirtualFrame frame, RAbstractVector vector) {
-        if (castCharacterNode == null) {
-            CompilerDirectives.transferToInterpreter();
-            castCharacterNode = adoptChild(CastStringNodeFactory.create(null, false, false, false));
-        }
-        Object ret = castCharacterNode.executeStringVector(frame, vector);
-        return (RStringVector) ret;
+        return castStringVector(frame, vector);
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsDouble.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsDouble.java
index 467d30ef11..299a679801 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsDouble.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsDouble.java
@@ -30,16 +30,39 @@ import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.unary.*;
 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.ops.na.*;
 
 @RBuiltin({"as.double", "as.numeric"})
 @SuppressWarnings("unused")
 public abstract class AsDouble extends RBuiltinNode {
 
-    private final NACheck check = NACheck.create();
-
     @Child CastDoubleNode castDoubleNode;
 
+    private double castDouble(VirtualFrame frame, int o) {
+        if (castDoubleNode == null) {
+            CompilerDirectives.transferToInterpreter();
+            castDoubleNode = adoptChild(CastDoubleNodeFactory.create(null, false, false));
+        }
+        return (double) castDoubleNode.executeDouble(frame, o);
+    }
+
+    private double castDouble(VirtualFrame frame, double o) {
+        if (castDoubleNode == null) {
+            CompilerDirectives.transferToInterpreter();
+            castDoubleNode = adoptChild(CastDoubleNodeFactory.create(null, false, false));
+        }
+        return (double) castDoubleNode.executeDouble(frame, o);
+    }
+
+    private double castDouble(VirtualFrame frame, byte o) {
+        if (castDoubleNode == null) {
+            CompilerDirectives.transferToInterpreter();
+            castDoubleNode = adoptChild(CastDoubleNodeFactory.create(null, false, false));
+        }
+        return (double) castDoubleNode.executeDouble(frame, o);
+    }
+
     private double castDouble(VirtualFrame frame, Object o) {
         if (castDoubleNode == null) {
             CompilerDirectives.transferToInterpreter();
@@ -62,21 +85,18 @@ public abstract class AsDouble extends RBuiltinNode {
     }
 
     @Specialization(order = 10)
-    public double asDoubleInt(int value) {
-        check.enable(value);
-        return check.convertIntToDouble(value);
+    public double asDoubleInt(VirtualFrame frame, int value) {
+        return castDouble(frame, value);
     }
 
     @Specialization
-    public double asDouble(byte value) {
-        check.enable(value);
-        return check.convertLogicalToDouble(value);
+    public double asDouble(VirtualFrame frame, byte value) {
+        return castDouble(frame, value);
     }
 
     @Specialization
-    public double asDouble(RComplex value) {
-        check.enable(value);
-        return check.convertComplexToDouble(value);
+    public double asDouble(VirtualFrame frame, RComplex value) {
+        return castDouble(frame, value);
     }
 
     @Specialization
@@ -94,26 +114,6 @@ public abstract class AsDouble extends RBuiltinNode {
         return RDataFactory.createDoubleVector(vector.getDataCopy(), vector.isComplete());
     }
 
-    @Specialization
-    public RDoubleVector asDouble(VirtualFrame frame, RIntVector vector) {
-        return castDoubleVector(frame, vector);
-    }
-
-    @Specialization
-    public RDoubleVector asDouble(VirtualFrame frame, RStringVector vector) {
-        return castDoubleVector(frame, vector);
-    }
-
-    @Specialization
-    public RDoubleVector asDouble(VirtualFrame frame, RLogicalVector vector) {
-        return castDoubleVector(frame, vector);
-    }
-
-    @Specialization
-    public RDoubleVector asDouble(VirtualFrame frame, RComplexVector vector) {
-        return castDoubleVector(frame, vector);
-    }
-
     @Specialization
     public RDoubleVector asDouble(RDoubleSequence sequence) {
         return (RDoubleVector) sequence.createVector();
@@ -129,4 +129,9 @@ public abstract class AsDouble extends RBuiltinNode {
         }
         return RDataFactory.createDoubleVector(result, RDataFactory.INCOMPLETE_VECTOR);
     }
+
+    @Specialization
+    public RDoubleVector asDouble(VirtualFrame frame, RAbstractVector vector) {
+        return castDoubleVector(frame, vector);
+    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java
index 0e23f4b37a..71303a640d 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java
@@ -37,8 +37,6 @@ import com.sun.org.apache.xml.internal.utils.*;
 @SuppressWarnings("unused")
 public abstract class AsInteger extends RBuiltinNode {
 
-    private final NACheck check = NACheck.create();
-
     @Child CastIntegerNode castIntNode;
 
     private int castInt(VirtualFrame frame, Object o) {
@@ -63,35 +61,28 @@ public abstract class AsInteger extends RBuiltinNode {
     }
 
     @Specialization
-    public int asInteger(double value) {
-        check.enable(value);
-        return check.convertDoubleToInt(value);
+    public int asInteger(VirtualFrame frame, double value) {
+        return castInt(frame, value);
     }
 
     @Specialization
-    public int asInteger(byte value) {
-        return RRuntime.logical2int(value);
+    public int asInteger(VirtualFrame frame, byte value) {
+        return castInt(frame, value);
     }
 
     @Specialization
-    public int asInteger(RComplex value) {
-        check.enable(value);
-        return check.convertComplexToInt(value);
+    public int asInteger(VirtualFrame frame, RComplex value) {
+        return castInt(frame, value);
     }
 
     @Specialization
-    public int asInteger(RRaw value) {
-        // Raw values cannot be NA.
-        return (value.getValue()) & 0xFF;
+    public int asInteger(VirtualFrame frame, RRaw value) {
+        return castInt(frame, value);
     }
 
     @Specialization
-    public int asInteger(String value) {
-        try {
-            return Integer.parseInt(value);
-        } catch (NumberFormatException ex) {
-            return RRuntime.INT_NA;
-        }
+    public int asInteger(VirtualFrame frame, String value) {
+        return castInt(frame, value);
     }
 
     @Specialization
@@ -104,43 +95,13 @@ public abstract class AsInteger extends RBuiltinNode {
         return RDataFactory.createIntVector(vector.getDataCopy(), vector.isComplete());
     }
 
-    @Specialization
-    public RIntVector asInteger(VirtualFrame frame, RDoubleVector vector) {
-        return castIntVector(frame, vector);
-    }
-
-    @Specialization
-    public RIntVector asInteger(VirtualFrame frame, RStringVector vector) {
-        return castIntVector(frame, vector);
-    }
-
-    @Specialization
-    public RIntVector asInteger(VirtualFrame frame, RLogicalVector vector) {
-        return castIntVector(frame, vector);
-    }
-
-    @Specialization
-    public RIntVector asInteger(VirtualFrame frame, RComplexVector vector) {
-        return castIntVector(frame, vector);
-    }
-
-    @Specialization
-    public RIntVector asInteger(VirtualFrame frame, RRawVector vector) {
-        return castIntVector(frame, vector);
-    }
-
     @Specialization
     public RIntVector asInteger(RIntSequence sequence) {
         return (RIntVector) sequence.createVector();
     }
 
     @Specialization
-    public RIntVector asInteger(VirtualFrame frame, RDoubleSequence sequence) {
-        return castIntVector(frame, sequence);
-    }
-
-    @Specialization
-    public RIntVector asInteger(VirtualFrame frame, RList list) {
-        return castIntVector(frame, list);
+    public RIntVector asInteger(VirtualFrame frame, RAbstractVector vector) {
+        return castIntVector(frame, vector);
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsLogical.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsLogical.java
index f10c9d2afa..ca2f24cb0a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsLogical.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsLogical.java
@@ -30,14 +30,13 @@ import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.unary.*;
 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.ops.na.*;
 
 @RBuiltin("as.logical")
 @SuppressWarnings("unused")
 public abstract class AsLogical extends RBuiltinNode {
 
-    private final NACheck check = NACheck.create();
-
     @Child CastLogicalNode castLogicalNode;
 
     public abstract RLogicalVector executeRLogicalVector(VirtualFrame frame, Object o) throws UnexpectedResultException;
@@ -64,27 +63,23 @@ public abstract class AsLogical extends RBuiltinNode {
     }
 
     @Specialization(order = 10)
-    public byte asLogical(int value) {
-        check.enable(value);
-        return check.convertIntToLogical(value);
+    public byte asLogical(VirtualFrame frame, int value) {
+        return castLogical(frame, value);
     }
 
     @Specialization(order = 12)
-    public byte asLogical(double value) {
-        check.enable(value);
-        return check.convertDoubleToLogical(value);
+    public byte asLogical(VirtualFrame frame, double value) {
+        return castLogical(frame, value);
     }
 
     @Specialization(order = 14)
-    public byte asLogical(RComplex value) {
-        check.enable(value);
-        return check.convertComplexToLogical(value);
+    public byte asLogical(VirtualFrame frame, RComplex value) {
+        return castLogical(frame, value);
     }
 
     @Specialization
     public byte asLogical(VirtualFrame frame, String value) {
-        check.enable(value);
-        return check.convertStringToLogical(value);
+        return castLogical(frame, value);
     }
 
     @Specialization
@@ -98,37 +93,7 @@ public abstract class AsLogical extends RBuiltinNode {
     }
 
     @Specialization
-    public RLogicalVector asLogical(VirtualFrame frame, RIntVector vector) {
-        return castLogicalVector(frame, vector);
-    }
-
-    @Specialization
-    public RLogicalVector asLogical(VirtualFrame frame, RStringVector vector) {
-        return castLogicalVector(frame, vector);
-    }
-
-    @Specialization
-    public RLogicalVector asLogical(VirtualFrame frame, RDoubleVector vector) {
-        return castLogicalVector(frame, vector);
-    }
-
-    @Specialization
-    public RLogicalVector asLogical(VirtualFrame frame, RComplexVector vector) {
-        return castLogicalVector(frame, vector);
-    }
-
-    @Specialization
-    public RLogicalVector asLogical(VirtualFrame frame, RDoubleSequence sequence) {
-        return castLogicalVector(frame, sequence);
-    }
-
-    @Specialization
-    public RLogicalVector asLogical(VirtualFrame frame, RIntSequence sequence) {
-        return castLogicalVector(frame, sequence);
-    }
-
-    @Specialization
-    public RLogicalVector asLogical(VirtualFrame frame, RRawVector vector) {
+    public RLogicalVector asLogical(VirtualFrame frame, RAbstractVector vector) {
         return castLogicalVector(frame, vector);
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java
index a2a9973089..52a1d5c0ff 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java
@@ -66,7 +66,13 @@ public abstract class Combine extends RBuiltinNode {
             CompilerDirectives.transferToInterpreter();
             castVector = adoptChild(CastToVectorNodeFactory.create(null));
         }
-        return castVector.executeRAbstractVector(frame, value);
+        RVector resultVector = castVector.executeRAbstractVector(frame, value).materialize();
+        // need to copy if vector is shared in case the same variable is used in combine, e.g. :
+        // x <- 1:2 ; names(x) <- c("A",NA) ; c(x,test=x)
+        if (resultVector.isShared()) {
+            resultVector = resultVector.copy();
+        }
+        return resultVector;
     }
 
     @Override
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
index 3b10e9c64e..4e9e623a75 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
@@ -26,6 +26,7 @@ import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.nodes.unary.ConvertNode.*;
+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.ops.na.*;
@@ -35,6 +36,12 @@ public abstract class CastDoubleNode extends CastNode {
 
     private final NACheck naCheck = NACheck.create();
 
+    public abstract Object executeDouble(VirtualFrame frame, int o);
+
+    public abstract Object executeDouble(VirtualFrame frame, double o);
+
+    public abstract Object executeDouble(VirtualFrame frame, byte o);
+
     public abstract Object executeDouble(VirtualFrame frame, Object o);
 
     public abstract Object executeDoubleVector(VirtualFrame frame, Object o);
@@ -68,124 +75,169 @@ public abstract class CastDoubleNode extends CastNode {
     }
 
     @Specialization(order = 20)
-    public double doLogical(byte operand) {
+    public double doDouble(RComplex operand) {
         naCheck.enable(operand);
-        return naCheck.convertLogicalToDouble(operand);
+        double result = naCheck.convertComplexToDouble(operand);
+        if (operand.getImaginaryPart() != 0.0) {
+            RContext.getInstance().setEvalWarning(RError.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+        }
+        return result;
     }
 
     @Specialization(order = 30)
-    public double doString(String operand) {
+    public double doLogical(byte operand) {
         naCheck.enable(operand);
-        return naCheck.convertStringToDouble(operand);
+        return naCheck.convertLogicalToDouble(operand);
     }
 
-    @Specialization
-    public RDoubleVector doIntVector(RIntVector operand) {
-        return performAbstractIntVector(operand);
+    @Specialization(order = 40)
+    public double doString(String operand) {
+        naCheck.enable(operand);
+        double result = naCheck.convertStringToDouble(operand);
+        if (isNA(result)) {
+            RContext.getInstance().setEvalWarning(RError.NA_INTRODUCED_COERCION);
+        }
+        return result;
     }
 
     @Specialization
-    public RDoubleVector doIntVector(RIntSequence operand) {
-        return performAbstractIntVector(operand);
+    public double doRaw(RRaw operand) {
+        return RRuntime.raw2double(operand);
     }
 
-    @Specialization(order = 101, guards = "preserveDimensions")
-    public RDoubleVector doLogicalVectorDims(RLogicalVector operand) {
+    private double[] dataFromLogical(RLogicalVector operand) {
         naCheck.enable(operand);
         double[] ddata = new double[operand.getLength()];
         for (int i = 0; i < operand.getLength(); i++) {
             byte value = operand.getDataAt(i);
             ddata[i] = naCheck.convertLogicalToDouble(value);
         }
-        return RDataFactory.createDoubleVector(ddata, operand.isComplete(), operand.getDimensions());
+        return ddata;
     }
 
-    @Specialization(order = 102, guards = "preserveNames")
-    public RDoubleVector doLogicalVectorNames(RLogicalVector operand) {
+    private double[] dataFromString(RStringVector operand) {
         naCheck.enable(operand);
         double[] ddata = new double[operand.getLength()];
+        boolean warning = false;
         for (int i = 0; i < operand.getLength(); i++) {
-            byte value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertLogicalToDouble(value);
+            String value = operand.getDataAt(i);
+            ddata[i] = naCheck.convertStringToDouble(value);
+            if (RRuntime.isNA(ddata[i])) {
+                warning = true;
+            }
         }
-        return RDataFactory.createDoubleVector(ddata, operand.isComplete(), operand.getNames());
+        if (warning) {
+            RContext.getInstance().setEvalWarning(RError.NA_INTRODUCED_COERCION);
+        }
+        return ddata;
     }
 
-    @Specialization(order = 103)
-    public RDoubleVector doLogicalVector(RLogicalVector operand) {
-        naCheck.enable(operand);
+    private static double[] dataFromRaw(RRawVector operand) {
         double[] ddata = new double[operand.getLength()];
         for (int i = 0; i < operand.getLength(); i++) {
-            byte value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertLogicalToDouble(value);
+            RRaw value = operand.getDataAt(i);
+            ddata[i] = RRuntime.raw2double(value);
         }
-        return RDataFactory.createDoubleVector(ddata, operand.isComplete());
+        return ddata;
     }
 
-    @Specialization(order = 104, guards = "preserveDimensions")
-    public RDoubleVector doStringVectorDims(RStringVector operand) {
+    private double[] dataFromComplex(RComplexVector operand) {
         naCheck.enable(operand);
         double[] ddata = new double[operand.getLength()];
+        boolean warning = false;
         for (int i = 0; i < operand.getLength(); i++) {
-            String value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertStringToDouble(value);
+            RComplex value = operand.getDataAt(i);
+            ddata[i] = naCheck.convertComplexToDouble(value);
+            if (value.getImaginaryPart() != 0.0) {
+                warning = true;
+            }
+        }
+        if (warning) {
+            RContext.getInstance().setEvalWarning(RError.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
-        return RDataFactory.createDoubleVector(ddata, operand.isComplete(), operand.getDimensions());
+        return ddata;
+    }
+
+    @Specialization
+    public RDoubleVector doIntVector(RIntVector operand) {
+        return performAbstractIntVector(operand);
+    }
+
+    @Specialization
+    public RDoubleVector doIntVector(RIntSequence operand) {
+        return performAbstractIntVector(operand);
+    }
+
+    @Specialization(order = 101, guards = "preserveDimensions")
+    public RDoubleVector doLogicalVectorDims(RLogicalVector operand) {
+        double[] ddata = dataFromLogical(operand);
+        return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
+    }
+
+    @Specialization(order = 102, guards = "preserveNames")
+    public RDoubleVector doLogicalVectorNames(RLogicalVector operand) {
+        double[] ddata = dataFromLogical(operand);
+        return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getNames());
+    }
+
+    @Specialization(order = 103)
+    public RDoubleVector doLogicalVector(RLogicalVector operand) {
+        double[] ddata = dataFromLogical(operand);
+        return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA());
+    }
+
+    @Specialization(order = 104, guards = "preserveDimensions")
+    public RDoubleVector doStringVectorDims(RStringVector operand) {
+        double[] ddata = dataFromString(operand);
+        return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
     }
 
     @Specialization(order = 105, guards = "preserveNames")
     public RDoubleVector doStringVectorNames(RStringVector operand) {
-        naCheck.enable(operand);
-        double[] ddata = new double[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            String value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertStringToDouble(value);
-        }
-        return RDataFactory.createDoubleVector(ddata, operand.isComplete(), operand.getNames());
+        double[] ddata = dataFromString(operand);
+        return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getNames());
     }
 
     @Specialization(order = 106)
     public RDoubleVector doStringVector(RStringVector operand) {
-        naCheck.enable(operand);
-        double[] ddata = new double[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            String value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertStringToDouble(value);
-        }
-        return RDataFactory.createDoubleVector(ddata, operand.isComplete());
+        double[] ddata = dataFromString(operand);
+        return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA());
     }
 
     @Specialization(order = 107, guards = "preserveDimensions")
     public RDoubleVector doComplexVectorDims(RComplexVector operand) {
-        naCheck.enable(operand);
-        double[] ddata = new double[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RComplex value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertComplexToDouble(value);
-        }
-        return RDataFactory.createDoubleVector(ddata, operand.isComplete(), operand.getDimensions());
+        double[] ddata = dataFromComplex(operand);
+        return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
     }
 
     @Specialization(order = 108, guards = "preserveNames")
     public RDoubleVector doComplexVectorNames(RComplexVector operand) {
-        naCheck.enable(operand);
-        double[] ddata = new double[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RComplex value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertComplexToDouble(value);
-        }
-        return RDataFactory.createDoubleVector(ddata, operand.isComplete(), operand.getNames());
+        double[] ddata = dataFromComplex(operand);
+        return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getNames());
     }
 
     @Specialization(order = 109)
     public RDoubleVector doComplexVector(RComplexVector operand) {
-        naCheck.enable(operand);
-        double[] ddata = new double[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RComplex value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertComplexToDouble(value);
-        }
-        return RDataFactory.createDoubleVector(ddata, operand.isComplete());
+        double[] ddata = dataFromComplex(operand);
+        return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA());
+    }
+
+    @Specialization(order = 110, guards = "preserveDimensions")
+    public RDoubleVector doRawVectorDims(RRawVector vector) {
+        double[] ddata = dataFromRaw(vector);
+        return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), vector.getDimensions());
+    }
+
+    @Specialization(order = 111, guards = "preserveNames")
+    public RDoubleVector doRawVectorNames(RRawVector vector) {
+        double[] ddata = dataFromRaw(vector);
+        return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), vector.getNames());
+    }
+
+    @Specialization(order = 112)
+    public RDoubleVector doRawVector(RRawVector vector) {
+        double[] ddata = dataFromRaw(vector);
+        return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA());
     }
 
     @Specialization
@@ -212,11 +264,11 @@ public abstract class CastDoubleNode extends CastNode {
             ddata[i] = naCheck.convertIntToDouble(value);
         }
         if (preserveDimensions()) {
-            return RDataFactory.createDoubleVector(ddata, operand.isComplete(), operand.getDimensions());
+            return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
         } else if (preserveNames()) {
-            return RDataFactory.createDoubleVector(ddata, operand.isComplete(), operand.getNames());
+            return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getNames());
         } else {
-            return RDataFactory.createDoubleVector(ddata, operand.isComplete());
+            return RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA());
         }
     }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
index 578a5707be..d686e5d1dc 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
@@ -95,13 +95,21 @@ public abstract class CastIntegerNode extends CastNode {
     @Specialization
     public int doComplex(RComplex operand) {
         check.enable(operand);
-        return check.convertComplexToInt(operand);
+        int result = check.convertComplexToInt(operand);
+        if (operand.getImaginaryPart() != 0.0) {
+            RContext.getInstance().setEvalWarning(RError.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+        }
+        return result;
     }
 
     @Specialization
     public int doCharacter(String operand) {
         check.enable(operand);
-        return check.convertStringToInt(operand);
+        int result = check.convertStringToInt(operand);
+        if (isNA(result)) {
+            RContext.getInstance().setEvalWarning(RError.NA_INTRODUCED_COERCION);
+        }
+        return result;
     }
 
     @Specialization
@@ -110,105 +118,116 @@ public abstract class CastIntegerNode extends CastNode {
         return check.convertLogicalToInt(operand);
     }
 
-    @Specialization(order = 101, guards = "preserveDimensions")
-    public RIntVector doComplexVectorDims(RComplexVector vector) {
-        check.enable(vector);
-        int length = vector.getLength();
-        int[] result = new int[length];
+    @Specialization
+    public int doRaw(RRaw operand) {
+        return RRuntime.raw2int(operand);
+    }
+
+    private int[] dataFromComplex(RComplexVector operand) {
+        check.enable(operand);
+        int length = operand.getLength();
+        int[] idata = new int[length];
+        boolean warning = false;
         for (int i = 0; i < length; i++) {
-            result[i] = check.convertComplexToInt(vector.getDataAt(i), false);
+            RComplex data = operand.getDataAt(i);
+            idata[i] = check.convertComplexToInt(data, false);
+            if (data.getImaginaryPart() != 0.0) {
+                warning = true;
+            }
+        }
+        if (warning) {
+            RContext.getInstance().setEvalWarning(RError.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+        }
+        return idata;
+    }
+
+    private int[] dataFromString(RStringVector operand) {
+        check.enable(operand);
+        int[] idata = new int[operand.getLength()];
+        boolean warning = false;
+        for (int i = 0; i < operand.getLength(); i++) {
+            String value = operand.getDataAt(i);
+            idata[i] = check.convertStringToInt(value);
+            if (RRuntime.isNA(idata[i])) {
+                warning = true;
+            }
+        }
+        if (warning) {
+            RContext.getInstance().setEvalWarning(RError.NA_INTRODUCED_COERCION);
         }
-        RContext.getInstance().setEvalWarning(RError.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+        return idata;
+    }
+
+    private int[] dataFromLogical(RLogicalVector operand) {
+        check.enable(operand);
+        int[] idata = new int[operand.getLength()];
+        for (int i = 0; i < operand.getLength(); i++) {
+            byte value = operand.getDataAt(i);
+            idata[i] = check.convertLogicalToInt(value);
+        }
+        return idata;
+    }
+
+    private static int[] dataFromRaw(RRawVector operand) {
+        int[] idata = new int[operand.getLength()];
+        for (int i = 0; i < operand.getLength(); i++) {
+            RRaw value = operand.getDataAt(i);
+            idata[i] = RRuntime.raw2int(value);
+        }
+        return idata;
+    }
+
+    @Specialization(order = 101, guards = "preserveDimensions")
+    public RIntVector doComplexVectorDims(RComplexVector vector) {
+        int[] result = dataFromComplex(vector);
         return RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions());
     }
 
     @Specialization(order = 102, guards = "preserveNames")
     public RIntVector doComplexVectorNames(RComplexVector vector) {
-        check.enable(vector);
-        int length = vector.getLength();
-        int[] result = new int[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = check.convertComplexToInt(vector.getDataAt(i), false);
-        }
-        RContext.getInstance().setEvalWarning(RError.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+        int[] result = dataFromComplex(vector);
         return RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames());
     }
 
     @Specialization(order = 103)
     public RIntVector doComplexVector(RComplexVector vector) {
-        check.enable(vector);
-        int length = vector.getLength();
-        int[] result = new int[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = check.convertComplexToInt(vector.getDataAt(i), false);
-        }
-        RContext.getInstance().setEvalWarning(RError.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+        int[] result = dataFromComplex(vector);
         return RDataFactory.createIntVector(result, check.neverSeenNA());
     }
 
     @Specialization(order = 104, guards = "preserveDimensions")
     public RIntVector doStringVectorDims(RStringVector vector) {
-        check.enable(vector);
-        int length = vector.getLength();
-        int[] result = new int[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = check.convertStringToInt(vector.getDataAt(i));
-        }
+        int[] result = dataFromString(vector);
         return RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions());
     }
 
     @Specialization(order = 105, guards = "preserveNames")
     public RIntVector doStringVectorNames(RStringVector vector) {
-        check.enable(vector);
-        int length = vector.getLength();
-        int[] result = new int[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = check.convertStringToInt(vector.getDataAt(i));
-        }
+        int[] result = dataFromString(vector);
         return RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames());
     }
 
     @Specialization(order = 106)
     public RIntVector doStringVector(RStringVector vector) {
-        check.enable(vector);
-        int length = vector.getLength();
-        int[] result = new int[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = check.convertStringToInt(vector.getDataAt(i));
-        }
+        int[] result = dataFromString(vector);
         return RDataFactory.createIntVector(result, check.neverSeenNA());
     }
 
     @Specialization(order = 107, guards = "preserveDimensions")
     public RIntVector doLogicalVectorDims(RLogicalVector vector) {
-        check.enable(vector);
-        int length = vector.getLength();
-        int[] result = new int[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = check.convertLogicalToInt(vector.getDataAt(i));
-        }
+        int[] result = dataFromLogical(vector);
         return RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions());
     }
 
     @Specialization(order = 108, guards = "preserveNames")
     public RIntVector doLogicalVectorNames(RLogicalVector vector) {
-        check.enable(vector);
-        int length = vector.getLength();
-        int[] result = new int[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = check.convertLogicalToInt(vector.getDataAt(i));
-        }
+        int[] result = dataFromLogical(vector);
         return RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames());
     }
 
     @Specialization(order = 109)
     public RIntVector doLogicalVector(RLogicalVector vector) {
-        check.enable(vector);
-        int length = vector.getLength();
-        int[] result = new int[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = check.convertLogicalToInt(vector.getDataAt(i));
-        }
+        int[] result = dataFromLogical(vector);
         return RDataFactory.createIntVector(result, check.neverSeenNA());
     }
 
@@ -235,31 +254,19 @@ public abstract class CastIntegerNode extends CastNode {
 
     @Specialization(order = 113, guards = "preserveDimensions")
     public RIntVector doRawVectorDims(RRawVector vector) {
-        int length = vector.getLength();
-        int[] result = new int[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = vector.getDataAt(i).getValue();
-        }
+        int[] result = dataFromRaw(vector);
         return RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions());
     }
 
     @Specialization(order = 114, guards = "preserveNames")
     public RIntVector doRawVectorNames(RRawVector vector) {
-        int length = vector.getLength();
-        int[] result = new int[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = vector.getDataAt(i).getValue();
-        }
+        int[] result = dataFromRaw(vector);
         return RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames());
     }
 
     @Specialization(order = 115)
     public RIntVector doRawVector(RRawVector vector) {
-        int length = vector.getLength();
-        int[] result = new int[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = vector.getDataAt(i).getValue();
-        }
+        int[] result = dataFromRaw(vector);
         return RDataFactory.createIntVector(result, check.neverSeenNA());
     }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java
index eee13c37d3..772007a5dc 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java
@@ -74,6 +74,12 @@ public abstract class CastLogicalNode extends CastNode {
         return naCheck.convertIntToLogical(operand);
     }
 
+    @Specialization
+    public byte doComplex(RComplex operand) {
+        naCheck.enable(operand);
+        return naCheck.convertComplexToLogical(operand);
+    }
+
     @Specialization
     public byte doString(String operand) {
         naCheck.enable(operand);
@@ -85,6 +91,35 @@ public abstract class CastLogicalNode extends CastNode {
         return RRuntime.raw2logical(operand);
     }
 
+    private byte[] dataFromString(RStringVector operand) {
+        naCheck.enable(operand);
+        byte[] ldata = new byte[operand.getLength()];
+        for (int i = 0; i < operand.getLength(); i++) {
+            String value = operand.getDataAt(i);
+            ldata[i] = naCheck.convertStringToLogical(value);
+        }
+        return ldata;
+    }
+
+    private byte[] dataFromComplex(RComplexVector operand) {
+        naCheck.enable(operand);
+        byte[] ldata = new byte[operand.getLength()];
+        for (int i = 0; i < operand.getLength(); i++) {
+            RComplex value = operand.getDataAt(i);
+            ldata[i] = naCheck.convertComplexToLogical(value);
+        }
+        return ldata;
+    }
+
+    private static byte[] dataFromRaw(RRawVector operand) {
+        byte[] ldata = new byte[operand.getLength()];
+        for (int i = 0; i < operand.getLength(); i++) {
+            RRaw value = operand.getDataAt(i);
+            ldata[i] = RRuntime.raw2logical(value);
+        }
+        return ldata;
+    }
+
     @Specialization
     public RLogicalVector doLogicalVector(RLogicalVector operand) {
         return operand;
@@ -112,98 +147,56 @@ public abstract class CastLogicalNode extends CastNode {
 
     @Specialization(order = 101, guards = "preserveDimensions")
     public RLogicalVector doStringVectorDims(RStringVector operand) {
-        naCheck.enable(operand);
-        byte[] ddata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            String value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertStringToLogical(value);
-        }
-        return RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
+        byte[] ldata = dataFromString(operand);
+        return RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getDimensions());
     }
 
     @Specialization(order = 102, guards = "preserveNames")
     public RLogicalVector doStringVectorNames(RStringVector operand) {
-        naCheck.enable(operand);
-        byte[] ddata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            String value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertStringToLogical(value);
-        }
-        return RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getNames());
+        byte[] ldata = dataFromString(operand);
+        return RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getNames());
     }
 
     @Specialization(order = 103)
     public RLogicalVector doStringVector(RStringVector operand) {
-        naCheck.enable(operand);
-        byte[] ddata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            String value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertStringToLogical(value);
-        }
-        return RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA());
+        byte[] ldata = dataFromString(operand);
+        return RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA());
     }
 
     @Specialization(order = 104, guards = "preserveDimensions")
     public RLogicalVector doComplexVectorDims(RComplexVector operand) {
-        naCheck.enable(operand);
-        byte[] ddata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RComplex value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertComplexToLogical(value);
-        }
-        return RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
+        byte[] ldata = dataFromComplex(operand);
+        return RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getDimensions());
     }
 
     @Specialization(order = 105, guards = "preserveNames")
     public RLogicalVector doComplexVectorNames(RComplexVector operand) {
-        naCheck.enable(operand);
-        byte[] ddata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RComplex value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertComplexToLogical(value);
-        }
-        return RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getNames());
+        byte[] ldata = dataFromComplex(operand);
+        return RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getNames());
     }
 
     @Specialization(order = 106)
     public RLogicalVector doComplexVector(RComplexVector operand) {
-        naCheck.enable(operand);
-        byte[] ddata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RComplex value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertComplexToLogical(value);
-        }
-        return RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA());
+        byte[] ldata = dataFromComplex(operand);
+        return RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA());
     }
 
     @Specialization(order = 107, guards = "preserveDimensions")
     public RLogicalVector doRawVectorDims(RRawVector operand) {
-        byte[] ddata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RRaw value = operand.getDataAt(i);
-            ddata[i] = RRuntime.raw2logical(value);
-        }
-        return RDataFactory.createLogicalVector(ddata, RDataFactory.COMPLETE_VECTOR, operand.getDimensions());
+        byte[] ldata = dataFromRaw(operand);
+        return RDataFactory.createLogicalVector(ldata, RDataFactory.COMPLETE_VECTOR, operand.getDimensions());
     }
 
     @Specialization(order = 108, guards = "preserveNames")
     public RLogicalVector doRawVectorNames(RRawVector operand) {
-        byte[] ddata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RRaw value = operand.getDataAt(i);
-            ddata[i] = RRuntime.raw2logical(value);
-        }
-        return RDataFactory.createLogicalVector(ddata, RDataFactory.COMPLETE_VECTOR, operand.getNames());
+        byte[] ldata = dataFromRaw(operand);
+        return RDataFactory.createLogicalVector(ldata, RDataFactory.COMPLETE_VECTOR, operand.getNames());
     }
 
     @Specialization(order = 109)
     public RLogicalVector doRawVector(RRawVector operand) {
-        byte[] ddata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RRaw value = operand.getDataAt(i);
-            ddata[i] = RRuntime.raw2logical(value);
-        }
-        return RDataFactory.createLogicalVector(ddata, RDataFactory.COMPLETE_VECTOR);
+        byte[] ldata = dataFromRaw(operand);
+        return RDataFactory.createLogicalVector(ldata, RDataFactory.COMPLETE_VECTOR);
     }
 
     @Generic
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java
index 696366bc85..bfc7a33515 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java
@@ -35,6 +35,12 @@ public abstract class CastStringNode extends CastNode {
 
     @Child private ToString toString = adoptChild(ToStringFactory.create(new RNode[1], null));
 
+    public abstract Object executeString(VirtualFrame frame, int o);
+
+    public abstract Object executeString(VirtualFrame frame, double o);
+
+    public abstract Object executeString(VirtualFrame frame, byte o);
+
     public abstract Object executeString(VirtualFrame frame, Object o);
 
     public abstract Object executeStringVector(VirtualFrame frame, Object o);
@@ -87,6 +93,42 @@ public abstract class CastStringNode extends CastNode {
         return toString.executeString(frame, value);
     }
 
+    private String[] dataFromLogical(VirtualFrame frame, RLogicalVector operand) {
+        String[] sdata = new String[operand.getLength()];
+        for (int i = 0; i < operand.getLength(); i++) {
+            byte value = operand.getDataAt(i);
+            sdata[i] = toString.executeString(frame, value);
+        }
+        return sdata;
+    }
+
+    private String[] dataFromComplex(VirtualFrame frame, RComplexVector operand) {
+        String[] sdata = new String[operand.getLength()];
+        for (int i = 0; i < operand.getLength(); i++) {
+            RComplex value = operand.getDataAt(i);
+            sdata[i] = toString.executeString(frame, value);
+        }
+        return sdata;
+    }
+
+    private String[] dataFromRaw(VirtualFrame frame, RRawVector operand) {
+        String[] sdata = new String[operand.getLength()];
+        for (int i = 0; i < operand.getLength(); i++) {
+            RRaw value = operand.getDataAt(i);
+            sdata[i] = toString.executeString(frame, value);
+        }
+        return sdata;
+    }
+
+    private String[] dataFromList(VirtualFrame frame, RList operand) {
+        String[] sdata = new String[operand.getLength()];
+        for (int i = 0; i < operand.getLength(); i++) {
+            Object value = operand.getDataAt(i);
+            sdata[i] = toString.executeString(frame, value);
+        }
+        return sdata;
+    }
+
     @Specialization(order = 100, guards = "isZeroLength")
     public Object doEmptyVector(@SuppressWarnings("unused") RAbstractVector vector) {
         return isEmptyVectorConvertedToNull() ? RNull.instance : RDataFactory.createStringVector(0);
@@ -119,121 +161,73 @@ public abstract class CastStringNode extends CastNode {
 
     @Specialization(order = 107, guards = {"!isZeroLength", "preserveDimensions"})
     public RStringVector doLogicalVectorDims(VirtualFrame frame, RLogicalVector vector) {
-        int length = vector.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, vector.getDataAt(i));
-        }
+        String[] result = dataFromLogical(frame, vector);
         return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions());
     }
 
     @Specialization(order = 108, guards = {"!isZeroLength", "preserveNames"})
     public RStringVector doLogicalVectorNames(VirtualFrame frame, RLogicalVector vector) {
-        int length = vector.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, vector.getDataAt(i));
-        }
+        String[] result = dataFromLogical(frame, vector);
         return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames());
     }
 
     @Specialization(order = 109, guards = "!isZeroLength")
     public RStringVector doLogicalVector(VirtualFrame frame, RLogicalVector vector) {
-        int length = vector.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, vector.getDataAt(i));
-        }
+        String[] result = dataFromLogical(frame, vector);
         return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR);
     }
 
     @Specialization(order = 110, guards = {"!isZeroLength", "preserveDimensions"})
     public RStringVector doComplexVectorDims(VirtualFrame frame, RComplexVector vector) {
-        int length = vector.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, vector.getDataAt(i));
-        }
+        String[] result = dataFromComplex(frame, vector);
         return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions());
     }
 
     @Specialization(order = 111, guards = {"!isZeroLength", "preserveNames"})
     public RStringVector doComplexVectorNames(VirtualFrame frame, RComplexVector vector) {
-        int length = vector.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, vector.getDataAt(i));
-        }
+        String[] result = dataFromComplex(frame, vector);
         return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames());
     }
 
     @Specialization(order = 112, guards = "!isZeroLength")
     public RStringVector doComplexVector(VirtualFrame frame, RComplexVector vector) {
-        int length = vector.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, vector.getDataAt(i));
-        }
+        String[] result = dataFromComplex(frame, vector);
         return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR);
     }
 
     @Specialization(order = 113, guards = {"!isZeroLength", "preserveDimensions"})
     public RStringVector doRawVectorDims(VirtualFrame frame, RRawVector vector) {
-        int length = vector.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, vector.getDataAt(i));
-        }
+        String[] result = dataFromRaw(frame, vector);
         return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions());
     }
 
     @Specialization(order = 114, guards = {"!isZeroLength", "preserveNames"})
     public RStringVector doRawVectorNames(VirtualFrame frame, RRawVector vector) {
-        int length = vector.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, vector.getDataAt(i));
-        }
+        String[] result = dataFromRaw(frame, vector);
         return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames());
     }
 
     @Specialization(order = 115, guards = "!isZeroLength")
     public RStringVector doRawVector(VirtualFrame frame, RRawVector vector) {
-        int length = vector.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, vector.getDataAt(i));
-        }
+        String[] result = dataFromRaw(frame, vector);
         return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR);
     }
 
     @Specialization(order = 116, guards = {"!isZeroLength", "preserveDimensions"})
     public RStringVector doListDims(VirtualFrame frame, RList list) {
-        int length = list.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, list.getDataAt(i));
-        }
+        String[] result = dataFromList(frame, list);
         return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, list.getDimensions());
     }
 
     @Specialization(order = 117, guards = {"!isZeroLength", "preserveNames"})
     public RStringVector doListNames(VirtualFrame frame, RList list) {
-        int length = list.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, list.getDataAt(i));
-        }
+        String[] result = dataFromList(frame, list);
         return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, list.getNames());
     }
 
     @Specialization(order = 118, guards = "!isZeroLength")
     public RStringVector doList(VirtualFrame frame, RList list) {
-        int length = list.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, list.getDataAt(i));
-        }
+        String[] result = dataFromList(frame, list);
         return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR);
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
index 11e856cab2..89cce30f97 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
@@ -103,22 +103,6 @@ public class RRuntime {
         return Double.isNaN(d);
     }
 
-    public static byte asLogical(boolean b) {
-        return b ? RRuntime.LOGICAL_TRUE : RRuntime.LOGICAL_FALSE;
-    }
-
-    public static int logical2int(byte value) {
-        return isNA(value) ? RRuntime.INT_NA : (int) value;
-    }
-
-    public static double logical2double(byte value) {
-        return isNA(value) ? RRuntime.DOUBLE_NA : (double) value;
-    }
-
-    public static RComplex logical2complex(byte value) {
-        return isNA(value) ? createComplexNA() : RDataFactory.createComplex(value, 0);
-    }
-
     public static String classToString(Class<?> c) {
         if (c == RLogical.class) {
             return TYPE_LOGICAL;
@@ -137,6 +121,55 @@ public class RRuntime {
         }
     }
 
+    public static boolean isFinite(double d) {
+        return !isNAorNaN(d) && !Double.isInfinite(d);
+    }
+
+    public static boolean doubleIsInt(double d) {
+        long longValue = (long) d;
+        return longValue == d && ((int) longValue & 0xffffffff) == longValue;
+    }
+
+    public static byte asLogical(boolean b) {
+        return b ? RRuntime.LOGICAL_TRUE : RRuntime.LOGICAL_FALSE;
+    }
+
+    // conversions from logical
+
+    public static int logical2intNoCheck(byte value) {
+        return value;
+    }
+
+    public static int logical2int(byte value) {
+        return isNA(value) ? RRuntime.INT_NA : logical2intNoCheck(value);
+    }
+
+    public static double logical2doubleNoCheck(byte value) {
+        return value;
+    }
+
+    public static double logical2double(byte value) {
+        return isNA(value) ? RRuntime.DOUBLE_NA : logical2doubleNoCheck(value);
+    }
+
+    public static RComplex logical2complexNoCheck(byte value) {
+        return RDataFactory.createComplex(value, 0);
+    }
+
+    public static RComplex logical2complex(byte value) {
+        return isNA(value) ? createComplexNA() : logical2complexNoCheck(value);
+    }
+
+    public static String logicalToStringNoCheck(byte operand) {
+        return operand == RRuntime.LOGICAL_TRUE ? "TRUE" : operand == RRuntime.LOGICAL_FALSE ? "FALSE" : STRING_NA;
+    }
+
+    public static String logicalToString(byte operand) {
+        return isNA(operand) ? STRING_NA : logicalToStringNoCheck(operand);
+    }
+
+    // conversions from raw
+
     public static byte raw2logical(RRaw value) {
         return value.getValue() == 0 ? RRuntime.LOGICAL_FALSE : RRuntime.LOGICAL_TRUE;
     }
@@ -149,175 +182,189 @@ public class RRuntime {
         return int2double(value.getValue() & 0xFF);
     }
 
-    public static boolean isFinite(double d) {
-        return !isNAorNaN(d) && !Double.isInfinite(d);
+    public static RComplex raw2complex(RRaw r) {
+        return int2complex(raw2int(r));
     }
 
-    public static int string2int(String s) {
-        if (s != STRING_NA) {
-            // FIXME use R rules
-            try {
-                return Integer.decode(s);  // decode supports hex constants
-            } catch (NumberFormatException e) {
-                RContext.getInstance().getAssumptions().naIntroduced.invalidate();
-            }
+    @SlowPath
+    public static String rawToString(RRaw operand) {
+        return intToString(raw2int(operand), false);
+    }
+
+    // conversions from string
+
+    public static int string2intNoCheck(String s) {
+        // FIXME use R rules
+        try {
+            return Integer.decode(s);  // decode supports hex constants
+        } catch (NumberFormatException e) {
+            RContext.getInstance().getAssumptions().naIntroduced.invalidate();
         }
         return INT_NA;
     }
 
-    public static boolean doubleIsInt(double d) {
-        long longValue = (long) d;
-        return longValue == d && ((int) longValue & 0xffffffff) == longValue;
+    public static int string2int(String s) {
+        if (isNA(s)) {
+            return INT_NA;
+        } else {
+            return string2intNoCheck(s);
+        }
     }
 
-    public static double string2double(String v) {
-        if (v != STRING_NA) {
-            // FIXME use R rules
-            if ("Inf".equals(v)) {
-                return Double.POSITIVE_INFINITY;
-            } else if ("NaN".equals(v)) {
-                return Double.NaN;
-            }
-            try {
-                return Double.parseDouble(v);
-            } catch (NumberFormatException e) {
-                if (v.startsWith("0x")) {
-                    try {
-                        return int2double(Integer.decode(v));
-                    } catch (NumberFormatException ein) {
-                    }
+    public static double string2doubleNoCheck(String v) {
+        // FIXME use R rules
+        if ("Inf".equals(v)) {
+            return Double.POSITIVE_INFINITY;
+        } else if ("NaN".equals(v)) {
+            return Double.NaN;
+        }
+        try {
+            return Double.parseDouble(v);
+        } catch (NumberFormatException e) {
+            if (v.startsWith("0x")) {
+                try {
+                    return int2double(Integer.decode(v));
+                } catch (NumberFormatException ein) {
                 }
-                RContext.getInstance().getAssumptions().naIntroduced.invalidate();
             }
+            RContext.getInstance().getAssumptions().naIntroduced.invalidate();
         }
         return DOUBLE_NA;
     }
 
-    public static double int2double(int i) {
-        return isNA(i) ? DOUBLE_NA : i;
+    public static double string2double(String v) {
+        if (isNA(v)) {
+            return DOUBLE_NA;
+        } else {
+            return string2doubleNoCheck(v);
+        }
     }
 
-    public static int double2int(double d) {
-        return isNA(d) ? INT_NA : (int) d;
+    public static byte string2logicalNoCheck(String s) {
+        if (s.equals("TRUE") || s.equals("T")) {
+            return TRUE;
+        }
+        if (s.equals("FALSE") || s.equals("F")) {
+            return FALSE;
+        }
+        if (s.equals("True") || s.equals("true")) {
+            return TRUE;
+        }
+        if (s.equals("False") || s.equals("false")) {
+            return FALSE;
+        }
+        RContext.getInstance().getAssumptions().naIntroduced.invalidate();
+        return LOGICAL_NA;
     }
 
-    public static byte double2logical(double d) {
-        return isNA(d) ? LOGICAL_NA : d == 0.0 ? LOGICAL_FALSE : LOGICAL_TRUE;
+    public static byte string2logical(String s) {
+        return isNA(s) ? LOGICAL_NA : string2logicalNoCheck(s);
     }
 
-    public static byte int2logical(int i) {
-        return isNA(i) ? LOGICAL_NA : i == 0 ? LOGICAL_FALSE : LOGICAL_TRUE;
-    }
+    @SlowPath
+    public static RComplex string2complexNoCheck(String v) {
+        try {
+            int startIdx = 0;
+            char firstChar = v.charAt(0);
+            boolean negativeReal = firstChar == '-';
+            if (firstChar == '+' || negativeReal) {
+                startIdx++;
+            }
 
-    public static byte complex2logical(RComplex c) {
-        return isNA(c) ? LOGICAL_NA : c.getRealPart() == 0.0 && c.getImaginaryPart() == 0.0 ? LOGICAL_FALSE : LOGICAL_TRUE;
-    }
+            int plusIdx = v.indexOf("+", startIdx);
+            int minusIdx = v.indexOf("-", startIdx);
+            int iIdx = v.indexOf("i", startIdx);
+            int signIdx = getSignIdx(plusIdx, minusIdx);
+            boolean negativeImaginary = minusIdx > 0;
 
-    public static byte string2logical(String s) {
-        if (s != STRING_NA) {
-            if (s.equals("TRUE") || s.equals("T")) {
-                return TRUE;
-            }
-            if (s.equals("FALSE") || s.equals("F")) {
-                return FALSE;
-            }
-            if (s.equals("True") || s.equals("true")) {
-                return TRUE;
-            }
-            if (s.equals("False") || s.equals("false")) {
-                return FALSE;
-            }
-            RContext.getInstance().getAssumptions().naIntroduced.invalidate();
+            double realPart = Double.parseDouble(v.substring(startIdx, signIdx));
+            double imaginaryPart = Double.parseDouble(v.substring(signIdx + 1, iIdx));
+
+            return RDataFactory.createComplex(realPart * (negativeReal ? -1 : 1), imaginaryPart * (negativeImaginary ? -1 : 1));
+        } catch (NumberFormatException ex) {
+            return RRuntime.createComplexNA();
         }
-        return LOGICAL_NA;
     }
 
-    public static RComplex int2complex(int i) {
-        return isNA(i) ? createComplexNA() : RDataFactory.createComplex(i, 0);
+    @SlowPath
+    public static RComplex string2complex(String v) {
+        return isNA(v) ? RRuntime.createComplexNA() : string2complexNoCheck(v);
     }
 
-    public static RComplex double2complex(double d) {
-        return isNA(d) ? createComplexNA() : RDataFactory.createComplex(d, 0);
+    // conversions from int
+
+    public static double int2doubleNoCheck(int i) {
+        return i;
     }
 
-    public static RComplex raw2complex(RRaw r) {
-        return int2complex(raw2int(r));
+    public static double int2double(int i) {
+        return isNA(i) ? DOUBLE_NA : int2doubleNoCheck(i);
     }
 
-    @SlowPath
-    public static String toString(Object object) {
-        if (object instanceof Integer) {
-            int intValue = (int) object;
-            if (intValue == INT_NA) {
-                return STRING_NA;
-            }
-            return intValue + "L";
-        } else if (object instanceof Double) {
-            double doubleValue = (double) object;
-            if (isNA(doubleValue)) {
-                return STRING_NA;
-            }
-            return String.valueOf(doubleValue);
-        } else if (object instanceof Boolean) {
-            return object == Boolean.TRUE ? "TRUE" : "FALSE";
-        }
+    public static byte int2logicalNoCheck(int i) {
+        return i == 0 ? LOGICAL_FALSE : LOGICAL_TRUE;
+    }
 
-        return object.toString();
+    public static byte int2logical(int i) {
+        return isNA(i) ? LOGICAL_NA : int2logicalNoCheck(i);
     }
 
-    public static boolean isNA(String value) {
-        return value == STRING_NA;
+    public static RComplex int2complexNoCheck(int i) {
+        return RDataFactory.createComplex(i, 0);
     }
 
-    public static boolean isNA(byte value) {
-        return value == LOGICAL_NA;
+    public static RComplex int2complex(int i) {
+        return isNA(i) ? createComplexNA() : int2complexNoCheck(i);
     }
 
-    public static boolean isNA(int left) {
-        return left == INT_NA;
+    @SlowPath
+    public static String intToStringNoCheck(int operand, boolean appendL) {
+        return String.valueOf(operand) + (appendL ? "L" : "");
     }
 
-    public static boolean isNA(double left) {
-        return Double.doubleToRawLongBits(left) == NA_LONGBITS;
+    @SlowPath
+    public static String intToString(int operand, boolean appendL) {
+        return isNA(operand) ? STRING_NA : intToStringNoCheck(operand, appendL);
     }
 
-    public static boolean isNA(RComplex left) {
-        return isNA(left.getRealPart());
+    // conversions from double
+
+    public static int double2intNoCheck(double d) {
+        return (int) d;
     }
 
-    public static boolean isComplete(String left) {
-        return !isNA(left);
+    public static int double2int(double d) {
+        return isNA(d) ? INT_NA : double2intNoCheck(d);
     }
 
-    public static boolean isComplete(byte left) {
-        return !isNA(left);
+    public static byte double2logicalNoCheck(double d) {
+        return d == 0.0 ? LOGICAL_FALSE : LOGICAL_TRUE;
     }
 
-    public static boolean isComplete(int left) {
-        return !isNA(left);
+    public static byte double2logical(double d) {
+        return isNA(d) ? LOGICAL_NA : double2logicalNoCheck(d);
     }
 
-    public static boolean isComplete(double left) {
-        return !isNA(left);
+    public static RComplex double2complexNoCheck(double d) {
+        return RDataFactory.createComplex(d, 0);
     }
 
-    public static boolean isComplete(RComplex left) {
-        return !isNA(left);
+    public static RComplex double2complex(double d) {
+        return isNA(d) ? createComplexNA() : double2complexNoCheck(d);
     }
 
     @SlowPath
-    public static String doubleToString(double operand, int digitsBehindDot) {
-        if (RRuntime.isNA(operand)) {
-            return STRING_NA;
-        }
+    public static String doubleToStringNoCheck(double operand, int digitsBehindDot) {
         return String.format("%." + digitsBehindDot + "f", operand);
     }
 
     @SlowPath
-    public static String doubleToString(double operand) {
-        if (RRuntime.isNA(operand)) {
-            return STRING_NA;
-        }
+    public static String doubleToString(double operand, int digitsBehindDot) {
+        return isNA(operand) ? STRING_NA : doubleToStringNoCheck(operand, digitsBehindDot);
+    }
+
+    @SlowPath
+    public static String doubleToStringNoCheck(double operand) {
         if (RRuntime.doubleIsInt(operand)) {
             return String.valueOf((int) operand);
         }
@@ -346,31 +393,119 @@ public class RRuntime {
     }
 
     @SlowPath
-    public static String intToString(int operand, boolean appendL) {
-        if (RRuntime.isNA(operand)) {
-            return STRING_NA;
-        }
-        return String.valueOf(operand) + (appendL ? "L" : "");
+    public static String doubleToString(double operand) {
+        return isNA(operand) ? STRING_NA : doubleToStringNoCheck(operand);
+    }
+
+    // conversions from complex
+
+    public static byte complex2logicalNoCheck(RComplex c) {
+        return c.getRealPart() == 0.0 && c.getImaginaryPart() == 0.0 ? LOGICAL_FALSE : LOGICAL_TRUE;
+    }
+
+    public static byte complex2logical(RComplex c) {
+        return isNA(c) ? LOGICAL_NA : complex2logicalNoCheck(c);
+    }
+
+    public static int complex2intNoCheck(RComplex c) {
+        return double2intNoCheck(c.getRealPart());
+    }
+
+    public static int complex2int(RComplex c) {
+        return isNA(c) ? LOGICAL_NA : complex2intNoCheck(c);
+    }
+
+    public static double complex2doubleNoCheck(RComplex c) {
+        return double2intNoCheck(c.getRealPart());
+    }
+
+    public static double complex2double(RComplex c) {
+        return isNA(c) ? LOGICAL_NA : complex2doubleNoCheck(c);
     }
 
     @SlowPath
-    public static String complexToString(RComplex operand) {
-        if (RRuntime.isNA(operand)) {
-            return STRING_NA;
-        }
+    public static String complexToStringNoCheck(RComplex operand) {
         return doubleToString(operand.getRealPart()) + "+" + doubleToString(operand.getImaginaryPart()) + "i";
     }
 
     @SlowPath
-    public static String rawToString(RRaw operand) {
-        return intToString(raw2int(operand), false);
+    public static String complexToString(RComplex operand) {
+        return isNA(operand) ? STRING_NA : complexToStringNoCheck(operand);
     }
 
-    public static String logicalToString(byte operand) {
-        if (RRuntime.isNA(operand)) {
-            return STRING_NA;
+    private static int getSignIdx(int plusIdx, int minusIdx) throws NumberFormatException {
+        if (plusIdx < 0) {
+            if (minusIdx < 0) {
+                throw new NumberFormatException();
+            }
+            return minusIdx;
+        } else {
+            if (minusIdx < 0) {
+                return plusIdx;
+            }
+            throw new NumberFormatException();
         }
-        return operand == RRuntime.LOGICAL_TRUE ? "TRUE" : operand == RRuntime.LOGICAL_FALSE ? "FALSE" : STRING_NA;
+    }
+
+    @SlowPath
+    public static String toString(Object object) {
+        if (object instanceof Integer) {
+            int intValue = (int) object;
+            if (intValue == INT_NA) {
+                return STRING_NA;
+            }
+            return intValue + "L";
+        } else if (object instanceof Double) {
+            double doubleValue = (double) object;
+            if (isNA(doubleValue)) {
+                return STRING_NA;
+            }
+            return String.valueOf(doubleValue);
+        } else if (object instanceof Boolean) {
+            return object == Boolean.TRUE ? "TRUE" : "FALSE";
+        }
+
+        return object.toString();
+    }
+
+    public static boolean isNA(String value) {
+        return value == STRING_NA;
+    }
+
+    public static boolean isNA(byte value) {
+        return value == LOGICAL_NA;
+    }
+
+    public static boolean isNA(int left) {
+        return left == INT_NA;
+    }
+
+    public static boolean isNA(double left) {
+        return Double.doubleToRawLongBits(left) == NA_LONGBITS;
+    }
+
+    public static boolean isNA(RComplex left) {
+        return isNA(left.getRealPart());
+    }
+
+    public static boolean isComplete(String left) {
+        return !isNA(left);
+    }
+
+    public static boolean isComplete(byte left) {
+        return !isNA(left);
+    }
+
+    public static boolean isComplete(int left) {
+        return !isNA(left);
+    }
+
+    public static boolean isComplete(double left) {
+        return !isNA(left);
+    }
+
+    public static boolean isComplete(RComplex left) {
+        return !isNA(left);
     }
 
     @SlowPath
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/na/NACheck.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/na/NACheck.java
index 9539985f2d..d2bd1bd06e 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/na/NACheck.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/na/NACheck.java
@@ -180,127 +180,96 @@ public final class NACheck implements RDataCheckClosure {
         if (check(value)) {
             return RRuntime.DOUBLE_NA;
         }
-        return value;
+        return RRuntime.logical2doubleNoCheck(value);
     }
 
-    @SuppressWarnings("static-method")
     public String convertLogicalToString(byte right) {
-        return RRuntime.logicalToString(right);
+        if (check(right)) {
+            return RRuntime.STRING_NA;
+        }
+        return RRuntime.logicalToStringNoCheck(right);
     }
 
-    @SuppressWarnings("static-method")
     public String convertIntToString(int right) {
-        return RRuntime.intToString(right, false);
+        if (check(right)) {
+            return RRuntime.STRING_NA;
+        }
+        return RRuntime.intToStringNoCheck(right, false);
     }
 
     @SlowPath
-    @SuppressWarnings("static-method")
     public double convertStringToDouble(String value) {
-        if (value.startsWith("0x") || value.startsWith("0X")) {
-            try {
-                return Long.valueOf(value.substring(2), 16);
-            } catch (NumberFormatException ex) {
-                return RRuntime.DOUBLE_NA;
-            }
-        } else {
-            try {
-                return Double.parseDouble(value);
-            } catch (NumberFormatException ex) {
-                return RRuntime.DOUBLE_NA;
-            }
+        if (check(value)) {
+            return RRuntime.DOUBLE_NA;
         }
+        double result = RRuntime.string2doubleNoCheck(value);
+        check(result); // can be NA
+        return result;
     }
 
-    @SuppressWarnings("static-method")
     public RComplex convertStringToComplex(String value) {
-        try {
-            int startIdx = 0;
-            char firstChar = value.charAt(0);
-            boolean negativeReal = firstChar == '-';
-            if (firstChar == '+' || negativeReal) {
-                startIdx++;
-            }
-
-            int plusIdx = value.indexOf("+", startIdx);
-            int minusIdx = value.indexOf("-", startIdx);
-            int iIdx = value.indexOf("i", startIdx);
-            int signIdx = getSignIdx(plusIdx, minusIdx);
-            boolean negativeImaginary = minusIdx > 0;
-
-            double realPart = Double.parseDouble(value.substring(startIdx, signIdx));
-            double imaginaryPart = Double.parseDouble(value.substring(signIdx + 1, iIdx));
-
-            return RDataFactory.createComplex(realPart * (negativeReal ? -1 : 1), imaginaryPart * (negativeImaginary ? -1 : 1));
-        } catch (NumberFormatException ex) {
+        if (check(value)) {
             return RRuntime.createComplexNA();
         }
-    }
-
-    private static int getSignIdx(int plusIdx, int minusIdx) throws NumberFormatException {
-        if (plusIdx < 0) {
-            if (minusIdx < 0) {
-                throw new NumberFormatException();
-            }
-            return minusIdx;
-        } else {
-            if (minusIdx < 0) {
-                return plusIdx;
-            }
-            throw new NumberFormatException();
-        }
+        RComplex result = RRuntime.string2complexNoCheck(value);
+        check(result); // can be NA
+        return result;
     }
 
     public int convertStringToInt(String value) {
         if (check(value)) {
             return RRuntime.INT_NA;
         }
-        try {
-            return Integer.parseInt(value);
-        } catch (NumberFormatException ex) {
-            return RRuntime.INT_NA;
-        }
+        return RRuntime.string2intNoCheck(value);
     }
 
     public String convertDoubleToString(double value) {
         if (check(value)) {
-            return "NA";
+            return RRuntime.STRING_NA;
         }
-        return RRuntime.doubleToString(value);
+        return RRuntime.doubleToStringNoCheck(value);
     }
 
     public String convertComplexToString(RComplex value) {
         if (check(value)) {
-            return "NA";
+            return RRuntime.STRING_NA;
         }
-        return value.toString();
+        return RRuntime.complexToStringNoCheck(value);
     }
 
     public double convertComplexToDouble(RComplex value) {
+        return convertComplexToDouble(value, false);
+    }
+
+    public double convertComplexToDouble(RComplex value, boolean warning) {
         if (check(value)) {
             return RRuntime.DOUBLE_NA;
         }
-        // TODO Output conversion warning
-        return value.getRealPart();
+        if (warning) {
+            RContext.getInstance().setEvalWarning(RError.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+        }
+        return RRuntime.complex2doubleNoCheck(value);
     }
 
     public byte convertComplexToLogical(RComplex value) {
         if (check(value)) {
             return RRuntime.LOGICAL_NA;
         }
-        // TODO Output conversion warning
-        return ((int) value.getRealPart()) == 0 ? RRuntime.LOGICAL_FALSE : RRuntime.LOGICAL_TRUE;
+        return RRuntime.complex2logicalNoCheck(value);
     }
 
     public int convertComplexToInt(RComplex right) {
         return convertComplexToInt(right, true);
     }
 
-    @SuppressWarnings("static-method")
     public int convertComplexToInt(RComplex right, boolean warning) {
+        if (check(right)) {
+            return RRuntime.INT_NA;
+        }
         if (warning) {
             RContext.getInstance().setEvalWarning(RError.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
-        return (int) right.getRealPart();
+        return RRuntime.complex2intNoCheck(right);
     }
 
     public boolean checkNAorNaN(double value) {
@@ -325,6 +294,7 @@ public final class NACheck implements RDataCheckClosure {
                 this.conversionOverflowReached = true;
             }
             RContext.getInstance().setEvalWarning(RError.NA_INTRODUCED_COERCION);
+            check(RRuntime.INT_NA); // na encountered
             return RRuntime.INT_NA;
         }
         return result;
@@ -346,6 +316,7 @@ public final class NACheck implements RDataCheckClosure {
                         this.conversionOverflowReached = true;
                     }
                     warning = true;
+                    check(RRuntime.INT_NA); // NA encountered
                     intValue = RRuntime.INT_NA;
                 }
                 result[i] = intValue;
@@ -357,19 +328,25 @@ public final class NACheck implements RDataCheckClosure {
         return result;
     }
 
-    @SuppressWarnings("static-method")
     public byte convertIntToLogical(int value) {
-        return RRuntime.int2logical(value);
+        if (check(value)) {
+            return RRuntime.LOGICAL_NA;
+        }
+        return RRuntime.int2logicalNoCheck(value);
     }
 
-    @SuppressWarnings("static-method")
     public byte convertDoubleToLogical(double value) {
-        return RRuntime.double2logical(value);
+        if (check(value)) {
+            return RRuntime.LOGICAL_NA;
+        }
+        return RRuntime.double2logicalNoCheck(value);
     }
 
-    @SuppressWarnings("static-method")
     public byte convertStringToLogical(String value) {
-        return RRuntime.string2logical(value);
+        if (check(value)) {
+            return RRuntime.LOGICAL_NA;
+        }
+        return RRuntime.string2logicalNoCheck(value);
     }
 
 }
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 1e5f2f623f..163d22ce28 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
@@ -2279,10 +2279,6 @@ character(0)
 #{ as.character(TRUE) }
 [1] "TRUE"
 
-##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsCharacter
-#{ as.character(list(1,2,3)) }
-[1] "1" "2" "3"
-
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsComplex
 #{ as.complex("-1+5i") }
 [1] -1+5i
@@ -2315,18 +2311,66 @@ character(0)
 #{ as.double("1.27") }
 [1] 1.27
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsDouble
+#{ as.double("TRUE") }
+[1] NA
+Warning message:
+NAs introduced by coercion
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsDouble
+#{ as.double(10+2i) }
+[1] 10
+Warning message:
+imaginary parts discarded in coercion
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsDouble
 #{ as.double(1L) }
 [1] 1
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsDouble
+#{ as.double(as.raw(1)) }
+[1] 1
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsDouble
+#{ as.double(c("1","hello")) }
+[1]  1 NA
+Warning message:
+NAs introduced by coercion
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsDouble
+#{ as.double(c(3+3i, 4+4i)) }
+[1] 3 4
+Warning message:
+imaginary parts discarded in coercion
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsDouble
+#{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, "foo")<-"foo"; y<-as.double(x); attributes(y) }
+NULL
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsDouble
+#{ x<-c(a=1L, b=2L); dim(x)<-c(1,2); attr(x, "foo")<-"foo"; y<-as.double(x); attributes(y) }
+NULL
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
 #{ as.integer("1") }
 [1] 1
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
+#{ as.integer("TRUE") }
+[1] NA
+Warning message:
+NAs introduced by coercion
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
 #{ as.integer(-0/0) }
 [1] NA
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
+#{ as.integer(-10000000000) }
+[1] NA
+Warning message:
+NAs introduced by coercion
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
 #{ as.integer(0/0) }
 [1] NA
@@ -2337,12 +2381,22 @@ character(0)
 Warning message:
 imaginary parts discarded in coercion
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
+#{ as.integer(10000000000) }
+[1] NA
+Warning message:
+NAs introduced by coercion
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
 #{ as.integer(10000000000000) }
 [1] NA
 Warning message:
 NAs introduced by coercion
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
+#{ as.integer(as.raw(1)) }
+[1] 1
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
 #{ as.integer(as.raw(c(1,2,3,4))) }
 [1] 1 2 3 4
@@ -2351,6 +2405,12 @@ NAs introduced by coercion
 #{ as.integer(c("1","2")) }
 [1] 1 2
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
+#{ as.integer(c("1","hello")) }
+[1]  1 NA
+Warning message:
+NAs introduced by coercion
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
 #{ as.integer(c(1,2,3)) }
 [1] 1 2 3
@@ -2381,6 +2441,18 @@ imaginary parts discarded in coercion
 #{ as.integer(list(list(1),2,3)) }
 [1] NA  2  3
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
+#{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, "foo")<-"foo"; y<-as.integer(x); attributes(y) }
+NULL
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsInteger
+#{ x<-c(a=1L, b=2L); dim(x)<-c(1,2); attr(x, "foo")<-"foo"; y<-as.integer(x); attributes(y) }
+NULL
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsLogical
+#{ as.logical("TRUE") }
+[1] TRUE
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsLogical
 #{ as.logical("dummy") }
 [1] NA
@@ -2393,6 +2465,26 @@ imaginary parts discarded in coercion
 #{ as.logical(1) }
 [1] TRUE
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsLogical
+#{ as.logical(10+2i) }
+[1] TRUE
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsLogical
+#{ as.logical(c("1","hello")) }
+[1] NA NA
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsLogical
+#{ as.logical(c(3+3i, 4+4i)) }
+[1] TRUE TRUE
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsLogical
+#{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, "foo")<-"foo"; y<-as.logical(x); attributes(y) }
+NULL
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsLogical
+#{ x<-c(a=1L, b=2L); dim(x)<-c(1,2); attr(x, "foo")<-"foo"; y<-as.logical(x); attributes(y) }
+NULL
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testAsRaw
 #{ as.raw(1) }
 [1] 01
@@ -2907,6 +2999,21 @@ NULL
 #{ c(1, c(2,3)) }
 [1] 1 2 3
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCombine
+#{ c(1,z=list(1,b=22,3)) }
+[[1]]
+[1] 1
+
+$z1
+[1] 1
+
+$z.b
+[1] 22
+
+$z3
+[1] 3
+
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCombine
 #{ c(1.0,1L) }
 [1] 1 1
@@ -3043,6 +3150,47 @@ NULL
 #{ c(TRUE, c(FALSE,FALSE)) }
 [1]  TRUE FALSE FALSE
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCombine
+#{ c(TRUE,1L,1.0,list(3,4)) }
+[[1]]
+[1] TRUE
+
+[[2]]
+[1] 1
+
+[[3]]
+[1] 1
+
+[[4]]
+[1] 3
+
+[[5]]
+[1] 4
+
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCombine
+#{ c(TRUE,1L,1.0,list(3,list(4,5))) }
+[[1]]
+[1] TRUE
+
+[[2]]
+[1] 1
+
+[[3]]
+[1] 1
+
+[[4]]
+[1] 3
+
+[[5]]
+[[5]][[1]]
+[1] 4
+
+[[5]][[2]]
+[1] 5
+
+
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCombine
 #{ c(a="bar", b="baz") }
     a     b
@@ -3063,6 +3211,21 @@ a
 a b
 1 2
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCombine
+#{ c(a=1,b=2:3,list(x=FALSE))  }
+$a
+[1] 1
+
+$b1
+[1] 2
+
+$b2
+[1] 3
+
+$x
+[1] FALSE
+
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCombine
 #{ c(a=1:2, 42) }
 a1 a2
@@ -3271,6 +3434,16 @@ a.z
 #{ c(c(TRUE,FALSE), c(FALSE,TRUE), c(FALSE,FALSE)) }
 [1]  TRUE FALSE FALSE  TRUE FALSE FALSE
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCombine
+#{ c(x=1,2) }
+x
+1 2
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCombine
+#{ c(x=1,y=2) }
+x y
+1 2
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCombine
 #{ f <- function(x,y) { c(x,y) } ; f(1,1) ; f(1, TRUE) ; f(NULL, NULL) }
 NULL
@@ -3279,6 +3452,11 @@ NULL
 #{ f <- function(x,y) { c(x,y) } ; f(1,1) ; f(1, TRUE) }
 [1] 1 1
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCombine
+#{ x <- 1:2 ; names(x) <- c("A",NA) ; c(x,test=x) }
+      A    <NA>  test.A test.NA
+      1       2       1       2
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCombine
 #{ x<-1:2; names(x)<-7:8;  z<-c(x, integer()); z }
 7 8
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java
index e91cfd611d..9b6cf461f9 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java
@@ -4089,7 +4089,7 @@ public class AllTests extends TestBase {
     }
 
     @Test
-    public void TestSimpleBuiltins_testAsCharacter_c803fc23a52fdc9950e5603f439b132f() {
+    public void TestSimpleBuiltins_testAsCharacterIgnore_c803fc23a52fdc9950e5603f439b132f() {
         assertEval("{ as.character(list(1,2,3)) }");
     }
 
@@ -4179,13 +4179,38 @@ public class AllTests extends TestBase {
     }
 
     @Test
-    public void TestSimpleBuiltins_testAsDoubleIgnore_82ae143056b783ea1c485d5aaaf8b2ef() {
-        assertEval("{ as.double(c(\"1\",\"hello\")) }");
+    public void TestSimpleBuiltins_testAsDouble_479fd1639fe2d6e0d67a0e816becabdc() {
+        assertEval("{ as.double(as.raw(1)) }");
     }
 
     @Test
-    public void TestSimpleBuiltins_testAsDoubleIgnore_6db9f2b7f030c3b545b6fb2f540cc502() {
-        assertEval("{ as.double(\"TRUE\") }");
+    public void TestSimpleBuiltins_testAsDouble_f8fef2e9f95f5b9cec473c1ae1ce5dc7() {
+        assertEval("{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.double(x); attributes(y) }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsDouble_bc1da27133d56768b192f56f13fb67a1() {
+        assertEval("{ x<-c(a=1L, b=2L); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.double(x); attributes(y) }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsDouble_82ae143056b783ea1c485d5aaaf8b2ef() {
+        assertEvalWarning("{ as.double(c(\"1\",\"hello\")) }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsDouble_6db9f2b7f030c3b545b6fb2f540cc502() {
+        assertEvalWarning("{ as.double(\"TRUE\") }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsDouble_d5d5b6abc97079dc1d2d996282a4b4a3() {
+        assertEvalWarning("{ as.double(10+2i) }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsDouble_69e00247e301060254e0797e5f04251b() {
+        assertEvalWarning("{ as.double(c(3+3i, 4+4i)) }");
     }
 
     @Test
@@ -4243,6 +4268,21 @@ public class AllTests extends TestBase {
         assertEval("{ as.integer(list(1,2,3,list())) }");
     }
 
+    @Test
+    public void TestSimpleBuiltins_testAsInteger_9e913fca8b29e8038c02e04e69e8db87() {
+        assertEval("{ as.integer(as.raw(1)) }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsInteger_4ba2c45f945b7d8bfed6f912ba52a340() {
+        assertEval("{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.integer(x); attributes(y) }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsInteger_9c882e3c87b92d65d6ad743d230ec501() {
+        assertEval("{ x<-c(a=1L, b=2L); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.integer(x); attributes(y) }");
+    }
+
     @Test
     public void TestSimpleBuiltins_testAsInteger_bdee86802f4d5a14a501cbdf208e49b7() {
         assertEvalWarning("{ as.integer(10+2i) }");
@@ -4259,13 +4299,23 @@ public class AllTests extends TestBase {
     }
 
     @Test
-    public void TestSimpleBuiltins_testAsIntegerIgnore_cd4b790d81dbb46f2e4bc1e8874e7f84() {
-        assertEval("{ as.integer(10000000000) }");
+    public void TestSimpleBuiltins_testAsInteger_cd4b790d81dbb46f2e4bc1e8874e7f84() {
+        assertEvalWarning("{ as.integer(10000000000) }");
     }
 
     @Test
-    public void TestSimpleBuiltins_testAsIntegerIgnore_10ae2ab3382a5b5a08b3c994ff8af6a4() {
-        assertEval("{ as.integer(-10000000000) }");
+    public void TestSimpleBuiltins_testAsInteger_10ae2ab3382a5b5a08b3c994ff8af6a4() {
+        assertEvalWarning("{ as.integer(-10000000000) }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsInteger_3fd0c179095e1763a074173595c24e9b() {
+        assertEvalWarning("{ as.integer(c(\"1\",\"hello\")) }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsInteger_a6edcce0ad2597fc069f850f20117738() {
+        assertEvalWarning("{ as.integer(\"TRUE\") }");
     }
 
     @Test
@@ -4283,6 +4333,36 @@ public class AllTests extends TestBase {
         assertEval("{ as.logical(\"dummy\") }");
     }
 
+    @Test
+    public void TestSimpleBuiltins_testAsLogical_9d9f6468397bd0dc22331958628d3fce() {
+        assertEval("{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.logical(x); attributes(y) }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsLogical_32deb020cd94418c900ab70fb006b75d() {
+        assertEval("{ x<-c(a=1L, b=2L); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.logical(x); attributes(y) }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsLogical_0566cd14ef0633a31e86fdfec9ee3d68() {
+        assertEval("{ as.logical(c(\"1\",\"hello\")) }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsLogical_b51b2ababbc6661feaaec2f13a052999() {
+        assertEval("{ as.logical(\"TRUE\") }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsLogical_0de6fee948230776fad55dbddab7a52f() {
+        assertEval("{ as.logical(10+2i) }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testAsLogical_23d0498579b5646b7c8ff983c9f82171() {
+        assertEval("{ as.logical(c(3+3i, 4+4i)) }");
+    }
+
     @Test
     public void TestSimpleBuiltins_testAsRaw_45e9a2f9092baa7b059e1d16b0a2dc36() {
         assertEval("{ as.raw(NULL) }");
@@ -5344,37 +5424,37 @@ public class AllTests extends TestBase {
     }
 
     @Test
-    public void TestSimpleBuiltins_testCombineBroken_9e952ef7a4db9df7944aa490c4223d4a() {
+    public void TestSimpleBuiltins_testCombine_9e952ef7a4db9df7944aa490c4223d4a() {
         assertEval("{ c(TRUE,1L,1.0,list(3,4)) }");
     }
 
     @Test
-    public void TestSimpleBuiltins_testCombineBroken_35615a7ebae2fab48bfd016636b142d0() {
+    public void TestSimpleBuiltins_testCombine_35615a7ebae2fab48bfd016636b142d0() {
         assertEval("{ c(TRUE,1L,1.0,list(3,list(4,5))) }");
     }
 
     @Test
-    public void TestSimpleBuiltins_testCombineBroken_991b4e290db12070daca4ed96a3ffc63() {
+    public void TestSimpleBuiltins_testCombine_991b4e290db12070daca4ed96a3ffc63() {
         assertEval("{ c(x=1,y=2) }");
     }
 
     @Test
-    public void TestSimpleBuiltins_testCombineBroken_500795124539a97439309c50c3a36290() {
+    public void TestSimpleBuiltins_testCombine_500795124539a97439309c50c3a36290() {
         assertEval("{ c(x=1,2) }");
     }
 
     @Test
-    public void TestSimpleBuiltins_testCombineBroken_d78532c80490f1bd045d0fbedd9b9c87() {
+    public void TestSimpleBuiltins_testCombine_d78532c80490f1bd045d0fbedd9b9c87() {
         assertEval("{ x <- 1:2 ; names(x) <- c(\"A\",NA) ; c(x,test=x) }");
     }
 
     @Test
-    public void TestSimpleBuiltins_testCombineBroken_dea889dee9bbedd803fa8a3c9437c69c() {
+    public void TestSimpleBuiltins_testCombine_dea889dee9bbedd803fa8a3c9437c69c() {
         assertEval("{ c(a=1,b=2:3,list(x=FALSE))  }");
     }
 
     @Test
-    public void TestSimpleBuiltins_testCombineBroken_3a952f6809176f161ea61dd876989666() {
+    public void TestSimpleBuiltins_testCombine_3a952f6809176f161ea61dd876989666() {
         assertEval("{ c(1,z=list(1,b=22,3)) }");
     }
 
@@ -8013,6 +8093,11 @@ public class AllTests extends TestBase {
         assertEval("{ x<-c(11, 7, 2222, 7, 33); names(x)<-1:5; print(x) }");
     }
 
+    @Test
+    public void TestSimpleBuiltins_testPrint_cb4a109b4038ad092aed2a2dce1f9da8() {
+        assertEval("{ print(list(list(list(1,2),list(3)),list(list(4),list(5,6)))) }");
+    }
+
     @Test
     public void TestSimpleBuiltins_testQr_4c61546a62c6441af95effa50e76e062() {
         assertEval(" { x <- qr(cbind(1:10,2:11), LAPACK=TRUE) ; round( qr.coef(x, 1:10), digits=5 ) }");
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java
index 94e5130a1f..94f6214b56 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java
@@ -1438,6 +1438,11 @@ public class FailingTests extends TestBase {
         assertEval("{ f<-function() { x<-2 ; sapply(1, function(i) { x }) } ; f() }");
     }
 
+    @Ignore
+    public void TestSimpleBuiltins_testAsCharacterIgnore_c803fc23a52fdc9950e5603f439b132f() {
+        assertEval("{ as.character(list(1,2,3)) }");
+    }
+
     @Ignore
     public void TestSimpleBuiltins_testAsCharacterIgnore_03efd474c6b2ac63cfa1f6d497c9cf80() {
         assertEval("{ as.character(list(c(\"hello\", \"hi\"))) }");
@@ -1478,26 +1483,6 @@ public class FailingTests extends TestBase {
         assertEval("{ as.complex(\"+.1e+2-3i\") }");
     }
 
-    @Ignore
-    public void TestSimpleBuiltins_testAsDoubleIgnore_82ae143056b783ea1c485d5aaaf8b2ef() {
-        assertEval("{ as.double(c(\"1\",\"hello\")) }");
-    }
-
-    @Ignore
-    public void TestSimpleBuiltins_testAsDoubleIgnore_6db9f2b7f030c3b545b6fb2f540cc502() {
-        assertEval("{ as.double(\"TRUE\") }");
-    }
-
-    @Ignore
-    public void TestSimpleBuiltins_testAsIntegerIgnore_cd4b790d81dbb46f2e4bc1e8874e7f84() {
-        assertEval("{ as.integer(10000000000) }");
-    }
-
-    @Ignore
-    public void TestSimpleBuiltins_testAsIntegerIgnore_10ae2ab3382a5b5a08b3c994ff8af6a4() {
-        assertEval("{ as.integer(-10000000000) }");
-    }
-
     @Ignore
     public void TestSimpleBuiltins_testAsRawIgnore_234cefc5ff95e036f3fa00ff5e0f2088() {
         assertEval("{ as.raw(1+1i) }");
@@ -1843,41 +1828,6 @@ public class FailingTests extends TestBase {
         assertEval("{ o <- outer(1:3, 1:4, \"<\") ; colSums(o) }");
     }
 
-    @Ignore
-    public void TestSimpleBuiltins_testCombineBroken_9e952ef7a4db9df7944aa490c4223d4a() {
-        assertEval("{ c(TRUE,1L,1.0,list(3,4)) }");
-    }
-
-    @Ignore
-    public void TestSimpleBuiltins_testCombineBroken_35615a7ebae2fab48bfd016636b142d0() {
-        assertEval("{ c(TRUE,1L,1.0,list(3,list(4,5))) }");
-    }
-
-    @Ignore
-    public void TestSimpleBuiltins_testCombineBroken_991b4e290db12070daca4ed96a3ffc63() {
-        assertEval("{ c(x=1,y=2) }");
-    }
-
-    @Ignore
-    public void TestSimpleBuiltins_testCombineBroken_500795124539a97439309c50c3a36290() {
-        assertEval("{ c(x=1,2) }");
-    }
-
-    @Ignore
-    public void TestSimpleBuiltins_testCombineBroken_d78532c80490f1bd045d0fbedd9b9c87() {
-        assertEval("{ x <- 1:2 ; names(x) <- c(\"A\",NA) ; c(x,test=x) }");
-    }
-
-    @Ignore
-    public void TestSimpleBuiltins_testCombineBroken_dea889dee9bbedd803fa8a3c9437c69c() {
-        assertEval("{ c(a=1,b=2:3,list(x=FALSE))  }");
-    }
-
-    @Ignore
-    public void TestSimpleBuiltins_testCombineBroken_3a952f6809176f161ea61dd876989666() {
-        assertEval("{ c(1,z=list(1,b=22,3)) }");
-    }
-
     @Ignore
     public void TestSimpleBuiltins_testCombineBroken_d365e1ffe5f8c886f6d1911c69b3af00() {
         assertEval("{ c(1i,0/0) }");
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java
index 1d2cfa5d93..f0f3731158 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java
@@ -228,6 +228,14 @@ public class TestSimpleBuiltins extends TestBase {
         assertEval("{ x<-c(1);  c(z=x, 42) }");
         assertEval("{ x<-c(y=1, 2);  c(a=x, 42) }");
 
+        assertEval("{ c(TRUE,1L,1.0,list(3,4)) }");
+        assertEval("{ c(TRUE,1L,1.0,list(3,list(4,5))) }");
+
+        assertEval("{ c(x=1,y=2) }");
+        assertEval("{ c(x=1,2) }");
+        assertEval("{ x <- 1:2 ; names(x) <- c(\"A\",NA) ; c(x,test=x) }");
+        assertEval("{ c(a=1,b=2:3,list(x=FALSE))  }");
+        assertEval("{ c(1,z=list(1,b=22,3)) }");
     }
 
     @Test
@@ -280,15 +288,6 @@ public class TestSimpleBuiltins extends TestBase {
     @Test
     @Ignore
     public void testCombineBroken() {
-        assertEval("{ c(TRUE,1L,1.0,list(3,4)) }");
-        assertEval("{ c(TRUE,1L,1.0,list(3,list(4,5))) }");
-
-        assertEval("{ c(x=1,y=2) }");
-        assertEval("{ c(x=1,2) }");
-        assertEval("{ x <- 1:2 ; names(x) <- c(\"A\",NA) ; c(x,test=x) }");
-        assertEval("{ c(a=1,b=2:3,list(x=FALSE))  }");
-        assertEval("{ c(1,z=list(1,b=22,3)) }");
-
         assertEval("{ c(1i,0/0) }"); // yes, this is done by GNU-R, note
         // inconsistency with as.complex(0/0)
     }
@@ -324,13 +323,13 @@ public class TestSimpleBuiltins extends TestBase {
         assertEval("{ as.integer(list(integer(),2,3)) }");
         assertEval("{ as.integer(list(list(1),2,3)) }");
         assertEval("{ as.integer(list(1,2,3,list())) }");
-    }
-
-    @Test
-    @Ignore
-    public void testAsIntegerIgnore() {
-        assertEval("{ as.integer(10000000000) }"); // FIXME coercion warning missing
-        assertEval("{ as.integer(-10000000000) }"); // FIXME coercion warning missing
+        assertEvalWarning("{ as.integer(10000000000) }");
+        assertEvalWarning("{ as.integer(-10000000000) }");
+        assertEvalWarning("{ as.integer(c(\"1\",\"hello\")) }");
+        assertEvalWarning("{ as.integer(\"TRUE\") }");
+        assertEval("{ as.integer(as.raw(1)) }");
+        assertEval("{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.integer(x); attributes(y) }");
+        assertEval("{ x<-c(a=1L, b=2L); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.integer(x); attributes(y) }");
     }
 
     @Test
@@ -340,12 +339,12 @@ public class TestSimpleBuiltins extends TestBase {
         assertEval("{ as.character(TRUE) }");
         assertEval("{ as.character(1:3) }");
         assertEval("{ as.character(NULL) }");
-        assertEval("{ as.character(list(1,2,3)) }");
     }
 
     @Test
     @Ignore
     public void testAsCharacterIgnore() {
+        assertEval("{ as.character(list(1,2,3)) }");
         assertEval("{ as.character(list(c(\"hello\", \"hi\"))) }");
         assertEval("{ as.character(list(list(c(\"hello\", \"hi\")))) }");
         assertEval("{ as.character(list(c(2L, 3L))) }");
@@ -356,22 +355,26 @@ public class TestSimpleBuiltins extends TestBase {
     public void testAsDouble() {
         assertEval("{ as.double(\"1.27\") }");
         assertEval("{ as.double(1L) }");
-    }
-
-    @Test
-    @Ignore
-    public void testAsDoubleIgnore() {
-        // FIXME coercion warnings missing
-        assertEval("{ as.double(c(\"1\",\"hello\")) }");
-        assertEval("{ as.double(\"TRUE\") }");
-
+        assertEval("{ as.double(as.raw(1)) }");
+        assertEvalWarning("{ as.double(c(\"1\",\"hello\")) }");
+        assertEvalWarning("{ as.double(\"TRUE\") }");
+        assertEvalWarning("{ as.double(10+2i) }");
+        assertEvalWarning("{ as.double(c(3+3i, 4+4i)) }");
+        assertEval("{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.double(x); attributes(y) }");
+        assertEval("{ x<-c(a=1L, b=2L); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.double(x); attributes(y) }");
     }
 
     @Test
     public void testAsLogical() {
         assertEval("{ as.logical(1) }");
         assertEval("{ as.logical(\"false\") }");
-        assertEval("{ as.logical(\"dummy\") }"); // no warning produced
+        assertEval("{ as.logical(\"dummy\") }"); // no warning produced (as it should be)
+        assertEval("{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.logical(x); attributes(y) }");
+        assertEval("{ x<-c(a=1L, b=2L); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.logical(x); attributes(y) }");
+        assertEval("{ as.logical(c(\"1\",\"hello\")) }");
+        assertEval("{ as.logical(\"TRUE\") }");
+        assertEval("{ as.logical(10+2i) }");
+        assertEval("{ as.logical(c(3+3i, 4+4i)) }");
     }
 
     @Test
-- 
GitLab