Skip to content

Commit 86d3326

Browse files
committed
Add object constructor
1 parent 4ede609 commit 86d3326

12 files changed

Lines changed: 157 additions & 3 deletions

File tree

ShapeScript/Interpreter.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,10 @@ extension Statement {
899899
name = "color"
900900
return type
901901
}
902+
if let type = context.options["*"] {
903+
context.options[name] = .any
904+
return type
905+
}
902906
return nil
903907
}() {
904908
return try context.define(name, as: .option(

ShapeScript/StandardLibrary.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,14 @@ extension Dictionary where Key == String, Value == Symbol {
547547
in: .whitespacesAndNewlines
548548
))
549549
},
550+
// Object
551+
"object": .block(.init([:], ["*": .any], .void, .any)) { context in
552+
var result = [String: ShapeScript.Value]()
553+
for name in context.options.keys {
554+
result[name] = context.value(for: name)
555+
}
556+
return .object(result)
557+
},
550558
]
551559

552560
static let name: Symbols = [

ShapeScriptTests/StandardLibraryTests.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,4 +999,20 @@ class StandardLibraryTests: XCTestCase {
999999
let geometry = try XCTUnwrap(context.children.first?.value as? Geometry)
10001000
XCTAssertEqual(geometry.transform.scale, Vector(1, 2, 3))
10011001
}
1002+
1003+
// MARK: Objects
1004+
1005+
func testObjectConstructor() throws {
1006+
let program = try parse("""
1007+
define foo object {
1008+
bar 5
1009+
baz "hello"
1010+
}
1011+
print foo
1012+
""")
1013+
let delegate = TestDelegate()
1014+
let context = EvaluationContext(source: program.source, delegate: delegate)
1015+
XCTAssertNoThrow(try program.evaluate(in: context))
1016+
XCTAssertEqual(delegate.log, [["bar": 5, "baz": "hello"] as [String: AnyHashable]])
1017+
}
10021018
}

docs/ios/expressions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ if (not a) and (b or c) {
173173

174174
## Members
175175

176-
Compound values like [vectors and tuples](literals.md#vectors-and-tuples) can be decomposed by using the *dot* operator to access individual components:
176+
Compound values like [vectors and tuples](literals.md#vectors-and-tuples) and [objects](literals.md#objects) can be decomposed by using the *dot* operator to access individual components or *members*:
177177

178178
```swift
179179
define vector 0.5 0.2 0.4

docs/ios/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ ShapeScript Help
101101
- [Strings](literals.md#strings)
102102
- [Vectors and Tuples](literals.md#vectors-and-tuples)
103103
- [Structured Data](literals.md#structured-data)
104+
- [Objects](literals.md#objects)
104105
- [Symbols](symbols.md)
105106
- [Expressions](expressions.md)
106107
- [Operators](expressions.md#operators)

docs/ios/literals.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,5 +196,46 @@ for row in data {
196196
}
197197
```
198198

199+
## Objects
200+
201+
For more complex [structured data](#structured-data) you can use the `object` command to create an object with arbitrary, named members:
202+
203+
```swift
204+
define data object {
205+
type "box"
206+
width 5
207+
height 10
208+
depth 15
209+
}
210+
211+
print data.height // prints 10
212+
```
213+
214+
Objects can also be nested:
215+
216+
```swift
217+
define data object {
218+
type "box"
219+
position 1 2 0
220+
dimensions object {
221+
width 5
222+
height 10
223+
depth 15
224+
}
225+
}
226+
227+
print data.dimensions.height // prints 10
228+
```
229+
230+
To enumerate all the members of an object, you can use a [for loop](control-flow.md#looping-over-values). Each member is returned as a tuple of the key (member name) and value:
231+
232+
```swift
233+
for row in data {
234+
print "key: " row.first ", value: " row.second
235+
}
236+
```
237+
238+
**Note:** object members are *unordered*, meaning that the order in which they are defined has no special significance. When looping through members of an object, the order will be alphabetical rather than the order in which the members were defined.
239+
199240
---
200241
[Index](index.md) | Next: [Symbols](symbols.md)

docs/mac/expressions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ if (not a) and (b or c) {
173173

174174
## Members
175175

176-
Compound values like [vectors and tuples](literals.md#vectors-and-tuples) can be decomposed by using the *dot* operator to access individual components:
176+
Compound values like [vectors and tuples](literals.md#vectors-and-tuples) and [objects](literals.md#objects) can be decomposed by using the *dot* operator to access individual components or *members*:
177177

178178
```swift
179179
define vector 0.5 0.2 0.4

docs/mac/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ ShapeScript Help
101101
- [Strings](literals.md#strings)
102102
- [Vectors and Tuples](literals.md#vectors-and-tuples)
103103
- [Structured Data](literals.md#structured-data)
104+
- [Objects](literals.md#objects)
104105
- [Symbols](symbols.md)
105106
- [Expressions](expressions.md)
106107
- [Operators](expressions.md#operators)

docs/mac/literals.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,5 +196,46 @@ for row in data {
196196
}
197197
```
198198

199+
## Objects
200+
201+
For more complex [structured data](#structured-data) you can use the `object` command to create an object with arbitrary, named members:
202+
203+
```swift
204+
define data object {
205+
type "box"
206+
width 5
207+
height 10
208+
depth 15
209+
}
210+
211+
print data.height // prints 10
212+
```
213+
214+
Objects can also be nested:
215+
216+
```swift
217+
define data object {
218+
type "box"
219+
position 1 2 0
220+
dimensions object {
221+
width 5
222+
height 10
223+
depth 15
224+
}
225+
}
226+
227+
print data.dimensions.height // prints 10
228+
```
229+
230+
To enumerate all the members of an object, you can use a [for loop](control-flow.md#looping-over-values). Each member is returned as a tuple of the key (member name) and value:
231+
232+
```swift
233+
for row in data {
234+
print "key: " row.first ", value: " row.second
235+
}
236+
```
237+
238+
**Note:** object members are *unordered*, meaning that the order in which they are defined has no special significance. When looping through members of an object, the order will be alphabetical rather than the order in which the members were defined.
239+
199240
---
200241
[Index](index.md) | Next: [Symbols](symbols.md)

docs/src/expressions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ if (not a) and (b or c) {
173173

174174
## Members
175175

176-
Compound values like [vectors and tuples](literals.md#vectors-and-tuples) can be decomposed by using the *dot* operator to access individual components:
176+
Compound values like [vectors and tuples](literals.md#vectors-and-tuples) and [objects](literals.md#objects) can be decomposed by using the *dot* operator to access individual components or *members*:
177177

178178
```swift
179179
define vector 0.5 0.2 0.4

0 commit comments

Comments
 (0)