Skip to content

Commit ecd50eb

Browse files
authored
Merge pull request #17 from ECP-Solutions/spread_and_rest_operators_support
## Summary ASF v2.0.8 introduces modern JavaScript-style spread/rest operators (`...`) and array destructuring assignments, significantly enhancing array manipulation capabilities and function parameter handling. --- ## Highlights - **Added** - Spread/rest operator (`...`) support: ```javascript // Spread in array literals arr1 = [1, 2, 3]; arr2 = [0, ...arr1, 4, 5]; // => [0, 1, 2, 3, 4, 5] // Spread in function calls fun add(a, b, c) { return a + b + c; }; numbers = [1, 2, 3]; result = add(...numbers); // => 6 // Rest parameters in functions fun sum(first, ...rest) { total = first; rest.forEach(fun(n) { total = total + n }); return total; }; sum(1, 2, 3, 4, 5); // => 15 // Spread strings into character arrays chars = [...'hello']; // => ['h', 'e', 'l', 'l', 'o'] ``` - Array destructuring assignments: ```javascript // Basic destructuring [a, b, c] = [1, 2, 3]; // a=1, b=2, c=3 // With rest element [first, ...rest] = [1, 2, 3, 4, 5]; // first=1, rest=[2, 3, 4, 5] // Fewer targets than elements [x, y] = [10, 20, 30, 40]; // x=10, y=20 // More targets than elements (assigns Empty) [p, q, r] = [100, 200]; // p=100, q=200, r=Empty // Practical use cases [a, b] = [b, a]; // Swap variables [head, ...tail] = myArray; // Extract head and tail // Combine spread and destructuring arr1 = [1, 2]; arr2 = [3, 4]; [first, ...combined] = [...arr1, ...arr2]; // first=1, combined=[2, 3, 4] ``` - **Internal core changes**: - **Parser** (`ASF_Parser.cls`): - Added tokenization for `...` spread/rest operator - New token type: `"SPREAD"` with value `"..."` - **Compiler** (`ASF_Compiler.cls`): - Added `IsSpreadToken()` helper function for spread operator detection - Rest parameter support in function and method definitions - Spread operator handling in array literal compilation (`ParseArrayLiteral`) - Spread operator support in function call argument processing - Array destructuring pattern detection in `ParseStatementTokensToAST` - New AST node type: `"ArrayDestructuring"` with targets collection and optional rest target - Compile-time validation: - Rest parameter must be last in function signatures - Only one rest parameter allowed per function - Rest element must be last in destructuring patterns - Multiple rest elements not allowed in destructuring patterns - **VM** (`ASF_VM.cls`): - Spread operator evaluation in `EvalArrayNode` with type handling - Array expansion for arrays, strings, and scalar values - Spread operator support in function call argument expansion - Rest parameter handling in function calls with automatic array creation - New `"ArrayDestructuring"` case handler in `ExecuteStmtNode` - **Technical Details**: - **Spread/Rest Token Structure**: ``` Token: ["SPREAD", "..."] ``` - **Rest Parameter AST**: ``` Function/Method node { params: Collection of parameter names restParam: String (optional) ... } ``` - **Array Destructuring AST**: ``` ArrayDestructuring { targets: Collection of Variable nodes restTarget: String (optional) source: Expression node } ``` - **Error Messages**: - `"Rest parameter must be last parameter"` - Rest parameter not in final position - `"Multiple rest parameters not allowed"` - More than one rest parameter in function - `"Rest element must be last in destructuring"` - Rest element not in final position - `"Multiple rest elements in destructuring"` - More than one rest element in pattern - `"Expected identifier after ... in destructuring"` - Invalid rest syntax - `"Cannot destructure non-array value"` - Runtime type validation failure --- **Full Changelog**: v2.0.7...v2.0.8
2 parents 9b03caa + 12480a3 commit ecd50eb

File tree

11 files changed

+1301
-72
lines changed

11 files changed

+1301
-72
lines changed

CHANGELOG.md

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,129 @@
22

33
All notable changes for ASF. This file combines the release notes from the project's releases.
44

5+
## [v2.0.8] - 2026-02-01
6+
https://github.com/ECP-Solutions/ASF/releases/tag/v2.0.8
7+
8+
## Summary
9+
ASF v2.0.8 introduces modern JavaScript-style spread/rest operators (`...`) and array destructuring assignments, significantly enhancing array manipulation capabilities and function parameter handling.
10+
11+
---
12+
13+
## Highlights
14+
15+
- **Added**
16+
- Spread/rest operator (`...`) support:
17+
```javascript
18+
// Spread in array literals
19+
arr1 = [1, 2, 3];
20+
arr2 = [0, ...arr1, 4, 5]; // => [0, 1, 2, 3, 4, 5]
21+
22+
// Spread in function calls
23+
fun add(a, b, c) { return a + b + c; };
24+
numbers = [1, 2, 3];
25+
result = add(...numbers); // => 6
26+
27+
// Rest parameters in functions
28+
fun sum(first, ...rest) {
29+
total = first;
30+
rest.forEach(fun(n) { total = total + n });
31+
return total;
32+
};
33+
sum(1, 2, 3, 4, 5); // => 15
34+
35+
// Spread strings into character arrays
36+
chars = [...'hello']; // => ['h', 'e', 'l', 'l', 'o']
37+
```
38+
39+
- Array destructuring assignments:
40+
```javascript
41+
// Basic destructuring
42+
[a, b, c] = [1, 2, 3]; // a=1, b=2, c=3
43+
44+
// With rest element
45+
[first, ...rest] = [1, 2, 3, 4, 5];
46+
// first=1, rest=[2, 3, 4, 5]
47+
48+
// Fewer targets than elements
49+
[x, y] = [10, 20, 30, 40]; // x=10, y=20
50+
51+
// More targets than elements (assigns Empty)
52+
[p, q, r] = [100, 200]; // p=100, q=200, r=Empty
53+
54+
// Practical use cases
55+
[a, b] = [b, a]; // Swap variables
56+
[head, ...tail] = myArray; // Extract head and tail
57+
58+
// Combine spread and destructuring
59+
arr1 = [1, 2];
60+
arr2 = [3, 4];
61+
[first, ...combined] = [...arr1, ...arr2];
62+
// first=1, combined=[2, 3, 4]
63+
```
64+
65+
- **Internal core changes**:
66+
- **Parser** (`ASF_Parser.cls`):
67+
- Added tokenization for `...` spread/rest operator
68+
- New token type: `"SPREAD"` with value `"..."`
69+
70+
- **Compiler** (`ASF_Compiler.cls`):
71+
- Added `IsSpreadToken()` helper function for spread operator detection
72+
- Rest parameter support in function and method definitions
73+
- Spread operator handling in array literal compilation (`ParseArrayLiteral`)
74+
- Spread operator support in function call argument processing
75+
- Array destructuring pattern detection in `ParseStatementTokensToAST`
76+
- New AST node type: `"ArrayDestructuring"` with targets collection and optional rest target
77+
- Compile-time validation:
78+
- Rest parameter must be last in function signatures
79+
- Only one rest parameter allowed per function
80+
- Rest element must be last in destructuring patterns
81+
- Multiple rest elements not allowed in destructuring patterns
82+
83+
- **VM** (`ASF_VM.cls`):
84+
- Spread operator evaluation in `EvalArrayNode` with type handling
85+
- Array expansion for arrays, strings, and scalar values
86+
- Spread operator support in function call argument expansion
87+
- Rest parameter handling in function calls with automatic array creation
88+
- New `"ArrayDestructuring"` case handler in `ExecuteStmtNode`
89+
90+
- **Technical Details**:
91+
- **Spread/Rest Token Structure**:
92+
```
93+
Token: ["SPREAD", "..."]
94+
```
95+
96+
- **Rest Parameter AST**:
97+
```
98+
Function/Method node {
99+
params: Collection of parameter names
100+
restParam: String (optional)
101+
...
102+
}
103+
```
104+
105+
- **Array Destructuring AST**:
106+
```
107+
ArrayDestructuring {
108+
targets: Collection of Variable nodes
109+
restTarget: String (optional)
110+
source: Expression node
111+
}
112+
```
113+
114+
- **Error Messages**:
115+
- `"Rest parameter must be last parameter"` - Rest parameter not in final position
116+
- `"Multiple rest parameters not allowed"` - More than one rest parameter in function
117+
- `"Rest element must be last in destructuring"` - Rest element not in final position
118+
- `"Multiple rest elements in destructuring"` - More than one rest element in pattern
119+
- `"Expected identifier after ... in destructuring"` - Invalid rest syntax
120+
- `"Cannot destructure non-array value"` - Runtime type validation failure
121+
122+
---
123+
124+
**Full Changelog**: https://github.com/ECP-Solutions/ASF/compare/v2.0.7...v2.0.8
125+
5126
## [v2.0.7] - 2026-01-28
6-
https://github.com/ECP-Solutions/ASF/releases/tag/v2.0.6
127+
https://github.com/ECP-Solutions/ASF/releases/tag/v2.0.7
7128

8129
## Summary
9130

README.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Debug.Print engine.OUTPUT_ ' => 12
6969
| Feature | Native VBA | ASF |
7070
|---------|-----------|-----|
7171
| **Array filtering** | Manual loops with counters | `.filter(fun(x) { return x > 10 })` |
72-
| **Data transformation** | ReDim + index juggling | `.map(fun(x) { return x * 2 })` |
72+
| **Data transformation** | ReDim + index juggling | `.map(fun(x) { return x * 2 })`. Array destructuring with rest operator support `[first, second, ...rest] = [1, 2, 3, 4, 5]`|
7373
| **Regex support** | COM + error-prone patterns | Built-in regex engine with lookarounds |
7474
| **JSON handling** | Parse character-by-character | Object/array literals: `{a: 1, b: [2, 3]}` |
7575
| **Classes & inheritance** | ❌ Not inheritance support | Full OOP with `extends` and `super` |
@@ -422,6 +422,38 @@ let activeNames = data.users
422422
print(activeNames); // => 'Alice, Charlie'
423423
```
424424

425+
#### 6. Spread/rest operator support
426+
427+
```js
428+
//rest argument
429+
fun greetAll(greeting, ...names) {
430+
result = greeting + ': ';
431+
for (name of names) {
432+
result = result + name + ', ';
433+
};
434+
return result.slice(0, -2);
435+
};
436+
msg = greetAll('Hello', 'Alice', 'Bob', 'Charlie');
437+
return msg //=> Hello: Alice, Bob, Charlie
438+
```
439+
440+
```js
441+
//spread operator on arrays
442+
begin = [1]; middle = [2, 3, 4]; end = [5]; combined = [...begin, ...middle, ...end];
443+
print(combined); //=> [ 1, 2, 3, 4, 5 ]
444+
445+
//spread operator on objects
446+
obj1 = {a: 1, b: 2}; obj2 = {c: 3, ...obj1, d: 4};
447+
return `${obj2.a}; ${obj2.b}; ${obj2.c}; ${obj2.d}` //=> 1; 2; 3; 4
448+
```
449+
450+
#### 7. Array destructuring
451+
452+
```js
453+
[first, second, ...rest] = [1, 2, 3, 4, 5];
454+
return `${rest}` //=> [ 3, 4, 5 ]
455+
```
456+
425457
---
426458

427459
## Performance & Benchmarks
@@ -812,7 +844,7 @@ When reporting issues, please include:
812844

813845
## Running the Test Suite
814846

815-
1. Open `ASF v2.0.2.xlsm` workbook
847+
1. Open `ASF [VERSION NAME].xlsm` workbook
816848
2. Install [Rubberduck VBA](https://rubberduckvba.com/)
817849
3. In Rubberduck, navigate to the test explorer
818850
4. Run all tests - they should pass ✅
@@ -824,6 +856,7 @@ The test suite covers:
824856
- Arrays & objects (literals, methods, chaining)
825857
- Classes & inheritance
826858
- String manipulation
859+
- Spread/rest operator
827860
- Regex engine
828861
- VBA integration
829862
- Error handling

docs/API.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ description: "ASF Public API."
88

99
# ASF — API Reference
1010

11-
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/ECP-Solutions/ASF?style=plastic)](https://github.com/ECP-Solutions/ASF/releases/latest) [![Tests](https://img.shields.io/badge/tests-290%2B-green.svg)](.)
11+
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/ECP-Solutions/ASF?style=plastic)](https://github.com/ECP-Solutions/ASF/releases/latest) [![Tests](https://img.shields.io/badge/tests-373%2B-green.svg)](.)
1212

1313
This document describes the runtime API exposed by ASF scripts and the VM builtins/methods available to scripts. It summarizes semantics, signatures, error behavior, and examples.
1414

docs/Language reference.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,12 +395,37 @@ let grade = (score >= 90) ? 'A' :
395395
(score >= 70) ? 'C' : 'F';
396396
```
397397

398+
### Spread/rest Operator
399+
400+
```js
401+
//rest argument
402+
fun greetAll(greeting, ...names) {
403+
result = greeting + ': ';
404+
for (name of names) {
405+
result = result + name + ', ';
406+
};
407+
return result.slice(0, -2);
408+
};
409+
msg = greetAll('Hello', 'Alice', 'Bob', 'Charlie');
410+
return msg //=> Hello: Alice, Bob, Charlie
411+
```
412+
413+
```js
414+
//spread operator on arrays
415+
begin = [1]; middle = [2, 3, 4]; end = [5]; combined = [...begin, ...middle, ...end];
416+
print(combined); //=> [ 1, 2, 3, 4, 5 ]
417+
418+
//spread operator on objects
419+
obj1 = {a: 1, b: 2}; obj2 = {c: 3, ...obj1, d: 4};
420+
return `${obj2.a}; ${obj2.b}; ${obj2.c}; ${obj2.d}` //=> 1; 2; 3; 4
421+
```
422+
398423
### Operator Precedence
399424

400425
From highest to lowest:
401426

402427
1. Parentheses `( )`
403-
2. Unary `!`, `-`, `typeof`
428+
2. Unary `!`, `-`, `typeof`, `...`
404429
3. Exponentiation `^`
405430
4. Multiplication/Division `*`, `/`, `%`
406431
5. Addition/Subtraction `+`, `-`
@@ -2907,8 +2932,6 @@ The following words are reserved and cannot be used as variable names:
29072932

29082933
- No `async/await` support
29092934
- No `Promise` or callback patterns
2910-
- No spread operator (`...`)
2911-
- No destructuring assignment
29122935
- No arrow functions (`=>`)
29132936
- No `const` declaration (use `let`)
29142937
- No `var` (use `let`)

docs/Syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ description: "ASF syntax."
88

99
# ASF — Syntax Reference
1010

11-
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/ECP-Solutions/ASF?style=plastic)](https://github.com/ECP-Solutions/ASF/releases/latest) [![Tests](https://img.shields.io/badge/tests-290%2B-green.svg)](.)
11+
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/ECP-Solutions/ASF?style=plastic)](https://github.com/ECP-Solutions/ASF/releases/latest) [![Tests](https://img.shields.io/badge/tests-373%2B-green.svg)](.)
1212

1313
This document defines the concrete syntax supported by the Advanced Scripting Framework (ASF) and contains a compact BNF grammar, operator precedence, and examples.
1414

0 commit comments

Comments
 (0)