diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quote.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quote.java index eeb128e52496fcb2e675abefb2d681232b98d69b..764a1ba351c8f9e6b5763a9f4100871b34ef5e04 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quote.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quote.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.function.signature.QuoteNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.Closure; import com.oracle.truffle.r.runtime.data.RMissing; @@ -37,6 +38,9 @@ import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RShareable; import com.oracle.truffle.r.runtime.data.RSymbol; +/** + * This builtin is just a fallback - this normally uses {@link QuoteNode} directly. + */ @RBuiltin(name = "quote", nonEvalArgs = 0, kind = PRIMITIVE, parameterNames = {"expr"}, behavior = PURE) public abstract class Quote extends RBuiltinNode.Arg1 { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java index 9f6f6652e1d19533b225ea5e3afe6c2943211587..1014eddf6e1e6af5fc16a37a4369a4a34b11a1cb 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java @@ -50,6 +50,7 @@ import com.oracle.truffle.r.nodes.function.RCallSpecialNode; import com.oracle.truffle.r.nodes.function.SaveArgumentsNode; import com.oracle.truffle.r.nodes.function.WrapDefaultArgumentNode; import com.oracle.truffle.r.nodes.function.signature.MissingNode; +import com.oracle.truffle.r.nodes.function.signature.QuoteNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.FastROptions; import com.oracle.truffle.r.runtime.RRuntime; @@ -142,6 +143,8 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> { return new BlockNode(source, lhsLookup, args.stream().map(n -> n.value.asRNode()).toArray(RNode[]::new)); case "missing": return new MissingNode(source, lhsLookup, createSignature(args), args.stream().map(a -> a.value).toArray(RSyntaxElement[]::new)); + case "quote": + return new QuoteNode(source, lhsLookup, createSignature(args), args.stream().map(a -> a.value).toArray(RSyntaxElement[]::new)); case ".Internal": return InternalNode.create(source, lhsLookup, createSignature(args), args.stream().map(a -> a.value).toArray(RSyntaxNode[]::new)); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/QuoteNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/QuoteNode.java new file mode 100644 index 0000000000000000000000000000000000000000..e31189acbce09dff4d85de5f6e705448f79bc4a1 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/QuoteNode.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.nodes.function.signature; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.RASTUtils; +import com.oracle.truffle.r.nodes.control.OperatorNode; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; +import com.oracle.truffle.r.runtime.ArgumentsSignature; +import com.oracle.truffle.r.runtime.RError.Message; +import com.oracle.truffle.r.runtime.data.RSymbol; +import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; +import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; + +public final class QuoteNode extends OperatorNode { + + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); + + private final ArgumentsSignature signature; + private final RSyntaxElement[] args; + + @CompilationFinal private Object value; + + public QuoteNode(SourceSection source, RSyntaxLookup operator, ArgumentsSignature signature, RSyntaxElement[] args) { + super(source, operator); + this.signature = signature; + this.args = args; + } + + @Override + public Object execute(VirtualFrame frame) { + if (value == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + if (args.length != 1) { + throw error(Message.ARGUMENTS_PASSED, args.length, "'missing'", 1); + } + String name = signature.getName(0); + if (name != null && !name.isEmpty() && !"expr".equals(name)) { + throw error(Message.ARGUMENT_NOT_MATCH, name, "expr"); + } + value = args[0] == null ? RSymbol.MISSING : RASTUtils.createLanguageElement(args[0]); + } + visibility.execute(frame, true); + return value; + } + + @Override + public ArgumentsSignature getSyntaxSignature() { + return signature; + } + + @Override + public RSyntaxElement[] getSyntaxArguments() { + return args; + } +}