diff --git a/src/main/java/com/redhat/ceylon/compiler/js/ForGenerator.java b/src/main/java/com/redhat/ceylon/compiler/js/ForGenerator.java index 355500f5..e1507192 100644 --- a/src/main/java/com/redhat/ceylon/compiler/js/ForGenerator.java +++ b/src/main/java/com/redhat/ceylon/compiler/js/ForGenerator.java @@ -88,8 +88,8 @@ boolean optimizeRange(final Tree.RangeOp range, final String itemVar) { final Tree.Term right = range.getRightTerm(); if (left instanceof Tree.NaturalLiteral && right instanceof NaturalLiteral) { try { - long una = gen.parseNaturalLiteral((Tree.NaturalLiteral)left); - long dos = gen.parseNaturalLiteral((Tree.NaturalLiteral)right); + long una = gen.parseNaturalLiteral((Tree.NaturalLiteral)left, false); + long dos = gen.parseNaturalLiteral((Tree.NaturalLiteral)right, false); optimizeNaturals(una, dos, itemVar); return true; } catch (NumberFormatException ex) { @@ -118,15 +118,15 @@ boolean optimizeSegment(Tree.SegmentOp that, final String itemVar) { final boolean rightNat = right instanceof Tree.NaturalLiteral; if (leftNat && rightNat) { try { - long una = gen.parseNaturalLiteral((Tree.NaturalLiteral)left); - long dos = gen.parseNaturalLiteral((Tree.NaturalLiteral)right); + long una = gen.parseNaturalLiteral((Tree.NaturalLiteral)left, false); + long dos = gen.parseNaturalLiteral((Tree.NaturalLiteral)right, false); optimizeNaturals(una, una+dos-1, itemVar); return true; } catch (NumberFormatException ex) { return false; } } - final String limvar = rightNat ? Long.toString(gen.parseNaturalLiteral((Tree.NaturalLiteral)right)) + final String limvar = rightNat ? Long.toString(gen.parseNaturalLiteral((Tree.NaturalLiteral)right, false)) : gen.getNames().createTempVariable(); gen.out("var ", itemVar, "="); left.visit(gen); diff --git a/src/main/java/com/redhat/ceylon/compiler/js/GenerateJsVisitor.java b/src/main/java/com/redhat/ceylon/compiler/js/GenerateJsVisitor.java index 8d768522..a1ae0c68 100644 --- a/src/main/java/com/redhat/ceylon/compiler/js/GenerateJsVisitor.java +++ b/src/main/java/com/redhat/ceylon/compiler/js/GenerateJsVisitor.java @@ -1554,17 +1554,22 @@ public void visit(final Tree.FloatLiteral that) { out(getClAlias(), "Float(", that.getText(), ")"); } - public long parseNaturalLiteral(Tree.NaturalLiteral that) throws NumberFormatException { - char prefix = that.getText().charAt(0); - int radix = 10; + long parseNaturalLiteral(Tree.NaturalLiteral that, boolean neg) throws NumberFormatException { String nt = that.getText(); + char prefix = nt.charAt(0); + int radix = 10; if (prefix == '$' || prefix == '#') { radix = prefix == '$' ? 2 : 16; nt = nt.substring(1); } final java.math.BigInteger lit = new java.math.BigInteger(nt, radix); - if (lit.bitLength() > 63) { - that.addError("Natural literal outside the valid range (-9223372036854775808..9223372036854775807)"); + if (radix==10 && lit.bitLength() > 63) { + if (lit.bitLength() == 64 && neg) { + return -lit.longValue(); + } + that.addError("literal outside representable range: " + nt + " is too large to be represented as an Integer"); + } else if (lit.bitLength() > 63 && lit.bitLength()==lit.bitCount()) { + out("/*bit length=" + lit.bitLength() + ", count=" + lit.bitCount(), " ERGO " + (lit.longValue()),"*/"); } return lit.longValue(); } @@ -1572,7 +1577,7 @@ public long parseNaturalLiteral(Tree.NaturalLiteral that) throws NumberFormatExc @Override public void visit(final Tree.NaturalLiteral that) { try { - out("(", Long.toString(parseNaturalLiteral(that)), ")"); + out("(", Long.toString(parseNaturalLiteral(that, false)), ")"); } catch (NumberFormatException ex) { that.addError("Invalid numeric literal " + that.getText()); } @@ -2630,12 +2635,13 @@ private void assignOp(final Tree.AssignmentOp that, final String functionName, f @Override public void visit(final Tree.NegativeOp that) { if (that.getTerm() instanceof Tree.NaturalLiteral) { - long t = parseNaturalLiteral((Tree.NaturalLiteral)that.getTerm()); + long t = parseNaturalLiteral((Tree.NaturalLiteral)that.getTerm(), true); out("("); if (t > 0) { - out("-"); + out("-", Long.toString(t)); + } else { + out(Long.toString(-t)); } - out(Long.toString(t)); out(")"); if (t == 0) { //Force -0 @@ -3406,7 +3412,10 @@ public int getExitCode() { boolean isNaturalLiteral(Tree.Term that) { if (that instanceof Tree.NaturalLiteral) { - out(Long.toString(parseNaturalLiteral((Tree.NaturalLiteral)that))); + out(Long.toString(parseNaturalLiteral((Tree.NaturalLiteral)that, false))); + return true; + } else if (that instanceof Tree.NegativeOp) { + that.visit(this); return true; } return false; diff --git a/src/main/java/com/redhat/ceylon/compiler/js/Operators.java b/src/main/java/com/redhat/ceylon/compiler/js/Operators.java index 1f75c97b..d5d615ed 100644 --- a/src/main/java/com/redhat/ceylon/compiler/js/Operators.java +++ b/src/main/java/com/redhat/ceylon/compiler/js/Operators.java @@ -16,13 +16,13 @@ static void simpleBinaryOp(final Tree.BinaryOperatorExpression exp, gen.out(before); } if (op.charAt(0)!='.' && exp.getLeftTerm() instanceof Tree.NaturalLiteral) { - gen.out(Long.toString(gen.parseNaturalLiteral((Tree.NaturalLiteral)exp.getLeftTerm()))); + gen.out(Long.toString(gen.parseNaturalLiteral((Tree.NaturalLiteral)exp.getLeftTerm(), false))); } else { gen.box(exp.getLeftTerm()); } gen.out(op); if (exp.getRightTerm() instanceof Tree.NaturalLiteral) { - gen.out(Long.toString(gen.parseNaturalLiteral((Tree.NaturalLiteral)exp.getRightTerm()))); + gen.out(Long.toString(gen.parseNaturalLiteral((Tree.NaturalLiteral)exp.getRightTerm(), false))); } else { gen.box(exp.getRightTerm()); } @@ -35,13 +35,13 @@ static void genericBinaryOp(final Tree.BinaryOperatorExpression exp, final Strin final Map targs, final Map overrides, final GenerateJsVisitor gen) { if (op.charAt(0)!='.' && exp.getLeftTerm() instanceof Tree.NaturalLiteral) { - gen.out(Long.toString(gen.parseNaturalLiteral((Tree.NaturalLiteral)exp.getLeftTerm()))); + gen.out(Long.toString(gen.parseNaturalLiteral((Tree.NaturalLiteral)exp.getLeftTerm(), false))); } else { gen.box(exp.getLeftTerm()); } gen.out(op); if (exp.getRightTerm() instanceof Tree.NaturalLiteral) { - gen.out(Long.toString(gen.parseNaturalLiteral((Tree.NaturalLiteral)exp.getRightTerm()))); + gen.out(Long.toString(gen.parseNaturalLiteral((Tree.NaturalLiteral)exp.getRightTerm(), false))); } else { gen.box(exp.getRightTerm()); } @@ -58,7 +58,7 @@ static void unaryOp(final Tree.UnaryOperatorExpression exp, final String before, gen.out(before); } if ((after==null || after.charAt(0)!='.' ) && exp.getTerm() instanceof Tree.NaturalLiteral) { - gen.out(Long.toString(gen.parseNaturalLiteral((Tree.NaturalLiteral)exp.getTerm()))); + gen.out(Long.toString(gen.parseNaturalLiteral((Tree.NaturalLiteral)exp.getTerm(), false))); } else { final int boxTypeLeft = gen.boxStart(exp.getTerm()); exp.getTerm().visit(gen);