diff --git a/Spreadsheet/Spreadsheet.xcodeproj/project.pbxproj b/Spreadsheet/Spreadsheet.xcodeproj/project.pbxproj
index ef79e83..64ad0cb 100644
--- a/Spreadsheet/Spreadsheet.xcodeproj/project.pbxproj
+++ b/Spreadsheet/Spreadsheet.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 46;
+ objectVersion = 63;
objects = {
/* Begin PBXBuildFile section */
@@ -118,9 +118,10 @@
83E6F36D1962FCDD0030D82A /* Project object */ = {
isa = PBXProject;
attributes = {
+ BuildIndependentTargetsInParallel = YES;
LastSwiftMigration = 0700;
LastSwiftUpdateCheck = 0700;
- LastUpgradeCheck = 0800;
+ LastUpgradeCheck = 1530;
ORGANIZATIONNAME = "Unsigned Integer";
TargetAttributes = {
83E6F3741962FCDD0030D82A = {
@@ -130,8 +131,8 @@
};
};
buildConfigurationList = 83E6F3701962FCDD0030D82A /* Build configuration list for PBXProject "Spreadsheet" */;
- compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
+ compatibilityVersion = "Xcode 15.3";
+ developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
@@ -196,21 +197,32 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
+ DEAD_CODE_STRIPPING = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -226,7 +238,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.9;
+ MACOSX_DEPLOYMENT_TARGET = 14.4;
METAL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
@@ -242,22 +254,33 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = YES;
+ DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -266,9 +289,10 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.9;
+ MACOSX_DEPLOYMENT_TARGET = 14.4;
METAL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
+ SWIFT_COMPILATION_MODE = wholemodule;
};
name = Release;
};
@@ -277,17 +301,22 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
+ DEAD_CODE_STRIPPING = YES;
INFOPLIST_FILE = Spreadsheet/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
"$(PROJECT_DIR)/Spreadsheet",
);
+ MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
PRODUCT_BUNDLE_IDENTIFIER = "com.unsignedinteger.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_INCLUDE_PATHS = "/Users/chris/Desktop/fpinswift/test-projects/Parsing/Parsing";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -296,17 +325,22 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
+ DEAD_CODE_STRIPPING = YES;
INFOPLIST_FILE = Spreadsheet/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
"$(PROJECT_DIR)/Spreadsheet",
);
+ MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
PRODUCT_BUNDLE_IDENTIFIER = "com.unsignedinteger.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_INCLUDE_PATHS = "/Users/chris/Desktop/fpinswift/test-projects/Parsing/Parsing";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
};
name = Release;
};
diff --git a/Spreadsheet/Spreadsheet.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Spreadsheet/Spreadsheet.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/Spreadsheet/Spreadsheet.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Spreadsheet/Spreadsheet.xcodeproj/project.xcworkspace/xcuserdata/macintosh.xcuserdatad/UserInterfaceState.xcuserstate b/Spreadsheet/Spreadsheet.xcodeproj/project.xcworkspace/xcuserdata/macintosh.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..b06d890
Binary files /dev/null and b/Spreadsheet/Spreadsheet.xcodeproj/project.xcworkspace/xcuserdata/macintosh.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/Spreadsheet/Spreadsheet.xcodeproj/xcuserdata/macintosh.xcuserdatad/xcschemes/xcschememanagement.plist b/Spreadsheet/Spreadsheet.xcodeproj/xcuserdata/macintosh.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..ad83256
--- /dev/null
+++ b/Spreadsheet/Spreadsheet.xcodeproj/xcuserdata/macintosh.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,14 @@
+
+
+
+
+ SchemeUserState
+
+ Spreadsheet.xcscheme_^#shared#^_
+
+ orderHint
+ 0
+
+
+
+
diff --git a/Spreadsheet/Spreadsheet/AppDelegate.swift b/Spreadsheet/Spreadsheet/AppDelegate.swift
index 409d829..13a5cf2 100644
--- a/Spreadsheet/Spreadsheet/AppDelegate.swift
+++ b/Spreadsheet/Spreadsheet/AppDelegate.swift
@@ -1,7 +1,7 @@
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate {
- var controller : SheetWindowController?
+ var controller: SheetWindowController?
func applicationDidFinishLaunching(_ aNotification: Notification) {
controller = SheetWindowController(windowNibName: "Sheet")
diff --git a/Spreadsheet/Spreadsheet/Expression.swift b/Spreadsheet/Spreadsheet/Expression.swift
index 5e5a613..5bf1431 100644
--- a/Spreadsheet/Spreadsheet/Expression.swift
+++ b/Spreadsheet/Spreadsheet/Expression.swift
@@ -45,7 +45,6 @@ extension Expression {
}
-
enum Result {
case int(Int)
case list([Result])
@@ -67,7 +66,7 @@ extension Expression {
case let .infix(l, op, r):
return self.evaluateArithmetic(context: context)
?? self.evaluateList(context: context)
- ?? .error("Invalid operator \(op) for operands \(l, r)")
+ ?? .error("Invalid operator \(op) for operands \(l) and \(r)")
default:
return .error("Couldn't evaluate expression \(self)")
}
@@ -117,7 +116,7 @@ extension Expression {
func lift(_ op: @escaping (Int, Int) -> Int) -> ((Result, Result) -> Result) {
return { lhs, rhs in
guard case let (.int(x), .int(y)) = (lhs, rhs) else {
- return .error("Invalid operands \(lhs, rhs) for integer operator")
+ return .error("Invalid operands \(lhs) and \(rhs) for integer operator")
}
return .int(op(x, y))
}
@@ -125,9 +124,5 @@ func lift(_ op: @escaping (Int, Int) -> Int) -> ((Result, Result) -> Result) {
func evaluate(expressions: [Expression?]) -> [Result] {
- return expressions.map { $0?.evaluate(context: expressions) ?? .error("Invalid expression \($0)") }
+ return expressions.map { $0?.evaluate(context: expressions) ?? .error("Invalid expression \(String(describing: $0))") }
}
-
-
-
-
diff --git a/Spreadsheet/Spreadsheet/Helpers.swift b/Spreadsheet/Spreadsheet/Helpers.swift
index db47233..2f20711 100644
--- a/Spreadsheet/Spreadsheet/Helpers.swift
+++ b/Spreadsheet/Spreadsheet/Helpers.swift
@@ -15,6 +15,3 @@ func curry(_ f: @escaping (A, B) -> C) -> (A) -> (B) -> C {
func curry(_ f: @escaping (A, B, C) -> D) -> (A) -> (B) -> (C) -> D {
return { a in { b in { c in f(a, b, c) } } }
}
-
-
-
diff --git a/Spreadsheet/Spreadsheet/Sheet.xib b/Spreadsheet/Spreadsheet/Sheet.xib
index 89969a8..3e286db 100644
--- a/Spreadsheet/Spreadsheet/Sheet.xib
+++ b/Spreadsheet/Spreadsheet/Sheet.xib
@@ -1,8 +1,8 @@
-
+
-
-
+
+
@@ -15,11 +15,11 @@
-
+
-
+
@@ -27,19 +27,18 @@
-
+
-
-
+
+
-
@@ -58,15 +57,15 @@
-
+
-
+
-
+
@@ -79,6 +78,7 @@
+
diff --git a/Spreadsheet/Spreadsheet/SheetWindowController.swift b/Spreadsheet/Spreadsheet/SheetWindowController.swift
index 4905983..ceb9d90 100644
--- a/Spreadsheet/Spreadsheet/SheetWindowController.swift
+++ b/Spreadsheet/Spreadsheet/SheetWindowController.swift
@@ -7,7 +7,7 @@ class SheetWindowController: NSWindowController {
override func windowDidLoad() {
delegate?.editedRowDelegate = dataSource
- NotificationCenter.default.addObserver(self, selector: NSSelectorFromString("endEditing:"), name: NSNotification.Name.NSControlTextDidEndEditing, object: nil)
+ NotificationCenter.default.addObserver(self, selector: NSSelectorFromString("endEditing:"), name: NSControl.textDidEndEditingNotification, object: nil)
}
func endEditing(_ note: Notification) {
@@ -17,7 +17,7 @@ class SheetWindowController: NSWindowController {
}
-protocol EditedRow: class {
+protocol EditedRow: AnyObject {
var editedRow: Int? { get set }
}
@@ -44,7 +44,7 @@ class SpreadsheetDatasource: NSObject, NSTableViewDataSource, EditedRow {
}
func parseAndEvaluate() {
- let expressions = formulas.map { Expression.parser.parse($0.characters)?.0 }
+ let expressions = formulas.map { formula in Expression.parser.parse(formula[...])?.0 }
results = evaluate(expressions: expressions)
}
diff --git a/Spreadsheet/Spreadsheet/main.swift b/Spreadsheet/Spreadsheet/main.swift
index 2408dd7..a511b5c 100644
--- a/Spreadsheet/Spreadsheet/main.swift
+++ b/Spreadsheet/Spreadsheet/main.swift
@@ -8,4 +8,4 @@
import Cocoa
-NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
+_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
diff --git a/Spreadsheet/Spreadsheet/parsing.swift b/Spreadsheet/Spreadsheet/parsing.swift
index 65ca165..2722538 100644
--- a/Spreadsheet/Spreadsheet/parsing.swift
+++ b/Spreadsheet/Spreadsheet/parsing.swift
@@ -1,14 +1,13 @@
import Foundation
-
struct Parser {
- typealias Stream = String.CharacterView
+ typealias Stream = Substring
let parse: (Stream) -> (A, Stream)?
}
extension Parser {
func run(_ string: String) -> (A, String)? {
- guard let (result, remainder) = parse(string.characters) else { return nil }
+ guard let (result, remainder) = parse(string[...]) else { return nil }
return (result, String(remainder))
}
@@ -61,8 +60,6 @@ extension Parser {
}
}
-
-
precedencegroup SequencePrecedence {
associativity: left
higherThan: AdditionPrecedence
@@ -93,9 +90,7 @@ func <|>(lhs: Parser, rhs: Parser) -> Parser {
return lhs.or(rhs)
}
-
-
-func character(condition: @escaping (Character) -> Bool) -> Parser {
+func character(matching condition: @escaping (Character) -> Bool) -> Parser {
return Parser { input in
guard let char = input.first, condition(char) else { return nil }
return (char, input.dropFirst())
@@ -105,7 +100,7 @@ func character(condition: @escaping (Character) -> Bool) -> Parser {
func string(_ string: String) -> Parser {
return Parser { input in
var remainder = input
- for c in string.characters {
+ for c in string {
let parser = character { $0 == c }
guard let (_, newRemainder) = parser.parse(remainder) else { return nil }
remainder = newRemainder
@@ -119,9 +114,6 @@ func lazy(_ parser: @autoclosure @escaping () -> Parser) -> Parser {
}
-let digit = character { CharacterSet.decimalDigits.contains($0) }
+let digit = character { $0.isNumber }
let integer = digit.many1.map { Int(String($0))! }
-let capitalLetter = character { CharacterSet.uppercaseLetters.contains($0) }
-
-
-
+let capitalLetter = character { $0.isUppercase }