@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
package/README.md
ADDED
|
@@ -0,0 +1,856 @@
|
|
|
1
|
+
# RobinPath
|
|
2
|
+
|
|
3
|
+
A scripting language interpreter with a REPL interface and built-in modules for math, strings, JSON, time, arrays, and more.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install RobinPath as a dependency in your project:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i @wiredwp/robinpath
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Integration
|
|
14
|
+
|
|
15
|
+
### Basic Usage
|
|
16
|
+
|
|
17
|
+
Import and create a `RobinPath` instance to execute scripts in your application:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { RobinPath } from '@wiredwp/robinpath';
|
|
21
|
+
|
|
22
|
+
// Create an interpreter instance
|
|
23
|
+
const rp = new RobinPath();
|
|
24
|
+
|
|
25
|
+
// Execute a script
|
|
26
|
+
const result = await rp.executeScript(`
|
|
27
|
+
add 10 20
|
|
28
|
+
multiply $ 2
|
|
29
|
+
`);
|
|
30
|
+
|
|
31
|
+
console.log('Result:', result); // 60
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### REPL Mode (Persistent State)
|
|
35
|
+
|
|
36
|
+
Use `executeLine()` for REPL-like behavior where state persists between calls:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
const rp = new RobinPath();
|
|
40
|
+
|
|
41
|
+
// First line - sets $result
|
|
42
|
+
await rp.executeLine('$result = add 10 20');
|
|
43
|
+
console.log(rp.getLastValue()); // 30
|
|
44
|
+
|
|
45
|
+
// Second line - uses previous result
|
|
46
|
+
await rp.executeLine('multiply $result 2');
|
|
47
|
+
console.log(rp.getLastValue()); // 60
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Working with Variables
|
|
51
|
+
|
|
52
|
+
Get and set variables programmatically:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
const rp = new RobinPath();
|
|
56
|
+
|
|
57
|
+
// Set a variable from JavaScript
|
|
58
|
+
rp.setVariable('name', 'Alice');
|
|
59
|
+
rp.setVariable('age', 25);
|
|
60
|
+
|
|
61
|
+
// Execute script that uses the variable
|
|
62
|
+
await rp.executeScript(`
|
|
63
|
+
log "Hello" $name
|
|
64
|
+
log "Age:" $age
|
|
65
|
+
`);
|
|
66
|
+
|
|
67
|
+
// Get a variable value
|
|
68
|
+
const name = rp.getVariable('name');
|
|
69
|
+
console.log(name); // "Alice"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Threads (Isolated Execution Contexts)
|
|
73
|
+
|
|
74
|
+
Create isolated execution contexts with threads:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const rp = new RobinPath({ threadControl: true });
|
|
78
|
+
|
|
79
|
+
// Create a new thread
|
|
80
|
+
const thread1 = rp.createThread('user-123');
|
|
81
|
+
await thread1.executeScript('$count = 10');
|
|
82
|
+
|
|
83
|
+
// Create another thread with separate variables
|
|
84
|
+
const thread2 = rp.createThread('user-456');
|
|
85
|
+
await thread2.executeScript('$count = 20');
|
|
86
|
+
|
|
87
|
+
// Each thread maintains its own state
|
|
88
|
+
console.log(thread1.getVariable('count')); // 10
|
|
89
|
+
console.log(thread2.getVariable('count')); // 20
|
|
90
|
+
|
|
91
|
+
// Switch between threads
|
|
92
|
+
rp.useThread('user-123');
|
|
93
|
+
console.log(rp.currentThread?.getVariable('count')); // 10
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Registering Custom Functions
|
|
97
|
+
|
|
98
|
+
Extend RobinPath with your own builtin functions:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const rp = new RobinPath();
|
|
102
|
+
|
|
103
|
+
// Register a simple builtin
|
|
104
|
+
rp.registerBuiltin('greet', (args) => {
|
|
105
|
+
const name = String(args[0] ?? 'World');
|
|
106
|
+
return `Hello, ${name}!`;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Use it in scripts
|
|
110
|
+
await rp.executeScript('greet "Alice"');
|
|
111
|
+
console.log(rp.getLastValue()); // "Hello, Alice!"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Registering Custom Modules
|
|
115
|
+
|
|
116
|
+
Create and register custom modules:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
const rp = new RobinPath();
|
|
120
|
+
|
|
121
|
+
// Register module functions
|
|
122
|
+
rp.registerModule('myapp', {
|
|
123
|
+
process: (args) => {
|
|
124
|
+
const data = args[0];
|
|
125
|
+
// Process data...
|
|
126
|
+
return processedData;
|
|
127
|
+
},
|
|
128
|
+
validate: (args) => {
|
|
129
|
+
const input = args[0];
|
|
130
|
+
return isValid(input);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Register function metadata for documentation
|
|
135
|
+
rp.registerModuleFunctionMeta('myapp', 'process', {
|
|
136
|
+
description: 'Processes input data',
|
|
137
|
+
parameters: [
|
|
138
|
+
{
|
|
139
|
+
name: 'data',
|
|
140
|
+
dataType: 'object',
|
|
141
|
+
description: 'Data to process',
|
|
142
|
+
formInputType: 'json',
|
|
143
|
+
required: true
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
returnType: 'object',
|
|
147
|
+
returnDescription: 'Processed data'
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// Register module-level metadata
|
|
151
|
+
rp.registerModuleInfo('myapp', {
|
|
152
|
+
description: 'Custom application module',
|
|
153
|
+
methods: ['process', 'validate']
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Use in scripts
|
|
157
|
+
await rp.executeScript(`
|
|
158
|
+
use myapp
|
|
159
|
+
myapp.process $data
|
|
160
|
+
`);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Getting Available Commands
|
|
164
|
+
|
|
165
|
+
Query available commands for autocomplete or help:
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
const rp = new RobinPath();
|
|
169
|
+
|
|
170
|
+
const commands = rp.getAvailableCommands();
|
|
171
|
+
console.log(commands.native); // Native commands (if, def, etc.)
|
|
172
|
+
console.log(commands.builtin); // Root-level builtins
|
|
173
|
+
console.log(commands.modules); // Available modules
|
|
174
|
+
console.log(commands.moduleFunctions); // Module.function names
|
|
175
|
+
console.log(commands.userFunctions); // User-defined functions
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### AST with Execution State
|
|
179
|
+
|
|
180
|
+
Get the AST with execution state for debugging or visualization:
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
const rp = new RobinPath({ threadControl: true });
|
|
184
|
+
const thread = rp.createThread('debug');
|
|
185
|
+
|
|
186
|
+
const script = `
|
|
187
|
+
add 5 5
|
|
188
|
+
$result = $
|
|
189
|
+
if $result > 5
|
|
190
|
+
multiply $result 2
|
|
191
|
+
endif
|
|
192
|
+
`;
|
|
193
|
+
|
|
194
|
+
const astResult = await thread.getASTWithState(script);
|
|
195
|
+
console.log(astResult.ast); // AST with lastValue at each node
|
|
196
|
+
console.log(astResult.variables); // Thread and global variables
|
|
197
|
+
console.log(astResult.lastValue); // Final result
|
|
198
|
+
console.log(astResult.callStack); // Call stack frames
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Checking for Incomplete Blocks
|
|
202
|
+
|
|
203
|
+
Check if a script needs more input (useful for multi-line input):
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
const rp = new RobinPath();
|
|
207
|
+
|
|
208
|
+
const check1 = rp.needsMoreInput('if $x > 5');
|
|
209
|
+
console.log(check1); // { needsMore: true, waitingFor: 'endif' }
|
|
210
|
+
|
|
211
|
+
const check2 = rp.needsMoreInput('if $x > 5\n log "yes"\nendif');
|
|
212
|
+
console.log(check2); // { needsMore: false }
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Error Handling
|
|
216
|
+
|
|
217
|
+
Handle errors from script execution:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
const rp = new RobinPath();
|
|
221
|
+
|
|
222
|
+
try {
|
|
223
|
+
await rp.executeScript('unknown_function 123');
|
|
224
|
+
} catch (error) {
|
|
225
|
+
console.error('Script error:', error.message);
|
|
226
|
+
// "Unknown function: unknown_function"
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## CLI Usage
|
|
231
|
+
|
|
232
|
+
### Installation
|
|
233
|
+
|
|
234
|
+
Install globally to use the `robinpath` command:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
npm i -g @wiredwp/robinpath
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Or use it directly with `npx`:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
npx @wiredwp/robinpath
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Starting the REPL
|
|
247
|
+
|
|
248
|
+
Start the interactive REPL:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
robinpath
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Or if installed locally:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
npm run cli
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
This will start an interactive session where you can type commands and see results immediately.
|
|
261
|
+
|
|
262
|
+
### REPL Commands
|
|
263
|
+
|
|
264
|
+
- `help` or `.help` - Show help message
|
|
265
|
+
- `exit`, `quit`, `.exit`, `.quit` - Exit the REPL
|
|
266
|
+
- `clear` or `.clear` - Clear the screen
|
|
267
|
+
- `..` - Show all available commands as JSON
|
|
268
|
+
|
|
269
|
+
### REPL Features
|
|
270
|
+
|
|
271
|
+
**Multi-line Blocks:**
|
|
272
|
+
The REPL automatically detects incomplete blocks and waits for completion:
|
|
273
|
+
|
|
274
|
+
```robinpath
|
|
275
|
+
> if $x > 5
|
|
276
|
+
... log "yes"
|
|
277
|
+
... endif
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Backslash Line Continuation:**
|
|
281
|
+
Use `\` at the end of a line to continue the command on the next line:
|
|
282
|
+
|
|
283
|
+
```robinpath
|
|
284
|
+
> log "this is a very long message " \
|
|
285
|
+
... "that continues on the next line"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
The backslash continuation works with any statement type and can be chained across multiple lines.
|
|
289
|
+
|
|
290
|
+
**Thread Management:**
|
|
291
|
+
When thread control is enabled, the prompt shows the current thread and module:
|
|
292
|
+
|
|
293
|
+
```robinpath
|
|
294
|
+
default@math> add 5 5
|
|
295
|
+
10
|
|
296
|
+
default@math> use clear
|
|
297
|
+
Cleared module context
|
|
298
|
+
default> thread list
|
|
299
|
+
Threads:
|
|
300
|
+
- default (current)
|
|
301
|
+
- user-123
|
|
302
|
+
default> thread use user-123
|
|
303
|
+
Switched to thread: user-123
|
|
304
|
+
user-123>
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**Module Context:**
|
|
308
|
+
The prompt shows the current module when using `use`:
|
|
309
|
+
|
|
310
|
+
```robinpath
|
|
311
|
+
> use math
|
|
312
|
+
Using module: math
|
|
313
|
+
default@math> add 5 5
|
|
314
|
+
10
|
|
315
|
+
default@math> use clear
|
|
316
|
+
Cleared module context
|
|
317
|
+
default>
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Basic Syntax
|
|
321
|
+
|
|
322
|
+
### Commands
|
|
323
|
+
|
|
324
|
+
Commands are executed by typing the command name followed by arguments:
|
|
325
|
+
|
|
326
|
+
```robinpath
|
|
327
|
+
add 10 20
|
|
328
|
+
log "Hello, World!"
|
|
329
|
+
multiply 5 3
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Variables
|
|
333
|
+
|
|
334
|
+
Variables are prefixed with `$`:
|
|
335
|
+
|
|
336
|
+
```robinpath
|
|
337
|
+
$name = "Alice"
|
|
338
|
+
$age = 25
|
|
339
|
+
log $name $age
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
You can declare variables with `var` (mutable) or `const` (immutable):
|
|
343
|
+
|
|
344
|
+
```robinpath
|
|
345
|
+
var $count 0
|
|
346
|
+
const $MAX_RETRIES 5
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Last Value Reference
|
|
350
|
+
|
|
351
|
+
Use `$` to reference the last computed value:
|
|
352
|
+
|
|
353
|
+
```robinpath
|
|
354
|
+
add 10 20
|
|
355
|
+
multiply $ 2 # Uses 30 (result of add)
|
|
356
|
+
log $ # Prints 60
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Shorthand Assignment
|
|
360
|
+
|
|
361
|
+
Assign the last value to a variable by simply referencing it:
|
|
362
|
+
|
|
363
|
+
```robinpath
|
|
364
|
+
add 5 3
|
|
365
|
+
$sum # Assigns 8 to $sum
|
|
366
|
+
log $sum # Prints 8
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Variable-to-Variable Assignment
|
|
370
|
+
|
|
371
|
+
Assign the value of one variable to another, including chained assignments:
|
|
372
|
+
|
|
373
|
+
```robinpath
|
|
374
|
+
$city = "New York"
|
|
375
|
+
$city2 = $city # Copies "New York" to $city2
|
|
376
|
+
log $city2 # Prints "New York"
|
|
377
|
+
|
|
378
|
+
$number1 = 42
|
|
379
|
+
$number2 = $number1 # Copies 42 to $number2
|
|
380
|
+
$number3 = $number2 # Can chain assignments
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### Into Syntax
|
|
384
|
+
|
|
385
|
+
Use `into $variable` to assign the result of a command, block, or function call directly to a variable:
|
|
386
|
+
|
|
387
|
+
```robinpath
|
|
388
|
+
math.add 10 20 into $sum
|
|
389
|
+
log $sum # Prints 30
|
|
390
|
+
|
|
391
|
+
# Works with functions
|
|
392
|
+
myFunction(1 2) into $result
|
|
393
|
+
|
|
394
|
+
# Works with do blocks
|
|
395
|
+
do into $blockResult
|
|
396
|
+
math.add 5 5
|
|
397
|
+
math.multiply $ 2
|
|
398
|
+
enddo
|
|
399
|
+
|
|
400
|
+
# Works with repeat loops
|
|
401
|
+
repeat 3 with into $total
|
|
402
|
+
add $2 10
|
|
403
|
+
endwith
|
|
404
|
+
|
|
405
|
+
# Works with object property assignment
|
|
406
|
+
math.add 1 2 into $obj.sum
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Attribute Access and Array Indexing
|
|
410
|
+
|
|
411
|
+
RobinPath supports accessing object properties and array elements directly using dot notation and bracket notation:
|
|
412
|
+
|
|
413
|
+
**Property Access:**
|
|
414
|
+
```robinpath
|
|
415
|
+
json.parse '{"name": "John", "age": 30, "address": {"city": "NYC"}}'
|
|
416
|
+
$user = $
|
|
417
|
+
|
|
418
|
+
# Access properties using dot notation
|
|
419
|
+
log $user.name # Prints "John"
|
|
420
|
+
log $user.age # Prints 30
|
|
421
|
+
log $user.address.city # Prints "NYC" (nested property access)
|
|
422
|
+
|
|
423
|
+
# Use in expressions
|
|
424
|
+
if $user.age >= 18
|
|
425
|
+
log "Adult"
|
|
426
|
+
endif
|
|
427
|
+
|
|
428
|
+
# Use as function arguments
|
|
429
|
+
math.add $user.age 5 # Adds 30 + 5 = 35
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Array Indexing:**
|
|
433
|
+
```robinpath
|
|
434
|
+
$arr = range 10 15
|
|
435
|
+
log $arr[0] # Prints 10 (first element)
|
|
436
|
+
log $arr[2] # Prints 12 (third element)
|
|
437
|
+
log $arr[5] # Prints 15 (last element)
|
|
438
|
+
|
|
439
|
+
# Out of bounds access returns null
|
|
440
|
+
log $arr[10] # Prints null
|
|
441
|
+
|
|
442
|
+
# Use in expressions
|
|
443
|
+
if $arr[0] == 10
|
|
444
|
+
log "First is 10"
|
|
445
|
+
endif
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
**Combined Access:**
|
|
449
|
+
You can combine property access and array indexing:
|
|
450
|
+
```robinpath
|
|
451
|
+
json.parse '{"items": [{"name": "item1", "price": 10}, {"name": "item2", "price": 20}]}'
|
|
452
|
+
$data = $
|
|
453
|
+
|
|
454
|
+
log $data.items[0].name # Prints "item1"
|
|
455
|
+
log $data.items[0].price # Prints 10
|
|
456
|
+
log $data.items[1].name # Prints "item2"
|
|
457
|
+
|
|
458
|
+
# Assign to variables
|
|
459
|
+
$firstItem = $data.items[0].name
|
|
460
|
+
log $firstItem # Prints "item1"
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
**Error Handling:**
|
|
464
|
+
- Accessing a property of `null` or `undefined` throws an error.
|
|
465
|
+
- Accessing a property of a non-object throws an error.
|
|
466
|
+
- Array indexing on a non-array throws an error.
|
|
467
|
+
- Out-of-bounds array access returns `null`.
|
|
468
|
+
|
|
469
|
+
**Note:** Assignment targets must be simple variable names or object/array paths:
|
|
470
|
+
```robinpath
|
|
471
|
+
$user.name = "Jane" # Supported
|
|
472
|
+
$arr[0] = 42 # Supported
|
|
473
|
+
$data.items[0].price = 99 # Deep assignment supported
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Native Reserved Methods
|
|
477
|
+
|
|
478
|
+
RobinPath includes several built-in reserved methods:
|
|
479
|
+
|
|
480
|
+
**`log` - Output values:**
|
|
481
|
+
```robinpath
|
|
482
|
+
log "Hello, World!"
|
|
483
|
+
log $name $age
|
|
484
|
+
log "Result:" $(add 5 5)
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
**`obj` - Create objects using JSON5 syntax or builder pattern:**
|
|
488
|
+
```robinpath
|
|
489
|
+
# Create empty object
|
|
490
|
+
obj
|
|
491
|
+
$empty = $
|
|
492
|
+
|
|
493
|
+
# Create object with JSON5 syntax
|
|
494
|
+
obj '{name: "John", age: 30}'
|
|
495
|
+
$user = $
|
|
496
|
+
|
|
497
|
+
# Create object with key-value pairs (builder style)
|
|
498
|
+
obj name "John" age 30
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
**`array` - Create arrays from arguments:**
|
|
502
|
+
```robinpath
|
|
503
|
+
# Create empty array
|
|
504
|
+
array
|
|
505
|
+
$empty = $
|
|
506
|
+
|
|
507
|
+
# Create array with elements
|
|
508
|
+
array 1 2 3
|
|
509
|
+
$numbers = $
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
**`set` - Assign a value:**
|
|
513
|
+
```robinpath
|
|
514
|
+
set $var "value"
|
|
515
|
+
set $var as "value" # 'as' is optional
|
|
516
|
+
set $obj.prop "value" # path assignment
|
|
517
|
+
|
|
518
|
+
# Set with fallback (used if value is null/empty)
|
|
519
|
+
set $var $maybeNull "default value"
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
**`get` - Get a value by path:**
|
|
523
|
+
```robinpath
|
|
524
|
+
get $user "address.city"
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
**`assign` - Assign a value to a variable (with optional fallback):**
|
|
528
|
+
```robinpath
|
|
529
|
+
# Basic assignment
|
|
530
|
+
assign $myVar "hello"
|
|
531
|
+
|
|
532
|
+
# Assignment with fallback (3rd parameter used if 2nd is empty/null)
|
|
533
|
+
assign $result $maybeEmpty "default value"
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
**`empty` - Clear/empty a variable:**
|
|
537
|
+
```robinpath
|
|
538
|
+
$myVar = "some value"
|
|
539
|
+
empty $myVar
|
|
540
|
+
log $myVar # Prints null
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
**`fallback` - Return variable value or fallback if empty/null:**
|
|
544
|
+
```robinpath
|
|
545
|
+
$maybeEmpty = null
|
|
546
|
+
fallback $maybeEmpty "default value" # Returns "default value"
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
**`meta` / `getMeta` - Manage metadata:**
|
|
550
|
+
```robinpath
|
|
551
|
+
# Set metadata for variables, functions, or constants
|
|
552
|
+
meta $var description "Description"
|
|
553
|
+
meta myFunction author "Author"
|
|
554
|
+
meta $const version "1.0"
|
|
555
|
+
|
|
556
|
+
# Get metadata
|
|
557
|
+
getMeta $var description
|
|
558
|
+
getMeta myFunction author
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
**`clear` - Clear the last return value ($):**
|
|
562
|
+
```robinpath
|
|
563
|
+
math.add 10 20
|
|
564
|
+
clear
|
|
565
|
+
log $ # Prints null
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
**`forget` - Hide a variable or function in the current scope:**
|
|
569
|
+
```robinpath
|
|
570
|
+
$val = 10
|
|
571
|
+
do
|
|
572
|
+
forget $val
|
|
573
|
+
log $val # Prints null
|
|
574
|
+
enddo
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
**`getType` - Get the type of a variable:**
|
|
578
|
+
```robinpath
|
|
579
|
+
getType "hello" # "string"
|
|
580
|
+
getType 42 # "number"
|
|
581
|
+
getType true # "boolean"
|
|
582
|
+
getType null # "null"
|
|
583
|
+
getType [] # "array"
|
|
584
|
+
getType {} # "object"
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
**`has` - Check if a variable or function exists:**
|
|
588
|
+
```robinpath
|
|
589
|
+
has $var
|
|
590
|
+
has myFunction
|
|
591
|
+
has math.add
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
**`end` - Stop script execution:**
|
|
595
|
+
```robinpath
|
|
596
|
+
log "Start"
|
|
597
|
+
end
|
|
598
|
+
log "This is never reached"
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### Do Blocks (Scopes)
|
|
602
|
+
|
|
603
|
+
`do` blocks create a new scope. Variables defined inside are local to the scope.
|
|
604
|
+
|
|
605
|
+
```robinpath
|
|
606
|
+
do
|
|
607
|
+
$local = 10
|
|
608
|
+
enddo
|
|
609
|
+
log $local # Prints null (if not defined globally)
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
**Isolated Scopes with Parameters:**
|
|
613
|
+
Scopes can be declared with parameters to create **isolated** execution contexts. Unlike regular `do` blocks, isolated scopes **do not inherit** variables from parent scopes unless they are explicitly passed as arguments.
|
|
614
|
+
|
|
615
|
+
```robinpath
|
|
616
|
+
$outer = 100
|
|
617
|
+
do $a $b
|
|
618
|
+
# $outer is NOT accessible here (returns null)
|
|
619
|
+
# $a and $b are initialized from arguments passed to the block
|
|
620
|
+
$inner = 20
|
|
621
|
+
enddo
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
### Comments
|
|
625
|
+
|
|
626
|
+
Lines starting with `#` are comments:
|
|
627
|
+
|
|
628
|
+
```robinpath
|
|
629
|
+
# This is a comment
|
|
630
|
+
add 1 2 # Inline comment
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
### Conditionals
|
|
634
|
+
|
|
635
|
+
**Inline if:**
|
|
636
|
+
```robinpath
|
|
637
|
+
if $age >= 18 then log "Adult"
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
**Block if:**
|
|
641
|
+
```robinpath
|
|
642
|
+
if $score >= 90
|
|
643
|
+
log "Grade: A"
|
|
644
|
+
elseif $score >= 80
|
|
645
|
+
log "Grade: B"
|
|
646
|
+
else
|
|
647
|
+
log "Grade: F"
|
|
648
|
+
endif
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
### Loops
|
|
652
|
+
|
|
653
|
+
**For loops:**
|
|
654
|
+
```robinpath
|
|
655
|
+
# Iterate over a range
|
|
656
|
+
for $i from 1 to 5
|
|
657
|
+
log "Iteration:" $i
|
|
658
|
+
endfor
|
|
659
|
+
|
|
660
|
+
# Iterate with custom step and key (index)
|
|
661
|
+
for $a from 0 to 10 step 2 key $index
|
|
662
|
+
log "value: " + $a + ", index: " + $index
|
|
663
|
+
endfor
|
|
664
|
+
|
|
665
|
+
# Range parameters can be in any order
|
|
666
|
+
for $x by 5 to 100 from 0
|
|
667
|
+
log $x
|
|
668
|
+
endfor
|
|
669
|
+
|
|
670
|
+
# Iterate over an array
|
|
671
|
+
$numbers = [10, 11, 12]
|
|
672
|
+
for $num in $numbers key $i
|
|
673
|
+
log "Number " + $i + ": " + $num
|
|
674
|
+
endfor
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
**Repeat loop:**
|
|
678
|
+
The `repeat` loop runs a block `N` times. Inside the block:
|
|
679
|
+
- `$1` is the current iteration index (0-based).
|
|
680
|
+
- `$2` is the result of the previous iteration (or `null` for the first).
|
|
681
|
+
|
|
682
|
+
```robinpath
|
|
683
|
+
repeat 5 with
|
|
684
|
+
log "Iteration:" $1 # 0, 1, 2, 3, 4
|
|
685
|
+
endwith
|
|
686
|
+
|
|
687
|
+
# Accumulate values
|
|
688
|
+
repeat 5 with
|
|
689
|
+
if $2 == null
|
|
690
|
+
return 0
|
|
691
|
+
endif
|
|
692
|
+
math.add $2 $1 # Adds current index to sum
|
|
693
|
+
endwith
|
|
694
|
+
# Result: 10 (0+1+2+3+4)
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
**Break and Continue:**
|
|
698
|
+
Use `break` to exit a loop early, and `continue` to skip to the next iteration.
|
|
699
|
+
|
|
700
|
+
```robinpath
|
|
701
|
+
for $i in range 1 10
|
|
702
|
+
if $i == 5
|
|
703
|
+
break
|
|
704
|
+
endif
|
|
705
|
+
endfor
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
### Functions
|
|
709
|
+
|
|
710
|
+
Define custom functions with `def` (or `define`):
|
|
711
|
+
|
|
712
|
+
```robinpath
|
|
713
|
+
def greet $name
|
|
714
|
+
log "Hello" $name
|
|
715
|
+
enddef
|
|
716
|
+
|
|
717
|
+
# 'define' alias works too
|
|
718
|
+
define sum $a $b
|
|
719
|
+
math.add $a $b
|
|
720
|
+
enddef
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
**Named Parameters:**
|
|
724
|
+
You can optionally use `as` after parameters.
|
|
725
|
+
|
|
726
|
+
```robinpath
|
|
727
|
+
def greet $name $age as
|
|
728
|
+
# $name is alias for $1
|
|
729
|
+
# $age is alias for $2
|
|
730
|
+
log "Hello" $name "Age" $age
|
|
731
|
+
enddef
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
**Call Syntax:**
|
|
735
|
+
```robinpath
|
|
736
|
+
# CLI-style
|
|
737
|
+
greet "Alice" 25
|
|
738
|
+
|
|
739
|
+
# Parenthesized style (commas optional)
|
|
740
|
+
greet("Alice" 25)
|
|
741
|
+
greet(
|
|
742
|
+
"Alice"
|
|
743
|
+
25
|
|
744
|
+
)
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
**Named Arguments:**
|
|
748
|
+
```robinpath
|
|
749
|
+
def config $env
|
|
750
|
+
log "Env:" $env "Key:" $args.key
|
|
751
|
+
enddef
|
|
752
|
+
|
|
753
|
+
config("prod" key="123")
|
|
754
|
+
config(
|
|
755
|
+
"prod"
|
|
756
|
+
key="123"
|
|
757
|
+
)
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
**Decorators:**
|
|
761
|
+
Use decorators to add metadata to functions and variables:
|
|
762
|
+
```robinpath
|
|
763
|
+
@desc "Calculates sum"
|
|
764
|
+
@param number $a "First number"
|
|
765
|
+
@param number $b "Second number"
|
|
766
|
+
@return number "The sum"
|
|
767
|
+
def add $a $b
|
|
768
|
+
math.add $a $b
|
|
769
|
+
enddef
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
Common decorators: `@desc`, `@title`, `@param`, `@arg`, `@required`, `@return`, `@deprecated`.
|
|
773
|
+
|
|
774
|
+
### Events
|
|
775
|
+
|
|
776
|
+
Define event handlers with `on`. Multiple handlers can be defined for the same event.
|
|
777
|
+
|
|
778
|
+
```robinpath
|
|
779
|
+
on "user_login"
|
|
780
|
+
log "User logged in:" $1
|
|
781
|
+
endon
|
|
782
|
+
|
|
783
|
+
# Trigger an event
|
|
784
|
+
trigger "user_login" "Alice"
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
### Parallel Execution
|
|
788
|
+
|
|
789
|
+
Use `together` to run blocks in parallel:
|
|
790
|
+
|
|
791
|
+
```robinpath
|
|
792
|
+
together
|
|
793
|
+
do
|
|
794
|
+
# Task 1
|
|
795
|
+
wait 1000
|
|
796
|
+
log "Task 1 done"
|
|
797
|
+
enddo
|
|
798
|
+
do
|
|
799
|
+
# Task 2
|
|
800
|
+
log "Task 2 done"
|
|
801
|
+
enddo
|
|
802
|
+
endtogether
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
### Modules
|
|
806
|
+
|
|
807
|
+
Use modules to access specialized functions:
|
|
808
|
+
|
|
809
|
+
```robinpath
|
|
810
|
+
use math
|
|
811
|
+
math.add 5 10
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
**Available Modules:**
|
|
815
|
+
- **`math`**: `add`, `subtract`, `multiply`, `divide`, `modulo`, `power`, `sqrt`, `abs`, `round`, `floor`, `ceil`, `min`, `max`.
|
|
816
|
+
- **`string`**: `length`, `substring`, `toUpperCase`, `toLowerCase`, `trim`, `replace`, `replaceAll`, `split`, `startsWith`, `endsWith`, `contains`, `indexOf`, `lastIndexOf`, `charAt`, `padStart`, `padEnd`, `repeat`, `concat`.
|
|
817
|
+
- **`json`**: `parse`, `stringify`, `isValid`.
|
|
818
|
+
- **`object`**: `keys`, `values`, `entries`, `merge`, `clone`. (Global commands like `keys` also available).
|
|
819
|
+
- **`time`**: `now`, `timestamp`, `format`, `addDays`, `diffDays`.
|
|
820
|
+
- **`random`**: `int`, `float`, `uuid`, `choice`.
|
|
821
|
+
- **`array`**: `create`, `length`, `get`, `slice`, `push`, `concat`, `join`.
|
|
822
|
+
- **`dom`**: `click` (with callback support), etc.
|
|
823
|
+
|
|
824
|
+
### Inline Subexpressions
|
|
825
|
+
|
|
826
|
+
Use `$( ... )` for inline subexpressions. Subexpressions can be multi-line and contain multiple statements (returns result of the last one).
|
|
827
|
+
|
|
828
|
+
```robinpath
|
|
829
|
+
log "Result:" $(math.add 10 20)
|
|
830
|
+
|
|
831
|
+
$val = $(
|
|
832
|
+
math.add 5 5
|
|
833
|
+
math.multiply $ 2
|
|
834
|
+
)
|
|
835
|
+
# $val is 20
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
### Comparison Functions
|
|
839
|
+
|
|
840
|
+
RobinPath provides built-in comparison functions useful for testing and assertions:
|
|
841
|
+
- `test.assertEqual`
|
|
842
|
+
- `test.isEqual`
|
|
843
|
+
- `test.isBigger`
|
|
844
|
+
- `test.isSmaller`
|
|
845
|
+
- `test.isEqualOrBigger`
|
|
846
|
+
- `test.isEqualOrSmaller`
|
|
847
|
+
- `test.assertTrue`
|
|
848
|
+
- `test.assertFalse`
|
|
849
|
+
- `test.assertNull`
|
|
850
|
+
- `test.assertNotNull`
|
|
851
|
+
- `test.assertType`
|
|
852
|
+
- `test.assertContains`
|
|
853
|
+
|
|
854
|
+
## Creating Custom Modules
|
|
855
|
+
|
|
856
|
+
(Refer to "Creating Custom Modules" in the previous section of documentation for details on extending RobinPath with TypeScript).
|