diff options
author | sanine-a <sanine.not@pm.me> | 2023-05-23 13:36:35 -0500 |
---|---|---|
committer | sanine-a <sanine.not@pm.me> | 2023-05-23 13:36:35 -0500 |
commit | 6826d32ca70ec6b6e751813bb595b6ade288cb69 (patch) | |
tree | 0322d95d880083f608492be73f66918be15c01c9 /src/vm/core.js | |
parent | c7f8ede9223502a96a74adf0cb790ac41de04742 (diff) |
add random non-overlapping ranges in core
Diffstat (limited to 'src/vm/core.js')
-rw-r--r-- | src/vm/core.js | 72 |
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; |