fez-lisp 1.5.32 → 1.5.34

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 CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "fez-lisp",
3
3
  "description": "Lisp interpreted & compiled to JavaScript",
4
4
  "author": "AT290690",
5
- "version": "1.5.32",
5
+ "version": "1.5.34",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -61,7 +61,6 @@ export const typeCheck = (ast) => {
61
61
  [DEBUG.SET_THEME]: {
62
62
  [STATS]: { type: APPLY, [ARGS_COUNT]: VARIADIC, [RETURNS]: UNKNOWN }
63
63
  },
64
- [SCOPE_NAME]: performance.now().toString().replace('.', 0),
65
64
  [KEYWORDS.BLOCK]: {
66
65
  [STATS]: { type: APPLY, [ARGS_COUNT]: VARIADIC, [RETURNS]: UNKNOWN }
67
66
  },
@@ -376,7 +375,29 @@ export const typeCheck = (ast) => {
376
375
  }
377
376
  }
378
377
  const errorStack = new Map()
379
- const withScope = (name, scope) => `${scope[SCOPE_NAME]}_${name}`
378
+ // const isDefinitionOfAFunction = (head, tail) =>
379
+ // head[TYPE] === APPLY &&
380
+ // head[VALUE] === KEYWORDS.DEFINE_VARIABLE &&
381
+ // tail.at(-1)[0][TYPE] === APPLY &&
382
+ // tail.at(-1)[0][VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
383
+ const getScopeNames = (scope) => {
384
+ const scopeNames = []
385
+ let current = scope
386
+
387
+ while (current) {
388
+ if (current[SCOPE_NAME]) {
389
+ scopeNames.push(current[SCOPE_NAME])
390
+ }
391
+ current = Object.getPrototypeOf(current)
392
+ }
393
+ return scopeNames.reverse()
394
+ }
395
+ const withScope = (name, scope) => {
396
+ const chain = getScopeNames(scope)
397
+ const str = `${chain.join('_')}_${name}`
398
+ // console.log({ str })
399
+ return { str, chain }
400
+ }
380
401
 
381
402
  const stack = []
382
403
  const check = (exp, env, scope) => {
@@ -385,14 +406,15 @@ export const typeCheck = (ast) => {
385
406
  switch (first[TYPE]) {
386
407
  case WORD:
387
408
  {
388
- const key = withScope(first[VALUE], scope)
389
- if (env[first[VALUE]] === undefined) {
390
- errorStack.set(
391
- key,
392
- `Trying to access undefined variable ${first[VALUE]} (check #11)`
393
- )
394
- }
395
- // else if (errorStack.has(key)) errorStack.delete(key)
409
+ stack.push(() => {
410
+ const key = withScope(first[VALUE], scope)
411
+ if (env[first[VALUE]] === undefined) {
412
+ errorStack.set(
413
+ key.str,
414
+ `Trying to access undefined variable ${first[VALUE]} (check #11)`
415
+ )
416
+ }
417
+ })
396
418
  }
397
419
  break
398
420
  case ATOM:
@@ -410,12 +432,11 @@ export const typeCheck = (ast) => {
410
432
  )}) (check #10)`
411
433
  )
412
434
  } else {
435
+ const name = rest[0][VALUE]
413
436
  if (
414
- rest.at(-1).length &&
415
437
  rest.at(-1)[0][TYPE] === APPLY &&
416
438
  rest.at(-1)[0][VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
417
439
  ) {
418
- const name = rest[0][VALUE]
419
440
  const n = rest.at(-1).length
420
441
  env[name] = {
421
442
  [STATS]: {
@@ -426,11 +447,8 @@ export const typeCheck = (ast) => {
426
447
  }
427
448
  if (name[name.length - 1] === PREDICATE_SUFFIX)
428
449
  env[name][STATS][SUBTYPE] = PREDICATE
429
- const key = withScope(name, scope)
430
- if (errorStack.has(key)) errorStack.delete(key)
431
- scope = exp
450
+ check(rest.at(-1), env, exp)
432
451
  } else {
433
- const name = rest[0][VALUE]
434
452
  if (!(name in env)) {
435
453
  if (rest[1][TYPE] === WORD)
436
454
  env[name] = env[rest[1][VALUE]]
@@ -445,16 +463,8 @@ export const typeCheck = (ast) => {
445
463
  }
446
464
  }
447
465
  }
448
- // if (name === 'math:decimal-scaling') {
449
- // const key = withScope(name, scope)
450
- // if (errorStack.has(key)) errorStack.delete(key)
451
- // }
452
- // if (scope[SCOPE_NAME]) {
453
- // const key = withScope(name, scope)
454
- // if (errorStack.has(key)) errorStack.delete(key)
455
- // }
466
+ check(rest.at(-1), env, scope)
456
467
  }
457
- check(rest.at(-1), env, scope)
458
468
  }
459
469
  }
460
470
  break
@@ -471,7 +481,7 @@ export const typeCheck = (ast) => {
471
481
  }
472
482
  const params = exp.slice(1, -1)
473
483
  const copy = Object.create(env)
474
- if (isLeaf(scope[1])) {
484
+ if (Array.isArray(scope[1]) && scope[1][TYPE] === WORD) {
475
485
  copy[SCOPE_NAME] = scope[1][VALUE]
476
486
  } else {
477
487
  copy[SCOPE_NAME] = performance
@@ -479,13 +489,12 @@ export const typeCheck = (ast) => {
479
489
  .toString()
480
490
  .replace('.', 0)
481
491
  }
482
-
483
492
  for (const param of params) {
484
493
  copy[param[VALUE]] = { [STATS]: { type: UNKNOWN } }
485
494
  if (env[copy[SCOPE_NAME]])
486
495
  env[copy[SCOPE_NAME]][STATS][ARGS].push(copy[param[VALUE]])
487
496
  }
488
- check(rest.at(-1), copy, scope)
497
+ check(rest.at(-1), copy, copy)
489
498
  }
490
499
  break
491
500
  default:
@@ -493,269 +502,227 @@ export const typeCheck = (ast) => {
493
502
  const key = withScope(first[VALUE], scope)
494
503
  if (env[first[VALUE]] === undefined)
495
504
  errorStack.set(
496
- key,
505
+ key.str,
497
506
  `Trying to call undefined (lambda) ${first[VALUE]} (check #9)`
498
507
  )
499
- else if (
500
- env[first[VALUE]][STATS].type === APPLY &&
501
- env[first[VALUE]][STATS][ARGS_COUNT] !== VARIADIC &&
502
- env[first[VALUE]][STATS][ARGS_COUNT] !== rest.length
503
- ) {
504
- errorStack.set(
505
- key,
506
- `Incorrect number of arguments for (${
507
- first[VALUE]
508
- }). Expected (= ${
509
- env[first[VALUE]][STATS][ARGS_COUNT]
510
- }) but got ${rest.length} (${stringifyArgs(
511
- exp
512
- )}) (check #8)`
513
- )
514
- } else {
515
- const isSpecial = SPECIAL_FORMS_SET.has(first[VALUE])
508
+ else {
509
+ if (
510
+ env[first[VALUE]][STATS].type === APPLY &&
511
+ env[first[VALUE]][STATS][ARGS_COUNT] !== VARIADIC &&
512
+ env[first[VALUE]][STATS][ARGS_COUNT] !== rest.length
513
+ ) {
514
+ errorStack.set(
515
+ key.str,
516
+ `Incorrect number of arguments for (${
517
+ first[VALUE]
518
+ }). Expected (= ${
519
+ env[first[VALUE]][STATS][ARGS_COUNT]
520
+ }) but got ${rest.length} (${stringifyArgs(
521
+ exp
522
+ )}) (check #8)`
523
+ )
524
+ } else {
525
+ const isSpecial = SPECIAL_FORMS_SET.has(first[VALUE])
516
526
 
517
- if (first[TYPE] === APPLY && !isSpecial) {
518
- if (env[first[VALUE]][STATS].type === ATOM) {
519
- errorStack.set(
520
- key,
521
- `(${first[VALUE]}) is not a (lambda) (${stringifyArgs(
522
- exp
523
- )})`
524
- )
525
- } else if (!env[first[VALUE]][STATS][ARGS_COUNT]) {
526
- env[first[VALUE]][STATS][RETURNS] = UNKNOWN
527
- env[first[VALUE]][STATS].type = APPLY
528
- env[first[VALUE]][STATS][ARGS_COUNT] = rest.length
527
+ if (first[TYPE] === APPLY && !isSpecial) {
528
+ if (env[first[VALUE]][STATS].type === ATOM) {
529
+ errorStack.set(
530
+ key.str,
531
+ `(${first[VALUE]}) is not a (lambda) (${stringifyArgs(
532
+ exp
533
+ )}) (check #12)`
534
+ )
535
+ } else if (!env[first[VALUE]][STATS][ARGS_COUNT]) {
536
+ env[first[VALUE]][STATS][RETURNS] = UNKNOWN
537
+ env[first[VALUE]][STATS].type = APPLY
538
+ env[first[VALUE]][STATS][ARGS_COUNT] = rest.length
539
+ }
529
540
  }
530
- }
531
- // also type of arg
532
- const args = env[first[VALUE]][STATS][ARGS]
533
- if (args) {
534
- for (let i = 0; i < args.length; ++i) {
535
- if (
536
- args[i][STATS] &&
537
- args[i][STATS].type === APPLY &&
538
- env[rest[i][VALUE]] &&
539
- env[rest[i][VALUE]][STATS] &&
540
- env[rest[i][VALUE]][STATS][ARGS_COUNT] &&
541
- args[i][STATS][ARGS_COUNT] !== VARIADIC &&
542
- env[rest[i][VALUE]][STATS][ARGS_COUNT] !== VARIADIC
543
- ) {
541
+ // also type of arg
542
+ const args = env[first[VALUE]][STATS][ARGS]
543
+ if (args) {
544
+ for (let i = 0; i < args.length; ++i) {
545
+ // type check
544
546
  if (
545
- args[i][STATS][ARGS_COUNT] !==
546
- env[rest[i][VALUE]][STATS][ARGS_COUNT]
547
+ first[TYPE] === APPLY &&
548
+ isSpecial &&
549
+ env[first[VALUE]][STATS][ARGS_COUNT] !== VARIADIC
547
550
  ) {
548
- errorStack.set(
549
- key,
550
- `Incorrect number of arguments for (${
551
- first[VALUE]
552
- }). Expected (= ${
553
- args[i][STATS][ARGS_COUNT]
554
- }) but got ${rest.length} (${stringifyArgs(
555
- exp
556
- )}) (check #7)`
557
- )
558
- }
559
- } else if (
560
- args[i][STATS] &&
561
- args[i][STATS].type === APPLY &&
562
- !isLeaf(rest[i]) &&
563
- rest[i][0][TYPE] === APPLY &&
564
- rest[i][0][VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
565
- ) {
566
- if (args[i][STATS][ARGS_COUNT] !== rest[i].length - 2)
567
- errorStack.set(
568
- key,
569
- `Incorrect number of arguments for (${
570
- first[VALUE]
571
- }). Expected (= ${
572
- args[i][STATS][ARGS_COUNT]
573
- }) but got ${rest.length} (${stringifyArgs(
574
- exp
575
- )}) (check #6)`
576
- )
577
- }
578
-
579
- // type check
580
- if (
581
- first[TYPE] === APPLY &&
582
- isSpecial &&
583
- env[first[VALUE]][STATS][ARGS_COUNT] !== VARIADIC
584
- ) {
585
- const expectedArgs = env[first[VALUE]][STATS][ARGS]
586
- for (let i = 0; i < rest.length; ++i) {
587
- if (expectedArgs[i][TYPE] === UNKNOWN) continue
588
- if (!isLeaf(rest[i])) {
589
- const CAR = rest[i][0][VALUE]
590
- if (
591
- env[CAR] &&
592
- env[CAR][STATS][RETURNS] != undefined &&
593
- env[CAR][STATS][RETURNS] !== UNKNOWN &&
594
- env[CAR][STATS][RETURNS] !== expectedArgs[i][TYPE]
595
- ) {
596
- // console.log(env[CAR][STATS], expectedArgs[i][TYPE])
597
- errorStack.set(
598
- key,
599
- `Incorrect type of arguments for special form (${
600
- first[VALUE]
601
- }). Expected (${toTypeNames(
551
+ const expectedArgs = env[first[VALUE]][STATS][ARGS]
552
+ for (let i = 0; i < rest.length; ++i) {
553
+ if (expectedArgs[i][TYPE] === UNKNOWN) continue
554
+ if (!isLeaf(rest[i])) {
555
+ const CAR = rest[i][0][VALUE]
556
+ if (
557
+ env[CAR] &&
558
+ env[CAR][STATS][RETURNS] != undefined &&
559
+ env[CAR][STATS][RETURNS] !== UNKNOWN &&
560
+ env[CAR][STATS][RETURNS] !==
602
561
  expectedArgs[i][TYPE]
603
- )}) but got (${toTypeNames(
604
- env[CAR][STATS][RETURNS]
605
- )}) (${stringifyArgs(exp)}) (check #1)`
606
- )
562
+ ) {
563
+ // console.log(env[CAR][STATS], expectedArgs[i][TYPE])
564
+ errorStack.set(
565
+ key.str,
566
+ `Incorrect type of arguments for special form (${
567
+ first[VALUE]
568
+ }). Expected (${toTypeNames(
569
+ expectedArgs[i][TYPE]
570
+ )}) but got (${toTypeNames(
571
+ env[CAR][STATS][RETURNS]
572
+ )}) (${stringifyArgs(exp)}) (check #1)`
573
+ )
574
+ }
575
+ // else {
576
+ // console.log(env[CAR])
577
+ // }
607
578
  }
608
- // else {
609
- // console.log(env[CAR])
610
- // }
611
- }
612
- if (
613
- env[rest[i][VALUE]] &&
614
- expectedArgs[i][TYPE] !== rest[i][TYPE]
615
- ) {
616
- switch (rest[i][TYPE]) {
617
- case UNKNOWN:
618
- env[first[VALUE]][STATS].type =
619
- expectedArgs[i][TYPE]
620
- break
621
- case WORD:
622
- const T = env[rest[i][VALUE]][STATS].type
623
- if (Array.isArray(T)) {
624
- const TT = T[VALUE]
625
- if (
626
- env[TT][STATS][RETURNS] &&
627
- env[TT][STATS][RETURNS] !== UNKNOWN &&
628
- expectedArgs[i][TYPE] !==
629
- env[TT][STATS][RETURNS]
630
- )
579
+ if (
580
+ env[rest[i][VALUE]] &&
581
+ expectedArgs[i][TYPE] !== rest[i][TYPE]
582
+ ) {
583
+ switch (rest[i][TYPE]) {
584
+ case UNKNOWN:
585
+ env[first[VALUE]][STATS].type =
586
+ expectedArgs[i][TYPE]
587
+ break
588
+ case WORD:
589
+ const T = env[rest[i][VALUE]][STATS].type
590
+ if (Array.isArray(T)) {
591
+ const TT = T[VALUE]
592
+ if (
593
+ env[TT][STATS][RETURNS] &&
594
+ env[TT][STATS][RETURNS] !== UNKNOWN &&
595
+ expectedArgs[i][TYPE] !==
596
+ env[TT][STATS][RETURNS]
597
+ )
598
+ errorStack.set(
599
+ key.str,
600
+ `Incorrect type of arguments for special form (${
601
+ first[VALUE]
602
+ }). Expected (${toTypeNames(
603
+ expectedArgs[i][TYPE]
604
+ )}) but got (${toTypeNames(
605
+ rest[i][TYPE]
606
+ )}) (${stringifyArgs(exp)}) (check #2)`
607
+ )
608
+ } else if (
609
+ T !== UNKNOWN &&
610
+ expectedArgs[i][TYPE] !== UNKNOWN &&
611
+ expectedArgs[i][TYPE] !== T
612
+ ) {
631
613
  errorStack.set(
632
- key,
614
+ key.str,
633
615
  `Incorrect type of arguments for special form (${
634
616
  first[VALUE]
635
617
  }). Expected (${toTypeNames(
636
618
  expectedArgs[i][TYPE]
637
619
  )}) but got (${toTypeNames(
638
- rest[i][TYPE]
639
- )}) (${stringifyArgs(exp)}) (check #2)`
620
+ T
621
+ )}) (${stringifyArgs(exp)}) (check #3)`
640
622
  )
641
- } else if (
642
- T !== UNKNOWN &&
643
- expectedArgs[i][TYPE] !== UNKNOWN &&
644
- expectedArgs[i][TYPE] !== T
645
- ) {
623
+ } else {
624
+ env[rest[i][VALUE]][STATS].type =
625
+ expectedArgs[i][TYPE]
626
+ }
627
+ break
628
+ case APPLY:
629
+ case ATOM:
646
630
  errorStack.set(
647
- key,
648
- `Incorrect type of arguments for special form (${
631
+ key.str,
632
+ `Incorrect type of arguments for (${
649
633
  first[VALUE]
650
634
  }). Expected (${toTypeNames(
651
635
  expectedArgs[i][TYPE]
652
636
  )}) but got (${toTypeNames(
653
- T
654
- )}) (${stringifyArgs(exp)}) (check #3)`
637
+ rest[i][TYPE]
638
+ )}) (${stringifyArgs(exp)}) (check #5)`
655
639
  )
656
- } else {
657
- env[rest[i][VALUE]][STATS].type =
658
- expectedArgs[i][TYPE]
659
- }
660
- break
661
- case APPLY:
662
- case ATOM:
663
- errorStack.set(
664
- key,
665
- `Incorrect type of arguments for (${
666
- first[VALUE]
667
- }). Expected (${toTypeNames(
668
- expectedArgs[i][TYPE]
669
- )}) but got (${toTypeNames(
670
- rest[i][TYPE]
671
- )}) (${stringifyArgs(exp)}) (check #5)`
672
- )
673
- break
640
+ break
641
+ }
674
642
  }
675
643
  }
676
644
  }
677
- }
678
- // type checking
679
- else if (
680
- rest[i] &&
681
- args[i][STATS] &&
682
- rest[i][TYPE] !== args[i][STATS].type
683
- ) {
684
- if (isLeaf(rest[i])) {
685
- const T =
686
- rest[i][TYPE] === WORD && env[rest[i][VALUE]]
687
- ? env[rest[i][VALUE]][STATS].type
688
- : rest[i][TYPE]
689
- if (
690
- (args[i][STATS].type !== UNKNOWN &&
691
- T === ATOM &&
692
- args[i][STATS].type !== ATOM) ||
693
- (env[rest[i][VALUE]] &&
694
- env[rest[i][VALUE]][STATS].type !== UNKNOWN &&
695
- args[i][STATS].type !== UNKNOWN &&
696
- env[rest[i][VALUE]][STATS].type !==
697
- args[i][STATS].type)
645
+ // type checking
646
+ else if (
647
+ rest[i] &&
648
+ args[i][STATS] &&
649
+ rest[i][TYPE] !== args[i][STATS].type
650
+ ) {
651
+ if (isLeaf(rest[i])) {
652
+ const T =
653
+ rest[i][TYPE] === WORD && env[rest[i][VALUE]]
654
+ ? env[rest[i][VALUE]][STATS].type
655
+ : rest[i][TYPE]
656
+ if (
657
+ (args[i][STATS].type !== UNKNOWN &&
658
+ T === ATOM &&
659
+ args[i][STATS].type !== ATOM) ||
660
+ (env[rest[i][VALUE]] &&
661
+ env[rest[i][VALUE]][STATS].type !== UNKNOWN &&
662
+ args[i][STATS].type !== UNKNOWN &&
663
+ env[rest[i][VALUE]][STATS].type !==
664
+ args[i][STATS].type)
665
+ ) {
666
+ errorStack.set(
667
+ key.str,
668
+ `Incorrect type of arguments ${i} for (${
669
+ first[VALUE]
670
+ }). Expected (${toTypeNames(
671
+ args[i][STATS].type
672
+ )}) but got (${toTypeNames(
673
+ T
674
+ )}) (${stringifyArgs(exp)})`
675
+ )
676
+ } else {
677
+ // env[rest[i][VALUE]][STATS] THiss SHOULD BE
678
+ const retry = env[rest[i][VALUE]]
679
+ if (
680
+ retry &&
681
+ !retry.retried &&
682
+ args[i][STATS].type === UNKNOWN
683
+ ) {
684
+ retry.retried = true
685
+ stack.unshift(() => check(exp, env, scope))
686
+ }
687
+ // console.log(
688
+ // first[VALUE],
689
+ // env[first[VALUE]][STATS],
690
+ // rest[i][TYPE],
691
+ // args[i][STATS].type
692
+ // )
693
+ }
694
+ } else if (
695
+ rest[i].length &&
696
+ SPECIAL_FORMS_SET.has(rest[i][0][VALUE]) &&
697
+ env[rest[i][0][VALUE]] &&
698
+ env[rest[i][0][VALUE]][STATS][RETURNS] !==
699
+ UNKNOWN &&
700
+ args[i][STATS].type !== UNKNOWN &&
701
+ env[rest[i][0][VALUE]][STATS][RETURNS] !==
702
+ args[i][STATS].type
698
703
  ) {
699
704
  errorStack.set(
700
- key,
705
+ key.str,
701
706
  `Incorrect type of arguments ${i} for (${
702
707
  first[VALUE]
703
708
  }). Expected (${toTypeNames(
704
709
  args[i][STATS].type
705
- )}) but got (${toTypeNames(T)}) (${stringifyArgs(
706
- exp
707
- )})`
710
+ )}) but got (${toTypeNames(
711
+ env[rest[i][0][VALUE]][STATS][RETURNS]
712
+ )}) (${stringifyArgs(exp)}) (check #4)`
708
713
  )
709
714
  } else {
710
- // env[rest[i][VALUE]][STATS] THiss SHOULD BE
711
- const retry = env[rest[i][VALUE]]
712
715
  if (
713
- retry &&
714
- !retry.retried &&
715
- args[i][STATS].type === UNKNOWN
716
+ rest[i].length &&
717
+ env[rest[i][0][VALUE]] &&
718
+ args[i][STATS].type === UNKNOWN &&
719
+ !env[rest[i][0][VALUE]].retried
716
720
  ) {
717
- retry.retried = true
721
+ env[rest[i][0][VALUE]].retried = true
718
722
  if (!scope[SCOPE_NAME])
719
723
  scope[SCOPE_NAME] = scope[1][VALUE]
720
724
  stack.unshift(() => check(exp, env, scope))
721
725
  }
722
- // console.log(
723
- // first[VALUE],
724
- // env[first[VALUE]][STATS],
725
- // rest[i][TYPE],
726
- // args[i][STATS].type
727
- // )
728
- }
729
- } else if (
730
- rest[i].length &&
731
- SPECIAL_FORMS_SET.has(rest[i][0][VALUE]) &&
732
- env[rest[i][0][VALUE]] &&
733
- env[rest[i][0][VALUE]][STATS][RETURNS] !== UNKNOWN &&
734
- args[i][STATS].type !== UNKNOWN &&
735
- env[rest[i][0][VALUE]][STATS][RETURNS] !==
736
- args[i][STATS].type
737
- ) {
738
- errorStack.set(
739
- key,
740
- `Incorrect type of arguments ${i} for (${
741
- first[VALUE]
742
- }). Expected (${toTypeNames(
743
- args[i][STATS].type
744
- )}) but got (${toTypeNames(
745
- env[rest[i][0][VALUE]][STATS][RETURNS]
746
- )}) (${stringifyArgs(exp)})`
747
- )
748
- } else {
749
- if (
750
- rest[i].length &&
751
- env[rest[i][0][VALUE]] &&
752
- args[i][STATS].type === UNKNOWN &&
753
- !env[rest[i][0][VALUE]].retried
754
- ) {
755
- env[rest[i][0][VALUE]].retried = true
756
- if (!scope[SCOPE_NAME])
757
- scope[SCOPE_NAME] = scope[1][VALUE]
758
- stack.unshift(() => check(exp, env, scope))
759
726
  }
760
727
  }
761
728
  }
@@ -771,6 +738,7 @@ export const typeCheck = (ast) => {
771
738
  }
772
739
  }
773
740
  const copy = JSON.parse(JSON.stringify(ast))
741
+ copy[SCOPE_NAME] = 'root'
774
742
  check(copy, root, copy)
775
743
  while (stack.length) stack.pop()()
776
744
  if (errorStack.size)