From 0505b69c6fa6a43b4e5df59aebebeb4c116ada32 Mon Sep 17 00:00:00 2001 From: Mick Jordan <mick.jordan@oracle.com> Date: Sun, 15 Jun 2014 10:24:57 -0700 Subject: [PATCH] eval bug fixes; printing for language is.language types; sys.source("file", globalenv()) working now" assert promise ony evaluated once RLanguage and RPromise siblings not subclasses; add RLanguageRep as parent --- .../oracle/truffle/r/nodes/RProxyNode.java | 1 + .../r/nodes/access/AccessArrayNode.java | 5 +++ .../r/nodes/builtin/RBuiltinRootNode.java | 2 +- .../r/nodes/builtin/base/EvalFunctions.java | 4 +- .../r/nodes/builtin/base/Expression.java | 19 +++++++-- .../truffle/r/nodes/builtin/base/OnExit.java | 2 +- .../nodes/builtin/base/PrettyPrinterNode.java | 40 ++++++++++++++++--- .../truffle/r/nodes/builtin/base/Quote.java | 4 +- .../truffle/r/nodes/function/PromiseNode.java | 18 ++++++--- .../truffle/r/nodes/function/RCallNode.java | 4 +- .../truffle/r/runtime/data/RLanguage.java | 12 ++---- .../truffle/r/runtime/data/RPromise.java | 6 ++- 12 files changed, 84 insertions(+), 33 deletions(-) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RProxyNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RProxyNode.java index 77e518bfc4..c480128296 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RProxyNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RProxyNode.java @@ -252,6 +252,7 @@ public abstract class RProxyNode extends RNode { return (RSymbol) proxyScalar(x); } + @Specialization public RLanguage wrap(RLanguage x) { return proxy(x); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArrayNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArrayNode.java index 47dd4ea7b7..8796155674 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArrayNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArrayNode.java @@ -1312,6 +1312,11 @@ public abstract class AccessArrayNode extends RNode { throw RError.getGenericError(getEncapsulatingSourceSection(), "data frames subset access not supported"); } + @Specialization(order = 1010) + Object access(VirtualFrame frame, RExpression expression, int recLevel, int position, RAbstractLogicalVector dropDim) { + return accessRecursive(frame, expression.getList(), position, recLevel, dropDim); + } + protected boolean outOfBounds(RList vector, @SuppressWarnings("unused") int recLevel, int position) { return position > vector.getLength(); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java index 95f1597a51..4f746cd197 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java @@ -53,7 +53,7 @@ public final class RBuiltinRootNode extends RRootNode { return rBuiltin == null || rBuiltin.nonEvalArgs().length == 0; } - public boolean evalArg(int index) { + public boolean evaluatesArg(int index) { RBuiltin rBuiltin = builtin.getRBuiltin(); if (rBuiltin == null) { return true; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java index ab281cd796..b9ba5beeb8 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java @@ -127,7 +127,7 @@ public class EvalFunctions { * evalq does not evaluate it's first argument */ controlVisibility(); - return doEvalBody(expr, envir, enclos); + return doEvalBody(RDataFactory.createLanguage(expr.getRep()), envir, enclos); } } @@ -157,7 +157,7 @@ public class EvalFunctions { * local does not evaluate it's first argument */ controlVisibility(); - return doEvalBody(expr, envir, enclos); + return doEvalBody(RDataFactory.createLanguage(expr.getRep()), envir, enclos); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java index 10c7b25f54..8454a750c3 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java @@ -38,16 +38,29 @@ public abstract class Expression extends RBuiltinNode { return PARAMETER_NAMES; } + /* + * Owing to the nonEvalArgs, all arguments are RPromise, but an expression actually consists of + * RLanguage elements so we convert, even though an RPromise is a subclass. + */ + @Specialization public Object doExpression(Object[] args) { - RList list = RDataFactory.createList(args); + RLanguage[] data = new RLanguage[args.length]; + for (int i = 0; i < args.length; i++) { + data[i] = convert((RPromise) args[i]); + } + RList list = RDataFactory.createList(data); return RDataFactory.createExpression(list); } @Specialization - public Object doExpression(RLanguage language) { - RList list = RDataFactory.createList(new Object[]{language}); + public Object doExpression(RPromise language) { + RList list = RDataFactory.createList(new Object[]{convert(language)}); return RDataFactory.createExpression(list); } + private static RLanguage convert(RPromise promise) { + return RDataFactory.createLanguage(promise.getRep()); + } + } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/OnExit.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/OnExit.java index 15de467902..14749648d7 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/OnExit.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/OnExit.java @@ -52,7 +52,7 @@ public abstract class OnExit extends RInvisibleBuiltinNode { } @Specialization - public Object onExit(@SuppressWarnings("unused") RLanguage expr, @SuppressWarnings("unused") RLanguage add) { + public Object onExit(@SuppressWarnings("unused") RPromise expr, @SuppressWarnings("unused") byte add) { controlVisibility(); RContext.getInstance().setEvalWarning("on.exit ignored"); return RNull.instance; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java index 5f05cac3ed..f854294286 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java @@ -198,8 +198,17 @@ public abstract class PrettyPrinterNode extends RNode { @Specialization(order = 80) public String prettyPrint(VirtualFrame frame, RExpression expr, Object listElementName) { - // TODO extract source of the elements - return "expression"; + StringBuilder builder = new StringBuilder(); + builder.append("expression("); + RList exprs = expr.getList(); + for (int i = 0; i < exprs.getLength(); i++) { + if (i != 0) { + builder.append(", "); + } + builder.append(prettyPrintLanguageRep((RLanguage) exprs.getDataAt(i), listElementName)); + } + builder.append(')'); + return builderToString(builder); } @Specialization(order = 85) @@ -208,9 +217,19 @@ public abstract class PrettyPrinterNode extends RNode { } @Specialization(order = 86) - public String prettyPrint(VirtualFrame frame, RLanguage expr, Object listElementName) { - // TODO extract source of the element - return "language element"; + public String prettyPrintPromise(VirtualFrame frame, RPromise promise, Object listElementName) { + return prettyPrintLanguageRep(promise, listElementName); + } + + @Specialization(order = 87) + public String prettyPrintLanguage(VirtualFrame frame, RLanguage language, Object listElementName) { + return prettyPrintLanguageRep(language, listElementName); + } + + public String prettyPrintLanguageRep(RLanguageRep languageRep, Object listElementName) { + RNode node = (RNode) languageRep.getRep(); + String s = node.getSourceSection().getCode(); + return s; } private String printAttributes(VirtualFrame frame, RAbstractVector vector, RAttributes attributes) { @@ -893,6 +912,17 @@ public abstract class PrettyPrinterNode extends RNode { public String prettyPrintListElement(VirtualFrame frame, RAbstractVector operand, Object listElementName) { return prettyPrintSingleElement(frame, operand, listElementName); } + + @Specialization + public String prettyPrintListElement(VirtualFrame frame, RSymbol operand, Object listElementName) { + return prettyPrintSingleElement(frame, operand, listElementName); + } + + @Specialization + public String prettyPrintListElement(VirtualFrame frame, RLanguage operand, Object listElementName) { + return prettyPrintSingleElement(frame, operand, listElementName); + } + } @NodeChild(value = "operand", type = RNode.class) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Quote.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Quote.java index e98994c032..d4d50e99ba 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Quote.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Quote.java @@ -51,8 +51,8 @@ public abstract class Quote extends RBuiltinNode { } @Specialization - public RLanguage doQuote(RLanguage arg) { + public RLanguage doQuote(RPromise arg) { controlVisibility(); - return arg; + return RDataFactory.createLanguage(arg.getRep()); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java index d4abcf6d0e..6a6fcdc898 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java @@ -23,23 +23,29 @@ package com.oracle.truffle.r.nodes.function; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.r.nodes.*; import com.oracle.truffle.r.runtime.data.*; public final class PromiseNode extends RNode { - RPromise promise; + RLanguageRep languageRep; - private PromiseNode(RPromise promise) { - this.promise = promise; + private PromiseNode(RLanguageRep languageRep) { + this.languageRep = languageRep; } - public static PromiseNode create(RPromise promise) { - return new PromiseNode(promise); + public static PromiseNode create(SourceSection src, RLanguageRep language) { + PromiseNode pn = new PromiseNode(language); + pn.assignSourceSection(src); + return pn; } + /** + * {@link RPromise} values are assign once. + */ @Override public Object execute(VirtualFrame frame) { - return promise; + return new RPromise(languageRep.getRep()); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java index 0c45092a06..3f25f90ef5 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java @@ -293,8 +293,8 @@ public abstract class RCallNode extends RNode { } private static RNode checkPromise(RBuiltinRootNode builtinRootNode, RNode argNode, int lix) { - if (!builtinRootNode.evalArg(lix)) { - return PromiseNode.create(new RPromise(argNode)); + if (!builtinRootNode.evaluatesArg(lix)) { + return PromiseNode.create(argNode.getSourceSection(), new RLanguageRep(argNode)); } else { return argNode; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java index 5400bcbeb4..6cddc5bf77 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java @@ -23,19 +23,13 @@ package com.oracle.truffle.r.runtime.data; /** - * Denotes an (unevaluated) element of, e.g. an {@link RExpression}. The representation is not - * disclosed here, owing partly to import circularities, but it will typically be an {@code RNode} - * that captures the (unevaluated) AST for the element. + * Denotes an (unevaluated) element of, e.g. an {@link RExpression}. */ @com.oracle.truffle.api.CompilerDirectives.ValueType -public class RLanguage { - private final Object rep; +public class RLanguage extends RLanguageRep { public RLanguage(Object rep) { - this.rep = rep; + super(rep); } - public Object getRep() { - return rep; - } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java index cb8ee36813..b1244a0a25 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java @@ -23,10 +23,10 @@ package com.oracle.truffle.r.runtime.data; /** - * Denotes an R {@code promise}. It extends {@link RLanguage} with a (lazily) evaluated value. + * Denotes an R {@code promise}. It extends {@link RLanguageRep} with a (lazily) evaluated value. */ @com.oracle.truffle.api.CompilerDirectives.ValueType -public class RPromise extends RLanguage { +public class RPromise extends RLanguageRep { /** * Denotes a promise that raised an error during evaluation. */ @@ -52,6 +52,8 @@ public class RPromise extends RLanguage { } else { this.value = newValue; } + } else { + assert false : "promise already has a value"; } return this.value; } -- GitLab