mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
1595 lines
63 KiB
HTML
1595 lines
63 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-apply">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>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
TODO: /**/ comments will be supported when I get around to it.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
whitespace ::= ' '
|
|
whitespace ::= '\n'
|
|
whitespace ::= '\r'
|
|
whitespace ::= '\t'
|
|
whitespace ::= '\0'
|
|
comment ::= //.*[\n\r]
|
|
</pre>
|
|
|
|
<p>Space, newline, tab, and the nul byte are all considered whitespace and are
|
|
discarded.</p>
|
|
|
|
<p>Comments follow the BCPL style, starting with a "//" and running to the end
|
|
of the file. Comments are ignored 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">
|
|
punctuation ::= '('
|
|
punctuation ::= ')'
|
|
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. 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 ::= 'meth'
|
|
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]*
|
|
identifier ::= [/=-+*%<>!&|^]+
|
|
</pre>
|
|
|
|
<p>There are two different regular expressions for identifiers, one for normal
|
|
identifiers and one for "punctuation identifiers". This ensures that
|
|
something like "foo+bar" gets lexed into three identifiers, not one. Aside
|
|
from the regex that controls lexing behavior, there is no other difference
|
|
between these two forms of identifiers.
|
|
</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<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">
|
|
translation-unit ::= top-level-item*
|
|
top-level-item ::= ';'
|
|
top-level-item ::= <a href="#decl-import">decl-import</a>
|
|
top-level-item ::= <a href="#decl-var">decl-var</a>
|
|
top-level-item ::= <a href="#decl-func">decl-func</a>
|
|
top-level-item ::= <a href="#decl-meth">decl-meth</a>
|
|
top-level-item ::= <a href="#decl-typealias">decl-typealias</a>
|
|
top-level-item ::= <a href="#decl-oneof">decl-oneof</a>
|
|
top-level-item ::= <a href="#decl-struct">decl-struct</a>
|
|
top-level-item ::= <a href="#expr">expr</a>
|
|
</pre>
|
|
|
|
<p>A source file in Swift is parsed as a list of top level declarations.
|
|
Extraneous semi colons are allowed at top level, as are a number of other
|
|
declarations.</p>
|
|
|
|
<p>TODO: Need to define the module system more.</p>
|
|
|
|
<p>Expressions at the top level of a file are executed at program startup time
|
|
in bottom-up order in the module dependence graph. This
|
|
becomes a static constructor for a library and is the "main" for an
|
|
executable. This allows 'print "hello world"' to work as a complete app.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-import">import</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
decl-import ::= 'import' attribute-list? identifier ('.' 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.</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</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
Eventually need to add support for "var x,y : int".
|
|
</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.</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">identifier</a>
|
|
var-name ::= '(' ')'
|
|
var-name ::= '(' 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) -> 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</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
decl-func ::= 'func' <a href="#attribute-list">attribute-list</a>? <a href="#identifier">identifier</a> <a href="#type">type</a> '=' <a href="#expr">expr</a>
|
|
decl-func ::= 'func' <a href="#attribute-list">attribute-list</a>? <a href="#identifier">identifier</a> <a href="#type">type</a> <a href="#brace-expr">brace-expr</a>
|
|
decl-func ::= 'func' <a href="#attribute-list">attribute-list</a>? <a href="#identifier">identifier</a> <a href="#type">type</a>
|
|
</pre>
|
|
|
|
<p>A 'func' declaration is just shorthand syntax for the (extremely) common
|
|
case of a declaration of function value. 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 an arbitrary expression. If the argument
|
|
type is not a function type, 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>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>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 b() -> void {}
|
|
|
|
<i>// Really simple function</i>
|
|
func c(arg : int) -> void = arg+4
|
|
|
|
<i>// Simple operator.</i>
|
|
func [infix=120] + (lhs: int, rhs: int) -> int;
|
|
|
|
<i>// Function with multiple return values:</i>
|
|
func d(a : int) -> (b : int) -> (res1 : int, res2 : int);
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-meth">meth</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
'meth' syntax is shorthand for defining a function that can be used with
|
|
dot syntax on the receiver type.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
decl-meth ::= 'meth' <a href="#attribute-list">attribute-list</a>? <a href="#type-identifier">type-identifier</a> '::' <a href="#identifier">identifier</a> <a href="#type">type</a> <a href="#brace-expr">brace-expr</a>?
|
|
</pre>
|
|
|
|
<p>A 'meth' declaration is shorthand syntax for declaring a 'func' with a
|
|
compound function type. 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 an arbitrary expression. If the argument
|
|
type is not a function type, 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. The initial first
|
|
argument is of the type specified before the '::'.</p>
|
|
|
|
<p>'meth' declarations may not be declared infix.</p>
|
|
|
|
<p>Here are some examples of meth definitions:</p>
|
|
|
|
<pre class="example">
|
|
<i>// Implicitly returns (), aka <a href="#stdlib-void">void</a></i>.
|
|
<i>// This declares a function 'a' of type "t1 -> () -> ()".</i>
|
|
meth t1::a() {}
|
|
|
|
<i>// Same as 'a'</i>
|
|
meth t1::a() -> void {}
|
|
|
|
<i>// A simple method on a trivial type.</i>
|
|
struct bankaccount { amount : int }
|
|
func bankaccount::deposit(arg : int) {
|
|
amount = amount + arg
|
|
}
|
|
</pre>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-typealias">typealias</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 -> 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> is just syntactic sugar for a <a
|
|
href="#type-oneof">oneof type</a> and a 'typealias'.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-oneof">oneof</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> oneof-body
|
|
</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 -> 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</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.
|
|
FIXME: Describe requirements on function/var it is applied to, must be binary
|
|
etc.</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 ::= '(' 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) -> (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>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". 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-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>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>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<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 and separation of parsing from type
|
|
analysis and name binding leads to a somewhat unusual system where
|
|
expression parsing just doesn't do very much. This does lead to interesting
|
|
phases of translation though, because we do "parsing" of expressions late
|
|
(in type checking) instead of right after lexing.<br><br>
|
|
|
|
Semicolons in C are generally just clutter. Swift generally defines away
|
|
their use through the type system (and careful grammar structure).<br><br>
|
|
|
|
Brace expressions don't fit naturally into the grammar anymore, because we
|
|
don't want them in some places (e.g. the condition of an 'if'). 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 ::= expr-primary+
|
|
expr-non-brace ::= expr-primary-non-brace+
|
|
|
|
expr-primary ::= expr-non-brace | <a href="#expr-brace">expr-brace</a>
|
|
expr-primary-non-brace ::= <a href="#expr-literal">expr-literal</a>
|
|
expr-primary-non-brace ::= <a href="#expr-identifier">expr-identifier</a>
|
|
expr-primary-non-brace ::= <a href="#expr-paren">expr-paren</a>
|
|
expr-primary-non-brace ::= <a href="#expr-delayed-identifier">expr-delayed-identifier</a>
|
|
expr-primary-non-brace ::= <a href="#expr-dot">expr-dot</a>
|
|
expr-primary-non-brace ::= <a href="#expr-subscript">expr-subscript</a>
|
|
|
|
expr-primary-non-brace ::= <a href="#expr-if">expr-if</a>
|
|
</pre>
|
|
|
|
<p>At the top level of the expression grammar, expressions are a sequence of
|
|
"primary" expressions.</p>
|
|
|
|
<pre class="example">
|
|
<i>// A silly, but valid, example of a single 'expr':</i>
|
|
4 4 (4+5) 4 4
|
|
|
|
<i>// A more reasonable example:</i>
|
|
foo()
|
|
x = 12
|
|
bar(49+1)
|
|
baz()
|
|
</i>
|
|
|
|
<i>// An example that is parsed as one list of three primary expressions,
|
|
// but is resolved in type checking to a var decl followed by a separate
|
|
// apply expression.</i>
|
|
var x = 4 foo()
|
|
</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">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-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-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-primary</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-primary</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-primary</a> '[' <a href="#expr-single">expr-single</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-paren">Parenthesized Expressions</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-paren ::= '(' ')'
|
|
expr-paren ::= '(' 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>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-brace">Brace Literals</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-brace ::= '{' expr-brace-item* '}'
|
|
expr-brace-item ::= ';'
|
|
expr-brace-item ::= <a href="#expr">expr</a>
|
|
expr-brace-item ::= <a href="#decl-var">decl-var</a>
|
|
expr-brace-item ::= <a href="#decl-func">decl-func</a>
|
|
expr-brace-item ::= <a href="#decl-typealias">decl-typealias</a>
|
|
expr-brace-item ::= <a href="#decl-oneof">decl-oneof</a>
|
|
expr-brace-item ::= <a href="#decl-struct">decl-struct</a>
|
|
</pre>
|
|
|
|
|
|
<p>FIXME: Need to kill off "the result of {} is the result of the last expr if
|
|
it doesn't have a ; at the end. Add return statement instead.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-apply">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-apply ::= <a href="#expr">expr</a> <a href="#expr">expr</a>
|
|
</pre>
|
|
|
|
<p>Juxtaposition of two expressions, when the former is of function type, is
|
|
application of a function to its argument, and the argument is converted to
|
|
the expected argument type. For example, "foo()" is a juxtaposition of the
|
|
foo expression with an empty tuple.</p>
|
|
|
|
<p>This expression is not formed by the parser, it is formed by the type
|
|
checker when it is processing consequtive sequences of primary expressions and
|
|
finds something of function type.</p>
|
|
|
|
<p>A simple example:</p>
|
|
|
|
<pre class="example">
|
|
<i>// Application of an empty tuple to the function f.</i>
|
|
f ()
|
|
<i>// Application of 4 to the function f, both are equivalent.</i>
|
|
g 4
|
|
g (4)
|
|
|
|
<i>// Application of 4 to the function returned by h().</i>
|
|
var h : int -> int -> int;
|
|
...
|
|
h () 4
|
|
|
|
<i>// Application of "{}" to the function returned by the result of
|
|
// applying "(x)" to "if".</i>
|
|
if (x) {}
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-infix">Infix Binary Expressions</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-infix ::= expr identifier expr
|
|
</pre>
|
|
|
|
<p>Infix binary expressions are not formed during parsing, they are formed
|
|
during type checking, when a sequence of primary expressions is being type
|
|
checked and a value with the <a href="#attribute-infix">infix</a> attribute
|
|
is found. The order of evaluation of the various subexpressions is defined by
|
|
the precedence of the infix attribute.
|
|
</p>
|
|
|
|
<p>TODO: Should this use the expr-identifier production to allow qualified
|
|
identifiers? This would allow "foo swift::min 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 min 42
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-if">'if' Expression</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-if ::= 'if' expr-non-brace brace-expr expr-if-else?
|
|
expr-if-else ::= 'else' brace-expr
|
|
expr-if-else ::= 'else' expr-if
|
|
</pre>
|
|
|
|
<p>'if' expressions 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' expression. The result type of an 'if'
|
|
expression is always '()', and the brace-expr operands are always forced to
|
|
'()' type.
|
|
</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>
|
|
|
|
<!-- ********************************************************************* -->
|
|
<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) -> 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=200] * (lhs: int, rhs: int) -> int
|
|
func [infix=200] / (lhs: int, rhs: int) -> int
|
|
func [infix=200] % (lhs: int, rhs: int) -> int
|
|
func [infix=190] + (lhs: int, rhs: int) -> int
|
|
func [infix=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">
|
|
var [infix=170] < : (lhs : int, rhs : int) -> bool
|
|
var [infix=170] > : (lhs : int, rhs : int) -> bool
|
|
var [infix=170] <= : (lhs : int, rhs : int) -> bool
|
|
var [infix=170] >= : (lhs : int, rhs : int) -> bool
|
|
var [infix=160] == : (lhs : int, rhs : int) -> bool
|
|
var [infix=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=120] && (lhs: bool, rhs: ()->bool) -> bool
|
|
func [infix=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> |