OLD | NEW |
1 \documentclass{article} | 1 \documentclass{article} |
2 \usepackage{epsfig} | 2 \usepackage{epsfig} |
3 \usepackage{color} | 3 \usepackage{color} |
4 \usepackage{dart} | 4 \usepackage{dart} |
5 \usepackage{bnf} | 5 \usepackage{bnf} |
6 \usepackage{hyperref} | 6 \usepackage{hyperref} |
7 \usepackage{lmodern} | 7 \usepackage{lmodern} |
8 \newcommand{\code}[1]{{\sf #1}} | 8 \newcommand{\code}[1]{{\sf #1}} |
9 \title{Dart Programming Language Specification \\ | 9 \title{Dart Programming Language Specification \\ |
10 {\large Version 1.10}} | 10 {\large Version 1.10}} |
(...skipping 5723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5734 \LMHash{} | 5734 \LMHash{} |
5735 The {\em switch statement} supports dispatching control among a large number of
cases. | 5735 The {\em switch statement} supports dispatching control among a large number of
cases. |
5736 | 5736 |
5737 \begin{grammar} | 5737 \begin{grammar} |
5738 {\bf switchStatement:} | 5738 {\bf switchStatement:} |
5739 \SWITCH{} `(' expression `)' `\{' switchCase* defaultCase? `\}'% could do
top level here and in cases | 5739 \SWITCH{} `(' expression `)' `\{' switchCase* defaultCase? `\}'% could do
top level here and in cases |
5740 . | 5740 . |
5741 | 5741 |
5742 | 5742 |
5743 {\bf switchCase:} | 5743 {\bf switchCase:} |
5744 label* (\CASE{} expression `{\escapegrammar :}') statements | 5744 label* \CASE{} expression `{\escapegrammar :}' statements |
5745 . | 5745 . |
5746 | 5746 |
5747 {\bf defaultCase:} | 5747 {\bf defaultCase:} |
5748 label* \DEFAULT{} `{\escapegrammar :}' statements | 5748 label* \DEFAULT{} `{\escapegrammar :}' statements |
5749 . | 5749 . |
5750 \end{grammar} | 5750 \end{grammar} |
5751 | 5751 |
5752 \LMHash{} | 5752 \LMHash{} |
5753 Given a switch statement of the form | 5753 Given a switch statement of the form |
5754 | 5754 |
5755 \begin{dartCode} | 5755 \begin{dartCode} |
5756 \SWITCH{} ($e$) \{ | 5756 \SWITCH{} ($e$) \{ |
5757 \CASE{} $label_{11} \ldots label_{1j_1}$ $e_1: s_1$ | 5757 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5758 $\ldots$ | 5758 $\ldots$ |
5759 \CASE{} $label_{n1} \ldots label_{nj_n}$ $e_n: s_n$ | 5759 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5760 \DEFAULT{}: $s_{n+1}$ | 5760 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ |
5761 \} | 5761 \} |
5762 \end{dartCode} | 5762 \end{dartCode} |
5763 | 5763 |
5764 or the form | 5764 or the form |
5765 | 5765 |
5766 \begin{dartCode} | 5766 \begin{dartCode} |
5767 \SWITCH{} ($e$) \{ | 5767 \SWITCH{} ($e$) \{ |
5768 \CASE{} $label_{11} \ldots label_{1j_1}$ $e_1: s_1$ | 5768 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5769 $\ldots$ | 5769 $\ldots$ |
5770 \CASE{} $label_{n1} \ldots label_{nj_n}$ $e_n: s_n$ | 5770 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5771 \} | 5771 \} |
5772 \end{dartCode} | 5772 \end{dartCode} |
5773 | 5773 |
5774 it is a compile-time error if the expressions $e_k$ are not compile-time consta
nts for all $k \in 1..n$. It is a compile-time error if the values of the expr
essions $e_k$ are not either: | 5774 it is a compile-time error if the expressions $e_k$ are not compile-time consta
nts for all $k \in 1..n$. It is a compile-time error if the values of the expr
essions $e_k$ are not either: |
5775 \begin{itemize} | 5775 \begin{itemize} |
5776 \item instances of the same class $C$, for all $k \in 1..n$, or | 5776 \item instances of the same class $C$, for all $k \in 1..n$, or |
5777 \item instances of a class that implements \cd{int}, for all $k \in 1..n$, or | 5777 \item instances of a class that implements \cd{int}, for all $k \in 1..n$, or |
5778 \item instances of a class that implements \cd{String}, for all $k \in 1..n$. | 5778 \item instances of a class that implements \cd{String}, for all $k \in 1..n$. |
5779 \end{itemize} | 5779 \end{itemize} |
5780 | 5780 |
5781 \commentary{In other words, all the expressions in the cases evaluate to consta
nts of the exact same user defined class or are of certain known types. Note th
at the values of the expressions are known at compile-time, and are independent
of any static type annotations. | 5781 \commentary{In other words, all the expressions in the cases evaluate to consta
nts of the exact same user defined class or are of certain known types. Note th
at the values of the expressions are known at compile-time, and are independent
of any static type annotations. |
5782 } | 5782 } |
5783 | 5783 |
5784 \LMHash{} | 5784 \LMHash{} |
5785 It is a compile-time error if the class $C$ has an implementation of the operato
r $==$ other than the one inherited from \code{Object} unless the value of the e
xpression is a string, an integer, literal symbol or the result of invoking a co
nstant constructor of class \cd{Symbol}. | 5785 It is a compile-time error if the class $C$ has an implementation of the operato
r $==$ other than the one inherited from \code{Object} unless the value of the e
xpression is a string, an integer, literal symbol or the result of invoking a co
nstant constructor of class \cd{Symbol}. |
5786 | 5786 |
5787 \rationale{ | 5787 \rationale{ |
5788 The prohibition on user defined equality allows us to implement the switch effi
ciently for user defined types. We could formulate matching in terms of identity
instead with the same efficiency. However, if a type defines an equality operat
or, programmers would find it quite surprising that equal objects did not match. | 5788 The prohibition on user defined equality allows us to implement the switch effi
ciently for user defined types. We could formulate matching in terms of identity
instead with the same efficiency. However, if a type defines an equality operat
or, programmers would find it quite surprising that equal objects did not match. |
5789 | 5789 |
5790 } | 5790 } |
5791 | 5791 |
5792 \commentary{ | 5792 \commentary{ |
5793 The \SWITCH{} statement should only be used in very limited situations (e.g., i
nterpreters or scanners). | 5793 The \SWITCH{} statement should only be used in very limited situations (e.g., i
nterpreters or scanners). |
5794 } | 5794 } |
5795 | 5795 |
5796 \LMHash{} | 5796 \LMHash{} |
5797 Execution of a switch statement of the form | 5797 Execution of a switch statement of the form |
5798 | 5798 |
5799 \begin{dartCode} | 5799 \begin{dartCode} |
5800 \SWITCH{} ($e$) \{ | 5800 \SWITCH{} ($e$) \{ |
5801 \CASE{} $label_{11} \ldots label_{1j_1}$ $e_1: s_1$ | 5801 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5802 $\ldots$ | 5802 $\ldots$ |
5803 \CASE{} $label_{n1} \ldots label_{nj_n}$ $e_n: s_n$ | 5803 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5804 \DEFAULT{}: $s_{n+1}$ | 5804 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ |
5805 \} | 5805 \} |
5806 \end{dartCode} | 5806 \end{dartCode} |
5807 | 5807 |
5808 or the form | 5808 or the form |
5809 | 5809 |
5810 \begin{dartCode} | 5810 \begin{dartCode} |
5811 \SWITCH{} ($e$) \{ | 5811 \SWITCH{} ($e$) \{ |
5812 \CASE{} $label_{11} \ldots label_{1j_1}$ $e_1: s_1$ | 5812 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5813 $\ldots$ | 5813 $\ldots$ |
5814 \CASE{} $label_{n1} \ldots label_{nj_n}$ $e_n: s_n$ | 5814 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5815 \} | 5815 \} |
5816 \end{dartCode} | 5816 \end{dartCode} |
5817 | 5817 |
5818 proceeds as follows: | 5818 proceeds as follows: |
5819 | 5819 |
5820 \LMHash{} | 5820 \LMHash{} |
5821 The statement \code{\VAR{} id = $e$;} is evaluated, where \code{id} is a variabl
e whose name is distinct from any other variable in the program. In checked mode
, it is a run time error if the value of $e$ is not an instance of the same clas
s as the constants $e_1 \ldots e_n$. | 5821 The statement \code{\VAR{} id = $e$;} is evaluated, where \code{id} is a variabl
e whose name is distinct from any other variable in the program. In checked mode
, it is a run time error if the value of $e$ is not an instance of the same clas
s as the constants $e_1 \ldots e_n$. |
5822 | 5822 |
5823 \commentary{Note that if there are no case clauses ($n = 0$), the type of $e$ do
es not matter.} | 5823 \commentary{Note that if there are no case clauses ($n = 0$), the type of $e$ do
es not matter.} |
5824 | 5824 |
5825 \LMHash{} | 5825 \LMHash{} |
5826 Next, the case clause \CASE{} $e_{1}: s_{1}$ is executed if it exists. If \CASE{
} $e_{1}: s_{1}$ does not exist, then if there is a \DEFAULT{} clause it is exe
cuted by executing $s_{n+1}$. | 5826 Next, the case clause \CASE{} $e_{1}: s_{1}$ is executed if it exists. If \CASE{
} $e_{1}: s_{1}$ does not exist, then if there is a \DEFAULT{} clause it is exe
cuted by executing $s_{n+1}$. |
5827 | 5827 |
5828 \LMHash{} | 5828 \LMHash{} |
5829 A case clause introduces a new scope, nested in the lexically surrounding scope.
The scope of a case clause ends immediately after the case clause's statement l
ist. | 5829 A case clause introduces a new scope, nested in the lexically surrounding scope.
The scope of a case clause ends immediately after the case clause's statement l
ist. |
5830 | 5830 |
5831 \LMHash{} | 5831 \LMHash{} |
5832 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement | 5832 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement |
5833 | 5833 |
5834 \begin{dartCode} | 5834 \begin{dartCode} |
5835 \SWITCH{} ($e$) \{ | 5835 \SWITCH{} ($e$) \{ |
5836 \CASE{} $label_{11} \ldots label_{1j_1}$ $e_1: s_1$ | 5836 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5837 $\ldots$ | 5837 $\ldots$ |
5838 \CASE{} $label_{n1} \ldots label_{nj_n}$ $e_n: s_n$ | 5838 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5839 \DEFAULT{}: $s_{n+1}$ | 5839 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ |
5840 \} | 5840 \} |
5841 \end{dartCode} | 5841 \end{dartCode} |
5842 | 5842 |
5843 proceeds as follows: | 5843 proceeds as follows: |
5844 | 5844 |
5845 \LMHash{} | 5845 \LMHash{} |
5846 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su
bjected to boolean conversion yielding a value $v$. | 5846 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su
bjected to boolean conversion yielding a value $v$. |
5847 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut
ed if it exists. If \CASE{} $e_{k+1}: s_{k+1}$ does not exist, then the \DEFAUL
T{} clause is executed by executing $s_{n+1}$. | 5847 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut
ed if it exists. If \CASE{} $e_{k+1}: s_{k+1}$ does not exist, then the \DEFAUL
T{} clause is executed by executing $s_{n+1}$. |
5848 If $v$ is \TRUE{}, let $h$ be the smallest number such that $h \ge k$ and $s_h
$ is non-empty. If no such $h$ exists, let $h = n + 1$. The sequence of stateme
nts $s_h$ is then executed. | 5848 If $v$ is \TRUE{}, let $h$ be the smallest number such that $h \ge k$ and $s_h
$ is non-empty. If no such $h$ exists, let $h = n + 1$. The sequence of stateme
nts $s_h$ is then executed. |
5849 If execution reaches the point after $s_h$ then a runtime error occurs, unless
$h = n+1$. | 5849 If execution reaches the point after $s_h$ then a runtime error occurs, unless
$h = n+1$. |
5850 | 5850 |
5851 \LMHash{} | 5851 \LMHash{} |
5852 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement | 5852 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement |
5853 | 5853 |
5854 \begin{dartCode} | 5854 \begin{dartCode} |
5855 \SWITCH{} ($e$) \{ | 5855 \SWITCH{} ($e$) \{ |
5856 \CASE{} $label_{11} \ldots label_{1j_1}$ $e_1: s_1$ | 5856 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5857 $\ldots$ | 5857 $\ldots$ |
5858 \CASE{} $label_{n1} \ldots label_{nj_n}$ $e_n: s_n$ | 5858 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5859 \} | 5859 \} |
5860 \end{dartCode} | 5860 \end{dartCode} |
5861 | 5861 |
5862 proceeds as follows: | 5862 proceeds as follows: |
5863 | 5863 |
5864 \LMHash{} | 5864 \LMHash{} |
5865 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su
bjected to boolean conversion yielding a value $v$. | 5865 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su
bjected to boolean conversion yielding a value $v$. |
5866 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut
ed if it exists. | 5866 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut
ed if it exists. |
5867 If $v$ is \TRUE{}, let $h$ be the smallest integer such that $h \ge k$ and $s_
h$ is non-empty. The sequence of statements $s_h$ is executed if it exists. | 5867 If $v$ is \TRUE{}, let $h$ be the smallest integer such that $h \ge k$ and $s_
h$ is non-empty. The sequence of statements $s_h$ is executed if it exists. |
5868 If execution reaches the point after $s_h$ then a runtime error occurs, unless
$h = n$. | 5868 If execution reaches the point after $s_h$ then a runtime error occurs, unless
$h = n$. |
5869 | 5869 |
5870 | 5870 |
5871 \commentary{ | 5871 \commentary{ |
5872 In other words, there is no implicit fall-through between cases. The last case i
n a switch (default or otherwise) can `fall-through' to the end of the statement
. | 5872 In other words, there is no implicit fall-through between non-empty cases. The l
ast case in a switch (default or otherwise) can `fall-through' to the end of the
statement. |
5873 } | 5873 } |
5874 | 5874 |
5875 \LMHash{} | 5875 \LMHash{} |
5876 It is a static warning if the type of $e$ may not be assigned to the type of $e_
k$. It is a static warning if the last statement of the statement sequence $s_k$
is not a \BREAK{}, \CONTINUE{}, \RETURN{} or \THROW{} statement. | 5876 It is a static warning if the type of $e$ may not be assigned to the type of $e_
k$. It is a static warning if the last statement of the statement sequence $s_k$
is not a \BREAK{}, \CONTINUE{}, \RETURN{} or \THROW{} statement. |
5877 | 5877 |
5878 \rationale{ | 5878 \rationale{ |
5879 The behavior of switch cases intentionally differs from the C tradition. Implic
it fall through is a known cause of programming errors and therefore disallowed.
Why not simply break the flow implicitly at the end of every case, rather than
requiring explicit code to do so? This would indeed be cleaner. It would also
be cleaner to insist that each case have a single (possibly compound) statement
. We have chosen not to do so in order to facilitate porting of switch statemen
ts from other languages. Implicitly breaking the control flow at the end of a c
ase would silently alter the meaning of ported code that relied on fall-through,
potentially forcing the programmer to deal with subtle bugs. Our design ensures
that the difference is immediately brought to the coder's attention. The progr
ammer will be notified at compile-time if they forget to end a case with a state
ment that terminates the straight-line control flow. We could make this warning
a compile-time error, but refrain from doing so because do not wish to force the
programmer to deal with this issue immediately while porting code. If develope
rs ignore the warning and run their code, a run time error will prevent the prog
ram from misbehaving in hard-to-debug ways (at least with respect to this issue)
. | 5879 The behavior of switch cases intentionally differs from the C tradition. Implic
it fall through is a known cause of programming errors and therefore disallowed.
Why not simply break the flow implicitly at the end of every case, rather than
requiring explicit code to do so? This would indeed be cleaner. It would also
be cleaner to insist that each case have a single (possibly compound) statement
. We have chosen not to do so in order to facilitate porting of switch statemen
ts from other languages. Implicitly breaking the control flow at the end of a c
ase would silently alter the meaning of ported code that relied on fall-through,
potentially forcing the programmer to deal with subtle bugs. Our design ensures
that the difference is immediately brought to the coder's attention. The progr
ammer will be notified at compile-time if they forget to end a case with a state
ment that terminates the straight-line control flow. We could make this warning
a compile-time error, but refrain from doing so because do not wish to force the
programmer to deal with this issue immediately while porting code. If develope
rs ignore the warning and run their code, a run time error will prevent the prog
ram from misbehaving in hard-to-debug ways (at least with respect to this issue)
. |
5880 | 5880 |
5881 The sophistication of the analysis of fall-through is another issue. For now, we
have opted for a very straightforward syntactic requirement. There are obviousl
y situations where code does not fall through, and yet does not conform to these
simple rules, e.g.: | 5881 The sophistication of the analysis of fall-through is another issue. For now, we
have opted for a very straightforward syntactic requirement. There are obviousl
y situations where code does not fall through, and yet does not conform to these
simple rules, e.g.: |
5882 } | 5882 } |
(...skipping 1921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7804 | 7804 |
7805 The invariant that each normative paragraph is associated with a line | 7805 The invariant that each normative paragraph is associated with a line |
7806 containing the text \LMHash{} should be maintained. Extra occurrences | 7806 containing the text \LMHash{} should be maintained. Extra occurrences |
7807 of \LMHash{} can be added if needed, e.g., in order to make | 7807 of \LMHash{} can be added if needed, e.g., in order to make |
7808 individual \item{}s in itemized lists addressable. Each \LM.. command | 7808 individual \item{}s in itemized lists addressable. Each \LM.. command |
7809 must occur on a separate line. \LMHash{} must occur immediately | 7809 must occur on a separate line. \LMHash{} must occur immediately |
7810 before the associated paragraph, and \LMLabel must occur immediately | 7810 before the associated paragraph, and \LMLabel must occur immediately |
7811 after the associated \section{}, \subsection{} etc. | 7811 after the associated \section{}, \subsection{} etc. |
7812 | 7812 |
7813 ---------------------------------------------------------------------- | 7813 ---------------------------------------------------------------------- |
OLD | NEW |