Skip to content

Commit

Permalink
[Truffle] Implemement more Bignum#% specs.
Browse files Browse the repository at this point in the history
  • Loading branch information
bjfish committed Apr 19, 2015
1 parent 77a5ca9 commit 71b46c9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/bignum/modulo_tags.txt

This file was deleted.

Expand Up @@ -206,7 +206,7 @@ public Object div(RubyBignum a, RubyBignum b) {

}

@CoreMethod(names = "%", required = 1)
@CoreMethod(names = {"%", "modulo"}, required = 1)
public abstract static class ModNode extends BignumCoreMethodNode {

public ModNode(RubyContext context, SourceSection sourceSection) {
Expand All @@ -219,19 +219,46 @@ public ModNode(ModNode prev) {

@Specialization
public Object mod(RubyBignum a, int b) {
if (b == 0) {
throw new ArithmeticException("divide by zero");
} else if (b < 0) {
final BigInteger bigint = BigInteger.valueOf(b);
final BigInteger mod = a.bigIntegerValue().mod(bigint.negate());
return fixnumOrBignum(mod.add(bigint));
}
return fixnumOrBignum(a.bigIntegerValue().mod(BigInteger.valueOf(b)));
}

@Specialization
public Object mod(RubyBignum a, long b) {
if (b == 0) {
throw new ArithmeticException("divide by zero");
} else if (b < 0) {
final BigInteger bigint = BigInteger.valueOf(b);
final BigInteger mod = a.bigIntegerValue().mod(bigint.negate());
return fixnumOrBignum(mod.add(bigint));
}
return fixnumOrBignum(a.bigIntegerValue().mod(BigInteger.valueOf(b)));
}

@Specialization
public Object mod(RubyBignum a, RubyBignum b) {
final BigInteger bigint = b.bigIntegerValue();
final int compare = bigint.compareTo(BigInteger.ZERO);
if (compare == 0) {
throw new ArithmeticException("divide by zero");
} else if (compare < 0) {
final BigInteger mod = a.bigIntegerValue().mod(bigint.negate());
return fixnumOrBignum(mod.add(bigint));
}
return fixnumOrBignum(a.bigIntegerValue().mod(b.bigIntegerValue()));
}

@Specialization(guards = {"!isInteger(arguments[1])", "!isLong(arguments[1])", "!isRubyBignum(arguments[1])"})
public Object mod(VirtualFrame frame, RubyBignum a, Object b) {
return ruby(frame, "redo_coerced :%, other", "other", b);
}

}

@CoreMethod(names = "<", required = 1)
Expand Down

0 comments on commit 71b46c9

Please sign in to comment.