fez-lisp 1.5.101 → 1.5.103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/utils.js CHANGED
@@ -347,3 +347,116 @@ export const UTILS = {
347
347
  stringifyArgs,
348
348
  shake
349
349
  }
350
+ export class Brr {
351
+ constructor(...items) {
352
+ this._left = [Brr._negativeZeroSymbol]
353
+ this._right = []
354
+ if (items.length === 0) return this
355
+ const half = (items.length / 2) | 0.5
356
+ for (let i = half - 1; i >= 0; --i) this._left.push(items[i])
357
+ for (let i = half; i < items.length; ++i) this._right.push(items[i])
358
+ return this
359
+ }
360
+ _addToLeft(item) {
361
+ this._left.push(item)
362
+ }
363
+ _addToRight(item) {
364
+ this._right.push(item)
365
+ }
366
+ _removeFromLeft() {
367
+ const len = this.length
368
+ if (len) {
369
+ if (len === 1) this.clear()
370
+ else if (this._left.length > 0) this._left.pop()
371
+ }
372
+ }
373
+ _removeFromRight() {
374
+ const len = this.length
375
+ if (len) {
376
+ if (len === 1) this.clear()
377
+ else if (this._right.length > 0) this._right.pop()
378
+ }
379
+ }
380
+ static _negativeZeroSymbol = Symbol('-0')
381
+ static isBrr(entity) {
382
+ return entity instanceof Brr
383
+ }
384
+ _offsetLeft() {
385
+ return (this._left.length - 1) * -1
386
+ }
387
+ _offsetRight() {
388
+ return this._right.length
389
+ }
390
+ get length() {
391
+ return this._left.length + this._right.length - 1
392
+ }
393
+ get first() {
394
+ return this.get(0)
395
+ }
396
+ get last() {
397
+ return this.get(-1)
398
+ }
399
+ get(offset) {
400
+ if (offset < 0) offset = this.length + offset
401
+ const offsetIndex = offset + this._offsetLeft()
402
+ const index = offsetIndex < 0 ? offsetIndex * -1 : offsetIndex
403
+ return offsetIndex >= 0 ? this._right[index] : this._left[index]
404
+ }
405
+ set(index, value) {
406
+ index = index < 0 ? this.length + index : index
407
+ const offset = index + this._offsetLeft()
408
+ if (offset >= 0) this._right[offset] = value
409
+ else this._left[offset * -1] = value
410
+ return this
411
+ }
412
+ append(item) {
413
+ this._addToRight(item)
414
+ return this
415
+ }
416
+ prepend(item) {
417
+ this._addToLeft(item)
418
+ return this
419
+ }
420
+ cut() {
421
+ if (this._offsetRight() === 0) this.balance()
422
+ const last = this.last
423
+ this._removeFromRight()
424
+ return last
425
+ }
426
+ chop() {
427
+ if (this._offsetLeft() === 0) this.balance()
428
+ const first = this.first
429
+ this._removeFromLeft()
430
+ return first
431
+ }
432
+ head() {
433
+ if (this._offsetRight() === 0) this.balance()
434
+ this._removeFromRight()
435
+ return this
436
+ }
437
+ tail() {
438
+ if (this._offsetLeft() === 0) this.balance()
439
+ this._removeFromLeft()
440
+ return this
441
+ }
442
+ clear() {
443
+ this._left.length = 1
444
+ this._right.length = 0
445
+ return this
446
+ }
447
+ isBalanced() {
448
+ return this._offsetRight() + this._offsetLeft() === 0
449
+ }
450
+ balance() {
451
+ if (this.isBalanced()) return this
452
+ const initial = [...this]
453
+ this.clear()
454
+ const half = (initial.length / 2) | 0.5
455
+ for (let i = half - 1; i >= 0; --i) this._addToLeft(initial[i])
456
+ for (let i = half; i < initial.length; ++i) this._addToRight(initial[i])
457
+ return this
458
+ }
459
+ *[Symbol.iterator]() {
460
+ for (let i = 0, len = this.length; i < len; ++i) yield this.get(i)
461
+ }
462
+ }