conjure-js 0.0.1
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/conjure +0 -0
- package/dist/assets/codicon-ngg6Pgfi.ttf +0 -0
- package/dist/assets/editor.worker-CdQrwHl8.js +26 -0
- package/dist/assets/main-A7ZMId9A.css +1 -0
- package/dist/assets/main-CmI-7epE.js +3137 -0
- package/dist/index.html +195 -0
- package/dist/vite.svg +1 -0
- package/package.json +68 -0
- package/src/bin/__fixtures__/smoke/app/lib.clj +4 -0
- package/src/bin/__fixtures__/smoke/app/main.clj +4 -0
- package/src/bin/__fixtures__/smoke/repl-smoke.ts +12 -0
- package/src/bin/bencode.ts +205 -0
- package/src/bin/cli.ts +250 -0
- package/src/bin/nrepl-utils.ts +59 -0
- package/src/bin/nrepl.ts +393 -0
- package/src/bin/version.ts +4 -0
- package/src/clojure/core.clj +620 -0
- package/src/clojure/core.clj.d.ts +189 -0
- package/src/clojure/demo/math.clj +16 -0
- package/src/clojure/demo/math.clj.d.ts +4 -0
- package/src/clojure/demo.clj +42 -0
- package/src/clojure/demo.clj.d.ts +0 -0
- package/src/clojure/generated/builtin-namespace-registry.ts +14 -0
- package/src/clojure/generated/clojure-core-source.ts +623 -0
- package/src/clojure/generated/clojure-string-source.ts +196 -0
- package/src/clojure/string.clj +192 -0
- package/src/clojure/string.clj.d.ts +25 -0
- package/src/core/assertions.ts +134 -0
- package/src/core/conversions.ts +108 -0
- package/src/core/core-env.ts +58 -0
- package/src/core/env.ts +78 -0
- package/src/core/errors.ts +39 -0
- package/src/core/evaluator/apply.ts +114 -0
- package/src/core/evaluator/arity.ts +174 -0
- package/src/core/evaluator/collections.ts +25 -0
- package/src/core/evaluator/destructure.ts +247 -0
- package/src/core/evaluator/dispatch.ts +73 -0
- package/src/core/evaluator/evaluate.ts +100 -0
- package/src/core/evaluator/expand.ts +79 -0
- package/src/core/evaluator/index.ts +72 -0
- package/src/core/evaluator/quasiquote.ts +87 -0
- package/src/core/evaluator/recur-check.ts +109 -0
- package/src/core/evaluator/special-forms.ts +517 -0
- package/src/core/factories.ts +155 -0
- package/src/core/gensym.ts +9 -0
- package/src/core/index.ts +76 -0
- package/src/core/positions.ts +38 -0
- package/src/core/printer.ts +86 -0
- package/src/core/reader.ts +559 -0
- package/src/core/scanners.ts +93 -0
- package/src/core/session.ts +610 -0
- package/src/core/stdlib/arithmetic.ts +361 -0
- package/src/core/stdlib/atoms.ts +88 -0
- package/src/core/stdlib/collections.ts +784 -0
- package/src/core/stdlib/errors.ts +81 -0
- package/src/core/stdlib/hof.ts +307 -0
- package/src/core/stdlib/meta.ts +48 -0
- package/src/core/stdlib/predicates.ts +240 -0
- package/src/core/stdlib/regex.ts +238 -0
- package/src/core/stdlib/strings.ts +311 -0
- package/src/core/stdlib/transducers.ts +256 -0
- package/src/core/stdlib/utils.ts +287 -0
- package/src/core/tokenizer.ts +437 -0
- package/src/core/transformations.ts +75 -0
- package/src/core/types.ts +258 -0
- package/src/main.ts +1 -0
- package/src/monaco-esm.d.ts +7 -0
- package/src/playground/clojure-tokens.ts +67 -0
- package/src/playground/editor.worker.ts +5 -0
- package/src/playground/find-form.ts +138 -0
- package/src/playground/playground.ts +342 -0
- package/src/playground/samples/00-welcome.clj +385 -0
- package/src/playground/samples/01-collections.clj +191 -0
- package/src/playground/samples/02-higher-order-functions.clj +215 -0
- package/src/playground/samples/03-destructuring.clj +194 -0
- package/src/playground/samples/04-strings-and-regex.clj +202 -0
- package/src/playground/samples/05-error-handling.clj +212 -0
- package/src/repl/repl.ts +116 -0
- package/tsconfig.build.json +10 -0
- package/tsconfig.json +31 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { EvaluationError } from './errors'
|
|
2
|
+
import type {
|
|
3
|
+
Arity,
|
|
4
|
+
CljAtom,
|
|
5
|
+
CljBoolean,
|
|
6
|
+
CljFunction,
|
|
7
|
+
CljKeyword,
|
|
8
|
+
CljList,
|
|
9
|
+
CljMacro,
|
|
10
|
+
CljMap,
|
|
11
|
+
CljMultiMethod,
|
|
12
|
+
CljNativeFunction,
|
|
13
|
+
CljNil,
|
|
14
|
+
CljNumber,
|
|
15
|
+
CljReduced,
|
|
16
|
+
CljRegex,
|
|
17
|
+
CljString,
|
|
18
|
+
CljSymbol,
|
|
19
|
+
CljValue,
|
|
20
|
+
CljVector,
|
|
21
|
+
CljVolatile,
|
|
22
|
+
DestructurePattern,
|
|
23
|
+
Env,
|
|
24
|
+
EvaluationContext,
|
|
25
|
+
} from './types'
|
|
26
|
+
|
|
27
|
+
export const cljNumber = <T extends number>(value: T) =>
|
|
28
|
+
({ kind: 'number', value }) as const satisfies CljNumber
|
|
29
|
+
export const cljString = <T extends string>(value: T) =>
|
|
30
|
+
({ kind: 'string', value }) as const satisfies CljString
|
|
31
|
+
export const cljBoolean = <T extends boolean>(value: T) =>
|
|
32
|
+
({ kind: 'boolean', value }) as const satisfies CljBoolean
|
|
33
|
+
export const cljKeyword = <T extends string>(name: T) =>
|
|
34
|
+
({ kind: 'keyword', name }) as const satisfies CljKeyword
|
|
35
|
+
export const cljNil = () =>
|
|
36
|
+
({ kind: 'nil', value: null }) as const satisfies CljNil
|
|
37
|
+
export const cljSymbol = <T extends string>(name: T) =>
|
|
38
|
+
({ kind: 'symbol', name }) as const satisfies CljSymbol
|
|
39
|
+
export const cljList = <T extends CljValue[]>(value: T) =>
|
|
40
|
+
({ kind: 'list', value }) as const satisfies CljList
|
|
41
|
+
export const cljVector = <T extends CljValue[]>(value: T) =>
|
|
42
|
+
({ kind: 'vector', value }) as const satisfies CljVector
|
|
43
|
+
export const cljMap = <T extends [CljValue, CljValue][]>(entries: T) =>
|
|
44
|
+
({ kind: 'map', entries }) as const satisfies CljMap
|
|
45
|
+
export const cljFunction = (
|
|
46
|
+
params: DestructurePattern[],
|
|
47
|
+
restParam: DestructurePattern | null,
|
|
48
|
+
body: CljValue[],
|
|
49
|
+
env: Env
|
|
50
|
+
): CljFunction => ({
|
|
51
|
+
kind: 'function',
|
|
52
|
+
arities: [{ params, restParam, body }],
|
|
53
|
+
env,
|
|
54
|
+
})
|
|
55
|
+
export const cljMultiArityFunction = (
|
|
56
|
+
arities: Arity[],
|
|
57
|
+
env: Env
|
|
58
|
+
): CljFunction => ({
|
|
59
|
+
kind: 'function',
|
|
60
|
+
arities,
|
|
61
|
+
env,
|
|
62
|
+
})
|
|
63
|
+
export const cljNativeFunction = <
|
|
64
|
+
T extends string,
|
|
65
|
+
U extends (...args: CljValue[]) => CljValue,
|
|
66
|
+
>(
|
|
67
|
+
name: T,
|
|
68
|
+
fn: U
|
|
69
|
+
) =>
|
|
70
|
+
({ kind: 'native-function', name, fn }) as const satisfies CljNativeFunction
|
|
71
|
+
export const cljNativeFunctionWithContext = <
|
|
72
|
+
T extends string,
|
|
73
|
+
U extends (ctx: EvaluationContext, callEnv: Env, ...args: CljValue[]) => CljValue,
|
|
74
|
+
>(
|
|
75
|
+
name: T,
|
|
76
|
+
fn: U
|
|
77
|
+
) =>
|
|
78
|
+
({
|
|
79
|
+
kind: 'native-function',
|
|
80
|
+
name,
|
|
81
|
+
// for now wrap this, we won't use it
|
|
82
|
+
fn: () => {
|
|
83
|
+
throw new EvaluationError('Native function called without context', {
|
|
84
|
+
name,
|
|
85
|
+
})
|
|
86
|
+
},
|
|
87
|
+
fnWithContext: fn,
|
|
88
|
+
}) as const satisfies CljNativeFunction
|
|
89
|
+
|
|
90
|
+
export const cljMacro = (
|
|
91
|
+
params: DestructurePattern[],
|
|
92
|
+
restParam: DestructurePattern | null,
|
|
93
|
+
body: CljValue[],
|
|
94
|
+
env: Env
|
|
95
|
+
): CljMacro => ({
|
|
96
|
+
kind: 'macro',
|
|
97
|
+
arities: [{ params, restParam, body }],
|
|
98
|
+
env,
|
|
99
|
+
})
|
|
100
|
+
export const cljMultiArityMacro = (arities: Arity[], env: Env): CljMacro => ({
|
|
101
|
+
kind: 'macro',
|
|
102
|
+
arities,
|
|
103
|
+
env,
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
export const cljRegex = (pattern: string, flags: string = ''): CljRegex => ({
|
|
107
|
+
kind: 'regex',
|
|
108
|
+
pattern,
|
|
109
|
+
flags,
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
export const cljAtom = (value: CljValue): CljAtom => ({ kind: 'atom', value })
|
|
113
|
+
export const cljReduced = (value: CljValue): CljReduced => ({
|
|
114
|
+
kind: 'reduced',
|
|
115
|
+
value,
|
|
116
|
+
})
|
|
117
|
+
export const cljVolatile = (value: CljValue): CljVolatile => ({
|
|
118
|
+
kind: 'volatile',
|
|
119
|
+
value,
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
export const withDoc = <T extends CljNativeFunction | CljFunction>(
|
|
123
|
+
fn: T,
|
|
124
|
+
doc: string,
|
|
125
|
+
arglists?: string[][]
|
|
126
|
+
): T => ({
|
|
127
|
+
...fn,
|
|
128
|
+
meta: cljMap([
|
|
129
|
+
[cljKeyword(':doc'), cljString(doc)],
|
|
130
|
+
...(arglists
|
|
131
|
+
? ([
|
|
132
|
+
[
|
|
133
|
+
cljKeyword(':arglists'),
|
|
134
|
+
cljVector(arglists.map((args) => cljVector(args.map(cljSymbol)))),
|
|
135
|
+
],
|
|
136
|
+
] as [CljValue, CljValue][])
|
|
137
|
+
: []),
|
|
138
|
+
]),
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
export const cljMultiMethod = (
|
|
142
|
+
name: string,
|
|
143
|
+
dispatchFn: CljFunction | CljNativeFunction,
|
|
144
|
+
methods: Array<{
|
|
145
|
+
dispatchVal: CljValue
|
|
146
|
+
fn: CljFunction | CljNativeFunction
|
|
147
|
+
}>,
|
|
148
|
+
defaultMethod?: CljFunction | CljNativeFunction
|
|
149
|
+
): CljMultiMethod => ({
|
|
150
|
+
kind: 'multi-method',
|
|
151
|
+
name,
|
|
152
|
+
dispatchFn,
|
|
153
|
+
methods,
|
|
154
|
+
defaultMethod,
|
|
155
|
+
})
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Session API
|
|
2
|
+
export { createSession, snapshotSession, createSessionFromSnapshot } from './session'
|
|
3
|
+
export type { Session, SessionSnapshot } from './session'
|
|
4
|
+
|
|
5
|
+
// Conversions
|
|
6
|
+
export { cljToJs, jsToClj, ConversionError } from './conversions'
|
|
7
|
+
|
|
8
|
+
// Evaluator
|
|
9
|
+
export { applyFunction, applyMacro, evaluateWithMeasurements } from './evaluator'
|
|
10
|
+
|
|
11
|
+
// Errors
|
|
12
|
+
export { EvaluationError, ReaderError, TokenizerError } from './errors'
|
|
13
|
+
|
|
14
|
+
// Factories
|
|
15
|
+
export {
|
|
16
|
+
cljNumber,
|
|
17
|
+
cljString,
|
|
18
|
+
cljBoolean,
|
|
19
|
+
cljKeyword,
|
|
20
|
+
cljNil,
|
|
21
|
+
cljSymbol,
|
|
22
|
+
cljList,
|
|
23
|
+
cljVector,
|
|
24
|
+
cljMap,
|
|
25
|
+
cljFunction,
|
|
26
|
+
cljMultiArityFunction,
|
|
27
|
+
cljNativeFunction,
|
|
28
|
+
cljMacro,
|
|
29
|
+
cljMultiArityMacro,
|
|
30
|
+
} from './factories'
|
|
31
|
+
|
|
32
|
+
// Assertions
|
|
33
|
+
export {
|
|
34
|
+
isCljValue,
|
|
35
|
+
isFalsy,
|
|
36
|
+
isTruthy,
|
|
37
|
+
isSymbol,
|
|
38
|
+
isVector,
|
|
39
|
+
isList,
|
|
40
|
+
isMap,
|
|
41
|
+
isKeyword,
|
|
42
|
+
isFunction,
|
|
43
|
+
isNativeFunction,
|
|
44
|
+
isMacro,
|
|
45
|
+
isAFunction,
|
|
46
|
+
isCollection,
|
|
47
|
+
isEqual,
|
|
48
|
+
} from './assertions'
|
|
49
|
+
|
|
50
|
+
// Env
|
|
51
|
+
export { define } from './env'
|
|
52
|
+
|
|
53
|
+
// Transformations
|
|
54
|
+
export { valueToString } from './transformations'
|
|
55
|
+
|
|
56
|
+
// Printer
|
|
57
|
+
export { printString } from './printer'
|
|
58
|
+
|
|
59
|
+
// Types
|
|
60
|
+
export type {
|
|
61
|
+
CljValue,
|
|
62
|
+
CljNumber,
|
|
63
|
+
CljString,
|
|
64
|
+
CljBoolean,
|
|
65
|
+
CljKeyword,
|
|
66
|
+
CljNil,
|
|
67
|
+
CljSymbol,
|
|
68
|
+
CljList,
|
|
69
|
+
CljVector,
|
|
70
|
+
CljMap,
|
|
71
|
+
CljFunction,
|
|
72
|
+
CljNativeFunction,
|
|
73
|
+
CljMacro,
|
|
74
|
+
Env,
|
|
75
|
+
Arity,
|
|
76
|
+
} from './types'
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { CljValue, Pos } from './types'
|
|
2
|
+
|
|
3
|
+
export function setPos(val: CljValue, pos: Pos): void {
|
|
4
|
+
Object.defineProperty(val, '_pos', {
|
|
5
|
+
value: pos,
|
|
6
|
+
enumerable: false,
|
|
7
|
+
writable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
})
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function getPos(val: CljValue): Pos | undefined {
|
|
13
|
+
return (val as unknown as { _pos?: Pos })._pos
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function getLineCol(
|
|
17
|
+
source: string,
|
|
18
|
+
offset: number
|
|
19
|
+
): { line: number; col: number; lineText: string } {
|
|
20
|
+
const lines = source.split('\n')
|
|
21
|
+
let pos = 0
|
|
22
|
+
for (let i = 0; i < lines.length; i++) {
|
|
23
|
+
const lineEnd = pos + lines[i].length
|
|
24
|
+
if (offset <= lineEnd) {
|
|
25
|
+
return { line: i + 1, col: offset - pos, lineText: lines[i] }
|
|
26
|
+
}
|
|
27
|
+
pos = lineEnd + 1 // +1 for the consumed '\n'
|
|
28
|
+
}
|
|
29
|
+
const last = lines[lines.length - 1]
|
|
30
|
+
return { line: lines.length, col: last.length, lineText: last }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function formatErrorContext(source: string, pos: Pos): string {
|
|
34
|
+
const { line, col, lineText } = getLineCol(source, pos.start)
|
|
35
|
+
const span = Math.max(1, pos.end - pos.start)
|
|
36
|
+
const caret = ' '.repeat(col) + '^'.repeat(span)
|
|
37
|
+
return `\n at line ${line}, col ${col + 1}:\n ${lineText}\n ${caret}`
|
|
38
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { EvaluationError } from './errors'
|
|
2
|
+
import { valueKeywords, type CljMultiMethod, type CljValue } from './types'
|
|
3
|
+
|
|
4
|
+
export function printString(value: CljValue): string {
|
|
5
|
+
switch (value.kind) {
|
|
6
|
+
case valueKeywords.number:
|
|
7
|
+
return value.value.toString()
|
|
8
|
+
case valueKeywords.string:
|
|
9
|
+
let escapedBuffer = ''
|
|
10
|
+
for (const char of value.value) {
|
|
11
|
+
switch (char) {
|
|
12
|
+
case '"':
|
|
13
|
+
escapedBuffer += '\\"'
|
|
14
|
+
break
|
|
15
|
+
case '\\':
|
|
16
|
+
escapedBuffer += '\\\\'
|
|
17
|
+
break
|
|
18
|
+
case '\n':
|
|
19
|
+
escapedBuffer += '\\n'
|
|
20
|
+
break
|
|
21
|
+
case '\r':
|
|
22
|
+
escapedBuffer += '\\r'
|
|
23
|
+
break
|
|
24
|
+
case '\t':
|
|
25
|
+
escapedBuffer += '\\t'
|
|
26
|
+
break
|
|
27
|
+
default:
|
|
28
|
+
escapedBuffer += char
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return `"${escapedBuffer}"`
|
|
32
|
+
case valueKeywords.boolean:
|
|
33
|
+
return value.value ? 'true' : 'false'
|
|
34
|
+
case valueKeywords.nil:
|
|
35
|
+
return 'nil'
|
|
36
|
+
case valueKeywords.keyword:
|
|
37
|
+
return `${value.name}`
|
|
38
|
+
case valueKeywords.symbol:
|
|
39
|
+
return `${value.name}`
|
|
40
|
+
case valueKeywords.list:
|
|
41
|
+
return `(${value.value.map(printString).join(' ')})`
|
|
42
|
+
case valueKeywords.vector:
|
|
43
|
+
return `[${value.value.map(printString).join(' ')}]`
|
|
44
|
+
case valueKeywords.map:
|
|
45
|
+
return `{${value.entries.map(([key, value]) => `${printString(key)} ${printString(value)}`).join(' ')}}`
|
|
46
|
+
case valueKeywords.function: {
|
|
47
|
+
if (value.arities.length === 1) {
|
|
48
|
+
const a = value.arities[0]
|
|
49
|
+
const params = a.restParam
|
|
50
|
+
? [...a.params, { kind: 'symbol' as const, name: '&' }, a.restParam]
|
|
51
|
+
: a.params
|
|
52
|
+
return `(fn [${params.map(printString).join(' ')}] ${a.body.map(printString).join(' ')})`
|
|
53
|
+
}
|
|
54
|
+
const clauses = value.arities.map((a) => {
|
|
55
|
+
const params = a.restParam
|
|
56
|
+
? [...a.params, { kind: 'symbol' as const, name: '&' }, a.restParam]
|
|
57
|
+
: a.params
|
|
58
|
+
return `([${params.map(printString).join(' ')}] ${a.body.map(printString).join(' ')})`
|
|
59
|
+
})
|
|
60
|
+
return `(fn ${clauses.join(' ')})`
|
|
61
|
+
}
|
|
62
|
+
case valueKeywords.nativeFunction:
|
|
63
|
+
return `(native-fn ${value.name})`
|
|
64
|
+
case valueKeywords.multiMethod:
|
|
65
|
+
return `(multi-method ${(value as CljMultiMethod).name})`
|
|
66
|
+
case valueKeywords.atom:
|
|
67
|
+
return `#<Atom ${printString(value.value)}>`
|
|
68
|
+
case valueKeywords.reduced:
|
|
69
|
+
return `#<Reduced ${printString(value.value)}>`
|
|
70
|
+
case valueKeywords.volatile:
|
|
71
|
+
return `#<Volatile ${printString(value.value)}>`
|
|
72
|
+
case valueKeywords.regex: {
|
|
73
|
+
const escaped = value.pattern.replace(/"/g, '\\"')
|
|
74
|
+
const prefix = value.flags ? `(?${value.flags})` : ''
|
|
75
|
+
return `#"${prefix}${escaped}"`
|
|
76
|
+
}
|
|
77
|
+
default:
|
|
78
|
+
throw new EvaluationError(`unhandled value type: ${value.kind}`, {
|
|
79
|
+
value,
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function joinLines(lines: string[]): string {
|
|
85
|
+
return lines.join('\n')
|
|
86
|
+
}
|