Skip to content

Commit

Permalink
Showing 3 changed files with 89 additions and 6 deletions.
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/string/modulo_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
fails:String#% formats multiple expressions
fails:String#% formats single % characters before a newline or NULL as literal %s
fails:String#% raises an error if single % appears anywhere else
fails:String#% raises an error if NULL or \n appear anywhere else in the format string
@@ -61,7 +60,6 @@ fails:String#% supports hex formats using %X for positive numbers
fails:String#% supports hex formats using %X for negative numbers
fails:String#% formats zero without prefix using %#x
fails:String#% formats zero without prefix using %#X
fails:String#% behaves as if calling Kernel#Integer for %b argument, if it does not respond to #to_ary
fails:String#% tries to convert the passed argument to an Array using #to_ary
fails:String#% behaves as if calling Kernel#Float for %e arguments, when the passed argument does not respond to #to_ary
fails:String#% behaves as if calling Kernel#Float for %e arguments, when the passed argument is hexadecimal string
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.core.format.format;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.format.FormatNode;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;

@NodeChildren({
@NodeChild(value = "spacePadding", type = FormatNode.class),
@NodeChild(value = "zeroPadding", type = FormatNode.class),
@NodeChild(value = "value", type = FormatNode.class),
})
public abstract class FormatIntegerBinaryNode extends FormatNode {

private final char format;

public FormatIntegerBinaryNode(RubyContext context, char format) {
super(context);
this.format = format;
}

@Specialization
public byte[] format(int spacePadding,
int zeroPadding,
int value) {
return getFormattedString(Integer.toBinaryString(value), spacePadding, zeroPadding, value < 0);
}

@TruffleBoundary
@Specialization(guards = "isRubyBignum(value)")
public byte[] format(int spacePadding, int zeroPadding, DynamicObject value) {
final BigInteger bigInteger = Layouts.BIGNUM.getValue(value);
return getFormattedString(bigInteger.toString(2), spacePadding, zeroPadding, bigInteger.signum() == -1);
}

@TruffleBoundary
private static byte[] getFormattedString(String formatted, int spacePadding, int zeroPadding, boolean negative) {
if (negative) {
if(formatted.contains("0")){
formatted = "..1" + formatted.substring(formatted.indexOf('0'), formatted.length());
} else {
formatted = "..1";
}
}
while (formatted.length() < spacePadding) {
formatted = " " + formatted;
}
while (formatted.length() < zeroPadding) {
formatted = "0" + formatted;
}
return formatted.getBytes(StandardCharsets.US_ASCII);
}

}
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
import org.jruby.truffle.core.format.convert.ToDoubleWithCoercionNodeGen;
import org.jruby.truffle.core.format.convert.ToIntegerNodeGen;
import org.jruby.truffle.core.format.convert.ToStringNodeGen;
import org.jruby.truffle.core.format.format.FormatIntegerBinaryNodeGen;
import org.jruby.truffle.core.format.format.FormatFloatHumanReadableNodeGen;
import org.jruby.truffle.core.format.format.FormatFloatNodeGen;
import org.jruby.truffle.core.format.format.FormatIntegerNodeGen;
@@ -155,6 +156,8 @@ public void exitFormat(PrintfParser.FormatContext ctx) {
}

break;
case 'b':
case 'B':
case 'd':
case 'i':
case 'o':
@@ -187,6 +190,10 @@ public void exitFormat(PrintfParser.FormatContext ctx) {
final char format;

switch (type) {
case 'b':
case 'B':
format = type;
break;
case 'd':
case 'i':
case 'u':
@@ -203,11 +210,19 @@ public void exitFormat(PrintfParser.FormatContext ctx) {
throw new UnsupportedOperationException();
}

node = WriteBytesNodeGen.create(context,
if(type == 'b' || type == 'B'){
node = WriteBytesNodeGen.create(context,
FormatIntegerBinaryNodeGen.create(context, format,
spacePaddingNode,
zeroPaddingNode,
ToIntegerNodeGen.create(context, valueNode)));
} else {
node = WriteBytesNodeGen.create(context,
FormatIntegerNodeGen.create(context, format,
spacePaddingNode,
zeroPaddingNode,
ToIntegerNodeGen.create(context, valueNode)));
spacePaddingNode,
zeroPaddingNode,
ToIntegerNodeGen.create(context, valueNode)));
}
break;
case 'f':
case 'e':

0 comments on commit 26066d1

Please sign in to comment.