Skip to content

Commit 7ee23a3

Browse files
committed
Extend sum function to work with vectors
1 parent 7c37759 commit 7ee23a3

5 files changed

Lines changed: 73 additions & 24 deletions

File tree

ShapeScript/StandardLibrary.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -496,9 +496,20 @@ extension Symbols {
496496
"min": .function(.list(.number), .number) { value, _ in
497497
.number(value.doublesValue.min() ?? 0)
498498
},
499-
"sum": .function(.list(.number), .number) { value, _ in
500-
let values = value.tupleValue as! [Double]
501-
return .number(values.reduce(0, +))
499+
"sum": .function(.list(.list(.number)), .list(.number)) { value, _ in
500+
let values = value.tupleValue as! [[Double]]
501+
if values.count == 1 {
502+
return .number(values[0].reduce(0, +))
503+
}
504+
// Vector sum
505+
var columns = values.reduce(0) { Swift.max($0, $1.count) }
506+
var sums = [Double](repeating: 0, count: columns)
507+
for vector in values {
508+
for i in vector.indices {
509+
sums[i] += vector[i]
510+
}
511+
}
512+
return sums.isEmpty ? 0 : .tuple(sums.map { .number($0) })
502513
},
503514
"sqrt": .function(.number, .number) { value, _ in
504515
.number(sqrt(value.doubleValue))

ShapeScriptTests/StandardLibraryTests.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,41 @@ final class StandardLibraryTests: XCTestCase {
10531053
XCTAssertEqual(delegate.log, [0.0, 0.0, 1.0])
10541054
}
10551055

1056+
func testScalarSum() {
1057+
let program = "print sum 1 2 3"
1058+
let delegate = TestDelegate()
1059+
XCTAssertNoThrow(try evaluate(parse(program), delegate: delegate))
1060+
XCTAssertEqual(delegate.log, [6.0])
1061+
}
1062+
1063+
func testVectorSum() {
1064+
let program = "print sum (1 2 3) (4 5 6) (7 8 9)"
1065+
let delegate = TestDelegate()
1066+
XCTAssertNoThrow(try evaluate(parse(program), delegate: delegate))
1067+
XCTAssertEqual(delegate.log, [12.0, 15.0, 18.0])
1068+
}
1069+
1070+
func testMixedWidthVectorSums() {
1071+
let program = "print sum (1 2) (3 4 5 6) (7 8 9)"
1072+
let delegate = TestDelegate()
1073+
XCTAssertNoThrow(try evaluate(parse(program), delegate: delegate))
1074+
XCTAssertEqual(delegate.log, [11.0, 14.0, 14.0, 6.0])
1075+
}
1076+
1077+
func testEmptyTupleSum() {
1078+
let program = "print sum ()"
1079+
let delegate = TestDelegate()
1080+
XCTAssertNoThrow(try evaluate(parse(program), delegate: delegate))
1081+
XCTAssertEqual(delegate.log, [0.0])
1082+
}
1083+
1084+
func testMultiEmptyTupleSum() {
1085+
let program = "print sum (() () ())"
1086+
let delegate = TestDelegate()
1087+
XCTAssertNoThrow(try evaluate(parse(program), delegate: delegate))
1088+
XCTAssertEqual(delegate.log, [0.0])
1089+
}
1090+
10561091
func testLength() {
10571092
let program = "print length(3 4)"
10581093
let delegate = TestDelegate()

docs/ios/functions.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,6 @@ max 2 4 // returns 4
9595
max 5 0 -5.1 // returns 5
9696
```
9797

98-
The `sum` function returns the sum of two or more values:
99-
100-
```swift
101-
sum 2 4 // returns 6
102-
sum 5 0 -5.1 // returns -0.1
103-
```
104-
10598
## Linear Algebra
10699

107100
ShapeScript also includes functions for operating on [vectors](literals.md#vectors-and-tuples):
@@ -136,6 +129,14 @@ define v (3 4)
136129
print normalize(v) // returns 0.6 0.8
137130
```
138131

132+
The `sum` function returns the sum of two or more values. It works with both scalar and vector inputs:
133+
134+
```swift
135+
sum 2 4 // returns 6
136+
sum 5 0 -5.1 // returns -0.1
137+
sum (1 2 3) (4 5 6) // returns (5 7 9)
138+
```
139+
139140
## Trigonometry
140141

141142
For the most part, you can avoid the need for trigonometry in ShapeScript by using the built-in [transform commands](transforms.md#relative-transforms) to manipulate geometry rather than manually calculating the positions of vertices.

docs/mac/functions.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,6 @@ max 2 4 // returns 4
9595
max 5 0 -5.1 // returns 5
9696
```
9797

98-
The `sum` function returns the sum of two or more values:
99-
100-
```swift
101-
sum 2 4 // returns 6
102-
sum 5 0 -5.1 // returns -0.1
103-
```
104-
10598
## Linear Algebra
10699

107100
ShapeScript also includes functions for operating on [vectors](literals.md#vectors-and-tuples):
@@ -136,6 +129,14 @@ define v (3 4)
136129
print normalize(v) // returns 0.6 0.8
137130
```
138131

132+
The `sum` function returns the sum of two or more values. It works with both scalar and vector inputs:
133+
134+
```swift
135+
sum 2 4 // returns 6
136+
sum 5 0 -5.1 // returns -0.1
137+
sum (1 2 3) (4 5 6) // returns (5 7 9)
138+
```
139+
139140
## Trigonometry
140141

141142
For the most part, you can avoid the need for trigonometry in ShapeScript by using the built-in [transform commands](transforms.md#relative-transforms) to manipulate geometry rather than manually calculating the positions of vertices.

docs/src/functions.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,6 @@ max 2 4 // returns 4
9595
max 5 0 -5.1 // returns 5
9696
```
9797

98-
The `sum` function returns the sum of two or more values:
99-
100-
```swift
101-
sum 2 4 // returns 6
102-
sum 5 0 -5.1 // returns -0.1
103-
```
104-
10598
## Linear Algebra
10699

107100
ShapeScript also includes functions for operating on [vectors](literals.md#vectors-and-tuples):
@@ -136,6 +129,14 @@ define v (3 4)
136129
print normalize(v) // returns 0.6 0.8
137130
```
138131

132+
The `sum` function returns the sum of two or more values. It works with both scalar and vector inputs:
133+
134+
```swift
135+
sum 2 4 // returns 6
136+
sum 5 0 -5.1 // returns -0.1
137+
sum (1 2 3) (4 5 6) // returns (5 7 9)
138+
```
139+
139140
## Trigonometry
140141

141142
For the most part, you can avoid the need for trigonometry in ShapeScript by using the built-in [transform commands](transforms.md#relative-transforms) to manipulate geometry rather than manually calculating the positions of vertices.

0 commit comments

Comments
 (0)