diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java
index 6a608d0284b9f13a080b26d1d164abf49fe9f871..dc3ad505ae91d6137443087c9f7a324a07fedd14 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.complexValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
 import static com.oracle.truffle.r.runtime.RDispatch.MATH_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -48,7 +48,7 @@ public abstract class Ceiling extends UnaryArithmeticBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.arg("x").mustBe(complexValue().not(), RError.Message.UNIMPLEMENTED_COMPLEX_FUN).asDoubleVector();
+        casts.arg("x").mustBe(numericValue(), RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION);
     }
 
     @Override
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java
index 41e4306860fc17cd6043184c8475c88ea6a1d3f9..5dc2785893d1cbbbab0ea56af09e4deb7102b9c5 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.complexValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
 import static com.oracle.truffle.r.runtime.RDispatch.MATH_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -48,7 +48,7 @@ public abstract class Floor extends UnaryArithmeticBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.arg("x").mustBe(complexValue().not(), RError.Message.UNIMPLEMENTED_COMPLEX_FUN).asDoubleVector();
+        casts.arg("x").mustBe(numericValue(), RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION);
     }
 
     @Override
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Max.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Max.java
index d6eeb7853e25c838c76cc6aa65bbce15db863bc9..dac7f3b6519043254b51eaf7301031457480b257 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Max.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Max.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.RDispatch.SUMMARY_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -49,7 +50,7 @@ public abstract class Max extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.firstBoolean(1);
+        casts.arg("na.rm").asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).map(toBoolean());
     }
 
     @Override
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Min.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Min.java
index 0762b506438c0c6fadfb2a8b5ff8df88533c95de..b29a667281d58fef36227aa7ca87672db093c4af 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Min.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Min.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.RDispatch.SUMMARY_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -49,7 +50,7 @@ public abstract class Min extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.firstBoolean(1);
+        casts.arg("na.rm").asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).map(toBoolean());
     }
 
     @Override
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NumericalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NumericalFunctions.java
index 9e3a9909e216cdc0abf4516cae1233641d6be7bb..e543390812c6ecd082696cbb250240082d2793d9 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NumericalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NumericalFunctions.java
@@ -22,12 +22,14 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.RDispatch.COMPLEX_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.RDispatch.MATH_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.unary.UnaryArithmeticBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
@@ -60,6 +62,11 @@ public class NumericalFunctions {
             super(RType.Integer, RError.Message.NON_NUMERIC_MATH, null);
         }
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("x").mustBe(numericValue().or(complexValue()), RError.Message.NON_NUMERIC_MATH);
+        }
+
         @Override
         public RType calculateResultType(RType argumentType) {
             switch (argumentType) {
@@ -98,6 +105,11 @@ public class NumericalFunctions {
             super(RType.Double, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, null);
         }
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("z").mustBe(numericValue().or(complexValue()), RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION);
+        }
+
         @Override
         public RType calculateResultType(RType argumentType) {
             switch (argumentType) {
@@ -136,6 +148,11 @@ public class NumericalFunctions {
             super(RType.Double, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, null);
         }
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("z").mustBe(numericValue().or(complexValue()), RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION);
+        }
+
         @Override
         public RType calculateResultType(RType argumentType) {
             switch (argumentType) {
@@ -174,6 +191,11 @@ public class NumericalFunctions {
             super(RType.Double, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, null);
         }
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("z").mustBe(numericValue().or(complexValue()), RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION);
+        }
+
         @Override
         public int op(byte op) {
             return op;
@@ -202,6 +224,11 @@ public class NumericalFunctions {
             super(RType.Double, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, null);
         }
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("z").mustBe(numericValue().or(complexValue()), RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION);
+        }
+
         @Override
         public RType calculateResultType(RType argumentType) {
             switch (argumentType) {
@@ -240,6 +267,11 @@ public class NumericalFunctions {
             super(RType.Logical);
         }
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("x").mustBe(numericValue(), RError.Message.UNIMPLEMENTED_COMPLEX_FUN);
+        }
+
         @Override
         public int op(byte op) {
             return op == RRuntime.LOGICAL_TRUE ? 1 : 0;
@@ -264,6 +296,11 @@ public class NumericalFunctions {
             super(RType.Double, RError.Message.NON_NUMERIC_MATH, null);
         }
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("x").mustBe(numericValue().or(complexValue()), RError.Message.UNIMPLEMENTED_COMPLEX_FUN);
+        }
+
         @Override
         public int op(byte op) {
             return op;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrintFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrintFunctions.java
index cfb8266c0508dbce669831f572566bec85c5a3be..aa6d793bfb46142f81652a8c8b18d9607aa29d03 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrintFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrintFunctions.java
@@ -22,6 +22,18 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asIntegerVector;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asStringVector;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.chain;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.findFirst;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.gte;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lte;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.mustBe;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notIntNA;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.RVisibility.OFF;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.IO;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
@@ -36,6 +48,7 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.printer.PrintParameters;
 import com.oracle.truffle.r.nodes.builtin.base.printer.ValuePrinterNode;
 import com.oracle.truffle.r.nodes.builtin.base.printer.ValuePrinterNodeGen;
+import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.context.RContext;
@@ -57,11 +70,25 @@ public class PrintFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            super.createCasts(casts);
-            casts.firstBoolean(2);
-            casts.firstBoolean(5);
-            casts.firstBoolean(7);
-            casts.firstBoolean(8);
+            casts.arg("digits").mapIf(nullValue().not(), chain(asIntegerVector()).with(findFirst().integerElement()).with(mustBe(notIntNA(), false)).with(
+                            mustBe(gte(Format.R_MIN_DIGITS_OPT).and(lte(Format.R_MAX_DIGITS_OPT)), false)).end());
+
+            casts.arg("quote").asLogicalVector().findFirst().notNA().map(toBoolean());
+
+            casts.arg("na.print").defaultError(RError.Message.INVALID_NA_PRINT_SPEC).mapIf(nullValue().not(),
+                            chain(mustBe(stringValue(), false)).with(asStringVector()).with(findFirst().stringElement()).end());
+
+            casts.arg("print.gap").defaultError(RError.Message.GAP_MUST_BE_NON_NEGATIVE).mapIf(nullValue().not(),
+                            chain(asIntegerVector()).with(findFirst().integerElement()).with(mustBe(notIntNA(),
+                                            false)).with(mustBe(gte(0), false)).end());
+
+            casts.arg("right").defaultError(RError.Message.INVALID_ARGUMENT, "right").asLogicalVector().findFirst().notNA().map(toBoolean());
+
+            casts.arg("max").mapIf(nullValue().not(), chain(asIntegerVector()).with(findFirst().integerElement()).with(mustBe(notIntNA(), false)).with(mustBe(gte(0), false)).end());
+
+            casts.arg("useSource").defaultError(RError.Message.INVALID_ARGUMENT, "useSource").asLogicalVector().findFirst().notNA().map(toBoolean());
+
+            casts.arg("noOpt").defaultError(RError.Message.GENERIC, "invalid 'tryS4' internal argument").asLogicalVector().findFirst().notNA().map(toBoolean());
         }
 
         @TruffleBoundary
@@ -98,10 +125,17 @@ public class PrintFunctions {
 
         @Child private ValuePrinterNode valuePrinter = ValuePrinterNodeGen.create();
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("x").mustBe(instanceOf(RFunction.class));
+
+            casts.arg("useSource").defaultError(RError.Message.INVALID_ARGUMENT, "useSource").asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).map(toBoolean());
+        }
+
         @SuppressWarnings("unused")
         @Specialization
-        protected RFunction printFunction(RFunction x, byte useSource, RArgsValuesAndNames extra) {
-            valuePrinter.executeString(x, PrintParameters.getDefaultDigits(), true, RString.valueOf(RRuntime.STRING_NA), 1, false, PrintParameters.getDefaultMaxPrint(), true, false);
+        protected RFunction printFunction(RFunction x, boolean useSource, RArgsValuesAndNames extra) {
+            valuePrinter.executeString(x, PrintParameters.getDefaultDigits(), true, RString.valueOf(RRuntime.STRING_NA), 1, false, PrintParameters.getDefaultMaxPrint(), useSource, false);
             return x;
         }
     }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
index cfd6a8900fc15b8a855cbed33c03c730c569bbc2..b103d1d726f7ab40774fc81a589a8cbbb34c086d 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
@@ -274,6 +274,7 @@ public final class RError extends RuntimeException {
         NEGATIVE_EXTENTS_TO_MATRIX("negative extents to matrix"),
         INVALID_SEP("invalid 'sep' specification"),
         INVALID_LENGTH("invalid '%s' length"),
+        INVALID_NA_PRINT_SPEC("invalid 'na.print' specification"),
         EMPTY_WHAT("empty 'what' specified"),
         LINE_ELEMENTS("line %d did not have %d elements"),
         ITEMS_NOT_MULTIPLE("number of items read is not a multiple of the number of columns"),
@@ -730,7 +731,8 @@ public final class RError extends RuntimeException {
         INVALID_FILENAME_PATTERN("invalid filename pattern"),
         INVALID_FILE_EXT("invalid file extension"),
         NO("no '%s'"),
-        APPLIES_TO_VECTORS("%s applies only to vectors");
+        APPLIES_TO_VECTORS("%s applies only to vectors"),
+        GAP_MUST_BE_NON_NEGATIVE("'gap' must be non-negative integer");
 
         public final String message;
         final boolean hasArgs;