littlewing 0.1.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.
- package/LICENSE +21 -0
- package/README.md +414 -0
- package/dist/index.d.ts +360 -0
- package/dist/index.js +673 -0
- package/package.json +81 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
declare namespace exports_ast {
|
|
2
|
+
export { unaryOp, subtract, number, negate, multiply, modulo, identifier, functionCall, exponentiate, divide, binaryOp, assign, add };
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Runtime value type - can be a number, Date, or unknown (for function results)
|
|
6
|
+
*/
|
|
7
|
+
type RuntimeValue = number | Date | unknown;
|
|
8
|
+
/**
|
|
9
|
+
* Execution context providing global functions and variables
|
|
10
|
+
* Functions must accept any arguments and return a number or Date
|
|
11
|
+
* Variables must be numbers or Dates
|
|
12
|
+
*/
|
|
13
|
+
interface ExecutionContext {
|
|
14
|
+
functions?: Record<string, (...args: any[]) => number | Date>;
|
|
15
|
+
variables?: Record<string, number | Date>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Token types for lexer output
|
|
19
|
+
*/
|
|
20
|
+
declare enum TokenType {
|
|
21
|
+
NUMBER = "NUMBER",
|
|
22
|
+
STRING = "STRING",
|
|
23
|
+
IDENTIFIER = "IDENTIFIER",
|
|
24
|
+
PLUS = "PLUS",
|
|
25
|
+
MINUS = "MINUS",
|
|
26
|
+
STAR = "STAR",
|
|
27
|
+
SLASH = "SLASH",
|
|
28
|
+
PERCENT = "PERCENT",
|
|
29
|
+
CARET = "CARET",
|
|
30
|
+
LPAREN = "LPAREN",
|
|
31
|
+
RPAREN = "RPAREN",
|
|
32
|
+
EQUALS = "EQUALS",
|
|
33
|
+
COMMA = "COMMA",
|
|
34
|
+
EOF = "EOF"
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Token produced by lexer
|
|
38
|
+
*/
|
|
39
|
+
interface Token {
|
|
40
|
+
type: TokenType;
|
|
41
|
+
value: string | number;
|
|
42
|
+
position: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* AST Node - base type
|
|
46
|
+
*/
|
|
47
|
+
type ASTNode = Program | NumberLiteral | StringLiteral | Identifier | BinaryOp | UnaryOp | FunctionCall | Assignment;
|
|
48
|
+
/**
|
|
49
|
+
* Program node (multiple statements)
|
|
50
|
+
*/
|
|
51
|
+
interface Program {
|
|
52
|
+
type: "Program";
|
|
53
|
+
statements: ASTNode[];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Number literal (123, 45.67)
|
|
57
|
+
*/
|
|
58
|
+
interface NumberLiteral {
|
|
59
|
+
type: "NumberLiteral";
|
|
60
|
+
value: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* String literal ('hello', '2025-10-01')
|
|
64
|
+
*/
|
|
65
|
+
interface StringLiteral {
|
|
66
|
+
type: "StringLiteral";
|
|
67
|
+
value: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Identifier (variable or function name)
|
|
71
|
+
*/
|
|
72
|
+
interface Identifier {
|
|
73
|
+
type: "Identifier";
|
|
74
|
+
name: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Binary operation (a + b, x * y, etc.)
|
|
78
|
+
*/
|
|
79
|
+
interface BinaryOp {
|
|
80
|
+
type: "BinaryOp";
|
|
81
|
+
left: ASTNode;
|
|
82
|
+
operator: "+" | "-" | "*" | "/" | "%" | "^";
|
|
83
|
+
right: ASTNode;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Unary operation (-x, -5, etc.)
|
|
87
|
+
*/
|
|
88
|
+
interface UnaryOp {
|
|
89
|
+
type: "UnaryOp";
|
|
90
|
+
operator: "-";
|
|
91
|
+
argument: ASTNode;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Function call (now(), abs(-5), etc.)
|
|
95
|
+
*/
|
|
96
|
+
interface FunctionCall {
|
|
97
|
+
type: "FunctionCall";
|
|
98
|
+
name: string;
|
|
99
|
+
arguments: ASTNode[];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Variable assignment (x = 5)
|
|
103
|
+
*/
|
|
104
|
+
interface Assignment {
|
|
105
|
+
type: "Assignment";
|
|
106
|
+
name: string;
|
|
107
|
+
value: ASTNode;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Builder functions for creating AST nodes manually
|
|
111
|
+
*/
|
|
112
|
+
/**
|
|
113
|
+
* Create a number literal node
|
|
114
|
+
*/
|
|
115
|
+
declare function number(value: number): NumberLiteral;
|
|
116
|
+
/**
|
|
117
|
+
* Create an identifier node
|
|
118
|
+
*/
|
|
119
|
+
declare function identifier(name: string): Identifier;
|
|
120
|
+
/**
|
|
121
|
+
* Create a binary operation node
|
|
122
|
+
*/
|
|
123
|
+
declare function binaryOp(left: ASTNode, operator: "+" | "-" | "*" | "/" | "%" | "^", right: ASTNode): BinaryOp;
|
|
124
|
+
/**
|
|
125
|
+
* Create a unary operation node (unary minus)
|
|
126
|
+
*/
|
|
127
|
+
declare function unaryOp(argument: ASTNode): UnaryOp;
|
|
128
|
+
/**
|
|
129
|
+
* Create a function call node
|
|
130
|
+
*/
|
|
131
|
+
declare function functionCall(name: string, args?: ASTNode[]): FunctionCall;
|
|
132
|
+
/**
|
|
133
|
+
* Create a variable assignment node
|
|
134
|
+
*/
|
|
135
|
+
declare function assign(name: string, value: ASTNode): Assignment;
|
|
136
|
+
/**
|
|
137
|
+
* Convenience functions for common operations
|
|
138
|
+
*/
|
|
139
|
+
/**
|
|
140
|
+
* Create an addition operation
|
|
141
|
+
*/
|
|
142
|
+
declare function add(left: ASTNode, right: ASTNode): BinaryOp;
|
|
143
|
+
/**
|
|
144
|
+
* Create a subtraction operation
|
|
145
|
+
*/
|
|
146
|
+
declare function subtract(left: ASTNode, right: ASTNode): BinaryOp;
|
|
147
|
+
/**
|
|
148
|
+
* Create a multiplication operation
|
|
149
|
+
*/
|
|
150
|
+
declare function multiply(left: ASTNode, right: ASTNode): BinaryOp;
|
|
151
|
+
/**
|
|
152
|
+
* Create a division operation
|
|
153
|
+
*/
|
|
154
|
+
declare function divide(left: ASTNode, right: ASTNode): BinaryOp;
|
|
155
|
+
/**
|
|
156
|
+
* Create a modulo operation
|
|
157
|
+
*/
|
|
158
|
+
declare function modulo(left: ASTNode, right: ASTNode): BinaryOp;
|
|
159
|
+
/**
|
|
160
|
+
* Create an exponentiation operation
|
|
161
|
+
*/
|
|
162
|
+
declare function exponentiate(left: ASTNode, right: ASTNode): BinaryOp;
|
|
163
|
+
/**
|
|
164
|
+
* Create a negation operation
|
|
165
|
+
*/
|
|
166
|
+
declare function negate(argument: ASTNode): UnaryOp;
|
|
167
|
+
/**
|
|
168
|
+
* Default execution context with common Math functions and date utilities
|
|
169
|
+
* Users can use this as-is or spread it into their own context
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* // Use as-is
|
|
173
|
+
* execute('abs(-5)', defaultContext)
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* // Spread into custom context
|
|
177
|
+
* execute('now() + minutes(5)', {
|
|
178
|
+
* ...defaultContext,
|
|
179
|
+
* variables: { customVar: 42 }
|
|
180
|
+
* })
|
|
181
|
+
*/
|
|
182
|
+
declare const defaultContext: ExecutionContext;
|
|
183
|
+
/**
|
|
184
|
+
* Executor - evaluates an AST with given context
|
|
185
|
+
*/
|
|
186
|
+
declare class Executor {
|
|
187
|
+
private context;
|
|
188
|
+
private variables;
|
|
189
|
+
constructor(context?: ExecutionContext);
|
|
190
|
+
/**
|
|
191
|
+
* Execute an AST node and return the result
|
|
192
|
+
*/
|
|
193
|
+
execute(node: ASTNode): RuntimeValue;
|
|
194
|
+
/**
|
|
195
|
+
* Execute a program (multiple statements)
|
|
196
|
+
*/
|
|
197
|
+
private executeProgram;
|
|
198
|
+
/**
|
|
199
|
+
* Execute a number literal
|
|
200
|
+
*/
|
|
201
|
+
private executeNumberLiteral;
|
|
202
|
+
/**
|
|
203
|
+
* Execute a string literal
|
|
204
|
+
*/
|
|
205
|
+
private executeStringLiteral;
|
|
206
|
+
/**
|
|
207
|
+
* Execute an identifier (variable reference)
|
|
208
|
+
*/
|
|
209
|
+
private executeIdentifier;
|
|
210
|
+
/**
|
|
211
|
+
* Execute a binary operation
|
|
212
|
+
*/
|
|
213
|
+
private executeBinaryOp;
|
|
214
|
+
/**
|
|
215
|
+
* Execute a unary operation
|
|
216
|
+
*/
|
|
217
|
+
private executeUnaryOp;
|
|
218
|
+
/**
|
|
219
|
+
* Execute a function call
|
|
220
|
+
*/
|
|
221
|
+
private executeFunctionCall;
|
|
222
|
+
/**
|
|
223
|
+
* Execute a variable assignment
|
|
224
|
+
*/
|
|
225
|
+
private executeAssignment;
|
|
226
|
+
/**
|
|
227
|
+
* Add two values (handles Date + number, number + Date, Date + Date, number + number)
|
|
228
|
+
*/
|
|
229
|
+
private add;
|
|
230
|
+
/**
|
|
231
|
+
* Subtract two values (handles Date - number, number - Date, Date - Date, number - number)
|
|
232
|
+
*/
|
|
233
|
+
private subtract;
|
|
234
|
+
/**
|
|
235
|
+
* Multiply two values (number * number only)
|
|
236
|
+
*/
|
|
237
|
+
private multiply;
|
|
238
|
+
/**
|
|
239
|
+
* Divide two values (number / number only)
|
|
240
|
+
*/
|
|
241
|
+
private divide;
|
|
242
|
+
/**
|
|
243
|
+
* Modulo operation (number % number only)
|
|
244
|
+
*/
|
|
245
|
+
private modulo;
|
|
246
|
+
/**
|
|
247
|
+
* Exponentiation operation (number ^ number only)
|
|
248
|
+
*/
|
|
249
|
+
private exponentiate;
|
|
250
|
+
/**
|
|
251
|
+
* Get type name for error messages
|
|
252
|
+
*/
|
|
253
|
+
private typeOf;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Execute source code with given context
|
|
257
|
+
*/
|
|
258
|
+
declare function execute(source: string, context?: ExecutionContext): RuntimeValue;
|
|
259
|
+
/**
|
|
260
|
+
* Lexer - converts source code into tokens
|
|
261
|
+
*/
|
|
262
|
+
declare class Lexer {
|
|
263
|
+
private source;
|
|
264
|
+
private position;
|
|
265
|
+
constructor(source: string);
|
|
266
|
+
/**
|
|
267
|
+
* Tokenize the entire source and return all tokens
|
|
268
|
+
*/
|
|
269
|
+
tokenize(): Token[];
|
|
270
|
+
/**
|
|
271
|
+
* Get the next token from the source
|
|
272
|
+
*/
|
|
273
|
+
nextToken(): Token;
|
|
274
|
+
/**
|
|
275
|
+
* Skip whitespace and comments
|
|
276
|
+
*/
|
|
277
|
+
private skipWhitespaceAndComments;
|
|
278
|
+
/**
|
|
279
|
+
* Read a number token
|
|
280
|
+
*/
|
|
281
|
+
private readNumber;
|
|
282
|
+
/**
|
|
283
|
+
* Read an identifier token
|
|
284
|
+
*/
|
|
285
|
+
private readIdentifier;
|
|
286
|
+
/**
|
|
287
|
+
* Read a string token
|
|
288
|
+
*/
|
|
289
|
+
private readString;
|
|
290
|
+
/**
|
|
291
|
+
* Get character at position
|
|
292
|
+
*/
|
|
293
|
+
private getCharAt;
|
|
294
|
+
/**
|
|
295
|
+
* Peek at the next character without consuming it
|
|
296
|
+
*/
|
|
297
|
+
private peek;
|
|
298
|
+
/**
|
|
299
|
+
* Check if character is a digit
|
|
300
|
+
*/
|
|
301
|
+
private isDigit;
|
|
302
|
+
/**
|
|
303
|
+
* Check if character is a letter
|
|
304
|
+
*/
|
|
305
|
+
private isLetter;
|
|
306
|
+
/**
|
|
307
|
+
* Check if character is whitespace
|
|
308
|
+
*/
|
|
309
|
+
private isWhitespace;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Parser using Pratt parsing (top-down operator precedence)
|
|
313
|
+
*/
|
|
314
|
+
declare class Parser {
|
|
315
|
+
private tokens;
|
|
316
|
+
private current;
|
|
317
|
+
constructor(tokens: Token[]);
|
|
318
|
+
/**
|
|
319
|
+
* Parse tokens into an AST
|
|
320
|
+
* Supports multiple statements separated by semicolons
|
|
321
|
+
*/
|
|
322
|
+
parse(): ASTNode;
|
|
323
|
+
/**
|
|
324
|
+
* Parse an expression with Pratt parsing (precedence climbing)
|
|
325
|
+
*/
|
|
326
|
+
private parseExpression;
|
|
327
|
+
/**
|
|
328
|
+
* Parse prefix (unary) expressions
|
|
329
|
+
*/
|
|
330
|
+
private parsePrefix;
|
|
331
|
+
/**
|
|
332
|
+
* Parse function call arguments
|
|
333
|
+
*/
|
|
334
|
+
private parseFunctionArguments;
|
|
335
|
+
/**
|
|
336
|
+
* Get operator precedence
|
|
337
|
+
*/
|
|
338
|
+
private getPrecedence;
|
|
339
|
+
/**
|
|
340
|
+
* Get unary operator precedence
|
|
341
|
+
*/
|
|
342
|
+
private getUnaryPrecedence;
|
|
343
|
+
/**
|
|
344
|
+
* Check if token is a binary operator
|
|
345
|
+
*/
|
|
346
|
+
private isBinaryOperator;
|
|
347
|
+
/**
|
|
348
|
+
* Get current token
|
|
349
|
+
*/
|
|
350
|
+
private peek;
|
|
351
|
+
/**
|
|
352
|
+
* Advance to next token
|
|
353
|
+
*/
|
|
354
|
+
private advance;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Parse source code string into AST
|
|
358
|
+
*/
|
|
359
|
+
declare function parseSource(source: string): ASTNode;
|
|
360
|
+
export { parseSource, execute, defaultContext, exports_ast as ast, TokenType, Token, RuntimeValue, Parser, Lexer, Executor, ExecutionContext, ASTNode };
|