//
// Parser.swift
// FootlessParser
//
// Released under the MIT License (MIT), http://opensource.org/licenses/MIT
//
// Copyright (c) 2015 NotTooBad Software. All rights reserved.
//

import Result
import Runes

// TODO: Implement ParserError
public typealias ParserError = String

public struct Parser <Token, Output> {
	public let parse: ParserInput<Token> -> Result<(output: Output, nextinput: ParserInput<Token>), ParserError>
}

/** Match a single token. */
public func token <T: Equatable> (token: T) -> Parser<T, T> {
	return Parser { input in
		return input.read(expect: toString(token)) >>- { next in
			if next.head == token {
				return .success(output:token, nextinput:next.tail)
			} else {
				return .failure("expected '\(token)', got '\(next.head)'.")
			}
		}
	}
}

/** Return whatever the next token is. */
public func any <T> () -> Parser<T, T> {
	return Parser { input in
		return input.read(expect: "anything") >>- { .success(output:$0.head, nextinput:$0.tail) }
	}
}

//
// Parser.swift
// FootlessParser
//
// Released under the MIT License (MIT), http://opensource.org/licenses/MIT
//
// Copyright (c) 2015 NotTooBad Software. All rights reserved.
//

import Result
import Runes

// TODO: Implement ParserError
public typealias ParserError = String

public struct Parser <Token, Output> {
	public let parse: ParserInput<Token> -> Result<(output: Output, nextinput: ParserInput<Token>), ParserError>
}

/** Succeeds iff 'condition' is true. Returns the token it read. */
public func satisfy <T> (# expect: String, condition: T -> Bool) -> Parser<T, T> {
	return Parser { input in
		return input.read(expect: expect) >>- { next in
			if condition(next.head) {
				return .success(output:next.head, nextinput:next.tail)
			} else {
				return .failure("expected '\(expect)', got '\(next.head)'.")
			}
		}
	}
}

/** Match a single token. */
public func token <T: Equatable> (token: T) -> Parser<T, T> {
	return satisfy(expect: toString(token)) { $0 == token }
}

/** Return whatever the next token is. */
public func any <T> () -> Parser<T, T> {
	return satisfy(expect: "anything") { T in true }
}

Make 'satisfy' parser, have 'any' and 'token' use it.
Make 'satisfy' parser, have 'any' and 'token' use it.

In

```swift
public func any <T> () -> Parser<T, T> {
	return satisfy(expect: "anything") { T in true }
}
```

"{ T in true }" is needed to avoid the compile error "error: 'Parser<(), ()>' is not convertible to 'Parser<T, T>'". Swift needs a little help to deduce types of generic parameters sometimes.
