Files
swift-mirror/docs/LangRef.html
Chris Lattner 41a924e723 synch up the grammar in the parser and langref, and make the
expression section of langref make more sense.



Swift SVN r571
2011-08-19 23:10:13 +00:00

1739 lines
68 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Swift Language Reference Manual</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="author" content="Chris Lattner">
<meta name="description"
content="Swift Language Reference Manual.">
<link rel="stylesheet" href="swift.css" type="text/css">
<script type="text/javascript" src="toc.js"></script>
</head>
<body>
<h1>Swift Language Reference</h1>
<p>
<!-- The Table of Contents is automatically inserted in this <div>.
Do not delete this <div>. -->
<div id="nav"></div>
</p>
<!-- ********************************************************************* -->
<h2>Introduction</h2>
<!-- ********************************************************************* -->
<div class="commentary">
In addition to the main spec, there are lots of open ended questions,
justification, and ideas of what best practices should be. That random
discussion is placed in boxes to the right side of the main text (like this
one) to clarify what is normative and what is discussion.
</div>
<p>This is the language reference manual for the Swift language, which is
highly volatile and constantly under development. It is my (Chris') intention
to keep this up to date as the prototype evolves.</p>
<p>The grammar and structure of the language is defined in BNF form in yellow
boxes. Examples are shown in gray boxes, and assume that the standard library
is in use (unless otherwise specified).</p>
<!-- ===================================================================== -->
<h3>Basic Goals</h3>
<!-- ===================================================================== -->
<div class="commentary">
A non-goal of the Swift project in general is to become some amazing
research project. We really want to focus on delivering a real product,
and having the design and spec co-evolve.
</div>
<ol>
<li>Support building great frameworks and applications, with a specific focus
on permiting rich and powerful APIs.</li>
<li>Get the defaults right: this reduces the barrier to entry and increases
the odds that the right thing happens.</li>
<li>Through our support for building great APIs, we aim to provide an
expressive and productive language that is fun to program in.</li>
<li>Support low-level system programming. We should want to write compilers,
operating system kernels, and media codecs in Swift. This means that being
able to obtain high performance is really quite important.</li>
<li>Provide really great tools.</li>
<li>Where possible, steal great ideas instead of innovating new things that
will work out in unpredictable ways. It turns out that there are a lot
of good ideas already out there.</li>
<li>Lots of other stuff too.</li>
</ol>
<!-- ===================================================================== -->
<h3>Basic Approach</h3>
<!-- ===================================================================== -->
<p>The basic approach in designing and implementing the Swift prototype was to
start at the very bottom of the stack (simple expressions and the trivial
bits of the type system) and incrementally build things up one brick at a
time. There is a big focus on making things as simple as possible and
having a clean internal core. Where it makes sense some sugar (e.g. "func"
and "struct") is added on top to make the core more expressive for common
situations.</p>
<p>One major aspect that dovetails with expressivity, learnability, and focus
on API development is that much of the language is implemented in a
standard library (inspired by the Haskell Standard Prelude). By pushing
much of the boring parts of the language out of the compiler into the
library, we end up with a smaller core language and we force the language
that is left to be highly expressive and extensible, which we hope will
allow for great libraries to be built on top of it.
</p>
<p>More later.</p>
<!-- ********************************************************************* -->
<h2>Phases of Translation</h2>
<!-- ********************************************************************* -->
<div class="commentary">
The careful factoring of the grammar allows forward referencing of
types and values and allows parsing without resolution of import
declarations.
</div>
<p>Swift has a strict separation between its phases of translation, and the
grammar is carefully factored so that there is never ambiguity about whether
an identifier refers to a type of a value. The phases of translation are:</p>
<ul>
<li><a href="#lexical">Lexing</a>: A translation unit is broken into tokens
according to a (nearly, /**/ comments can be nested) regular grammar.</li>
<li>Parsing and AST Building: The tokens are parsed according to the grammar
set out below. The grammar is context free and does not require any "type
feedback" from the lexer or later stages. During parsing, name binding for
references to local variables and other declarations that are not at
translation unit (and eventually namespace) scope are bound.
</li>
<li><a href="#namebind">Name Binding</a>: At this phase, references to
non-local types and values are bound, and <a href="#decl-import">import
directives</a> are both validated and searched. Name binding can cause
recursive compilation of modules that are referenced but not yet built.
</li>
<li><a href="#typecheck">Type Checking</a>: During this phase all types are
resolved within value definitions, <a href="#expr-call">function
application</a> and <a href="#expr-infix">binary expressions</a> are found
and formed, and overloaded functions are resolved.</li>
<li>Code Generation</li>
<li>Linking</li>
</ul>
<p>
TODO: "import swift" implicitly added as the last import in translation unit.
</p>
<!-- ********************************************************************* -->
<h2 id="lexical">Lexical Structure</h2>
<!-- ********************************************************************* -->
<div class="commentary">
Not all characters are "taken" in the language, this is because it is still
growing. As there becomes a reason to assign things into the identifier or
punctuation bucket, we will do so as swift evolves.
</div>
<p>The lexical structure of a Swift file is very simple: the files are
tokenized according to the following productions and categories. As is
usual with most languages, tokenization uses the maximal munch rule and
whitespace separates tokens. This means that "a b" and "ab" lex into
different token streams and are therefore different in the grammar.</p>
<!-- ===================================================================== -->
<h3>Whitespace and Comments</h3>
<!-- ===================================================================== -->
<pre class="grammar">
whitespace ::= ' '
whitespace ::= '\n'
whitespace ::= '\r'
whitespace ::= '\t'
whitespace ::= '\0'
comment ::= //.*[\n\r]
comment ::= /* .... */
</pre>
<p>Space, newline, tab, and the nul byte are all considered whitespace and are
discarded, with one exception: a '(' which does not follow a
non-whitespace character is different kind of token (called
<em>spaced</em>) from one which does not (called <em>unspaced</em>).
A '(' at the beginning of a file is spaced.</p>
<p>Comments may follow the BCPL style, starting with a "//" and running to the
end of the line, or may be nested /**/ style comments. Comments are
ignored and treated as whitespace.</p>
<!-- ===================================================================== -->
<h3>Reserved Punctuation Tokens</h3>
<!-- ===================================================================== -->
<div class="commentary">
The difference between reserved punctuation and identifiers is that you
can't "overload an operator" with one of these names.<br><br>
Note that -&gt; is used for function types "() -&gt; int", not pointer
dereferencing.
</div>
<pre class="grammar">
lparen-spaced ::= '(' // preceded by space
lparen-unspaced ::= '(' // not preceded by space
lparen-any ::= lparen-spaced
lparen-any ::= lparen-unspaced
punctuation ::= lparen-spaced
punctuation ::= lparen-unspaced
punctuation ::= ')'
punctuation ::= '{'
punctuation ::= '}'
punctuation ::= '['
punctuation ::= ']'
punctuation ::= '.'
punctuation ::= ','
punctuation ::= ';'
punctuation ::= ':'
punctuation ::= '::'
punctuation ::= '='
punctuation ::= '-&gt;'
</pre>
<p>These are all reserved punctuation that are lexed into tokens. Most other
punctuation is matched as <a href="identifier">identifiers</a>.
</p>
<!-- ===================================================================== -->
<h3>Reserved Keywords</h3>
<!-- ===================================================================== -->
<div class="commentary">
The number of keywords is reduced by pushing most functionality
into the library. This allows us to add new stuff to the library in
the future without worrying about conflicting with the user's namespace.
<br><br>
Idea: Should _foo be "private" and "foo" be public, how about "Foo" vs
"foo"? In the code you immediately know whether something is exported, and
don't need to sprinkle attributes everywhere, OTOH, it makes it harder to
remember (like not having a naming convention).<br><br>
Enumerating the integer types is expedient, but silly and unneeded. There
isn't a good reason to expose an i13 LLVM IR type, but i128 would be
reasonable.
</div>
<pre class="grammar">
keyword ::= '__builtin_int1_type'
keyword ::= '__builtin_int8_type'
keyword ::= '__builtin_int16_type'
keyword ::= '__builtin_int32_type'
keyword ::= '__builtin_int64_type'
keyword ::= 'import'
keyword ::= 'oneof'
keyword ::= 'struct'
keyword ::= 'var'
keyword ::= 'func'
keyword ::= 'typealias'
keyword ::= 'if'
keyword ::= 'else'
</pre>
<p>These are the builtin keywords. Swift intentionally tries to reduce the
number of keywords where possible.</p>
<p>FIXME: __ should be considered the compiler/languages reserved namespace,
any use of an unknown identifier here should be an error.</p>
<!-- ===================================================================== -->
<h3 id="numeric_constant">Numeric Constant</h3>
<!-- ===================================================================== -->
<pre class="grammar">
numeric_constant ::= [0-9]+
</pre>
<p>Numeric constant tokens represent simple integer values.</p>
<p>TODO: Obviously need a floating point constant when we have a fp type.</p>
<!-- ===================================================================== -->
<h3 id="identifier">Identifier Tokens</h3>
<!-- ===================================================================== -->
<pre class="grammar">
identifier ::= [a-zA-Z_][a-zA-Z_$0-9]*
operator ::= [/=-+*%&lt;&gt;!&amp;|^]+
any-identifier ::= identifier | operator
</pre>
<!-- ===================================================================== -->
<h3 id="dollarident">Implementation Identifier Token</h3>
<!-- ===================================================================== -->
<pre class="grammar">
dollarident ::= $[0-9a-zA-Z_$]*
</pre>
<p>Tokens that start with a $ are separate class of identifier, which are
fixed purpose names that are defined by the implementation.
</p>
<!-- ********************************************************************* -->
<h2 id="decl">Declarations</h2>
<!-- ********************************************************************* -->
<pre class="grammar">
decl ::= <a href="#decl-import">decl-import</a>
decl ::= <a href="#decl-var">decl-var</a>
decl ::= <a href="#decl-func">decl-func</a>
decl ::= <a href="#decl-typealias">decl-typealias</a>
decl ::= <a href="#decl-oneof">decl-oneof</a>
decl ::= <a href="#decl-struct">decl-struct</a>
</pre>
<!-- ===================================================================== -->
<h3 id="decl-import">import Declarations</h3>
<!-- ===================================================================== -->
<pre class="grammar">
decl-import ::= 'import' attribute-list? any-identifier ('.' any-identifier)*
</pre>
<p>'import' declarations allow named values and types to be accessed with
local names, even when they are defined in other modules and namespaces. See
the section on <a href="#namebind">name binding</a> for more
information on how these work. import declarations are only allowed at
translation unit scope.</p>
<p>'import' directives only impact a single translation unit: imports in one
swift file do not affect name lookup in another file. import directives can
only occur at the top level of a file, not within a function or namespace.</p>
<p>If a single identifier is specified for the import declaration, then the
entire module is imported in its entirety into the current scope. If a
scope (such as a namespace) is named, then all entities in the namespace are
imported. If a specific type or variable is named (e.g. "import swift.int")
then only the one type and/or value is imported.</p>
<pre class="example">
<i>// Import all of the top level symbols and types in a package.</i>
import swift
<i>// Import all of the symbols within a namespace.</i>
import swift.io
<i>// Import a single variable, function, type, etc.</i>
import swift.io.bufferedstream
</pre>
<!-- ===================================================================== -->
<h3 id="decl-var">var Declarations</h3>
<!-- ===================================================================== -->
<div class="commentary">
Eventually add support for "var x,y : int", to allow declarating multiple
values of the same type?
</div>
<pre id="value-specifier" class="grammar">
decl-var ::= 'var' <a href="#attribute-list">attribute-list</a>? var-name <a href="#value-specifier">value-specifier</a>
value-specifier ::= ':' <a href="#type">type</a>
value-specifier ::= ':' <a href="#type">type</a> '=' <a href="#expr">expr</a>
value-specifier ::= '=' <a href="#expr">expr</a>
</pre>
<!--
Note that the initializer can't be expr-singular. If it were we would fail
to handle dependent cases like "var x : somestruct = :foo(4)
-->
<p>'var' declarations form the backbone of value declarations in Swift and
are the core semantic model for these values. The <a
href="#decl-func">func declaration</a> is just syntactic sugar for a var
declaration with an <a href="#expr-func">expr-func</a> body.</p>
<p>Syntactically, var declarations come in three forms from the
value-specifier production. In the first form,
a type is specified and the value is default initialized. In the second
form the type is elided but a value is specified, the declaration gets the
specified value and has the same type as its initializer. In the third
form, the value's type is as specified and the initializer is <a
href="#typecheck_conversions">converted to</a> that type if required.</p>
<p>Var declarations can optionally have a list of <a
href="#attribute-list">attributes</a> applied to them.</p>
<pre class="grammar">
var-name ::= <a href="#identifier">any-identifier</a>
var-name ::= lparen-any ')'
var-name ::= lparen-any var-name (',' var-name)* ')'
</pre>
<p>The name given to the var can have structure that allows fields of the
returned value to be directly named and accessed in later code. The
structure of the name is required to match up with the type being matched.
An single identifier is always valid to capture the entire value
(potentially as an aggregate). Parenthesized values match up against tuple
types and against single element oneof types.
</p>
<p>Here are some examples of var declarations:</p>
<pre class="example">
<i>// Simple examples.</i>
var a = 4
var b : int
var c : int = 42
<i>// Declaring a function like value with 'var', using an attribute.</i>
<i>// The name here is "==", the type is a function that takes a tuple</i>
<i>// and returns an int.</i>
var [infix=120] == : (lhs : int, rhs : int) -&gt; int
<i>// This decodes the tuple return value into independently named parts</i>
<i>// and both 'val' and 'err' are in scope after this line.</i>
var (val, err) = foo()
<i>// This binds elements of a struct into local variables.</i>
struct point { x : int, y : int }
var (a, b) = foo() <i>// when foo returns a 'point'.</i>
</pre>
<!-- ===================================================================== -->
<h3 id="decl-func">func Declarations</h3>
<!-- ===================================================================== -->
<pre class="grammar">
decl-func ::= 'func' <a href="#attribute-list">attribute-list</a>? <a href="#identifier">any-identifier</a> <a href="#type">type</a> <a href="#stmt-brace">stmt-brace</a>?
decl-func ::= 'func' <a href="#attribute-list">attribute-list</a>? <a href="#type-identifier">type-identifier</a> '::' <a href="#identifier">any-identifier</a> <a href="#type">type</a> <a href="#stmt-brace">stmt-brace</a>?
</pre>
<div class="commentary">
The second form is shorthand for defining a function that can be used with
dot syntax on the receiver type.
</div>
<p>A 'func' declaration is syntactic sugar for a 'var' to be used in the
(extremely) common case of a declaring a function. The argument list and
optional return value are specified by the type production of the function,
and the body is either not specified or is a brace expression. Like other
declarations, functions are can have attributes.</p>
<p>If the type is not syntactically a function type (i.e., has no -&gt; in it
at top-level), then the return value is implicitly inferred to be "()". All
of the argument and return value names are injected into the
<a href="#namebind_scope">scope</a> of the function body.</p>
<p>When the second form is used, the underlying declaration is defined to take
an implicit 'this' parameter of the specified type-identifier, and injects
members of the type into the scope of the body so they can be found with
normal name lookup. This allows convenient syntax for declaring a function on
an existing type.</p>
<p>TODO: Func should be an immutable name binding, it should implicitly add
an attribute immutable when it exists.</p>
<p>TODO: Incoming arguments should be readonly, result should be implicitly
writeonly when we have these attributes.</p>
<p>TODO: Should generalize the second form to take something like a
nested-name specifier when we have namespaces.</p>
<p>Here are some examples of func definitions:</p>
<pre class="example">
<i>// Implicitly returns (), aka <a href="#stdlib-void">void</a></i>
func a() {}
<i>// Same as 'a'</i>
func a1() -&gt; void {}
var a2 = func ()-&gt;() {}
var a3 = func () {}
var a4 = func {}
<i>// Really simple function</i>
func c(arg : int) -&gt; int { return arg+4 }
<i>// Simple operator.</i>
func [infix=120] + (lhs: int, rhs: int) -&gt; int
<i>// Function with multiple return values:</i>
func d(a : int) -&gt; (b : int) -&gt; (res1 : int, res2 : int)
<i>// Same as: func e(this : sometype) -&gt; (a : int) -&gt; int</i>
func sometype::e(a : int) -&gt; int
<i>// Same as: func f(this : sometype) -&gt; (a : int) -&gt; ()</i>
func sometype::f(a : int)
<i>// A more realistic example on a trivial type.</i>
struct bankaccount { amount : int }
func bankaccount::deposit(arg : int) {
amount = amount + arg
}
</pre>
<!-- ===================================================================== -->
<h3 id="decl-typealias">typealias Declarations</h3>
<!-- ===================================================================== -->
<pre class="grammar">
decl-typealias ::= 'typealias' <a href="#identifier">identifier</a> ':' <a href="#type">type</a>
</pre>
<p>'typealias' makes a named alias of a type, like a typedef in C. From that
point on, the alias may be used in all situations the specified name is. It
is named "typealias" because it really is an alias, not a "new" type.</p>
<p>Here are some examples of type aliases:</p>
<pre class="example">
<i>// location is an alias for a tuple of ints.</i>
typealias location : (x : int, y : int)
<i>// pair_fn is a function that takes two ints and returns a tuple.</i>
typealias pair_fn : int -&gt; int -&gt; (first : int, second : int)
</pre>
<p>'typealias' is the core semantic model for all named types. For example, a
<a href="#decl-oneof">oneof decl</a> is just syntactic sugar for a <a
href="#type-oneof">oneof type</a> and a 'typealias'.</p>
<!-- ===================================================================== -->
<h3 id="decl-oneof">oneof Declarations</h3>
<!-- ===================================================================== -->
<div class="commentary">
In actual practice, we expect oneof to be commonly used for "enums" and
"struct" below to be used for data declarations. The use of "oneof" for
discriminated unions will be much less common (but is still very important)
than its use for "enums".
</div>
<pre class="grammar">
decl-oneof ::= 'oneof' <a href="#attribute-list">attribute-list</a>? <a href="#identifier">identifier</a> <a href="#type-oneof">oneof-body</a>
</pre>
<p>A oneof declaration is a convenient way to declare a type and name it at
the same time, as it is simple syntactic sugar for a <a
href="#type-oneof">oneof</a> type and a <a
href="#decl-typealias">typealias</a> declaration. Please see <a
href="#type-oneof">oneof types</a> for more information about their
capabilities. Here are two exactly equivalent declarations for
intuition:</p>
<pre class="example">
<i>// Declare discriminated union with typealias + oneof type.</i>
typealias SomeInts : oneof {
None,
One : int,
Two : (:int, :int)
}
<i>// Declare discriminated union with oneof decl (preferred).</i>
oneof SomeInts {
None,
One : int,
Two : (:int, :int)
}
</pre>
<p>Here are some more examples of oneof declarations:</p>
<pre class="example">
<i>// Declares three "enums".</i>
oneof DataSearchFlags {
None, Backward, Anchored
}
func f1(searchpolicy : DataSearchFlags) <i>// DataSearchFlags is a valid type name</i>
func test1() {
f1(DataSearchFlags::None) <i>// Use of constructor with qualified identifier</i>
f1(:None) <i>// Use of constructor with context sensitive type inference</i>
<i>// "None" has no type argument, so the constructor's type is "DataSearchFlags".</i>
var a : DataSearchFlags = :None
}
oneof SomeInts {
None, <i>// Doesn't conflict with previous "None".</i>
One : int, <i>// Argument type is simple int.</i>
Two : (:int, :int) <i>// Argument type is simple tuple.</i>
}
func f2(a : SomeInts)
func test2() {
<i>Constructors for oneof element can be used in the obvious way.</i>
f2(:None)
f2(:One 4)
f2(:Two(1, 2))
<i>Constructor for None has type "SomeInts".</i>
var a : SomeInts = SomeInts::None
<i>Constructor for One has type "int -&gt; SomeInts".</i>
var b : int -&gt; SomeInts = SomeInts::One
<i>Constructor for Two has type "(:int,:int) -&gt; SomeInts".</i>
var c : (:int,:int) -&gt; SomeInts = SomeInts::Two
}
</pre>
<!-- ===================================================================== -->
<h3 id="decl-struct">struct Declarations</h3>
<!-- ===================================================================== -->
<pre class="grammar">
decl-struct ::= 'struct' <a href="#attribute-list">attribute-list</a>? <a href="#identifier">identifier</a> { <a href="#type-tuple">type-tuple-body? </a> }
</pre>
<p>A struct declaration is syntactic sugar for a oneof declaration of a single
element, and a 'typealias'. It requires that a tuple type be specified (whose
body is specified in curly braces), and declares a oneof with a single
constructor value of the same name as the struct.</p>
<p>Note that unlike <a href="#decl-oneof">oneof</a>, 'struct' <em>does</em>
inject its single constructor value into the containing scope. This means that
you don't need to use qualified lookup to get access to the constructor for a
struct.</p>
<p>These two declarations are equivalent (other than their names):</p>
<pre class="example">
struct S1 { a : int, b : int }
oneof S2 {
S2 : (a : int, b : int)
}
var S2 = S2::S2 <i>// Constructor injected into global scope.</i>
</pre>
<p>Here are some examples of structs:</p>
<pre class="example">
struct Point { x : int, y : int }
struct Size { width : int, height : int }
struct Rect { origin : Point, size : Size }
func test4() {
var a : Point
var b = Point::Point(1, 2) // Silly but fine.
var c = Point(.y = 1, .x = 2) // Using injected name.
var x1 = Rect(a, Size(42, 123))
var x2 = Rect(.size = Size(.width = 42, .height=123), .origin = a)
var x1_area = x1.width*x1.height
}
</pre>
<!-- ===================================================================== -->
<h3 id="attribute-list">Attribute Lists</h3>
<!-- ===================================================================== -->
<pre class="grammar">
attribute-list ::= '[' ']'
attribute-list ::= '[' attribute (',' attribute)* ']'
attribute ::= attribute-infix
</pre>
<p>An attribute is a (possibly empty) comma separated list of attributes.</p>
<h4 id="attribute-infix">Infix Attribute</h4>
<pre class="grammar">
attribute-infix ::= 'infix' '=' <a href="#numeric_constant">numeric_constant</a>
</pre>
<p>The only attribute supported so far is the 'infix' attribute.</p>
<p>The 'infix' attribute may only be applied to the declaration of a
function of binary operator type whose name is an
<a href="#identifier"><tt>operator</tt></a>.
FIXME: Implement these restrictions.</p>
<p>TODO: Add support for a bunch more attributes.</p>
<!-- ********************************************************************* -->
<h2 id="type">Types</h2>
<!-- ********************************************************************* -->
<pre class="grammar">
type ::= type-simple
type ::= <a href="#type-function">type-function</a>
type ::= <a href="#type-array">type-array</a>
type-simple ::= <a href="#type-builtin">type-builtin</a>
type-simple ::= <a href="#type-identifier">type-identifier</a>
type-simple ::= <a href="#type-tuple">type-tuple</a>
type-simple ::= <a href="#type-oneof">oneof Types</a>
</pre>
<p>Swift has a small collection of core datatypes that are built into the
compiler. Most datatypes that the user is exposed are defined by the
<a href="#stdlib">standard library</a> or declared as a user defined
types.</p>
<p>
FIXME: Why is array a type instead of type-simple?
</p>
<!-- ===================================================================== -->
<h3 id="type-builtin">Builtin Primitive Types</h3>
<!-- ===================================================================== -->
<pre class="grammar">
type-builtin ::= '__builtin_int1_type'
type-builtin ::= '__builtin_int8_type'
type-builtin ::= '__builtin_int16_type'
type-builtin ::= '__builtin_int32_type'
type-builtin ::= '__builtin_int64_type'
</pre>
<p>'__builtin_int*_type's are the name of the integer types of the
corresponding size. These types specify a storage, but they have no semantics
assigned to them (e.g. signed vs unsigned arithmetic) because there are no
operations on them built into the language.</p>
<p>TODO: Support builtin float and double.</p>
<!-- ===================================================================== -->
<h3 id="type-identifier">Named Types</h3>
<!-- ===================================================================== -->
<pre class="grammar">
type-identifier ::= <a href="#identifier">identifier</a>
</pre>
<p>Named types may be used simply by using their name. Named types are
introduced by <a href="#decl-typealias">typealias</a> declarations or
through syntactic sugar that expands to one.</p>
<pre class="example">
typealias location : (x : int, y : int)
var x : location <i>// use of a named type.</i>
</pre>
<!-- ===================================================================== -->
<h3 id="type-tuple">Tuple Types</h3>
<!-- ===================================================================== -->
<pre class="grammar">
type-tuple ::= lparen-any type-tuple-body? ')'
type-tuple-body ::= identifier? <a href="#value-specifier">value-specifier</a> (',' identifier? <a href="#value-specifier">value-specifier</a>)*
</pre>
<p>Syntactically, tuple types are simply a (possibly empty) list of
elements.</p>
<p>Tuples are the primary form of data aggregation in Swift, and are used as
the building block of <a href="#type-function">function</a> argument lists,
multiple return values, <a href="#decl-struct">struct</a> and
<a href="#decl-oneof">oneof</a> bodies, etc. Because tuples are widely
accessible and available everywhere in the language, aggregate data access and
transformation is uniform and powerful.</p>
<p>Each element of a tuple contains an optional name followed by a type and/or
and default value expression, whose type conversion rules work like those in a
var declaration. The name affects swizzling of elements in the tuple when <a
href="#typecheck_conversions">tuple conversions</a> are performed.</p>
<pre class="example">
<i>// Variable definitions.</i>
var a : ()
var b : (:int, :int)
var c : (x : (), y : int)
var d : (a : int, b = 4) <i>// Value is initialized to (0,4)</i>
var e : (a : int, b = 4) = (1) <i>// Value is initialized to (1,4)</i>
<i>// Tuple type inferred from an initializers:</i>
var m = () <i>// Type = ()</i>
var n = (.x = 1, .y = 2) <i>// Type = (x : int, y : int)</i>
var o = (1, 2, 3) <i>// Type = (:int, :int, :int)</i>
<i>// Function argument and result is a tuple type.</i>
func foo(x : int, y : int) -&gt; (val : int, err : int)
<i>// oneof and struct declarations with tuple values.</i>
struct S { a : int, b : int }
oneof Vertex {
Point2 : (x : int, y : int),
Point3 : (x : int, y : int, z : int),
Point4 : (w : int, x : int, y : int, z : int)
}
</pre>
<!-- ===================================================================== -->
<h3 id="type-function">Function Types</h3>
<!-- ===================================================================== -->
<pre class="grammar">
type-function ::= <a href="#type">type-simple</a> '-&gt;' <a href="#type">type</a>
</pre>
<p>Function types have a single input and single result type, separated by
an arrow. Because each of the types is allowed to be a tuple, we trivially
support multiple arguments and multiple results. "Function" types are
more properly known as a "closure" type, because they can embody any
context captured when the function value was formed.</p>
<p>Because of the grammar structure, a nested function type like
"a -&gt; b -&gt; c" is parsed as "a -&gt; (b -&gt; c)". This means that if
you declare this that you can pass it one argument to get a function that
"takes b and returns c" or you can pass two arguments to "get a c". For
example:
</p>
<pre class="example">
<i>// A simple function that takes a tuple and returns int:</i>
var a : (a : int, b : int) -&gt; int
<i>// A simple function that returns multiple values:</i>
var a : (a : int, b : int) -&gt; (val: int, err: int)
<i>// Declare a function that returns a function:</i>
var x : int -&gt; int -&gt; int
<i>// y has type int -&gt; int</i>
var y = x 1
<i>// z1 and z2 both has type int, and both have the same value (assuming
// the function had no side effects).</i>
var z1 = x 1 2
var z2 = y 2
</pre>
<!-- ===================================================================== -->
<h3 id="type-array">Array Types</h3>
<!-- ===================================================================== -->
<div class="commentary">
Array types are currently a hack, and only partially implemented in the
compiler. Arrays don't make sense to fully define until we have generics,
because array syntax should just be sugar for a standard library type.
"int[4]" should just be sugar for array&lt;int, 4&gt; or whatever.
</div>
<pre class="grammar">
type-array ::= <a href="#type">type</a> '[' ']'
type-array ::= <a href="#type">type</a> '[' <a href="#expr">expr</a> ']'
</pre>
<p>Array types include a base type and an optional size. Array types indicate
a linear sequence of elements stored consequtively memory. Array elements may
be efficiently indexed in constant time. All array indexes are bounds checked
and out of bound accesses are diagnosed with either a compile time or
runtime failure (TODO: runtime failure mode not specified).</p>
<p>While they look syntactically very similar, an array type with a size has
very different semantics than an array without. In the former case, the type
indicates a declaration of actual storage space. In the later case, the type
indicates a <em>reference</em> to storage space allocated elsewhere of
runtime-specified size.
</p>
<p>FIXME: We should separate out "Arrays" from "Slices". Arrays should always
require a size and is by-value, a slice is a by-ref and never have a
(statically specified) size.</p>
<p>For an array with a size, the size must be more than zero (no
indices would be valid). For now, the array size must be a literal integer.
TODO: Define a notion like C's integer-constant-expression for how constant
folding works.</p>
<p>FIXME: int[][] not valid because the element type isn't sized. We need
some constraint to reject this, or do we?</p>
<p>Some example array types:</p>
<pre class="example">
<i>// A simple array declaration:</i>
var a : int[4]
<i>// A reference to another array:</i>
var b : int[] = a
<i>// Declare a two dimensional array:</i>
var c : int[4][4]
<i>// Declare a reference to another array, two dimensional:</i>
var d : int[4][]
<i>// Declare an array of function pointers:</i>
var array_fn_ptrs : (: int -&gt; int)[42]
var g = array_fn_ptrs[12](4)
<i>// Without parens, this is a function that returns a fixed size array:</i>
var fn_returning_array : int -&gt; int[42]
var h : int[42] = fn_returning_array(4)
<i>// You can even have arrays of tuples and other things, these work right
// through composition:</i>
var array_of_tuples : (a : int, b : int)[42]
var tuple_of_arrays : (a : int[42], b : int[42])
array_of_tuples[12].a = array_of_tuples[13].b
tuple_of_arrays.a[12] = array_of_tuples.b[13]
</pre>
<!-- ===================================================================== -->
<h3 id="type-oneof">oneof Types</h3>
<!-- ===================================================================== -->
<div class="commentary">
In actual practice, we expect explicit oneof types to be rare, used mainly
as a replacement for "bool" arguments. It will be much more common to use
oneof decls for "enums" and "struct" decls for data declarations. The use
of "oneof" for discriminated unions will be much less common (but is still
very important) than its use for "enums". In any case, the decl form of
this is important syntactic sugar for the type version of oneof.<br><br>
'oneof' types are known as <a
href="http://en.wikipedia.org/wiki/Algebraic_data_type">algebraic data
types</a> by the broader programming language community. The name 'oneof'
comes from CLU.
</div>
<pre class="grammar">
type-oneof ::= 'oneof' <a href="#attribute-list">attribute-list</a>? oneof-body
oneof-body ::= '{' oneof-element (',' oneof-element)* '}'
oneof-element ::= <a href="#identifier">identifier</a>
oneof-element ::= <a href="#identifier">identifier</a> ':' <a href="#type">type</a>
</pre>
<p>A oneof type consists of a comma-separated list of elements,
which are each either an identifier or an identifier with a type. The runtime
representation of a value of oneof type only has one of the specified oneof
elements at a time: a oneof value is a simple discriminated union.</p>
<p>A oneof type declares two things: 1) the type itself as an anonymous type,
and 2) each of the oneof elements declares a constructor value which creates a
value of the oneof type with the specified element kind. The constructor
values are defined in a nested scope within the oneof descriptor type, so they
must be accessed with either a <a href="#expr-identifier">qualified
identifier</a> (if the type itself is named) or through <a
href="#expr-delayed-identifier">delayed identifier resolution</a>
with <a href="#typecheck_context">context sensitive type inference</a>.
</p>
<p>If the oneof element has no type specified with it, then the type of the
constructor is the oneof type. If a oneof element has a
type "T" associated with it, then the type of the constructor is a function
that takes "T" and returns the oneof type.</p>
<p>A default initialized value of oneof type is initialized to the first
element type in the list, with the default value for its element type.</p>
<p>Here are some examples of oneof types:</p>
<pre class="example">
<i>// Declares three "enums" using a oneof type. Better and easier with a
// <a href="#decl-oneof">oneof declaration</a> though.</i>
typealias DataSearchFlags : oneof {
None, Backward, Anchored
}
func f1(searchpolicy : DataSearchFlags)
func test1() {
f1(DataSearchFlags::None) <i>// Use of constructor with qualified identifier</i>
f1(:None) <i>// Use of constructor with context sensitive type inference</i>
<i>// "None" has no type argument, so the constructor's type is "DataSearchFlags".</i>
var a : DataSearchFlags = :None
}
<i>// A more typical use case, anonymous argument for flags, death to
// content-free bools in function arguments.</i>
func search(val : int, direction : oneof { Up, Down })
func test2() {
search(42, :Up)
search(17, :Down)
}
</pre>
<p>TODO: Should attributes be allowed on oneof elements?
TODO: Eventually, with generics we'll have equality and inequality operators.
Oneof decls should implicitly define these for their types.
TODO: Need pattern matching and element extraction.
</p>
<!-- ********************************************************************* -->
<h2 id="expr">Expressions</h2>
<!-- ********************************************************************* -->
<div class="commentary">
Support for user-defined operators causes some amount of parsing
to be delayed until after name resolution has occurred. Other
restrictions and disambiguations in the grammar permit the parser
to decide all other aspects of parsing, such as where statements
must be divided.<br><br>
Semicolons in C are generally just clutter. Swift generally tries
to define away their use.<br><br>
Brace expressions don't fit naturally into the grammar anymore. It would
be nice if they were not allowed in general as an expression anymore, but
that would detract from their use as closures etc.
</div>
<pre class="grammar">
expr-primary ::= <a href="#expr-literal">expr-literal</a>
expr-primary ::= <a href="#expr-identifier">expr-identifier</a>
expr-primary ::= <a href="#expr-paren">expr-paren</a>
expr-primary ::= <a href="#expr-delayed-identifier">expr-delayed-identifier</a>
expr-primary ::= <a href="#expr-func">expr-func</a>
expr-postfix ::= expr-primary
expr-postfix ::= <a href="#expr-dot">expr-dot</a>
expr-postfix ::= <a href="#expr-subscript">expr-subscript</a>
expr-postfix ::= <a href="#expr-call">expr-call</a>
expr ::= <a href="#expr-unary">expr-unary</a> <a href="#expr-binary">expr-binary</a>*
</pre>
<p>At the top level of the expression grammar, expressions are a
sequence of unary expressions joined by operators. When parsing
an expr, any operator immediately following an expr-unary
continues the expression, and the program is ill-formed if it is
not then followed by another expr-unary. This resolves an
ambiguity which could otherwise arise in statement contexts due to
semicolon elision.</p>
<pre class="example">
5 !- +~123 -+- ~+6
(foo)(())
bar(49+1)
baz()
</pre>
<!-- ===================================================================== -->
<h3 id="expr-literal">Simple Literals</h3>
<!-- ===================================================================== -->
<div class="commentary">
Consider treating literal numbers like go's arbitrary precision integers
that are resolved to a type later. It would be really great for x+4.0 to
work if x is a float, not a double. Likewise when we have multiple
different width integers floating around. This is somewhat easy (just give
numbers dependent type) but we would needs some magic to make "var x = 4"
work, since we want it to get a default type, not be ambiguous.
</div>
<pre class="grammar">
expr-literal ::= <a href="#numeric_constant">numeric_constant</a>
</pre>
<p>The only literal currently supported are integer constants. These are
given 'integer_literal_type' type, which must be defined by the library.
If an integer literal is used and integer_literal_type is not defined, then
the code is malformed.</p>
<!-- ===================================================================== -->
<h3 id="expr-identifier">Identifiers</h3>
<!-- ===================================================================== -->
<pre class="grammar">
expr-identifier ::= <a href="#identifier">identifier</a>
</pre>
<p>A raw identifier refers to a value found via <a
href="#namebind_value_lookup_unqual">unqualified value lookup</a>, and has
the type of the declaration returned by name lookup and overload
resolution. Value declarations are installed with <a
href="#decl-var">var</a> and the syntactic sugar forms like <a
href="decl-func">func</a> declarations.</p>
<pre class="grammar">
expr-identifier ::= <a href="#dollarident">dollarident</a>
</pre>
<p>A use of an identifier whose name fits the "$[0-9]+" regular
expression is a reference to an anonymous closure argument that is formed when
the containing expression is <a href="#typecheck_anon">coerced into a closure
context</a>. All other dollar identifiers are invalid.</p>
<pre class="grammar">
expr-identifier ::= <a href="#type-identifier">type-identifier</a> '::' <a href="#identifier">any-identifier</a>
</pre>
<p>Qualified identifiers look up a constructor member of a <a
href="type-oneof">oneof</a> type (and eventually into namespaces). The
first identifier is looked up as a <a href="#type-identifier">type name</a>.
</p>
<!-- ===================================================================== -->
<h3 id="expr-paren">Parenthesized Expressions</h3>
<!-- ===================================================================== -->
<pre class="grammar">
expr-paren ::= lparen-any ')'
expr-paren ::= lparen-any expr-paren-element (',' expr-paren-element)* ')'
expr-paren-element ::= ('.' <a href="#identifier">identifier</a> '=')? <a href="#expr">expr</a>
</pre>
<p>Some enclosing productions restrict the <tt>lparen-any</tt> to a
<tt>lparen-unspaced</tt>.</p>
<p>Parentheses expressions contain an (optionally empty) list of optionally
named values. Parentheses in an expression context denote one of two
things: 1) grouping parentheses, or 2) a tuple literal.</p>
<p>Grouping parentheses occur when there is exactly one value in the list and
that value does not have a name. In this case, the type of the parenthesis
expression is the type of the single value.</p>
<p>All other cases are tuple literals. The type of the expression is a tuple
type whose elements and order match that of the initializer. If there are
any named elements, those elements become names for the tuple type. A
parenthesis expression with no value has a type of the empty tuple.
</p>
<p>Some examples:</p>
<pre class="example">
<i>// Simple grouping parenthesis.</i>
var a = (4) <i>// Type = int</i>
var b = (4+a) <i>// Type = int</i>
<i>// Tuple literals.</i>
var c = () <i>// Type = ()</i>
var d = (4, 5) <i>// Type = (:int,:int)</i>
var e = (c, d) <i>// Type = ((), (:int, :int))</i>
var f = (.x = 4, .y = 5) <i>// Type = (x : int, y : int)</i>
var g = (4, .y = 5, 6) <i>// Type = (:int, y : int, :int)</i>
<i>// Named arguments to functions.</i>
func foo(a : int, b : int)
foo(.b = 4, .a = 1)
</pre>
<!-- ===================================================================== -->
<h3 id="expr-delayed-identifier">Delayed Identifier Resolution</h3>
<!-- ===================================================================== -->
<div class="commentary">
The ":bar" syntax was picked because it is "half" of a fully qualified
"foo::bar" reference.
</div>
<pre class="grammar">
expr-delayed-identifier ::= ':' <a href="#identifier">identifier</a>
</pre>
<p>A delayed identifier expression refers to a constructor of a <a
href="type-oneof">oneof</a> type, without knowing which type it is referring
to. The expression is resolved to a constructor of a concrete type through
context sensitive type inference. Delayed identifier resolution is actually
more powerful than qualified identifier resolution, because it can find
constructors of anonymous types.</p>
<pre class="example">
<i>// A function with an argument that has an anonymous type.</i>
func search(val : int, direction : oneof { Up, Down })
func f() {
search(42, :Up)
search(17, :Down)
}
</pre>
<!-- ===================================================================== -->
<h3 id="expr-func">Func Expressions</h3>
<!-- ===================================================================== -->
<div class="commentary">
Func expressions will probably not be widely used directly, but they are
the core semantic model underlying 'func' declarations, and can be
convenient for declaring first-class function values that want named
arguments.
</div>
<pre class="grammar">
expr-func ::= 'func' <a href="#type">type</a>? <a href="#stmt-brace">stmt-brace</a>
</pre>
<p>A func expression is an anonymous (unnamed) function literal definition,
which can define named arguments (and whose names are in scope for its
body) and that can refer to values defined in parent scopes.</p>
<p>A func expression captures a reference to any values in parent scopes that
are used.</p>
<p>If a type is specified in the func expression, it specifies the signature
of the anonymous function. The first element of the type must be a tuple
type (thus it must start with '('). If the entire type is not lexically a
function type, it is made into one by declaring a function type that takes
the specified type and returns (). If no type is specified, the type of
the func is "<tt>()-&gt;()</tt>".</p>
<p>TODO: Allow attributes on funcs when useful.</p>
<pre class="example">
<i>// A simple func expression.</i>
var a = func(val : int) { print(val+1) }
<i>// A recursive func expression.</i>
var fib = func(n : int) {
if (n &lt; 2) return n;
return fib(n-1)+fib(n-2)
}
</pre>
<!-- ===================================================================== -->
<h3 id="expr-dot">Dot Expressions</h3>
<!-- ===================================================================== -->
<div class="commentary">
Instead of using "foo.$1" to get to fields of a tuple (which is ugly), we
could use "foo[1]". This would then make people want to use variable
indexes into tuples though, which is a bad idea.
</div>
<pre class="grammar">
expr-dot ::= <a href="#expr">expr-postfix</a> '.' <a href="#dollarident">dollarident</a>
</pre>
<p>If the base expression has <a href="#type-tuple">tuple type</a>, then the
magic identifier "$[0-9]+" accesses the specified anonymous member of the
tuple. Otherwise, this form is invalid.</p>
<pre class="grammar">
expr-dot ::= <a href="#expr">expr-postfix</a> '.' <a href="#identifier">identifier</a>
</pre>
<p>If the base expression has <a href="#type-tuple">tuple type</a> and if the
identifier is the name of a field in the tuple, then this is a reference to
the specified field.</p>
<p>
FIXME: Remove by injecting field members are overloaded functions.
If the base expression is a oneof record with one element, which has
an associated type of tuple (which is true of all struct declarations that
have tuple body type), then the field access directly accesses the
underlying tuple.</p>
<p>Otherwise, if <a href="#namebind_value_lookup_dot">dot name lookup</a> is
performed, and this expression is treated as function application. "x.foo"
is treated as a synonym for "foo x", (other than the differing name lookup
rules).</p>
<p>TODO: If dot name lookup fails, do ADL into the namespace of the base
expression's type.</p>
<p>No other field accesses are currently allowed.</p>
<!-- ===================================================================== -->
<h3 id="expr-subscript">Subscript Expressions</h3>
<!-- ===================================================================== -->
<div class="commentary">
As with arrays, this is just hacked in for now. Revisit this after we have
generics.
</div>
<pre class="grammar">
expr-subscript ::= <a href="#expr">expr-postfix</a> '[' <a href="#expr">expr</a> ']'
</pre>
<p>FIXME: Array subscript should just be an overloaded operator like any
other. a[x] should just call a function subscript(a, x). This will allow
natural support for arrays and dictionaries, whose implementation of subscript
comes from the stdlib.</p>
<p>FIXME2: Two problems with this: 1) we need support for lvalue function
calls e.g. f(a, x) = 4, otherwise we can't use an array subscript as an
lvalue. 2) we want overloading in the long term to get non-array types.</p>
<!--
<p>On an array, the subscript expression accesses the specified element number
of the array, where the first element is numbered zero. The index expression
is required to convert to an integer type. All array accesses
are bounds checked and out-of-bounds array accesses are detected at either
compile time or run time.</p>
<p>TODO: Eventually support map operations etc.</p> -->
<!-- ===================================================================== -->
<h3 id="expr-call">Function Application</h3>
<!-- ===================================================================== -->
<div class="commentary">
Type conversions/casts are just normal function calls: int(4.0) just runs
the (overloaded) 'int' function on its argument. Separation of the value
and type namespace makes this simple.
</div>
<pre class="grammar">
expr-call ::= <a href="#expr">expr-postfix</a> <a href="#expr-paren">expr-paren</a>
</pre>
<p>The leading <tt>'('</tt> of the <tt>expr-paren</tt> must be
a <tt>lparen-unspaced</tt>. This greatly reduces the likelihood of
confusion from semicolon elision, without requiring feedback from
the typechecker or more aggressive whitespace sensitivity.</p>
<p>Simple examples:</p>
<pre class="example">
<i>// Application of an empty tuple to the function f.</i>
f()
<i>// Application of 4 to the function f.</i>
g(4)
<i>// Application of 4 to the function returned by h().</i>
var h : int -&gt; int -&gt; int
...
h()(4)
<i>// Two separate statements</i>
i()
(j &lt;+ 2)()
</pre>
<!-- ===================================================================== -->
<h3 id="expr-unary">Unary Operators</h3>
<!-- ===================================================================== -->
<pre class="grammar">
expr-unary ::= <a href="#expr">expr-postfix</a>
expr-unary ::= operator <a href="#expr">expr-postfix</a>
</pre>
<p>If an operator is used as a unary operator, but name resolution
does not find at least one function of unary operator type, the
expression is ill-formed.</p>
<!-- ===================================================================== -->
<h3 id="expr-binary">Binary Operators</h3>
<!-- ===================================================================== -->
<pre class="grammar">
expr-binary ::= operator <a href="#expr-unary">expr-unary</a>
</pre>
<p>Infix binary expressions are not formed during parsing. Instead,
they are formed after name resolution by building a tree from an
operator-delimited sequence of unary expressions. Precedence and
associativity are determined by the <a href="#attribute-infix">infix</a>
attribute on the resolved names, which must fully agree.</p>
<p>If an operator is used as a binary operator, but name resolution
does not find at least one function of binary operator type, the
expression is ill-formed.</p>
<p>TODO: Should this use the expr-identifier production to allow qualified
identifiers? This would allow "foo swift::+ bar". Oneof members cannot
be declared infix, but future module/namespace scopes seem worth
accessing, though ADL is probably enough.</p>
<p>A simple example is:</p>
<pre class="example">
4 + 5 * 123
</pre>
<!-- ********************************************************************* -->
<h2 id = "stmt">Statements</h2>
<!-- ********************************************************************* -->
<div class="commentary">
Statements can only exist in contexts that are themselves a stmt or a
compound expression. Statements have no type, they just induce control
flow changes.
</div>
<pre class="grammar">
stmt ::= <a href="#stmt-semicolon">stmt-semicolon</a>
stmt ::= <a href="#stmt-assign">stmt-assign</a>
stmt ::= <a href="#stmt-brace">stmt-brace</a>
stmt ::= <a href="#stmt-return">stmt-return</a>
stmt ::= <a href="#stmt-if">stmt-if</a>
stmt ::= <a href="#stmt-while">stmt-while</a>
</pre>
<p>Statements blah blah blah ... </p>
<p>FIXME: Return stmt</p>
<pre class="example">
<i>// A function with some statements.</i>
func fib(v : int) -&gt; int {
if v &lt; 2 {
return v
}
return fib(v-1)+fib(v-2)
}
</pre>
<!-- ===================================================================== -->
<h3 id="stmt-semicolon">Semicolon Statement</h3>
<!-- ===================================================================== -->
<pre class="grammar">
stmt-semicolon ::= ';'
</pre>
<p>The semicolon statement has no effect.</p>
<!-- ===================================================================== -->
<h3 id="stmt-assign">Assignment Statement</h3>
<!-- ===================================================================== -->
<pre class="grammar">
stmt-assign ::= <a href="#expr">expr-postfix</a> '=' <a href="#expr">expr</a>
</pre>
<p>The assignment statement evaluates its left hand side as some sort of
lvalue, then evaluates the right hand side, the assigns one to the other -
somehow.
</p>
<!-- ===================================================================== -->
<h3 id="stmt-brace">Brace Statement</h3>
<!-- ===================================================================== -->
<pre class="grammar">
stmt-brace ::= '{' stmt-brace-item* '}'
stmt-brace-item ::= <a href="#decl">decl</a>
stmt-brace-item ::= <a href="#expr">expr</a>
stmt-brace-item ::= <a href="#stmt">stmt</a>
translation-unit ::= <a href="#stmt-brace">stmt-brace-item</a>*
</pre>
<p>The brace statement provides a sequencing operation which evaluates the
members of its body in order. The top level of a swift source file is
grammatically identical to a brace statement without the braces.
</p>
<!-- ===================================================================== -->
<h3 id="stmt-return">'return' Statement</h3>
<!-- ===================================================================== -->
<pre class="grammar">
stmt-return ::= 'return' <a href="#expr">expr</a>
stmt-return ::= 'return'
</pre>
<p>The return statement sets the return value of the current <a
href="#decl-func">func declaration</a> or <a href="#expr-func">func
expression</a> and transfers control out of the function. It sets the
return value by converting the specified expression result (or '()' if
none is specified) to the return type of the 'func'.
</p>
<p>The stmt-return grammar is ambiguous: "{ return 4 }" could be parsed as
{"return" "4"} or as a single statement. Ambiguity here is resolved toward
the first production, because control flow can't transfer to an
subexpression.</p>
<!-- ===================================================================== -->
<h3 id="stmt-if">'if' Statement</h3>
<!-- ===================================================================== -->
<pre class="grammar">
stmt-if ::= 'if' <a href="#expr">expr</a> <a href="#stmt-brace">stmt-brace</a> expr-if-else?
expr-if-else ::= 'else' <a href="#stmt-brace">stmt-brace</a>
expr-if-else ::= 'else' stmt-if
</pre>
<p>'if' statements provide a simple control transfer operations that evalutes
the condition, then invokes the 'convertToLogicValue' function on the result,
and determines the direction of the branch based on the result of
convertToLogicValue. This structure allows any type that can be converted to
a logic value to be used in an 'if' condition.
</p>
<p>If there is no convertToLogicValue function that accepts a 'T', or if
the resultant function does not produce a value of '<a
href="#type-builtin">__builtin_int1_type</a>' type, then the code is
malformed.
</p>
<p>Some examples include:</p>
<pre class="example">
if true {
/*...*/
}
if X == 4 {
} else {
}
if X == 4 {
} else if X == 5 {
} else {
}
</pre>
<!-- ===================================================================== -->
<h3 id="stmt-while">'while' Statement</h3>
<!-- ===================================================================== -->
<pre class="grammar">
stmt-while ::= 'while' <a href="#expr">expr</a> <a href="#stmt-brace">stmt-brace</a>
</pre>
<p>'while' statements provide simple loop construct which (on each iteration
of the loop) evalutes the condition, then invokes the 'convertToLogicValue'
function on the result and uses it to determine whether to keep looping.
This structure allows any type that can be converted to a logic value to be
used in an 'if' condition.
</p>
<p>If there is no convertToLogicValue function that accepts a 'T', or if
the resultant function does not produce a value of '<a
href="#type-builtin">__builtin_int1_type</a>' type, then the code is
malformed.
</p>
<p>Some examples include:</p>
<pre class="example">
while true {
/*...*/
}
while X == 4 {
X = 3
}
</pre>
<!-- ********************************************************************* -->
<h2>Protocols</h2>
<!-- ********************************************************************* -->
<!-- ********************************************************************* -->
<h2>Objects</h2>
<!-- ********************************************************************* -->
<!-- ********************************************************************* -->
<h2>Generics</h2>
<!-- ********************************************************************* -->
<!-- ********************************************************************* -->
<h2 id="namebind">Name Binding</h2>
<!-- ********************************************************************* -->
<p>Name binding in swift is performed in different ways depending on what
language entity is being considered:</p>
<p>Value names (for <a
href="#decl-var">var</a> and <a href="#decl-func">func</a> declarations) and
type names (for <a href="#decl-typealias">typealias</a>, <a
href="#decl-oneof">oneof</a>, and <a href="#decl-struct">struct</a>
declarations) follow the same <a href="#namebind_scope">scope</a> and
<a href="#namebind_typevalue_lookup">name lookup</a> rules as described below.
</p>
<p>tuple element names</p>
<p>scope within oneof decls</p>
<p>Context sensitive member references are resolved <a
href="#typecheck_context">during type checking</a>.</p>
<h3 id="namebind_scope">Scopes for Type and Value Names</h3>
<h3 id="namebind_value_lookup_unqual">Name Lookup Unqualified Value Names</h3>
<h3 id="namebind_value_lookup_dot">"dot" Name Lookup Value Names</h3>
<h3 id="namebind_typevalue_lookup">Name Lookup for Type and Value Names</h3>
<p>Basic algo:</p>
<ul>
<li>Search the current scope tree for a local name. Local names cannot be
forward referenced.</li>
<li>Bind to names defined in the current component, including the current
translation unit. TODO: is this a good thing? We could require explicit
imports if we wanted to.</li>
<li>Bind to identifiers that are imported with an import directive. Imports
are searched in order of introduction (top-down). The location of an
import directive in a file (e.g. between func decls) does not affect name
lookup, but the order of imports w.r.t. each other does.</li>
</ul>
<h3 id="namebind_dot">Name Lookup for Dot Expressions</h3>
<p>
<a href="#expr-dot">Dot Expressions</a> bind to name of tuple elements.
</p>
<!-- ********************************************************************* -->
<h2 id="typecheck">Type Checking</h2>
<!-- ********************************************************************* -->
<p>
Binary expressions, function application, etc.
</p>
<h3 id="typecheck_conversions">Standard Conversions</h3>
<!--
Consider foo(4, 5) when foo is declared to take ((int,int=3), int=6). This
could be parsed as either ((4,5), 6) or ((4,3),5), but the later one is
the "right" answer.
-->
<h3 id="typecheck_anon">Anonymous Argument Resolution</h3>
<h3 id="typecheck_context">Context Sensitive Type Resolution</h3>
<!-- ********************************************************************* -->
<h2 id="stdlib">Standard Library</h2>
<!-- ********************************************************************* -->
<div class="commentary">
It would be really great to have literate swift code someday, that way
this could be generated directly from the code. This would also be powerful
for Swift library developers to be able to depend on being available and
standardized.
</div>
<p>This describes some of the standard swift code as it is being built up.
Since Swift is designed to give power to the library developers, much of
what is normally considered the "language" is actually just implemented in
the library.</p>
<p>All of this code is published by the 'swift' module, which is
implicitly imported into each translation unit, unless some sort of pragma
in the code (attribute on an import?) is used to change or disable this
behavior.</p>
<!-- ===================================================================== -->
<h3 id="stdlib-simple-types">Simple Types</h3>
<!-- ===================================================================== -->
<h4 id="stdlib-void">void</h4>
<pre class="stdlib">
<i>// void is just a type alias for the empty tuple.</i>
typealias void : ()
</pre>
<h4 id="stdlib-int">int</h4>
<pre class="stdlib">
<i>// int is just a wrapper around the 64-bit integer type.</i>
struct int { value : __builtin_int64_type }
</pre>
<h4 id="stdlib-bool">bool, true, false</h4>
<pre class="stdlib">
<i>// bool is a simple discriminated union.</i>
oneof bool {
true, false
}
<i>// Allow true and false to be used unqualified.</i>
var true = bool::true
var false = bool::false
</pre>
<!-- ===================================================================== -->
<h3 id="stdlib-logic-value">Logic Value Evalution For Control Flow</h3>
<!-- ===================================================================== -->
<h4 id="stdlib-void">void</h4>
<pre class="stdlib">
<i>// logic_value is the standard type to be used for values that can be
// used in control flow conditionals.</i>
typealias logic_value : __builtin_int1_type
func convertToLogicValue(v : logic_value) -&gt; logic_value
func convertToLogicValue(v : bool) -&gt; logic_value
</pre>
<!-- ===================================================================== -->
<h3 id="stdlib-arithmetic">Arithmetic and Logical Operations</h3>
<!-- ===================================================================== -->
<div class="commentary">
This is all eagerly awaiting the day when we have generics and overloading.
For now, int is the only arithmetic type :)
</div>
<h4 id="stdlib-arithmetic">Arithmetic Operators</h4>
<pre class="stdlib">
<i>// Simple binary operators, following the same precedence as C.</i>
func [infix=200] * (lhs: int, rhs: int) -&gt; int
func [infix=200] / (lhs: int, rhs: int) -&gt; int
func [infix=200] % (lhs: int, rhs: int) -&gt; int
func [infix=190] + (lhs: int, rhs: int) -&gt; int
func [infix=190] - (lhs: int, rhs: int) -&gt; int
<i>// In C, &lt;&lt;, &gt;&gt; is 180.</i>
</pre>
<h4 id="stdlib-comparison">Relational and Equality Operators</h4>
<pre class="stdlib">
var [infix=170] &lt; : (lhs : int, rhs : int) -&gt; bool
var [infix=170] &gt; : (lhs : int, rhs : int) -&gt; bool
var [infix=170] &lt;= : (lhs : int, rhs : int) -&gt; bool
var [infix=170] &gt;= : (lhs : int, rhs : int) -&gt; bool
var [infix=160] == : (lhs : int, rhs : int) -&gt; bool
var [infix=160] != : (lhs : int, rhs : int) -&gt; bool
<i>// In C, bitwise logical operators are 130,140,150.</i>
</pre>
<h4 id="stdlib-short-circuit-logical">Short Circuiting Logical Operators</h4>
<pre class="stdlib">
func [infix=120] &amp;&amp; (lhs: bool, rhs: ()-&gt;bool) -&gt; bool
func [infix=110] || (lhs: bool, rhs: ()-&gt;bool) -&gt; bool
<i>// In C, 100 is ?:</i>
<i>// In C, 90 is =, *=, += etc.</i>
</pre>
<!-- *********************************************************************** -->
<hr>
<address>
<a href="http://jigsaw.w3.org/css-validator/check/referer"><img
src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS"></a>
<a href="http://validator.w3.org/check/referer"><img
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
</address>
</body>
</html>