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.
Files changed (80) hide show
  1. package/conjure +0 -0
  2. package/dist/assets/codicon-ngg6Pgfi.ttf +0 -0
  3. package/dist/assets/editor.worker-CdQrwHl8.js +26 -0
  4. package/dist/assets/main-A7ZMId9A.css +1 -0
  5. package/dist/assets/main-CmI-7epE.js +3137 -0
  6. package/dist/index.html +195 -0
  7. package/dist/vite.svg +1 -0
  8. package/package.json +68 -0
  9. package/src/bin/__fixtures__/smoke/app/lib.clj +4 -0
  10. package/src/bin/__fixtures__/smoke/app/main.clj +4 -0
  11. package/src/bin/__fixtures__/smoke/repl-smoke.ts +12 -0
  12. package/src/bin/bencode.ts +205 -0
  13. package/src/bin/cli.ts +250 -0
  14. package/src/bin/nrepl-utils.ts +59 -0
  15. package/src/bin/nrepl.ts +393 -0
  16. package/src/bin/version.ts +4 -0
  17. package/src/clojure/core.clj +620 -0
  18. package/src/clojure/core.clj.d.ts +189 -0
  19. package/src/clojure/demo/math.clj +16 -0
  20. package/src/clojure/demo/math.clj.d.ts +4 -0
  21. package/src/clojure/demo.clj +42 -0
  22. package/src/clojure/demo.clj.d.ts +0 -0
  23. package/src/clojure/generated/builtin-namespace-registry.ts +14 -0
  24. package/src/clojure/generated/clojure-core-source.ts +623 -0
  25. package/src/clojure/generated/clojure-string-source.ts +196 -0
  26. package/src/clojure/string.clj +192 -0
  27. package/src/clojure/string.clj.d.ts +25 -0
  28. package/src/core/assertions.ts +134 -0
  29. package/src/core/conversions.ts +108 -0
  30. package/src/core/core-env.ts +58 -0
  31. package/src/core/env.ts +78 -0
  32. package/src/core/errors.ts +39 -0
  33. package/src/core/evaluator/apply.ts +114 -0
  34. package/src/core/evaluator/arity.ts +174 -0
  35. package/src/core/evaluator/collections.ts +25 -0
  36. package/src/core/evaluator/destructure.ts +247 -0
  37. package/src/core/evaluator/dispatch.ts +73 -0
  38. package/src/core/evaluator/evaluate.ts +100 -0
  39. package/src/core/evaluator/expand.ts +79 -0
  40. package/src/core/evaluator/index.ts +72 -0
  41. package/src/core/evaluator/quasiquote.ts +87 -0
  42. package/src/core/evaluator/recur-check.ts +109 -0
  43. package/src/core/evaluator/special-forms.ts +517 -0
  44. package/src/core/factories.ts +155 -0
  45. package/src/core/gensym.ts +9 -0
  46. package/src/core/index.ts +76 -0
  47. package/src/core/positions.ts +38 -0
  48. package/src/core/printer.ts +86 -0
  49. package/src/core/reader.ts +559 -0
  50. package/src/core/scanners.ts +93 -0
  51. package/src/core/session.ts +610 -0
  52. package/src/core/stdlib/arithmetic.ts +361 -0
  53. package/src/core/stdlib/atoms.ts +88 -0
  54. package/src/core/stdlib/collections.ts +784 -0
  55. package/src/core/stdlib/errors.ts +81 -0
  56. package/src/core/stdlib/hof.ts +307 -0
  57. package/src/core/stdlib/meta.ts +48 -0
  58. package/src/core/stdlib/predicates.ts +240 -0
  59. package/src/core/stdlib/regex.ts +238 -0
  60. package/src/core/stdlib/strings.ts +311 -0
  61. package/src/core/stdlib/transducers.ts +256 -0
  62. package/src/core/stdlib/utils.ts +287 -0
  63. package/src/core/tokenizer.ts +437 -0
  64. package/src/core/transformations.ts +75 -0
  65. package/src/core/types.ts +258 -0
  66. package/src/main.ts +1 -0
  67. package/src/monaco-esm.d.ts +7 -0
  68. package/src/playground/clojure-tokens.ts +67 -0
  69. package/src/playground/editor.worker.ts +5 -0
  70. package/src/playground/find-form.ts +138 -0
  71. package/src/playground/playground.ts +342 -0
  72. package/src/playground/samples/00-welcome.clj +385 -0
  73. package/src/playground/samples/01-collections.clj +191 -0
  74. package/src/playground/samples/02-higher-order-functions.clj +215 -0
  75. package/src/playground/samples/03-destructuring.clj +194 -0
  76. package/src/playground/samples/04-strings-and-regex.clj +202 -0
  77. package/src/playground/samples/05-error-handling.clj +212 -0
  78. package/src/repl/repl.ts +116 -0
  79. package/tsconfig.build.json +10 -0
  80. 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,9 @@
1
+ let _counter = 0
2
+
3
+ export function makeGensym(prefix = 'G'): string {
4
+ return `${prefix}__${_counter++}`
5
+ }
6
+
7
+ export function resetGensymCounter(): void {
8
+ _counter = 0
9
+ }
@@ -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
+ }