conjure-js 0.0.12 → 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 +9360 -5298
- package/dist-vite-plugin/index.mjs +9463 -5185
- package/package.json +3 -1
- package/src/bin/cli.ts +2 -2
- package/src/bin/nrepl-symbol.ts +150 -0
- package/src/bin/nrepl.ts +289 -167
- package/src/bin/version.ts +1 -1
- package/src/clojure/core.clj +757 -29
- package/src/clojure/core.clj.d.ts +75 -131
- package/src/clojure/generated/builtin-namespace-registry.ts +4 -0
- package/src/clojure/generated/clojure-core-source.ts +758 -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 +20 -6
- 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 +28 -5
- package/src/core/evaluator/destructure.ts +180 -69
- package/src/core/evaluator/dispatch.ts +12 -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 +234 -191
- package/src/core/factories.ts +182 -3
- package/src/core/index.ts +54 -4
- package/src/core/module.ts +136 -0
- package/src/core/ns-forms.ts +107 -0
- package/src/core/printer.ts +371 -11
- package/src/core/reader.ts +84 -33
- package/src/core/registry.ts +209 -0
- package/src/core/runtime.ts +376 -0
- package/src/core/session.ts +253 -487
- package/src/core/stdlib/arithmetic.ts +528 -194
- package/src/core/stdlib/async-fns.ts +132 -0
- package/src/core/stdlib/atoms.ts +291 -56
- package/src/core/stdlib/errors.ts +54 -50
- package/src/core/stdlib/hof.ts +82 -166
- 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 +61 -30
- package/src/core/stdlib/predicates.ts +325 -187
- 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 +292 -130
- package/src/core/stdlib/vars.ts +27 -27
- package/src/core/stdlib/vectors.ts +122 -0
- package/src/core/tokenizer.ts +2 -2
- package/src/core/transformations.ts +117 -9
- package/src/core/types.ts +98 -2
- package/src/host/node-host-module.ts +74 -0
- package/src/{vite-plugin-clj/nrepl-relay.ts → nrepl/relay.ts} +72 -11
- package/src/vite-plugin-clj/codegen.ts +87 -95
- package/src/vite-plugin-clj/index.ts +178 -23
- 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 -72
- package/src/clojure/demo.clj.d.ts +0 -0
- package/src/core/core-env.ts +0 -61
- package/src/core/stdlib/collections.ts +0 -739
- package/src/host/node.ts +0 -55
|
@@ -1,228 +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
|
-
),
|
|
123
|
-
|
|
124
|
-
'list?': withDoc(
|
|
125
|
-
cljNativeFunction('list?', (x: CljValue) =>
|
|
126
|
-
cljBoolean(x !== undefined && isList(x))
|
|
127
|
-
),
|
|
128
|
-
'Returns true if the value is a list, false otherwise.',
|
|
129
|
-
[['x']]
|
|
130
|
-
),
|
|
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']]),
|
|
131
94
|
|
|
132
|
-
'
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
)
|
|
136
|
-
'Returns true if the value is a
|
|
137
|
-
[['x']]
|
|
138
|
-
),
|
|
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']]),
|
|
139
100
|
|
|
140
|
-
'
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
)
|
|
144
|
-
'Returns true if the value is a
|
|
145
|
-
[['x']]
|
|
146
|
-
),
|
|
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']]),
|
|
147
106
|
|
|
148
|
-
'
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
)
|
|
152
|
-
'Returns true if the value is a
|
|
153
|
-
[['x']]
|
|
154
|
-
),
|
|
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']]),
|
|
155
112
|
|
|
156
|
-
'
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
+
]),
|
|
163
125
|
|
|
164
|
-
'
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
)
|
|
168
|
-
'Returns true if the value is a
|
|
169
|
-
[['x']]
|
|
170
|
-
),
|
|
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']]),
|
|
171
131
|
|
|
172
|
-
'
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
)
|
|
176
|
-
'Returns true if
|
|
177
|
-
[['x']]
|
|
178
|
-
),
|
|
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']]),
|
|
179
137
|
|
|
180
|
-
'
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
some: withDoc(
|
|
188
|
-
cljNativeFunction('some', (pred: CljValue, coll: CljValue): CljValue => {
|
|
189
|
-
if (pred === undefined || !isAFunction(pred)) {
|
|
190
|
-
throw EvaluationError.atArg(`some expects a function as first argument${pred !== undefined ? `, got ${printString(pred)}` : ''}`, { pred }, 0)
|
|
191
|
-
}
|
|
192
|
-
if (coll === undefined) {
|
|
193
|
-
return cljNil()
|
|
194
|
-
}
|
|
195
|
-
if (!isSeqable(coll)) {
|
|
196
|
-
throw EvaluationError.atArg(`some expects a collection or string as second argument, got ${printString(coll)}`, { coll }, 1)
|
|
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('/')
|
|
144
|
+
)
|
|
197
145
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
+
}
|
|
202
195
|
}
|
|
196
|
+
return v.nil()
|
|
203
197
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
'every?':
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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
|
+
)
|
|
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)
|
|
214
233
|
}
|
|
215
|
-
|
|
216
|
-
|
|
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)
|
|
217
244
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
+
)
|
|
221
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
|
+
}
|
|
345
|
+
throw new EvaluationError(
|
|
346
|
+
`compare: cannot compare ${printString(x)} to ${printString(y)}`,
|
|
347
|
+
{ x, y }
|
|
348
|
+
)
|
|
349
|
+
}
|
|
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
|
|
222
362
|
}
|
|
223
|
-
return
|
|
224
|
-
})
|
|
225
|
-
'Returns
|
|
226
|
-
[['pred', 'coll']]
|
|
227
|
-
),
|
|
363
|
+
return v.number(h)
|
|
364
|
+
})
|
|
365
|
+
.doc('Returns the hash code of its argument.', [['x']]),
|
|
228
366
|
}
|