fez-lisp 1.5.102 → 1.5.104
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/package.json +1 -1
- package/src/check.js +29 -16
- package/src/utils.js +113 -0
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -37,6 +37,7 @@ import {
|
|
37
37
|
validateLambda
|
38
38
|
} from './types.js'
|
39
39
|
import {
|
40
|
+
Brr,
|
40
41
|
getSuffix,
|
41
42
|
hasApplyLambdaBlock,
|
42
43
|
hasBlock,
|
@@ -240,13 +241,13 @@ const retry = (stats, stack, cb) => {
|
|
240
241
|
stats.retried < MAX_RETRY_DEFINITION
|
241
242
|
) {
|
242
243
|
stats.retried += 1
|
243
|
-
stack.
|
244
|
+
stack.prepend(() => cb())
|
244
245
|
}
|
245
246
|
}
|
246
247
|
const retryArgs = (stats, stack, cb) => {
|
247
248
|
if (stats.counter < MAX_ARGUMENT_RETRY) {
|
248
249
|
stats.counter++
|
249
|
-
stack.
|
250
|
+
stack.prepend(cb)
|
250
251
|
}
|
251
252
|
}
|
252
253
|
const ifExpression = ({ re, env, ref }) => {
|
@@ -329,7 +330,7 @@ const resolveCondition = ({ rem, name, env, exp }) => {
|
|
329
330
|
default:
|
330
331
|
if (env[ret[VALUE]]) setReturnRef(ref[STATS], env[ret[VALUE]][STATS])
|
331
332
|
else
|
332
|
-
stack.
|
333
|
+
stack.append(() => {
|
333
334
|
if (env[ret[VALUE]]) setReturnRef(ref[STATS], env[ret[VALUE]][STATS])
|
334
335
|
})
|
335
336
|
break
|
@@ -355,7 +356,7 @@ const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
|
|
355
356
|
// rest.at(-1)[0][TYPE] === APPLY
|
356
357
|
// Here is upon application to store the result in the variable
|
357
358
|
if (isUnknownType(env[name][STATS]))
|
358
|
-
stack.
|
359
|
+
stack.prepend(() => {
|
359
360
|
setTypeToReturn(env[name][STATS], env[returns[VALUE]][STATS])
|
360
361
|
// env[name][STATS][TYPE_PROP][0] =
|
361
362
|
// env[returns[VALUE]][STATS][RETURNS][0]
|
@@ -390,7 +391,7 @@ export const typeCheck = (ast, error = true) => {
|
|
390
391
|
let scopeIndex = 0
|
391
392
|
const root = structuredClone(SPECIAL_FORM_TYPES)
|
392
393
|
const Types = new Map()
|
393
|
-
const stack =
|
394
|
+
const stack = new Brr()
|
394
395
|
const check = (exp, env, scope) => {
|
395
396
|
const [first, ...rest] = isLeaf(exp) ? [exp] : exp
|
396
397
|
if (first === undefined)
|
@@ -402,7 +403,7 @@ export const typeCheck = (ast, error = true) => {
|
|
402
403
|
switch (first[TYPE]) {
|
403
404
|
case WORD:
|
404
405
|
if (!isSpecial)
|
405
|
-
stack.
|
406
|
+
stack.append(() => {
|
406
407
|
// Figure out how to determine if varible is define after it's used
|
407
408
|
if (env[first[VALUE]] === undefined) {
|
408
409
|
throw new TypeError(
|
@@ -567,7 +568,7 @@ export const typeCheck = (ast, error = true) => {
|
|
567
568
|
// TODO figure out what we do here
|
568
569
|
// this here is a variable WORD
|
569
570
|
// so return type of that function is that varible type
|
570
|
-
stack.
|
571
|
+
stack.append(
|
571
572
|
() =>
|
572
573
|
copy[returns[VALUE]] &&
|
573
574
|
setReturnToType(ref[STATS], copy[returns[VALUE]][STATS])
|
@@ -589,7 +590,7 @@ export const typeCheck = (ast, error = true) => {
|
|
589
590
|
if (copy[ret[VALUE]])
|
590
591
|
setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
|
591
592
|
else
|
592
|
-
stack.
|
593
|
+
stack.append(() => {
|
593
594
|
if (copy[ret[VALUE]])
|
594
595
|
setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
|
595
596
|
})
|
@@ -619,7 +620,7 @@ export const typeCheck = (ast, error = true) => {
|
|
619
620
|
}
|
620
621
|
break
|
621
622
|
default:
|
622
|
-
stack.
|
623
|
+
stack.append(() => {
|
623
624
|
if (!isSpecial && env[first[VALUE]] === undefined)
|
624
625
|
throw new TypeError(
|
625
626
|
`Trying to call undefined (lambda) ${first[VALUE]} (check #9)`
|
@@ -848,7 +849,7 @@ export const typeCheck = (ast, error = true) => {
|
|
848
849
|
getType(args[i][STATS]) !== ATOM
|
849
850
|
) {
|
850
851
|
throw new TypeError(
|
851
|
-
`Incorrect type of
|
852
|
+
`Incorrect type of argument (${i}) for (${
|
852
853
|
first[VALUE]
|
853
854
|
}). Expected (${toTypeNames(
|
854
855
|
getType(args[i][STATS])
|
@@ -862,8 +863,19 @@ export const typeCheck = (ast, error = true) => {
|
|
862
863
|
!isUnknownType(env[rest[i][VALUE]][STATS]) &&
|
863
864
|
env[rest[i][VALUE]][STATS][ARG_COUNT] !== VARIADIC
|
864
865
|
) {
|
866
|
+
if (getType(args[i][STATS]) !== APPLY)
|
867
|
+
// TODO this should really happen in 10 or 16
|
868
|
+
throw new TypeError(
|
869
|
+
`Incorrect type for argument of (${
|
870
|
+
first[VALUE]
|
871
|
+
}) at position (${i}). Expected (${
|
872
|
+
STATIC_TYPES.ABSTRACTION
|
873
|
+
}) but got (${toTypeNames(
|
874
|
+
getType(args[i][STATS])
|
875
|
+
)}) (${stringifyArgs(exp)}) (check #111)`
|
876
|
+
)
|
865
877
|
// Handles words that are Lambdas
|
866
|
-
if (
|
878
|
+
else if (
|
867
879
|
env[rest[i][VALUE]][STATS][ARG_COUNT] !==
|
868
880
|
args[i][STATS][ARG_COUNT]
|
869
881
|
) {
|
@@ -936,6 +948,7 @@ export const typeCheck = (ast, error = true) => {
|
|
936
948
|
}
|
937
949
|
}
|
938
950
|
}
|
951
|
+
|
939
952
|
if (
|
940
953
|
T === COLLECTION &&
|
941
954
|
env[rest[i][VALUE]] &&
|
@@ -944,7 +957,7 @@ export const typeCheck = (ast, error = true) => {
|
|
944
957
|
!compareTypes(env[rest[i][VALUE]][STATS], args[i][STATS])
|
945
958
|
) {
|
946
959
|
throw new TypeError(
|
947
|
-
`Incorrect type of
|
960
|
+
`Incorrect type of argument (${i}) for (${
|
948
961
|
first[VALUE]
|
949
962
|
}). Expected (${toTypeNames(
|
950
963
|
getType(args[i][STATS])
|
@@ -952,9 +965,9 @@ export const typeCheck = (ast, error = true) => {
|
|
952
965
|
exp
|
953
966
|
)}) (check #30)`
|
954
967
|
)
|
955
|
-
} else if (isUnknownType(args[i][STATS]))
|
968
|
+
} else if (isUnknownType(args[i][STATS])) {
|
956
969
|
retry(args[i][STATS], stack, () => check(exp, env, scope))
|
957
|
-
else if (
|
970
|
+
} else if (
|
958
971
|
env[rest[i][VALUE]] &&
|
959
972
|
!isUnknownType(args[i][STATS]) &&
|
960
973
|
isUnknownType(env[rest[i][VALUE]][STATS]) &&
|
@@ -974,7 +987,7 @@ export const typeCheck = (ast, error = true) => {
|
|
974
987
|
if (!isUnknownType(expected) && !isUnknownReturn(actual))
|
975
988
|
if (!compareTypeWithReturn(expected, actual))
|
976
989
|
throw new TypeError(
|
977
|
-
`Incorrect type of
|
990
|
+
`Incorrect type of argument (${i}) for (${
|
978
991
|
first[VALUE]
|
979
992
|
}). Expected (${toTypeNames(
|
980
993
|
getType(expected)
|
@@ -1130,7 +1143,7 @@ export const typeCheck = (ast, error = true) => {
|
|
1130
1143
|
}
|
1131
1144
|
const copy = JSON.parse(JSON.stringify(ast))
|
1132
1145
|
check(copy, root, copy)
|
1133
|
-
while (stack.length) stack.
|
1146
|
+
while (stack.length) stack.cut()()
|
1134
1147
|
return [ast, Types]
|
1135
1148
|
}
|
1136
1149
|
export const type = (ast) => typeCheck(ast)[0]
|
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
|
+
}
|