-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Truffle] Refactor sprintf parser/builder, update format nodes
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
Brandon Fish
committed
Jul 14, 2016
1 parent
fd87e04
commit b01533b
Showing
13 changed files
with
1,158 additions
and
529 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 0 additions & 30 deletions
30
truffle/src/main/antlr4/org/jruby/truffle/core/format/printf/PrintfLexer.g4
This file was deleted.
Oops, something went wrong.
32 changes: 0 additions & 32 deletions
32
truffle/src/main/antlr4/org/jruby/truffle/core/format/printf/PrintfParser.g4
This file was deleted.
Oops, something went wrong.
85 changes: 85 additions & 0 deletions
85
truffle/src/main/java/org/jruby/truffle/core/format/format/FormatCharacterNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package org.jruby.truffle.core.format.format; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
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.frame.VirtualFrame; | ||
import org.jruby.truffle.RubyContext; | ||
import org.jruby.truffle.core.format.FormatNode; | ||
import org.jruby.truffle.core.format.LiteralFormatNode; | ||
import org.jruby.truffle.core.format.convert.ToIntegerNode; | ||
import org.jruby.truffle.core.format.convert.ToIntegerNodeGen; | ||
import org.jruby.truffle.core.format.convert.ToStringNode; | ||
import org.jruby.truffle.core.format.convert.ToStringNodeGen; | ||
import org.jruby.truffle.core.format.exceptions.NoImplicitConversionException; | ||
import org.jruby.truffle.core.format.write.bytes.WriteByteNodeGen; | ||
import org.jruby.truffle.language.control.RaiseException; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "width", type = FormatNode.class), | ||
@NodeChild(value = "value", type = FormatNode.class), | ||
}) | ||
public abstract class FormatCharacterNode extends FormatNode { | ||
|
||
private final boolean hasMinusFlag; | ||
|
||
@Child private ToIntegerNode toIntegerNode; | ||
@Child private ToStringNode toStringNode; | ||
|
||
public FormatCharacterNode(RubyContext context, boolean hasMinusFlag) { | ||
super(context); | ||
this.hasMinusFlag = hasMinusFlag; | ||
} | ||
|
||
// @TruffleBoundary | ||
@Specialization | ||
protected byte[] format(VirtualFrame frame, int width, Object value) { | ||
if (toStringNode == null) { | ||
CompilerDirectives.transferToInterpreterAndInvalidate(); | ||
toStringNode = insert(ToStringNodeGen.create(getContext(), | ||
false, | ||
"to_str", | ||
false, | ||
null, | ||
WriteByteNodeGen.create(getContext(), new LiteralFormatNode(getContext(), value)))); | ||
} | ||
Object toStrResult; | ||
try { | ||
toStrResult = toStringNode.executeToString(frame, value); | ||
} catch (NoImplicitConversionException e) { | ||
toStrResult = null; | ||
} | ||
|
||
final String charString; | ||
if (toStrResult == null || isNil(toStrResult)) { | ||
if (toIntegerNode == null) { | ||
CompilerDirectives.transferToInterpreterAndInvalidate(); | ||
toIntegerNode = insert(ToIntegerNodeGen.create(getContext(), null)); | ||
} | ||
final int charValue = (int) toIntegerNode.executeToInteger(frame, value); | ||
// TODO BJF check char length is > 0 | ||
charString = Character.toString((char) charValue); | ||
} else { | ||
final String resultString = new String((byte[]) toStrResult); | ||
final int size = resultString.length(); | ||
if (size > 1) { | ||
throw new RaiseException(getContext().getCoreExceptions().argumentError("%c requires a character", this)); | ||
} | ||
charString = resultString; | ||
} | ||
|
||
|
||
final boolean leftJustified = hasMinusFlag || width < 0; | ||
if (width < 0) { | ||
width = -width; | ||
} | ||
|
||
final String result = String.format("%" + (leftJustified ? "-" : "") + width + "." + width + "s", charString); | ||
return result.getBytes(StandardCharsets.US_ASCII); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
592 changes: 592 additions & 0 deletions
592
truffle/src/main/java/org/jruby/truffle/core/format/printf/PrintfSimpleParser.java
Large diffs are not rendered by default.
Oops, something went wrong.
197 changes: 197 additions & 0 deletions
197
truffle/src/main/java/org/jruby/truffle/core/format/printf/PrintfSimpleTreeBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
package org.jruby.truffle.core.format.printf; | ||
|
||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jcodings.specific.USASCIIEncoding; | ||
import org.jruby.truffle.RubyContext; | ||
import org.jruby.truffle.core.format.FormatNode; | ||
import org.jruby.truffle.core.format.LiteralFormatNode; | ||
import org.jruby.truffle.core.format.control.SequenceNode; | ||
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.FormatCharacterNodeGen; | ||
import org.jruby.truffle.core.format.format.FormatFloatHumanReadableNodeGen; | ||
import org.jruby.truffle.core.format.format.FormatFloatNodeGen; | ||
import org.jruby.truffle.core.format.format.FormatIntegerBinaryNodeGen; | ||
import org.jruby.truffle.core.format.format.FormatIntegerNodeGen; | ||
import org.jruby.truffle.core.format.read.SourceNode; | ||
import org.jruby.truffle.core.format.read.array.ReadArgumentIndexValueNodeGen; | ||
import org.jruby.truffle.core.format.read.array.ReadHashValueNodeGen; | ||
import org.jruby.truffle.core.format.read.array.ReadIntegerNodeGen; | ||
import org.jruby.truffle.core.format.read.array.ReadStringNodeGen; | ||
import org.jruby.truffle.core.format.read.array.ReadValueNodeGen; | ||
import org.jruby.truffle.core.format.write.bytes.WriteBytesNodeGen; | ||
import org.jruby.truffle.core.format.write.bytes.WritePaddedBytesNodeGen; | ||
import org.jruby.truffle.core.rope.CodeRange; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class PrintfSimpleTreeBuilder { | ||
|
||
|
||
private final RubyContext context; | ||
private final List<FormatNode> sequence = new ArrayList<>(); | ||
private final List<PrintfSimpleParser.SprintfConfig> configs; | ||
|
||
public static int DEFAULT = -1; | ||
|
||
private static final byte[] EMPTY_BYTES = new byte[]{}; | ||
|
||
public PrintfSimpleTreeBuilder(RubyContext context, List<PrintfSimpleParser.SprintfConfig> configs) { | ||
this.context = context; | ||
this.configs = configs; | ||
} | ||
|
||
private void buildTree() { | ||
for (PrintfSimpleParser.SprintfConfig config : configs) { | ||
final FormatNode node; | ||
if (config.isLiteral()) { | ||
node = WriteBytesNodeGen.create(context, new LiteralFormatNode(context, config.getLiteralBytes())); | ||
} else { | ||
final FormatNode valueNode; | ||
|
||
if (config.getNamesBytes() != null) { | ||
final DynamicObject key = context.getSymbolTable().getSymbol(context.getRopeTable().getRope(config.getNamesBytes(), USASCIIEncoding.INSTANCE, CodeRange.CR_7BIT)); | ||
valueNode = ReadHashValueNodeGen.create(context, key, new SourceNode()); | ||
} else if (config.getAbsoluteArgumentIndex() != null) { | ||
valueNode = ReadArgumentIndexValueNodeGen.create(context, config.getAbsoluteArgumentIndex(), new SourceNode()); | ||
} else { | ||
valueNode = ReadValueNodeGen.create(context, new SourceNode()); | ||
} | ||
|
||
final FormatNode widthNode; | ||
if (config.isWidthStar()) { | ||
widthNode = ReadIntegerNodeGen.create(context, new SourceNode()); | ||
} else if (config.isArgWidth()){ | ||
widthNode = ReadArgumentIndexValueNodeGen.create(context, config.getWidth(), new SourceNode()); | ||
} else { | ||
widthNode = new LiteralFormatNode(context, config.getWidth() == null ? -1 : config.getWidth()); | ||
} | ||
|
||
final FormatNode precisionNode; | ||
if(config.isPrecisionStar()){ | ||
precisionNode = ReadIntegerNodeGen.create(context, new SourceNode()); | ||
} else if(config.isPrecisionArg()){ | ||
precisionNode = ReadArgumentIndexValueNodeGen.create(context, config.getPrecision(), new SourceNode()); | ||
} else { | ||
precisionNode = new LiteralFormatNode(context, config.getPrecision() == null ? -1 : config.getPrecision()); | ||
} | ||
|
||
|
||
switch (config.getFormatType()){ | ||
case INTEGER: | ||
final char format; | ||
switch (config.getFormat()) { | ||
case 'b': | ||
case 'B': | ||
format = config.getFormat(); | ||
break; | ||
case 'd': | ||
case 'i': | ||
case 'u': | ||
format = 'd'; | ||
break; | ||
case 'o': | ||
format = 'o'; | ||
break; | ||
case 'x': | ||
case 'X': | ||
format = config.getFormat(); | ||
break; | ||
default: | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
if(config.getFormat() == 'b' || config.getFormat() == 'B'){ | ||
node = WriteBytesNodeGen.create(context, | ||
FormatIntegerBinaryNodeGen.create(context, format, | ||
config.isPlus(), config.isFsharp(), | ||
config.isMinus(), | ||
config.isHasSpace(), | ||
config.isZero(), | ||
widthNode, | ||
precisionNode, | ||
ToIntegerNodeGen.create(context, valueNode))); | ||
} else { | ||
node = WriteBytesNodeGen.create(context, | ||
FormatIntegerNodeGen.create(context, format, config.isHasSpace(), config.isZero(), config.isPlus(), config.isMinus(), config.isFsharp(), | ||
widthNode, | ||
precisionNode, | ||
ToIntegerNodeGen.create(context, valueNode))); | ||
} | ||
break; | ||
case FLOAT: | ||
switch (config.getFormat()){ | ||
case 'f': | ||
case 'e': | ||
case 'E': | ||
node = WriteBytesNodeGen.create(context, | ||
FormatFloatNodeGen.create(context, | ||
config.getFormat(), config.isHasSpace(), config.isZero(), config.isPlus(), config.isMinus(), | ||
widthNode, | ||
precisionNode, | ||
ToDoubleWithCoercionNodeGen.create(context, | ||
valueNode))); | ||
break; | ||
case 'g': | ||
case 'G': | ||
node = WriteBytesNodeGen.create(context, | ||
FormatFloatHumanReadableNodeGen.create(context, | ||
ToDoubleWithCoercionNodeGen.create(context, | ||
valueNode))); | ||
break; | ||
default: | ||
throw new UnsupportedOperationException(); | ||
} | ||
break; | ||
case OTHER: | ||
switch (config.getFormat()){ | ||
case 'c': | ||
node = WriteBytesNodeGen.create(context, | ||
FormatCharacterNodeGen.create(context, config.isMinus(), widthNode, | ||
valueNode)); | ||
break; | ||
case 's': | ||
case 'p': | ||
final String conversionMethodName = config.getFormat() == 's' ? "to_s" : "inspect"; | ||
final FormatNode conversionNode; | ||
|
||
if(config.getAbsoluteArgumentIndex() == null && config.getNamesBytes() == null) { | ||
conversionNode = ReadStringNodeGen.create(context, true, conversionMethodName, false, EMPTY_BYTES, new SourceNode()); | ||
} else { | ||
conversionNode = ToStringNodeGen.create(context, true, conversionMethodName, false, EMPTY_BYTES, valueNode); | ||
} | ||
|
||
if (config.getWidth() != null || config.isWidthStar()) { | ||
node = WritePaddedBytesNodeGen.create(context, config.isMinus(), widthNode, conversionNode); | ||
} else { | ||
node = WriteBytesNodeGen.create(context, conversionNode); | ||
} | ||
break; | ||
default: | ||
throw new UnsupportedOperationException(); | ||
} | ||
break; | ||
default: | ||
throw new UnsupportedOperationException("unsupported type: " + config.getFormatType().toString()); | ||
|
||
|
||
|
||
} | ||
|
||
} | ||
sequence.add(node); | ||
} | ||
|
||
|
||
} | ||
|
||
|
||
|
||
public FormatNode getNode() { | ||
buildTree(); | ||
return new SequenceNode(context, sequence.toArray(new FormatNode[sequence.size()])); | ||
} | ||
|
||
} |
276 changes: 0 additions & 276 deletions
276
truffle/src/main/java/org/jruby/truffle/core/format/printf/PrintfTreeBuilder.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters