conjure-js 0.0.11 → 0.0.13
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/dist-cli/conjure-js.mjs +9336 -5028
- package/dist-vite-plugin/index.mjs +10455 -0
- package/package.json +9 -2
- package/src/bin/cli.ts +2 -2
- package/src/bin/nrepl-symbol.ts +150 -0
- package/src/bin/nrepl.ts +301 -157
- package/src/bin/version.ts +1 -1
- package/src/clojure/core.clj +764 -29
- package/src/clojure/core.clj.d.ts +76 -4
- package/src/clojure/demo/math.clj +5 -1
- package/src/clojure/generated/builtin-namespace-registry.ts +4 -0
- package/src/clojure/generated/clojure-core-source.ts +765 -29
- package/src/clojure/generated/clojure-set-source.ts +136 -0
- package/src/clojure/generated/clojure-walk-source.ts +72 -0
- package/src/clojure/set.clj +132 -0
- package/src/clojure/set.clj.d.ts +20 -0
- package/src/clojure/string.clj.d.ts +14 -0
- package/src/clojure/walk.clj +68 -0
- package/src/clojure/walk.clj.d.ts +7 -0
- package/src/core/assertions.ts +114 -6
- package/src/core/bootstrap.ts +337 -0
- package/src/core/conversions.ts +48 -31
- package/src/core/core-module.ts +303 -0
- package/src/core/env.ts +42 -7
- package/src/core/errors.ts +8 -0
- package/src/core/evaluator/apply.ts +40 -25
- package/src/core/evaluator/arity.ts +8 -8
- package/src/core/evaluator/async-evaluator.ts +565 -0
- package/src/core/evaluator/collections.ts +30 -4
- package/src/core/evaluator/destructure.ts +180 -69
- package/src/core/evaluator/dispatch.ts +24 -14
- package/src/core/evaluator/evaluate.ts +22 -20
- package/src/core/evaluator/expand.ts +45 -15
- package/src/core/evaluator/form-parsers.ts +178 -0
- package/src/core/evaluator/index.ts +7 -9
- package/src/core/evaluator/js-interop.ts +189 -0
- package/src/core/evaluator/quasiquote.ts +14 -8
- package/src/core/evaluator/recur-check.ts +6 -6
- package/src/core/evaluator/special-forms.ts +380 -173
- package/src/core/factories.ts +182 -3
- package/src/core/index.ts +55 -5
- package/src/core/module.ts +136 -0
- package/src/core/ns-forms.ts +107 -0
- package/src/core/positions.ts +9 -2
- package/src/core/printer.ts +371 -11
- package/src/core/reader.ts +127 -29
- package/src/core/registry.ts +209 -0
- package/src/core/runtime.ts +376 -0
- package/src/core/session.ts +263 -478
- package/src/core/stdlib/arithmetic.ts +516 -215
- package/src/core/stdlib/async-fns.ts +132 -0
- package/src/core/stdlib/atoms.ts +286 -63
- package/src/core/stdlib/errors.ts +54 -50
- package/src/core/stdlib/hof.ts +74 -173
- package/src/core/stdlib/js-namespace.ts +344 -0
- package/src/core/stdlib/lazy.ts +34 -0
- package/src/core/stdlib/maps-sets.ts +322 -0
- package/src/core/stdlib/meta.ts +109 -28
- package/src/core/stdlib/predicates.ts +322 -196
- package/src/core/stdlib/regex.ts +126 -98
- package/src/core/stdlib/seq.ts +564 -0
- package/src/core/stdlib/strings.ts +164 -135
- package/src/core/stdlib/transducers.ts +95 -100
- package/src/core/stdlib/utils.ts +283 -147
- package/src/core/stdlib/vars.ts +27 -27
- package/src/core/stdlib/vectors.ts +122 -0
- package/src/core/tokenizer.ts +13 -3
- package/src/core/transformations.ts +117 -9
- package/src/core/types.ts +118 -6
- package/src/host/node-host-module.ts +74 -0
- package/src/nrepl/relay.ts +432 -0
- package/src/vite-plugin-clj/codegen.ts +87 -95
- package/src/vite-plugin-clj/index.ts +242 -18
- package/src/vite-plugin-clj/namespace-utils.ts +39 -0
- package/src/vite-plugin-clj/static-analysis.ts +211 -0
- package/src/clojure/demo.clj +0 -63
- package/src/clojure/demo.clj.d.ts +0 -0
- package/src/core/core-env.ts +0 -60
- package/src/core/stdlib/collections.ts +0 -784
- package/src/host/node.ts +0 -55
|
@@ -1,240 +1,366 @@
|
|
|
1
1
|
// Predicates & logical: nil?, true?, false?, truthy?, falsy?, not, not=,
|
|
2
2
|
// number?, string?, boolean?, vector?, list?, map?, keyword?, symbol?, fn?,
|
|
3
3
|
// coll?, some, every?
|
|
4
|
-
import {
|
|
5
|
-
isAFunction,
|
|
6
|
-
isCollection,
|
|
7
|
-
isEqual,
|
|
8
|
-
isFalsy,
|
|
9
|
-
isKeyword,
|
|
10
|
-
isSeqable,
|
|
11
|
-
isSymbol,
|
|
12
|
-
isTruthy,
|
|
13
|
-
isList,
|
|
14
|
-
isVector,
|
|
15
|
-
isMap,
|
|
16
|
-
} from '../assertions'
|
|
17
|
-
import { applyFunction } from '../evaluator'
|
|
4
|
+
import { is } from '../assertions'
|
|
18
5
|
import { EvaluationError } from '../errors'
|
|
19
|
-
import {
|
|
6
|
+
import { v } from '../factories'
|
|
20
7
|
import { printString } from '../printer'
|
|
21
8
|
import { toSeq } from '../transformations'
|
|
22
|
-
import type { CljValue } from '../types'
|
|
9
|
+
import type { CljNumber, CljValue, Env, EvaluationContext } from '../types'
|
|
23
10
|
|
|
24
11
|
export const predicateFunctions: Record<string, CljValue> = {
|
|
25
|
-
'nil?':
|
|
26
|
-
|
|
27
|
-
return
|
|
28
|
-
})
|
|
29
|
-
'Returns true if the value is nil, false otherwise.',
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
'true?': withDoc(
|
|
33
|
-
cljNativeFunction('true?', (arg: CljValue) => {
|
|
12
|
+
'nil?': v
|
|
13
|
+
.nativeFn('nil?', function nilPredImpl(arg: CljValue) {
|
|
14
|
+
return v.boolean(arg.kind === 'nil')
|
|
15
|
+
})
|
|
16
|
+
.doc('Returns true if the value is nil, false otherwise.', [['arg']]),
|
|
17
|
+
'true?': v
|
|
18
|
+
.nativeFn('true?', function truePredImpl(arg: CljValue) {
|
|
34
19
|
// returns true if the value is a boolean and true
|
|
35
20
|
if (arg.kind !== 'boolean') {
|
|
36
|
-
return
|
|
21
|
+
return v.boolean(false)
|
|
37
22
|
}
|
|
38
|
-
return
|
|
39
|
-
})
|
|
40
|
-
'Returns true if the value is a boolean and true, false otherwise.',
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
'false?':
|
|
44
|
-
|
|
23
|
+
return v.boolean(arg.value === true)
|
|
24
|
+
})
|
|
25
|
+
.doc('Returns true if the value is a boolean and true, false otherwise.', [
|
|
26
|
+
['arg'],
|
|
27
|
+
]),
|
|
28
|
+
'false?': v
|
|
29
|
+
.nativeFn('false?', function falsePredImpl(arg: CljValue) {
|
|
45
30
|
// returns true if the value is a boolean and false
|
|
46
31
|
if (arg.kind !== 'boolean') {
|
|
47
|
-
return
|
|
32
|
+
return v.boolean(false)
|
|
48
33
|
}
|
|
49
|
-
return
|
|
50
|
-
})
|
|
51
|
-
'Returns true if the value is a boolean and false, false otherwise.',
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
'truthy?':
|
|
55
|
-
|
|
56
|
-
return
|
|
57
|
-
})
|
|
58
|
-
'Returns true if the value is not nil or false, false otherwise.',
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
'falsy?':
|
|
62
|
-
|
|
63
|
-
return
|
|
64
|
-
})
|
|
65
|
-
'Returns true if the value is nil or false, false otherwise.',
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// return cljBoolean(!isTruthy(arg))
|
|
71
|
-
// }),
|
|
72
|
-
// 'Returns the negation of the truthiness of the value.',
|
|
73
|
-
// [['arg']]
|
|
74
|
-
// ),
|
|
75
|
-
'not=': withDoc(
|
|
76
|
-
cljNativeFunction('not=', (...vals: CljValue[]) => {
|
|
34
|
+
return v.boolean(arg.value === false)
|
|
35
|
+
})
|
|
36
|
+
.doc('Returns true if the value is a boolean and false, false otherwise.', [
|
|
37
|
+
['arg'],
|
|
38
|
+
]),
|
|
39
|
+
'truthy?': v
|
|
40
|
+
.nativeFn('truthy?', function truthyPredImpl(arg: CljValue) {
|
|
41
|
+
return v.boolean(is.truthy(arg))
|
|
42
|
+
})
|
|
43
|
+
.doc('Returns true if the value is not nil or false, false otherwise.', [
|
|
44
|
+
['arg'],
|
|
45
|
+
]),
|
|
46
|
+
'falsy?': v
|
|
47
|
+
.nativeFn('falsy?', function falsyPredImpl(arg: CljValue) {
|
|
48
|
+
return v.boolean(is.falsy(arg))
|
|
49
|
+
})
|
|
50
|
+
.doc('Returns true if the value is nil or false, false otherwise.', [
|
|
51
|
+
['arg'],
|
|
52
|
+
]),
|
|
53
|
+
'not=': v
|
|
54
|
+
.nativeFn('not=', function notEqualImpl(...vals: CljValue[]) {
|
|
77
55
|
if (vals.length < 2) {
|
|
78
56
|
throw new EvaluationError('not= expects at least two arguments', {
|
|
79
57
|
args: vals,
|
|
80
58
|
})
|
|
81
59
|
}
|
|
82
60
|
for (let i = 1; i < vals.length; i++) {
|
|
83
|
-
if (!
|
|
84
|
-
return
|
|
61
|
+
if (!is.equal(vals[i], vals[i - 1])) {
|
|
62
|
+
return v.boolean(true)
|
|
85
63
|
}
|
|
86
64
|
}
|
|
87
|
-
return
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
'number?': withDoc(
|
|
93
|
-
cljNativeFunction('number?', (x: CljValue) =>
|
|
94
|
-
cljBoolean(x !== undefined && x.kind === 'number')
|
|
65
|
+
return v.boolean(false)
|
|
66
|
+
})
|
|
67
|
+
.doc(
|
|
68
|
+
'Returns true if any two adjacent arguments are not equal, false otherwise.',
|
|
69
|
+
[['&', 'vals']]
|
|
95
70
|
),
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
71
|
+
'number?': v
|
|
72
|
+
.nativeFn('number?', function numberPredImpl(x: CljValue) {
|
|
73
|
+
return v.boolean(x !== undefined && x.kind === 'number')
|
|
74
|
+
})
|
|
75
|
+
.doc('Returns true if the value is a number, false otherwise.', [['x']]),
|
|
99
76
|
|
|
100
|
-
'string?':
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
)
|
|
104
|
-
'Returns true if the value is a string, false otherwise.',
|
|
105
|
-
[['x']]
|
|
106
|
-
),
|
|
77
|
+
'string?': v
|
|
78
|
+
.nativeFn('string?', function stringPredImpl(x: CljValue) {
|
|
79
|
+
return v.boolean(x !== undefined && is.string(x))
|
|
80
|
+
})
|
|
81
|
+
.doc('Returns true if the value is a string, false otherwise.', [['x']]),
|
|
107
82
|
|
|
108
|
-
'boolean?':
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
)
|
|
112
|
-
'Returns true if the value is a boolean, false otherwise.',
|
|
113
|
-
[['x']]
|
|
114
|
-
),
|
|
83
|
+
'boolean?': v
|
|
84
|
+
.nativeFn('boolean?', function booleanPredImpl(x: CljValue) {
|
|
85
|
+
return v.boolean(x !== undefined && x.kind === 'boolean')
|
|
86
|
+
})
|
|
87
|
+
.doc('Returns true if the value is a boolean, false otherwise.', [['x']]),
|
|
115
88
|
|
|
116
|
-
'vector?':
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
)
|
|
120
|
-
'Returns true if the value is a vector, false otherwise.',
|
|
121
|
-
[['x']]
|
|
122
|
-
),
|
|
89
|
+
'vector?': v
|
|
90
|
+
.nativeFn('vector?', function vectorPredImpl(x: CljValue) {
|
|
91
|
+
return v.boolean(x !== undefined && is.vector(x))
|
|
92
|
+
})
|
|
93
|
+
.doc('Returns true if the value is a vector, false otherwise.', [['x']]),
|
|
123
94
|
|
|
124
|
-
'list?':
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
)
|
|
128
|
-
'Returns true if the value is a list, false otherwise.',
|
|
129
|
-
[['x']]
|
|
130
|
-
),
|
|
95
|
+
'list?': v
|
|
96
|
+
.nativeFn('list?', function listPredImpl(x: CljValue) {
|
|
97
|
+
return v.boolean(x !== undefined && is.list(x))
|
|
98
|
+
})
|
|
99
|
+
.doc('Returns true if the value is a list, false otherwise.', [['x']]),
|
|
131
100
|
|
|
132
|
-
'map?':
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
)
|
|
136
|
-
'Returns true if the value is a map, false otherwise.',
|
|
137
|
-
[['x']]
|
|
138
|
-
),
|
|
101
|
+
'map?': v
|
|
102
|
+
.nativeFn('map?', function mapPredImpl(x: CljValue) {
|
|
103
|
+
return v.boolean(x !== undefined && is.map(x))
|
|
104
|
+
})
|
|
105
|
+
.doc('Returns true if the value is a map, false otherwise.', [['x']]),
|
|
139
106
|
|
|
140
|
-
'keyword?':
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
)
|
|
144
|
-
'Returns true if the value is a keyword, false otherwise.',
|
|
145
|
-
[['x']]
|
|
146
|
-
),
|
|
107
|
+
'keyword?': v
|
|
108
|
+
.nativeFn('keyword?', function keywordPredImpl(x: CljValue) {
|
|
109
|
+
return v.boolean(x !== undefined && is.keyword(x))
|
|
110
|
+
})
|
|
111
|
+
.doc('Returns true if the value is a keyword, false otherwise.', [['x']]),
|
|
147
112
|
|
|
148
|
-
'qualified-keyword?':
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
113
|
+
'qualified-keyword?': v
|
|
114
|
+
.nativeFn(
|
|
115
|
+
'qualified-keyword?',
|
|
116
|
+
function qualifiedKeywordPredImpl(x: CljValue) {
|
|
117
|
+
return v.boolean(
|
|
118
|
+
x !== undefined && is.keyword(x) && x.name.includes('/')
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
)
|
|
122
|
+
.doc('Returns true if the value is a qualified keyword, false otherwise.', [
|
|
123
|
+
['x'],
|
|
124
|
+
]),
|
|
155
125
|
|
|
156
|
-
'symbol?':
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
)
|
|
160
|
-
'Returns true if the value is a symbol, false otherwise.',
|
|
161
|
-
[['x']]
|
|
162
|
-
),
|
|
126
|
+
'symbol?': v
|
|
127
|
+
.nativeFn('symbol?', function symbolPredImpl(x: CljValue) {
|
|
128
|
+
return v.boolean(x !== undefined && is.symbol(x))
|
|
129
|
+
})
|
|
130
|
+
.doc('Returns true if the value is a symbol, false otherwise.', [['x']]),
|
|
163
131
|
|
|
164
|
-
'
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
)
|
|
168
|
-
'Returns true if
|
|
169
|
-
[['x']]
|
|
170
|
-
),
|
|
132
|
+
'namespace?': v
|
|
133
|
+
.nativeFn('namespace?', function namespaceQImpl(x: CljValue) {
|
|
134
|
+
return v.boolean(x !== undefined && x.kind === 'namespace')
|
|
135
|
+
})
|
|
136
|
+
.doc('Returns true if x is a namespace.', [['x']]),
|
|
171
137
|
|
|
172
|
-
'
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
),
|
|
179
|
-
|
|
180
|
-
'coll?': withDoc(
|
|
181
|
-
cljNativeFunction('coll?', (x: CljValue) =>
|
|
182
|
-
cljBoolean(x !== undefined && isCollection(x))
|
|
183
|
-
),
|
|
184
|
-
'Returns true if the value is a collection, false otherwise.',
|
|
185
|
-
[['x']]
|
|
186
|
-
),
|
|
187
|
-
some: withDoc(
|
|
188
|
-
cljNativeFunction('some', (pred: CljValue, coll: CljValue): CljValue => {
|
|
189
|
-
if (pred === undefined || !isAFunction(pred)) {
|
|
190
|
-
throw new EvaluationError(
|
|
191
|
-
`some expects a function as first argument${pred !== undefined ? `, got ${printString(pred)}` : ''}`,
|
|
192
|
-
{ pred }
|
|
138
|
+
'qualified-symbol?': v
|
|
139
|
+
.nativeFn(
|
|
140
|
+
'qualified-symbol?',
|
|
141
|
+
function qualifiedSymbolPredImpl(x: CljValue) {
|
|
142
|
+
return v.boolean(
|
|
143
|
+
x !== undefined && is.symbol(x) && x.name.includes('/')
|
|
193
144
|
)
|
|
194
145
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
146
|
+
)
|
|
147
|
+
.doc('Returns true if the value is a qualified symbol, false otherwise.', [
|
|
148
|
+
['x'],
|
|
149
|
+
]),
|
|
150
|
+
|
|
151
|
+
'fn?': v
|
|
152
|
+
.nativeFn('fn?', function fnPredImpl(x: CljValue) {
|
|
153
|
+
return v.boolean(x !== undefined && is.aFunction(x))
|
|
154
|
+
})
|
|
155
|
+
.doc('Returns true if the value is a function, false otherwise.', [['x']]),
|
|
156
|
+
|
|
157
|
+
'coll?': v
|
|
158
|
+
.nativeFn('coll?', function collPredImpl(x: CljValue) {
|
|
159
|
+
return v.boolean(x !== undefined && is.collection(x))
|
|
160
|
+
})
|
|
161
|
+
.doc('Returns true if the value is a collection, false otherwise.', [
|
|
162
|
+
['x'],
|
|
163
|
+
]),
|
|
164
|
+
some: v
|
|
165
|
+
.nativeFnCtx(
|
|
166
|
+
'some',
|
|
167
|
+
function someImpl(
|
|
168
|
+
ctx: EvaluationContext,
|
|
169
|
+
callEnv: Env,
|
|
170
|
+
pred: CljValue,
|
|
171
|
+
coll: CljValue
|
|
172
|
+
): CljValue {
|
|
173
|
+
if (pred === undefined || !is.aFunction(pred)) {
|
|
174
|
+
throw EvaluationError.atArg(
|
|
175
|
+
`some expects a function as first argument${pred !== undefined ? `, got ${printString(pred)}` : ''}`,
|
|
176
|
+
{ pred },
|
|
177
|
+
0
|
|
178
|
+
)
|
|
179
|
+
}
|
|
180
|
+
if (coll === undefined) {
|
|
181
|
+
return v.nil()
|
|
182
|
+
}
|
|
183
|
+
if (!is.seqable(coll)) {
|
|
184
|
+
throw EvaluationError.atArg(
|
|
185
|
+
`some expects a collection or string as second argument, got ${printString(coll)}`,
|
|
186
|
+
{ coll },
|
|
187
|
+
1
|
|
188
|
+
)
|
|
189
|
+
}
|
|
190
|
+
for (const item of toSeq(coll)) {
|
|
191
|
+
const result = ctx.applyFunction(pred, [item], callEnv)
|
|
192
|
+
if (is.truthy(result)) {
|
|
193
|
+
return result
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return v.nil()
|
|
203
197
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
198
|
+
)
|
|
199
|
+
.doc(
|
|
200
|
+
'Returns the first truthy result of applying pred to each item in coll, or nil if no item satisfies pred.',
|
|
201
|
+
[['pred', 'coll']]
|
|
202
|
+
),
|
|
203
|
+
|
|
204
|
+
'every?': v
|
|
205
|
+
.nativeFnCtx(
|
|
206
|
+
'every?',
|
|
207
|
+
function everyPredImpl(
|
|
208
|
+
ctx: EvaluationContext,
|
|
209
|
+
callEnv: Env,
|
|
210
|
+
pred: CljValue,
|
|
211
|
+
coll: CljValue
|
|
212
|
+
): CljValue {
|
|
213
|
+
if (pred === undefined || !is.aFunction(pred)) {
|
|
214
|
+
throw EvaluationError.atArg(
|
|
215
|
+
`every? expects a function as first argument${pred !== undefined ? `, got ${printString(pred)}` : ''}`,
|
|
216
|
+
{ pred },
|
|
217
|
+
0
|
|
218
|
+
)
|
|
208
219
|
}
|
|
220
|
+
if (coll === undefined || !is.seqable(coll)) {
|
|
221
|
+
throw EvaluationError.atArg(
|
|
222
|
+
`every? expects a collection or string as second argument${coll !== undefined ? `, got ${printString(coll)}` : ''}`,
|
|
223
|
+
{ coll },
|
|
224
|
+
1
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
for (const item of toSeq(coll)) {
|
|
228
|
+
if (is.falsy(ctx.applyFunction(pred, [item], callEnv))) {
|
|
229
|
+
return v.boolean(false)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return v.boolean(true)
|
|
209
233
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
`every? expects a function as first argument${pred !== undefined ? `, got ${printString(pred)}` : ''}`,
|
|
221
|
-
{ pred }
|
|
222
|
-
)
|
|
234
|
+
)
|
|
235
|
+
.doc('Returns true if all items in coll satisfy pred, false otherwise.', [
|
|
236
|
+
['pred', 'coll'],
|
|
237
|
+
]),
|
|
238
|
+
|
|
239
|
+
'identical?': v
|
|
240
|
+
.nativeFn(
|
|
241
|
+
'identical?',
|
|
242
|
+
function identicalPredImpl(x: CljValue, y: CljValue) {
|
|
243
|
+
return v.boolean(x === y)
|
|
223
244
|
}
|
|
224
|
-
|
|
245
|
+
)
|
|
246
|
+
.doc('Tests if 2 arguments are the same object (reference equality).', [
|
|
247
|
+
['x', 'y'],
|
|
248
|
+
]),
|
|
249
|
+
|
|
250
|
+
'seqable?': v
|
|
251
|
+
.nativeFn('seqable?', function seqablePredImpl(x: CljValue) {
|
|
252
|
+
return v.boolean(x !== undefined && is.seqable(x))
|
|
253
|
+
})
|
|
254
|
+
.doc('Return true if the seq function is supported for x.', [['x']]),
|
|
255
|
+
|
|
256
|
+
'sequential?': v
|
|
257
|
+
.nativeFn('sequential?', function sequentialPredImpl(x: CljValue) {
|
|
258
|
+
return v.boolean(x !== undefined && (is.list(x) || is.vector(x)))
|
|
259
|
+
})
|
|
260
|
+
.doc('Returns true if coll is a sequential collection (list or vector).', [
|
|
261
|
+
['coll'],
|
|
262
|
+
]),
|
|
263
|
+
|
|
264
|
+
'associative?': v
|
|
265
|
+
.nativeFn('associative?', function associativePredImpl(x: CljValue) {
|
|
266
|
+
return v.boolean(x !== undefined && (is.map(x) || is.vector(x)))
|
|
267
|
+
})
|
|
268
|
+
.doc('Returns true if coll implements Associative (map or vector).', [
|
|
269
|
+
['coll'],
|
|
270
|
+
]),
|
|
271
|
+
|
|
272
|
+
'counted?': v
|
|
273
|
+
.nativeFn('counted?', function countedPredImpl(x: CljValue) {
|
|
274
|
+
return v.boolean(
|
|
275
|
+
x !== undefined &&
|
|
276
|
+
(is.list(x) ||
|
|
277
|
+
is.vector(x) ||
|
|
278
|
+
is.map(x) ||
|
|
279
|
+
x.kind === 'set' ||
|
|
280
|
+
is.string(x))
|
|
281
|
+
)
|
|
282
|
+
})
|
|
283
|
+
.doc('Returns true if coll implements count in constant time.', [['coll']]),
|
|
284
|
+
|
|
285
|
+
'int?': v
|
|
286
|
+
.nativeFn('int?', function intPredImpl(x: CljValue) {
|
|
287
|
+
return v.boolean(
|
|
288
|
+
x !== undefined &&
|
|
289
|
+
x.kind === 'number' &&
|
|
290
|
+
Number.isInteger((x as import('../types').CljNumber).value)
|
|
291
|
+
)
|
|
292
|
+
})
|
|
293
|
+
.doc('Return true if x is a fixed precision integer.', [['x']]),
|
|
294
|
+
|
|
295
|
+
'double?': v
|
|
296
|
+
.nativeFn('double?', function doublePredImpl(x: CljValue) {
|
|
297
|
+
return v.boolean(x !== undefined && x.kind === 'number')
|
|
298
|
+
})
|
|
299
|
+
.doc('Return true if x is a Double (all numbers in JS are doubles).', [
|
|
300
|
+
['x'],
|
|
301
|
+
]),
|
|
302
|
+
|
|
303
|
+
'NaN?': v
|
|
304
|
+
.nativeFn('NaN?', function nanPredImpl(x: CljValue) {
|
|
305
|
+
return v.boolean(
|
|
306
|
+
x !== undefined && x.kind === 'number' && isNaN((x as CljNumber).value)
|
|
307
|
+
)
|
|
308
|
+
})
|
|
309
|
+
.doc('Returns true if num is NaN, else false.', [['num']]),
|
|
310
|
+
|
|
311
|
+
'infinite?': v
|
|
312
|
+
.nativeFn('infinite?', function infinitePredImpl(x: CljValue) {
|
|
313
|
+
return v.boolean(
|
|
314
|
+
x !== undefined &&
|
|
315
|
+
x.kind === 'number' &&
|
|
316
|
+
!isFinite((x as CljNumber).value)
|
|
317
|
+
)
|
|
318
|
+
})
|
|
319
|
+
.doc('Returns true if num is positive or negative infinity, else false.', [
|
|
320
|
+
['num'],
|
|
321
|
+
]),
|
|
322
|
+
|
|
323
|
+
compare: v
|
|
324
|
+
.nativeFn(
|
|
325
|
+
'compare',
|
|
326
|
+
function compareImpl(x: CljValue, y: CljValue): CljValue {
|
|
327
|
+
if (is.nil(x) && is.nil(y)) return v.number(0)
|
|
328
|
+
if (is.nil(x)) return v.number(-1)
|
|
329
|
+
if (is.nil(y)) return v.number(1)
|
|
330
|
+
if (is.number(x) && is.number(y)) {
|
|
331
|
+
return v.number(
|
|
332
|
+
(x as CljNumber).value < (y as CljNumber).value
|
|
333
|
+
? -1
|
|
334
|
+
: (x as CljNumber).value > (y as CljNumber).value
|
|
335
|
+
? 1
|
|
336
|
+
: 0
|
|
337
|
+
)
|
|
338
|
+
}
|
|
339
|
+
if (is.string(x) && is.string(y)) {
|
|
340
|
+
return v.number(x.value < y.value ? -1 : x.value > y.value ? 1 : 0)
|
|
341
|
+
}
|
|
342
|
+
if (is.keyword(x) && is.keyword(y)) {
|
|
343
|
+
return v.number(x.name < y.name ? -1 : x.name > y.name ? 1 : 0)
|
|
344
|
+
}
|
|
225
345
|
throw new EvaluationError(
|
|
226
|
-
`
|
|
227
|
-
{
|
|
346
|
+
`compare: cannot compare ${printString(x)} to ${printString(y)}`,
|
|
347
|
+
{ x, y }
|
|
228
348
|
)
|
|
229
349
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
350
|
+
)
|
|
351
|
+
.doc('Comparator. Returns a negative number, zero, or a positive number.', [
|
|
352
|
+
['x', 'y'],
|
|
353
|
+
]),
|
|
354
|
+
|
|
355
|
+
hash: v
|
|
356
|
+
.nativeFn('hash', function hashImpl(x: CljValue) {
|
|
357
|
+
// Simple hash — consistent within a session, not cryptographic
|
|
358
|
+
const s = printString(x)
|
|
359
|
+
let h = 0
|
|
360
|
+
for (let i = 0; i < s.length; i++) {
|
|
361
|
+
h = (Math.imul(31, h) + s.charCodeAt(i)) | 0
|
|
234
362
|
}
|
|
235
|
-
return
|
|
236
|
-
})
|
|
237
|
-
'Returns
|
|
238
|
-
[['pred', 'coll']]
|
|
239
|
-
),
|
|
363
|
+
return v.number(h)
|
|
364
|
+
})
|
|
365
|
+
.doc('Returns the hash code of its argument.', [['x']]),
|
|
240
366
|
}
|