summaryrefslogtreecommitdiff
path: root/src/vm/core.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/core.js')
-rw-r--r--src/vm/core.js72
1 files changed, 66 insertions, 6 deletions
diff --git a/src/vm/core.js b/src/vm/core.js
index 4fdd0a0..184be00 100644
--- a/src/vm/core.js
+++ b/src/vm/core.js
@@ -3,6 +3,46 @@
const { Op, AddrMode} = require('./enum.js');
+function mod(a, N) {
+ const A = a % N;
+ if (A < 0) {
+ return A + N;
+ } else {
+ return A;
+ }
+}
+
+
+class Range {
+ constructor(start, end, coresize) {
+ this.start = start;
+ this.end = end;
+ this.coresize = coresize;
+ }
+
+
+ // thanks to https://fgiesen.wordpress.com/2015/09/24/intervals-in-modular-arithmetic/
+ // c:
+ contains(n) {
+ return mod(n - this.start, this.coresize) <= mod(this.end - this.start, this.coresize);
+ }
+
+ overlaps(other) {
+ return (
+ this.contains(other.start) ||
+ other.contains(this.start)
+ );
+ }
+}
+
+
+function randomRange(coresize, length) {
+ const start = Math.floor(Math.random() * coresize);
+ const end = mod(start + length - 1, coresize);
+ return new Range(start, end, coresize);
+}
+
+
class Core {
constructor(size) {
this.data = new Array(size);
@@ -18,13 +58,31 @@ class Core {
}
- normalize(pc, value) {
- const v = (pc + value) % this.data.length;
- if (v < 0) {
- return v + this.data.length;
- } else {
- return v;
+ getRanges(lengths, ranges) {
+ if (ranges === undefined) {
+ ranges = [];
+ }
+
+ if (lengths.length === 0) {
+ return ranges;
}
+
+ const length = lengths[0];
+ let range;
+ do {
+ range = randomRange(this.data.length, length);
+ } while (
+ ranges
+ .map(r => r.overlaps(range))
+ .reduce((acc, overlap) => acc || overlap, false)
+ );
+
+ return this.getRanges(lengths.slice(1), [...ranges, range]);
+ }
+
+
+ normalize(pc, value) {
+ return mod((pc + value), this.data.length);
}
@@ -57,4 +115,6 @@ class Core {
}
+exports.mod = mod;
+exports.Range = Range;
exports.Core = Core;