mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
This cleans up handling of int/fp literals by splitting them appart at the lexer level. Swift SVN r1137
2156 lines
85 KiB
HTML
2156 lines
85 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. As the prototype evolves,
|
|
this document should be kept up to date with what is actually implemented.</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>
|
|
|
|
<p>In no particular order, and not explained well:</p>
|
|
|
|
<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, like an IDE, debugger, profiling, etc.</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>Memory safe by default: array overrun errors, uninitialized values,
|
|
and other problems endemic to C should not occur in Swift, even if it
|
|
means some amount of runtime overhead. Eventually these checks will be
|
|
disablable for people who want ultimate performance in production
|
|
builds.</li>
|
|
<li>Efficiently implementable with a static compiler: runtime compilation is
|
|
great technology and Swift may eventually get a runtime optimizer, but it
|
|
is a strong goal to be able to implement swift with just a static
|
|
compiler.</li>
|
|
<li>Interoperate as transparently as possible with C, Objective-C, and
|
|
C++ without having to write an equivalent of "extern C" for every
|
|
referenced definition.</li>
|
|
<li>Great support for efficient by-value types.</li>
|
|
<li>Elegant and natural syntax, aiming to be familiar and easy to transition
|
|
to for "C" people. Differences from the C family should only be done when
|
|
it provides a significant win (e.g. eliminate declarator syntax).</li>
|
|
<li>Lots of other stuff too.</li>
|
|
</ol>
|
|
|
|
<p>A smaller wishlist goal is to support embedded sub-languages in swift, so
|
|
that we don't get the OpenCL-is-like-C-but-very-different-in-many-details
|
|
problem.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3>Basic Approach</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
Pushing as much of the language as realistic out of the compiler and into
|
|
the library is generally good for a few reasons: 1) we end up with a smaller
|
|
core language. 2) we force the language that is left to be highly
|
|
expressive and extensible. 3) this highly expressive language core can then
|
|
be used to build a lot of other great libraries, hopefully many we can't
|
|
even anticipate at this point.
|
|
</div>
|
|
|
|
<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, sugar 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 <a
|
|
href="#stdlib">standard library</a> (inspired in part by the Haskell
|
|
Standard Prelude). This means that things like 'int' and 'void' are not
|
|
part of the language itself, but are instead part of the standard library.
|
|
</p>
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h2>Phases of Translation</h2>
|
|
<!-- ********************************************************************* -->
|
|
|
|
<div class="commentary">
|
|
Because Swift doesn't rely on a C-style "lexer hack" to know what is a type
|
|
and what is a value, it is possible to fully parse a file without resolving
|
|
import declarations.
|
|
</div>
|
|
|
|
<p>Swift has a strict separation between its phases of translation, and the
|
|
compiler follows a conceptually simple design. 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: The AST is converted the LLVM IR, optimizations are
|
|
performed, and machine code generated.</li>
|
|
<li>Linking: runtime libraries and referenced modules are linked in.</li>
|
|
</ul>
|
|
|
|
<p>
|
|
FIXME: "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>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
Nested block comments are important because we don't have the nestable
|
|
"#if 0" hack from C to rely on.
|
|
</div>
|
|
<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 recursively 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 -> is used for function types "() -> 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 ::= '->'
|
|
</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 (e.g. "builtin" datatypes like 'int' and 'bool'). This
|
|
allows us to add new stuff to the library in the future without worrying
|
|
about conflicting with the user's namespace.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
keyword ::= 'else'
|
|
keyword ::= 'extension'
|
|
keyword ::= 'if'
|
|
keyword ::= 'import'
|
|
keyword ::= 'func'
|
|
keyword ::= 'oneof'
|
|
keyword ::= 'plus'
|
|
keyword ::= 'protocol'
|
|
keyword ::= 'return'
|
|
keyword ::= 'struct'
|
|
keyword ::= 'typealias'
|
|
keyword ::= 'var'
|
|
keyword ::= 'while'
|
|
</pre>
|
|
|
|
<p>These are the builtin keywords.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="integer_literal">Integer Literals</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
integer_literal ::= [0-9]+
|
|
</pre>
|
|
|
|
<p>integer_literal tokens represent simple integer values of unspecified
|
|
precision.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="floating_literal">Floating Point Literals</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
We require a digit after a dot to allow lexing "4.km" as "4 . km" instead of
|
|
"4. km". This regex can be generalized to support exponents someday.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
floating_literal ::= [0-9]*.[0-9]+
|
|
</pre>
|
|
|
|
<p>floating_literal tokens represent floating point values of unspecified
|
|
precision.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="identifier">Identifier Tokens</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
identifier ::= [a-zA-Z_][a-zA-Z_$0-9]*
|
|
operator ::= [/=-+*%<>!&|^]+
|
|
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-extension">decl-extension</a>
|
|
decl ::= <a href="#decl-func">decl-func</a>
|
|
decl ::= <a href="#decl-import">decl-import</a>
|
|
decl ::= <a href="#decl-oneof">decl-oneof</a>
|
|
decl ::= <a href="#decl-protocol">decl-protocol</a>
|
|
decl ::= <a href="#decl-struct">decl-struct</a>
|
|
decl ::= <a href="#decl-typealias">decl-typealias</a>
|
|
decl ::= <a href="#decl-var">decl-var</a>
|
|
</pre>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-translation-unit">Translation Unit</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
translation-unit ::= <a href="#stmt-brace">stmt-brace-item</a>*
|
|
</pre>
|
|
|
|
<p>The top level of a swift source file is grammatically identical to the
|
|
contents of a <a href="#stmt-brace">brace statement</a>. Some declarations
|
|
have semantic restrictions that only allow them within a translation unit
|
|
though.
|
|
</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-import">import Declarations</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
decl-import ::= 'import' <a href="#attribute-list">attribute-list</a> 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. If the named value is
|
|
overloaded, then the entire overload set 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
|
|
|
|
<i>// Import all multiplication overloads.</i>
|
|
import swift.*
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-extension">extension Declarations</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
Eventually allow extending classes, even adding data members.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
decl-extension ::= 'extension' <a href="#type-identifier">type-identifier</a> '{' <a href="#decl">decl</a>* '}'
|
|
</pre>
|
|
|
|
<p>'extension' declarations allow adding member declarations to existing
|
|
types, even in other translation units and modules. There are different
|
|
semantic rules for each type that is extended.
|
|
</p>
|
|
|
|
<!-- _____________________________________________________________________ -->
|
|
<h4 id="decl-extension-oneof-struct"><a href="#decl-oneof">oneof</a> and <a
|
|
href="#decl-struct">struct</a> declaration extensions</h4>
|
|
|
|
<p>'<a href="#decl-var">var</a>' decls are not allowed in a oneof or struct,
|
|
data members should be used instead.</p>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<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>
|
|
decl-var-simple ::= 'var' <a href="#attribute-list">attribute-list</a> <a href="#identifier">identifier</a> <a href="#value-specifier">value-specifier</a>
|
|
|
|
value-specifier ::= ':' <a href="#type">type-annotation</a>
|
|
value-specifier ::= ':' <a href="#type">type-annotation</a> '=' <a href="#expr">expr</a>
|
|
value-specifier ::= '=' <a href="#expr">expr</a>
|
|
</pre>
|
|
|
|
|
|
<p>'var' declarations form the backbone of value declarations in Swift.
|
|
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>Like all other declarations, var's can optionally have a list of <a
|
|
href="#attribute-list">attributes</a> applied to them.</p>
|
|
|
|
<pre class="grammar">
|
|
var-name ::= <a href="#identifier">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. FIXME: This should be integrated with pattern matching.
|
|
</p>
|
|
|
|
<p>The type of a variable must be
|
|
<a href="#materializable"><i>materializable</i></a>.</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>// 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>
|
|
// <b>FIXME</b> This seems like a really bad idea, making binding 'fragile'.
|
|
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 ::= 'plus'? 'func' <a href="#attribute-list">attribute-list</a> <a href="#identifier">any-identifier</a> <a href="#func-signature">func-signature</a> <a href="#stmt-brace">stmt-brace</a>?
|
|
</pre>
|
|
|
|
<p>'func' is a declaration for a function. The argument list and
|
|
optional return value are specified by the type production of the function,
|
|
and the body is either a brace expression or elided. Like all other
|
|
declarations, functions are can have attributes.</p>
|
|
|
|
<p>If the type is not syntactically a function type (i.e., has no -> in it
|
|
at top-level), then the return value is implicitly inferred to be
|
|
"<tt>()</tt>". All of the argument and return value names are injected into
|
|
the <a href="#namebind_scope">scope</a> of the function body.</p>
|
|
|
|
<p>A function in an <a href="#decl-extension">extension</a> of some type (or
|
|
in other places that are semantically equivalent to an extension) implicitly
|
|
get a 'this' argument with these rules ... [todo]</p>
|
|
|
|
<p>'plus' functions are only allowed in an <a
|
|
href="#decl-extension">extension</a> of some type (or in other places
|
|
that are semantically equivalent to an extension). They indicate that
|
|
the function is actually defined on the <a href="#metatype">metatype</a>
|
|
for the type, not on the
|
|
type itself. Thus it does not implicitly get a first 'this' argument, and
|
|
can be used with dot syntax on the metatype.</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>
|
|
|
|
<!-- _____________________________________________________________________ -->
|
|
<h4 id="func-signature">Function signatures</h4>
|
|
|
|
<pre class="grammar">
|
|
func-signature ::= <a href="#pattern-tuple">pattern-tuple</a>+ func-signature-result?
|
|
func-signature-result ::= '->' <a href="#type">type</a>
|
|
</pre>
|
|
|
|
<p>A function signature specifies one or more sets of parameter
|
|
patterns, plus an optional result type.</p>
|
|
|
|
<p>When a result type is not written, it is implicitly the empty tuple type,
|
|
<tt>()</tt>.</p>
|
|
|
|
<p>In the body of the function described by a particular signature,
|
|
all the variables bound by all of the parameter patterns are in
|
|
scope, and the function must return a value of the result type.</p>
|
|
|
|
<p>An outermost pattern in a function signature must be fully-typed
|
|
and irrefutable. If a result type is given, it must also be
|
|
fully-typed.</p>
|
|
|
|
<p>The type of a function with signature <tt>(P<sub>0</sub>)(P<sub>1</sub>)..(P<sub><i>n</i></sub>) -> R</tt>
|
|
is <tt>T<sub>0</sub> -> T<sub>1</sub> -> .. -> T<sub><i>n</i></sub> -> R</tt>,
|
|
where <tt>T<sub><i>i</i></sub></tt> is the bottom-up type of the pattern
|
|
<tt>P<sub><i>i</i></sub></tt>. This is called "currying". The
|
|
behavior of all the intermediate functions (those which do not
|
|
return <tt>R</tt>) is to capture their arguments, plus any
|
|
arguments from prior patterns, and returns a function which takes
|
|
the next set of arguments. When the "uncurried" function is
|
|
called (the one taking <tt>T<sub><i>n</i></sub></tt> and returning
|
|
<tt>R</tt>), all of the arguments are then available and the
|
|
function body is finally evaluated as normal.</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() -> void {}
|
|
|
|
<i>// Function pointers to a function expression.</i>
|
|
var a2 = func ()->() {}
|
|
var a3 = func () {}
|
|
var a4 = func {}
|
|
|
|
<i>// Really simple function</i>
|
|
func c(arg : int) -> int { return arg+4 }
|
|
|
|
<i>// Simple operators.</i>
|
|
func [infix_left=190] + (lhs : int, rhs : int) -> int
|
|
func [infix_left=160] == (lhs : int, rhs : int) -> bool
|
|
|
|
<i>// Curried function with multiple return values:</i>
|
|
func d(a : int) -> (b : int) -> (res1 : int, res2 : int)
|
|
|
|
<i>// A more realistic example on a trivial type.</i>
|
|
struct bankaccount {
|
|
amount : int
|
|
|
|
plus func bankaccount() -> bankaccount {
|
|
// Custom 'constructor' logic goes here.
|
|
}
|
|
func deposit(arg : int) {
|
|
amount = amount + arg
|
|
}
|
|
|
|
plus func someMetaTypeMethod() {}
|
|
}
|
|
|
|
// Dot syntax on metatype.
|
|
bankaccount.someMetaTypeMethod()
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-typealias">typealias Declarations</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
We use the keyword "typealias" instead of "typedef" because it really is an
|
|
alias for an existing type, not a "definition" of a new type.
|
|
</div>
|
|
|
|
|
|
<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.</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 -> int -> (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> uses an implicit 'typealias' to
|
|
represent the name for the type.</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 than its use for "enums". If
|
|
there is a compelling reason to, we could add an "enum" sugar for
|
|
oneof's.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
decl-oneof ::= 'oneof' <a href="#attribute-list">attribute-list</a> <a href="#identifier">identifier</a> oneof-body
|
|
oneof-body ::= '{' (oneof-element (',' oneof-element)*)? decl* '}'
|
|
|
|
oneof-element ::= <a href="#identifier">identifier</a>
|
|
oneof-element ::= <a href="#identifier">identifier</a> ':' <a href="#type">type-annotation</a>
|
|
</pre>
|
|
|
|
<p>A oneof declaration provides direct access to <a
|
|
href="#type-oneof">oneof</a> types with a <a
|
|
href="#decl-typealias">typealias</a> declaration specifying a name. Please
|
|
see <a href="#type-oneof">oneof types</a> for more information about their
|
|
capabilities.</p>
|
|
|
|
<p>A 'oneof' may include a list of decls after its member types, which is
|
|
syntactic sugar for defining an <a href="#decl-extension">extension</a> of
|
|
the type. The limitations of an <a
|
|
href="#decl-extension-oneof-struct">oneof extensions</a> apply here as
|
|
well.</p>
|
|
|
|
<p>Here are some examples of oneof declarations:</p>
|
|
|
|
<pre class="example">
|
|
<i>// Declare discriminated union with oneof decl.</i>
|
|
oneof SomeInts {
|
|
None,
|
|
One : int,
|
|
Two : (:int, :int)
|
|
}
|
|
|
|
<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 -> SomeInts".</i>
|
|
var b : int -> SomeInts = SomeInts::One
|
|
|
|
<i>Constructor for Two has type "(:int,:int) -> SomeInts".</i>
|
|
var c : (:int,:int) -> 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> '{' decl-struct-body '}'
|
|
decl-struct-body ::= <a href="#type-tuple">type-tuple-body</a>? <a href="#decl">decl</a>*
|
|
</pre>
|
|
|
|
<p>A struct declares a simple value type that can contain data members and
|
|
have methods. A struct is syntactic sugar for more primitive forms: a
|
|
oneof declaration of a single element, a 'typealias', a constructor, and
|
|
potentially an extension with functions in it. Unlike tuple elements, all
|
|
members of the struct must be named.</p>
|
|
|
|
<p>Since the element types of a oneof must
|
|
be <a href="#materializable">materializable</a>, it follows that
|
|
all the struct field types must be as well.</p>
|
|
|
|
<p>A 'struct' may include a list of decls after its member types, which is
|
|
syntactic sugar for defining an <a href="#decl-extension">extension</a> of
|
|
the type. The limitations of an <a
|
|
href="#decl-extension-oneof-struct">struct extensions</a> apply here as
|
|
well.</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)
|
|
}
|
|
</pre>
|
|
|
|
Likewise, these are two equivalent ways of writing the same thing:
|
|
|
|
<pre class="example">
|
|
struct S3a { x = 4, y : int }
|
|
struct S3b {
|
|
x = 4
|
|
y : int
|
|
}
|
|
</pre>
|
|
|
|
Likewise, a <a href="#decl-func">func</a> declared in the struct are
|
|
equivalent to declaring an <a href="#decl-extension">extension</a> containing
|
|
the func.
|
|
|
|
<pre class="example">
|
|
struct S4a {
|
|
x : int
|
|
func doStuff() { ... }
|
|
}
|
|
struct S4b {
|
|
x : int
|
|
}
|
|
extension S4b {
|
|
func doStuff() { ... }
|
|
}
|
|
</pre>
|
|
|
|
<p>Here are some more realistic 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
|
|
|
|
typealias CoordinateType : int
|
|
|
|
func area() -> int { return size.width*size.height }
|
|
}
|
|
|
|
func test4() {
|
|
var a : Point
|
|
var b = Point.Point(1, 2) // Silly but fine.
|
|
var c = Point(y = 1, x = 2) // Using metatype.
|
|
|
|
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
|
|
var x1_area2 = x1.area()
|
|
}
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-protocol">Protocol Declarations</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
<b>The Protocol implementation is just an initial hack and is likely to
|
|
change substantially.</b>
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
decl-protocol ::= 'protocol' <a href="#attribute-list">attribute-list</a> <a href="#identifier">identifier</a> protocol-body
|
|
protocol-body ::= '{' protocol-member* '}'
|
|
</pre>
|
|
|
|
<p>A protocol declaration describes an abstract interface implemented by
|
|
another type. It consists of a comma-separated list of elements, each of
|
|
which are members that instances of the protocol are guaranteed to have.
|
|
Internally, protocol declarations are modelled as a <a
|
|
href="#decl-typealias">typealias</a> that wraps a protocol type.</p>
|
|
|
|
<p>Here are some examples of protocols:</p>
|
|
|
|
<pre class="example">
|
|
protocol Document {
|
|
func title() -> string
|
|
}
|
|
protocol VersionedDocument <i>/*: Document*/</i> {
|
|
func version() -> int
|
|
}
|
|
</pre>
|
|
|
|
<!-- _____________________________________________________________________ -->
|
|
<h4 id="protocol-member-func">'func' protocol elements</h4>
|
|
|
|
<pre class="grammar">
|
|
protocol-member ::= <a href="#decl-func">decl-func</a>
|
|
</pre>
|
|
|
|
<p>'func' members of a protocol define a value of function type that may be
|
|
accessed with dot syntax on a value of the protocol's type. The function
|
|
gets an implicit "this" argument of the protocol type.</p>
|
|
|
|
<p>TODO: var members and typealias members</p>
|
|
|
|
<!-- _____________________________________________________________________ -->
|
|
<h4 id="protocol-member-var">'var' protocol elements</h4>
|
|
|
|
<pre class="grammar">
|
|
protocol-member ::= <a href="#decl-var">decl-var-simple</a>
|
|
</pre>
|
|
|
|
<p>'var' members of a protocol define "property" values that may be accessed
|
|
with dot syntax on a value of the protocol's type. The declaration itself has
|
|
function type, where the argument is an implicit "this" argument of the
|
|
protocol type.</p>
|
|
|
|
<p>TODO: typealias members</p>
|
|
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="attribute-list">Attribute Lists</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
attribute-list ::= /*empty*/
|
|
attribute-list ::= '[' ']'
|
|
attribute-list ::= '[' attribute (',' attribute)* ']'
|
|
|
|
attribute ::= attribute-infix
|
|
attribute ::= attribute-resilience
|
|
attribute ::= attribute-byref
|
|
</pre>
|
|
|
|
<p>An attribute is a (possibly empty) comma separated list of attributes.</p>
|
|
|
|
<h4 id="attribute-infix">Infix Attributes</h4>
|
|
|
|
<pre class="grammar">
|
|
attribute-infix ::= 'infix_left' '=' <a href="#integer_literal">integer_literal</a>
|
|
attribute-infix ::= 'infix_right' '=' <a href="#integer_literal">integer_literal</a>
|
|
attribute-infix ::= 'infix '=' <a href="#integer_literal">integer_literal</a>
|
|
</pre>
|
|
|
|
<p>The infix attributes 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>. The name indicates the
|
|
associativity of the operator, either left associative, right associative, or
|
|
non-associative.</p>
|
|
|
|
<p>FIXME: Implement these restrictions.</p>
|
|
|
|
<h4 id="attribute-resilence">Resilience Attribute</h4>
|
|
|
|
<pre class="grammar">
|
|
attribute-resilience ::= 'resilient'
|
|
attribute-resilience ::= 'fragile'
|
|
attribute-resilience ::= 'born_fragile'
|
|
</pre>
|
|
|
|
<p>See the resilience design.</p>
|
|
|
|
<h4 id="attribute-byref">By-Reference Attribute</h4>
|
|
|
|
<pre class="grammar">
|
|
attribute-byref ::= 'byref'
|
|
</pre>
|
|
|
|
<p><tt>byref</tt> is only valid in a <tt>type-annotation</tt> that
|
|
appears within either a <a href="#pattern"><tt>pattern</tt></a> of
|
|
a <tt>function-signature</tt> or the input type of a function
|
|
type.
|
|
</p>
|
|
|
|
<p><tt>byref</tt> indicates that the argument will be passed "by
|
|
reference": the bound variable will be an l-value.</p>
|
|
|
|
<p>The type being annotated must be <a href="#materializable">materializable</a>.
|
|
The type after annotation is never materializable.</tt>
|
|
|
|
<p>FIXME: we probably need a const-like variant, which permits
|
|
r-values (and avoids writeback when the l-value is not physical).
|
|
We may also need some way of representing <q>this will be
|
|
consumed by the nth curry</q>.
|
|
</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-identifier">type-identifier</a>
|
|
type-simple ::= <a href="#type-tuple">type-tuple</a>
|
|
|
|
type-annotation ::= <a href="#attribute-list">attribute-list</a> type
|
|
</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>
|
|
|
|
<!-- _____________________________________________________________________ -->
|
|
<h4>Metatypes</h4>
|
|
|
|
<p id="metatype">Each type has a corresponding <i>metatype</i>, with the same
|
|
name as the type, that is injected into the standard name lookup scope when
|
|
a type is <a href="#decl">declared</a>. This allows access to '<a
|
|
href="#decl-func">plus functions</a>' through dot syntax. For example:</p>
|
|
|
|
<pre class="example">
|
|
// Declares a type 'foo' as well as its metatype.
|
|
struct foo {
|
|
plus func bar() {}
|
|
}
|
|
|
|
// Declares x to be of type foo. A reference to a name in type context
|
|
// refers to the type itself.
|
|
var x : foo
|
|
|
|
// Accesses a plus function on the foo metatype. In a value context, the
|
|
// name of its type refers to its metatype.
|
|
foo.bar()
|
|
</pre>
|
|
|
|
<!-- _____________________________________________________________________ -->
|
|
<h4>Full-Typed Types</h4>
|
|
|
|
<p>A type may be <i>fully-typed</i>. A type is fully-typed unless
|
|
it is 1) a function type whose result or input type is not
|
|
fully-typed or 2) a tuple type with an element that is not
|
|
fully-typed. A tuple element is fully-typed unless it has no
|
|
explicit type (which is permitted for defaultable elements) or its
|
|
explicit type is not fully-typed. In other words, a type is
|
|
fully-typed unless it syntactically contains a tuple element with
|
|
no explicit type annotation.</p>
|
|
|
|
<p>A type being 'fully-typed' informally means that the type is specified
|
|
directly from its type annotation without needing contextual or other
|
|
information to resolve its type.</p>
|
|
|
|
<!-- _____________________________________________________________________ -->
|
|
<h4>Materializable Types</h4>
|
|
|
|
<p id="materializable">A type may be <i>materializable</i>. A type
|
|
is materializable unless it is 1) annotated with
|
|
a <a href="#attribute-byref"><tt>byref</tt></a> attribute or 2) a
|
|
tuple with a non-materializable element type. In general, variables
|
|
must have materializable type.</p>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="type-identifier">Named Types</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
type-identifier ::= <a href="#identifier">identifier</a> ('.' <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 type declarations that expand to one.</p>
|
|
|
|
<pre class="example">
|
|
typealias location : (x : int, y : int)
|
|
var x : location <i>// use of a named type.</i>
|
|
</pre>
|
|
|
|
<p>Type names may use dot syntax to refer to names types declared in other
|
|
modules or types nested within other types.</p>
|
|
|
|
<pre class="example">
|
|
<i>// Direct reference to a member of another module.</i>
|
|
var x : Swift.Int
|
|
</pre>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="type-tuple">Tuple Types</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
Tuples are everywhere in Swift: even the argument list of a function is a
|
|
tuple of those arguments.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
type-tuple ::= lparen-any type-tuple-body? ')'
|
|
type-tuple-body ::= type-tuple-element (',' type-tuple-element)*
|
|
type-tuple-element ::= identifier <a href="#value-specifier">value-specifier</a>
|
|
type-tuple-element ::= <a href="#type">type-annotation</a>
|
|
</pre>
|
|
|
|
<p>Syntactically, tuple types are simply a (possibly empty) list of
|
|
elements enclosed in parentheses. A tuple type with a single, anonymous,
|
|
undefaulted element is exactly that type: the parentheses are treated as
|
|
grouping parentheses.</p>
|
|
|
|
<p>Tuples are the low-level 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
|
|
a 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) -> (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> '->' <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>The result type of a function type must
|
|
be <a href="#materializable">materializable</a>.
|
|
FIXME: The argument will eventually have to be a tuple.</p>
|
|
|
|
<p>Because of the grammar structure, a nested function type like
|
|
"a -> b -> c" is parsed as "a -> (b -> 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". This
|
|
is known as <a href="http://en.wikipedia.org/wiki/Currying">currying</a>.
|
|
For example:
|
|
</p>
|
|
|
|
<pre class="example">
|
|
<i>// A simple function that takes a tuple and returns int:</i>
|
|
var a : (a : int, b : int) -> int
|
|
|
|
<i>// A simple function that returns multiple values:</i>
|
|
var a : (a : int, b : int) -> (val: int, err: int)
|
|
|
|
<i>// Declare a function that returns a function:</i>
|
|
var x : int -> int -> int
|
|
|
|
<i>// y has type int -> 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-oneof">oneof Types</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
'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>
|
|
|
|
<p>A oneof type is a simple discriminated union: the runtime representation
|
|
of a value of oneof type only has one of the specified elements at a time.</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>All of the element types of a oneof type must
|
|
be <a href="#materializable">materializable</a>.</p>
|
|
|
|
<p>Oneof types are implicitly created when <a href="#decl-oneof">declaring a
|
|
oneof</a>, <a href="#decl-struct">struct</a>, which produces a typealias and
|
|
an underlying oneof type. There is no way to create an anonymous oneof type
|
|
in the type production of the grammar.
|
|
|
|
<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>
|
|
|
|
<!-- ===================================================================== -->
|
|
<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<int, 4> 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>The element type of an array type must
|
|
be <a href="#materializable">materializable</a>.</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 -> 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 -> 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>
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h2 id="pattern">Patterns</h2>
|
|
<!-- ********************************************************************* -->
|
|
|
|
<div class="commentary">
|
|
We intend to have a pattern-matching statement eventually, and
|
|
probably a pattern-matching predicate expression. There are several
|
|
other places in the language, however, which can also be usefully
|
|
expressed in terms of patterns. This has the benefit of allowing
|
|
uniform decomposition of tuples.<br><br>
|
|
|
|
The pattern grammar mirrors the expression grammar, or to be more
|
|
specific, the grammar of literals. This is because the conceptual
|
|
algorithm for matching a value against a pattern is to try to find
|
|
an assignment of values to variables which makes the pattern equal
|
|
the value. So every expression form which can be used to build a
|
|
value directly should generally have a corresponding pattern form.
|
|
<br><br>
|
|
|
|
For now, however, we do not include literals in the pattern grammar.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
pattern-atom ::= <a href="#pattern-identifier">pattern-identifier</a>
|
|
pattern-atom ::= <a href="#pattern-tuple">pattern-tuple</a>
|
|
|
|
pattern ::= pattern-atom
|
|
pattern ::= <a href="#pattern-typed">pattern-typed</a>
|
|
</pre>
|
|
|
|
<p>The basic pattern grammar is a literal "atom" followed by an
|
|
optional type annotation. Type annotations are useful for
|
|
documentation, as well as for coercing a matched expression to a
|
|
particular kind. They are also required when patterns are used in
|
|
a <a href="#func-signature">function signature</a>.</p>
|
|
|
|
<p>A pattern has a type. A pattern may be "fully-typed", meaning
|
|
informally that its type is fully determined by the type
|
|
annotations it contains. Some patterns may also derive a type
|
|
from their context, be it an enclosing pattern or the way it is
|
|
used; this set of situations is not yet fully determined.</p>
|
|
|
|
<p>A pattern may be "irrefutable", meaning informally that it
|
|
matches all values of its type. Patterns in some contexts are
|
|
required to be irrefutable.</p>
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h3 id="pattern-typed">Typed Patterns</h3>
|
|
<!-- ********************************************************************* -->
|
|
|
|
<pre class="grammar">
|
|
pattern-typed ::= pattern-atom ':' <a href="#type">type-annotation</a>
|
|
</pre>
|
|
|
|
<p>A type annotation constrains a pattern to have a specific type.
|
|
An annotated pattern is fully-typed if its annotation type is
|
|
fully-typed. It is irrefutable if and only if its subpattern is
|
|
irrefutable.</p>
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h3 id="pattern-identifier">Identifier Patterns</h3>
|
|
<!-- ********************************************************************* -->
|
|
|
|
<pre class="grammar">
|
|
pattern-identifier ::= <a href="#identifier">identifier</a>
|
|
</pre>
|
|
|
|
<p>An identifier pattern binds a value to a particular name, which is
|
|
then a legal variable of the pattern's type within its scope. It is
|
|
irrefutable. It is not fully-typed; the type must be inferred from
|
|
context.</p>
|
|
|
|
<p>As a special case, if the identifier is <tt>_</tt> then no variable
|
|
comes into scope, and the value matched is lost. Such an identifier
|
|
pattern is called an "ignore pattern". An identifier pattern
|
|
which is not an ignore pattern is called a "named pattern".</p>
|
|
|
|
<p>The type of a named pattern must be
|
|
<a href="#materializable">materializable</a> unless it appears in a
|
|
<a href="#function-signature">function-signature</a> and is directly
|
|
a <a href="attribute-byref"><tt>byref</tt></a>-annotated type.</p>
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h3 id="pattern-tuple">Tuple Patterns</h3>
|
|
<!-- ********************************************************************* -->
|
|
|
|
<pre class="grammar">
|
|
pattern-tuple ::= '(' pattern-tuple-body? ')'
|
|
pattern-tuple-body ::= pattern-tuple-element
|
|
pattern-tuple-body ::= pattern-tuple-element ',' pattern-tuple-body
|
|
pattern-tuple-element ::= pattern
|
|
pattern-tuple-element ::= pattern '=' <a href="#expr">expr</a>
|
|
</pre>
|
|
|
|
<p>A tuple pattern is a list of zero or more patterns. Within a
|
|
function signature, patterns may also be given a default-value
|
|
expression.</p>
|
|
|
|
<p>A tuple pattern is irrefutable if all its sub-patterns are
|
|
irrefutable.</p>
|
|
|
|
<p>A tuple pattern is fully-typed if all its sub-patterns are
|
|
fully-typed, in which case its type is the corresponding tuple
|
|
type, where each <tt>type-tuple-element</tt> has the type,
|
|
label, and default value of the corresponding <tt>pattern-tuple-element</tt>.
|
|
A <tt>pattern-tuple-element</tt> has a label if it is a named
|
|
pattern or a type annotation of a named pattern.</p>
|
|
|
|
<p>As a special case, a tuple pattern with one element that lacks
|
|
both a label and default value is treated as a grouping parenthesis: it has
|
|
the type of its constituent pattern, not a tuple type.</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 the need for them.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
expr ::= <a href="#expr-unary">expr-unary</a> <a href="#expr-binary">expr-binary</a>*
|
|
|
|
expr-primary ::= <a href="#expr-literal">expr-literal</a>
|
|
expr-primary ::= <a href="#expr-identifier">expr-identifier</a>
|
|
expr-primary ::= <a href="#expr-anon-closure-arg">expr-anon-closure-arg</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>
|
|
|
|
</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-binary">Binary Operators</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
Should this use the expr-identifier production to allow qualified
|
|
identifiers? This would allow "foo swift.+ bar". Is ADL or something
|
|
like it enough?
|
|
</div>
|
|
|
|
<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>A simple example is:</p>
|
|
|
|
<pre class="example">
|
|
4 + 5 * 123
|
|
</pre>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-unary">Unary Operators</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
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 that takes a single argument, the
|
|
expression is ill-formed.</p>
|
|
|
|
<p>Simple examples:</p>
|
|
|
|
<pre class="example">
|
|
i = -j
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-literal">Literals</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
The type of a literal is inferred from its context, to allow things like "4"
|
|
to be compatible with any width integer type without 'promotion' rules or
|
|
casting. In ambiguous cases like "var x = 4", the literals are forced to
|
|
a default type specified by the standard library.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
expr-literal ::= <a href="#integer_literal">integer_literal</a>
|
|
expr-literal ::= <a href="#floating_literal">floating_literal</a>
|
|
</pre>
|
|
|
|
<p>Numeric literals are either integer or floating point depending on their
|
|
lexical form. The type of the literal is inferred
|
|
based on its context. If there is no contextual type information for an
|
|
expression, all unresolved types are inferred to 'integer_literal_type'
|
|
type and floating point values to 'float_literal_type'. If a literal is
|
|
used and these types are not defined, then the code is malformed.</p>
|
|
|
|
<p>A literal is compatible with its inferred type if that type implements an
|
|
informal protocol required by literals. This informal protocol requires
|
|
that the type have an unambiguous metatype ("plus") function defined whose
|
|
result type is the same as the inferred type, and that takes a single
|
|
argument that is either itself literal compatible, or is a <a
|
|
href="#builtin">builtin</a> integer type.
|
|
</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>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-anon-closure-arg">Anonymous Closure Arguments</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-anon-closure-arg ::= <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>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-delayed-identifier">Delayed Identifier Resolution</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
The ":bar" syntax was picked because it is related to the syntax 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.</p>
|
|
|
|
<pre class="example">
|
|
oneof Direction { Up, Down }
|
|
func search(val : int, direction : Direction)
|
|
|
|
func f() {
|
|
search(42, :Up)
|
|
search(17, :Down)
|
|
}
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<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>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>Note that some enclosing productions restrict the <tt>lparen-any</tt> to a
|
|
<tt>lparen-unspaced</tt>.</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-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="#func-signature">func-signature</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 the function signature is omitted, it is implicitly <tt>() -> ()</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 < 2) return n;
|
|
return fib(n-1)+fib(n-2)
|
|
}
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-dot">Dot Expressions</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
"foo.$1" is a pretty ugly way to get to fields of a tuple, but we don't
|
|
want to use "foo[1]" (that would encourage people to use variable indexes)
|
|
and tuples should generally be accessed with pattern matching anyway.
|
|
</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>Otherwise, <a href="#namebind_value_lookup_dot">dot name lookup</a> is
|
|
performed, and this expression is treated as function application. This
|
|
allows looking up members in modules, metatypes, etc.</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 -> int -> int
|
|
...
|
|
h()(4)
|
|
|
|
<i>// Two separate statements</i>
|
|
i()
|
|
(j <+ 2)()
|
|
</pre>
|
|
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h2 id = "stmt">Statements</h2>
|
|
<!-- ********************************************************************* -->
|
|
|
|
<div class="commentary">
|
|
Statements can only exist in contexts that are themselves a stmt.
|
|
Statements have no type, they just induce control flow changes. We choose
|
|
to use constructs that will be familiar to a broad range of C/Java
|
|
programmers.
|
|
</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 provide the control flow constructs of function bodies and
|
|
top-level code.</p>
|
|
|
|
<pre class="example">
|
|
<i>// A function with some statements.</i>
|
|
func fib(v : int) -> int {
|
|
if v < 2 {
|
|
return v
|
|
}
|
|
return fib(v-1)+fib(v-2)
|
|
}
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="stmt-semicolon">Semicolon Statement</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
Allowing semicolons as statements causes us to allow semicolons as statement
|
|
separators as well. This, in turn, means that we don't reject code that has
|
|
semicolons after each statement, which will be common when people first
|
|
start getting used to Swift.
|
|
</div>
|
|
|
|
<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</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.
|
|
FIXME: The requirements for lvalues should be described, and tied into a
|
|
description of lvalue types.
|
|
</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>
|
|
</pre>
|
|
|
|
<p>The brace statement provides a sequencing operation which evaluates the
|
|
members of its body in order. Function bodies and the bodies of control
|
|
flow statements use braces. Also, the <a
|
|
href="#decl-translation-unit">translation unit</a> itself is effectively and
|
|
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>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
We require braces around the body of an 'if' for two reasons: first, it
|
|
eliminates the need for parentheses around the condition by making them
|
|
visually distinctive. Second, it will eliminate all the dithering about
|
|
whether and when people should, or should not, use braces for if bodies.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
stmt-if ::= 'if' <a href="#expr">expr</a> <a href="#stmt-brace">stmt-brace</a> stmt-if-else?
|
|
stmt-if-else ::= 'else' <a href="#stmt-brace">stmt-brace</a>
|
|
stmt-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. FIXME: revise this to work
|
|
more like literal handling.
|
|
</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="builtin">Builtin Module</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<p>In the initial Swift implementation, a module named <tt>Builtin</tt> is
|
|
imported into every file. Its declarations can only be found by <a
|
|
href="#expr-dot">dot syntax</a>. It provides access to a small
|
|
number of primitive representation types and operations defined over them
|
|
that map directly to LLVM IR.</p>
|
|
|
|
<p>The existance of and details of this module are a private implementation
|
|
detail used by our implementation of the standard library. Swift code
|
|
outside the standard library should not be aware of this library, and an
|
|
independent implementation of the swift standard library should be
|
|
allowed to be implemented without the builtin library if it desires.</p>
|
|
|
|
<p>For reference below, the description of the standard library uses the
|
|
"Builtin." namespace to refer to this module, but independent
|
|
implementations could use another implementation if they so desire.</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>
|
|
|
|
<div class="commentary">
|
|
Having a single standardized integer type that can be used by default
|
|
everywhere is important. One advantage Swift has is that by the time it is
|
|
in widespread use, 64-bit architectures will be pervasive, and the LLVM
|
|
optimizer should grow to be good at shrinking 64-bit integers to 32-bit in
|
|
many cases for those 32-bit architectures that persist.
|
|
</div>
|
|
|
|
<h4 id="stdlib-int">int, int8, int16, int32, int64</h4>
|
|
|
|
<pre class="stdlib">
|
|
<i>// Fixed size types are simple structs of the right size.</i>
|
|
struct int8 { value : Builtin.int8 }
|
|
struct int16 { value : Builtin.int16 }
|
|
struct int32 { value : Builtin.int32 }
|
|
struct int64 { value : Builtin.int64 }
|
|
|
|
<i>// int is just an alias for the 64-bit integer type.</i>
|
|
typealias int : int64
|
|
</pre>
|
|
|
|
<h4 id="stdlib-int">int, int8, int16, int32, int64</h4>
|
|
<pre class="stdlib">
|
|
struct float { value : Builtin.float32 }
|
|
struct double { value : Builtin.float64 }
|
|
</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>
|
|
|
|
<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) -> logic_value
|
|
func convertToLogicValue(v : bool) -> 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_left=200] * (lhs: int, rhs: int) -> int
|
|
func [infix_left=200] / (lhs: int, rhs: int) -> int
|
|
func [infix_left=200] % (lhs: int, rhs: int) -> int
|
|
func [infix_left=190] + (lhs: int, rhs: int) -> int
|
|
func [infix_left=190] - (lhs: int, rhs: int) -> int
|
|
<i>// In C, <<, >> is 180.</i>
|
|
</pre>
|
|
|
|
<h4 id="stdlib-comparison">Relational and Equality Operators</h4>
|
|
|
|
<pre class="stdlib">
|
|
func [infix_left=170] < : (lhs : int, rhs : int) -> bool
|
|
func [infix_left=170] > : (lhs : int, rhs : int) -> bool
|
|
func [infix_left=170] <= : (lhs : int, rhs : int) -> bool
|
|
func [infix_left=170] >= : (lhs : int, rhs : int) -> bool
|
|
func [infix_left=160] == : (lhs : int, rhs : int) -> bool
|
|
func [infix_left=160] != : (lhs : int, rhs : int) -> 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_left=120] && (lhs: bool, rhs: ()->bool) -> bool
|
|
func [infix_left=110] || (lhs: bool, rhs: ()->bool) -> 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>
|