Convert alt to match. Stop parsing alt
This commit is contained in:
parent
d3a9bb1bd4
commit
ecaf9e39c9
359 changed files with 2938 additions and 2915 deletions
40
doc/rust.md
40
doc/rust.md
|
@ -209,7 +209,7 @@ import export use mod
|
|||
The keywords in [source files](#source-files) are the following strings:
|
||||
|
||||
~~~~~~~~ {.keyword}
|
||||
alt again assert
|
||||
again assert
|
||||
break
|
||||
check class const copy
|
||||
drop
|
||||
|
@ -217,7 +217,7 @@ else enum export extern
|
|||
fail false fn for
|
||||
if impl import
|
||||
let log loop
|
||||
mod mut
|
||||
match mod mut
|
||||
pure
|
||||
return
|
||||
true trait type
|
||||
|
@ -956,7 +956,7 @@ An example of a predicate that uses an unchecked block:
|
|||
# import std::list::*;
|
||||
|
||||
fn pure_foldl<T, U: copy>(ls: list<T>, u: U, f: fn(&&T, &&U) -> U) -> U {
|
||||
alt ls {
|
||||
match ls {
|
||||
nil => u,
|
||||
cons(hd, tl) => f(hd, pure_foldl(*tl, f(hd, u), f))
|
||||
}
|
||||
|
@ -1156,7 +1156,7 @@ class file_descriptor {
|
|||
let mut name: option<~str>;
|
||||
}
|
||||
fn get_name() -> ~str {
|
||||
alt self.name {
|
||||
match self.name {
|
||||
none => fail ~"File has no name!",
|
||||
some(n) => n
|
||||
}
|
||||
|
@ -2171,21 +2171,21 @@ evaluated. If all `if` and `else if` conditions evaluate to `false`
|
|||
then any `else` block is executed.
|
||||
|
||||
|
||||
### Alternative expressions
|
||||
### Match expressions
|
||||
|
||||
~~~~~~~~{.ebnf .gram}
|
||||
alt_expr : "alt" expr '{' alt_arm [ '|' alt_arm ] * '}' ;
|
||||
match_expr : "match" expr '{' match_arm [ '|' match_arm ] * '}' ;
|
||||
|
||||
alt_arm : alt_pat '=>' expr_or_blockish ;
|
||||
match_arm : match_pat '=>' expr_or_blockish ;
|
||||
|
||||
alt_pat : pat [ "to" pat ] ? [ "if" expr ] ;
|
||||
match_pat : pat [ "to" pat ] ? [ "if" expr ] ;
|
||||
~~~~~~~~
|
||||
|
||||
|
||||
An `alt` expression branches on a *pattern*. The exact form of matching that
|
||||
A `match` expression branches on a *pattern*. The exact form of matching that
|
||||
occurs depends on the pattern. Patterns consist of some combination of
|
||||
literals, destructured enum constructors, records and tuples, variable binding
|
||||
specifications, wildcards (`*`), and placeholders (`_`). An `alt` expression has a *head
|
||||
specifications, wildcards (`*`), and placeholders (`_`). A `match` expression has a *head
|
||||
expression*, which is the value to compare to the patterns. The type of the
|
||||
patterns must equal the type of the head expression.
|
||||
|
||||
|
@ -2198,7 +2198,7 @@ enum list<X> { nil, cons(X, @list<X>) }
|
|||
|
||||
let x: list<int> = cons(10, @cons(11, @nil));
|
||||
|
||||
alt x {
|
||||
match x {
|
||||
cons(_, @nil) => fail ~"singleton list",
|
||||
cons(*) => return,
|
||||
nil => fail ~"empty list"
|
||||
|
@ -2210,13 +2210,13 @@ tail value of `@nil`. The second pattern matches `any` list constructed with `co
|
|||
ignoring the values of its arguments. The difference between `_` and `*` is that the pattern `C(_)` is only type-correct if
|
||||
`C` has exactly one argument, while the pattern `C(*)` is type-correct for any enum variant `C`, regardless of how many arguments `C` has.
|
||||
|
||||
To execute an `alt` expression, first the head expression is evaluated, then
|
||||
To execute an `match` expression, first the head expression is evaluated, then
|
||||
its value is sequentially compared to the patterns in the arms until a match
|
||||
is found. The first arm with a matching pattern is chosen as the branch target
|
||||
of the `alt`, any variables bound by the pattern are assigned to local
|
||||
of the `match`, any variables bound by the pattern are assigned to local
|
||||
variables in the arm's block, and control enters the block.
|
||||
|
||||
An example of an `alt` expression:
|
||||
An example of an `match` expression:
|
||||
|
||||
|
||||
~~~~
|
||||
|
@ -2227,7 +2227,7 @@ enum list<X> { nil, cons(X, @list<X>) }
|
|||
|
||||
let x: list<int> = cons(10, @cons(11, @nil));
|
||||
|
||||
alt x {
|
||||
match x {
|
||||
cons(a, @cons(b, _)) => {
|
||||
process_pair(a,b);
|
||||
}
|
||||
|
@ -2264,7 +2264,7 @@ fn main() {
|
|||
}
|
||||
};
|
||||
|
||||
alt r {
|
||||
match r {
|
||||
{options: {choose: true, _}, _} => {
|
||||
choose_player(r)
|
||||
}
|
||||
|
@ -2278,20 +2278,20 @@ fn main() {
|
|||
}
|
||||
~~~~
|
||||
|
||||
Multiple alternative patterns may be joined with the `|` operator. A
|
||||
Multiple match patterns may be joined with the `|` operator. A
|
||||
range of values may be specified with `to`. For example:
|
||||
|
||||
~~~~
|
||||
# let x = 2;
|
||||
|
||||
let message = alt x {
|
||||
let message = match x {
|
||||
0 | 1 => ~"not many",
|
||||
2 to 9 => ~"a few",
|
||||
_ => ~"lots"
|
||||
};
|
||||
~~~~
|
||||
|
||||
Finally, alt patterns can accept *pattern guards* to further refine the
|
||||
Finally, match patterns can accept *pattern guards* to further refine the
|
||||
criteria for matching a case. Pattern guards appear after the pattern and
|
||||
consist of a bool-typed expression following the `if` keyword. A pattern
|
||||
guard may refer to the variables bound within the pattern they follow.
|
||||
|
@ -2301,7 +2301,7 @@ guard may refer to the variables bound within the pattern they follow.
|
|||
# fn process_digit(i: int) { }
|
||||
# fn process_other(i: int) { }
|
||||
|
||||
let message = alt maybe_digit {
|
||||
let message = match maybe_digit {
|
||||
some(x) if x < 10 => process_digit(x),
|
||||
some(x) => process_other(x),
|
||||
none => fail
|
||||
|
|
|
@ -116,7 +116,7 @@ fn main() {
|
|||
let pick = || (~[rock, paper, scissors])[rng.gen_uint() % 3];
|
||||
|
||||
// Pick two gestures and decide the result
|
||||
alt (pick(), pick()) {
|
||||
match (pick(), pick()) {
|
||||
(rock, scissors) | (paper, rock) | (scissors, paper) => copy player1,
|
||||
(scissors, rock) | (rock, paper) | (paper, scissors) => copy player2,
|
||||
_ => ~"tie"
|
||||
|
@ -707,14 +707,14 @@ have type `int`, because control doesn't reach the end of that arm
|
|||
|
||||
## Pattern matching
|
||||
|
||||
Rust's `alt` construct is a generalized, cleaned-up version of C's
|
||||
Rust's `match` construct is a generalized, cleaned-up version of C's
|
||||
`switch` construct. You provide it with a value and a number of arms,
|
||||
each labelled with a pattern, and it will execute the arm that matches
|
||||
the value.
|
||||
|
||||
~~~~
|
||||
# let my_number = 1;
|
||||
alt my_number {
|
||||
match my_number {
|
||||
0 => io::println(~"zero"),
|
||||
1 | 2 => io::println(~"one or two"),
|
||||
3 to 10 => io::println(~"three to ten"),
|
||||
|
@ -732,14 +732,14 @@ valid patterns, and will match only their own value. The pipe operator
|
|||
of numeric literal patterns can be expressed with `to`. The underscore
|
||||
(`_`) is a wildcard pattern that matches everything.
|
||||
|
||||
The patterns in an alt arm are followed by a fat arrow, `=>`, then an
|
||||
The patterns in an match arm are followed by a fat arrow, `=>`, then an
|
||||
expression to evaluate. Each case is separated by commas. It's often
|
||||
convenient to use a block expression for a case, in which case the
|
||||
commas are optional.
|
||||
|
||||
~~~
|
||||
# let my_number = 1;
|
||||
alt my_number {
|
||||
match my_number {
|
||||
0 => {
|
||||
io::println(~"zero")
|
||||
}
|
||||
|
@ -750,9 +750,9 @@ alt my_number {
|
|||
~~~
|
||||
|
||||
If the arm with the wildcard pattern was left off in the above
|
||||
example, the typechecker would reject it at compile time. `alt`
|
||||
example, the typechecker would reject it at compile time. `match`
|
||||
constructs must be exhaustive: they must have an arm covering every
|
||||
possible case. (You may use the `alt check` construct to write a
|
||||
possible case. (You may use the `match check` construct to write a
|
||||
non-exhaustive match, but it's highly undesirable to do so. You may
|
||||
reason that the missing cases will never occur, but the typechecker
|
||||
provides you with no assurance that your reasoning is correct.)
|
||||
|
@ -763,7 +763,7 @@ that `(float, float)` is a tuple of two floats:
|
|||
|
||||
~~~~
|
||||
fn angle(vec: (float, float)) -> float {
|
||||
alt vec {
|
||||
match vec {
|
||||
(0f, y) if y < 0f => 1.5 * float::consts::pi,
|
||||
(0f, y) => 0.5 * float::consts::pi,
|
||||
(x, y) => float::atan(y / x)
|
||||
|
@ -777,7 +777,7 @@ y)` matches any tuple whose first element is zero, and binds `y` to
|
|||
the second element. `(x, y)` matches any tuple, and binds both
|
||||
elements to a variable.
|
||||
|
||||
Any `alt` arm can have a guard clause (written `if EXPR`), which is
|
||||
Any `match` arm can have a guard clause (written `if EXPR`), which is
|
||||
an expression of type `bool` that determines, after the pattern is
|
||||
found to match, whether the arm is taken or not. The variables bound
|
||||
by the pattern are available in this guard expression.
|
||||
|
@ -851,7 +851,7 @@ task failure:
|
|||
|
||||
* Accessing an out-of-bounds element of a vector.
|
||||
|
||||
* Having no clauses match when evaluating an `alt check` expression.
|
||||
* Having no clauses match when evaluating an `match check` expression.
|
||||
|
||||
* An assertion failure.
|
||||
|
||||
|
@ -1044,14 +1044,14 @@ not an actual new type.)
|
|||
|
||||
## Record patterns
|
||||
|
||||
Records can be destructured in `alt` patterns. The basic syntax is
|
||||
Records can be destructured in `match` patterns. The basic syntax is
|
||||
`{fieldname: pattern, ...}`, but the pattern for a field can be
|
||||
omitted as a shorthand for simply binding the variable with the same
|
||||
name as the field.
|
||||
|
||||
~~~~
|
||||
# let mypoint = {x: 0f, y: 0f};
|
||||
alt mypoint {
|
||||
match mypoint {
|
||||
{x: 0f, y: y_name} => { /* Provide sub-patterns for fields */ }
|
||||
{x, y} => { /* Simply bind the fields */ }
|
||||
}
|
||||
|
@ -1157,7 +1157,7 @@ patterns, as in this definition of `area`:
|
|||
# type point = {x: float, y: float};
|
||||
# enum shape { circle(point, float), rectangle(point, point) }
|
||||
fn area(sh: shape) -> float {
|
||||
alt sh {
|
||||
match sh {
|
||||
circle(_, size) => float::consts::pi * size * size,
|
||||
rectangle({x, y}, {x: x2, y: y2}) => (x2 - x) * (y2 - y)
|
||||
}
|
||||
|
@ -1170,7 +1170,7 @@ Another example, matching nullary enum variants:
|
|||
# type point = {x: float, y: float};
|
||||
# enum direction { north, east, south, west }
|
||||
fn point_from_direction(dir: direction) -> point {
|
||||
alt dir {
|
||||
match dir {
|
||||
north => {x: 0f, y: 1f},
|
||||
east => {x: 1f, y: 0f},
|
||||
south => {x: 0f, y: -1f},
|
||||
|
@ -1188,7 +1188,7 @@ nil, `()`, as the empty tuple if you like).
|
|||
|
||||
~~~~
|
||||
let mytup: (int, int, float) = (10, 20, 30.0);
|
||||
alt mytup {
|
||||
match mytup {
|
||||
(a, b, c) => log(info, a + b + (c as int))
|
||||
}
|
||||
~~~~
|
||||
|
@ -1922,7 +1922,7 @@ gets access to them.
|
|||
## Other uses of safe references
|
||||
|
||||
Safe references are not only used for argument passing. When you
|
||||
destructure on a value in an `alt` expression, or loop over a vector
|
||||
destructure on a value in a `match` expression, or loop over a vector
|
||||
with `for`, variables bound to the inside of the given data structure
|
||||
will use safe references, not copies. This means such references are
|
||||
very cheap, but you'll occasionally have to copy them to ensure
|
||||
|
@ -1930,7 +1930,7 @@ safety.
|
|||
|
||||
~~~~
|
||||
let mut my_rec = {a: 4, b: ~[1, 2, 3]};
|
||||
alt my_rec {
|
||||
match my_rec {
|
||||
{a, b} => {
|
||||
log(info, b); // This is okay
|
||||
my_rec = {a: a + 1, b: b + ~[a]};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue