Swiftの構文に変更を加えてみる


## はじめに

以前に書いた記事[「[Swift]途中で停止可能なforEachを暇つぶしに書いてみたメモ」](http://qiita.com/JunSuzukiJapan/items/49ddc544c80d9d76c429)で、

```swift:
// 略

list.forEach({$0 < 3}) {
    print("number: \($0)")
}
```

のようなコードを書いたのだが、```list.forEach({$0 < 3})```部分で'({'のように２種類のカッコを続けて書く必要があるのがちょっと気になっていた。

Swiftがオープンソースになったので、その辺をちょっと修正してみる。

具体的には、

```swift:
list.forEach {$0 < 3} {
    print($0)
}
```

のように、関数の引数に複数のクロージャを並べてかけるようにする。

## 変更点

変更点は以下の４箇所。

### swift/include/swift/Parse/Token.h

#### 1

```swift:swift/include/swift/Parse/Token.h（２８３行目あたり）　ー　変更前
  /// True if the token is an l_paren token that does not start a new line.
  bool isFollowingLParen() const {
    return !isAtStartOfLine() && Kind == tok::l_paren;
  }
```

上記の```isFollowingLParen()```関数の次に、```isFollowingLBrace()```を追加。

```swift:swift/include/swift/Parse/Token.h（２８３行目あたり）　ー　変更後
  /// True if the token is an l_paren token that does not start a new line.
  bool isFollowingLParen() const {
    return !isAtStartOfLine() && Kind == tok::l_paren;
  }

  /// True if the token is an l_brace token that does not start a new line.
  bool isFollowingLBrace() const {
    return !isAtStartOfLine() && Kind == tok::l_brace;
  }
```

### swift/lib/Parse/ParseExpr.cpp

#### 2

```swift:swift/lib/Parse/ParseExpr.cpp（１２３２行目あたり）　ー　変更前
      // We only allow a single trailing closure on a call.  This could be
      // generalized in the future, but needs further design.
      if (Tok.is(tok::l_brace)) break;
      continue;
```

```if (Tok.is(tok::l_brace)) break;```をコメントアウト。

```swift:swift/lib/Parse/ParseExpr.cpp（１２３２行目あたり）　ー　変更後
      // We only allow a single trailing closure on a call.  This could be
      // generalized in the future, but needs further design.
      //if (Tok.is(tok::l_brace)) break;
      continue;
 
```


#### 3


```swift:swift/lib/Parse/ParseExpr.cpp（１５３０行目あたり）　ー　変更前
  if (Tok.isAny(tok::l_paren, tok::l_square, tok::identifier, tok::kw__)) {
```

ifの条件内に```tok::l_brace```を追加。

```swift:swift/lib/Parse/ParseExpr.cpp（１５３０行目あたり）　ー　変更後
  if (Tok.isAny(tok::l_paren, tok::l_square, tok::identifier, tok::kw__, tok::l_brace)) {
```

#### 4


```swift:swift/lib/Parse/ParseExpr.cpp（１５４２行目あたり）　ー　変更前
    // Parse pattern-tuple func-signature-result? 'in'.
    if (consumeIf(tok::l_paren)) {      // Consume the ')'.

      // While we don't have '->' or ')', eat balanced tokens.
      while (!Tok.is(tok::r_paren) && !Tok.is(tok::eof))
        skipSingle();

      // Consume the ')', if it's there.
      if (consumeIf(tok::r_paren)) {
        consumeIf(tok::kw_throws) || consumeIf(tok::kw_rethrows);
        // Parse the func-signature-result, if present.
        if (consumeIf(tok::arrow)) {
          if (!canParseType())
            return false;
        }
      }

      // Okay, we have a closure signature.
    } else if (Tok.isIdentifierOrUnderscore()) {
      // Parse identifier (',' identifier)*

```

最初の```if```と次の```else if```の間に、新たに```else if```以下を追加。

```swift:swift/lib/Parse/ParseExpr.cpp（１５４２行目あたり）　ー　変更後
    // Parse pattern-tuple func-signature-result? 'in'.
    if (consumeIf(tok::l_paren)) {      // Consume the ')'.

      // While we don't have '->' or ')', eat balanced tokens.
      while (!Tok.is(tok::r_paren) && !Tok.is(tok::eof))
        skipSingle();

      // Consume the ')', if it's there.
      if (consumeIf(tok::r_paren)) {
        consumeIf(tok::kw_throws) || consumeIf(tok::kw_rethrows);
        // Parse the func-signature-result, if present.
        if (consumeIf(tok::arrow)) {
          if (!canParseType())
            return false;
        }
      }
      
      
      

    // ここから
    } else if (consumeIf(tok::l_brace)){  // Consume the '{'

      // While we don't have '->' or ')', eat balanced tokens.
      while (!Tok.is(tok::r_brace) && !Tok.is(tok::eof))
        skipSingle();

      // Consume the ')', if it's there.
      if (consumeIf(tok::r_brace)) {
        //consumeIf(tok::kw_throws) || consumeIf(tok::kw_rethrows);
        // Parse the func-signature-result, if present.
        //if (consumeIf(tok::arrow)) {
        //  if (!canParseType())
        //    return false;
        //}
      }
      // ここまでを追加。
      
      
      

      // Okay, we have a closure signature.
    } else if (Tok.isIdentifierOrUnderscore()) {
      // Parse identifier (',' identifier)*
```

## ビルド

修正したコードのビルド方法は以下の記事を参考にしてください。

[オープンソースになったSwiftをビルドしてみる](http://qiita.com/shu223/items/99b5ecc0ac5af2566c9c)

## 課題？

この修正が他の文法に影響を与えてないか調べる必要がある。
……のだが、ちょっと思いつかないので、「こんなコードが動かなくなった」などの情報をお寄せいただくと助かります。