conjure-js 0.0.13 → 0.0.14
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 +2328 -2089
- package/dist-vite-plugin/index.mjs +2327 -2088
- package/package.json +1 -1
- package/src/bin/version.ts +1 -1
- package/src/core/assertions.ts +10 -3
- package/src/core/bootstrap.ts +7 -23
- package/src/core/compiler/binding.ts +164 -0
- package/src/core/compiler/callable.ts +41 -0
- package/src/core/compiler/compile-env.ts +40 -0
- package/src/core/compiler/control-flow.ts +79 -0
- package/src/core/compiler/index.ts +121 -0
- package/src/core/env.ts +4 -4
- package/src/core/errors.ts +1 -0
- package/src/core/evaluator/apply.ts +7 -3
- package/src/core/evaluator/arity.ts +16 -6
- package/src/core/evaluator/async-evaluator.ts +68 -89
- package/src/core/evaluator/collections.ts +9 -4
- package/src/core/evaluator/destructure.ts +45 -55
- package/src/core/evaluator/dispatch.ts +21 -24
- package/src/core/evaluator/evaluate.ts +14 -2
- package/src/core/evaluator/expand.ts +5 -7
- package/src/core/evaluator/js-interop.ts +46 -33
- package/src/core/evaluator/quasiquote.ts +7 -11
- package/src/core/evaluator/recur-check.ts +1 -1
- package/src/core/evaluator/special-forms.ts +18 -38
- package/src/core/index.ts +1 -1
- package/src/core/keywords.ts +105 -0
- package/src/core/modules/core/index.ts +131 -0
- package/src/core/{stdlib → modules/core/stdlib}/arithmetic.ts +6 -6
- package/src/core/{stdlib → modules/core/stdlib}/async-fns.ts +6 -6
- package/src/core/{stdlib → modules/core/stdlib}/atoms.ts +7 -7
- package/src/core/{stdlib → modules/core/stdlib}/errors.ts +4 -4
- package/src/core/{stdlib → modules/core/stdlib}/hof.ts +6 -6
- package/src/core/{stdlib → modules/core/stdlib}/lazy.ts +4 -4
- package/src/core/{stdlib → modules/core/stdlib}/maps-sets.ts +6 -6
- package/src/core/{stdlib → modules/core/stdlib}/meta.ts +5 -5
- package/src/core/{stdlib → modules/core/stdlib}/predicates.ts +7 -7
- package/src/core/modules/core/stdlib/print.ts +108 -0
- package/src/core/{stdlib → modules/core/stdlib}/regex.ts +5 -5
- package/src/core/{stdlib → modules/core/stdlib}/seq.ts +7 -7
- package/src/core/{stdlib → modules/core/stdlib}/strings.ts +6 -6
- package/src/core/{stdlib → modules/core/stdlib}/transducers.ts +6 -6
- package/src/core/{stdlib → modules/core/stdlib}/utils.ts +10 -10
- package/src/core/{stdlib → modules/core/stdlib}/vars.ts +4 -4
- package/src/core/{stdlib → modules/core/stdlib}/vectors.ts +6 -6
- package/src/core/modules/js/index.ts +402 -0
- package/src/core/ns-forms.ts +25 -17
- package/src/core/positions.ts +22 -2
- package/src/core/printer.ts +162 -53
- package/src/core/reader.ts +25 -22
- package/src/core/registry.ts +10 -10
- package/src/core/runtime.ts +23 -23
- package/src/core/session.ts +17 -7
- package/src/core/tokenizer.ts +14 -4
- package/src/core/transformations.ts +48 -29
- package/src/core/types.ts +57 -81
- package/src/core/core-module.ts +0 -303
- package/src/core/stdlib/js-namespace.ts +0 -344
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
RuntimeModule,
|
|
3
|
+
VarDeclaration,
|
|
4
|
+
VarMap,
|
|
5
|
+
ModuleContext,
|
|
6
|
+
} from '../../module'
|
|
7
|
+
import type { CljMap } from '../../types'
|
|
8
|
+
import { arithmeticFunctions } from './stdlib/arithmetic'
|
|
9
|
+
import { atomFunctions } from './stdlib/atoms'
|
|
10
|
+
import { mapsSetsFunctions } from './stdlib/maps-sets'
|
|
11
|
+
import { seqFunctions } from './stdlib/seq'
|
|
12
|
+
import { vectorFunctions } from './stdlib/vectors'
|
|
13
|
+
import { errorFunctions } from './stdlib/errors'
|
|
14
|
+
import { hofFunctions } from './stdlib/hof'
|
|
15
|
+
import { metaFunctions } from './stdlib/meta'
|
|
16
|
+
import { predicateFunctions } from './stdlib/predicates'
|
|
17
|
+
import { regexFunctions } from './stdlib/regex'
|
|
18
|
+
import { stringFunctions } from './stdlib/strings'
|
|
19
|
+
import { transducerFunctions } from './stdlib/transducers'
|
|
20
|
+
import { utilFunctions } from './stdlib/utils'
|
|
21
|
+
import { lazyFunctions } from './stdlib/lazy'
|
|
22
|
+
import { varFunctions } from './stdlib/vars'
|
|
23
|
+
// --- ASYNC (experimental) ---
|
|
24
|
+
import { asyncFunctions } from './stdlib/async-fns'
|
|
25
|
+
import { printFunctions, printVars } from './stdlib/print'
|
|
26
|
+
// --- END ASYNC ---
|
|
27
|
+
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Native function registry — installed as the initial clojure.core binding
|
|
30
|
+
// set by createRuntime.
|
|
31
|
+
//
|
|
32
|
+
// INTENTIONAL BOOTSTRAP OVERRIDES:
|
|
33
|
+
// Several functions below are redefined by clojure.core.clj after bootstrap.
|
|
34
|
+
// They serve as scaffolding during the bootstrap phase only. The Clojure
|
|
35
|
+
// source versions (lazy / transducer-aware) become authoritative once loaded.
|
|
36
|
+
// Overridden by clojure.core.clj:
|
|
37
|
+
// concat → lazy recursive version (shadows eager native)
|
|
38
|
+
// map → lazy + transducer 2-arity
|
|
39
|
+
// filter → lazy + transducer 2-arity
|
|
40
|
+
// take → lazy + stateful transducer
|
|
41
|
+
// drop → lazy + stateful transducer
|
|
42
|
+
// take-while → lazy + stateless transducer
|
|
43
|
+
// drop-while → lazy + stateful transducer
|
|
44
|
+
// map-indexed → lazy + stateful transducer
|
|
45
|
+
// keep → lazy + transducer
|
|
46
|
+
// keep-indexed→ lazy + stateful transducer
|
|
47
|
+
// mapcat → lazy + transducer
|
|
48
|
+
// partition-by→ lazy + stateful transducer
|
|
49
|
+
// iterate → lazy infinite sequence
|
|
50
|
+
// repeatedly → lazy infinite sequence
|
|
51
|
+
// cycle → lazy infinite sequence
|
|
52
|
+
// repeat → lazy infinite (delegates to repeat* for finite arity)
|
|
53
|
+
// range → lazy infinite (delegates to range* for finite arity)
|
|
54
|
+
// into → 2-arity uses reduce+conj; 3-arity uses transduce
|
|
55
|
+
// sequence → materialise via into
|
|
56
|
+
// completing → 0-arity init + 1-arity completion wrapper
|
|
57
|
+
// newline → redefined as (defn newline [] (println ""))
|
|
58
|
+
// not → redefined as pure Clojure (if x false true)
|
|
59
|
+
// dorun → redefined in Clojure
|
|
60
|
+
// doall → redefined in Clojure
|
|
61
|
+
//
|
|
62
|
+
// Dynamic vars declared here (NOT overridden by clojure.core.clj):
|
|
63
|
+
// *out* → nil by default; bound by with-out-str to capture stdout
|
|
64
|
+
// *err* → nil by default; bound by with-err-str to capture stderr
|
|
65
|
+
// *print-length*, *print-level* → print control
|
|
66
|
+
//
|
|
67
|
+
// range* and repeat* are intentionally kept — clojure.core.clj calls them
|
|
68
|
+
// explicitly as private native helpers for finite-arity range/repeat.
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
const nativeFunctions = {
|
|
72
|
+
...arithmeticFunctions,
|
|
73
|
+
...atomFunctions,
|
|
74
|
+
...seqFunctions,
|
|
75
|
+
...vectorFunctions,
|
|
76
|
+
...mapsSetsFunctions,
|
|
77
|
+
...errorFunctions,
|
|
78
|
+
...predicateFunctions,
|
|
79
|
+
...hofFunctions,
|
|
80
|
+
...metaFunctions,
|
|
81
|
+
...transducerFunctions,
|
|
82
|
+
...regexFunctions,
|
|
83
|
+
...stringFunctions,
|
|
84
|
+
...utilFunctions,
|
|
85
|
+
...varFunctions,
|
|
86
|
+
...lazyFunctions,
|
|
87
|
+
...printFunctions,
|
|
88
|
+
// --- ASYNC (experimental) ---
|
|
89
|
+
...asyncFunctions,
|
|
90
|
+
// --- END ASYNC ---
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const nativeDynamicVars = {
|
|
94
|
+
...printVars,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Returns the full clojure.core RuntimeModule.
|
|
99
|
+
*
|
|
100
|
+
* IO functions (println, print, newline, pr, prn, pprint) read ctx.io.stdout
|
|
101
|
+
* at call time instead of closing over an emit callback. This means:
|
|
102
|
+
* - No output parameter needed here
|
|
103
|
+
* - Snapshot clones automatically use the correct output without reinstalling
|
|
104
|
+
* any IO vars (restoreRuntime no longer needs makeIOModule)
|
|
105
|
+
*/
|
|
106
|
+
export function makeCoreModule(): RuntimeModule {
|
|
107
|
+
return {
|
|
108
|
+
id: 'clojure/core',
|
|
109
|
+
declareNs: [
|
|
110
|
+
{
|
|
111
|
+
name: 'clojure.core',
|
|
112
|
+
vars(_ctx: ModuleContext): VarMap {
|
|
113
|
+
const map = new Map<string, VarDeclaration>()
|
|
114
|
+
|
|
115
|
+
// Pure stdlib functions (all have .meta via .doc())
|
|
116
|
+
for (const [name, fn] of Object.entries(nativeFunctions)) {
|
|
117
|
+
const meta = (fn as { meta?: CljMap }).meta
|
|
118
|
+
map.set(name, { value: fn, ...(meta ? { meta } : {}) })
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Dynamic vars
|
|
122
|
+
for (const [name, value] of Object.entries(nativeDynamicVars)) {
|
|
123
|
+
map.set(name, { value, dynamic: true })
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return map
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { is } from '
|
|
2
|
-
import { EvaluationError } from '
|
|
3
|
-
import { v } from '
|
|
4
|
-
import { printString } from '
|
|
5
|
-
import { toSeq } from '
|
|
6
|
-
import type { CljList, CljNumber, CljValue, CljVector } from '
|
|
1
|
+
import { is } from '../../../assertions'
|
|
2
|
+
import { EvaluationError } from '../../../errors'
|
|
3
|
+
import { v } from '../../../factories'
|
|
4
|
+
import { printString } from '../../../printer'
|
|
5
|
+
import { toSeq } from '../../../transformations'
|
|
6
|
+
import type { CljList, CljNumber, CljValue, CljVector } from '../../../types'
|
|
7
7
|
|
|
8
8
|
export const arithmeticFunctions: Record<string, CljValue> = {
|
|
9
9
|
'+': v
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* To revert: delete this file and remove the import from core-module.ts.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { v } from '
|
|
8
|
-
import { CljThrownSignal, EvaluationError } from '
|
|
9
|
-
import { is } from '
|
|
10
|
-
import { printString } from '
|
|
11
|
-
import { toSeq } from '
|
|
12
|
-
import type { EvaluationContext, CljValue, Env } from '
|
|
7
|
+
import { v } from '../../../factories'
|
|
8
|
+
import { CljThrownSignal, EvaluationError } from '../../../errors'
|
|
9
|
+
import { is } from '../../../assertions'
|
|
10
|
+
import { printString } from '../../../printer'
|
|
11
|
+
import { toSeq } from '../../../transformations'
|
|
12
|
+
import type { EvaluationContext, CljValue, Env } from '../../../types'
|
|
13
13
|
|
|
14
14
|
export const asyncFunctions: Record<string, CljValue> = {
|
|
15
15
|
// (then val f) — apply f when resolved, or immediately if val is not pending
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { is } from '
|
|
2
|
-
import { EvaluationError } from '
|
|
3
|
-
import { v } from '
|
|
4
|
-
import { printString } from '
|
|
5
|
-
import { realizeDelay } from '
|
|
1
|
+
import { is } from '../../../assertions'
|
|
2
|
+
import { EvaluationError } from '../../../errors'
|
|
3
|
+
import { v } from '../../../factories'
|
|
4
|
+
import { printString } from '../../../printer'
|
|
5
|
+
import { realizeDelay } from '../../../transformations'
|
|
6
6
|
import type {
|
|
7
7
|
CljAtom,
|
|
8
8
|
CljFunction,
|
|
9
9
|
CljNativeFunction,
|
|
10
10
|
CljValue,
|
|
11
11
|
Env,
|
|
12
|
-
} from '
|
|
12
|
+
} from '../../../types'
|
|
13
13
|
|
|
14
14
|
function validateAtom(
|
|
15
15
|
a: CljAtom,
|
|
16
16
|
newVal: CljValue,
|
|
17
|
-
ctx: import('
|
|
17
|
+
ctx: import('../../../types').EvaluationContext,
|
|
18
18
|
callEnv: Env
|
|
19
19
|
) {
|
|
20
20
|
if (a.validator && is.aFunction(a.validator)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { CljThrownSignal, EvaluationError } from '
|
|
2
|
-
import { v } from '
|
|
3
|
-
import { is } from '
|
|
4
|
-
import type { CljValue } from '
|
|
1
|
+
import { CljThrownSignal, EvaluationError } from '../../../errors'
|
|
2
|
+
import { v } from '../../../factories'
|
|
3
|
+
import { is } from '../../../assertions'
|
|
4
|
+
import type { CljValue } from '../../../types'
|
|
5
5
|
|
|
6
6
|
export const errorFunctions = {
|
|
7
7
|
throw: v
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Higher-order functions: map, filter, reduce, apply, partial, comp,
|
|
2
2
|
// map-indexed, identity
|
|
3
|
-
import { is } from '
|
|
4
|
-
import { EvaluationError } from '
|
|
5
|
-
import { v } from '
|
|
6
|
-
import { printString } from '
|
|
7
|
-
import { toSeq } from '
|
|
8
|
-
import type { CljValue, Env, EvaluationContext } from '
|
|
3
|
+
import { is } from '../../../assertions'
|
|
4
|
+
import { EvaluationError } from '../../../errors'
|
|
5
|
+
import { v } from '../../../factories'
|
|
6
|
+
import { printString } from '../../../printer'
|
|
7
|
+
import { toSeq } from '../../../transformations'
|
|
8
|
+
import type { CljValue, Env, EvaluationContext } from '../../../types'
|
|
9
9
|
|
|
10
10
|
export const hofFunctions: Record<string, CljValue> = {
|
|
11
11
|
reduce: v
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { is } from '
|
|
2
|
-
import { v } from '
|
|
3
|
-
import { realizeDelay, realizeLazySeq } from '
|
|
4
|
-
import type { CljValue } from '
|
|
1
|
+
import { is } from '../../../assertions'
|
|
2
|
+
import { v } from '../../../factories'
|
|
3
|
+
import { realizeDelay, realizeLazySeq } from '../../../transformations'
|
|
4
|
+
import type { CljValue } from '../../../types'
|
|
5
5
|
|
|
6
6
|
export const lazyFunctions = {
|
|
7
7
|
force: v
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
// here because their primary semantic is associative (key→value update/remove);
|
|
6
6
|
// the vector branch is an edge case within the same dispatch.
|
|
7
7
|
|
|
8
|
-
import { is } from '
|
|
9
|
-
import { EvaluationError } from '
|
|
10
|
-
import { v } from '
|
|
11
|
-
import { printString } from '
|
|
12
|
-
import { toSeq } from '
|
|
13
|
-
import { type CljNumber, type CljValue } from '
|
|
8
|
+
import { is } from '../../../assertions'
|
|
9
|
+
import { EvaluationError } from '../../../errors'
|
|
10
|
+
import { v } from '../../../factories'
|
|
11
|
+
import { printString } from '../../../printer'
|
|
12
|
+
import { toSeq } from '../../../transformations'
|
|
13
|
+
import { type CljNumber, type CljValue } from '../../../types'
|
|
14
14
|
|
|
15
15
|
export const mapsSetsFunctions: Record<string, CljValue> = {
|
|
16
16
|
'hash-map': v
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// Metadata: with-meta, meta, alter-meta!
|
|
2
|
-
import { is } from '
|
|
3
|
-
import { EvaluationError } from '
|
|
4
|
-
import { v } from '
|
|
5
|
-
import { printString } from '
|
|
2
|
+
import { is } from '../../../assertions'
|
|
3
|
+
import { EvaluationError } from '../../../errors'
|
|
4
|
+
import { v } from '../../../factories'
|
|
5
|
+
import { printString } from '../../../printer'
|
|
6
6
|
import type {
|
|
7
7
|
CljAtom,
|
|
8
8
|
CljMap,
|
|
9
9
|
CljValue,
|
|
10
10
|
Env,
|
|
11
11
|
EvaluationContext,
|
|
12
|
-
} from '
|
|
12
|
+
} from '../../../types'
|
|
13
13
|
|
|
14
14
|
export const metaFunctions: Record<string, CljValue> = {
|
|
15
15
|
meta: v
|
|
@@ -1,12 +1,12 @@
|
|
|
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 { is } from '
|
|
5
|
-
import { EvaluationError } from '
|
|
6
|
-
import { v } from '
|
|
7
|
-
import { printString } from '
|
|
8
|
-
import { toSeq } from '
|
|
9
|
-
import type { CljNumber, CljValue, Env, EvaluationContext } from '
|
|
4
|
+
import { is } from '../../../assertions'
|
|
5
|
+
import { EvaluationError } from '../../../errors'
|
|
6
|
+
import { v } from '../../../factories'
|
|
7
|
+
import { printString } from '../../../printer'
|
|
8
|
+
import { toSeq } from '../../../transformations'
|
|
9
|
+
import type { CljNumber, CljValue, Env, EvaluationContext } from '../../../types'
|
|
10
10
|
|
|
11
11
|
export const predicateFunctions: Record<string, CljValue> = {
|
|
12
12
|
'nil?': v
|
|
@@ -287,7 +287,7 @@ export const predicateFunctions: Record<string, CljValue> = {
|
|
|
287
287
|
return v.boolean(
|
|
288
288
|
x !== undefined &&
|
|
289
289
|
x.kind === 'number' &&
|
|
290
|
-
Number.isInteger((x as import('
|
|
290
|
+
Number.isInteger((x as import('../../../types').CljNumber).value)
|
|
291
291
|
)
|
|
292
292
|
})
|
|
293
293
|
.doc('Return true if x is a fixed precision integer.', [['x']]),
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { derefValue } from '../../../env'
|
|
2
|
+
import { v } from '../../../factories'
|
|
3
|
+
import {
|
|
4
|
+
buildPrintContext,
|
|
5
|
+
prettyPrintString,
|
|
6
|
+
printString,
|
|
7
|
+
withPrintContext,
|
|
8
|
+
} from '../../../printer'
|
|
9
|
+
import { valueToString } from '../../../transformations'
|
|
10
|
+
import type { CljValue, Env, EvaluationContext } from '../../../types'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Emit text to the current output channel.
|
|
14
|
+
* If *out* is dynamically bound to a callable (e.g. inside with-out-str),
|
|
15
|
+
* invoke it. Otherwise fall back to ctx.io.stdout.
|
|
16
|
+
*
|
|
17
|
+
* NOTE: We look up *out* via ctx.resolveNs('clojure.core') rather than
|
|
18
|
+
* tryLookup(callEnv) because Clojure functions close over the original
|
|
19
|
+
* snapshot env. After a snapshot restore, those closure envs point to the
|
|
20
|
+
* old CljVar objects, not the session's freshly cloned ones. resolveNs goes
|
|
21
|
+
* through the runtime registry and always returns the session's own var.
|
|
22
|
+
*/
|
|
23
|
+
function emitToOut(ctx: EvaluationContext, callEnv: Env, text: string): void {
|
|
24
|
+
const outVar = ctx.resolveNs('clojure.core')?.vars.get('*out*')
|
|
25
|
+
const out = outVar ? derefValue(outVar) : undefined
|
|
26
|
+
if (out && (out.kind === 'function' || out.kind === 'native-function')) {
|
|
27
|
+
ctx.applyCallable(out, [v.string(text)], callEnv)
|
|
28
|
+
} else {
|
|
29
|
+
ctx.io.stdout(text)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Emit text to the current error channel.
|
|
35
|
+
* If *err* is dynamically bound to a callable (e.g. inside with-err-str),
|
|
36
|
+
* invoke it. Otherwise fall back to ctx.io.stderr.
|
|
37
|
+
* Same snapshot-env rationale as emitToOut.
|
|
38
|
+
*/
|
|
39
|
+
function emitToErr(ctx: EvaluationContext, callEnv: Env, text: string): void {
|
|
40
|
+
const errVar = ctx.resolveNs('clojure.core')?.vars.get('*err*')
|
|
41
|
+
const err = errVar ? derefValue(errVar) : undefined
|
|
42
|
+
if (err && (err.kind === 'function' || err.kind === 'native-function')) {
|
|
43
|
+
ctx.applyCallable(err, [v.string(text)], callEnv)
|
|
44
|
+
} else {
|
|
45
|
+
ctx.io.stderr(text)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const printFunctions: Record<string, CljValue> = {
|
|
50
|
+
println: v.nativeFnCtx('println', (ctx, callEnv, ...args: CljValue[]) => {
|
|
51
|
+
withPrintContext(buildPrintContext(ctx), () => {
|
|
52
|
+
emitToOut(ctx, callEnv, args.map(valueToString).join(' ') + '\n')
|
|
53
|
+
})
|
|
54
|
+
return v.nil()
|
|
55
|
+
}),
|
|
56
|
+
print: v.nativeFnCtx('print', (ctx, callEnv, ...args: CljValue[]) => {
|
|
57
|
+
withPrintContext(buildPrintContext(ctx), () => {
|
|
58
|
+
emitToOut(ctx, callEnv, args.map(valueToString).join(' '))
|
|
59
|
+
})
|
|
60
|
+
return v.nil()
|
|
61
|
+
}),
|
|
62
|
+
newline: v.nativeFnCtx('newline', (ctx, callEnv) => {
|
|
63
|
+
emitToOut(ctx, callEnv, '\n')
|
|
64
|
+
return v.nil()
|
|
65
|
+
}),
|
|
66
|
+
pr: v.nativeFnCtx('pr', (ctx, callEnv, ...args: CljValue[]) => {
|
|
67
|
+
withPrintContext(buildPrintContext(ctx), () => {
|
|
68
|
+
emitToOut(ctx, callEnv, args.map((v) => printString(v)).join(' '))
|
|
69
|
+
})
|
|
70
|
+
return v.nil()
|
|
71
|
+
}),
|
|
72
|
+
prn: v.nativeFnCtx('prn', (ctx, callEnv, ...args: CljValue[]) => {
|
|
73
|
+
withPrintContext(buildPrintContext(ctx), () => {
|
|
74
|
+
emitToOut(ctx, callEnv, args.map((v) => printString(v)).join(' ') + '\n')
|
|
75
|
+
})
|
|
76
|
+
return v.nil()
|
|
77
|
+
}),
|
|
78
|
+
pprint: v.nativeFnCtx(
|
|
79
|
+
'pprint',
|
|
80
|
+
(ctx, callEnv, form: CljValue, widthArg?: CljValue) => {
|
|
81
|
+
if (form === undefined) return v.nil()
|
|
82
|
+
const maxWidth = widthArg?.kind === 'number' ? widthArg.value : 80
|
|
83
|
+
withPrintContext(buildPrintContext(ctx), () => {
|
|
84
|
+
emitToOut(ctx, callEnv, prettyPrintString(form, maxWidth) + '\n')
|
|
85
|
+
})
|
|
86
|
+
return v.nil()
|
|
87
|
+
}
|
|
88
|
+
),
|
|
89
|
+
warn: v.nativeFnCtx('warn', (ctx, callEnv, ...args: CljValue[]) => {
|
|
90
|
+
withPrintContext(buildPrintContext(ctx), () => {
|
|
91
|
+
emitToErr(ctx, callEnv, args.map(valueToString).join(' ') + '\n')
|
|
92
|
+
})
|
|
93
|
+
return v.nil()
|
|
94
|
+
}),
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export const printVars: Record<string, CljValue> = {
|
|
98
|
+
// Dynamic output-channel vars. IO functions check these first before
|
|
99
|
+
// falling back to ctx.io.stdout / ctx.io.stderr. Bound by with-out-str
|
|
100
|
+
// and with-err-str macros defined in clojure.core.
|
|
101
|
+
'*out*': v.nil(),
|
|
102
|
+
'*err*': v.nil(),
|
|
103
|
+
// Dynamic print-control vars
|
|
104
|
+
'*print-length*': v.nil(),
|
|
105
|
+
'*print-level*': v.nil(),
|
|
106
|
+
// Compatibility var for IDE tooling
|
|
107
|
+
'*compiler-options*': v.map([]),
|
|
108
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// Regex stdlib: regexp?, re-pattern, re-find, re-matches, re-seq
|
|
2
2
|
// Also exports str-split* used internally by clojure.string/split.
|
|
3
|
-
import { is } from '
|
|
4
|
-
import { EvaluationError } from '
|
|
5
|
-
import { v } from '
|
|
6
|
-
import { printString } from '
|
|
7
|
-
import type { CljRegex, CljValue } from '
|
|
3
|
+
import { is } from '../../../assertions'
|
|
4
|
+
import { EvaluationError } from '../../../errors'
|
|
5
|
+
import { v } from '../../../factories'
|
|
6
|
+
import { printString } from '../../../printer'
|
|
7
|
+
import type { CljRegex, CljValue } from '../../../types'
|
|
8
8
|
|
|
9
9
|
// ---------------------------------------------------------------------------
|
|
10
10
|
// Inline-flag extraction
|
|
@@ -6,13 +6,12 @@
|
|
|
6
6
|
// construction protocol (prepend for lists, append for vectors, kv-pair for maps,
|
|
7
7
|
// element dedup for sets).
|
|
8
8
|
|
|
9
|
-
import { is } from '
|
|
10
|
-
import { EvaluationError } from '
|
|
11
|
-
import { v } from '
|
|
12
|
-
import { printString } from '
|
|
13
|
-
import { realizeLazySeq, toSeq } from '
|
|
9
|
+
import { is } from '../../../assertions.ts'
|
|
10
|
+
import { EvaluationError } from '../../../errors.ts'
|
|
11
|
+
import { v } from '../../../factories.ts'
|
|
12
|
+
import { printString } from '../../../printer.ts'
|
|
13
|
+
import { realizeLazySeq, toSeq } from '../../../transformations.ts'
|
|
14
14
|
import {
|
|
15
|
-
valueKeywords,
|
|
16
15
|
type CljList,
|
|
17
16
|
type CljMap,
|
|
18
17
|
type CljNumber,
|
|
@@ -20,7 +19,8 @@ import {
|
|
|
20
19
|
type CljString,
|
|
21
20
|
type CljValue,
|
|
22
21
|
type CljVector,
|
|
23
|
-
} from '
|
|
22
|
+
} from '../../../types.ts'
|
|
23
|
+
import { valueKeywords } from '../../../keywords.ts'
|
|
24
24
|
|
|
25
25
|
export const seqFunctions: Record<string, CljValue> = {
|
|
26
26
|
list: v
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// Native string helpers used by clojure.string.
|
|
2
2
|
// All public API lives in src/clojure/string.clj; these are private helpers.
|
|
3
|
-
import { is } from '
|
|
4
|
-
import { EvaluationError } from '
|
|
5
|
-
import { v } from '
|
|
6
|
-
import { printString } from '
|
|
7
|
-
import { valueToString } from '
|
|
3
|
+
import { is } from '../../../assertions'
|
|
4
|
+
import { EvaluationError } from '../../../errors'
|
|
5
|
+
import { v } from '../../../factories'
|
|
6
|
+
import { printString } from '../../../printer'
|
|
7
|
+
import { valueToString } from '../../../transformations'
|
|
8
8
|
import type {
|
|
9
9
|
CljFunction,
|
|
10
10
|
CljNativeFunction,
|
|
@@ -12,7 +12,7 @@ import type {
|
|
|
12
12
|
CljValue,
|
|
13
13
|
Env,
|
|
14
14
|
EvaluationContext,
|
|
15
|
-
} from '
|
|
15
|
+
} from '../../../types'
|
|
16
16
|
|
|
17
17
|
// ---------------------------------------------------------------------------
|
|
18
18
|
// Internal helpers
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// Transducer protocol primitives: reduced, volatile!, transduce
|
|
2
2
|
|
|
3
|
-
import { is } from '
|
|
4
|
-
import { EvaluationError } from '
|
|
5
|
-
import { v } from '
|
|
6
|
-
import { joinLines, printString } from '
|
|
7
|
-
import { toSeq } from '
|
|
3
|
+
import { is } from '../../../assertions'
|
|
4
|
+
import { EvaluationError } from '../../../errors'
|
|
5
|
+
import { v } from '../../../factories'
|
|
6
|
+
import { joinLines, printString } from '../../../printer'
|
|
7
|
+
import { toSeq } from '../../../transformations'
|
|
8
8
|
import type {
|
|
9
9
|
CljFunction,
|
|
10
10
|
CljNativeFunction,
|
|
11
11
|
CljValue,
|
|
12
12
|
Env,
|
|
13
13
|
EvaluationContext,
|
|
14
|
-
} from '
|
|
14
|
+
} from '../../../types'
|
|
15
15
|
|
|
16
16
|
export const transducerFunctions: Record<string, CljValue> = {
|
|
17
17
|
// ── Reduced sentinel ────────────────────────────────────────────────────
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// Miscellaneous utilities: str, type, gensym, eval, macroexpand-1, macroexpand,
|
|
2
2
|
// namespace, name, keyword
|
|
3
|
-
import { is } from '
|
|
4
|
-
import { tryLookup } from '
|
|
5
|
-
import { EvaluationError } from '
|
|
6
|
-
import { v } from '
|
|
7
|
-
import { makeGensym } from '
|
|
8
|
-
import { buildPrintContext, joinLines, prettyPrintString, printString, withPrintContext } from '
|
|
9
|
-
import { readForms } from '
|
|
10
|
-
import { tokenize } from '
|
|
11
|
-
import { valueToString } from '
|
|
12
|
-
import type { CljValue, Env, EvaluationContext } from '
|
|
3
|
+
import { is } from '../../../assertions'
|
|
4
|
+
import { tryLookup } from '../../../env'
|
|
5
|
+
import { EvaluationError } from '../../../errors'
|
|
6
|
+
import { v } from '../../../factories'
|
|
7
|
+
import { makeGensym } from '../../../gensym'
|
|
8
|
+
import { buildPrintContext, joinLines, prettyPrintString, printString, withPrintContext } from '../../../printer'
|
|
9
|
+
import { readForms } from '../../../reader'
|
|
10
|
+
import { tokenize } from '../../../tokenizer'
|
|
11
|
+
import { valueToString } from '../../../transformations'
|
|
12
|
+
import type { CljValue, Env, EvaluationContext } from '../../../types'
|
|
13
13
|
|
|
14
14
|
export const utilFunctions: Record<string, CljValue> = {
|
|
15
15
|
str: v
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { is } from '
|
|
2
|
-
import { EvaluationError } from '
|
|
3
|
-
import { v } from '
|
|
4
|
-
import type { CljValue } from '
|
|
1
|
+
import { is } from '../../../assertions'
|
|
2
|
+
import { EvaluationError } from '../../../errors'
|
|
3
|
+
import { v } from '../../../factories'
|
|
4
|
+
import type { CljValue } from '../../../types'
|
|
5
5
|
|
|
6
6
|
export const varFunctions: Record<string, CljValue> = {
|
|
7
7
|
'var?': v
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
// These functions are exclusively concerned with vectors (or lists treated as
|
|
4
4
|
// a stack for peek/pop). Pure vector construction and stack operations.
|
|
5
5
|
|
|
6
|
-
import { is } from '
|
|
7
|
-
import { EvaluationError } from '
|
|
8
|
-
import { v } from '
|
|
9
|
-
import { printString } from '
|
|
10
|
-
import { toSeq } from '
|
|
11
|
-
import { type CljValue } from '
|
|
6
|
+
import { is } from '../../../assertions'
|
|
7
|
+
import { EvaluationError } from '../../../errors'
|
|
8
|
+
import { v } from '../../../factories'
|
|
9
|
+
import { printString } from '../../../printer'
|
|
10
|
+
import { toSeq } from '../../../transformations'
|
|
11
|
+
import { type CljValue } from '../../../types'
|
|
12
12
|
|
|
13
13
|
export const vectorFunctions: Record<string, CljValue> = {
|
|
14
14
|
vector: v
|