├── .gitignore ├── jiffy.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── project.pbxproj ├── Jiffy ├── jiffy.h ├── Info.plist ├── Types.swift ├── Combinators.swift ├── Operators.swift └── DSON.swift └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | xcuserdata/ 2 | -------------------------------------------------------------------------------- /jiffy.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Jiffy/jiffy.h: -------------------------------------------------------------------------------- 1 | // 2 | // Jiffy.h 3 | // Jiffy 4 | // 5 | // Created by Hao on 11/22/15. 6 | // 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Jiffy. 12 | FOUNDATION_EXPORT double JiffyVersionNumber; 13 | 14 | //! Project version string for Jiffy. 15 | FOUNDATION_EXPORT const unsigned char JiffyVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Jiffy/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Jiffy/Types.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // a - token type 4 | // u - result type 5 | class Parser { 6 | func Run(_: Stream) -> Reply { 7 | return Reply.Error("wrong class") 8 | } 9 | } 10 | 11 | class Stream { 12 | let hay: [u] 13 | var i = 0 14 | typealias StreamSnapshot = Int 15 | 16 | init(hay: [u]) { 17 | self.hay = hay 18 | } 19 | 20 | func Peek() -> u { 21 | let x = self.hay.startIndex 22 | return self.hay[x] 23 | } 24 | 25 | func Skip() { 26 | i += 1 27 | } 28 | 29 | func Snapshot() -> StreamSnapshot { 30 | return self.i 31 | } 32 | 33 | func Rewind(i: StreamSnapshot) { 34 | self.i = i 35 | } 36 | } 37 | 38 | enum Reply { 39 | case Error(String) 40 | case Lovely(a) 41 | } 42 | 43 | class Thunk: Parser { 44 | let thunk: Stream -> Reply 45 | init(thunk: Stream -> Reply) { 46 | self.thunk = thunk 47 | } 48 | } 49 | 50 | class ParserRef: Parser { 51 | var parser: Parser? 52 | override init() { 53 | self.parser = nil 54 | } 55 | func Put(parser: Parser) { 56 | self.parser = parser 57 | } 58 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jiffy? 2 | 3 | *Jiffy* is a parser-combinator library written in Swift, heavily inspired by [FParsec](http://www.quanttec.com/fparsec/), which in turn originates from [Parsec](http://legacy.cs.uu.nl/daan/parsec.html). 4 | 5 | Included is a work-in-progress parser for the [Doge Serialized Object Notation](http://dogeon.org/), the premier textual data representation of our time. See: [DSON.swift](https://github.com/hlian/jiffy/blob/master/Jiffy/DSON.swift). 6 | 7 | # Parser combinators? 8 | 9 | Are fantastic, and you can read all about them here: ["Dive into parser combinators."](http://blog.fogcreek.com/fparsec/) Whoever wrote that must be a pretty OK dude. Gist: you can quickly and easily write composable, readable parsers for complicated grammars. Here, for example, is a parser for floating-point numbers: 10 | 11 | let pdigit = oneOf(Array("01234567")) 12 | let pdigit1 = oneOf(Array("1234567")) 13 | let pceil = string("0") <|> (concat <%> (s <%> pdigit1) <*> manyChar(pdigit1)) 14 | let pmantissa = concat <%> oneChar(".") <*> many1Char(pdigit) 15 | let pexponent = (string("very") <|> string("VERY")) *> (concat <%> oneCharOf(Array("+-")) <*> many1Char(pdigit)) 16 | let pnumber = toNumber <%> opt(oneChar("-")) <*> pceil <*> opt(pmantissa) <*> opt(pexponent) 17 | 18 | (If IEEE were to replace the `e` keyword with the DOGE `very` -- and I think we can all agree they should.) 19 | 20 | If you allow for some leeway, I hope to convince you that the code is a trivial transcription of this diagram: 21 | 22 | ![DSON floating-point number diagram](http://i.imgur.com/bHhToCN.png) 23 | 24 | # Swift? 25 | 26 | [Swift](http://haskell.org/) is a new language with a compiler that crashes and hangs a lot. 27 | Generics and typeclasses I mean protocols are ideal for something like parser combinators, don't you think? Having custom operators doesn't hurt either. 28 | 29 | If you're coming from Haskell or F#, there's one slight change you should be aware of: `<$>` isn't a valid operator name in Swift, so I went with `<%>` instead. Mnemonic: they're right next to each other! 30 | 31 | Yours,
32 | Hao. 33 | -------------------------------------------------------------------------------- /Jiffy/Combinators.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | func satisfy(pred: u -> Bool) -> Parser { 5 | let f: Stream -> Reply = { 6 | stream in 7 | if (pred(stream.Peek())) { 8 | return Reply.Error("not satisfied") 9 | } else { 10 | let c = stream.Peek() 11 | stream.Skip() 12 | return Reply.Lovely(c) 13 | } 14 | } 15 | return Thunk(thunk: f) 16 | } 17 | 18 | func many(parser: Parser) -> Parser { 19 | let f: Stream -> Reply<[a]> = { 20 | stream in 21 | var results: [a] = [] 22 | loop: while (true) { 23 | let r = parser.Run(stream) 24 | switch (r) { 25 | case .Lovely(let result): 26 | results.append(result) 27 | case .Error(_): 28 | break loop 29 | } 30 | } 31 | return Reply.Lovely(results) 32 | } 33 | return Thunk(thunk: f) 34 | } 35 | 36 | func many1(parser: Parser) -> Parser { 37 | let f: Stream -> Reply<[a]> = { 38 | stream in 39 | let r = many(parser).Run(stream) 40 | switch (r) { 41 | case .Lovely(let result): 42 | if result.count > 1 { 43 | return Reply.Lovely(result) 44 | } else { 45 | return Reply.Error("not enough") 46 | } 47 | case .Error(let error): 48 | return Reply.Error(error) 49 | } 50 | } 51 | return Thunk(thunk: f) 52 | } 53 | 54 | func opt(parser: Parser) -> Parser { 55 | let f: Stream -> Reply = { 56 | stream in 57 | let i = stream.Snapshot() 58 | let r = parser.Run(stream) 59 | switch (r) { 60 | case .Lovely(let result): 61 | return Reply.Lovely(result) 62 | case .Error(_): 63 | stream.Rewind(i) 64 | return Reply.Lovely(nil) 65 | } 66 | } 67 | return Thunk(thunk: f) 68 | } 69 | 70 | func one(x: u) -> Parser { 71 | let f: u -> Bool = { $0 == x } 72 | return satisfy(f) 73 | } 74 | 75 | func oneOf(xs: [u]) -> Parser { 76 | return satisfy { (y: u) in 77 | let filtered = xs.filter { $0 == y } 78 | return filtered.count > 0 79 | } 80 | } 81 | 82 | func string(xs: String) -> Parser { 83 | preconditionFailure("gotta write this") 84 | } 85 | 86 | func sepBy(parser: Parser, _ separator: Parser) -> Parser { 87 | preconditionFailure("gotta write this") 88 | } 89 | 90 | func between(parens: Parser, _ parser: Parser) -> Parser { 91 | preconditionFailure("gotta write this") 92 | } 93 | -------------------------------------------------------------------------------- /Jiffy/Operators.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | // The default precedence is 100. 5 | infix operator <%> { associativity left } 6 | infix operator >>= { associativity left precedence 80 } 7 | infix operator <*> { associativity left } 8 | infix operator <* { associativity left } 9 | infix operator *> { associativity left } 10 | infix operator <|> { associativity left precedence 90 } 11 | infix operator <% { associativity left } 12 | infix operator <**> { associativity left } 13 | 14 | // Functor 15 | func <%>(f: t -> a, parser: Parser) -> Parser { 16 | let f: Stream -> Reply
= { 17 | stream in 18 | switch (parser.Run(stream)) { 19 | case .Lovely(let result): 20 | return Reply.Lovely(f(result)) 21 | case .Error(let error): 22 | return Reply.Error(error) 23 | } 24 | } 25 | return Thunk(thunk: f) 26 | } 27 | 28 | // Applicative 29 | func pure(x: a) -> Parser { 30 | let f: Stream -> Reply = { 31 | stream in 32 | return Reply.Lovely(x) 33 | } 34 | return Thunk(thunk: f) 35 | } 36 | 37 | func <*>(parserF: Parser a>, parser: Parser) -> Parser { 38 | let f: Stream -> Reply = { 39 | stream in 40 | switch (parserF.Run(stream)) { 41 | case .Lovely(let g): 42 | switch (parser.Run(stream)) { 43 | case .Lovely(let result): 44 | return Reply.Lovely(g(result)) 45 | case .Error(let error): 46 | return Reply.Error(error) 47 | } 48 | case .Error(let error): 49 | return Reply.Error(error) 50 | } 51 | } 52 | return Thunk(thunk: f) 53 | } 54 | 55 | func <**>(parser: Parser, parserF: Parser a>) -> Parser { 56 | return parserF <*> parser; 57 | } 58 | 59 | func <*(left: Parser, right: Parser) -> Parser { 60 | return { a in { b in a } } <%> left <*> right; 61 | } 62 | 63 | func *>(left: Parser, right: Parser) -> Parser { 64 | return { a in { b in b } } <%> left <*> right; 65 | } 66 | 67 | // Alternative 68 | func <|>(left: Parser, right: Parser) -> Parser { 69 | let f: Stream -> Reply = { 70 | stream in 71 | let snapshot = stream.Snapshot() 72 | switch (left.Run(stream)) { 73 | case .Lovely(let result): 74 | return Reply.Lovely(result) 75 | case .Error(_): 76 | stream.Rewind(snapshot) 77 | return right.Run(stream) 78 | } 79 | } 80 | return Thunk(thunk: f) 81 | } 82 | 83 | // Monad 84 | func >>=(parser: Parser, binder: t -> Parser) -> Parser { 85 | let f: Stream -> Reply = { 86 | stream in 87 | switch (parser.Run(stream)) { 88 | case .Lovely(let result): 89 | return binder(result).Run(stream) 90 | case .Error(let error): 91 | return Reply.Error(error) 92 | } 93 | } 94 | return Thunk(thunk: f) 95 | } 96 | 97 | // Utility functions 98 | func <%(x: a, left: Parser) -> Parser { 99 | return { _ in x } <%> left 100 | } -------------------------------------------------------------------------------- /Jiffy/DSON.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | enum DSON { 4 | case DString(String) 5 | case Number(Float) 6 | case Array([DSON]) 7 | case Object(Dictionary) 8 | case NotFalse 9 | case NotTrue 10 | case Nullish 11 | } 12 | 13 | // I wish: 14 | // - constructors were functions 15 | // - the compiler didn't hang or crash 16 | // - closures were curried by default 17 | 18 | extension Optional { 19 | func or(val: Wrapped) -> Wrapped { 20 | return self == nil ? val : self!; 21 | } 22 | } 23 | 24 | extension String { 25 | var array: [Character] { 26 | return Array(self.characters) 27 | } 28 | } 29 | 30 | func toNumber(sign: String?)(ceiling: String)(mantissa: String?)(exponent: String?) -> Float { 31 | let s = sign.or("") + ceiling + mantissa.or("") + exponent.or("") 32 | return Float(s)! 33 | } 34 | 35 | func toObject(tuples: [(String, DSON)]) -> Dictionary { 36 | var d: Dictionary = [:] 37 | for (k, v) in tuples { 38 | d[k] = v 39 | } 40 | return d 41 | } 42 | 43 | func makeDSONParser() -> Parser { 44 | let concat: String -> String -> String = { x in { y in x + y } } 45 | let joinCharacters: ([Character]) -> String = { xs in xs.map { String($0) }.joinWithSeparator("") } 46 | let manyChar: Parser -> Parser = { joinCharacters <%> many($0) } 47 | let many1Char: Parser -> Parser = { joinCharacters <%> many1($0) } 48 | let s: Character -> String = { String($0) } 49 | let oneChar: Character -> Parser = { s <%> one($0) } 50 | let oneCharOf: ([Character]) -> Parser = { s <%> oneOf($0) } 51 | 52 | let pvalue: ParserRef = ParserRef() 53 | let pwhitespace = many(oneOf(" \r\n".array)) 54 | let pnext = pwhitespace *> string("next") *> pwhitespace 55 | 56 | let pcharUnicode = satisfy { (c: Character) in c != "\"" && c != "\\" } 57 | let pchar = pcharUnicode <|> ({ _ in "\"" } <%> string("\\\"")) // TODO 58 | let pstringInnards = manyChar(pchar) 59 | let pstring = between(one("\""), pstringInnards) 60 | 61 | let pobjectTuple = { a in { b in (a, b) } } <%> (pstring <* pwhitespace <* string("is") <* pwhitespace) <*> pvalue 62 | let pobjectInnards = sepBy(pobjectTuple, pnext) 63 | let pobject = toObject <%> (string("such") *> pobjectInnards <* string("wow")) 64 | 65 | let parrayInnards = sepBy(pvalue, pnext) 66 | let parray: Parser = (string("so") *> pwhitespace) *> parrayInnards <* (pwhitespace *> string("many")) 67 | 68 | let notfalse = { _ in DSON.NotFalse } <%> string("notfalse") 69 | let nottrue = { _ in DSON.NotTrue } <%> string("nottrue") 70 | let nullish = { _ in DSON.Nullish } <%> string("nullish") 71 | let keyword = notfalse <|> nottrue <|> nullish 72 | 73 | let pdigit = oneOf(Array("0123456789".array)) 74 | let pdigit1 = oneOf(Array("123456789".array)) 75 | let pceil = string("0") <|> (concat <%> (s <%> pdigit1) <*> manyChar(pdigit1)) 76 | 77 | let pmantissa = concat <%> oneChar(".") <*> many1Char(pdigit) 78 | let pexponent = (string("very") <|> string("VERY")) *> (concat <%> oneCharOf(Array("+-".characters)) <*> many1Char(pdigit)) 79 | let pnumber = toNumber <%> opt(oneChar("-")) <*> pceil <*> opt(pmantissa) <*> opt(pexponent) 80 | 81 | pvalue.Put( 82 | ({ DSON.DString($0) } <%> pstring) 83 | <|> ({ DSON.Number($0) } <%> pnumber) 84 | <|> ({ DSON.Object($0) } <%> pobject) 85 | <|> ({ DSON.Array($0) } <%> parray) 86 | <|> keyword) 87 | 88 | return pvalue 89 | } 90 | 91 | let DSONParser = makeDSONParser() 92 | -------------------------------------------------------------------------------- /jiffy.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3FAD34761C018DFD00F10F55 /* Jiffy.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FAD34751C018DFD00F10F55 /* Jiffy.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 3FAD347B1C018E3700F10F55 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FAD345F1C018D9200F10F55 /* Operators.swift */; }; 12 | 3FAD347C1C018E3700F10F55 /* Combinators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1DCBA0195781C700965619 /* Combinators.swift */; }; 13 | 3FAD347D1C018E3700F10F55 /* DSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1DCBA1195781C700965619 /* DSON.swift */; }; 14 | 3FAD347E1C018E3700F10F55 /* Types.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1DCBA2195781C700965619 /* Types.swift */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXFileReference section */ 18 | 3F1DCBA0195781C700965619 /* Combinators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Combinators.swift; path = Jiffy/Combinators.swift; sourceTree = ""; }; 19 | 3F1DCBA1195781C700965619 /* DSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DSON.swift; path = Jiffy/DSON.swift; sourceTree = ""; }; 20 | 3F1DCBA2195781C700965619 /* Types.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Types.swift; path = Jiffy/Types.swift; sourceTree = ""; }; 21 | 3FAD345F1C018D9200F10F55 /* Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Operators.swift; path = Jiffy/Operators.swift; sourceTree = ""; }; 22 | 3FAD34731C018DFD00F10F55 /* Jiffy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jiffy.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | 3FAD34751C018DFD00F10F55 /* Jiffy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Jiffy.h; sourceTree = ""; }; 24 | 3FAD34771C018DFD00F10F55 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 25 | /* End PBXFileReference section */ 26 | 27 | /* Begin PBXFrameworksBuildPhase section */ 28 | 3FAD346F1C018DFD00F10F55 /* Frameworks */ = { 29 | isa = PBXFrameworksBuildPhase; 30 | buildActionMask = 2147483647; 31 | files = ( 32 | ); 33 | runOnlyForDeploymentPostprocessing = 0; 34 | }; 35 | /* End PBXFrameworksBuildPhase section */ 36 | 37 | /* Begin PBXGroup section */ 38 | 3F1DCB991957814D00965619 = { 39 | isa = PBXGroup; 40 | children = ( 41 | 3FAD345F1C018D9200F10F55 /* Operators.swift */, 42 | 3F1DCBA0195781C700965619 /* Combinators.swift */, 43 | 3F1DCBA1195781C700965619 /* DSON.swift */, 44 | 3F1DCBA2195781C700965619 /* Types.swift */, 45 | 3FAD34741C018DFD00F10F55 /* Jiffy */, 46 | 3F1DCBA8195781FD00965619 /* Products */, 47 | ); 48 | sourceTree = ""; 49 | }; 50 | 3F1DCBA8195781FD00965619 /* Products */ = { 51 | isa = PBXGroup; 52 | children = ( 53 | 3FAD34731C018DFD00F10F55 /* Jiffy.framework */, 54 | ); 55 | name = Products; 56 | sourceTree = ""; 57 | }; 58 | 3FAD34741C018DFD00F10F55 /* Jiffy */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3FAD34751C018DFD00F10F55 /* Jiffy.h */, 62 | 3FAD34771C018DFD00F10F55 /* Info.plist */, 63 | ); 64 | path = Jiffy; 65 | sourceTree = ""; 66 | }; 67 | /* End PBXGroup section */ 68 | 69 | /* Begin PBXHeadersBuildPhase section */ 70 | 3FAD34701C018DFD00F10F55 /* Headers */ = { 71 | isa = PBXHeadersBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | 3FAD34761C018DFD00F10F55 /* Jiffy.h in Headers */, 75 | ); 76 | runOnlyForDeploymentPostprocessing = 0; 77 | }; 78 | /* End PBXHeadersBuildPhase section */ 79 | 80 | /* Begin PBXNativeTarget section */ 81 | 3FAD34721C018DFD00F10F55 /* Jiffy */ = { 82 | isa = PBXNativeTarget; 83 | buildConfigurationList = 3FAD34781C018DFD00F10F55 /* Build configuration list for PBXNativeTarget "Jiffy" */; 84 | buildPhases = ( 85 | 3FAD346E1C018DFD00F10F55 /* Sources */, 86 | 3FAD346F1C018DFD00F10F55 /* Frameworks */, 87 | 3FAD34701C018DFD00F10F55 /* Headers */, 88 | 3FAD34711C018DFD00F10F55 /* Resources */, 89 | ); 90 | buildRules = ( 91 | ); 92 | dependencies = ( 93 | ); 94 | name = Jiffy; 95 | productName = Jiffy; 96 | productReference = 3FAD34731C018DFD00F10F55 /* Jiffy.framework */; 97 | productType = "com.apple.product-type.framework"; 98 | }; 99 | /* End PBXNativeTarget section */ 100 | 101 | /* Begin PBXProject section */ 102 | 3F1DCB9A1957814D00965619 /* Project object */ = { 103 | isa = PBXProject; 104 | attributes = { 105 | LastSwiftUpdateCheck = 0710; 106 | LastUpgradeCheck = 0710; 107 | TargetAttributes = { 108 | 3FAD34721C018DFD00F10F55 = { 109 | CreatedOnToolsVersion = 7.1.1; 110 | }; 111 | }; 112 | }; 113 | buildConfigurationList = 3F1DCB9D1957814D00965619 /* Build configuration list for PBXProject "jiffy" */; 114 | compatibilityVersion = "Xcode 3.2"; 115 | developmentRegion = English; 116 | hasScannedForEncodings = 0; 117 | knownRegions = ( 118 | en, 119 | ); 120 | mainGroup = 3F1DCB991957814D00965619; 121 | productRefGroup = 3F1DCBA8195781FD00965619 /* Products */; 122 | projectDirPath = ""; 123 | projectRoot = ""; 124 | targets = ( 125 | 3FAD34721C018DFD00F10F55 /* Jiffy */, 126 | ); 127 | }; 128 | /* End PBXProject section */ 129 | 130 | /* Begin PBXResourcesBuildPhase section */ 131 | 3FAD34711C018DFD00F10F55 /* Resources */ = { 132 | isa = PBXResourcesBuildPhase; 133 | buildActionMask = 2147483647; 134 | files = ( 135 | ); 136 | runOnlyForDeploymentPostprocessing = 0; 137 | }; 138 | /* End PBXResourcesBuildPhase section */ 139 | 140 | /* Begin PBXSourcesBuildPhase section */ 141 | 3FAD346E1C018DFD00F10F55 /* Sources */ = { 142 | isa = PBXSourcesBuildPhase; 143 | buildActionMask = 2147483647; 144 | files = ( 145 | 3FAD347B1C018E3700F10F55 /* Operators.swift in Sources */, 146 | 3FAD347C1C018E3700F10F55 /* Combinators.swift in Sources */, 147 | 3FAD347D1C018E3700F10F55 /* DSON.swift in Sources */, 148 | 3FAD347E1C018E3700F10F55 /* Types.swift in Sources */, 149 | ); 150 | runOnlyForDeploymentPostprocessing = 0; 151 | }; 152 | /* End PBXSourcesBuildPhase section */ 153 | 154 | /* Begin XCBuildConfiguration section */ 155 | 3F1DCB9E1957814D00965619 /* Debug */ = { 156 | isa = XCBuildConfiguration; 157 | buildSettings = { 158 | ENABLE_TESTABILITY = YES; 159 | ONLY_ACTIVE_ARCH = YES; 160 | }; 161 | name = Debug; 162 | }; 163 | 3F1DCB9F1957814D00965619 /* Release */ = { 164 | isa = XCBuildConfiguration; 165 | buildSettings = { 166 | }; 167 | name = Release; 168 | }; 169 | 3FAD34791C018DFD00F10F55 /* Debug */ = { 170 | isa = XCBuildConfiguration; 171 | buildSettings = { 172 | ALWAYS_SEARCH_USER_PATHS = NO; 173 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 174 | CLANG_CXX_LIBRARY = "libc++"; 175 | CLANG_ENABLE_MODULES = YES; 176 | CLANG_ENABLE_OBJC_ARC = YES; 177 | CLANG_WARN_BOOL_CONVERSION = YES; 178 | CLANG_WARN_CONSTANT_CONVERSION = YES; 179 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 180 | CLANG_WARN_EMPTY_BODY = YES; 181 | CLANG_WARN_ENUM_CONVERSION = YES; 182 | CLANG_WARN_INT_CONVERSION = YES; 183 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 184 | CLANG_WARN_UNREACHABLE_CODE = YES; 185 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 186 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 187 | COPY_PHASE_STRIP = NO; 188 | CURRENT_PROJECT_VERSION = 1; 189 | DEBUG_INFORMATION_FORMAT = dwarf; 190 | DEFINES_MODULE = YES; 191 | DYLIB_COMPATIBILITY_VERSION = 1; 192 | DYLIB_CURRENT_VERSION = 1; 193 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 194 | ENABLE_STRICT_OBJC_MSGSEND = YES; 195 | GCC_C_LANGUAGE_STANDARD = gnu99; 196 | GCC_DYNAMIC_NO_PIC = NO; 197 | GCC_NO_COMMON_BLOCKS = YES; 198 | GCC_OPTIMIZATION_LEVEL = 0; 199 | GCC_PREPROCESSOR_DEFINITIONS = ( 200 | "DEBUG=1", 201 | "$(inherited)", 202 | ); 203 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 204 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 205 | GCC_WARN_UNDECLARED_SELECTOR = YES; 206 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 207 | GCC_WARN_UNUSED_FUNCTION = YES; 208 | GCC_WARN_UNUSED_VARIABLE = YES; 209 | INFOPLIST_FILE = Jiffy/Info.plist; 210 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 211 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 212 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 213 | MTL_ENABLE_DEBUG_INFO = YES; 214 | PRODUCT_BUNDLE_IDENTIFIER = org.haolian.Jiffy; 215 | PRODUCT_NAME = "$(TARGET_NAME)"; 216 | SDKROOT = iphoneos; 217 | SKIP_INSTALL = YES; 218 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 219 | TARGETED_DEVICE_FAMILY = "1,2"; 220 | VERSIONING_SYSTEM = "apple-generic"; 221 | VERSION_INFO_PREFIX = ""; 222 | }; 223 | name = Debug; 224 | }; 225 | 3FAD347A1C018DFD00F10F55 /* Release */ = { 226 | isa = XCBuildConfiguration; 227 | buildSettings = { 228 | ALWAYS_SEARCH_USER_PATHS = NO; 229 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 230 | CLANG_CXX_LIBRARY = "libc++"; 231 | CLANG_ENABLE_MODULES = YES; 232 | CLANG_ENABLE_OBJC_ARC = YES; 233 | CLANG_WARN_BOOL_CONVERSION = YES; 234 | CLANG_WARN_CONSTANT_CONVERSION = YES; 235 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 236 | CLANG_WARN_EMPTY_BODY = YES; 237 | CLANG_WARN_ENUM_CONVERSION = YES; 238 | CLANG_WARN_INT_CONVERSION = YES; 239 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 240 | CLANG_WARN_UNREACHABLE_CODE = YES; 241 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 242 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 243 | COPY_PHASE_STRIP = NO; 244 | CURRENT_PROJECT_VERSION = 1; 245 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 246 | DEFINES_MODULE = YES; 247 | DYLIB_COMPATIBILITY_VERSION = 1; 248 | DYLIB_CURRENT_VERSION = 1; 249 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 250 | ENABLE_NS_ASSERTIONS = NO; 251 | ENABLE_STRICT_OBJC_MSGSEND = YES; 252 | GCC_C_LANGUAGE_STANDARD = gnu99; 253 | GCC_NO_COMMON_BLOCKS = YES; 254 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 255 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 256 | GCC_WARN_UNDECLARED_SELECTOR = YES; 257 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 258 | GCC_WARN_UNUSED_FUNCTION = YES; 259 | GCC_WARN_UNUSED_VARIABLE = YES; 260 | INFOPLIST_FILE = Jiffy/Info.plist; 261 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 262 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 263 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 264 | MTL_ENABLE_DEBUG_INFO = NO; 265 | PRODUCT_BUNDLE_IDENTIFIER = org.haolian.Jiffy; 266 | PRODUCT_NAME = "$(TARGET_NAME)"; 267 | SDKROOT = iphoneos; 268 | SKIP_INSTALL = YES; 269 | TARGETED_DEVICE_FAMILY = "1,2"; 270 | VALIDATE_PRODUCT = YES; 271 | VERSIONING_SYSTEM = "apple-generic"; 272 | VERSION_INFO_PREFIX = ""; 273 | }; 274 | name = Release; 275 | }; 276 | /* End XCBuildConfiguration section */ 277 | 278 | /* Begin XCConfigurationList section */ 279 | 3F1DCB9D1957814D00965619 /* Build configuration list for PBXProject "jiffy" */ = { 280 | isa = XCConfigurationList; 281 | buildConfigurations = ( 282 | 3F1DCB9E1957814D00965619 /* Debug */, 283 | 3F1DCB9F1957814D00965619 /* Release */, 284 | ); 285 | defaultConfigurationIsVisible = 0; 286 | defaultConfigurationName = Release; 287 | }; 288 | 3FAD34781C018DFD00F10F55 /* Build configuration list for PBXNativeTarget "Jiffy" */ = { 289 | isa = XCConfigurationList; 290 | buildConfigurations = ( 291 | 3FAD34791C018DFD00F10F55 /* Debug */, 292 | 3FAD347A1C018DFD00F10F55 /* Release */, 293 | ); 294 | defaultConfigurationIsVisible = 0; 295 | }; 296 | /* End XCConfigurationList section */ 297 | }; 298 | rootObject = 3F1DCB9A1957814D00965619 /* Project object */; 299 | } 300 | --------------------------------------------------------------------------------