Skip to content

Commit a9bc961

Browse files
chore: Format
1 parent a9ab907 commit a9bc961

8 files changed

Lines changed: 124 additions & 129 deletions

File tree

Sources/Units/Expression.swift

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
public final class Expression {
33
// Implemented as a linked list of ExpressionNodes. This allows us to indicate operators,
44
// and iteratively solve by reducing the list according to the order of operations.
5-
5+
66
var first: ExpressionNode
77
var last: ExpressionNode
88
var count: Int
9-
9+
1010
init(node: ExpressionNode) {
11-
self.first = node
12-
self.last = node
11+
first = node
12+
last = node
1313
count = 1
1414
}
15-
15+
1616
/// Initializes an expression from a string.
1717
///
1818
/// Parsing rules:
@@ -29,25 +29,25 @@ public final class Expression {
2929
/// - Parameter expr: The string expression to parse.
3030
public init(_ expr: String) throws {
3131
let parsed = try Parser(expr).parseExpression()
32-
self.first = parsed.first
33-
self.last = parsed.last
34-
self.count = parsed.count
32+
first = parsed.first
33+
last = parsed.last
34+
count = parsed.count
3535
}
36-
36+
3737
/// Reduces the expression to a single measurement, respecting the [order of operations](https://en.wikipedia.org/wiki/Order_of_operations)
3838
public func solve() throws -> Measurement {
3939
let copy = self.copy()
4040
return try copy.computeAndDestroy()
4141
}
42-
42+
4343
@discardableResult
4444
func append(op: Operator, node: ExpressionNode) -> Self {
4545
last.next = .init(op: op, node: node)
4646
last = node
4747
count = count + 1
4848
return self
4949
}
50-
50+
5151
func copy() -> Expression {
5252
// Copy the expression list so the original is not destroyed
5353
let copy = Expression(node: first.copy())
@@ -58,12 +58,11 @@ public final class Expression {
5858
}
5959
return copy
6060
}
61-
61+
6262
/// Reduces the expression to a single measurement, respecting the [order of operations](https://en.wikipedia.org/wiki/Order_of_operations)
6363
///
6464
/// NOTE: This flattens the list, destroying it. Use `solve` for non-destructive behavior.
6565
private func computeAndDestroy() throws -> Measurement {
66-
6766
// SubExpressions
6867
func computeSubExpression(node: ExpressionNode) throws {
6968
switch node.value {
@@ -81,7 +80,7 @@ public final class Expression {
8180
}
8281
try computeSubExpression(node: left)
8382
// At this point, there should be no more sub expressions
84-
83+
8584
// Exponentals
8685
func exponentiate(node: ExpressionNode) throws {
8786
guard let exponent = node.exponent else {
@@ -102,7 +101,7 @@ public final class Expression {
102101
left = next.node
103102
}
104103
try exponentiate(node: left)
105-
104+
106105
// Multiplication
107106
left = first
108107
while let next = left.next {
@@ -123,15 +122,15 @@ public final class Expression {
123122
fatalError("Parentheses still present during multiplication phase")
124123
}
125124
}
126-
125+
127126
// Addition
128127
left = first
129128
while let next = left.next {
130129
let right = next.node
131130
switch (left.value, right.value) {
132131
case let (.measurement(leftMeasurement), .measurement(rightMeasurement)):
133132
switch next.op {
134-
case .add: // Compute and absorb right node into left
133+
case .add: // Compute and absorb right node into left
135134
left.value = try .measurement(leftMeasurement + rightMeasurement)
136135
left.next = right.next
137136
case .subtract: // Compute and absorb right node into left
@@ -144,7 +143,7 @@ public final class Expression {
144143
fatalError("Parentheses still present during addition phase")
145144
}
146145
}
147-
146+
148147
if first.next != nil {
149148
fatalError("Expression list reduction not complete")
150149
}
@@ -194,15 +193,15 @@ class ExpressionNode {
194193
var value: ExpressionNodeValue
195194
var exponent: Int?
196195
var next: ExpressionLink?
197-
196+
198197
init(_ value: ExpressionNodeValue, exponent: Int? = nil, next: ExpressionLink? = nil) {
199198
self.value = value
200199
self.exponent = exponent
201200
self.next = next
202201
}
203-
202+
204203
func copy() -> ExpressionNode {
205-
return .init(value.copy(), exponent: self.exponent)
204+
return .init(value.copy(), exponent: exponent)
206205
}
207206
}
208207

@@ -216,7 +215,7 @@ extension ExpressionNode: Equatable {
216215
enum ExpressionNodeValue {
217216
case measurement(Measurement)
218217
case subExpression(Expression)
219-
218+
220219
func copy() -> ExpressionNodeValue {
221220
switch self {
222221
case let .measurement(measurement):
@@ -254,7 +253,7 @@ extension ExpressionNodeValue: Equatable {
254253
class ExpressionLink {
255254
let op: Operator
256255
let node: ExpressionNode
257-
256+
258257
init(op: Operator, node: ExpressionNode) {
259258
self.op = op
260259
self.node = node

Sources/Units/Measurement/Measurement.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ extension Measurement: LosslessStringConvertible {
166166
guard let parsed = try? Parser(description).parseMeasurement() else {
167167
return nil
168168
}
169-
self.value = parsed.value
170-
self.unit = parsed.unit
169+
value = parsed.value
170+
unit = parsed.unit
171171
}
172172
}
173173

Sources/Units/Parser.swift

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,25 @@ import Foundation
33
class Parser {
44
var data: [UnicodeScalar]
55
var position = 0
6-
6+
77
private var cur: Character? {
88
guard position < data.count else {
99
return nil
1010
}
1111
return Character(UnicodeScalar(data[position]))
1212
}
13-
13+
1414
private var peek: Character? {
1515
guard position < data.count - 1 else {
1616
return nil
1717
}
18-
return Character(UnicodeScalar(data[position+1]))
18+
return Character(UnicodeScalar(data[position + 1]))
1919
}
20-
20+
2121
init(_ string: String) {
22-
self.data = Array(string.unicodeScalars)
22+
data = Array(string.unicodeScalars)
2323
}
24-
24+
2525
func parseMeasurement() throws -> Measurement {
2626
let value: Double
2727
switch try next() {
@@ -30,7 +30,7 @@ class Parser {
3030
default:
3131
throw ParserError.invalidMeasurement
3232
}
33-
33+
3434
let unit: Unit
3535
switch try next() {
3636
case let .unit(parsed):
@@ -40,17 +40,17 @@ class Parser {
4040
default:
4141
throw ParserError.invalidMeasurement
4242
}
43-
43+
4444
return Measurement(value: value, unit: unit)
4545
}
46-
46+
4747
func parseExpression() throws -> Expression {
4848
return try parseExpression(isSubExpression: false)
4949
}
50-
50+
5151
private func parseExpression(isSubExpression: Bool) throws -> Expression {
5252
var expression: Expression? = nil
53-
53+
5454
var token = try next()
5555
var op: Operator? = nil
5656
// We do while/true because we can exit on either eof or rParen, depending on isSubExpression
@@ -63,7 +63,7 @@ class Parser {
6363
break parseLoop
6464
case let .number(value):
6565
let unit: Unit
66-
66+
6767
// Check next token to see if it is a unit. Continue loop to avoid calling next again below.
6868
let nextToken = try next()
6969
switch nextToken {
@@ -89,7 +89,7 @@ class Parser {
8989
case .lParen:
9090
let subExpression = try parseExpression(isSubExpression: true)
9191
let node = ExpressionNode(.subExpression(subExpression))
92-
92+
9393
if let expression = expression {
9494
guard let op = op else {
9595
throw ParserError.invalidExpression(reason: "No operator preceeding left parentheses")
@@ -127,7 +127,7 @@ class Parser {
127127
}
128128
token = try next()
129129
}
130-
130+
131131
if let op = op {
132132
throw ParserError.invalidExpression(reason: "Expression ended with operator `\(op)`")
133133
}
@@ -136,33 +136,30 @@ class Parser {
136136
}
137137
return expression
138138
}
139-
139+
140140
private func next() throws -> Token {
141141
guard let char = cur else {
142142
return .eof
143143
}
144-
144+
145145
if char.isNumber {
146146
let startPosition = position
147147
var numberString = ""
148-
while let cur = cur, (cur.isNumber || cur == ".") {
148+
while let cur = cur, cur.isNumber || cur == "." {
149149
numberString.append(cur)
150150
consume()
151151
}
152152
guard let number = Double(numberString) else {
153153
throw ParserError.unableToParseNumber(numberString, position: startPosition)
154154
}
155155
return .number(number)
156-
}
157-
else if char == "(" {
156+
} else if char == "(" {
158157
consume()
159158
return .lParen
160-
}
161-
else if char == ")" {
159+
} else if char == ")" {
162160
consume()
163161
return .rParen
164-
}
165-
else if char == "^" {
162+
} else if char == "^" {
166163
let startPosition = position
167164
try consume("^")
168165
var intString = ""
@@ -174,8 +171,7 @@ class Parser {
174171
throw ParserError.unableToParseExponent("^\(intString)", position: startPosition)
175172
}
176173
return .exp(int)
177-
}
178-
else if char.isWhitespace {
174+
} else if char.isWhitespace {
179175
if peek == "+" {
180176
try consume(" ")
181177
try consume("+")
@@ -200,26 +196,25 @@ class Parser {
200196
try consume(" ")
201197
return .div
202198
}
203-
199+
204200
// consume and try again
205201
consume()
206202
return try next()
207-
}
208-
else {
203+
} else {
209204
var unitString = ""
210205
while let cur = cur, cur != "(" && cur != ")" && !cur.isWhitespace {
211206
unitString.append(cur)
212207
consume()
213208
}
214-
let unit = try Unit.init(fromSymbol: unitString)
209+
let unit = try Unit(fromSymbol: unitString)
215210
return .unit(unit)
216211
}
217212
}
218-
213+
219214
private func consume() {
220215
position = position + 1
221216
}
222-
217+
223218
private func consume(_ expected: Character) throws {
224219
guard let character = cur else {
225220
return
@@ -248,7 +243,7 @@ enum ParserError: Error {
248243
case unexpectedCharacter(Character, position: Int)
249244
case unableToParseNumber(String, position: Int)
250245
case unableToParseExponent(String, position: Int)
251-
246+
252247
case invalidMeasurement
253248
case invalidExpression(reason: String)
254249
}

Sources/Units/Registry.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,11 @@ class Registry {
253253
// MARK: Luminous Intensity
254254

255255
DefaultUnits.candela,
256-
256+
257257
// MARK: Luminous Flux
258258

259259
DefaultUnits.lumen,
260-
260+
261261
// MARK: Magnetic Flux
262262

263263
DefaultUnits.weber,

Sources/Units/Unit/DefaultUnits.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Foundation
33
/// Static type containing this package's pre-defined units
44
enum DefaultUnits {
55
// MARK: If adding units to this list, add corresponding entries to the following files:
6+
67
// - Unit+DefaultUnits.swift
78
// - Registry.swift
89
// - DefinitionTests.swift

Tests/UnitsTests/DefinitionTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class DefinitionTests: XCTestCase {
6464
try XCTAssertEqual(Measurement("1Ebit"), 1e18.measured(in: .bit).convert(to: .exabit))
6565
try XCTAssertEqual(Measurement("1Zbit"), 1e21.measured(in: .bit).convert(to: .zetabit))
6666
try XCTAssertEqual(Measurement("1Ybit"), 1e24.measured(in: .bit).convert(to: .yottabit))
67-
67+
6868
try XCTAssertEqual(Measurement("1Kibit"), 1024.measured(in: .bit).convert(to: .kibibit))
6969
try XCTAssertEqual(Measurement("1Mibit"), pow(1024, 2).measured(in: .bit).convert(to: .mebibit))
7070
try XCTAssertEqual(Measurement("1Gibit"), pow(1024, 3).measured(in: .bit).convert(to: .gibibit))
@@ -73,7 +73,7 @@ class DefinitionTests: XCTestCase {
7373
try XCTAssertEqual(Measurement("1Eibit"), pow(1024, 6).measured(in: .bit).convert(to: .exbibit))
7474
try XCTAssertEqual(Measurement("1Zibit"), pow(1024, 7).measured(in: .bit).convert(to: .zebibit))
7575
try XCTAssertEqual(Measurement("1Yibit"), pow(1024, 8).measured(in: .bit).convert(to: .yobibit))
76-
76+
7777
try XCTAssertEqual(Measurement("1byte"), 8.measured(in: .bit).convert(to: .byte))
7878
try XCTAssertEqual(Measurement("1kB"), 8000.measured(in: .bit).convert(to: .kilobyte))
7979
try XCTAssertEqual(Measurement("1MB"), 8e6.measured(in: .bit).convert(to: .megabyte))
@@ -83,7 +83,7 @@ class DefinitionTests: XCTestCase {
8383
try XCTAssertEqual(Measurement("1EB"), 8e18.measured(in: .bit).convert(to: .exabyte))
8484
try XCTAssertEqual(Measurement("1ZB"), 8e21.measured(in: .bit).convert(to: .zetabyte))
8585
try XCTAssertEqual(Measurement("1YB"), 8e24.measured(in: .bit).convert(to: .yottabyte))
86-
86+
8787
try XCTAssertEqual(Measurement("1KiB"), (8 * 1024).measured(in: .bit).convert(to: .kibibyte))
8888
try XCTAssertEqual(Measurement("1MiB"), (8 * pow(1024, 2)).measured(in: .bit).convert(to: .mebibyte))
8989
try XCTAssertEqual(Measurement("1GiB"), (8 * pow(1024, 3)).measured(in: .bit).convert(to: .gibibyte))

0 commit comments

Comments
 (0)