seval.js 1.0.0

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 (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +131 -0
  3. package/dist/evaluator.d.ts +31 -0
  4. package/dist/evaluator.d.ts.map +1 -0
  5. package/dist/evaluator.js +297 -0
  6. package/dist/evaluator.js.map +1 -0
  7. package/dist/index.d.ts +27 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +32 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/parser.d.ts +40 -0
  12. package/dist/parser.d.ts.map +1 -0
  13. package/dist/parser.js +152 -0
  14. package/dist/parser.js.map +1 -0
  15. package/dist/primitives/arithmetic.d.ts +6 -0
  16. package/dist/primitives/arithmetic.d.ts.map +1 -0
  17. package/dist/primitives/arithmetic.js +13 -0
  18. package/dist/primitives/arithmetic.js.map +1 -0
  19. package/dist/primitives/array.d.ts +6 -0
  20. package/dist/primitives/array.d.ts.map +1 -0
  21. package/dist/primitives/array.js +33 -0
  22. package/dist/primitives/array.js.map +1 -0
  23. package/dist/primitives/comparison.d.ts +6 -0
  24. package/dist/primitives/comparison.d.ts.map +1 -0
  25. package/dist/primitives/comparison.js +12 -0
  26. package/dist/primitives/comparison.js.map +1 -0
  27. package/dist/primitives/index.d.ts +19 -0
  28. package/dist/primitives/index.d.ts.map +1 -0
  29. package/dist/primitives/index.js +45 -0
  30. package/dist/primitives/index.js.map +1 -0
  31. package/dist/primitives/logical.d.ts +6 -0
  32. package/dist/primitives/logical.d.ts.map +1 -0
  33. package/dist/primitives/logical.js +9 -0
  34. package/dist/primitives/logical.js.map +1 -0
  35. package/dist/primitives/math.d.ts +6 -0
  36. package/dist/primitives/math.d.ts.map +1 -0
  37. package/dist/primitives/math.js +21 -0
  38. package/dist/primitives/math.js.map +1 -0
  39. package/dist/primitives/object.d.ts +6 -0
  40. package/dist/primitives/object.d.ts.map +1 -0
  41. package/dist/primitives/object.js +42 -0
  42. package/dist/primitives/object.js.map +1 -0
  43. package/dist/primitives/string.d.ts +6 -0
  44. package/dist/primitives/string.d.ts.map +1 -0
  45. package/dist/primitives/string.js +21 -0
  46. package/dist/primitives/string.js.map +1 -0
  47. package/dist/primitives/type.d.ts +6 -0
  48. package/dist/primitives/type.d.ts.map +1 -0
  49. package/dist/primitives/type.js +12 -0
  50. package/dist/primitives/type.js.map +1 -0
  51. package/dist/tokenizer.d.ts +31 -0
  52. package/dist/tokenizer.d.ts.map +1 -0
  53. package/dist/tokenizer.js +154 -0
  54. package/dist/tokenizer.js.map +1 -0
  55. package/dist/types.d.ts +52 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/dist/types.js +12 -0
  58. package/dist/types.js.map +1 -0
  59. package/package.json +40 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 cpunion
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # seval.js
2
+
3
+ > S-expression evaluator for TypeScript/JavaScript
4
+
5
+ [![CI](https://github.com/cpunion/seval.js/actions/workflows/ci.yml/badge.svg)](https://github.com/cpunion/seval.js/actions/workflows/ci.yml)
6
+ [![Codecov](https://codecov.io/gh/cpunion/seval.js/branch/main/graph/badge.svg)](https://codecov.io/gh/cpunion/seval.js)
7
+ [![npm version](https://img.shields.io/npm/v/seval.js.svg)](https://www.npmjs.com/package/seval.js)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ `seval.js` is a safe, sandboxed S-expression parser and evaluator. It's designed to be easily extensible and embeddable in JavaScript/TypeScript applications.
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install seval.js
16
+ # or
17
+ bun add seval.js
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ```typescript
23
+ import { evalString, createEvaluator } from 'seval.js'
24
+
25
+ // Simple evaluation
26
+ evalString('(+ 1 2 3)') // 6
27
+ evalString('(* 2 (+ 3 4))') // 14
28
+
29
+ // Conditional and logic
30
+ evalString('(if (> 5 3) "yes" "no")') // "yes"
31
+ evalString('(and true (not false))') // true
32
+
33
+ // Lambda and closures
34
+ evalString('((lambda (x) (* x x)) 5)') // 25
35
+
36
+ // Custom primitives
37
+ const evaluator = createEvaluator({
38
+ primitives: {
39
+ uuid: () => crypto.randomUUID(),
40
+ greet: (args) => `Hello, ${args[0]}!`,
41
+ }
42
+ })
43
+ evaluator.evalString('(greet "World")') // "Hello, World!"
44
+ ```
45
+
46
+ ## Features
47
+
48
+ - **Safe sandboxed evaluation** - No access to global scope or dangerous APIs
49
+ - **Rich primitive library** - 60+ built-in functions for math, strings, arrays, objects
50
+ - **Lambda and closures** - First-class functions with lexical scoping
51
+ - **Customizable** - Add or override primitives easily
52
+ - **TypeScript support** - Full type definitions included
53
+
54
+ ## Built-in Primitives
55
+
56
+ ### Arithmetic
57
+ `+`, `-`, `*`, `/`, `%`
58
+
59
+ ### Comparison
60
+ `=`, `!=`, `<`, `>`, `<=`, `>=`
61
+
62
+ ### Logical
63
+ `and`, `or`, `not`
64
+
65
+ ### Math
66
+ `abs`, `min`, `max`, `floor`, `ceil`, `round`, `sqrt`, `pow`, `clamp`, `sin`, `cos`, `tan`, `log`, `exp`, `random`
67
+
68
+ ### Strings
69
+ `concat`, `str`, `strlen`, `substr`, `str-starts-with`, `str-ends-with`, `str-contains`, `str-replace`, `str-split`, `str-join`, `str-trim`, `str-upper`, `str-lower`, `parse-num`, `parse-int`
70
+
71
+ ### Arrays
72
+ `list`, `length`, `first`, `rest`, `last`, `nth`, `append`, `prepend`, `concat-lists`, `slice`, `reverse`, `range`, `empty?`, `contains`, `index-of`
73
+
74
+ ### Objects
75
+ `obj`, `get`, `set`, `keys`, `values`, `has-key`, `update-at`, `merge`
76
+
77
+ ### Type checks
78
+ `null?`, `number?`, `string?`, `bool?`, `list?`, `object?`
79
+
80
+ ## Special Forms
81
+
82
+ ```lisp
83
+ ; Conditionals
84
+ (if condition then-expr else-expr)
85
+ (cond (test1 expr1) (test2 expr2) (else exprN))
86
+
87
+ ; Variable bindings
88
+ (let ((x 1) (y 2)) (+ x y))
89
+
90
+ ; Functions
91
+ (lambda (x y) (+ x y))
92
+ (define (square x) (* x x))
93
+ (define pi 3.14159)
94
+
95
+ ; Sequences
96
+ (begin expr1 expr2 ...)
97
+ (progn expr1 expr2 ...)
98
+
99
+ ; Higher-order functions
100
+ (map (lambda (x) (* x 2)) (list 1 2 3)) ; (2 4 6)
101
+ (filter (lambda (x) (> x 2)) (list 1 2 3 4)) ; (3 4)
102
+ (reduce (list 1 2 3) 0 (acc x) (+ acc x)) ; 6
103
+ ```
104
+
105
+ ## API
106
+
107
+ ### `evalString(code: string): Value`
108
+ Parse and evaluate an S-expression string.
109
+
110
+ ### `evaluate(expr: SExpr, env?: Environment): Value`
111
+ Evaluate a parsed S-expression AST.
112
+
113
+ ### `parse(code: string): SExpr`
114
+ Parse an S-expression string into an AST.
115
+
116
+ ### `stringify(expr: SExpr): string`
117
+ Convert an AST back to string.
118
+
119
+ ### `createEvaluator(options?: EvaluatorOptions)`
120
+ Create a custom evaluator with additional primitives.
121
+
122
+ ```typescript
123
+ interface EvaluatorOptions {
124
+ primitives?: Record<string, PrimitiveFunction>
125
+ maxDepth?: number // default: 100
126
+ }
127
+ ```
128
+
129
+ ## License
130
+
131
+ MIT
@@ -0,0 +1,31 @@
1
+ /**
2
+ * S-Expression Evaluator
3
+ *
4
+ * Safe, sandboxed evaluation of S-expressions with customizable primitives.
5
+ *
6
+ * Design:
7
+ * - Symbols (typeof === 'symbol') are variable references, looked up in env
8
+ * - Strings (typeof === 'string') are string literals, returned as-is
9
+ */
10
+ import { type SExpr } from './parser';
11
+ import type { Environment, EvaluatorOptions, Value } from './types';
12
+ /**
13
+ * Create a new evaluator instance with optional custom primitives
14
+ */
15
+ export declare function createEvaluator(options?: EvaluatorOptions): {
16
+ evaluate: (expr: SExpr, env?: Environment) => Value;
17
+ evalString: (code: string, env?: Environment) => Value;
18
+ };
19
+ export declare const defaultEvaluator: {
20
+ evaluate: (expr: SExpr, env?: Environment) => Value;
21
+ evalString: (code: string, env?: Environment) => Value;
22
+ };
23
+ /**
24
+ * Evaluate an S-expression AST
25
+ */
26
+ export declare const evaluate: (expr: SExpr, env?: Environment) => Value;
27
+ /**
28
+ * Parse and evaluate an S-expression string
29
+ */
30
+ export declare const evalString: (code: string, env?: Environment) => Value;
31
+ //# sourceMappingURL=evaluator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../src/evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,KAAK,EAAiC,MAAM,UAAU,CAAA;AAEpE,OAAO,KAAK,EACR,WAAW,EAEX,gBAAgB,EAGhB,KAAK,EACR,MAAM,SAAS,CAAA;AAGhB;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,gBAAqB;qBAmSrC,KAAK,QAAO,WAAW;uBACrB,MAAM,QAAO,WAAW;EAElD;AAGD,eAAO,MAAM,gBAAgB;qBANJ,KAAK,QAAO,WAAW;uBACrB,MAAM,QAAO,WAAW;CAKF,CAAA;AAEjD;;GAEG;AACH,eAAO,MAAM,QAAQ,SAXI,KAAK,QAAO,WAAW,UAWC,CAAA;AAEjD;;GAEG;AACH,eAAO,MAAM,UAAU,SAfI,MAAM,QAAO,WAAW,UAeE,CAAA"}
@@ -0,0 +1,297 @@
1
+ /**
2
+ * S-Expression Evaluator
3
+ *
4
+ * Safe, sandboxed evaluation of S-expressions with customizable primitives.
5
+ *
6
+ * Design:
7
+ * - Symbols (typeof === 'symbol') are variable references, looked up in env
8
+ * - Strings (typeof === 'string') are string literals, returned as-is
9
+ */
10
+ import { isSymbol, parse, symName } from './parser';
11
+ import { defaultPrimitives } from './primitives';
12
+ import { isLambda } from './types';
13
+ /**
14
+ * Create a new evaluator instance with optional custom primitives
15
+ */
16
+ export function createEvaluator(options = {}) {
17
+ const primitives = {
18
+ ...defaultPrimitives,
19
+ ...options.primitives,
20
+ };
21
+ const maxDepth = options.maxDepth ?? 100;
22
+ function evaluate(expr, env, depth = 0) {
23
+ if (depth > maxDepth) {
24
+ throw new Error('Maximum evaluation depth exceeded');
25
+ }
26
+ // Null
27
+ if (expr === null)
28
+ return null;
29
+ // Literal values
30
+ if (typeof expr === 'number')
31
+ return expr;
32
+ if (typeof expr === 'boolean')
33
+ return expr;
34
+ // String literal - return as-is
35
+ if (typeof expr === 'string')
36
+ return expr;
37
+ // Symbol - look up in environment
38
+ if (isSymbol(expr)) {
39
+ const name = symName(expr);
40
+ if (name in env) {
41
+ return env[name];
42
+ }
43
+ // Symbol not found - return the name as string (might be a primitive name)
44
+ return name;
45
+ }
46
+ // List (function application)
47
+ if (Array.isArray(expr)) {
48
+ if (expr.length === 0)
49
+ return [];
50
+ const [op, ...args] = expr;
51
+ const opName = isSymbol(op) ? symName(op) : null;
52
+ // Special forms (check by symbol name)
53
+ if (opName === 'if') {
54
+ const [cond, thenExpr, elseExpr] = args;
55
+ const condResult = evaluate(cond, env, depth + 1);
56
+ return condResult
57
+ ? evaluate(thenExpr, env, depth + 1)
58
+ : evaluate(elseExpr, env, depth + 1);
59
+ }
60
+ if (opName === 'let') {
61
+ // (let ((x 1) (y 2)) body)
62
+ const [bindings, body] = args;
63
+ const newEnv = { ...env };
64
+ for (const binding of bindings) {
65
+ const [nameExpr, value] = binding;
66
+ const name = isSymbol(nameExpr) ? symName(nameExpr) : String(nameExpr);
67
+ newEnv[name] = evaluate(value, newEnv, depth + 1);
68
+ }
69
+ return evaluate(body, newEnv, depth + 1);
70
+ }
71
+ if (opName === 'cond') {
72
+ // (cond (test1 expr1) (test2 expr2) (else exprN))
73
+ for (const clause of args) {
74
+ const [test, result] = clause;
75
+ const isElse = isSymbol(test) && symName(test) === 'else';
76
+ if (isElse || evaluate(test, env, depth + 1)) {
77
+ return evaluate(result, env, depth + 1);
78
+ }
79
+ }
80
+ return null;
81
+ }
82
+ if (opName === 'begin' || opName === 'progn' || opName === 'do') {
83
+ let result = null;
84
+ for (const subExpr of args) {
85
+ result = evaluate(subExpr, env, depth + 1);
86
+ }
87
+ return result;
88
+ }
89
+ if (opName === 'quote') {
90
+ const val = args[0];
91
+ // For symbols, return the name as string
92
+ if (isSymbol(val)) {
93
+ return symName(val);
94
+ }
95
+ return val;
96
+ }
97
+ // Lambda: (lambda (x y) (+ x y)) or (fn (x y) (+ x y))
98
+ if (opName === 'lambda' || opName === 'fn') {
99
+ const [params, body] = args;
100
+ return {
101
+ __lambda: true,
102
+ params: params.map((p) => (isSymbol(p) ? symName(p) : String(p))),
103
+ body: body,
104
+ closure: env,
105
+ };
106
+ }
107
+ // Define: (define name value) or (define (name args...) body)
108
+ if (opName === 'define' || opName === 'defun') {
109
+ const first = args[0];
110
+ if (Array.isArray(first)) {
111
+ // (define (name args...) body) - function definition shorthand
112
+ const [nameExpr, ...paramExprs] = first;
113
+ const name = isSymbol(nameExpr) ? symName(nameExpr) : String(nameExpr);
114
+ const params = paramExprs.map((p) => (isSymbol(p) ? symName(p) : String(p)));
115
+ const body = args[1];
116
+ const fn = {
117
+ __lambda: true,
118
+ params,
119
+ body: body,
120
+ closure: env,
121
+ };
122
+ env[name] = fn;
123
+ return fn;
124
+ }
125
+ // (define name value)
126
+ const name = isSymbol(first) ? symName(first) : String(first);
127
+ const value = evaluate(args[1], env, depth + 1);
128
+ env[name] = value;
129
+ return value;
130
+ }
131
+ // Apply: (apply fn list-of-args)
132
+ if (opName === 'apply') {
133
+ const fn = evaluate(args[0], env, depth + 1);
134
+ const fnArgs = evaluate(args[1], env, depth + 1);
135
+ if (isLambda(fn)) {
136
+ const callEnv = { ...fn.closure };
137
+ fn.params.forEach((param, i) => {
138
+ callEnv[param] = fnArgs[i];
139
+ });
140
+ return evaluate(fn.body, callEnv, depth + 1);
141
+ }
142
+ throw new Error(`Cannot apply non-function: ${fn}`);
143
+ }
144
+ // Higher-order functions with inline predicates or lambda
145
+ if (opName === 'filter') {
146
+ const [predExpr, listExpr] = args;
147
+ const pred = evaluate(predExpr, env, depth + 1);
148
+ const list = evaluate(listExpr, env, depth + 1);
149
+ if (isLambda(pred)) {
150
+ return list.filter((item) => {
151
+ const callEnv = { ...pred.closure };
152
+ callEnv[pred.params[0]] = item;
153
+ return evaluate(pred.body, callEnv, depth + 1);
154
+ });
155
+ }
156
+ // Inline expression form
157
+ return list.filter((item) => {
158
+ const itemEnv = { ...env, '@': item, it: item };
159
+ return evaluate(predExpr, itemEnv, depth + 1);
160
+ });
161
+ }
162
+ if (opName === 'map') {
163
+ const [mapExpr, listExpr] = args;
164
+ const mapper = evaluate(mapExpr, env, depth + 1);
165
+ const list = evaluate(listExpr, env, depth + 1);
166
+ if (isLambda(mapper)) {
167
+ return list.map((item) => {
168
+ const callEnv = { ...mapper.closure };
169
+ callEnv[mapper.params[0]] = item;
170
+ return evaluate(mapper.body, callEnv, depth + 1);
171
+ });
172
+ }
173
+ // Inline expression form
174
+ return list.map((item) => {
175
+ const itemEnv = { ...env, '@': item, it: item };
176
+ return evaluate(mapExpr, itemEnv, depth + 1);
177
+ });
178
+ }
179
+ if (opName === 'find') {
180
+ const [listExpr, predExpr] = args;
181
+ const list = evaluate(listExpr, env, depth + 1);
182
+ return (list.find((item) => {
183
+ const itemEnv = { ...env, '@': item, it: item };
184
+ return evaluate(predExpr, itemEnv, depth + 1);
185
+ }) ?? null);
186
+ }
187
+ if (opName === 'find-index') {
188
+ const [listExpr, predExpr] = args;
189
+ const list = evaluate(listExpr, env, depth + 1);
190
+ return list.findIndex((item) => {
191
+ const itemEnv = { ...env, '@': item, it: item };
192
+ return evaluate(predExpr, itemEnv, depth + 1);
193
+ });
194
+ }
195
+ if (opName === 'sort-by') {
196
+ const [listExpr, keyExpr] = args;
197
+ const list = evaluate(listExpr, env, depth + 1);
198
+ return [...list].sort((a, b) => {
199
+ const aKey = evaluate(keyExpr, { ...env, '@': a, it: a }, depth + 1);
200
+ const bKey = evaluate(keyExpr, { ...env, '@': b, it: b }, depth + 1);
201
+ return aKey - bKey;
202
+ });
203
+ }
204
+ if (opName === 'count') {
205
+ const [listExpr, predExpr] = args;
206
+ const list = evaluate(listExpr, env, depth + 1);
207
+ if (!predExpr)
208
+ return list.length;
209
+ return list.filter((item) => {
210
+ const itemEnv = { ...env, '@': item, it: item };
211
+ return evaluate(predExpr, itemEnv, depth + 1);
212
+ }).length;
213
+ }
214
+ // Reduce: (reduce list init-value (acc item) body) or (reduce list init-value fn)
215
+ if (opName === 'reduce' || opName === 'fold') {
216
+ const [listExpr, initExpr, ...rest] = args;
217
+ const list = evaluate(listExpr, env, depth + 1);
218
+ let acc = evaluate(initExpr, env, depth + 1);
219
+ if (rest.length === 2) {
220
+ // Inline form: (reduce list init (acc item) body)
221
+ const [params, body] = rest;
222
+ const [accExpr, itemExpr] = params;
223
+ const accName = isSymbol(accExpr) ? symName(accExpr) : String(accExpr);
224
+ const itemName = isSymbol(itemExpr) ? symName(itemExpr) : String(itemExpr);
225
+ for (const item of list) {
226
+ const reduceEnv = { ...env, [accName]: acc, [itemName]: item };
227
+ acc = evaluate(body, reduceEnv, depth + 1);
228
+ }
229
+ }
230
+ else {
231
+ // Function form: (reduce list init fn)
232
+ const fn = evaluate(rest[0], env, depth + 1);
233
+ if (isLambda(fn)) {
234
+ for (const item of list) {
235
+ const callEnv = { ...fn.closure };
236
+ callEnv[fn.params[0]] = acc;
237
+ callEnv[fn.params[1]] = item;
238
+ acc = evaluate(fn.body, callEnv, depth + 1);
239
+ }
240
+ }
241
+ else {
242
+ throw new Error('reduce requires a function');
243
+ }
244
+ }
245
+ return acc;
246
+ }
247
+ // Regular function call or lambda invocation
248
+ // First check if op is a symbol that resolves to a lambda
249
+ const opValue = opName && opName in env ? env[opName] : null;
250
+ if (isLambda(opValue)) {
251
+ // Call user-defined function
252
+ const evaluatedArgs = args.map((arg) => evaluate(arg, env, depth + 1));
253
+ const callEnv = { ...opValue.closure };
254
+ opValue.params.forEach((param, i) => {
255
+ callEnv[param] = evaluatedArgs[i];
256
+ });
257
+ return evaluate(opValue.body, callEnv, depth + 1);
258
+ }
259
+ // Check if it's a primitive function (by symbol name)
260
+ if (opName) {
261
+ const fn = primitives[opName];
262
+ if (fn) {
263
+ const evaluatedArgs = args.map((arg) => evaluate(arg, env, depth + 1));
264
+ const evalFn = (e, newEnv) => evaluate(e, newEnv, depth + 1);
265
+ return fn(evaluatedArgs, env, evalFn);
266
+ }
267
+ }
268
+ // Maybe op itself is a lambda expression (not a symbol)
269
+ const evaluatedOp = evaluate(op, env, depth + 1);
270
+ if (isLambda(evaluatedOp)) {
271
+ const evaluatedArgs = args.map((arg) => evaluate(arg, env, depth + 1));
272
+ const callEnv = { ...evaluatedOp.closure };
273
+ evaluatedOp.params.forEach((param, i) => {
274
+ callEnv[param] = evaluatedArgs[i];
275
+ });
276
+ return evaluate(evaluatedOp.body, callEnv, depth + 1);
277
+ }
278
+ throw new Error(`Unknown function: ${opName ?? String(op)}`);
279
+ }
280
+ throw new Error(`Cannot evaluate: ${JSON.stringify(expr)}`);
281
+ }
282
+ return {
283
+ evaluate: (expr, env = {}) => evaluate(expr, env),
284
+ evalString: (code, env = {}) => evaluate(parse(code), env),
285
+ };
286
+ }
287
+ // Default evaluator instance
288
+ export const defaultEvaluator = createEvaluator();
289
+ /**
290
+ * Evaluate an S-expression AST
291
+ */
292
+ export const evaluate = defaultEvaluator.evaluate;
293
+ /**
294
+ * Parse and evaluate an S-expression string
295
+ */
296
+ export const evalString = defaultEvaluator.evalString;
297
+ //# sourceMappingURL=evaluator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator.js","sourceRoot":"","sources":["../src/evaluator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * seval - S-Expression Evaluator
3
+ *
4
+ * A safe, sandboxed S-expression parser and evaluator for TypeScript/JavaScript.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { evalString, createEvaluator } from 'seval'
9
+ *
10
+ * // Simple usage
11
+ * const result = evalString('(+ 1 2 3)') // 6
12
+ *
13
+ * // Custom primitives
14
+ * const evaluator = createEvaluator({
15
+ * primitives: {
16
+ * uuid: () => crypto.randomUUID(),
17
+ * }
18
+ * })
19
+ * evaluator.evalString('(uuid)') // "550e8400-e29b-41d4-a716-446655440000"
20
+ * ```
21
+ */
22
+ export { parse, stringify, isSymbol, sym, symName, type SExpr } from './parser';
23
+ export { tokenize, TokenType, type Token } from './tokenizer';
24
+ export { createEvaluator, evaluate, evalString, defaultEvaluator } from './evaluator';
25
+ export { isLambda, type Value, type Environment, type PrimitiveFunction, type EvaluatorOptions, type LambdaFunction, type EvaluateFn, type ValueArray, type ValueObject, } from './types';
26
+ export { defaultPrimitives, arithmeticPrimitives, comparisonPrimitives, logicalPrimitives, stringPrimitives, arrayPrimitives, objectPrimitives, mathPrimitives, typePrimitives, } from './primitives';
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,UAAU,CAAA;AAG/E,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAA;AAG7D,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGrF,OAAO,EACH,QAAQ,EACR,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,WAAW,GACnB,MAAM,SAAS,CAAA;AAGhB,OAAO,EACH,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,GACjB,MAAM,cAAc,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * seval - S-Expression Evaluator
3
+ *
4
+ * A safe, sandboxed S-expression parser and evaluator for TypeScript/JavaScript.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { evalString, createEvaluator } from 'seval'
9
+ *
10
+ * // Simple usage
11
+ * const result = evalString('(+ 1 2 3)') // 6
12
+ *
13
+ * // Custom primitives
14
+ * const evaluator = createEvaluator({
15
+ * primitives: {
16
+ * uuid: () => crypto.randomUUID(),
17
+ * }
18
+ * })
19
+ * evaluator.evalString('(uuid)') // "550e8400-e29b-41d4-a716-446655440000"
20
+ * ```
21
+ */
22
+ // Parser exports
23
+ export { parse, stringify, isSymbol, sym, symName } from './parser';
24
+ // Tokenizer exports
25
+ export { tokenize, TokenType } from './tokenizer';
26
+ // Evaluator exports
27
+ export { createEvaluator, evaluate, evalString, defaultEvaluator } from './evaluator';
28
+ // Type exports
29
+ export { isLambda, } from './types';
30
+ // Primitives exports
31
+ export { defaultPrimitives, arithmeticPrimitives, comparisonPrimitives, logicalPrimitives, stringPrimitives, arrayPrimitives, objectPrimitives, mathPrimitives, typePrimitives, } from './primitives';
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,iBAAiB;AACjB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAc,MAAM,UAAU,CAAA;AAE/E,oBAAoB;AACpB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAc,MAAM,aAAa,CAAA;AAE7D,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAErF,eAAe;AACf,OAAO,EACH,QAAQ,GASX,MAAM,SAAS,CAAA;AAEhB,qBAAqB;AACrB,OAAO,EACH,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,GACjB,MAAM,cAAc,CAAA"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * S-Expression Parser
3
+ *
4
+ * Parses strings like "(+ 1 2)" into nested arrays [Symbol.for('+'), 1, 2]
5
+ *
6
+ * Design:
7
+ * - Symbols (identifiers) are represented as JS Symbol via Symbol.for(name)
8
+ * - Strings are plain JS strings
9
+ * - This cleanly distinguishes variable references from string literals
10
+ */
11
+ /**
12
+ * S-Expression AST type
13
+ * - symbol: variable reference (looked up in environment)
14
+ * - string: string literal (used as-is)
15
+ * - number/boolean: primitive values
16
+ * - array: list/function call
17
+ */
18
+ export type SExpr = symbol | string | number | boolean | null | SExpr[];
19
+ /**
20
+ * Check if a value is a symbol (variable reference)
21
+ */
22
+ export declare function isSymbol(value: unknown): value is symbol;
23
+ /**
24
+ * Create a symbol from a name
25
+ */
26
+ export declare function sym(name: string): symbol;
27
+ /**
28
+ * Get the name from a symbol
29
+ */
30
+ export declare function symName(s: symbol): string;
31
+ /**
32
+ * Parse S-expression string into AST
33
+ */
34
+ export declare function parse(input: string): SExpr;
35
+ /**
36
+ * Convert S-expression AST back to string
37
+ */
38
+ export declare function stringify(expr: SExpr): string;
39
+ export declare const STRING_LITERAL_PREFIX = "\0STR:";
40
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,EAAE,CAAA;AAEvE;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExC;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAiG1C;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAgB7C;AAGD,eAAO,MAAM,qBAAqB,WAAW,CAAA"}