@robinpath/robinpath 0.30.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/README.md +856 -0
- package/bin/robinpath.js +374 -0
- package/dist/classes/ASTSerializer.d.ts +45 -0
- package/dist/classes/ExecutionStateTracker.d.ts +30 -0
- package/dist/classes/Executor.d.ts +193 -0
- package/dist/classes/ExpressionEvaluator.d.ts +20 -0
- package/dist/classes/Lexer.d.ts +86 -0
- package/dist/classes/Parser.d.ts +71 -0
- package/dist/classes/RobinPathThread.d.ts +146 -0
- package/dist/classes/TokenStream.d.ts +217 -0
- package/dist/classes/code-converter/ASTToCodeConverter.d.ts +178 -0
- package/dist/classes/code-converter/LineIndex.d.ts +54 -0
- package/dist/classes/code-converter/Printer.d.ts +117 -0
- package/dist/classes/code-converter/Writer.d.ts +42 -0
- package/dist/classes/code-converter/index.d.ts +8 -0
- package/dist/classes/code-converter/types.d.ts +29 -0
- package/dist/classes/exceptions.d.ts +26 -0
- package/dist/classes/index.d.ts +16 -0
- package/dist/index.d.ts +485 -0
- package/dist/index.js +13808 -0
- package/dist/modules/Array.d.ts +10 -0
- package/dist/modules/Core.d.ts +10 -0
- package/dist/modules/Dom.d.ts +10 -0
- package/dist/modules/Fetch.d.ts +6 -0
- package/dist/modules/Json.d.ts +10 -0
- package/dist/modules/Math.d.ts +10 -0
- package/dist/modules/Object.d.ts +10 -0
- package/dist/modules/Random.d.ts +6 -0
- package/dist/modules/String.d.ts +10 -0
- package/dist/modules/Test.d.ts +10 -0
- package/dist/modules/Time.d.ts +10 -0
- package/dist/parsers/ArrayLiteralParser.d.ts +17 -0
- package/dist/parsers/AssignmentParser.d.ts +37 -0
- package/dist/parsers/BracketParser.d.ts +31 -0
- package/dist/parsers/BreakParser.d.ts +15 -0
- package/dist/parsers/CellBlockParser.d.ts +11 -0
- package/dist/parsers/ChunkMarkerParser.d.ts +12 -0
- package/dist/parsers/CommandParser.d.ts +56 -0
- package/dist/parsers/CommentParser.d.ts +37 -0
- package/dist/parsers/ContinueParser.d.ts +15 -0
- package/dist/parsers/DecoratorParser.d.ts +29 -0
- package/dist/parsers/DefineParser.d.ts +18 -0
- package/dist/parsers/EventParser.d.ts +17 -0
- package/dist/parsers/ExpressionParser.d.ts +3 -0
- package/dist/parsers/FenceClassifier.d.ts +29 -0
- package/dist/parsers/ForLoopParser.d.ts +17 -0
- package/dist/parsers/IfBlockParser.d.ts +17 -0
- package/dist/parsers/ObjectLiteralParser.d.ts +17 -0
- package/dist/parsers/ParserUtils.d.ts +15 -0
- package/dist/parsers/PromptBlockParser.d.ts +10 -0
- package/dist/parsers/ReturnParser.d.ts +16 -0
- package/dist/parsers/ScopeParser.d.ts +24 -0
- package/dist/parsers/StringTemplateParser.d.ts +31 -0
- package/dist/parsers/SubexpressionParser.d.ts +33 -0
- package/dist/parsers/TogetherBlockParser.d.ts +18 -0
- package/dist/parsers/WithScopeParser.d.ts +24 -0
- package/dist/types/Ast.type.d.ts +455 -0
- package/dist/types/Environment.type.d.ts +53 -0
- package/dist/utils/args.d.ts +24 -0
- package/dist/utils/errorFormatter.d.ts +22 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/stringParsing.d.ts +41 -0
- package/dist/utils/types.d.ts +15 -0
- package/dist/utils/valueConversion.d.ts +25 -0
- package/package.json +50 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { TokenStream } from '../classes/TokenStream';
|
|
2
|
+
import { Token } from '../classes/Lexer';
|
|
3
|
+
import { SubexpressionExpression, CodePosition, Statement } from '../types/Ast.type';
|
|
4
|
+
export interface SubexpressionParserContext {
|
|
5
|
+
/**
|
|
6
|
+
* Parse a statement from the stream
|
|
7
|
+
*/
|
|
8
|
+
parseStatement: (stream: TokenStream) => Statement | null;
|
|
9
|
+
/**
|
|
10
|
+
* Create code position from tokens
|
|
11
|
+
*/
|
|
12
|
+
createCodePosition: (startToken: Token, endToken: Token) => CodePosition;
|
|
13
|
+
}
|
|
14
|
+
export declare class SubexpressionParser {
|
|
15
|
+
/**
|
|
16
|
+
* Parse a subexpression from TokenStream
|
|
17
|
+
* Expects stream to be positioned at the '$(' token
|
|
18
|
+
* Syntax: $( ... )
|
|
19
|
+
*
|
|
20
|
+
* @param stream - TokenStream positioned at the '$(' token
|
|
21
|
+
* @param context - Context with helper methods
|
|
22
|
+
* @returns Parsed SubexpressionExpression
|
|
23
|
+
*/
|
|
24
|
+
static parse(stream: TokenStream, context: SubexpressionParserContext): SubexpressionExpression;
|
|
25
|
+
/**
|
|
26
|
+
* Check if the current token is the start of a subexpression
|
|
27
|
+
* Subexpressions must start with SUBEXPRESSION_OPEN ($()
|
|
28
|
+
*
|
|
29
|
+
* @param stream - TokenStream to check
|
|
30
|
+
* @returns true if current token is SUBEXPRESSION_OPEN
|
|
31
|
+
*/
|
|
32
|
+
static isSubexpression(stream: TokenStream): boolean;
|
|
33
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TokenStream } from '../classes/TokenStream';
|
|
2
|
+
import { Token } from '../classes/Lexer';
|
|
3
|
+
import { TogetherBlock, Statement, CodePosition, DecoratorCall } from '../types/Ast.type';
|
|
4
|
+
export interface TogetherBlockParserContext {
|
|
5
|
+
parseStatement: (stream: TokenStream) => Statement | null;
|
|
6
|
+
parseComment: (stream: TokenStream) => Statement | null;
|
|
7
|
+
createCodePosition: (start: Token, end: Token) => CodePosition;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Parse a 'together' block from TokenStream
|
|
11
|
+
* Expects stream to be positioned at the 'together' keyword
|
|
12
|
+
*
|
|
13
|
+
* @param stream - TokenStream positioned at the 'together' keyword
|
|
14
|
+
* @param context - Context with helper methods
|
|
15
|
+
* @param decorators - Optional decorators to attach to this together block
|
|
16
|
+
* @returns Parsed TogetherBlock
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseTogether(stream: TokenStream, context: TogetherBlockParserContext, decorators?: DecoratorCall[]): TogetherBlock;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { TokenStream } from '../classes/TokenStream';
|
|
2
|
+
import { ScopeBlock, Statement, DecoratorCall } from '../types/Ast.type';
|
|
3
|
+
export declare class WithScopeParser {
|
|
4
|
+
/**
|
|
5
|
+
* Maximum number of iterations allowed before detecting an infinite loop
|
|
6
|
+
*/
|
|
7
|
+
static readonly MAX_STUCK_ITERATIONS = 100;
|
|
8
|
+
/**
|
|
9
|
+
* Debug mode flag - set to true to enable logging
|
|
10
|
+
* Can be controlled via VITE_DEBUG environment variable or set programmatically
|
|
11
|
+
*/
|
|
12
|
+
static debug: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Parse a 'with' scope block (callback block)
|
|
15
|
+
* Expects stream to be positioned at the 'with' keyword
|
|
16
|
+
*
|
|
17
|
+
* @param stream - TokenStream positioned at the 'with' keyword
|
|
18
|
+
* @param parseStatement - Callback to parse a statement from the stream
|
|
19
|
+
* @param parseComment - Callback to parse a comment from the stream
|
|
20
|
+
* @param decorators - Optional decorators to attach to this with block
|
|
21
|
+
* @returns Parsed ScopeBlock (with type 'do' for AST compatibility)
|
|
22
|
+
*/
|
|
23
|
+
static parse(stream: TokenStream, parseStatement: (stream: TokenStream) => Statement | null, parseComment: (stream: TokenStream) => Statement | null, decorators?: DecoratorCall[]): ScopeBlock;
|
|
24
|
+
}
|
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import { Value, AttributePathSegment } from '../utils/types';
|
|
2
|
+
/**
|
|
3
|
+
* Represents the position of code in the source file
|
|
4
|
+
*/
|
|
5
|
+
export interface CodePosition {
|
|
6
|
+
startRow: number;
|
|
7
|
+
startCol: number;
|
|
8
|
+
endRow: number;
|
|
9
|
+
endCol: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Represents a comment with its position in the source code
|
|
13
|
+
*/
|
|
14
|
+
export interface CommentWithPosition {
|
|
15
|
+
text: string;
|
|
16
|
+
codePos: CodePosition;
|
|
17
|
+
inline?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Represents a standalone comment statement in the AST
|
|
21
|
+
*/
|
|
22
|
+
export interface CommentStatement {
|
|
23
|
+
type: 'comment';
|
|
24
|
+
nodeKey?: string;
|
|
25
|
+
comments: CommentWithPosition[];
|
|
26
|
+
lineNumber: number;
|
|
27
|
+
/**
|
|
28
|
+
* Number of blank lines after this statement (for preserving formatting).
|
|
29
|
+
*
|
|
30
|
+
* **Semantics:**
|
|
31
|
+
* - `undefined` or `0`: No trailing blank lines (statement immediately followed by next)
|
|
32
|
+
* - `1`: One blank line after statement (two consecutive newlines: `\n\n`)
|
|
33
|
+
* - `2`: Two blank lines after statement (three consecutive newlines: `\n\n\n`)
|
|
34
|
+
* - ... and so on
|
|
35
|
+
*
|
|
36
|
+
* **For the LAST statement in a file:**
|
|
37
|
+
* - `undefined` or `0`: File does NOT end with a newline
|
|
38
|
+
* - `1`: File ends with exactly one newline (no blank line at EOF)
|
|
39
|
+
* - `2`: File ends with one blank line (two newlines at EOF)
|
|
40
|
+
* - ... and so on
|
|
41
|
+
*
|
|
42
|
+
* **Note:** The statement's own ending newline is NOT counted in trailingBlankLines.
|
|
43
|
+
* Each statement implicitly ends with `\n`. This field only tracks EXTRA blank lines.
|
|
44
|
+
*/
|
|
45
|
+
trailingBlankLines?: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Represents a variable reference expression
|
|
49
|
+
*/
|
|
50
|
+
export interface VarExpression {
|
|
51
|
+
type: 'var';
|
|
52
|
+
name: string;
|
|
53
|
+
path?: AttributePathSegment[];
|
|
54
|
+
codePos?: CodePosition;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Represents the last value expression ($)
|
|
58
|
+
*/
|
|
59
|
+
export interface LastValueExpression {
|
|
60
|
+
type: 'lastValue';
|
|
61
|
+
codePos?: CodePosition;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Represents a literal value expression
|
|
65
|
+
*/
|
|
66
|
+
export interface LiteralExpression {
|
|
67
|
+
type: 'literal';
|
|
68
|
+
value: Value;
|
|
69
|
+
codePos?: CodePosition;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Represents a number literal expression
|
|
73
|
+
*/
|
|
74
|
+
export interface NumberExpression {
|
|
75
|
+
type: 'number';
|
|
76
|
+
value: number;
|
|
77
|
+
codePos?: CodePosition;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Represents a string literal expression
|
|
81
|
+
*/
|
|
82
|
+
export interface StringExpression {
|
|
83
|
+
type: 'string';
|
|
84
|
+
value: string;
|
|
85
|
+
codePos?: CodePosition;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Represents a property in an object literal
|
|
89
|
+
*/
|
|
90
|
+
export interface ObjectProperty {
|
|
91
|
+
key: string | Expression;
|
|
92
|
+
value: Expression;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Represents an object literal expression { ... }
|
|
96
|
+
*/
|
|
97
|
+
export interface ObjectLiteralExpression {
|
|
98
|
+
type: 'objectLiteral';
|
|
99
|
+
properties: ObjectProperty[];
|
|
100
|
+
codePos?: CodePosition;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Represents an array literal expression [ ... ]
|
|
104
|
+
*/
|
|
105
|
+
export interface ArrayLiteralExpression {
|
|
106
|
+
type: 'arrayLiteral';
|
|
107
|
+
elements: Expression[];
|
|
108
|
+
codePos?: CodePosition;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Represents $( ... ) – a subexpression that contains statements.
|
|
112
|
+
* The result value is the lastValue after executing the body.
|
|
113
|
+
*/
|
|
114
|
+
export interface SubexpressionExpression {
|
|
115
|
+
type: 'subexpression';
|
|
116
|
+
body: Statement[];
|
|
117
|
+
codePos: CodePosition;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Binary operators for expressions
|
|
121
|
+
*/
|
|
122
|
+
export type BinaryOperator = '==' | '!=' | '<' | '<=' | '>' | '>=' | 'and' | 'or' | '+' | '-' | '*' | '/' | '%';
|
|
123
|
+
/**
|
|
124
|
+
* Represents a binary operation expression
|
|
125
|
+
*/
|
|
126
|
+
export interface BinaryExpression {
|
|
127
|
+
type: 'binary';
|
|
128
|
+
operator: BinaryOperator;
|
|
129
|
+
left: Expression;
|
|
130
|
+
right: Expression;
|
|
131
|
+
codePos?: CodePosition;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Unary operators for expressions
|
|
135
|
+
*/
|
|
136
|
+
export type UnaryOperator = 'not' | '-' | '+';
|
|
137
|
+
/**
|
|
138
|
+
* Represents a unary operation expression
|
|
139
|
+
*/
|
|
140
|
+
export interface UnaryExpression {
|
|
141
|
+
type: 'unary';
|
|
142
|
+
operator: UnaryOperator;
|
|
143
|
+
argument: Expression;
|
|
144
|
+
codePos?: CodePosition;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Represents a function/command call within an expression
|
|
148
|
+
*/
|
|
149
|
+
export interface CallExpression {
|
|
150
|
+
type: 'call';
|
|
151
|
+
callee: string;
|
|
152
|
+
args: Expression[];
|
|
153
|
+
codePos?: CodePosition;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Union type representing all possible expression types
|
|
157
|
+
*/
|
|
158
|
+
export type Expression = VarExpression | LastValueExpression | LiteralExpression | NumberExpression | StringExpression | ObjectLiteralExpression | ArrayLiteralExpression | SubexpressionExpression | BinaryExpression | UnaryExpression | CallExpression;
|
|
159
|
+
/**
|
|
160
|
+
* Represents named arguments (key=value pairs)
|
|
161
|
+
*/
|
|
162
|
+
export interface NamedArgsExpression {
|
|
163
|
+
type: 'namedArgs';
|
|
164
|
+
args: Record<string, Expression>;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Represents an argument passed to a command or function
|
|
168
|
+
*
|
|
169
|
+
* @deprecated The old Arg types with code strings are being phased out.
|
|
170
|
+
* Use Expression nodes instead. For backward compatibility, we keep the old types
|
|
171
|
+
* but they should be replaced with Expression nodes.
|
|
172
|
+
*/
|
|
173
|
+
export type Arg = Expression | NamedArgsExpression | {
|
|
174
|
+
type: 'subexpr';
|
|
175
|
+
code: string;
|
|
176
|
+
} | {
|
|
177
|
+
type: 'object';
|
|
178
|
+
code: string;
|
|
179
|
+
} | {
|
|
180
|
+
type: 'array';
|
|
181
|
+
code: string;
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Represents a decorator call (e.g., @desc "description")
|
|
185
|
+
*/
|
|
186
|
+
export interface DecoratorCall {
|
|
187
|
+
name: string;
|
|
188
|
+
args: Arg[];
|
|
189
|
+
codePos: CodePosition;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Represents a command/function call
|
|
193
|
+
*/
|
|
194
|
+
export interface CommandCall {
|
|
195
|
+
type: 'command';
|
|
196
|
+
nodeKey?: string;
|
|
197
|
+
name: string;
|
|
198
|
+
args: Arg[];
|
|
199
|
+
syntaxType?: 'space' | 'parentheses' | 'named-parentheses' | 'multiline-parentheses';
|
|
200
|
+
isTaggedTemplate?: boolean;
|
|
201
|
+
decorators?: DecoratorCall[];
|
|
202
|
+
into?: {
|
|
203
|
+
targetName: string;
|
|
204
|
+
targetPath?: AttributePathSegment[];
|
|
205
|
+
};
|
|
206
|
+
callback?: ScopeBlock;
|
|
207
|
+
comments?: CommentWithPosition[];
|
|
208
|
+
trailingBlankLines?: number;
|
|
209
|
+
codePos: CodePosition;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Represents a variable assignment (e.g., $var = value)
|
|
213
|
+
*/
|
|
214
|
+
export interface Assignment {
|
|
215
|
+
type: 'assignment';
|
|
216
|
+
nodeKey?: string;
|
|
217
|
+
targetName: string;
|
|
218
|
+
targetPath?: AttributePathSegment[];
|
|
219
|
+
command?: CommandCall;
|
|
220
|
+
literalValue?: Value;
|
|
221
|
+
literalValueType?: 'string' | 'number' | 'boolean' | 'null' | 'object' | 'array';
|
|
222
|
+
isLastValue?: boolean;
|
|
223
|
+
isSet?: boolean;
|
|
224
|
+
isVar?: boolean;
|
|
225
|
+
isConst?: boolean;
|
|
226
|
+
hasAs?: boolean;
|
|
227
|
+
isImplicit?: boolean;
|
|
228
|
+
fallbackValue?: Value;
|
|
229
|
+
fallbackValueType?: 'string' | 'number' | 'boolean' | 'null';
|
|
230
|
+
comments?: CommentWithPosition[];
|
|
231
|
+
decorators?: DecoratorCall[];
|
|
232
|
+
trailingBlankLines?: number;
|
|
233
|
+
codePos: CodePosition;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Represents a shorthand assignment (e.g., $var = $)
|
|
237
|
+
*/
|
|
238
|
+
export interface ShorthandAssignment {
|
|
239
|
+
type: 'shorthand';
|
|
240
|
+
nodeKey?: string;
|
|
241
|
+
targetName: string;
|
|
242
|
+
comments?: CommentWithPosition[];
|
|
243
|
+
trailingBlankLines?: number;
|
|
244
|
+
codePos: CodePosition;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Represents an inline if statement (e.g., if condition then command [else command])
|
|
248
|
+
*/
|
|
249
|
+
export interface InlineIf {
|
|
250
|
+
type: 'inlineIf';
|
|
251
|
+
nodeKey?: string;
|
|
252
|
+
condition: Expression;
|
|
253
|
+
command: Statement;
|
|
254
|
+
elseCommand?: Statement;
|
|
255
|
+
comments?: CommentWithPosition[];
|
|
256
|
+
trailingBlankLines?: number;
|
|
257
|
+
codePos: CodePosition;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Represents an if/elseif/else block
|
|
261
|
+
*/
|
|
262
|
+
export interface IfBlock {
|
|
263
|
+
type: 'ifBlock';
|
|
264
|
+
nodeKey?: string;
|
|
265
|
+
condition: Expression;
|
|
266
|
+
thenBranch: Statement[];
|
|
267
|
+
elseBranch?: Statement[];
|
|
268
|
+
elseHasThen?: boolean;
|
|
269
|
+
elseKeywordPos?: CodePosition;
|
|
270
|
+
elseifBranches?: Array<{
|
|
271
|
+
condition: Expression;
|
|
272
|
+
body: Statement[];
|
|
273
|
+
hasThen?: boolean;
|
|
274
|
+
keywordPos?: CodePosition;
|
|
275
|
+
}>;
|
|
276
|
+
decorators?: DecoratorCall[];
|
|
277
|
+
comments?: CommentWithPosition[];
|
|
278
|
+
trailingBlankLines?: number;
|
|
279
|
+
codePos: CodePosition;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Represents an iftrue statement (e.g., iftrue command)
|
|
283
|
+
*/
|
|
284
|
+
export interface IfTrue {
|
|
285
|
+
type: 'ifTrue';
|
|
286
|
+
nodeKey?: string;
|
|
287
|
+
command: Statement;
|
|
288
|
+
comments?: CommentWithPosition[];
|
|
289
|
+
trailingBlankLines?: number;
|
|
290
|
+
codePos: CodePosition;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Represents an iffalse statement (e.g., iffalse command)
|
|
294
|
+
*/
|
|
295
|
+
export interface IfFalse {
|
|
296
|
+
type: 'ifFalse';
|
|
297
|
+
nodeKey?: string;
|
|
298
|
+
command: Statement;
|
|
299
|
+
comments?: CommentWithPosition[];
|
|
300
|
+
trailingBlankLines?: number;
|
|
301
|
+
codePos: CodePosition;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Represents a function definition (def/enddef)
|
|
305
|
+
*/
|
|
306
|
+
export interface DefineFunction {
|
|
307
|
+
type: 'define';
|
|
308
|
+
nodeKey?: string;
|
|
309
|
+
name: string;
|
|
310
|
+
paramNames: string[];
|
|
311
|
+
body: Statement[];
|
|
312
|
+
decorators?: DecoratorCall[];
|
|
313
|
+
comments?: CommentWithPosition[];
|
|
314
|
+
trailingBlankLines?: number;
|
|
315
|
+
codePos: CodePosition;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Represents a scope block (do/enddo)
|
|
319
|
+
*/
|
|
320
|
+
export interface ScopeBlock {
|
|
321
|
+
type: 'do';
|
|
322
|
+
nodeKey?: string;
|
|
323
|
+
paramNames?: string[];
|
|
324
|
+
body: Statement[];
|
|
325
|
+
into?: {
|
|
326
|
+
targetName: string;
|
|
327
|
+
targetPath?: AttributePathSegment[];
|
|
328
|
+
};
|
|
329
|
+
decorators?: DecoratorCall[];
|
|
330
|
+
comments?: CommentWithPosition[];
|
|
331
|
+
trailingBlankLines?: number;
|
|
332
|
+
codePos: CodePosition;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Represents a together block (together/endtogether)
|
|
336
|
+
*/
|
|
337
|
+
export interface TogetherBlock {
|
|
338
|
+
type: 'together';
|
|
339
|
+
nodeKey?: string;
|
|
340
|
+
blocks: ScopeBlock[];
|
|
341
|
+
decorators?: DecoratorCall[];
|
|
342
|
+
comments?: CommentWithPosition[];
|
|
343
|
+
trailingBlankLines?: number;
|
|
344
|
+
codePos: CodePosition;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Represents a for loop (for/endfor)
|
|
348
|
+
*/
|
|
349
|
+
export interface ForLoop {
|
|
350
|
+
type: 'forLoop';
|
|
351
|
+
nodeKey?: string;
|
|
352
|
+
varName: string;
|
|
353
|
+
iterable?: Expression;
|
|
354
|
+
from?: Expression;
|
|
355
|
+
to?: Expression;
|
|
356
|
+
step?: Expression;
|
|
357
|
+
keyVarName?: string;
|
|
358
|
+
body: Statement[];
|
|
359
|
+
decorators?: DecoratorCall[];
|
|
360
|
+
comments?: CommentWithPosition[];
|
|
361
|
+
trailingBlankLines?: number;
|
|
362
|
+
codePos: CodePosition;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Represents a return statement
|
|
366
|
+
*/
|
|
367
|
+
export interface ReturnStatement {
|
|
368
|
+
type: 'return';
|
|
369
|
+
nodeKey?: string;
|
|
370
|
+
value?: Arg;
|
|
371
|
+
comments?: CommentWithPosition[];
|
|
372
|
+
trailingBlankLines?: number;
|
|
373
|
+
codePos: CodePosition;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Represents a break statement
|
|
377
|
+
*/
|
|
378
|
+
export interface BreakStatement {
|
|
379
|
+
type: 'break';
|
|
380
|
+
nodeKey?: string;
|
|
381
|
+
comments?: CommentWithPosition[];
|
|
382
|
+
trailingBlankLines?: number;
|
|
383
|
+
codePos: CodePosition;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Represents a continue statement
|
|
387
|
+
*/
|
|
388
|
+
export interface ContinueStatement {
|
|
389
|
+
type: 'continue';
|
|
390
|
+
nodeKey?: string;
|
|
391
|
+
comments?: CommentWithPosition[];
|
|
392
|
+
trailingBlankLines?: number;
|
|
393
|
+
codePos: CodePosition;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Represents an event handler block (on/endon)
|
|
397
|
+
*/
|
|
398
|
+
export interface OnBlock {
|
|
399
|
+
type: 'onBlock';
|
|
400
|
+
nodeKey?: string;
|
|
401
|
+
eventName: string;
|
|
402
|
+
body: Statement[];
|
|
403
|
+
decorators?: DecoratorCall[];
|
|
404
|
+
comments?: CommentWithPosition[];
|
|
405
|
+
trailingBlankLines?: number;
|
|
406
|
+
codePos: CodePosition;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Represents a cell block (---cell <cellType> <meta...>--- ... ---end---)
|
|
410
|
+
*/
|
|
411
|
+
export interface CellBlock {
|
|
412
|
+
type: 'cell';
|
|
413
|
+
nodeKey?: string;
|
|
414
|
+
cellType: string;
|
|
415
|
+
meta: Record<string, string>;
|
|
416
|
+
rawBody: string;
|
|
417
|
+
body?: Statement[];
|
|
418
|
+
headerPos: CodePosition;
|
|
419
|
+
bodyPos: CodePosition;
|
|
420
|
+
codePos: CodePosition;
|
|
421
|
+
comments?: CommentWithPosition[];
|
|
422
|
+
trailingBlankLines?: number;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Represents a prompt block statement (--- ... ---)
|
|
426
|
+
*/
|
|
427
|
+
export interface PromptBlockStatement {
|
|
428
|
+
type: 'prompt_block';
|
|
429
|
+
nodeKey?: string;
|
|
430
|
+
rawText: string;
|
|
431
|
+
fence: '---';
|
|
432
|
+
codePos: CodePosition;
|
|
433
|
+
openPos: CodePosition;
|
|
434
|
+
bodyPos: CodePosition;
|
|
435
|
+
closePos: CodePosition;
|
|
436
|
+
comments?: CommentWithPosition[];
|
|
437
|
+
trailingBlankLines?: number;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Represents a chunk marker statement (--- chunk:<id> ---)
|
|
441
|
+
*/
|
|
442
|
+
export interface ChunkMarkerStatement {
|
|
443
|
+
type: 'chunk_marker';
|
|
444
|
+
nodeKey?: string;
|
|
445
|
+
id: string;
|
|
446
|
+
meta?: Record<string, string>;
|
|
447
|
+
codePos: CodePosition;
|
|
448
|
+
raw?: string;
|
|
449
|
+
comments?: CommentWithPosition[];
|
|
450
|
+
trailingBlankLines?: number;
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Union type representing all possible statement types in the AST
|
|
454
|
+
*/
|
|
455
|
+
export type Statement = CommandCall | Assignment | ShorthandAssignment | InlineIf | IfBlock | IfTrue | IfFalse | DefineFunction | ScopeBlock | TogetherBlock | ForLoop | ReturnStatement | BreakStatement | ContinueStatement | OnBlock | CommentStatement | ChunkMarkerStatement | CellBlock | PromptBlockStatement;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Value } from '../utils';
|
|
2
|
+
import { DefineFunction, OnBlock, Arg } from './Ast.type';
|
|
3
|
+
export type BuiltinCallback = (callbackArgs: Value[]) => Promise<Value> | Value | null;
|
|
4
|
+
export type BuiltinHandler = (args: Value[], callback?: BuiltinCallback | null) => Promise<Value> | Value | null;
|
|
5
|
+
export type DecoratorHandler = (targetName: string, func: DefineFunction | null, originalArgs: Value[], decoratorArgs: Value[], originalDecoratorArgs?: Arg[]) => Promise<Value[] | Value | null | undefined>;
|
|
6
|
+
export type ParseDecoratorHandler = (targetName: string, func: DefineFunction | null, decoratorArgs: Arg[], environment: Environment) => Promise<void> | void;
|
|
7
|
+
export interface Environment {
|
|
8
|
+
variables: Map<string, Value>;
|
|
9
|
+
functions: Map<string, DefineFunction>;
|
|
10
|
+
builtins: Map<string, BuiltinHandler>;
|
|
11
|
+
decorators: Map<string, DecoratorHandler>;
|
|
12
|
+
parseDecorators: Map<string, ParseDecoratorHandler>;
|
|
13
|
+
metadata: Map<string, FunctionMetadata>;
|
|
14
|
+
moduleMetadata: Map<string, ModuleMetadata>;
|
|
15
|
+
currentModule: string | null;
|
|
16
|
+
variableMetadata: Map<string, Map<string, Value>>;
|
|
17
|
+
functionMetadata: Map<string, Map<string, Value>>;
|
|
18
|
+
constants: Set<string>;
|
|
19
|
+
eventHandlers: Map<string, OnBlock[]>;
|
|
20
|
+
}
|
|
21
|
+
export interface Frame {
|
|
22
|
+
locals: Map<string, Value>;
|
|
23
|
+
lastValue: Value;
|
|
24
|
+
isFunctionFrame?: boolean;
|
|
25
|
+
forgotten?: Set<string>;
|
|
26
|
+
isIsolatedScope?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export type DataType = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null' | 'any';
|
|
29
|
+
export type FormInputType = 'text' | 'number' | 'textarea' | 'select' | 'checkbox' | 'radio' | 'date' | 'datetime' | 'file' | 'json' | 'code' | 'varname';
|
|
30
|
+
export interface ParameterMetadata {
|
|
31
|
+
name: string;
|
|
32
|
+
label?: string;
|
|
33
|
+
dataType: DataType;
|
|
34
|
+
description: string;
|
|
35
|
+
formInputType: FormInputType;
|
|
36
|
+
required?: boolean;
|
|
37
|
+
defaultValue?: Value;
|
|
38
|
+
children?: ParameterMetadata;
|
|
39
|
+
}
|
|
40
|
+
export interface FunctionMetadata {
|
|
41
|
+
description: string;
|
|
42
|
+
parameters: ParameterMetadata[];
|
|
43
|
+
returnType: DataType;
|
|
44
|
+
returnDescription: string;
|
|
45
|
+
example?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface ModuleMetadata {
|
|
48
|
+
description: string;
|
|
49
|
+
methods: string[];
|
|
50
|
+
author?: string;
|
|
51
|
+
category?: string;
|
|
52
|
+
doc_url?: string;
|
|
53
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Value } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Utility function to extract named arguments from function call arguments.
|
|
4
|
+
* Named arguments are passed as the last argument (an object with string keys).
|
|
5
|
+
*
|
|
6
|
+
* @param args The arguments array passed to a BuiltinHandler
|
|
7
|
+
* @returns An object with `positionalArgs` (Value[]) and `namedArgs` (Record<string, Value>)
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* export const MyFunctions: Record<string, BuiltinHandler> = {
|
|
12
|
+
* myFunction: (args) => {
|
|
13
|
+
* const { positionalArgs, namedArgs } = extractNamedArgs(args);
|
|
14
|
+
* const url = namedArgs.url || positionalArgs[0];
|
|
15
|
+
* const body = namedArgs.body || positionalArgs[1];
|
|
16
|
+
* // ... use url and body
|
|
17
|
+
* }
|
|
18
|
+
* };
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractNamedArgs(args: Value[]): {
|
|
22
|
+
positionalArgs: Value[];
|
|
23
|
+
namedArgs: Record<string, Value>;
|
|
24
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CodePosition } from '../types/Ast.type';
|
|
2
|
+
import { Token } from '../classes/Lexer';
|
|
3
|
+
export interface ErrorContext {
|
|
4
|
+
codePos?: CodePosition;
|
|
5
|
+
code?: string;
|
|
6
|
+
token?: Token;
|
|
7
|
+
message: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Format an error message with code context
|
|
11
|
+
*
|
|
12
|
+
* @param context - Error context with position and code information
|
|
13
|
+
* @returns Formatted error message with code snippet
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatErrorWithContext(context: ErrorContext): string;
|
|
16
|
+
/**
|
|
17
|
+
* Create an error with code context
|
|
18
|
+
*
|
|
19
|
+
* @param context - Error context
|
|
20
|
+
* @returns Error object with formatted message
|
|
21
|
+
*/
|
|
22
|
+
export declare function createErrorWithContext(context: ErrorContext): Error;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { AttributePathSegment } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Split a script into logical lines, respecting strings, $() subexpressions, and backslash continuation.
|
|
4
|
+
* Treats ; and \n as line separators, but only at the top level (not inside strings or $()).
|
|
5
|
+
* Handles backslash line continuation: lines ending with \ are joined with the next line.
|
|
6
|
+
*/
|
|
7
|
+
export declare function splitIntoLogicalLines(script: string): string[];
|
|
8
|
+
/**
|
|
9
|
+
* Handle backslash line continuation.
|
|
10
|
+
* Lines ending with \ are joined with the next line, removing the backslash
|
|
11
|
+
* and replacing the newline + leading whitespace with a single space.
|
|
12
|
+
*/
|
|
13
|
+
export declare function handleBackslashContinuation(script: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Lexer utility functions for token parsing
|
|
16
|
+
*/
|
|
17
|
+
export declare class LexerUtils {
|
|
18
|
+
static parseString(token: string): string;
|
|
19
|
+
static isString(token: string): boolean;
|
|
20
|
+
static isNumber(token: string): boolean;
|
|
21
|
+
static isInteger(token: string): boolean;
|
|
22
|
+
static isVariable(token: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Parse attribute access path from a variable token
|
|
25
|
+
* Returns the base variable name and path segments
|
|
26
|
+
* If name is empty string, it means the last value ($) with attributes
|
|
27
|
+
*/
|
|
28
|
+
static parseVariablePath(token: string): {
|
|
29
|
+
name: string;
|
|
30
|
+
path: AttributePathSegment[];
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Parse a dynamic key from inside brackets: [$varName] or [$varName.property]
|
|
34
|
+
* @param str The full string being parsed
|
|
35
|
+
* @param pos Position right after the '$' character
|
|
36
|
+
* @returns The parsed segment and the position after the closing ']'
|
|
37
|
+
*/
|
|
38
|
+
private static parseDynamicKey;
|
|
39
|
+
static isLastValue(token: string): boolean;
|
|
40
|
+
static isPositionalParam(token: string): boolean;
|
|
41
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for utility functions
|
|
3
|
+
*/
|
|
4
|
+
export type Value = string | number | boolean | null | object;
|
|
5
|
+
export type AttributePathSegment = {
|
|
6
|
+
type: 'property';
|
|
7
|
+
name: string;
|
|
8
|
+
} | {
|
|
9
|
+
type: 'index';
|
|
10
|
+
index: number;
|
|
11
|
+
} | {
|
|
12
|
+
type: 'dynamicKey';
|
|
13
|
+
variable: string;
|
|
14
|
+
varPath?: AttributePathSegment[];
|
|
15
|
+
};
|