From fe1cc11e13cf3cbdb49c1d2058f15bb9bd83c4ce Mon Sep 17 00:00:00 2001
From: Zbynek Slajchrt <zbynek.slajchrt@oracle.com>
Date: Tue, 23 Aug 2016 18:20:49 +0200
Subject: [PATCH] Ceiling and Floor builtins refactored

---
 .../truffle/r/nodes/builtin/base/Ceiling.java | 54 +++++++++++++----
 .../truffle/r/nodes/builtin/base/Floor.java   | 59 +++++++++++++------
 2 files changed, 84 insertions(+), 29 deletions(-)

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 1d60402d10..eb47cff189 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,6 +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.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;
@@ -29,32 +30,61 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNode;
 import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNodeGen;
+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.nodes.unary.UnaryArithmeticNode;
 import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNodeGen;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RComplex;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.ops.UnaryArithmeticFactory;
 
 @RBuiltin(name = "ceiling", kind = PRIMITIVE, parameterNames = {"x"}, dispatch = MATH_GROUP_GENERIC, behavior = PURE)
-public abstract class Ceiling extends RBuiltinNode {
+public abstract class Ceiling extends UnaryArithmeticBuiltinNode {
 
-    public static final UnaryArithmeticFactory CEILING = CeilingArithmetic::new;
+    public static final UnaryArithmeticFactory CEILING = FloorNodeGen.create(null);
 
-    @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create();
-    @Child private UnaryArithmeticNode ceiling = UnaryArithmeticNodeGen.create(CEILING, RError.Message.NON_NUMERIC_MATH, RType.Double);
+    public Ceiling() {
+        super(RType.Double, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, null);
+    }
 
-    @Specialization
-    protected Object ceiling(Object value) {
-        return ceiling.execute(boxPrimitive.execute(value));
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").mustBe(complexValue().not(), RError.Message.UNIMPLEMENTED_COMPLEX_FUN).asDoubleVector();
+    }
+
+    @Override
+    public int op(byte op) {
+        return op;
     }
 
-    private static final class CeilingArithmetic extends Round.RoundArithmetic {
+    @Override
+    public int op(int op) {
+        return op;
+    }
+
+    @Override
+    public double op(double op) {
+        return Math.ceil(op);
+    }
 
-        @Override
-        public double op(double op) {
-            return Math.ceil(op);
-        }
+    @Override
+    protected double opd(double re, double im) {
+        return op(re);
     }
+
+    @Override
+    public RComplex op(double re, double im) {
+        return RDataFactory.createComplex(op(re), op(im));
+    }
+
+    @Specialization
+    @Override
+    public Object calculateUnboxed(Object op) {
+        return super.calculateUnboxed(op);
+    }
+
 }
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 b4fe2e8b93..41e4306860 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,39 +22,64 @@
  */
 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.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.binary.BoxPrimitiveNode;
-import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNodeGen;
-import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNode;
-import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNodeGen;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
+import com.oracle.truffle.r.nodes.unary.UnaryArithmeticBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RComplex;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.ops.UnaryArithmeticFactory;
 
 @RBuiltin(name = "floor", kind = PRIMITIVE, parameterNames = {"x"}, dispatch = MATH_GROUP_GENERIC, behavior = PURE)
-public abstract class Floor extends RBuiltinNode {
+public abstract class Floor extends UnaryArithmeticBuiltinNode {
 
-    public static final UnaryArithmeticFactory FLOOR = FloorArithmetic::new;
+    public static final UnaryArithmeticFactory FLOOR = FloorNodeGen.create(null);
 
-    @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create();
-    @Child private UnaryArithmeticNode floor = UnaryArithmeticNodeGen.create(FLOOR, RError.Message.NON_NUMERIC_MATH, RType.Double);
+    public Floor() {
+        super(RType.Double, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, null);
+    }
 
-    @Specialization
-    protected Object floor(Object value) {
-        return floor.execute(boxPrimitive.execute(value));
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").mustBe(complexValue().not(), RError.Message.UNIMPLEMENTED_COMPLEX_FUN).asDoubleVector();
+    }
+
+    @Override
+    public int op(byte op) {
+        return op;
     }
 
-    private static final class FloorArithmetic extends Round.RoundArithmetic {
+    @Override
+    public int op(int op) {
+        return op;
+    }
+
+    @Override
+    public double op(double op) {
+        return Math.floor(op);
+    }
 
-        @Override
-        public double op(double op) {
-            return Math.floor(op);
-        }
+    @Override
+    protected double opd(double re, double im) {
+        return op(re);
     }
+
+    @Override
+    public RComplex op(double re, double im) {
+        return RDataFactory.createComplex(op(re), op(im));
+    }
+
+    @Specialization
+    @Override
+    public Object calculateUnboxed(Object op) {
+        return super.calculateUnboxed(op);
+    }
+
 }
-- 
GitLab