Files
swift-mirror/include/swift/AST/ExprNodes.def
Doug Gregor ce3fe3ae92 Implement Ruby-inspired closure syntax.
This commit implements closure syntax that places the (optional)
parameter list in pipes within the curly braces of a closure. This
syntax "slides" well from very simple closures with anonymous
arguments, e.g.,

  sort(array, {$1 > $0})

to naming the arguments

  sort(array, {|x, y| x > y})

to adding a return type and/or parameter types

  sort(array, {|x : String, y : String| -> Bool x > y})

and with multiple statements in the body:

  sort(array, {|x, y|
    print("Comparing \(x) and \(y)\n")
    return x > y
  })

When the body contains only a single expression, that expression
participates in type inference with its enclosing expression, which
allows one to type-check, e.g.,

  map(strings, {|x| x.toUpper()})

without context. If one has multiple statements, however, one will
need to provide additional type information either with context

  strings = map(strings, {
    return $0.toUpper()
  })

or via annotations

  map(strings, {|x| -> String 
    return x.toUpper()
  }

because we don't perform inter-statement type inference.

The new closure expressions are only available with the new type
checker, where they completely displace the existing { $0 + $1 }
anonymous closures. 'func' expressions remain unchanged.

The tiny test changes (in SIL output and the constraint-checker test)
are due to the PipeClosureExpr AST storing anonymous closure arguments
($0, $1, etc.) within a pattern in the AST. It's far cleaner to
implement this way.

The testing here is still fairly light. In particular, we need better
testing of parser recovery, name lookup for closures with local types,
more deduction scenarios, and multi-statement closures (which don't
get exercised beyond the unit tests).



Swift SVN r5169
2013-05-14 05:17:10 +00:00

140 lines
4.8 KiB
C++

//===--- ExprNodes.def - Swift Expression AST Metaprogramming ---*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines macros used for macro-metaprogramming with expressions.
//
//===----------------------------------------------------------------------===//
/// EXPR(Id, Parent)
/// If the expression node is not abstract, its enumerator value is
/// ExprKind::Id. The node's class name is Id##Expr, and the name of
/// its base class (in the Expr hierarchy) is Parent.
#ifndef EXPR
#define EXPR(Id, Parent)
#endif
/// An abstract expression node is an abstract base class in the hierarchy;
/// it is never a most-derived type, and it does not have an enumerator in
/// ExprKind.
///
/// Most metaprograms do not care about abstract expressions, so the default
/// is to ignore them.
#ifndef ABSTRACT_EXPR
#define ABSTRACT_EXPR(Id, Parent)
#endif
/// An "unchecked" expression node is removed from valid code by the end
/// of the type-checking phase.
///
/// By default, these are treated like any other expression.
#ifndef UNCHECKED_EXPR
#define UNCHECKED_EXPR(Id, Parent) EXPR(Id, Parent)
#endif
/// A convenience for determining the range of expressions. These will always
/// appear immediately after the last member.
#ifndef EXPR_RANGE
#define EXPR_RANGE(Id, First, Last)
#endif
EXPR(Error, Expr)
ABSTRACT_EXPR(Literal, Expr)
EXPR(IntegerLiteral, LiteralExpr)
EXPR(FloatLiteral, LiteralExpr)
EXPR(CharacterLiteral, LiteralExpr)
EXPR(StringLiteral, LiteralExpr)
EXPR(InterpolatedStringLiteral, LiteralExpr)
EXPR_RANGE(Literal, IntegerLiteral, InterpolatedStringLiteral)
EXPR(DeclRef, Expr)
EXPR(SuperRef, Expr)
EXPR(OtherConstructorDeclRef, Expr)
UNCHECKED_EXPR(UnresolvedConstructor, Expr)
EXPR(DotSyntaxBaseIgnored, Expr)
ABSTRACT_EXPR(OverloadSetRef, Expr)
UNCHECKED_EXPR(OverloadedDeclRef, OverloadSetRefExpr)
UNCHECKED_EXPR(OverloadedMemberRef, OverloadSetRefExpr)
EXPR_RANGE(OverloadSetRef, OverloadedDeclRef, OverloadedMemberRef)
UNCHECKED_EXPR(UnresolvedDeclRef, Expr)
UNCHECKED_EXPR(UnresolvedIf, Expr)
UNCHECKED_EXPR(UnresolvedElse, Expr)
EXPR(MemberRef, Expr)
EXPR(ExistentialMemberRef, Expr)
EXPR(ArchetypeMemberRef, Expr)
EXPR(GenericMemberRef, Expr)
UNCHECKED_EXPR(UnresolvedSpecialize, Expr)
UNCHECKED_EXPR(UnresolvedMember, Expr)
UNCHECKED_EXPR(UnresolvedDot, Expr)
UNCHECKED_EXPR(Sequence, Expr)
EXPR(Paren, Expr)
EXPR(Tuple, Expr)
ABSTRACT_EXPR(Collection, Expr)
EXPR(Array, CollectionExpr)
EXPR(Dictionary, CollectionExpr)
EXPR_RANGE(Collection, Array, Dictionary)
EXPR(Subscript, Expr)
UNCHECKED_EXPR(OverloadedSubscript, Expr)
EXPR(ExistentialSubscript, Expr)
EXPR(ArchetypeSubscript, Expr)
EXPR(GenericSubscript, Expr)
EXPR(TupleElement, Expr)
ABSTRACT_EXPR(Capturing, Expr)
EXPR(Func, CapturingExpr)
EXPR(PipeClosure, CapturingExpr)
ABSTRACT_EXPR(Closure, CapturingExpr)
EXPR(ExplicitClosure, ClosureExpr)
EXPR(ImplicitClosure, ClosureExpr)
EXPR_RANGE(Capturing, Func, ImplicitClosure)
EXPR(Module, Expr)
EXPR(AddressOf, Expr)
EXPR(NewArray, Expr)
EXPR(Metatype, Expr)
EXPR(RebindThisInConstructor, Expr)
UNCHECKED_EXPR(OpaqueValue, Expr)
ABSTRACT_EXPR(Apply, Expr)
EXPR(Call, ApplyExpr)
EXPR(PrefixUnary, ApplyExpr)
EXPR(PostfixUnary, ApplyExpr)
EXPR(Binary, ApplyExpr)
ABSTRACT_EXPR(ThisApply, ApplyExpr)
EXPR(DotSyntaxCall, ThisApplyExpr)
EXPR(ConstructorRefCall, ThisApplyExpr)
EXPR_RANGE(ThisApply, DotSyntaxCall, ConstructorRefCall)
EXPR_RANGE(Apply, Call, ConstructorRefCall)
ABSTRACT_EXPR(ImplicitConversion, Expr)
EXPR(Load, ImplicitConversionExpr)
EXPR(Materialize, ImplicitConversionExpr)
EXPR(Requalify, ImplicitConversionExpr)
EXPR(TupleShuffle, ImplicitConversionExpr)
EXPR(FunctionConversion, ImplicitConversionExpr)
EXPR(MetatypeConversion, ImplicitConversionExpr)
EXPR(Erasure, ImplicitConversionExpr)
EXPR(Specialize, ImplicitConversionExpr)
EXPR(DerivedToBase, ImplicitConversionExpr)
EXPR(ArchetypeToSuper, ImplicitConversionExpr)
EXPR(ScalarToTuple, ImplicitConversionExpr)
EXPR(BridgeToBlock, ImplicitConversionExpr)
EXPR_RANGE(ImplicitConversion, Load, BridgeToBlock)
ABSTRACT_EXPR(ExplicitCast, Expr)
EXPR(Coerce, ExplicitCastExpr)
EXPR(UncheckedDowncast, ExplicitCastExpr)
EXPR(UncheckedSuperToArchetype, ExplicitCastExpr)
EXPR_RANGE(ExplicitCast, Coerce, UncheckedSuperToArchetype)
EXPR(If, Expr)
EXPR(IsSubtype, Expr)
EXPR(ZeroValue, Expr)
EXPR(DefaultValue, Expr)
#undef EXPR_RANGE
#undef UNCHECKED_EXPR
#undef ABSTRACT_EXPR
#undef EXPR