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
@@ -0,0 +1,154 @@
1
+ /**
2
+ * S-Expression Tokenizer
3
+ *
4
+ * Converts source string into a stream of tokens.
5
+ */
6
+ /**
7
+ * Token types
8
+ */
9
+ export var TokenType;
10
+ (function (TokenType) {
11
+ TokenType["LeftParen"] = "LeftParen";
12
+ TokenType["RightParen"] = "RightParen";
13
+ TokenType["Number"] = "Number";
14
+ TokenType["String"] = "String";
15
+ TokenType["Symbol"] = "Symbol";
16
+ TokenType["Boolean"] = "Boolean";
17
+ TokenType["EOF"] = "EOF";
18
+ })(TokenType || (TokenType = {}));
19
+ /**
20
+ * Tokenize S-expression source code
21
+ */
22
+ export function tokenize(input) {
23
+ const tokens = [];
24
+ let pos = 0;
25
+ let line = 1;
26
+ let column = 1;
27
+ function advance() {
28
+ const char = input[pos++];
29
+ if (char === '\n') {
30
+ line++;
31
+ column = 1;
32
+ }
33
+ else {
34
+ column++;
35
+ }
36
+ return char ?? '';
37
+ }
38
+ function peek() {
39
+ return input[pos] ?? '';
40
+ }
41
+ function skipWhitespace() {
42
+ while (pos < input.length) {
43
+ const char = peek();
44
+ if (/\s/.test(char)) {
45
+ advance();
46
+ }
47
+ else if (char === ';') {
48
+ // Skip comment until end of line
49
+ while (pos < input.length && peek() !== '\n') {
50
+ advance();
51
+ }
52
+ }
53
+ else {
54
+ break;
55
+ }
56
+ }
57
+ }
58
+ function readString() {
59
+ const startLine = line;
60
+ const startColumn = column;
61
+ advance(); // skip opening quote
62
+ let value = '';
63
+ while (pos < input.length && peek() !== '"') {
64
+ if (peek() === '\\' && pos + 1 < input.length) {
65
+ advance(); // skip backslash
66
+ const escaped = advance();
67
+ switch (escaped) {
68
+ case 'n':
69
+ value += '\n';
70
+ break;
71
+ case 't':
72
+ value += '\t';
73
+ break;
74
+ case '\\':
75
+ value += '\\';
76
+ break;
77
+ case '"':
78
+ value += '"';
79
+ break;
80
+ default:
81
+ value += escaped;
82
+ }
83
+ }
84
+ else {
85
+ value += advance();
86
+ }
87
+ }
88
+ if (peek() !== '"') {
89
+ throw new Error(`Unterminated string at line ${startLine}, column ${startColumn}`);
90
+ }
91
+ advance(); // skip closing quote
92
+ return { type: TokenType.String, value, line: startLine, column: startColumn };
93
+ }
94
+ function readAtom() {
95
+ const startLine = line;
96
+ const startColumn = column;
97
+ let atom = '';
98
+ while (pos < input.length && !/[\s()";\[\]]/.test(peek())) {
99
+ atom += advance();
100
+ }
101
+ if (atom === '') {
102
+ throw new Error(`Unexpected character '${peek()}' at line ${line}, column ${column}`);
103
+ }
104
+ // Check for boolean
105
+ if (atom === 'true' || atom === '#t') {
106
+ return { type: TokenType.Boolean, value: true, line: startLine, column: startColumn };
107
+ }
108
+ if (atom === 'false' || atom === '#f') {
109
+ return { type: TokenType.Boolean, value: false, line: startLine, column: startColumn };
110
+ }
111
+ // Check for number
112
+ const num = Number(atom);
113
+ if (!Number.isNaN(num)) {
114
+ return { type: TokenType.Number, value: num, line: startLine, column: startColumn };
115
+ }
116
+ // Symbol
117
+ return { type: TokenType.Symbol, value: atom, line: startLine, column: startColumn };
118
+ }
119
+ while (pos < input.length) {
120
+ skipWhitespace();
121
+ if (pos >= input.length)
122
+ break;
123
+ const startLine = line;
124
+ const startColumn = column;
125
+ const char = peek();
126
+ if (char === '(') {
127
+ advance();
128
+ tokens.push({
129
+ type: TokenType.LeftParen,
130
+ value: '(',
131
+ line: startLine,
132
+ column: startColumn,
133
+ });
134
+ }
135
+ else if (char === ')') {
136
+ advance();
137
+ tokens.push({
138
+ type: TokenType.RightParen,
139
+ value: ')',
140
+ line: startLine,
141
+ column: startColumn,
142
+ });
143
+ }
144
+ else if (char === '"') {
145
+ tokens.push(readString());
146
+ }
147
+ else {
148
+ tokens.push(readAtom());
149
+ }
150
+ }
151
+ tokens.push({ type: TokenType.EOF, value: '', line, column });
152
+ return tokens;
153
+ }
154
+ //# sourceMappingURL=tokenizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../src/tokenizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * S-Expression Types
3
+ *
4
+ * Core type definitions for the S-Expression evaluator.
5
+ */
6
+ import type { SExpr } from './parser';
7
+ /**
8
+ * Lambda function representation with closure support
9
+ */
10
+ export interface LambdaFunction {
11
+ __lambda: true;
12
+ params: string[];
13
+ body: SExpr;
14
+ closure: Environment;
15
+ }
16
+ /**
17
+ * Runtime value types
18
+ */
19
+ export type Value = string | number | boolean | null | ValueArray | ValueObject | LambdaFunction;
20
+ export interface ValueArray extends Array<Value> {
21
+ }
22
+ export interface ValueObject extends Record<string, Value> {
23
+ }
24
+ /**
25
+ * Variable environment (lexical scope)
26
+ */
27
+ export type Environment = Record<string, Value>;
28
+ /**
29
+ * Evaluate function signature for recursive evaluation
30
+ */
31
+ export type EvaluateFn = (expr: SExpr, env: Environment) => Value;
32
+ /**
33
+ * Primitive function signature
34
+ * @param args - Evaluated arguments
35
+ * @param env - Current environment
36
+ * @param evaluate - Evaluate function for lazy evaluation needs
37
+ */
38
+ export type PrimitiveFunction = (args: Value[], env: Environment, evaluate: EvaluateFn) => Value;
39
+ /**
40
+ * Evaluator configuration options
41
+ */
42
+ export interface EvaluatorOptions {
43
+ /** Custom primitive functions to add or override */
44
+ primitives?: Record<string, PrimitiveFunction>;
45
+ /** Maximum recursion depth (default: 100) */
46
+ maxDepth?: number;
47
+ }
48
+ /**
49
+ * Type guard for lambda functions
50
+ */
51
+ export declare function isLambda(v: Value): v is LambdaFunction;
52
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAErC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,IAAI,CAAA;IACd,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,IAAI,EAAE,KAAK,CAAA;IACX,OAAO,EAAE,WAAW,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,UAAU,GAAG,WAAW,GAAG,cAAc,CAAA;AAEhG,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,KAAK,CAAC;CAAG;AACnD,MAAM,WAAW,WAAY,SAAQ,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;CAAG;AAE7D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;AAE/C;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,KAAK,KAAK,CAAA;AAEjE;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,KAAK,KAAK,CAAA;AAEhG;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;IAC9C,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,IAAI,cAAc,CAEtD"}
package/dist/types.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * S-Expression Types
3
+ *
4
+ * Core type definitions for the S-Expression evaluator.
5
+ */
6
+ /**
7
+ * Type guard for lambda functions
8
+ */
9
+ export function isLambda(v) {
10
+ return v !== null && typeof v === 'object' && '__lambda' in v && v.__lambda === true;
11
+ }
12
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkDH;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,CAAQ;IAC7B,OAAO,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,UAAU,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAA;AACxF,CAAC"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "seval.js",
3
+ "version": "1.0.0",
4
+ "description": "S-expression evaluator for TypeScript/JavaScript",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": ["dist"],
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "dev": "tsc --watch",
19
+ "test": "bun test",
20
+ "test:watch": "bun test --watch",
21
+ "test:coverage": "bun test --coverage",
22
+ "lint": "biome check .",
23
+ "lint:fix": "biome check --write .",
24
+ "format": "biome format --write .",
25
+ "format:check": "biome format --write . && git diff --exit-code",
26
+ "prepublishOnly": "bun run build"
27
+ },
28
+ "keywords": ["s-expression", "sexp", "lisp", "evaluator", "interpreter"],
29
+ "author": "cpunion",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/cpunion/seval.js.git"
34
+ },
35
+ "devDependencies": {
36
+ "@biomejs/biome": "^1.9.4",
37
+ "@types/bun": "latest",
38
+ "typescript": "^5.7.2"
39
+ }
40
+ }