Skip to content
Snippets Groups Projects
Commit 97863d66 authored by stepan's avatar stepan
Browse files

Fix: printing attribute values with prefix

When attribute value is a list, it is printed with
prefix, which is the name of the attribute. + test case
parent 194b7104
Branches
No related tags found
No related merge requests found
......@@ -85,12 +85,18 @@ final class AttributesPrinter implements ValuePrinter<RAttributable> {
}
out.println(tag);
int origLen = printCtx.getTagBuffer().length();
printCtx.getTagBuffer().append(tag);
if (RContext.getInstance().isMethodTableDispatchOn() && utils.isS4(a.getValue())) {
S4ObjectPrinter.printS4(printCtx, a.getValue());
// throw new UnsupportedOperationException("TODO");
} else {
ValuePrinters.INSTANCE.print(a.getValue(), printCtx);
}
// restore tag buffer to its original value
printCtx.getTagBuffer().setLength(origLen);
}
}
}
......@@ -17,8 +17,6 @@ import static com.oracle.truffle.r.nodes.builtin.base.printer.Utils.snprintf;
import java.io.IOException;
import java.io.PrintWriter;
//Transcribed from GnuR, src/main/print.c
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
import com.oracle.truffle.r.runtime.RDeparse;
......@@ -38,6 +36,8 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
//Transcribed from GnuR, src/main/print.c
final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> {
static final ListPrinter INSTANCE = new ListPrinter();
......@@ -159,38 +159,9 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> {
final PrintParameters pp = printCtx.parameters();
final PrintWriter out = printCtx.output();
class TagBuf {
final int tagStartMark = buffer().length();
private StringBuilder buffer() {
StringBuilder buf = (StringBuilder) printCtx.getAttribute(ListPrinter.class.getName());
if (buf == null) {
buf = new StringBuilder();
printCtx.setAttribute(ListPrinter.class.getName(), buf);
}
return buf;
}
int taglen() {
return buffer().length();
}
void appendTag(String tag) {
buffer().append(tag);
}
void removeTag() {
buffer().delete(tagStartMark, buffer().length());
}
@Override
public String toString() {
return buffer().toString();
}
}
final TagBuf tagbuf = new TagBuf();
int taglen = tagbuf.taglen();
final StringBuffer tagbuf = printCtx.getTagBuffer();
// save the original length so that we can restore the original value
int taglen = tagbuf.length();
int ns = s.getLength();
......@@ -212,7 +183,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> {
*/
if (taglen + ss.length() > TAGBUFLEN) {
if (taglen <= TAGBUFLEN) {
tagbuf.appendTag("$...");
tagbuf.append("$...");
}
} else {
/*
......@@ -220,21 +191,21 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> {
* non-syntactic) name
*/
if (ss == RRuntime.STRING_NA) {
tagbuf.appendTag("$<NA>");
tagbuf.append("$<NA>");
} else if (RDeparse.isValidName(ss)) {
tagbuf.appendTag(String.format("$%s", ss));
tagbuf.append(String.format("$%s", ss));
} else {
tagbuf.appendTag(String.format("$`%s`", ss));
tagbuf.append(String.format("$`%s`", ss));
}
}
} else {
if (taglen + indexWidth(i) > TAGBUFLEN) {
if (taglen <= TAGBUFLEN) {
tagbuf.appendTag("$...");
tagbuf.append("$...");
}
} else {
tagbuf.appendTag(String.format("[[%d]]", i + 1));
tagbuf.append(String.format("[[%d]]", i + 1));
}
}
......@@ -246,7 +217,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> {
ValuePrinters.INSTANCE.println(si, printCtx);
}
tagbuf.removeTag();
tagbuf.setLength(taglen); // reset tag buffer to the original value
}
if (npr < ns) {
......
......@@ -33,6 +33,7 @@ final class PrintContext {
private final PrintParameters params;
private final PrettyPrintWriter out;
private final Map<String, Object> attrs = new HashMap<>();
private StringBuffer tagbuf;
private static final ThreadLocal<ArrayDeque<PrintContext>> printCtxTL = new ThreadLocal<>();
......@@ -42,6 +43,18 @@ final class PrintContext {
this.out = output;
}
/**
* TagBuffer is part of {@link PrintContext} and represents a prefix that should be printed
* before any value. This value reflects global variable {@code tagbuf} in GnuR. In FastR we can
* have more parallel buffers.
*/
public StringBuffer getTagBuffer() {
if (tagbuf == null) {
tagbuf = new StringBuffer();
}
return tagbuf;
}
public PrintParameters parameters() {
return params;
}
......
......@@ -73,5 +73,6 @@ public class TestBuiltin_print extends TestBase {
assertEval("{ y<-c(\"a\",\"b\",\"c\",\"d\");dim(y)<-c(1,2,2);print(y,quote=FALSE)}");
assertEval("{ n <- 17 ; fac <- factor(rep(1:3, length = n), levels = 1:5) ; y<-tapply(1:n, fac, sum); y }");
assertEval("{ nql <- noquote(letters); nql}");
assertEval("{ x <- 42; attr(x,'myattr') <- list(k=3); attributes(x) }");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment