fez-lisp 1.5.108 → 1.5.110

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.108",
5
+ "version": "1.5.110",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -3,6 +3,9 @@ import {
3
3
  ATOM,
4
4
  FALSE,
5
5
  KEYWORDS,
6
+ MULTI_DIMENTIONAL_SETTERS,
7
+ MUTATION_SUFFIX,
8
+ MUTATORS_SET,
6
9
  PLACEHOLDER,
7
10
  PREDICATE_SUFFIX,
8
11
  PREDICATES_INPUT_SET,
@@ -35,7 +38,10 @@ import {
35
38
  formatType,
36
39
  ANONYMOUS_FUNCTION_TYPE_PREFIX,
37
40
  validateLambda,
38
- NIL
41
+ NIL,
42
+ TRUE_WORD,
43
+ FALSE_WORD,
44
+ BOOLEAN_SUBTYPE
39
45
  } from './types.js'
40
46
  import {
41
47
  Brr,
@@ -90,6 +96,15 @@ export const setPropToAtom = (stats, prop) => {
90
96
  (stats[prop][0] = ATOM)
91
97
  )
92
98
  }
99
+ export const setPropToPredicate = (stats, prop) => {
100
+ return (stats[prop][1] = BOOLEAN_SUBTYPE())
101
+ }
102
+ export const setReturnToPredicate = (stats) => {
103
+ return (stats[RETURNS][1] = BOOLEAN_SUBTYPE())
104
+ }
105
+ export const setTypeToPredicate = (stats) => {
106
+ return (stats[RETURNS][1] = BOOLEAN_SUBTYPE())
107
+ }
93
108
  export const setPropToAbstraction = (stats, prop) => {
94
109
  return (
95
110
  (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
@@ -100,14 +115,16 @@ export const setProp = (stats, prop, value) => {
100
115
  return (
101
116
  (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
102
117
  value[prop][0] !== UNKNOWN &&
103
- (stats[prop][0] = value[prop][0])
118
+ ((stats[prop][0] = value[prop][0]),
119
+ value[prop][1] && (stats[prop][1] = value[prop][1]))
104
120
  )
105
121
  }
106
122
  export const setPropToReturn = (stats, prop, value) => {
107
123
  return (
108
124
  (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
109
125
  value[RETURNS][0] !== UNKNOWN &&
110
- (stats[prop][0] = value[RETURNS][0])
126
+ ((stats[prop][0] = value[RETURNS][0]),
127
+ value[RETURNS][1] && (stats[prop][1] = value[RETURNS][1]))
111
128
  )
112
129
  }
113
130
  export const setPropToReturnRef = (stats, prop, value) => {
@@ -120,7 +137,8 @@ export const setPropToReturnRef = (stats, prop, value) => {
120
137
  export const setPropToType = (stats, prop, value) => {
121
138
  return (
122
139
  (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
123
- (stats[prop][0] = value[TYPE_PROP][0])
140
+ ((stats[prop][0] = value[TYPE_PROP][0]),
141
+ value[TYPE_PROP][1] && (stats[prop][1] = value[TYPE_PROP][1]))
124
142
  )
125
143
  }
126
144
  export const setPropToTypeRef = (stats, prop, value) => {
@@ -169,27 +187,33 @@ export const setReturn = (stats, value) => {
169
187
  return (
170
188
  isUnknownReturn(stats) &&
171
189
  !isUnknownReturn(value) &&
172
- (stats[RETURNS][0] = value[RETURNS][0])
190
+ ((stats[RETURNS][0] = value[RETURNS][0]),
191
+ value[RETURNS][1] && (stats[RETURNS][1] = value[RETURNS][1]))
173
192
  )
174
193
  }
175
194
  export const setType = (stats, value) =>
176
195
  (isUnknownType(stats) || isAnyType(stats)) &&
177
196
  !isUnknownType(value) &&
178
- (stats[TYPE_PROP][0] = value[TYPE_PROP][0])
197
+ ((stats[TYPE_PROP][0] = value[TYPE_PROP][0]),
198
+ value[TYPE_PROP][1] && (stats[TYPE_PROP][1] = value[TYPE_PROP][1]))
179
199
  export const setTypeToReturn = (stats, value) =>
180
200
  (isUnknownType(stats) || isAnyType(stats)) &&
181
201
  !isUnknownReturn(value) &&
182
- (stats[TYPE_PROP][0] = value[RETURNS][0])
202
+ ((stats[TYPE_PROP][0] = value[RETURNS][0]),
203
+ value[RETURNS][1] && (stats[TYPE_PROP][1] = value[RETURNS][1]))
183
204
  export const setReturnToType = (stats, value) =>
184
205
  (isUnknownReturn(stats) || isAnyReturn(stats)) &&
185
206
  !isUnknownType(value) &&
186
- (stats[RETURNS][0] = value[TYPE_PROP][0])
207
+ ((stats[RETURNS][0] = value[TYPE_PROP][0]),
208
+ value[TYPE_PROP][1] && (stats[RETURNS][1] = value[TYPE_PROP][1]))
187
209
  export const isAnyReturn = (stats) => stats && stats[RETURNS][0] === ANY
188
210
  export const isAnyType = (stats) => stats && stats[TYPE_PROP][0] === ANY
189
211
  export const isUnknownType = (stats) => stats && stats[TYPE_PROP][0] === UNKNOWN
190
212
  export const isUnknownReturn = (stats) => stats[RETURNS][0] === UNKNOWN
191
213
  export const getType = (stats) => stats && stats[TYPE_PROP][0]
214
+ export const getTypes = (stats) => stats && stats[TYPE_PROP]
192
215
  export const getReturn = (stats) => stats && stats[RETURNS][0]
216
+ export const getReturns = (stats) => stats && stats[RETURNS]
193
217
  export const isAtomType = (stats) =>
194
218
  isAnyType(stats) || stats[TYPE_PROP][0] === ATOM
195
219
  export const isAtomReturn = (stats) =>
@@ -200,59 +224,56 @@ export const compareReturns = (a, b) =>
200
224
  isAnyReturn(a) || isAnyReturn(b) || a[RETURNS][0] === b[RETURNS][0]
201
225
  export const compareTypeWithReturn = (a, b) =>
202
226
  isAnyType(a) || isAnyReturn(b) || a[TYPE_PROP][0] === b[RETURNS][0]
227
+ const IsPredicate = (leaf) =>
228
+ (leaf[TYPE] === ATOM && (leaf[VALUE] === TRUE || leaf[VALUE] === FALSE)) ||
229
+ (leaf[TYPE] === WORD &&
230
+ (leaf[VALUE] === TRUE_WORD ||
231
+ leaf[VALUE] === FALSE_WORD ||
232
+ leaf[VALUE] === NIL ||
233
+ getSuffix(leaf[VALUE]) === PREDICATE_SUFFIX)) ||
234
+ (leaf[TYPE] === APPLY &&
235
+ (PREDICATES_OUTPUT_SET.has(leaf[VALUE]) ||
236
+ getSuffix(leaf[VALUE]) === PREDICATE_SUFFIX))
203
237
  const checkPredicateName = (exp, rest) => {
204
238
  if (getSuffix(rest[0][VALUE]) === PREDICATE_SUFFIX) {
205
239
  const last = rest.at(-1)
206
- if (isLeaf(last)) {
207
- if (last[TYPE] === ATOM && last[VALUE] !== TRUE && last[VALUE] !== FALSE)
240
+ if (last[TYPE] !== APPLY && isLeaf(last) && !IsPredicate(last)) {
241
+ if (!IsPredicate(last))
208
242
  throw new TypeError(
209
- `Assigning predicate (ending in ?) variable (${
243
+ `Assigning predicate (ending in ?) variable (${
210
244
  rest[0][VALUE]
211
245
  }) to an (${
212
246
  STATIC_TYPES.ATOM
213
- }) that is not (or ${TRUE} ${FALSE}) (${stringifyArgs(exp)})`
214
- )
215
- else if (
216
- last[TYPE] === WORD &&
217
- getSuffix(last[VALUE]) !== PREDICATE_SUFFIX &&
218
- !PREDICATES_OUTPUT_SET.has(last[VALUE])
219
- )
220
- throw new TypeError(
221
- `Assigning predicate (ending in ?) variable (${
222
- rest[0][VALUE]
223
- }) to another variable which is not a predicate (also ending in ?) (${stringifyArgs(
247
+ }) that is not (or ${TRUE} ${FALSE}) or to another variable which is not a predicate (also ending in ?) or to a variable that is not (or true false nil) (${stringifyArgs(
224
248
  exp
225
- )})`
249
+ )}) (check #100)`
226
250
  )
227
251
  } else if (last[0][0] === APPLY) {
228
252
  const application = last[0]
229
- if (
230
- application[VALUE] !== KEYWORDS.IF &&
231
- getSuffix(application[VALUE]) !== PREDICATE_SUFFIX &&
232
- !PREDICATES_OUTPUT_SET.has(application[VALUE])
233
- )
253
+ if (application[VALUE] !== KEYWORDS.IF && !IsPredicate(application))
234
254
  throw new TypeError(
235
255
  `Assigning predicate (ending in ?) variable (${
236
256
  application[VALUE]
237
- }) to another variable which is not a predicate (also ending in ?) (${stringifyArgs(
257
+ }) to another variable which is not a predicate (also ending in ?) or to a variable that is not (or true false nil) (${stringifyArgs(
238
258
  exp
239
- )})`
259
+ )}) (check #101)`
240
260
  )
241
261
  }
262
+ return true
242
263
  }
264
+ return false
243
265
  }
244
266
  const checkPredicateNameDeep = (name, exp, rest, returns) => {
245
267
  if (returns[VALUE] === KEYWORDS.CALL_FUNCTION) {
246
268
  const fn = rest.at(-1).at(-1).at(-1)
247
- checkPredicateName(exp, [
269
+ return checkPredicateName(exp, [
248
270
  [WORD, name],
249
271
  isLeaf(fn)
250
272
  ? fn // when apply is a word (let x? (lambda (apply [] array:empty!)))
251
273
  : drillReturnType(fn, (r) => r[VALUE] === KEYWORDS.CALL_FUNCTION) // when apply is an annonymous lambda // (let fn? (lambda x (apply x (lambda x (array:empty! [])))))
252
274
  ])
253
- } else {
254
- checkPredicateName(exp, [[WORD, name], returns])
255
275
  }
276
+ return checkPredicateName(exp, [[WORD, name], returns])
256
277
  }
257
278
  const fillUknownArgs = (n) =>
258
279
  Array.from({ length: n })
@@ -408,31 +429,33 @@ const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
408
429
  if (returns[TYPE] === ATOM) {
409
430
  // ATOM ASSIGMENT
410
431
  setPropToAtom(env[name][STATS], prop)
411
- checkPredicateName(exp, [[WORD, name], returns])
412
432
  } else {
413
433
  switch (returns[VALUE]) {
414
434
  case KEYWORDS.IF:
415
435
  resolveCondition({ rem, name, env, exp, prop })
416
436
  break
417
437
  default:
418
- checkPredicateNameDeep(name, exp, exp.slice(1), returns)
419
- if (!env[returns[VALUE]]) return false
420
- else if (getType(env[returns[VALUE]][STATS]) === APPLY) {
421
- if (returns[TYPE] === WORD) setReturnToAbbstraction(env[name][STATS])
422
- else {
423
- // ALWAYS APPLY
424
- // rest.at(-1)[0][TYPE] === APPLY
425
- // Here is upon application to store the result in the variable
426
- if (isUnknownType(env[name][STATS]))
427
- stack.prepend(() => {
428
- setTypeToReturn(env[name][STATS], env[returns[VALUE]][STATS])
429
- // env[name][STATS][TYPE_PROP][0] =
430
- // env[returns[VALUE]][STATS][RETURNS][0]
431
- // this seems to be able to be deleted
432
- // env[name][STATS][TYPE_PROP][1] =
433
- // env[returns[VALUE]][STATS][RETURNS][1]
434
- })
435
- else setReturnRef(env[name][STATS], env[returns[VALUE]][STATS])
438
+ {
439
+ checkPredicateNameDeep(name, exp, exp.slice(1), returns)
440
+ if (!env[returns[VALUE]]) return false
441
+ else if (getType(env[returns[VALUE]][STATS]) === APPLY) {
442
+ if (returns[TYPE] === WORD)
443
+ setReturnToAbbstraction(env[name][STATS])
444
+ else {
445
+ // ALWAYS APPLY
446
+ // rest.at(-1)[0][TYPE] === APPLY
447
+ // Here is upon application to store the result in the variable
448
+ if (isUnknownType(env[name][STATS]))
449
+ stack.prepend(() => {
450
+ setTypeToReturn(env[name][STATS], env[returns[VALUE]][STATS])
451
+ // env[name][STATS][TYPE_PROP][0] =
452
+ // env[returns[VALUE]][STATS][RETURNS][0]
453
+ // this seems to be able to be deleted
454
+ // env[name][STATS][TYPE_PROP][1] =
455
+ // env[returns[VALUE]][STATS][RETURNS][1]
456
+ })
457
+ else setReturnRef(env[name][STATS], env[returns[VALUE]][STATS])
458
+ }
436
459
  }
437
460
  }
438
461
  break
@@ -570,16 +593,18 @@ export const typeCheck = (ast, error = true) => {
570
593
  retried: 0,
571
594
  counter: 0,
572
595
  [SIGNATURE]: name,
573
- [TYPE_PROP]: [
574
- isLeafNode
575
- ? right[TYPE]
576
- : env[right[VALUE]] == undefined
577
- ? UNKNOWN
578
- : env[right[VALUE]][STATS][RETURNS][0]
579
- ],
596
+ [TYPE_PROP]: [UNKNOWN],
580
597
  [RETURNS]: [UNKNOWN]
581
598
  }
582
599
  }
600
+ const type = isLeafNode
601
+ ? right[TYPE]
602
+ : env[right[VALUE]] == undefined
603
+ ? UNKNOWN
604
+ : env[right[VALUE]][STATS][RETURNS][0]
605
+ if (type !== UNKNOWN)
606
+ setTypeToReturn(env[name][STATS], env[right[VALUE]][STATS])
607
+
583
608
  const body = rightHand
584
609
  const rem = hasBlock(body) ? body.at(-1) : body
585
610
  const returns = isLeaf(rem) ? rem : rem[0]
@@ -628,10 +653,15 @@ export const typeCheck = (ast, error = true) => {
628
653
  const ref = env[copy[SCOPE_NAME]]
629
654
  if (!ref) continue
630
655
  ref[STATS][ARGUMENTS][i] = copy[param[VALUE]]
631
- const returns = deepLambdaReturn(
632
- hasBlock(exp) ? exp.at(-1) : exp,
633
- (result) => result[VALUE] !== KEYWORDS.IF
634
- )
656
+
657
+ // TODO overwrite return type check here
658
+ }
659
+ const returns = deepLambdaReturn(
660
+ hasBlock(exp) ? exp.at(-1) : exp,
661
+ (result) => result[VALUE] !== KEYWORDS.IF
662
+ )
663
+ const ref = env[copy[SCOPE_NAME]]
664
+ if (ref)
635
665
  if (isLeaf(returns))
636
666
  // TODO figure out what we do here
637
667
  // this here is a variable WORD
@@ -667,8 +697,6 @@ export const typeCheck = (ast, error = true) => {
667
697
  }
668
698
  })
669
699
  }
670
- // TODO overwrite return type check here
671
- }
672
700
  check(rest.at(-1), copy, copy)
673
701
  break
674
702
  case STATIC_TYPES.ABSTRACTION:
@@ -768,60 +796,6 @@ export const typeCheck = (ast, error = true) => {
768
796
  const MAIN_TYPE = getType(args[i][STATS])
769
797
  if (MAIN_TYPE === ANY) continue
770
798
  if (first[TYPE] === APPLY && isSpecial) {
771
- if (
772
- MAIN_TYPE === ATOM &&
773
- PREDICATES_INPUT_SET.has(first[VALUE])
774
- ) {
775
- if (
776
- !isRestILeaf &&
777
- rest[i][0][TYPE] === APPLY &&
778
- rest[i][0][VALUE] === KEYWORDS.CALL_FUNCTION
779
- ) {
780
- if (isLeaf(rest[i].at(-1))) {
781
- const fnName = rest[i].at(-1)[VALUE]
782
- const fn = env[fnName]
783
- if (fn && getReturn(fn[STATS]) !== ATOM)
784
- throw new TypeError(
785
- `Incorrect type of argument (${i}) for (${
786
- first[VALUE]
787
- }). Expected (${toTypeNames(
788
- ATOM
789
- )}) but got an (${toTypeNames(
790
- getReturn(fn[STATS])
791
- )}) (${stringifyArgs(exp)}) (check #26)`
792
- )
793
- } else {
794
- const body = rest[i].at(-1).at(-1)
795
- const rem = hasBlock(body) ? body.at(-1) : body
796
- const returns = isLeaf(rem) ? rem : rem[0]
797
- if (returns[TYPE] === ATOM) {
798
- if (MAIN_TYPE !== ATOM)
799
- throw new TypeError(
800
- `Incorrect type of argument ${i} for (${
801
- first[VALUE]
802
- }). Expected (${toTypeNames(
803
- MAIN_TYPE
804
- )}) but got an (${toTypeNames(
805
- ATOM
806
- )}) (${stringifyArgs(exp)}) (check #27)`
807
- )
808
- } else if (
809
- env[returns[VALUE]] &&
810
- !isUnknownReturn(env[returns[VALUE]][STATS]) &&
811
- getReturn(env[returns[VALUE]][STATS]) !== ATOM
812
- )
813
- throw new TypeError(
814
- `Incorrect type of argument ${i} for (${
815
- first[VALUE]
816
- }). Expected (${toTypeNames(
817
- ATOM
818
- )}) but got (${toTypeNames(
819
- getReturn(env[returns[VALUE]][STATS])
820
- )}) (${stringifyArgs(exp)}) (check #29)`
821
- )
822
- }
823
- }
824
- }
825
799
  const expectedArgs = env[first[VALUE]][STATS][ARGUMENTS]
826
800
  if (!isRestILeaf) {
827
801
  const name = rest[i][0][VALUE]
@@ -1207,6 +1181,48 @@ export const typeCheck = (ast, error = true) => {
1207
1181
  }
1208
1182
  match()
1209
1183
  }
1184
+
1185
+ // handly typehints for arrays
1186
+ if (
1187
+ first[TYPE] === APPLY &&
1188
+ MUTATORS_SET.has(first[VALUE]) &&
1189
+ env[first[VALUE]]
1190
+ ) {
1191
+ const current = env[rest[i][VALUE]]
1192
+ if (current) {
1193
+ if (rest[i][TYPE] === WORD) {
1194
+ if (!current[STATS][TYPE_PROP][1]) {
1195
+ current[STATS][TYPE_PROP][1] = new Set()
1196
+ }
1197
+ if (MULTI_DIMENTIONAL_SETTERS.has(first[VALUE])) {
1198
+ current[STATS][TYPE_PROP][1].add(COLLECTION)
1199
+ } else {
1200
+ const right = isLeaf(rest.at(-1))
1201
+ ? rest.at(-1)
1202
+ : rest.at(-1)[0]
1203
+ switch (right[TYPE]) {
1204
+ case ATOM:
1205
+ current[STATS][TYPE_PROP][1].add(ATOM)
1206
+ break
1207
+ case WORD:
1208
+ if (env[right[VALUE]]) {
1209
+ current[STATS][TYPE_PROP][1].add(
1210
+ ...env[right[VALUE]][STATS][TYPE_PROP]
1211
+ )
1212
+ }
1213
+ break
1214
+ case APPLY:
1215
+ if (env[right[VALUE]])
1216
+ current[STATS][TYPE_PROP][1].add(
1217
+ ...env[right[VALUE]][STATS][RETURNS]
1218
+ )
1219
+ break
1220
+ }
1221
+ }
1222
+ }
1223
+ }
1224
+ }
1225
+ // handly typehints for arrays
1210
1226
  }
1211
1227
  }
1212
1228
  })
package/src/compiler.js CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  STATIC_TYPES
10
10
  } from './keywords.js'
11
11
  import { leaf, isLeaf, AST } from './parser.js'
12
+ import { FALSE_WORD, TRUE_WORD } from './types.js'
12
13
  const deepRename = (name, newName, tree) => {
13
14
  if (!isLeaf(tree))
14
15
  for (const leaf of tree) {
@@ -40,6 +41,10 @@ const toCamelCase = (name) => {
40
41
  const dashToLodashes = (name) => name.replace(new RegExp(/-/g), '_')
41
42
  const keywordToHelper = (name) => {
42
43
  switch (name) {
44
+ case TRUE_WORD:
45
+ return '__true'
46
+ case FALSE_WORD:
47
+ return '__false'
43
48
  case KEYWORDS.ADDITION:
44
49
  return '__add'
45
50
  case KEYWORDS.MULTIPLICATION:
package/src/enchance.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  VALUE,
9
9
  WORD
10
10
  } from './keywords.js'
11
- import { getSuffix, shake, wrapInBlock } from './utils.js'
11
+ import { getPrefix, getSuffix, shake, wrapInBlock } from './utils.js'
12
12
  import std from '../lib/baked/std.js'
13
13
  export const OPTIMIZATIONS = {
14
14
  RECURSION: 'recursive',
@@ -47,7 +47,7 @@ export const enhance = (ast) => {
47
47
  last[0][VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
48
48
  ) {
49
49
  const name = exp[1][VALUE]
50
- const prefix = name.split(':')[0]
50
+ const prefix = getPrefix(name)
51
51
  if (prefix === OPTIMIZATIONS.RECURSION) {
52
52
  const args = last.slice(1, -1)
53
53
  const newName = `${OPTIMIZED_PREFIX}${name}::*${performance
package/src/keywords.js CHANGED
@@ -97,3 +97,34 @@ export const PREDICATES_OUTPUT_SET = new Set([
97
97
  KEYWORDS.IS_ATOM,
98
98
  KEYWORDS.IS_LAMBDA
99
99
  ])
100
+ export const MUTATORS_SET = new Set([
101
+ KEYWORDS.SET_ARRAY,
102
+ 'set:with!',
103
+ 'map:with!',
104
+ 'matrix:set!',
105
+ 'matrix:set-and-get!',
106
+ 'array:set-and-get!',
107
+ 'var:set-and-get!',
108
+ 'map:set-and-get!',
109
+ 'set:add-and-get!',
110
+ 'set:add!',
111
+ 'map:set!',
112
+ 'array:set!',
113
+ 'array:append!',
114
+ 'array:push!',
115
+ 'var:set!',
116
+ 'array:merge!',
117
+ 'list:merge!',
118
+ 'list:concat!'
119
+ ])
120
+ export const MULTI_DIMENTIONAL_SETTERS = new Set([
121
+ 'set:with!',
122
+ 'map:with!',
123
+ 'matrix:set!',
124
+ 'matrix:set-and-get!',
125
+ 'array:set-and-get!',
126
+ 'set:add!',
127
+ 'map:set!',
128
+ 'list:merge!',
129
+ 'list:concat!'
130
+ ])
package/src/macros.js CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  FALSE,
11
11
  KEYWORDS,
12
12
  PLACEHOLDER,
13
+ STATIC_TYPES,
13
14
  TRUE,
14
15
  TYPE,
15
16
  VALUE,
@@ -77,6 +78,14 @@ export const deSuggarAst = (ast, scope) => {
77
78
  // break
78
79
  case KEYWORDS.BLOCK:
79
80
  {
81
+ if (rest.length === 0)
82
+ throw new RangeError(
83
+ `Invalid number of arguments for (${
84
+ KEYWORDS.BLOCK
85
+ }), expected (>= 1) but got (0) (${
86
+ KEYWORDS.BLOCK
87
+ } ${stringifyArgs(rest)})`
88
+ )
80
89
  if (
81
90
  prev &&
82
91
  prev[TYPE] === APPLY &&
@@ -151,12 +160,10 @@ export const deSuggarAst = (ast, scope) => {
151
160
  let temp = exp
152
161
  for (let i = 0; i < rest.length; i += 2) {
153
162
  if (i === rest.length - 2) {
154
- temp.push(
155
- [APPLY, KEYWORDS.IF],
156
- rest[i],
157
- rest.at(-1),
158
- rest.at(-1)
159
- )
163
+ temp.push([APPLY, KEYWORDS.IF], rest[i], rest.at(-1), [
164
+ [APPLY, STATIC_TYPES.ANY],
165
+ [WORD, NIL]
166
+ ])
160
167
  } else {
161
168
  temp.push([APPLY, KEYWORDS.IF], rest[i], rest[i + 1], [])
162
169
  temp = temp.at(-1)
@@ -239,8 +246,9 @@ export const deSuggarAst = (ast, scope) => {
239
246
  break
240
247
  case KEYWORDS.MULTIPLICATION:
241
248
  if (!rest.length) {
242
- exp[0][TYPE] = ATOM
243
- exp[0][VALUE] = TRUE
249
+ // exp[0][TYPE] = ATOM
250
+ exp[0][VALUE] = KEYWORDS.NOT
251
+ exp[1] = [ATOM, FALSE]
244
252
  } else if (rest.length > 2) {
245
253
  exp.length = 0
246
254
  let temp = exp