Skip to content

Commit

Permalink
Showing 10 changed files with 57 additions and 20 deletions.
5 changes: 5 additions & 0 deletions core/src/main/java/org/jruby/ast/BignumNode.java
Original file line number Diff line number Diff line change
@@ -57,6 +57,11 @@ public <T> T accept(NodeVisitor<T> iVisitor) {
return iVisitor.visitBignumNode(this);
}

@Override
public NumericNode negate() {
return new BignumNode(getPosition(), value.negate());
}

/**
* Gets the value.
* @return Returns a BigInteger
5 changes: 5 additions & 0 deletions core/src/main/java/org/jruby/ast/FixnumNode.java
Original file line number Diff line number Diff line change
@@ -56,6 +56,11 @@ public NodeType getNodeType() {
return NodeType.FIXNUMNODE;
}

@Override
public NumericNode negate() {
return new FixnumNode(getPosition(), -value);
}

/**
* Gets the value.
* @return Returns a long
5 changes: 5 additions & 0 deletions core/src/main/java/org/jruby/ast/FloatNode.java
Original file line number Diff line number Diff line change
@@ -56,6 +56,11 @@ public <T> T accept(NodeVisitor<T> iVisitor) {
return iVisitor.visitFloatNode(this);
}

@Override
public NumericNode negate() {
return new FloatNode(getPosition(), -value);
}

/**
* Gets the value.
* @return Returns a double
5 changes: 5 additions & 0 deletions core/src/main/java/org/jruby/ast/NumericNode.java
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

import org.jruby.ast.types.ILiteralNode;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.lexer.yacc.SyntaxException;

/**
* Any node representing a numeric value.
@@ -10,4 +11,8 @@ public abstract class NumericNode extends Node implements ILiteralNode {
public NumericNode(ISourcePosition position) {
super(position, false);
}

public NumericNode negate() {
throw new IllegalArgumentException("Unexpected negation of a numeric type");
}
}
15 changes: 10 additions & 5 deletions core/src/main/java/org/jruby/ast/RationalNode.java
Original file line number Diff line number Diff line change
@@ -15,10 +15,10 @@
* @author enebo
*/
public class RationalNode extends NumericNode implements SideEffectFree {
private final long numerator;
private final long denominator;
private final NumericNode numerator;
private final NumericNode denominator;

public RationalNode(ISourcePosition position, long numerator, long denominator) {
public RationalNode(ISourcePosition position, NumericNode numerator, NumericNode denominator) {
super(position);

this.numerator = numerator;
@@ -30,6 +30,11 @@ public Object accept(NodeVisitor visitor) {
return visitor.visitRationalNode(this);
}

@Override
public NumericNode negate() {
return new RationalNode(getPosition(), numerator.negate(), denominator);
}

@Override
public List<Node> childNodes() {
return EMPTY_LIST;
@@ -40,11 +45,11 @@ public NodeType getNodeType() {
return NodeType.RATIONALNODE;
}

public long getNumerator() {
public NumericNode getNumerator() {
return numerator;
}

public long getDenominator() {
public NumericNode getDenominator() {
return denominator;
}
}
4 changes: 3 additions & 1 deletion core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -3453,7 +3453,9 @@ public Operand buildPreExe(PreExeNode preExeNode) {
}

public Operand buildRational(RationalNode rationalNode) {
return new Rational(rationalNode.getNumerator(), rationalNode.getDenominator());

return new Rational((ImmutableLiteral) build(rationalNode.getNumerator()),
(ImmutableLiteral) build(rationalNode.getDenominator()));
}

public Operand buildRedo() {
15 changes: 9 additions & 6 deletions core/src/main/java/org/jruby/ir/operands/Rational.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package org.jruby.ir.operands;

import org.jruby.RubyRational;
import org.jruby.ir.IRVisitor;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;

/**
* Literal Rational number.
*/
public class Rational extends ImmutableLiteral {
private final long numerator;
private final long denominator;
private final ImmutableLiteral numerator;
private final ImmutableLiteral denominator;

public Rational(long numerator, long denominator) {
public Rational(ImmutableLiteral numerator, ImmutableLiteral denominator) {
super();

this.numerator = numerator;
@@ -24,7 +26,8 @@ public OperandType getOperandType() {

@Override
public Object createCacheObject(ThreadContext context) {
return context.runtime.newRational(numerator, denominator);
return RubyRational.newRationalRaw(context.runtime,
(IRubyObject) numerator.cachedObject(context), (IRubyObject) denominator.cachedObject(context));
}

@Override
@@ -37,11 +40,11 @@ public void visit(IRVisitor visitor) {
visitor.Rational(this);
}

public long getNumerator() {
public ImmutableLiteral getNumerator() {
return numerator;
}

public long getDenominator() {
public ImmutableLiteral getDenominator() {
return denominator;
}
}
6 changes: 3 additions & 3 deletions core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
Original file line number Diff line number Diff line change
@@ -2458,9 +2458,9 @@ public void ObjectClass(ObjectClass objectclass) {
@Override
public void Rational(Rational rational) {
jvmMethod().loadRuntime();
jvmAdapter().ldc(rational.getNumerator());
jvmAdapter().ldc(rational.getDenominator());
jvmAdapter().invokevirtual(p(Ruby.class), "newRational", sig(RubyRational.class, long.class, long.class));
visit(rational.getNumerator());
visit(rational.getDenominator());
jvmAdapter().invokevirtual(p(RubyRational.class), "newRationalRaw", sig(RubyRational.class, Ruby.class, IRubyObject.class, IRubyObject.class));
}

@Override
13 changes: 11 additions & 2 deletions core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java
Original file line number Diff line number Diff line change
@@ -126,7 +126,15 @@ private FixnumNode newFixnumNode(String value, int radix) throws NumberFormatExc
}

private RationalNode newRationalNode(String value, int radix) throws NumberFormatException {
return new RationalNode(getPosition(), Long.parseLong(value, radix), 1);
NumericNode numerator;

try {
numerator = new FixnumNode(getPosition(), Long.parseLong(value, radix));
} catch (NumberFormatException e) {
numerator = new BignumNode(getPosition(), new BigInteger(value, radix));
}

return new RationalNode(getPosition(), numerator, new FixnumNode(getPosition(), 1));
}

private ComplexNode newComplexNode(NumericNode number) {
@@ -429,7 +437,8 @@ private int getFloatToken(String number, int suffix) {
BigDecimal numerator = bd.multiply(denominator);

try {
yaccValue = new RationalNode(getPosition(), numerator.longValueExact(), denominator.longValueExact());
yaccValue = new RationalNode(getPosition(), new FixnumNode(getPosition(), numerator.longValueExact()),
new FixnumNode(getPosition(), denominator.longValueExact()));
} catch (ArithmeticException ae) {
// FIXME: Rational supports Bignum numerator and denominator
compile_error(PID.RATIONAL_OUT_OF_RANGE, "Rational (" + numerator + "/" + denominator + ") out of range.");
4 changes: 1 addition & 3 deletions core/src/main/java/org/jruby/parser/ParserSupport.java
Original file line number Diff line number Diff line change
@@ -1086,9 +1086,7 @@ public ComplexNode negateComplexNode(ComplexNode complexNode) {
}

public RationalNode negateRational(RationalNode rationalNode) {
return new RationalNode(rationalNode.getPosition(),
-rationalNode.getNumerator(),
rationalNode.getDenominator());
return (RationalNode) rationalNode.negate();
}

private Node checkForNilNode(Node node, ISourcePosition defaultPosition) {

0 comments on commit 5f83b90

Please sign in to comment.