Skip to content

Commit

Permalink
Improve support of BigIntegers
Browse files Browse the repository at this point in the history
- move the intOrBigInt to platform

Signed-off-by: Stefan Marr <[email protected]>
  • Loading branch information
smarr committed Dec 17, 2020
1 parent 300b036 commit 991b467
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 32 deletions.
12 changes: 12 additions & 0 deletions src/lib/platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,16 @@ function isInIntRange(val) {
return val >= -2147483647 && val <= 2147483647;
}

function intOrBigInt(val, universe) {
if (isInIntRange(val)) {
if (typeof val === "bigint") {
return universe.newInteger(Number(val) | 0);
}
return universe.newInteger(val | 0);
} else {
return universe.newBigInteger(val);
}
}

exports.isInIntRange = isInIntRange;
exports.intOrBigInt = intOrBigInt;
16 changes: 8 additions & 8 deletions src/som/compiler/Parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const factory = require('../interpreter/NodeFactory');
const u = require('../vm/Universe');

const isInIntRange = require('../../lib/platform').isInIntRange;
const intOrBigInt = require('../../lib/platform').intOrBigInt;


function isIdentifier(sym) {
Expand Down Expand Up @@ -633,22 +634,21 @@ function Parser(fileContent, fileName) {
}

function literalInteger(isNegative) {
var i = parseInt(text, 10);
if (isNaN(i)) {
let i;

try {
i = BigInt(text);
} catch (e) {
throw new ParseError("Could not parse integer. Expected a number " +
"but got '" + text + "'", Sym.NONE, _this);
}

if (isNegative) {
i = 0 - i;
i = 0n - i;
}
expect(Sym.Integer);

if (isInIntRange(i)) {
return u.universe.newInteger(i);
} else {
return u.universe.newBigInteger(BigInt(i));
}
return intOrBigInt(i, u.universe);
}

function literalDouble(isNegative) {
Expand Down
4 changes: 2 additions & 2 deletions src/som/primitives/SystemPrimitives.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ function SystemPrimitives() {

function _time(_frame, _args) {
var diff = platform.getMillisecondTicks() - u.startTime;
return intOrBigInt(diff);
return intOrBigInt(diff, u.universe);
}

function _ticks(_frame, _args) {
var diff = platform.getMillisecondTicks() - u.startTime;
return intOrBigInt(diff * 1000);
return intOrBigInt(diff * 1000, u.universe);
}

function _fullGC(_frame, _args) {
Expand Down
2 changes: 1 addition & 1 deletion src/som/vm/Universe.js
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ function Universe() {
// Exit from the Java system
lastExitCode = errorCode;
if (!avoidExit) {
exitInterpreter(errorCode);
platform.exitInterpreter(errorCode);
}
throw new ExitException(errorCode);
};
Expand Down
33 changes: 12 additions & 21 deletions src/som/vmobjects/numbers.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,11 @@ const RuntimeException = require('../../lib/exceptions').RuntimeException;
const assert = require('../../lib/assert').assert;
const notYetImplemented = require('../../lib/assert').notYetImplemented;
const isInIntRange = require('../../lib/platform').isInIntRange;
const intOrBigInt = require('../../lib/platform').intOrBigInt;

const SAbstractObject = require('./SAbstractObject').SAbstractObject;
const u = require('../vm/Universe');

function intOrBigInt(val) {
if (isInIntRange(val)) {
return u.universe.newInteger(val | 0);
} else {
return u.universe.newBigInteger(BigInt(val));
}
}

function SInteger(intVal) {
assert(isInIntRange(intVal) && Math.floor(intVal) == intVal);
SAbstractObject.call(this);
Expand All @@ -55,7 +48,7 @@ function SInteger(intVal) {
this.primLessThan = function (right) {
var result;
if (right instanceof SBigInteger) {
result = BigInt(intVal).lesser(right.getEmbeddedBigInteger());
result = intVal < right.getEmbeddedBigInteger();
} else if (right instanceof SDouble) {
return toDouble.primLessThan(right);
} else {
Expand All @@ -71,24 +64,24 @@ function SInteger(intVal) {
this.primAdd = function (right) {
if (right instanceof SBigInteger) {
return u.universe.newBigInteger(
right.getEmbeddedBigInteger().add(intVal));
right.getEmbeddedBigInteger() + BigInt(intVal));
} else if (right instanceof SDouble) {
return toDouble().primAdd(right);
} else {
var r = right.getEmbeddedInteger();
return intOrBigInt(intVal + r);
return intOrBigInt(intVal + r, u.universe);
}
};

this.primSubtract = function (right) {
if (right instanceof SBigInteger) {
return u.universe.newBigInteger(
right.getEmbeddedBigInteger().subtract(intVal));
BigInt(intVal) - right.getEmbeddedBigInteger());
} else if (right instanceof SDouble) {
return toDouble().primSubtract(right);
} else {
var r = right.getEmbeddedInteger();
return intOrBigInt(intVal - r);
const r = right.getEmbeddedInteger();
return intOrBigInt(intVal - r, u.universe);
}
};

Expand All @@ -100,7 +93,7 @@ function SInteger(intVal) {
return toDouble().primMultiply(right);
} else {
var r = right.getEmbeddedInteger();
return intOrBigInt(intVal * r);
return intOrBigInt(intVal * r, u.universe);
}
};

Expand Down Expand Up @@ -167,7 +160,7 @@ function SInteger(intVal) {
this.prim32BitUnsignedValue = function () {
var arr = new Uint32Array(1);
arr[0] = intVal;
return intOrBigInt(arr[0]);
return intOrBigInt(arr[0], u.universe);
}

this.prim32BitSignedValue = function () {
Expand Down Expand Up @@ -283,7 +276,7 @@ function SBigInteger(bigintVal) {
} else if (right instanceof SDouble) {
return u.universe.newDouble(bigintVal.toJSNumber() - right.getEmbeddedDouble());
} else {
result = bigintVal - right.getEmbeddedInteger()
result = bigintVal - BigInt(right.getEmbeddedInteger())
}
return u.universe.newBigInteger(result);
};
Expand Down Expand Up @@ -355,13 +348,11 @@ function SBigInteger(bigintVal) {
};

this.prim32BitUnsignedValue = function () {
var val = Number(bigintVal) >>> 0;
return intOrBigInt(val);
return intOrBigInt(BigInt.asUintN(32, bigintVal), u.universe);
}

this.prim32BitSignedValue = function () {
var val = Number(bigintVal) >> 0;
return intOrBigInt(val);
return intOrBigInt(BigInt.asIntN(32, bigintVal), u.universe);
}
}
SBigInteger.prototype = Object.create(SAbstractObject.prototype);
Expand Down

0 comments on commit 991b467

Please sign in to comment.