Skip to content
This repository has been archived by the owner on Dec 5, 2019. It is now read-only.

Update Madness to master #11

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cartfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
github "robrix/Madness" "significant-indentation"
github "robrix/Either" ~> 1.1
github "robrix/Box" ~> 1.0.1
github "robrix/Prelude" ~> 1.4
github "robrix/Madness" "master"
github "robrix/Either" ~> 1.2.2
github "robrix/Box" ~> 1.2.2
github "robrix/Prelude" ~> 1.5
4 changes: 2 additions & 2 deletions Cartfile.private
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
github "jspahrsummers/xcconfigs"
github "Quick/Quick" ~> 0.2.2
github "Quick/Nimble" ~> 0.2
github "Quick/Quick" ~> 0.3.1
github "Quick/Nimble" ~> 1.0.0
14 changes: 7 additions & 7 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github "robrix/Box" "1.0.1"
github "robrix/Either" "1.1"
github "robrix/Madness" "b5e2882e924b2377da83adcdb59592ba7fdab52a"
github "Quick/Nimble" "v0.2.0"
github "robrix/Prelude" "1.4"
github "Quick/Quick" "v0.2.2"
github "jspahrsummers/xcconfigs" "0.7.1"
github "robrix/Box" "1.2.2"
github "Quick/Nimble" "v1.0.0"
github "robrix/Prelude" "1.5.0"
github "Quick/Quick" "v0.3.1"
github "jspahrsummers/xcconfigs" "0.8.1"
github "robrix/Either" "1.2.2"
github "robrix/Madness" "fa440dd21e7341f687f748afd98ccb12574e1bd0"
2 changes: 1 addition & 1 deletion Carthage/Checkouts/Madness
Submodule Madness updated 55 files
+11 −2 .gitmodules
+1 −0 Cartfile
+1 −0 Cartfile.private
+4 −0 Cartfile.resolved
+1 −0 Carthage/Checkouts/Assertions
+1 −0 Carthage/Checkouts/Box
+1 −0 Carthage/Checkouts/Either
+1 −0 Carthage/Checkouts/Prelude
+8 −0 Documentation/Collections.playground/contents.xcplayground
+1 −0 Documentation/Collections.playground/section-1.swift
+13 −0 Documentation/Collections.playground/section-2.swift
+0 −0 Documentation/Collections.playground/timeline.xctimeline
+8 −0 Documentation/Colours.playground/contents.xcplayground
+5 −0 Documentation/Colours.playground/section-1.swift
+29 −0 Documentation/Colours.playground/section-2.swift
+6 −0 Documentation/Colours.playground/timeline.xctimeline
+8 −0 Documentation/Lambda Calculus.playground/contents.xcplayground
+4 −0 Documentation/Lambda Calculus.playground/section-1.swift
+32 −0 Documentation/Lambda Calculus.playground/section-2.swift
+6 −0 Documentation/Lambda Calculus.playground/timeline.xctimeline
+0 −7 Documentation/Madness.playground/contents.xcplayground
+0 −64 Documentation/Madness.playground/section-1.swift
+0 −12 Documentation/Madness.playground/timeline.xctimeline
+0 −2 Documentation/Significant Indentation.playground/section-2.swift
+0 −0 Documentation/Subset of Common Markdown.playground/contents.xcplayground
+2 −0 Documentation/Subset of Common Markdown.playground/section-1.swift
+67 −0 Documentation/Subset of Common Markdown.playground/section-2.swift
+11 −0 Documentation/Subset of Common Markdown.playground/timeline.xctimeline
+0 −1 External/Either
+356 −36 Madness.xcodeproj/project.pbxproj
+8 −8 Madness.xcodeproj/xcshareddata/xcschemes/Madness-Mac.xcscheme
+110 −0 Madness.xcodeproj/xcshareddata/xcschemes/Madness-iOS.xcscheme
+14 −5 Madness.xcworkspace/contents.xcworkspacedata
+97 −0 Madness/Alternation.swift
+36 −0 Madness/Concatenation.swift
+58 −0 Madness/Error.swift
+22 −0 Madness/Ignore.swift
+63 −0 Madness/Map.swift
+52 −196 Madness/Parser.swift
+19 −0 Madness/Reduction.swift
+83 −0 Madness/Repetition.swift
+0 −11 Madness/String.swift
+102 −0 MadnessTests/AlternationTests.swift
+0 −59 MadnessTests/Assertions.swift
+0 −69 MadnessTests/BindTests.swift
+27 −0 MadnessTests/CollectionTests.swift
+54 −0 MadnessTests/ConcatenationTests.swift
+33 −0 MadnessTests/ErrorTests.swift
+35 −0 MadnessTests/Fixtures.swift
+44 −0 MadnessTests/IgnoreTests.swift
+111 −0 MadnessTests/MapTests.swift
+25 −226 MadnessTests/ParserTests.swift
+35 −0 MadnessTests/ReductionTests.swift
+201 −0 MadnessTests/RepetitionTests.swift
+18 −0 README.md
2 changes: 1 addition & 1 deletion Carthage/Checkouts/Nimble
Submodule Nimble updated 88 files
+1 −0 .gitignore
+0 −9 .travis.yml
+18 −4 CONTRIBUTING.md
+8 −7 Nimble.podspec
+191 −49 Nimble.xcodeproj/project.pbxproj
+2 −2 Nimble.xcodeproj/project.xcworkspace/xcshareddata/Nimble.xccheckout
+2 −3 Nimble/Adapters/AdapterProtocols.swift
+20 −0 Nimble/Adapters/AssertionDispatcher.swift
+54 −6 Nimble/Adapters/AssertionRecorder.swift
+28 −0 Nimble/Adapters/NimbleXCTestHandler.swift
+0 −10 Nimble/Adapters/XCTestHandler.swift
+43 −0 Nimble/DSL+Wait.swift
+8 −37 Nimble/DSL.swift
+31 −18 Nimble/Expectation.swift
+51 −5 Nimble/Expression.swift
+32 −7 Nimble/FailureMessage.swift
+88 −0 Nimble/Matchers/AllPass.swift
+11 −1 Nimble/Matchers/BeAKindOf.swift
+11 −1 Nimble/Matchers/BeAnInstanceOf.swift
+52 −4 Nimble/Matchers/BeCloseTo.swift
+16 −4 Nimble/Matchers/BeEmpty.swift
+2 −2 Nimble/Matchers/BeGreaterThan.swift
+2 −2 Nimble/Matchers/BeGreaterThanOrEqualTo.swift
+1 −1 Nimble/Matchers/BeIdenticalTo.swift
+2 −2 Nimble/Matchers/BeLessThan.swift
+1 −1 Nimble/Matchers/BeLessThanOrEqual.swift
+38 −21 Nimble/Matchers/BeLogical.swift
+1 −1 Nimble/Matchers/BeNil.swift
+2 −2 Nimble/Matchers/BeginWith.swift
+16 −2 Nimble/Matchers/Contain.swift
+5 −4 Nimble/Matchers/EndWith.swift
+63 −1 Nimble/Matchers/Equal.swift
+2 −2 Nimble/Matchers/Match.swift
+4 −35 Nimble/Matchers/MatcherProtocols.swift
+137 −54 Nimble/Matchers/RaisesException.swift
+79 −0 Nimble/ObjCExpectation.swift
+4 −4 Nimble/Utils/Stringers.swift
+48 −55 Nimble/Wrappers/AsyncMatcherWrapper.swift
+0 −28 Nimble/Wrappers/BasicMatcherWrapper.swift
+0 −18 Nimble/Wrappers/FullMatcherWrapper.swift
+56 −16 Nimble/Wrappers/MatcherFunc.swift
+0 −56 Nimble/Wrappers/NonNilMatcherWrapper.swift
+17 −93 Nimble/Wrappers/ObjCMatcher.swift
+23 −2 Nimble/objc/DSL.h
+27 −0 Nimble/objc/DSL.m
+1 −1 Nimble/objc/NMBExceptionCapture.h
+6 −7 NimbleTests/AsynchronousTest.swift
+44 −21 NimbleTests/Helpers/utils.swift
+74 −0 NimbleTests/Matchers/AllPassTest.swift
+18 −0 NimbleTests/Matchers/BeAKindOfTest.swift
+20 −0 NimbleTests/Matchers/BeAnInstanceOfTest.swift
+45 −0 NimbleTests/Matchers/BeCloseToTest.swift
+1 −1 NimbleTests/Matchers/BeEmptyTest.swift
+9 −9 NimbleTests/Matchers/BeIdenticalToObjectTest.swift
+2 −2 NimbleTests/Matchers/BeIdenticalToTest.swift
+22 −0 NimbleTests/Matchers/BeLogicalTest.swift
+1 −1 NimbleTests/Matchers/BeNilTest.swift
+2 −2 NimbleTests/Matchers/BeginWithTest.swift
+2 −2 NimbleTests/Matchers/EndWithTest.swift
+31 −0 NimbleTests/Matchers/EqualTest.swift
+131 −27 NimbleTests/Matchers/RaisesExceptionTest.swift
+0 −376 NimbleTests/objc/CompatibilityTest.m
+15 −0 NimbleTests/objc/NimbleSpecHelper.h
+38 −0 NimbleTests/objc/ObjCAllPassTest.m
+53 −0 NimbleTests/objc/ObjCAsyncTest.m
+34 −0 NimbleTests/objc/ObjCBeAnInstanceOfTest.m
+36 −0 NimbleTests/objc/ObjCBeCloseToTest.m
+80 −0 NimbleTests/objc/ObjCBeEmptyTest.m
+24 −0 NimbleTests/objc/ObjCBeFalseTest.m
+28 −0 NimbleTests/objc/ObjCBeFalsyTest.m
+33 −0 NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m
+33 −0 NimbleTests/objc/ObjCBeGreaterThanTest.m
+36 −0 NimbleTests/objc/ObjCBeIdenticalToTest.m
+34 −0 NimbleTests/objc/ObjCBeKindOfTest.m
+33 −0 NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m
+33 −0 NimbleTests/objc/ObjCBeLessThanTest.m
+24 −0 NimbleTests/objc/ObjCBeNilTest.m
+25 −0 NimbleTests/objc/ObjCBeTrueTest.m
+28 −0 NimbleTests/objc/ObjCBeTruthyTest.m
+37 −0 NimbleTests/objc/ObjCBeginWithTest.m
+50 −0 NimbleTests/objc/ObjCContainTest.m
+37 −0 NimbleTests/objc/ObjCEndWithTest.m
+35 −0 NimbleTests/objc/ObjCEqualTest.m
+33 −0 NimbleTests/objc/ObjCMatchTest.m
+176 −0 NimbleTests/objc/ObjCRaiseExceptionTest.m
+158 −56 README.md
+37 −0 circle.yml
+5 −4 test
2 changes: 1 addition & 1 deletion Carthage/Checkouts/Quick
Submodule Quick updated 37 files
+0 −5 .travis.yml
+4 −0 CONTRIBUTING.md
+220 −0 Documentation/ArrangeActAssert.md
+87 −0 Documentation/BehavioralTesting.md
+103 −0 Documentation/ConfiguringQuick.md
+28 −0 Documentation/InstallingFileTemplates.md
+141 −0 Documentation/InstallingQuick.md
+28 −0 Documentation/MoreResources.md
+106 −0 Documentation/NimbleAssertions.md
+462 −0 Documentation/QuickExamplesAndGroups.md
+53 −0 Documentation/QuickInObjectiveC.md
+42 −0 Documentation/README.md
+73 −0 Documentation/SettingUpYourXcodeProject.md
+125 −0 Documentation/SharedExamples.md
+179 −0 Documentation/TestingApps.md
+1 −1 Externals/Nimble
+4 −3 Quick.podspec
+44 −70 Quick.xcodeproj/project.pbxproj
+0 −1,348 Quick.xcodeproj/project.pbxproj.orig
+17 −17 Quick/DSL/DSL.swift
+1 −1 Quick/DSL/QCKDSL.h
+3 −3 Quick/DSL/QCKDSL.m
+9 −9 Quick/DSL/World+DSL.swift
+0 −25 QuickTests/ExampleMetadataFunctionalTests.swift
+1 −1 QuickTests/Fixtures/FunctionalTests_SharedExamplesTests_SharedExamples.swift
+0 −27 QuickTests/Fixtures/Person.swift
+0 −11 QuickTests/Fixtures/Poet.swift
+0 −65 QuickTests/FunctionalTests+ObjC.m
+0 −156 QuickTests/FunctionalTests.swift
+42 −0 QuickTests/FunctionalTests/AfterSuiteTests+ObjC.m
+1 −1 QuickTests/FunctionalTests/AfterSuiteTests.swift
+0 −0 QuickTests/FunctionalTests/BeforeSuiteTests+ObjC.m
+1 −1 QuickTests/FunctionalTests/BeforeSuiteTests.swift
+59 −0 QuickTests/FunctionalTests/SharedExamples+BeforeEachTests+ObjC.m
+36 −0 QuickTests/FunctionalTests/SharedExamplesTests+ObjC.m
+0 −21 QuickTests/FunctionalTests/WorldExampleMetadataFunctionalTests.swift
+9 −944 README.md
2 changes: 1 addition & 1 deletion Carthage/Checkouts/xcconfigs
111 changes: 56 additions & 55 deletions OGDL/Parser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,27 @@ import Madness
import Prelude

/// Returns a parser which parses one character from the given set.
internal prefix func % (characterSet: NSCharacterSet) -> Parser<String>.Function {
return { string in
let scalars = string.unicodeScalars

if let scalar = first(scalars) {
if characterSet.longCharacterIsMember(scalar.value) {
return (String(scalar), String(dropFirst(scalars)))
}
}

return nil
internal prefix func % <C: CollectionType where C.Generator.Element == Character>(characterSet: NSCharacterSet) -> Parser<C, String>.Function {
return { collection, index in
if index != collection.endIndex {
if let scalar = first(String(collection[index]).unicodeScalars) where characterSet.longCharacterIsMember(scalar.value) {
return .right(String(scalar), index.successor())
}
}
return .left(.leaf("Character is not present in NSCharacterSet", index))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixing tabs & spaces here, incidentally.

}
}

/// Removes the characters in the given string from the character set.
internal func - (characterSet: NSCharacterSet, characters: String) -> NSCharacterSet {
let mutableSet = characterSet.mutableCopy() as NSMutableCharacterSet
let mutableSet = characterSet.mutableCopy() as! NSMutableCharacterSet
mutableSet.removeCharactersInString(characters)
return mutableSet
}

/// Removes characters in the latter set from the former.
internal func - (characterSet: NSCharacterSet, subtrahend: NSCharacterSet) -> NSCharacterSet {
let mutableSet = characterSet.mutableCopy() as NSMutableCharacterSet
let mutableSet = characterSet.mutableCopy() as! NSMutableCharacterSet
mutableSet.formIntersectionWithCharacterSet(subtrahend.invertedSet)
return mutableSet
}
Expand All @@ -44,8 +41,8 @@ internal func - (characterSet: NSCharacterSet, subtrahend: NSCharacterSet) -> NS
postfix operator |? {}

/// Matches zero or one occurrence of the given parser.
internal postfix func |? <T>(parser: Parser<T>.Function) -> Parser<T?>.Function {
return (parser * (0..<2)) --> first
internal postfix func |? <C: CollectionType, T where C.Generator.Element: Equatable>(parser: Parser<C, T>.Function) -> Parser<C, T?>.Function {
return first <^> (parser * (0..<2))
}

private let char_control = NSCharacterSet.controlCharacterSet()
Expand All @@ -57,43 +54,46 @@ private let char_break = NSCharacterSet.newlineCharacterSet()
// TODO: Use this somewhere.
private let char_end = char_control - NSCharacterSet.whitespaceAndNewlineCharacterSet()

private let wordStart: Parser<String>.Function = %(char_word - "#'\"")
private let wordChars: Parser<String>.Function = (%(char_word - "'\""))* --> { strings in join("", strings) }
private let word: Parser<String>.Function = wordStart ++ wordChars --> (+)
private let br: Parser<()>.Function = ignore(%char_break)
private let eof: Parser<()>.Function = { $0 == "" ? ((), "") : nil }
private let comment: Parser<()>.Function = ignore(%"#" ++ (%char_text)+ ++ (br | eof))
private let wordStart: Parser<String, String>.Function = %(char_word - "#'\"")
private let wordChars: Parser<String, String>.Function = { join("", $0) } <^> (%(char_word - "'\""))*
private let word: Parser<String, String>.Function = (+) <^> wordStart ++ wordChars
private let br: Parser<String, Ignore>.Function = ignore(%char_break)
private let eof: Parser<String, Ignore>.Function = ignore("")//{ $0 == "" ? ((), "") : nil }

private let br_eof = br | eof
private let comment: Parser<String, Ignore>.Function = ignore(%"#" ++ (%char_text)+ ++ br_eof)

// TODO: Escape sequences.
private let singleQuotedChars: Parser<String>.Function = (%(char_text - "'"))* --> { strings in join("", strings) }
private let singleQuoted: Parser<String>.Function = ignore(%"'") ++ singleQuotedChars ++ ignore(%"'")
private let doubleQuotedChars: Parser<String>.Function = (%(char_text - "\""))* --> { strings in join("", strings) }
private let doubleQuoted: Parser<String>.Function = ignore(%"\"") ++ doubleQuotedChars ++ ignore(%"\"")
private let quoted: Parser<String>.Function = singleQuoted | doubleQuoted
private let requiredSpace: Parser<()>.Function = ignore((comment | %char_space)+)
private let optionalSpace: Parser<()>.Function = ignore((comment | %char_space)*)
private let separator: Parser<()>.Function = ignore(optionalSpace ++ %"," ++ optionalSpace)
private let singleQuotedChars: Parser<String, String>.Function = { join("", $0) } <^> (%(char_text - "'"))*
private let singleQuoted: Parser<String, String>.Function = ignore(%"'") ++ singleQuotedChars ++ ignore(%"'")
private let doubleQuotedChars: Parser<String, String>.Function = { join("", $0) } <^> (%(char_text - "\""))*
private let doubleQuoted: Parser<String, String>.Function = ignore(%"\"") ++ doubleQuotedChars ++ ignore(%"\"")
private let quoted: Parser<String, String>.Function = singleQuoted | doubleQuoted
private let requiredSpace: Parser<String, Ignore>.Function = ignore((comment | %char_space)+)
private let optionalSpace: Parser<String, Ignore>.Function = ignore((comment | %char_space)*)
private let separator: Parser<String, Ignore>.Function = ignore(optionalSpace ++ %"," ++ optionalSpace)

private let value: Parser<String>.Function = word | quoted
private let value: Parser<String, String>.Function = word | quoted

/// A function taking an Int and returning a parser which parses at least that many
/// indentation characters.
func indentation(n: Int) -> Parser<Int>.Function {
return (%char_space * (n..<Int.max)) --> { $0.count }
func indentation(n: Int) -> Parser<String, Int>.Function {
return count <^> (%char_space * (n..<Int.max))
}

// MARK: Generic combinators
// FIXME: move these into Madness.

/// Delays the evaluation of a parser so that it can be used in a recursive grammar without deadlocking Swift at runtime.
private func lazy<T>(parser: () -> Parser<T>.Function) -> Parser<T>.Function {
private func lazy<C: CollectionType, T where C.Generator.Element: Equatable>(parser: () -> Parser<C, T>.Function) -> Parser<C, T>.Function {
return { parser()($0) }
}

/// Returns a parser which produces an array of parse trees produced by `parser` interleaved with ignored parses of `separator`.
///
/// This is convenient for e.g. comma-separated lists.
private func interleave<T, U>(separator: Parser<U>.Function, parser: Parser<T>.Function) -> Parser<[T]>.Function {
return (parser ++ (ignore(separator) ++ parser)*) --> { [$0] + $1 }
private func interleave<C: CollectionType, T, U where C.Generator.Element: Equatable>(separator: Parser<C, U>.Function, parser: Parser<C, T>.Function) -> Parser<C, [T]>.Function {
return { [$0] + $1 } <^> (parser ++ (ignore(separator) ++ parser)*)
}

private func foldr<S: SequenceType, Result>(sequence: S, initial: Result, combine: (S.Generator.Element, Result) -> Result) -> Result {
Expand All @@ -105,12 +105,12 @@ private func foldr<G: GeneratorType, Result>(inout generator: G, initial: Result
return generator.next().map { combine($0, foldr(&generator, initial, combine)) } ?? initial
}

private func | <T, U> (left: Parser<T>.Function, right: String -> U) -> Parser<Either<T, U>>.Function {
return left | { (right($0), $0) }
private func | <C: CollectionType, T, U where C.Generator.Element: Equatable>(left: Parser<C, T>.Function, right: () -> U) -> Parser<C, Either<T, U>>.Function {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it would be better if the type of right was: (C, C.Index) -> U but then compiling takes endlessly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, let’s not sweat it.

return left | { .right(right(), $1 == $0.endIndex ? $1 : $1.successor()) }
}

private func | <T> (left: Parser<T>.Function, right: String -> T) -> Parser<T>.Function {
return left | { (right($0), $0) }
private func | <C: CollectionType, T where C.Generator.Element: Equatable>(left: Parser<C, T>.Function, right: () -> T) -> Parser<C, T>.Function {
return left | { .right(right(), $1 == $0.endIndex ? $1 : $1.successor()) }
}

private func flatMap<T, U>(x: [T], f: T -> [U]) -> [U] {
Expand All @@ -119,45 +119,46 @@ private func flatMap<T, U>(x: [T], f: T -> [U]) -> [U] {

// MARK: OGDL

private let children: Parser<[Node]>.Function = lazy { group | (element --> { elem in [ elem ] }) }
private let children: Parser<String, [Node]>.Function = lazy { group | ({ elem in [ elem ] } <^> element) }

private let element = lazy { value ++ (optionalSpace ++ children)|? --> { value, children in Node(value: value, children: children ?? []) } }
private let element = lazy { { Node(value: $0, children: $1 ?? []) } <^> value ++ (optionalSpace ++ children)|? }

// TODO: See Carthage/ogdl-swift#3.
private let block: Int -> Parser<()>.Function = { n in const(nil) }
private let block: Int -> Parser<String, Ignore>.Function = { _ in ignore(any) }

/// Parses a single descendent element.
///
/// This is an element which may be an in-line descendent, and which may further have in-line descendents of its own.
private let descendent = value --> { Node(value: $0) }
private let descendent = { Node(value: $0) } <^> value

/// Parses a sequence of hierarchically descending elements, e.g.:
///
/// x y z # => Node(x, [Node(y, Node(z))])
public let descendents: Parser<Node>.Function = interleave(requiredSpace, descendent) --> {
foldr(dropLast($0), last($0)!) { $0.nodeByAppendingChildren([ $1 ]) }
}
public let descendents: Parser<String, Node>.Function =
{ foldr(dropLast($0), last($0)!) { $0.nodeByAppendingChildren([ $1 ]) } }
<^> interleave(requiredSpace, descendent)

/// Parses a chain of descendents, optionally ending in a group.
///
/// x y (u, v) # => Node(x, [ Node(y, [ Node(u), Node(v) ]) ])
private let descendentChain: Parser<Node>.Function = (descendents ++ ((optionalSpace ++ group) | const([]))) --> uncurry(Node.nodeByAppendingChildren)
private let descendentChain: Parser<String, Node>.Function =
uncurry(Node.nodeByAppendingChildren) <^> (descendents ++ ((optionalSpace ++ group) | const([])))

/// Parses a sequence of adjacent sibling elements, e.g.:
///
/// x, y z, w (u, v) # => [ Node(x), Node(y, Node(z)), Node(w, [ Node(u), Node(v) ]) ]
public let adjacent: Parser<[Node]>.Function = lazy { interleave(separator, descendentChain) }
public let adjacent: Parser<String, [Node]>.Function = lazy { interleave(separator, descendentChain) }

/// Parses a parenthesized sequence of sibling elements, e.g.:
///
/// (x, y z, w) # => [ Node(x), Node(y, Node(z)), Node(w) ]
private let group = lazy { ignore(%"(") ++ optionalSpace ++ adjacent ++ optionalSpace ++ ignore(%")") }

private let subgraph: Int -> Parser<[Node]>.Function = { n in
(descendents ++ lines(n + 1) --> { [ $0.nodeByAppendingChildren($1) ] }) | adjacent
private let subgraph: Int -> Parser<String, [Node]>.Function = { n in
({ [ $0.nodeByAppendingChildren($1) ] } <^> descendents ++ lines(n + 1)) | adjacent
}

private let line: Int -> Parser<[Node]>.Function = fix { line in
private let line: Int -> Parser<String, [Node]>.Function = fix { line in
{ n in
// TODO: block parsing: ignore(%char_space+ ++ block(n))|?) ++
// See Carthage/ogdl-swift#3.
Expand All @@ -167,14 +168,14 @@ private let line: Int -> Parser<[Node]>.Function = fix { line in
}
}

private let followingLine: Int -> Parser<[Node]>.Function = { n in (ignore(comment | br)+ ++ line(n)) }
private let lines: Int -> Parser<[Node]>.Function = { n in
(line(n)|? ++ followingLine(n)*) --> { ($0 ?? []) + flatMap($1, id) }
private let followingLine: Int -> Parser<String, [Node]>.Function = { n in (ignore(comment | br)+ ++ line(n)) }
private let lines: Int -> Parser<String, [Node]>.Function = { n in
{ ($0 ?? []) + flatMap($1, id) } <^> (line(n)|? ++ followingLine(n)*)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: tabs, not spaces.

}

/// Parses a textual OGDL graph into a list of nodes (and their descendants).
///
/// Example:
///
/// let nodes = parse(graph, "foo (bar, buzz baz)")
public let graph: Parser<[Node]>.Function = ignore(comment | br)* ++ (lines(0) | adjacent) ++ ignore(comment | br)*
public let graph: Parser<String, [Node]>.Function = ignore(comment | br)* ++ (lines(0) | adjacent) ++ ignore(comment | br)*
30 changes: 15 additions & 15 deletions OGDLTests/ParserSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,34 @@ import Quick
class ParserSpec: QuickSpec {
override func spec() {
it("should parse the empty string") {
expect(parse(graph, "")).to(equal([]))
expect(parse(graph, "").right).to(equal([]))
}

it("should parse a line break") {
expect(parse(graph, "\n")).to(equal([]))
expect(parse(graph, "\n").right).to(equal([]))
}

it("should parse a series of line breaks") {
expect(parse(graph, "\n\n\n")).to(equal([]))
expect(parse(graph, "\n\n\n").right).to(equal([]))
}

it("should parse a single node with descendents") {
expect(parse(descendents, "foobar")).to(equal(Node(value: "foobar")))
expect(parse(descendents, "foobar").right).to(equal(Node(value: "foobar")))
}

it("should parse a single node with adjacent") {
expect(parse(adjacent, "foobar")).to(equal([ Node(value: "foobar") ]))
expect(parse(adjacent, "foobar").right).to(equal([ Node(value: "foobar") ]))
}

it("should parse a single node") {
let expectedGraph = [ Node(value: "foobar") ]
let parsedGraph = parse(graph, "foobar")
let parsedGraph = parse(graph, "foobar").right
expect(parsedGraph).to(equal(expectedGraph))
}

it("should parse a single node ending with a newline") {
let expectedGraph = [ Node(value: "foobar") ]
let parsedGraph = parse(graph, "foobar\n")
let parsedGraph = parse(graph, "foobar\n").right
expect(parsedGraph).to(equal(expectedGraph))
}

Expand All @@ -57,7 +57,7 @@ class ParserSpec: QuickSpec {
])
]

let parsedGraph = parse(graph, "foo bar fuzz buzz")
let parsedGraph = parse(graph, "foo bar fuzz buzz").right
expect(parsedGraph).to(equal(expectedGraph))
}

Expand All @@ -70,7 +70,7 @@ class ParserSpec: QuickSpec {
])
]

let parsedGraph = parse(graph, "foo \"bar\" \"fuzz buzz\"")
let parsedGraph = parse(graph, "foo \"bar\" \"fuzz buzz\"").right
expect(parsedGraph).to(equal(expectedGraph))
}

Expand All @@ -86,7 +86,7 @@ class ParserSpec: QuickSpec {
])
]

let parsedGraph = parse(graph, "foo bar, fuzz buzz")
let parsedGraph = parse(graph, "foo bar, fuzz buzz").right
expect(parsedGraph).to(equal(expectedGraph))
}

Expand All @@ -99,7 +99,7 @@ class ParserSpec: QuickSpec {
])
]

let parsedGraph = parse(graph, "foo (bar, quux)")
let parsedGraph = parse(graph, "foo (bar, quux)").right
expect(parsedGraph).to(equal(expectedGraph))
}

Expand All @@ -112,12 +112,12 @@ class ParserSpec: QuickSpec {
])
]

let parsedGraph = parse(graph, "foo ( bar.o 1.2, quux.o 2.1 )")
let parsedGraph = parse(graph, "foo ( bar.o 1.2, quux.o 2.1 )").right
expect(parsedGraph).to(equal(expectedGraph))
}

it("should parse comments") {
let parsedGraph = parse(graph, "#foo")
let parsedGraph = parse(graph, "#foo").right
expect(parsedGraph).to(equal([]))
}

Expand All @@ -142,10 +142,10 @@ class ParserSpec: QuickSpec {
for i in 1...5 {
let URL = NSBundle(forClass: self.dynamicType).URLForResource("Example2-\(i)", withExtension: "ogdl", subdirectory: "Samples")!

let sample = NSString(contentsOfURL: URL, encoding: NSUTF8StringEncoding, error: nil)
let sample = NSString(contentsOfURL: URL, encoding: NSUTF8StringEncoding, error: nil) as? String
expect(sample).notTo(beNil())

let parsedGraph = parse(graph, sample ?? "")
let parsedGraph = parse(graph, sample ?? "").right
if let parsedGraph = parsedGraph {
println("graph \(i):\n\(parsedGraph)\n")
}
Expand Down