OLD | NEW |
---|---|
1 \documentclass{article} | 1 4\documentclass{article} |
floitsch
2016/10/10 18:58:15
typo?
Lasse Reichstein Nielsen
2016/10/11 07:52:43
That, or advanced LaTeX magic - who knows?
(LaTeX
eernst
2016/10/17 16:44:57
Make it 5.
| |
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 {4th edition draft}\\ | 10 {4th edition draft}\\ |
11 {\large Version 1.14}} | 11 {\large Version 1.14}} |
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1205 | 1205 |
1206 % The enclosing scope of a generative constructor is the instance scope of the c lass in which it is declared (but what about redirecting?) | 1206 % The enclosing scope of a generative constructor is the instance scope of the c lass in which it is declared (but what about redirecting?) |
1207 | 1207 |
1208 \LMHash{} | 1208 \LMHash{} |
1209 Iff no constructor is specified for a class $C$, it implicitly has a default con structor \code{C() : \SUPER{}() \{\}}, unless $C$ is class \code{Object}. | 1209 Iff no constructor is specified for a class $C$, it implicitly has a default con structor \code{C() : \SUPER{}() \{\}}, unless $C$ is class \code{Object}. |
1210 | 1210 |
1211 \subsubsection{Generative Constructors} | 1211 \subsubsection{Generative Constructors} |
1212 \LMLabel{generativeConstructors} | 1212 \LMLabel{generativeConstructors} |
1213 | 1213 |
1214 \LMHash{} | 1214 \LMHash{} |
1215 A {\em generative constructor} consists of a constructor name, a constructor par ameter list, and either a redirect clause or an initializer list and an optiona l body. | 1215 A {\em generative constructor} is executed to initialize a freshly allocated obj ect. |
eernst
2016/10/17 16:44:56
Even though it is tempting to add explanatory text
Lasse Reichstein Nielsen
2016/10/19 14:34:32
I want to say something here because it introduces
Lasse Reichstein Nielsen
2016/10/31 16:54:42
Done.
| |
1216 It consists of a constructor name, a constructor parameter list, and either a re direct clause or an initializer list and an optional body. | |
1216 | 1217 |
1217 \begin{grammar} | 1218 \begin{grammar} |
1218 {\bf constructorSignature:} | 1219 {\bf constructorSignature:} |
1219 identifier (`{\escapegrammar .}' identifier)? formalParameterList | 1220 identifier (`{\escapegrammar .}' identifier)? formalParameterList |
1220 . | 1221 . |
1221 \end{grammar} | 1222 \end{grammar} |
1222 | 1223 |
1223 \LMHash{} | 1224 \LMHash{} |
1224 A {\em constructor parameter list} is a parenthesized, comma-separated list of f ormal constructor parameters. A {\em formal constructor parameter} is either a f ormal parameter (\ref{formalParameters}) or an initializing formal. An {\em init ializing formal} has the form \code{\THIS{}.id}, where \code{id} is the name of an instance variable of the immediately enclosing class. It is a compile-time e rror if \code{id} is not an instance variable of the immediately enclosing class . It is a compile-time error if an initializing formal is used by a function oth er than a non-redirecting generative constructor. | 1225 A {\em constructor parameter list} is a parenthesized, comma-separated list of f ormal constructor parameters. A {\em formal constructor parameter} is either a f ormal parameter (\ref{formalParameters}) or an initializing formal. An {\em init ializing formal} has the form \code{\THIS{}.id}, where \code{id} is the name of an instance variable of the immediately enclosing class. It is a compile-time e rror if \code{id} is not an instance variable of the immediately enclosing class . It is a compile-time error if an initializing formal is used by a function oth er than a non-redirecting generative constructor. |
1225 | 1226 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1277 | 1278 |
1278 \LMHash{} | 1279 \LMHash{} |
1279 A generative constructor may be {\em redirecting}, in which case its only action is to invoke another generative constructor. A redirecting constructor has no body; instead, it has a redirect clause that specifies which constructor the inv ocation is redirected to, and with what arguments. | 1280 A generative constructor may be {\em redirecting}, in which case its only action is to invoke another generative constructor. A redirecting constructor has no body; instead, it has a redirect clause that specifies which constructor the inv ocation is redirected to, and with what arguments. |
1280 | 1281 |
1281 \begin{grammar} | 1282 \begin{grammar} |
1282 {\bf redirection:} | 1283 {\bf redirection:} |
1283 `{\escapegrammar :}' \THIS{} (`{\escapegrammar .}' identifier)? arguments | 1284 `{\escapegrammar :}' \THIS{} (`{\escapegrammar .}' identifier)? arguments |
1284 . | 1285 . |
1285 \end{grammar} | 1286 \end{grammar} |
1286 | 1287 |
1288 A redirecting generative constructor is executed to initialize an object $o$ as | |
1289 follows: | |
1290 | |
1291 Let $C$ be the class containing the redirecting generative constructor. | |
1292 Let $k$ the target generative constructor specified by either \THIS{} (the const ructor named $C$) or $\THIS{}.id$ (the constructor named $C.id$). | |
1293 Evaluate \code{arguments} to an argument list. | |
1294 Then bind the argument list to the formal parameters of $k$ and | |
1295 execute $k$ on the fresh object $o$. | |
1296 | |
1297 | |
1287 % Need to specify exactly how executing a redirecting constructor works | 1298 % Need to specify exactly how executing a redirecting constructor works |
eernst
2016/10/17 16:44:56
I think the new text in lines 1288-1297 is redunda
Lasse Reichstein Nielsen
2016/10/19 14:34:31
I have removed these lines.
| |
1288 | 1299 |
1289 | 1300 |
1290 %\Q{We now have generative constructors with no bodies as well.} | 1301 %\Q{We now have generative constructors with no bodies as well.} |
1291 | 1302 |
1292 \paragraph{Initializer Lists} | 1303 \paragraph{Initializer Lists} |
1293 \LMLabel{initializerLists} | 1304 \LMLabel{initializerLists} |
1294 | 1305 |
1295 \LMHash{} | 1306 \LMHash{} |
1296 An initializer list begins with a colon, and consists of a comma-separated list of individual {\em initializers}. There are two kinds of initializers. | 1307 An initializer list begins with a colon, and consists of a comma-separated list of individual {\em initializers}. There are two kinds of initializers. |
1297 \begin{itemize} | 1308 \begin{itemize} |
(...skipping 19 matching lines...) Expand all Loading... | |
1317 | 1328 |
1318 \end{grammar} | 1329 \end{grammar} |
1319 | 1330 |
1320 \LMHash{} | 1331 \LMHash{} |
1321 Let $k$ be a generative constructor. Then $k$ may include at most one superini tializer in its initializer list or a compile-time error occurs. If no superinit ializer is provided, an implicit superinitializer of the form \SUPER{}() is adde d at the end of $k$'s initializer list, unless the enclosing class is class \cod e{Object}. It is a compile-time error if more than one initializer corresponding to a given instance variable appears in $k$'s initializer list. It is a compile -time error if $k$'s initializer list contains an initializer for a variable tha t is initialized by means of an initializing formal of $k$. % It is a compile-ti me error if $k$'s initializer list contains an initializer for a final variable $f$ whose declaration includes an initialization expression. | 1332 Let $k$ be a generative constructor. Then $k$ may include at most one superini tializer in its initializer list or a compile-time error occurs. If no superinit ializer is provided, an implicit superinitializer of the form \SUPER{}() is adde d at the end of $k$'s initializer list, unless the enclosing class is class \cod e{Object}. It is a compile-time error if more than one initializer corresponding to a given instance variable appears in $k$'s initializer list. It is a compile -time error if $k$'s initializer list contains an initializer for a variable tha t is initialized by means of an initializing formal of $k$. % It is a compile-ti me error if $k$'s initializer list contains an initializer for a final variable $f$ whose declaration includes an initialization expression. |
1322 | 1333 |
1323 \LMHash{} | 1334 \LMHash{} |
1324 Each final instance variable $f$ declared in the immediately enclosing class mus t have an initializer in $k$'s initializer list unless it has already been initi alized by one of the following means: | 1335 Each final instance variable $f$ declared in the immediately enclosing class mus t have an initializer in $k$'s initializer list unless it has already been initi alized by one of the following means: |
1325 \begin{itemize} | 1336 \begin{itemize} |
1326 \item Initialization at the declaration of $f$. | 1337 \item Initialization at the declaration of $f$. |
1327 \item Initialization by means of an initializing formal of $k$. | 1338 \item Initialization by means of an initializing formal of $k$. |
1328 \end{itemize} | 1339 \end{itemize} |
1329 | 1340 |
1330 or a static warning occurs. It is a compile-time error if $k$'s initializer list contains an initializer for a variable that is not an instance variable declare d in the immediately surrounding class. | 1341 or a static warning occurs. It is a compile-time error if $k$'s initializer list contains an initializer for a variable that is not an instance variable declare d in the immediately surrounding class. |
1331 | 1342 |
1332 | 1343 |
1333 \commentary{The initializer list may of course contain an initializer for any instance variable declared by the immediately surrounding class, even if it is n ot final. | 1344 \commentary{The initializer list may of course contain an initializer for any instance variable declared by the immediately surrounding class, even if it is n ot final. |
1334 } | 1345 } |
1335 | 1346 |
1336 \LMHash{} | 1347 \LMHash{} |
1337 It is a compile-time error if a generative constructor of class \code{Object} includes a superinitializer. | 1348 It is a compile-time error if a generative constructor of class \code{Object} includes a superinitializer. |
1338 | 1349 |
1339 \LMHash{} | 1350 \LMHash{} |
1340 Execution of a generative constructor $k$ is always done with respect to a set o f bindings for its formal parameters and with \THIS{} bound to a fresh instance $i$ and the type parameters of the immediately enclosing class bound to a set o f actual type arguments $V_1, \ldots , V_m$. | 1351 Execution of a generative constructor $k$ to initialize a fresh instance $i$ |
eernst
2016/10/17 16:44:57
I think we need to preserve the information about
Lasse Reichstein Nielsen
2016/10/19 14:34:30
I don't think that's necessary here. The `this` is
| |
1352 is always done with respect to a set of bindings for its formal parameters | |
1353 and the type parameters of the immediately enclosing class bound to a set of act ual type arguments $V_1, \ldots , V_m$. | |
eernst
2016/10/17 16:44:56
The binding of value parameters are specified else
Lasse Reichstein Nielsen
2016/10/19 14:34:31
The constructor $k$ is invoked on a type $T$. The
Lasse Reichstein Nielsen
2016/10/31 16:54:42
Done.
| |
1341 | 1354 |
1342 \commentary{These bindings are usually determined by the instance creation expre ssion that invoked the constructor (directly or indirectly). However, they may a lso be determined by a reflective call,. | 1355 \commentary{These bindings are usually determined by the instance creation expre ssion that invoked the constructor (directly or indirectly). However, they may a lso be determined by a reflective call,. |
1343 } | 1356 } |
1344 | 1357 |
1358 | |
eernst
2016/10/17 16:44:57
No need for two empty lines: No new sections here.
Lasse Reichstein Nielsen
2016/10/19 14:34:30
Acknowledged.
Lasse Reichstein Nielsen
2016/10/31 16:54:42
Done.
| |
1345 \LMHash{} | 1359 \LMHash{} |
1346 If $k$ is redirecting then its redirect clause has the form | 1360 If $k$ is redirecting then its redirect clause has the form |
1347 | 1361 |
1348 \THIS{}$.g(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 1362 \THIS{}$.g(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
1349 | 1363 |
1350 where $g$ identifies another generative constructor of the immediately surround ing class. Then execution of $k$ proceeds by evaluating the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, and then executing $g$ with respect to the bindings resulting from the evaluation of $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ and with \THIS{} bound to $i$ and the type parameters of the immediately enclosing class bound to $V_1, \ ldots , V_m$. | 1364 where $g$ identifies another generative constructor of the immediately surround ing class. Then execution of $k$ to initialize $i$ proceeds by evaluating the ar gument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, and then executing $g$ to initialize $i$ with respect to the bindings resulting from the evaluation of $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ and with \THIS{} bound to $i$ and the type parameters of the immediat ely enclosing class bound to $V_1, \ldots , V_m$. |
1351 | 1365 |
1352 \LMHash{} | 1366 \LMHash{} |
1353 Otherwise, execution proceeds as follows: | 1367 Otherwise, execution proceeds as follows: |
1354 | 1368 |
1355 \LMHash{} | 1369 \LMHash{} |
1356 %First, a fresh instance (\ref{generativeConstructors}) $i$ of the immediately e nclosing class is allocated. Next, the instance variable declarations of the im mediately enclosing class are visited in the order they appear in the program te xt. For each such declaration $d$, if $d$ has the form \code{$finalConstVarOrTy pe$ $v$ = $e$; } then the instance variable $v$ of $i$ is bound to the value of $e$ (which is necessarily a compile-time constant). | 1370 %First, a fresh instance (\ref{generativeConstructors}) $i$ of the immediately e nclosing class is allocated. |
eernst
2016/10/17 16:44:56
So here's the answer to the question "where does i
Lasse Reichstein Nielsen
2016/10/19 14:34:31
It *is* a side-effect of evaluating a `new` expres
| |
1371 | |
1372 The instance variable declarations of the immediately enclosing class are visite d in the order they appear in the program text. | |
1373 For each such declaration $d$, if $d$ has the form \code{$finalConstVarOrType$ $ v$ = $e$; } | |
1374 then $e$ is evaluated to an object $o$ | |
1375 and the instance variable $v$ of $i$ is bound to $o$. | |
eernst
2016/10/17 16:44:57
OK, so this is now uncommented, and that's an impr
Lasse Reichstein Nielsen
2016/10/19 14:34:31
The initialization of fields were also done in the
| |
1376 | |
1357 %Next, a | 1377 %Next, a |
eernst
2016/10/17 16:44:55
We might as well delete this line.
Lasse Reichstein Nielsen
2016/10/19 14:34:31
We could delete all the comments.
A few might me r
Lasse Reichstein Nielsen
2016/10/31 16:54:42
Done.
| |
1358 Any initializing formals declared in $k$'s parameter list are executed in the or der they appear in the program text. | 1378 Any initializing formals declared in $k$'s parameter list are executed in the or der they appear in the program text. |
1359 % In fact, this order is unobservable; this could be done any time prior to runn ing the body, since | 1379 % In fact, this order is unobservable; this could be done any time prior to runn ing the body, since |
1360 % these only effect \THIS{}. | 1380 % these only effect \THIS{}. |
1361 Then, $k$'s initializers are executed in the order they appear in the program. | 1381 Then, $k$'s initializers are executed to initialize $i$ |
1382 in the order they appear in the program. | |
eernst
2016/10/17 16:44:56
This sounds like we'll evaluate the initializing e
Lasse Reichstein Nielsen
2016/10/19 14:34:30
This only refers to the initializers in the initia
| |
1362 | 1383 |
1363 \rationale {We could observe the order by side effecting external routines call ed. So we need to specify the order.} | 1384 \rationale {We could observe the order by side effecting external routines calle d. So we need to specify the order.} |
1385 | |
1386 Then if any instance variable of $i$ declared by the immediately enclosing class | |
1387 is not yet bound to a value, | |
1388 it is a dynamic error if such a variable is a \FINAL{} variable, | |
1389 otherwise all such variables are initialized with the \NULL{} value. | |
eernst
2016/10/17 16:44:56
We should strive to specify each property only onc
Lasse Reichstein Nielsen
2016/10/19 14:34:31
I don't see the rewrite as better than what's alre
| |
1390 | |
1391 After this, unless the enclosing class is \code{Object}, the super constructor c all implicitly or explicitly specified in $k$'s initializers, is now executed to further initialize $i$, as specified below. | |
eernst
2016/10/17 16:44:57
This is the place where it really helps to mention
| |
1392 | |
1393 \commentary{ | |
1394 The super constructor call can be written anywhere in the initalizers of $k$, bu t the actual call always happens after all initializers have been processed. | |
1395 It is not equivalent to moving the super call to the end of the initializers | |
eernst
2016/10/17 16:44:57
Seems more clear to use 'initializer list', becaus
Lasse Reichstein Nielsen
2016/10/19 14:34:30
Acknowledged.
| |
1396 because the argument expressions may have visible side effects | |
1397 which must happen in the order the expressions occour in the program text. | |
floitsch
2016/10/10 18:58:15
occur
Lasse Reichstein Nielsen
2016/10/19 14:34:30
Acknowledged.
| |
1398 } | |
1364 | 1399 |
1365 \LMHash{} | 1400 \LMHash{} |
1366 After all the initializers have completed, the body of $k$ is executed in a sc ope where \THIS{} is bound to $i$. Execution of the body begins with execution o f the body of the superconstructor with \THIS{} bound to $i$, the type paramete rs of the immediately enclosing class bound to a set of actual type arguments $V _1, \ldots , V_m$ and the formal parameters bindings determined by the argument list of the superinitializer of $k$. | 1401 After all superclass constructors have completed, the body of $k$ is executed in a scope where \THIS{} is bound to $i$. |
eernst
2016/10/17 16:44:56
I believe we should say 'After the superinitialize
Lasse Reichstein Nielsen
2016/10/19 14:34:31
Good point.
| |
1367 | 1402 |
1368 \rationale{ | 1403 \rationale{ |
1369 This process ensures that no uninitialized final field is ever seen by code. Not e that \THIS{} is not in scope on the right hand side of an initializer (see \re f{this}) so no instance method can execute during initialization: an instance me thod cannot be directly invoked, nor can \THIS{} be passed into any other code being invoked in the initializer. | 1404 This process ensures that no uninitialized final field is ever seen by code. Not e that \THIS{} is not in scope on the right hand side of an initializer (see \re f{this}) so no instance method can execute during initialization: an instance me thod cannot be directly invoked, nor can \THIS{} be passed into any other code being invoked in the initializer. |
1370 } | 1405 } |
1371 | 1406 |
1372 \LMHash{} | 1407 \LMHash{} |
1373 Execution of an initializer of the form \code{\THIS{}.$v$ = $e$} proceeds as fol lows: | 1408 Execution of an initializer of the form \code{\THIS{}.$v$ = $e$} to initialize a n object $i$ proceeds as follows: |
eernst
2016/10/17 16:44:56
It's probably simpler if we avoid introducing yet
Lasse Reichstein Nielsen
2016/10/19 14:34:31
ACK
Lasse Reichstein Nielsen
2016/10/31 16:54:43
Done.
| |
1374 | 1409 |
1375 \LMHash{} | 1410 \LMHash{} |
1376 First, the expression $e$ is evaluated to an object $o$. Then, the instance vari able $v$ of the object denoted by \THIS{} is bound to $o$, unless $v$ is a final variable that has already been initialized, in which case a runtime error occur s. In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the int erface of the class of $o$ is not a subtype of the actual type of the field $v$. | 1411 First, the expression $e$ is evaluated to an object $o$. Then, the instance vari able $v$ of $i$ is bound to $o$, unless $v$ is a final variable that has already been initialized, in which case a runtime error occurs. In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the interface of the class of $o$ is not a subtype of the actual type of the field $v$. |
1377 | 1412 |
1378 \LMHash{} | 1413 \LMHash{} |
1379 An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of t he form \code{\THIS{}.$v$ = $e$}. | 1414 An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of t he form \code{\THIS{}.$v$ = $e$}. |
1380 | 1415 |
1381 \LMHash{} | 1416 \LMHash{} |
1382 Execution of a superinitializer of the form | 1417 Execution of a superinitializer of the form |
1383 | 1418 |
1384 \SUPER{}$(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ | 1419 \SUPER{}$(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ |
1385 | 1420 |
1386 (respectively \SUPER{}$.id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ | 1421 (respectively \SUPER{}$.id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ |
1387 | 1422 |
1388 proceeds as follows: | 1423 proceeds as follows: |
1389 | 1424 |
1390 \LMHash{} | 1425 \LMHash{} |
1391 First, the argument list $(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ is evaluated. | 1426 First, the argument list $(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ is evaluated. |
1427 This evaluated argument list is remembered until after the entire initializer li st has been evaluated, at which point the constructor is executed as follows: | |
eernst
2016/10/17 16:44:58
I'd prefer avoiding to introduce 'remember' as a n
Lasse Reichstein Nielsen
2016/10/19 14:34:31
I believe "binding" refers to the result of applyi
Lasse Reichstein Nielsen
2016/10/31 16:54:43
Actually, I don't think the binding of formal vari
| |
1392 | 1428 |
1393 \LMHash{} | 1429 \LMHash{} |
1394 Let $C$ be the class in which the superinitializer appears and let $S$ be the su perclass of $C$. If $S$ is generic (\ref{generics}), let $U_1, , \ldots, U_m$ b e the actual type arguments passed to $S$ in the superclass clause of $C$. | 1430 Let $C$ be the class in which the superinitializer appears and let $S$ be the su perclass of $C$. If $S$ is generic (\ref{generics}), let $U_1, , \ldots, U_m$ b e the actual type arguments passed to $S$ in the superclass clause of $C$. |
1395 | 1431 |
1396 \LMHash{} | 1432 \LMHash{} |
1397 Then, the initializer list of the constructor $S$ (respectively $S.id$) is execu ted with respect to the bindings that resulted from the evaluation of the argume nt list, with \THIS{} bound to the current binding of \THIS{}, and the type pa rameters (if any) of class $S$ bound to the current bindings of $U_1, , \ldots, U_m$. | 1433 The generative constructor $S$ (respectively $S.id$) of $S$ is executed to initi alize $i$ with respect to the bindings that resulted from the evaluation of the argument list, and the type parameters (if any) of class $S$ bound to the curren t bindings of $U_1, , \ldots, U_m$. |
eernst
2016/10/17 16:44:58
'..with respect to the bindings $B$, and the type
Lasse Reichstein Nielsen
2016/10/19 14:34:31
No, the U_1 .. U_m *are* the type parameters of th
Lasse Reichstein Nielsen
2016/10/31 16:54:42
It's still suspicious that we talk about the "Actu
| |
1398 | 1434 |
1399 \LMHash{} | 1435 \LMHash{} |
1400 It is a compile-time error if class $S$ does not declare a generative constructo r named $S$ (respectively $S.id$). | 1436 It is a compile-time error if class $S$ does not declare a generative constructo r named $S$ (respectively $S.id$). |
1401 | 1437 |
1402 \subsubsection{Factories} | 1438 \subsubsection{Factories} |
1403 \LMLabel{factories} | 1439 \LMLabel{factories} |
1404 | 1440 |
1405 \LMHash{} | 1441 \LMHash{} |
1406 A {\em factory} is a constructor prefaced by the built-in identifier (\ref{iden tifierReference}) \FACTORY{}. | 1442 A {\em factory} is a constructor prefaced by the built-in identifier (\ref{iden tifierReference}) \FACTORY{}. |
1407 | 1443 |
(...skipping 12 matching lines...) Expand all Loading... | |
1420 \LMHash{} | 1456 \LMHash{} |
1421 It is a compile-time error if $M$ is not the name of the immediately enclosing c lass. | 1457 It is a compile-time error if $M$ is not the name of the immediately enclosing c lass. |
1422 | 1458 |
1423 \LMHash{} | 1459 \LMHash{} |
1424 In checked mode, it is a dynamic type error if a factory returns a non-null obje ct whose type is not a subtype of its actual (\ref{actualTypeOfADeclaration}) re turn type. | 1460 In checked mode, it is a dynamic type error if a factory returns a non-null obje ct whose type is not a subtype of its actual (\ref{actualTypeOfADeclaration}) re turn type. |
1425 | 1461 |
1426 \rationale{It seems useless to allow a factory to return null. But it is more un iform to allow it, as the rules currently do.} | 1462 \rationale{It seems useless to allow a factory to return null. But it is more un iform to allow it, as the rules currently do.} |
1427 | 1463 |
1428 \rationale{Factories address classic weaknesses associated with constructors in other languages. | 1464 \rationale{Factories address classic weaknesses associated with constructors in other languages. |
1429 Factories can produce instances that are not freshly allocated: they can come fr om a cache. Likewise, factories can return instances of different classes. | 1465 Factories can produce instances that are not freshly allocated: they can come fr om a cache. Likewise, factories can return instances of different classes. |
1430 | |
1431 } | 1466 } |
1432 | 1467 |
1433 \paragraph{Redirecting Factory Constructors} | 1468 \paragraph{Redirecting Factory Constructors} |
1434 \LMLabel{redirectingFactoryConstructors} | 1469 \LMLabel{redirectingFactoryConstructors} |
1435 | 1470 |
1436 \LMHash{} | 1471 \LMHash{} |
1437 A {\em redirecting factory constructor} specifies a call to a constructor of ano ther class that is to be used whenever the redirecting constructor is called. | 1472 A {\em redirecting factory constructor} specifies a call to a constructor of ano ther class that is to be used whenever the redirecting constructor is called. |
1438 | 1473 |
1439 \begin{grammar} | 1474 \begin{grammar} |
1440 {\bf redirectingFactoryConstructorSignature:} | 1475 {\bf redirectingFactoryConstructorSignature:} |
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2331 \LMHash{} | 2366 \LMHash{} |
2332 The constant expression given in an annotation is type checked and evaluated in the scope surrounding the declaration being annotated. | 2367 The constant expression given in an annotation is type checked and evaluated in the scope surrounding the declaration being annotated. |
2333 | 2368 |
2334 | 2369 |
2335 \section{Expressions} | 2370 \section{Expressions} |
2336 \LMLabel{expressions} | 2371 \LMLabel{expressions} |
2337 | 2372 |
2338 \LMHash{} | 2373 \LMHash{} |
2339 An {\em expression} is a fragment of Dart code that can be evaluated at run time to yield a {\em value}, which is always an object. Every expression has an asso ciated static type (\ref{staticTypes}). Every value has an associated dynamic ty pe (\ref{dynamicTypeSystem}). | 2374 An {\em expression} is a fragment of Dart code that can be evaluated at run time to yield a {\em value}, which is always an object. Every expression has an asso ciated static type (\ref{staticTypes}). Every value has an associated dynamic ty pe (\ref{dynamicTypeSystem}). |
2340 | 2375 |
2376 Expressions can also {\em throw} an exception object and an associated stack tra ce. | |
Kevin Millikin (Google)
2016/10/13 08:38:28
I suggest a more radical rewrite of this section.
Lasse Reichstein Nielsen
2016/10/17 10:08:22
Rewritten completely. Changed "yield" to "produce"
| |
2377 | |
2378 Evaluation of an expression will always either {\em yield a value} or it will {\ em throw an exception} along with an associated stack trace. | |
2379 | |
2380 If evaluation of an expression is defined in terms of evaluation of another | |
2381 expression, and the evaluation of the other expression throws an exception, | |
2382 if nothing else is stated, the evaluation of the first expression stops | |
2383 at that point and throws the same exception. | |
eernst
2016/10/17 16:44:58
Aha, here is the congruence rule! (I was waiting f
Lasse Reichstein Nielsen
2016/10/19 14:34:30
Acknowledged.
Lasse Reichstein Nielsen
2016/10/31 16:54:42
We won't use "complete" for expressions.
I have tr
| |
2384 | |
eernst
2016/10/17 16:44:57
Typo: Spurious empty line.
Lasse Reichstein Nielsen
2016/10/31 16:54:42
Done.
| |
2341 | 2385 |
2342 \begin{grammar} | 2386 \begin{grammar} |
2343 | 2387 |
2344 {\bf expression:}assignableExpression assignmentOperator expression; | 2388 {\bf expression:}assignableExpression assignmentOperator expression; |
2345 conditionalExpression cascadeSection*; | 2389 conditionalExpression cascadeSection*; |
2346 throwExpression | 2390 throwExpression |
2347 . | 2391 . |
2348 | 2392 |
2349 | 2393 |
2350 {\bf expressionWithoutCascade:}assignableExpression assignmentOperator expressio nWithoutCascade; | 2394 {\bf expressionWithoutCascade:}assignableExpression assignmentOperator expressio nWithoutCascade; |
(...skipping 24 matching lines...) Expand all Loading... | |
2375 An expression $e$ may always be enclosed in parentheses, but this never has any semantic effect on $e$. | 2419 An expression $e$ may always be enclosed in parentheses, but this never has any semantic effect on $e$. |
2376 | 2420 |
2377 \commentary{ | 2421 \commentary{ |
2378 Sadly, it may have an effect on the surrounding expression. Given a class $C$ wi th static method $m => 42$, $C.m()$ returns 42, but $(C).m()$ produces a \code{N oSuchMethodError}. This anomaly can be corrected by removing the restrictions o n calling the members of instances of \code{Type}. This issue may be addressed i n future versions of Dart. | 2422 Sadly, it may have an effect on the surrounding expression. Given a class $C$ wi th static method $m => 42$, $C.m()$ returns 42, but $(C).m()$ produces a \code{N oSuchMethodError}. This anomaly can be corrected by removing the restrictions o n calling the members of instances of \code{Type}. This issue may be addressed i n future versions of Dart. |
2379 } | 2423 } |
2380 | 2424 |
2381 \subsubsection{Object Identity} | 2425 \subsubsection{Object Identity} |
2382 \LMLabel{objectIdentity} | 2426 \LMLabel{objectIdentity} |
2383 | 2427 |
2384 \LMHash{} | 2428 \LMHash{} |
2385 The predefined Dart function \cd{identical()} is defined such that \code{identic al($c_1$, $c_2$)} iff: | 2429 The predefined Dart function \cd{identical()} is defined such that \code{identic al($c_1$, $c_2$)} iff: |
Kevin Millikin (Google)
2016/10/13 08:38:28
Consider this outside the scope of this change, bu
Lasse Reichstein Nielsen
2016/10/17 10:08:22
ACK.
Definitely out of scope for this CL.
Definite
| |
2386 \begin{itemize} | 2430 \begin{itemize} |
2387 \item $c_1$ evaluates to either \NULL{} or an instance of \code{bool} and \co de{$c_1$ == $c_2$}, OR | 2431 \item $c_1$ evaluates to either \NULL{} or an instance of \code{bool} and \co de{$c_1$ == $c_2$}, OR |
Kevin Millikin (Google)
2016/10/13 08:38:28
c_1 can't actually evaluate to null, null is a res
| |
2388 \item $c_1$ and $c_2$ are instances of \code{int} and \code{$c_1$ == $c_2$}, OR | 2432 \item $c_1$ and $c_2$ are instances of \code{int} and \code{$c_1$ == $c_2$}, OR |
Kevin Millikin (Google)
2016/10/13 08:38:28
c_1 and c_2 are expressions, so they are not insta
| |
2389 \item $c_1$ and $c_2$ are constant strings and \code{$c_1$ == $c_2$}, OR | 2433 \item $c_1$ and $c_2$ are constant strings and \code{$c_1$ == $c_2$}, OR |
Kevin Millikin (Google)
2016/10/13 08:38:28
The spec defines constant expressions, not constan
| |
2390 \item $c_1$ and $c_2$ are instances of \cd{double} and one of the following holds: | 2434 \item $c_1$ and $c_2$ are instances of \cd{double} and one of the following holds: |
2391 \begin{itemize} | 2435 \begin{itemize} |
2392 \item $c_1$ and $c_2$ are non-zero and \code{$c_1$ == $c_2$}. | 2436 \item $c_1$ and $c_2$ are non-zero and \code{$c_1$ == $c_2$}. |
2393 \item Both $c_1$ and $c_2$ are $+0.0$. | 2437 \item Both $c_1$ and $c_2$ are $+0.0$. |
2394 \item Both $c_1$ and $c_2$ are $-0.0$. | 2438 \item Both $c_1$ and $c_2$ are $-0.0$. |
2395 \item Both $c_1$ and $c_2$ represent a NaN value with the same underlying bit pattern. | 2439 \item Both $c_1$ and $c_2$ represent a NaN value with the same underlying bit pattern. |
2396 \end{itemize} | 2440 \end{itemize} |
2397 OR | 2441 OR |
2398 \item $c_1$ and $c_2$ are constant lists that are defined to be identical in th e specification of literal list expressions (\ref{lists}), OR | 2442 \item $c_1$ and $c_2$ are constant lists that are defined to be identical in th e specification of literal list expressions (\ref{lists}), OR |
2399 \item $c_1$ and $c_2$ are constant maps that are defined to be identical in the specification of literal map expressions (\ref{maps}), OR | 2443 \item $c_1$ and $c_2$ are constant maps that are defined to be identical in the specification of literal map expressions (\ref{maps}), OR |
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3037 \THROW{} expression | 3081 \THROW{} expression |
3038 . | 3082 . |
3039 | 3083 |
3040 {\bf throwExpressionWithoutCascade:} | 3084 {\bf throwExpressionWithoutCascade:} |
3041 \THROW{} expressionWithoutCascade | 3085 \THROW{} expressionWithoutCascade |
3042 . | 3086 . |
3043 | 3087 |
3044 \end{grammar} | 3088 \end{grammar} |
3045 | 3089 |
3046 \LMHash{} | 3090 \LMHash{} |
3047 The {\em current exception} is the last exception raised and not subsequently c aught at a given moment during runtime. | 3091 Evaluation of a throw expression of the form \code{\THROW{} $e$;} proceeds as f ollows: |
3048 | |
3049 \LMHash{} | |
3050 Evaluation of a throw expression of the form \code{\THROW{} $e$;} proceeds as follows: | |
3051 | 3092 |
3052 \LMHash{} | 3093 \LMHash{} |
3053 The expression $e$ is evaluated yielding a value $v$. | 3094 The expression $e$ is evaluated yielding a value $v$. |
3054 | 3095 |
3055 \commentary{ | 3096 \commentary{ |
3056 There is no requirement that the expression $e$ evaluate to a special kind of ex ception or error object. | 3097 There is no requirement that the expression $e$ evaluate to a special kind of ex ception or error object. |
eernst
2016/10/17 16:44:56
Maybe add this, because the reader might consider
Lasse Reichstein Nielsen
2016/10/19 14:34:30
Acknowledged.
Lasse Reichstein Nielsen
2016/10/31 16:54:42
I actually find that more confusing than not havin
| |
3057 } | 3098 } |
3058 | 3099 |
3059 \LMHash{} | 3100 \LMHash{} |
3060 If $e$ evaluates to \NULL{} (\ref{null}), then a \code{NullThrownError} is throw n. Otherwise the current exception is set to $v$ and the current return value (\ ref{return}) becomes undefined. | 3101 If $e$ evaluates to \NULL{} (\ref{null}), then a \code{NullThrownError} is throw n. Otherwise let $t$ be a stack trace corresponding to the current execution sta te, and the \THROW{} statement aborts by {\em throwing} with $e$ as exception ob ject and $t$ as stack trace. |
eernst
2016/10/17 16:44:56
We might as well have a newline per sentence here.
Lasse Reichstein Nielsen
2016/10/31 16:54:41
Added newlines, removed emphasis. Changed ref to {
| |
3061 | |
3062 \rationale{The current exception and the current return value must never be simu ltaneously defined, as they represent mutually exclusive options for exiting the current function. | |
3063 } | |
3064 | 3102 |
3065 \LMHash{} | 3103 \LMHash{} |
3066 Let $f$ be the immediately enclosing function. | 3104 If $e$ is an instance of class \code{Error} or a subclass thereof, its \code{sta ckTrace} getter will return the stack trace captured at the point where the obje ct was first thrown. |
3067 | |
3068 \LMHash{} | |
3069 If $f$ is synchronous (\ref{functions}), control is transferred to the nearest d ynamically enclosing exception handler. | |
3070 | 3105 |
3071 \commentary{ | 3106 \commentary{ |
3072 If $f$ is marked \SYNC* then a dynamically enclosing exception handler encloses the call to \code{moveNext()} that initiated the evaluation of the throw express ion. | 3107 If the same \code{Error} object is thrown more than once, its \code{stackTrace} getter will return the stack trace captured the {\em first} time it was thrown. |
3073 } | 3108 } |
eernst
2016/10/17 16:44:56
I think this text should remain normative (interpr
Lasse Reichstein Nielsen
2016/10/19 14:34:31
The previous paragraph (which has since been rewri
| |
3074 | 3109 |
3075 \LMHash{} | 3110 \LMHash{} |
3076 If $f$ is asynchronous then if there is a dynamically enclosing exception handl er $h$ (\ref{try}) introduced by the current activation, control is transferred to $h$, otherwise $f$ terminates. | |
3077 | |
3078 \rationale{ | |
3079 The rules for where a thrown exception will be handled must necessarily differ b etween the synchronous and asynchronous cases. Asynchronous functions cannot tra nsfer control to an exception handler defined outside themselves. Asynchronous generators post exceptions to their stream. Other asynchronous functions report exceptions via their future. | |
3080 } | |
3081 | |
3082 \LMHash{} | |
3083 If the object being thrown is an instance of class \code{Error} or a subclass th ereof, its \code{stackTrace} getter will return the stack trace current at the p oint where the object was first thrown. | |
3084 | |
3085 \LMHash{} | |
3086 The static type of a throw expression is $\bot$. | 3111 The static type of a throw expression is $\bot$. |
3087 | 3112 |
3088 | 3113 |
3089 \subsection{ Function Expressions} | 3114 \subsection{ Function Expressions} |
3090 \LMLabel{functionExpressions} | 3115 \LMLabel{functionExpressions} |
3091 | 3116 |
3092 \LMHash{} | 3117 \LMHash{} |
3093 A {\em function literal} is an object that encapsulates an executable unit of co de. | 3118 A {\em function literal} is an object that encapsulates an executable unit of co de. |
3094 | 3119 |
3095 \begin{grammar} | 3120 \begin{grammar} |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3337 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k} : a_{n+k})$ is evaluated. | 3362 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k} : a_{n+k})$ is evaluated. |
3338 | 3363 |
3339 \LMHash{} | 3364 \LMHash{} |
3340 If $T$ is a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs. | 3365 If $T$ is a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs. |
3341 | 3366 |
3342 \LMHash{} | 3367 \LMHash{} |
3343 Then, if $q$ is a non-factory constructor of an abstract class then an \code{Abs tractClassInstantiationError} is thrown. | 3368 Then, if $q$ is a non-factory constructor of an abstract class then an \code{Abs tractClassInstantiationError} is thrown. |
3344 | 3369 |
3345 \LMHash{} | 3370 \LMHash{} |
3346 If $T$ is malformed or if $T$ is a type variable a dynamic error occurs. In che cked mode, if $T$ or any of its superclasses is malbounded a dynamic error occur s. | 3371 If $T$ is malformed or if $T$ is a type variable a dynamic error occurs. In che cked mode, if $T$ or any of its superclasses is malbounded a dynamic error occur s. |
3347 Otherwise, if $q$ is not defined or not accessible, a \code{NoSuchMethodError} is thrown. If $q$ has less than $n$ positional parameters or more than $n$ req uired parameters, or if $q$ lacks any of the keyword parameters $\{ x_{n+1}, \ld ots, x_{n+k}\}$ a \code{NoSuchMethodError} is thrown. | 3372 Otherwise, if $q$ is not defined or not accessible, a \code{NoSuchMethodError} i s thrown. If $q$ has less than $n$ positional parameters or more than $n$ requ ired parameters, or if $q$ lacks any of the keyword parameters $\{ x_{n+1}, \ldo ts, x_{n+k}\}$ a \code{NoSuchMethodError} is thrown. |
3348 | 3373 |
3349 \LMHash{} | 3374 \LMHash{} |
3350 Otherwise, if $q$ is a generative constructor (\ref{generativeConstructors}), th en: | 3375 Otherwise, if $q$ is a generative constructor (\ref{generativeConstructors}), th en: |
3351 | 3376 |
3352 \commentary{Note that it this point we are assured that the number of actual typ e arguments match the number of formal type parameters.} | 3377 \commentary{Note that it this point we are assured that the number of actual typ e arguments match the number of formal type parameters.} |
eernst
2016/10/17 16:44:56
Could fix typo: 'at this point'.
Lasse Reichstein Nielsen
2016/10/19 14:34:31
Done.
| |
3353 | 3378 |
3354 \LMHash{} | 3379 \LMHash{} |
3355 A fresh instance (\ref{generativeConstructors}), $i$, of class $R$ is allocated . For each instance variable $f$ of $i$, if the variable declaration of $f$ has an initializer expression $e_f$, then $e_f$ is evaluated, with the type paramet ers (if any) of $R$ bound to the actual type arguments $V_1, \ldots, V_l$, to an object $o_f$ and $f$ is bound to $o_f$. Otherwise $f$ is bound to \NULL{}. | 3380 A fresh instance (\ref{generativeConstructors}), $i$, of class $R$ is allocated. |
eernst
2016/10/17 16:44:57
Aha, so we should definitely simply delete the com
Lasse Reichstein Nielsen
2016/10/19 14:34:31
The allocation was always done here. Previously th
| |
3381 Then $q$ is executed to initialize $i$ with its formal parameters bound to the e valuated argument list and, if $R$ is a generic class, with its type parameters bound to $V_1 \ldots V_m$. | |
eernst
2016/10/17 16:44:57
The binding stuff is still a mess, but this is pro
Lasse Reichstein Nielsen
2016/10/19 14:34:31
Again I don't think that applies because the actua
Lasse Reichstein Nielsen
2016/10/31 16:54:42
I'm wrong. Reworded to be consistent with other si
| |
3356 | 3382 |
3357 \commentary{ | 3383 If execution of $q$ completes normally, $e$ evaluates to $i$. |
eernst
2016/10/17 16:44:56
This is a very special situation, because we canno
Lasse Reichstein Nielsen
2016/10/19 14:34:31
That's mixing expressions and statements. A statem
Lasse Reichstein Nielsen
2016/10/31 16:54:42
No explicitly propagates exception from execution
| |
3358 Observe that \THIS{} is not in scope in $e_f$. Hence, the initialization cannot depend on other properties of the object being instantiated. | |
3359 } | |
3360 | |
3361 \LMHash{} | |
3362 Next, $q$ is executed with \THIS{} bound to $i$, the type parameters (if any) of $R$ bound to the actual type arguments $V_1, \ldots, V_l$ and the formal par ameter bindings that resulted from the evaluation of the argument list. The resu lt of the evaluation of $e$ is $i$. | |
3363 | 3384 |
3364 \LMHash{} | 3385 \LMHash{} |
3365 Otherwise, $q$ is a factory constructor (\ref{factories}). Then: | 3386 Otherwise, $q$ is a factory constructor (\ref{factories}). Then: |
3366 | 3387 |
3367 \LMHash{} | 3388 \LMHash{} |
3368 If $q$ is a redirecting factory constructor of the form $T(p_1, \ldots, p_{n+k}) = c;$ or of the form $T.id(p_1, \ldots, p_{n+k}) = c;$ then the result of the evaluation of $e$ is equivalent to evaluating the expression | 3389 If $q$ is a redirecting factory constructor of the form $T(p_1, \ldots, p_{n+k}) = c;$ or of the form $T.id(p_1, \ldots, p_{n+k}) = c;$ then the result of the evaluation of $e$ is equivalent to evaluating the expression |
3369 | 3390 |
3370 $[V_1, \ldots, V_m/T_1, \ldots, T_m]($\code{\NEW{} $c(a_1, \ldots, a_n, x_{n+1 }: a_{n+1}, \ldots, x_{n+k}: a_{n+k}))$}. If evaluation of $q$ causes $q$ to be re-evaluated cyclically, a runtime error occurs. | 3391 $[V_1, \ldots, V_m/T_1, \ldots, T_m]($\code{\NEW{} $c(a_1, \ldots, a_n, x_{n+1 }: a_{n+1}, \ldots, x_{n+k}: a_{n+k}))$}. If evaluation of $q$ causes $q$ to be re-evaluated cyclically, with only factory constructor redirections in-between, a runtime error occurs. |
3392 % Used to not have the "in-between" clause, which would disallow a factory const ructor redirecting to another constructor which conditionally calls the original factory constructor again with different arguments. | |
eernst
2016/10/17 16:44:56
Reword to work for the general case, not just this
Lasse Reichstein Nielsen
2016/10/19 14:34:30
Not sure what you are asking for.
| |
3371 | 3393 |
3372 | 3394 |
3373 \LMHash{} | 3395 \LMHash{} |
3374 Otherwise, the body of $q$ is executed with respect to the bindings that resulte d from the evaluation of the argument list and the type parameters (if any) of $ q$ bound to the actual type arguments $V_1, \ldots, V_l$ resulting in an object $i$. The result of the evaluation of $e$ is $i$. | 3396 Otherwise, the body of $q$ is executed with respect to the bindings that resulte d from the evaluation of the argument list and the type parameters (if any) of $ q$ bound to the actual type arguments $V_1, \ldots, V_l$. |
eernst
2016/10/17 16:44:57
We definitely need to have a comma here: '..argume
Lasse Reichstein Nielsen
2016/10/31 16:54:42
Done.
| |
3397 If this execution {\em returns} or {\em completes normally} (\ref{completion}), | |
3398 let $i$ be the value {\em returned} by this execution, or \NULL{} if the executi on returns without a value or it completes normally. | |
3399 The result of the evaluation of $e$ is $i$. | |
eernst
2016/10/17 16:44:55
Isn't a factory constructor a function that return
Lasse Reichstein Nielsen
2016/10/19 14:34:30
A non-redirecting factory constructor is basically
| |
3375 | 3400 |
3376 \LMHash{} | 3401 \LMHash{} |
3377 It is a static warning if $q$ is a constructor of an abstract class and $q$ is n ot a factory constructor. | 3402 It is a static warning if $q$ is a constructor of an abstract class and $q$ is n ot a factory constructor. |
3378 | 3403 |
3379 \commentary{The above gives precise meaning to the idea that instantiating an ab stract class leads to a warning. | 3404 \commentary{The above gives precise meaning to the idea that instantiating an ab stract class leads to a warning. |
3380 A similar clause applies to constant object creation in the next section. | 3405 A similar clause applies to constant object creation in the next section. |
3381 } | 3406 } |
3382 | 3407 |
3383 \rationale{In particular, a factory constructor can be declared in an abstract c lass and used safely, as it will either produce a valid instance or lead to a wa rning inside its own declaration. | 3408 \rationale{In particular, a factory constructor can be declared in an abstract c lass and used safely, as it will either produce a valid instance or lead to a wa rning inside its own declaration. |
3384 } | 3409 } |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3528 | 3553 |
3529 | 3554 |
3530 | 3555 |
3531 \subsection{ Function Invocation} | 3556 \subsection{ Function Invocation} |
3532 \LMLabel{functionInvocation} | 3557 \LMLabel{functionInvocation} |
3533 | 3558 |
3534 \LMHash{} | 3559 \LMHash{} |
3535 Function invocation occurs in the following cases: when a function expression ( \ref{functionExpressions}) is invoked (\ref{functionExpressionInvocation}), when a method (\ref{methodInvocation}), getter (\ref{topLevelGetterInvocation}, \ref {propertyExtraction}) or setter (\ref{assignment}) is invoked or when a construc tor is invoked (either via instance creation (\ref{instanceCreation}), construct or redirection (\ref{redirectingConstructors}) or super initialization). The var ious kinds of function invocation differ as to how the function to be invoked, $ f$, is determined, as well as whether \THIS{} (\ref{this}) is bound. Once $f$ h as been determined, the formal parameters of $f$ are bound to corresponding actu al arguments. When the body of $f$ is executed it will be executed with the afor ementioned bindings. | 3560 Function invocation occurs in the following cases: when a function expression ( \ref{functionExpressions}) is invoked (\ref{functionExpressionInvocation}), when a method (\ref{methodInvocation}), getter (\ref{topLevelGetterInvocation}, \ref {propertyExtraction}) or setter (\ref{assignment}) is invoked or when a construc tor is invoked (either via instance creation (\ref{instanceCreation}), construct or redirection (\ref{redirectingConstructors}) or super initialization). The var ious kinds of function invocation differ as to how the function to be invoked, $ f$, is determined, as well as whether \THIS{} (\ref{this}) is bound. Once $f$ h as been determined, the formal parameters of $f$ are bound to corresponding actu al arguments. When the body of $f$ is executed it will be executed with the afor ementioned bindings. |
3536 | 3561 |
3537 \LMHash{} | 3562 \LMHash{} |
3538 If $f$ is marked \ASYNC{} (\ref{functions}), then a fresh instance (\ref{generat iveConstructors}) $o$ implementing the built-in class \code{Future} is associate d with the invocation and immediately returned to the caller. The body of $f$ is scheduled for execution at some future time. The future $o$ will complete when $f$ terminates. The value used to complete $o$ is the current return value (\ref {return}), if it is defined, and the current exception (\ref{throw}) otherwise. | 3563 If $f$ is marked \ASYNC{} (\ref{functions}), then a fresh instance (\ref{generat iveConstructors}) $o$ implementing the built-in class \code{Future} is associate d with the invocation and immediately returned to the caller. The body of $f$ is scheduled for execution at some future time. The future $o$ will complete when execution of $f$ completes (\ref{completion}). If $f$ completes by {\em returnin g} a value, that value used to complete $o$, if it {\em completes normally} or b y {\em returning} with no value, $o$ is completed with \NULL{}, and if it comple tes by {\em throwing} an exception $e$ and stack trace $t$, $o$ is completed wit h $e$ and stack trace $t$ as an error. |
eernst
2016/10/17 16:44:55
I'd suggest that we avoid the concept of completin
Lasse Reichstein Nielsen
2016/10/19 14:34:31
I considered doing that, but Kevin actually liked
| |
3539 | 3564 |
3540 \LMHash{} | 3565 \LMHash{} |
3541 If $f$ is marked \ASYNC* (\ref{functions}), then a fresh instance $s$ implementi ng the built-in class \code{Stream} is associated with the invocation and immedi ately returned. When $s$ is listened to, execution of the body of $f$ will begin . When $f$ terminates: | 3566 If $f$ is marked \ASYNC* (\ref{functions}), then a fresh instance $s$ implementi ng the built-in class \code{Stream} is associated with the invocation and immedi ately returned. When $s$ is listened to, execution of the body of $f$ will begin . When $f$ completes: |
3542 \begin{itemize} | 3567 \begin{itemize} |
3543 \item If the current return value is defined then, if $s$ has been canceled then its cancellation future is completed with \NULL{} (\ref{null}). | 3568 \item If $f$ {\em completes normally}, then if $s$ has been canceled then its ca ncellation future is completed with \NULL{} (\ref{null}). |
eernst
2016/10/17 16:44:57
I think we should reserve `{\em ..}` for introduct
Lasse Reichstein Nielsen
2016/10/19 14:34:31
Are you sure it's not worth emphasizing that this
Lasse Reichstein Nielsen
2016/10/31 16:54:42
Done.
| |
3544 \item If the current exception $x$ is defined: | 3569 \item If $f$ {\em throws} exception $e$ and stack trace $t$: |
eernst
2016/10/17 16:44:56
Keeping the usual phrases for this, we would have
Lasse Reichstein Nielsen
2016/10/19 14:34:30
I don't think "completes with an exception" is def
| |
3545 \begin{itemize} | 3570 \begin{itemize} |
3546 \item $x$ is added to $s$. | 3571 \item $e$ and $t$ are added to $s$ as an error. |
3547 \item If $s$ has been canceled then its cancellation future is completed with $x$ as an error. | 3572 \item If $s$ has been canceled then its cancellation future is completed with $e$ and $t$ as an error. |
eernst
2016/10/17 16:44:55
$e$ would now be $o$, twice.
Lasse Reichstein Nielsen
2016/10/19 14:34:30
I think I'll keep using $e$ for the error.
| |
3548 \end{itemize} | 3573 \end{itemize} |
3549 \item $s$ is closed. | 3574 \item $s$ is closed. |
3550 \end{itemize} | 3575 \end{itemize} |
3551 | 3576 |
3552 \rationale{ | 3577 \rationale{ |
3553 When an asynchronous generator's stream has been canceled, cleanup will occur in the \FINALLY{} clauses (\ref{try}) inside the generator. We choose to direct an y exceptions that occur at this time to the cancellation future rather than have them be lost. | 3578 When an asynchronous generator's stream has been canceled, cleanup will occur in the \FINALLY{} clauses (\ref{try}) inside the generator. We choose to direct an y exceptions that occur at this time to the cancellation future rather than have them be lost. |
3554 } | 3579 } |
3555 | 3580 |
3556 \LMHash{} | |
3557 If $f$ is asynchronous then, when $f$ terminates, any open stream subscriptions associated with any asynchronous for loops (\ref{asynchronousFor-in}) or yield- each statements (\ref{yieldEach}) executing within $f$ are canceled, in the ord er of their nesting, innermost first. | |
3558 | |
3559 \rationale{Such streams may be left open by for loops that were escaped when an exception was thrown within them for example. | |
3560 } | |
3561 | |
3562 %\LMHash{} | 3581 %\LMHash{} |
3563 %When a stream is canceled, the implementation must wait for the cancelation fut ure returned by \cd{cancell()} to complete before proceeding. | 3582 %When a stream is canceled, the implementation must wait for the cancelation fut ure returned by \cd{cancell()} to complete before proceeding. |
3564 | 3583 |
3565 \LMHash{} | 3584 \LMHash{} |
3566 If $f$ is marked \SYNC* (\ref{functions}), then a fresh instance $i$ implementin g the built-in class \code{Iterable} is associated with the invocation and immed iately returned. | 3585 If $f$ is marked \SYNC* (\ref{functions}), then a fresh instance $i$ implementin g the built-in class \code{Iterable} is associated with the invocation and immed iately returned. |
3567 | 3586 |
3568 | 3587 |
3569 \commentary{ | 3588 \commentary{ |
3570 A Dart implementation will need to provide a specific implementation of \code{It erable} that will be returned by \SYNC* methods. A typical strategy would be to produce an instance of a subclass of class \code{IterableBase} defined in \code{ dart:core}. The only method that needs to be added by the Dart implementation in that case is \code{iterator}. | 3589 A Dart implementation will need to provide a specific implementation of \code{It erable} that will be returned by \SYNC* methods. A typical strategy would be to produce an instance of a subclass of class \code{IterableBase} defined in \code{ dart:core}. The only method that needs to be added by the Dart implementation in that case is \code{iterator}. |
3571 } | 3590 } |
3572 | 3591 |
3573 \LMHash{} | 3592 \LMHash{} |
3574 The iterable implementation must comply with the contract of \code{Iterable} and should not take any steps identified as exceptionally efficient in that contrac t. | 3593 The iterable implementation must comply with the contract of \code{Iterable} and should not take any steps identified as exceptionally efficient in that contrac t. |
3575 | 3594 |
3576 \commentary { | 3595 \commentary { |
3577 The contract explicitly mentions a number of situations where certain iterables could be more efficient than normal. For example, by precomputing their length. Normal iterables must iterate over their elements to determine their length. Thi s is certainly true in the case of a synchronous generator, where each element i s computed by a function. It would not be acceptable to pre-compute the results of the generator and cache them, for example. | 3596 The contract explicitly mentions a number of situations where certain iterables could be more efficient than normal. For example, by precomputing their length. Normal iterables must iterate over their elements to determine their length. Thi s is certainly true in the case of a synchronous generator, where each element i s computed by a function. It would not be acceptable to pre-compute the results of the generator and cache them, for example. |
3578 } | 3597 } |
3579 | 3598 |
3580 \LMHash{} | 3599 \LMHash{} |
3581 When iteration over the iterable is started, by getting an iterator $j$ from the iterable and calling \code{moveNext()}, execution of the body of $f$ will begin . When $f$ terminates, $j$ is positioned after its last element, so that its cur rent value is \NULL{} and the current call to \code{moveNext()} on $j$ returns f alse, as will all further calls. | 3600 When iteration over the iterable is started, by getting an iterator $j$ from the iterable and calling \code{moveNext()}, execution of the body of $f$ will begin . When $f$ completes (\ref{completion}, |
3601 \begin{itemize} | |
3602 \item If $f$ {\em completes normally}, $j$ is positioned after its last element, so that its current value is \NULL{} and the current call to \code{moveNext()} on $j$ returns false, as will all further calls. | |
eernst
2016/10/17 16:44:58
'If $f$ completes normally with the value $v$, $v$
Lasse Reichstein Nielsen
2016/10/31 16:54:42
Not using that phrasing.
| |
3603 \item If $f$ {\em throws} exception $e$ and stack trace $t$ then the current val ue is \NULL{} and the current call to \code{moveNext()} throws $e$ and $t$ as we ll. Further calls must return false. | |
eernst
2016/10/17 16:44:55
'If $f$ completes with an exception then a call to
Lasse Reichstein Nielsen
2016/10/31 16:54:42
Done.
| |
3604 \end{itemize} | |
3582 | 3605 |
3583 Each iterator starts a separate computation. If the \SYNC* function is impure, t he sequence of values yielded by each iterator may differ. | 3606 Each iterator starts a separate computation. If the \SYNC* function is impure, t he sequence of values yielded by each iterator may differ. |
3584 | 3607 |
3585 \commentary{ | 3608 \commentary{ |
3586 One can derive more than one iterator from a given iterable. Note that operati ons on the iterable itself can create distinct iterators. An example would be \c ode{length}. It is conceivable that different iterators might yield sequences o f different length. The same care needs to be taken when writing \SYNC* function s as when | 3609 One can derive more than one iterator from a given iterable. Note that operati ons on the iterable itself can create distinct iterators. An example would be \c ode{length}. It is conceivable that different iterators might yield sequences o f different length. The same care needs to be taken when writing \SYNC* function s as when |
3587 writing an \code{Iterator} class. In particular, it should handle multiple | 3610 writing an \code{Iterator} class. In particular, it should handle multiple |
3588 simultaneous iterators gracefully. If the iterator depends on external state | 3611 simultaneous iterators gracefully. If the iterator depends on external state |
3589 that might change, it should check that the state is still valid after every | 3612 that might change, it should check that the state is still valid after every |
3590 yield (and maybe throw a \code{ConcurrentModificationError} if it isn't). | 3613 yield (and maybe throw a \code{ConcurrentModificationError} if it isn't). |
3591 } | 3614 } |
3592 | 3615 |
3593 \LMHash{} | 3616 \LMHash{} |
3594 Each iterator runs with its own shallow copies of all local variables; in partic ular, each iterator has the same initial arguments, even if their bindings are m odified by the function. | 3617 Each iterator runs with its own shallow copies of all local variables; in partic ular, each iterator has the same initial arguments, even if their bindings are m odified by the function. |
3595 \commentary{ | 3618 \commentary{ |
3596 Two executions of an iterator interact only via state outside the function. | 3619 Two executions of an iterator interact only via state outside the function. |
3597 } | 3620 } |
3598 % The alternative would be to cache the results of an iterator in the iterable, and check the cache at each \YIELD{}. This would have strange issues as well. T he yielded value might differ from the expression in the yield. And it is a pote ntial memory leak as the cache is kept alive by any iterator. | 3621 % The alternative would be to cache the results of an iterator in the iterable, and check the cache at each \YIELD{}. This would have strange issues as well. T he yielded value might differ from the expression in the yield. And it is a pote ntial memory leak as the cache is kept alive by any iterator. |
3599 | 3622 |
3600 | 3623 |
3601 \LMHash{} | 3624 \LMHash{} |
3602 If $f$ is synchronous and is not a generator (\ref{functions}) then execution of the body of $f$ begins immediately. When $f$ terminates the current return val ue is returned to the caller. | 3625 If $f$ is synchronous and is not a generator (\ref{functions}) then execution of the body of $f$ begins immediately. |
3626 When $f$ completes (\ref{completion}) by returning a value, that value is return ed to the caller. | |
3627 If $f$ completes by returning without a value or by completing normally, \NULL{} is returned to the callse. | |
3628 If $f$ completes by {\em throwing}, the invoking call expression throws the same exception object and stack trace. | |
eernst
2016/10/17 16:44:57
Following the same style we would have something l
Lasse Reichstein Nielsen
2016/10/19 14:34:30
The "last statement" shouldn't need to be mentione
| |
3603 | 3629 |
3604 | 3630 \commentary{ |
3605 \LMHash{} | 3631 A function body can never {\em abort} by {\em breaking} or {\em continuing} |
3606 Execution of $f$ terminates when the first of the following occurs: | 3632 because any \BREAK{} or \CONTINUE{} statement must occuring inside statement |
3607 \begin{itemize} | 3633 which will handle the \BREAK{} or \CONTINUE{}, |
3608 \item An exception is thrown and not caught within the current function activati on. | 3634 either by declaring the same label, if the \BREAK{} or \CONTINUE{} has a label, |
3609 \item A return statement (\ref{return}) immediately nested in the body of $f$ is executed and not intercepted in a \FINALLY{} (\ref{try}) clause. | 3635 or merely by being a loop or \SWITCH{} statement. |
3610 \item The last statement of the body completes execution. | 3636 This means that a function body can only abort by {\em throwing}, so an |
3611 \end{itemize} | 3637 expression can represent the behavior of a function body. |
eernst
2016/10/17 16:44:56
I know this is commentary, but I think there are t
Lasse Reichstein Nielsen
2016/10/19 14:34:31
ACK. I'm actually considering moving this to the \
Lasse Reichstein Nielsen
2016/10/31 16:54:42
REmoved \em's. Reworded.
| |
3612 | 3638 } |
3613 | |
3614 | |
3615 | 3639 |
3616 \subsubsection{ Actual Argument List Evaluation} | 3640 \subsubsection{ Actual Argument List Evaluation} |
3617 \LMLabel{actualArguments} | 3641 \LMLabel{actualArguments} |
3618 | 3642 |
3619 \LMHash{} | 3643 \LMHash{} |
3620 Function invocation involves evaluation of the list of actual arguments to the f unction and binding of the results to the function's formal parameters. | 3644 Function invocation involves evaluation of the list of actual arguments to the f unction and binding of the results to the function's formal parameters. |
3621 | 3645 |
3622 \begin{grammar} | 3646 \begin{grammar} |
3623 {\bf arguments:} | 3647 {\bf arguments:} |
3624 `(' (argumentList `,'?)? `)' | 3648 `(' (argumentList `,'?)? `)' |
(...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5004 \begin{grammar} | 5028 \begin{grammar} |
5005 {\bf awaitExpression:} | 5029 {\bf awaitExpression:} |
5006 \AWAIT{} unaryExpression | 5030 \AWAIT{} unaryExpression |
5007 \end{grammar} | 5031 \end{grammar} |
5008 | 5032 |
5009 \LMHash{} | 5033 \LMHash{} |
5010 Evaluation of an await expression $a$ of the form \AWAIT{} $e$ proceeds as follo ws: | 5034 Evaluation of an await expression $a$ of the form \AWAIT{} $e$ proceeds as follo ws: |
5011 First, the expression $e$ is evaluated. Next: | 5035 First, the expression $e$ is evaluated. Next: |
5012 | 5036 |
5013 \LMHash{} | 5037 \LMHash{} |
5014 If $e$ raises an exception $x$, then an instance $f$ of class \code{Future} is a llocated and later completed with $x$. Otherwise, if $e$ evaluates to an object $o$ that is not an instance of \code{Future}, then let $f$ be the result of call ing \code{Future.value()} with $o$ as its argument; otherwise let $f$ be the res ult of evaluating $e$. | 5038 % NOTICE: Removed the requirement that an error thrown by $e$ is caught in a |
5039 % future. There is no reason $var x = e; await x;$ and $await e$ should behave | |
5040 % differently, and no implementation actually implemented it. | |
5041 If $e$ evaluates to an object $o$ that is not an instance of \code{Future}, then let $f$ be the result of creating a new object using the constructor \code{Futu re.value()} with $o$ as its argument; otherwise let $f$ be the result of evaluat ing $e$. | |
eernst
2016/10/17 16:44:56
I'd prefer if we keep all completion situations ex
Lasse Reichstein Nielsen
2016/10/31 16:54:42
I have trouble parsing that. I read it as:
if (e
| |
5015 | 5042 |
5016 \LMHash{} | 5043 \LMHash{} |
5017 Next, execution of the function $m$ immediately enclosing $a$ is suspended unti l after $f$ completes. The stream associated with the innermost enclosing asynch ronous for loop (\ref{asynchronousFor-in}), if any, is paused. At some time afte r $f$ is completed, control returns to the current invocation. The stream associ ated with the innermost enclosing asynchronous for loop (\ref{asynchronousFor-i n}), if any, is resumed. If $f$ has completed with an exception $x$, $a$ raises $x$. If $f$ completes with a value $v$, $a$ evaluates to $v$. | 5044 Next, the stream associated with the innermost enclosing asynchronous for loop ( \ref{asynchronousFor-in}), if any, is paused. Execution of the function $m$ imme diately enclosing $a$ is suspended until after $f$ completes. At some time after $f$ is completed, control returns to the current invocation. If $f$ has complet ed with an exception $x$ and stack trace $t$, $a$ {\em throws} $x$ and $t$. If $ f$ completes with a value $v$, $a$ evaluates to $v$. |
eernst
2016/10/17 16:44:56
OK, we discussed a while back how to interleave th
Lasse Reichstein Nielsen
2016/10/19 14:34:31
It's not, good point.
It should be possible to des
| |
5018 | 5045 |
5019 %Otherwise, the value of $a$ is the value of $e$. If evaluation of $e$ raises an exception $x$, $a$ raises $x$. | 5046 %Otherwise, the value of $a$ is the value of $e$. If evaluation of $e$ raises an exception $x$, $a$ raises $x$. |
5020 | 5047 |
5021 \commentary{ | 5048 \commentary{ |
5022 It is a compile-time error if the function immediately enclosing $a$ is not declared asynchronous. However, this error is simply a syntax error, because in the context of a normal function, \AWAIT{} has no special meaning. | 5049 It is a compile-time error if the function immediately enclosing $a$ is not declared asynchronous. However, this error is simply a syntax error, because in the context of a normal function, \AWAIT{} has no special meaning. |
5050 % TODO(lrn): Update this, it's not actually correct, | |
5051 % the expression "await(expr)" is valid non-async syntax *and* a valid | |
5052 % async await expression. | |
5023 } | 5053 } |
5024 | 5054 |
5025 \rationale{ | 5055 \rationale{ |
5026 An await expression has no meaning in a synchronous function. If such a function were to suspend waiting for a future, it would no longer be synchronous. | 5056 An await expression has no meaning in a synchronous function. If such a function were to suspend waiting for a future, it would no longer be synchronous. |
5027 } | 5057 } |
5028 | 5058 |
5029 \commentary{ | 5059 \commentary{ |
5030 It is not a static warning if the type of $e$ is not a subtype of \code{Future}. Tools may choose to give a hint in such cases. | 5060 It is not a static warning if the type of $e$ is not a subtype of \code{Future}. Tools may choose to give a hint in such cases. |
5031 } | 5061 } |
5032 | 5062 |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5416 | 5446 |
5417 \LMHash{} | 5447 \LMHash{} |
5418 The expression $e$ is evaluated to a value $v$. Then, if $T$ is a malformed or d eferred type (\ref{staticTypes}), a dynamic error occurs. Otherwise, if the inte rface of the class of $v$ is a subtype of $T$, the cast expression evaluates to $v$. Otherwise, if $v$ is \NULL{}, the cast expression evaluates to $v$. | 5448 The expression $e$ is evaluated to a value $v$. Then, if $T$ is a malformed or d eferred type (\ref{staticTypes}), a dynamic error occurs. Otherwise, if the inte rface of the class of $v$ is a subtype of $T$, the cast expression evaluates to $v$. Otherwise, if $v$ is \NULL{}, the cast expression evaluates to $v$. |
5419 In all other cases, a \code{CastError} is thrown. | 5449 In all other cases, a \code{CastError} is thrown. |
5420 | 5450 |
5421 \LMHash{} | 5451 \LMHash{} |
5422 The static type of a cast expression \code{$e$ \AS{} $T$} is $T$. | 5452 The static type of a cast expression \code{$e$ \AS{} $T$} is $T$. |
5423 | 5453 |
5424 | 5454 |
5425 \section{Statements} | 5455 \section{Statements} |
5426 \LMLabel{statements} | 5456 \LMLabel{statements} |
eernst
2016/10/17 16:44:56
Missing empty line, then missing `\LMHash{}` for t
Lasse Reichstein Nielsen
2016/10/19 14:34:30
But why?
I.e., hat are the rules for using LMHash
| |
5457 A {\em statement} is a fragment of Dart code that can be executed at runtime. St atements, unlike expressions, do not evaluate to a value, but are instead execut ed for their effect on the program state. | |
eernst
2016/10/17 16:44:57
It's a smart phrase, 'Statements, unlike expressio
Lasse Reichstein Nielsen
2016/10/19 14:34:31
Acknowledged.
Lasse Reichstein Nielsen
2016/10/31 16:54:43
The more I think about it, the less I agree.
We ar
| |
5458 Some statements can affect control flow, in particular \BREAK{}, \CONTINUE{}, \R ETURN{} and \THROW{} statements. | |
eernst
2016/10/17 16:44:57
Function invocations do affect the control flow as
Lasse Reichstein Nielsen
2016/10/19 14:34:30
Good point.
I'm exactly talking about the things t
Lasse Reichstein Nielsen
2016/10/31 16:54:42
I have reworded considerably, this sentence is now
| |
5459 | |
5460 \LMLabel{completion} | |
eernst
2016/10/17 16:44:57
It breaks the rules to have an \LMLabel{} which is
Lasse Reichstein Nielsen
2016/10/19 14:34:31
Is it a problem to have two labels for the same se
| |
5461 Execution of a statement can {\em complete} in two ways: either it {\em complete s normally} or it {\em aborts}. It can {\em abort} in one of four ways: Either i t {\em breaks} or it {\em continues} (either to a label or without a label), it {\em returns}, either with a value or without one, or it {\em throws} an excepti on object and an associated stack trace. | |
eernst
2016/10/17 16:44:57
It is tempting to use these short-hands, but I sti
Lasse Reichstein Nielsen
2016/10/19 14:34:31
This has been rewritten already.
Also, as discusse
| |
5462 | |
5463 In the description of statement execution, the default is that the execution | |
5464 {\em completes normally} unless otherwise stated. | |
5465 | |
5466 If the execution of a statement, $s$, is defined in terms of executing | |
5467 another statement, | |
5468 like the body of a loop or the branches of an \IF{} statement, | |
5469 and the execution of that other statement {\em aborts}, | |
5470 then, unless otherwise stated, the execution of $s$ stops | |
5471 at that point and aborts in the same way. | |
5472 | |
5473 If the execution of a statement is defined in terms of evaluating an expression, | |
5474 like the condition expression of an \IF{} statement or the value of a \RETURN{}, | |
5475 and the evaluation of that expression throws, | |
5476 then, unless otherwise stated, the execution of the statement stops | |
5477 at that point and throws the same exception object and stack trace. | |
eernst
2016/10/17 16:44:57
I'm not so happy about introducing any 'default' m
Lasse Reichstein Nielsen
2016/10/19 14:34:31
Seems reasonable, although doing the S_1 .. S_k se
Lasse Reichstein Nielsen
2016/10/31 16:54:43
Kept the existing text mostly unchanged. Getting i
| |
5478 | |
5479 \LMHash{} | |
eernst
2016/10/17 16:44:56
We haven't otherwise used \LMHash{} markers on gra
Lasse Reichstein Nielsen
2016/10/19 14:34:30
What is the purpose of LMHash markers?
I am thinki
| |
5427 | 5480 |
5428 \begin{grammar} | 5481 \begin{grammar} |
5429 {\bf statements:} | 5482 {\bf statements:} |
5430 statement* | 5483 statement* |
5431 . | 5484 . |
5432 | 5485 |
5433 | 5486 |
5434 {\bf statement:} | 5487 {\bf statement:} |
5435 label* nonLabelledStatement | 5488 label* nonLabelledStatement |
5436 . | 5489 . |
(...skipping 15 matching lines...) Expand all Loading... | |
5452 expressionStatement; | 5505 expressionStatement; |
5453 assertStatement; | 5506 assertStatement; |
5454 localFunctionDeclaration | 5507 localFunctionDeclaration |
5455 . | 5508 . |
5456 \end{grammar} | 5509 \end{grammar} |
5457 | 5510 |
5458 \subsection{Blocks} | 5511 \subsection{Blocks} |
5459 \LMLabel{blocks} | 5512 \LMLabel{blocks} |
5460 | 5513 |
5461 \LMHash{} | 5514 \LMHash{} |
5462 A {\em block statement} supports sequencing of code. | 5515 A {\em block statement} supports sequencing of code. |
5463 | 5516 |
5464 \LMHash{} | 5517 \LMHash{} |
5465 Execution of a block statement $\{s_1, \ldots, s_n\}$ proceeds as follows: | 5518 Execution of a block statement $\{s_1, \ldots, s_n\}$ proceeds as follows: |
5466 | 5519 |
5467 \LMHash{} | 5520 \LMHash{} |
5468 For $i \in 1 .. n, s_i$ is executed. | 5521 For $i \in 1 .. n, s_i$ is executed. |
5469 | 5522 |
5470 \LMHash{} | 5523 \LMHash{} |
5471 A block statement introduces a new scope, which is nested in the lexically enclo sing scope in which the block statement appears. | 5524 A block statement introduces a new scope, which is nested in the lexically enclo sing scope in which the block statement appears. |
5472 | 5525 |
eernst
2016/10/17 16:44:57
Just for consistency, let's keep 2 empty lines bef
Lasse Reichstein Nielsen
2016/10/19 14:34:30
Acknowledged.
| |
5473 | 5526 \subsection{Expression Statements} |
5474 | 5527 \LMLabel{expressionStatements} |
5475 \subsection{Expression Statements} | |
5476 \LMLabel{expressionStatements} | |
5477 | 5528 |
5478 \LMHash{} | 5529 \LMHash{} |
5479 An {\em expression statement} consists of an expression other than a non-constan t map literal (\ref{maps}) that has no explicit type arguments. | 5530 An {\em expression statement} consists of an expression other than a non-constan t map literal (\ref{maps}) that has no explicit type arguments. |
5480 | 5531 |
5481 \rationale{ | 5532 \rationale{ |
5482 The restriction on maps is designed to resolve an ambiguity in the grammar, whe n a statement begins with \{. | 5533 The restriction on maps is designed to resolve an ambiguity in the grammar, whe n a statement begins with \{. |
5483 } | 5534 } |
5484 | 5535 |
5485 \begin{grammar} | 5536 \begin{grammar} |
5486 {\bf expressionStatement:} | 5537 {\bf expressionStatement:} |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5593 % elaborate on function identity and equality, runtime type. Likewsie in functio n expressions (closures) and declarations | 5644 % elaborate on function identity and equality, runtime type. Likewsie in functio n expressions (closures) and declarations |
5594 | 5645 |
5595 \subsection{If} | 5646 \subsection{If} |
5596 \LMLabel{if} | 5647 \LMLabel{if} |
5597 | 5648 |
5598 \LMHash{} | 5649 \LMHash{} |
5599 The {\em if statement} allows for conditional execution of statements. | 5650 The {\em if statement} allows for conditional execution of statements. |
5600 | 5651 |
5601 \begin{grammar} | 5652 \begin{grammar} |
5602 {\bf ifStatement:} | 5653 {\bf ifStatement:} |
5603 \IF{} `(' expression `)' statement ( \ELSE{} statement)? % we could allow top level expression | 5654 \IF{} `(' expression `)' statement ( \ELSE{} statement)? |
5604 . | 5655 . |
5605 \end{grammar} | 5656 \end{grammar} |
5606 | 5657 |
5607 Execution of an if statement of the form \code {\IF{} (}$b$\code{)}$s_1$ \code{ \ELSE{} } $s_2$ proceeds as follows: | 5658 Execution of an if statement of the form \code {\IF{} (}$b$\code{)}$s_1$ \code{ \ELSE{} } $s_2$ proceeds as follows: |
5608 | 5659 |
5609 \LMHash{} | 5660 \LMHash{} |
5610 First, the expression $b$ is evaluated to an object $o$. Then, $o$ is subjecte d to boolean conversion (\ref{booleanConversion}), producing an object $r$. If $ r$ is \TRUE{}, then the statement $\{s_1\}$ is executed, otherwise statement $\{ s_2\}$ is executed. | 5661 First, the expression $b$ is evaluated to an object $o$. Then, $o$ is subjected to boolean conversion (\ref{booleanConversion}), producing an object $r$. If $r $ is \TRUE{}, then the statement $\{s_1\}$ is executed, otherwise statement $\{s _2\}$ is executed. |
5611 | |
5612 | 5662 |
5613 \commentary { | 5663 \commentary { |
5614 Put another way, \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} } $s_2$ is equiv alent to | 5664 Put another way, \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} } $s_2$ is equiv alent to |
5615 \code {\IF{} (}$b$\code{)}$\{s_1\}$ \code{\ELSE{} } $\{s_2\}$ | 5665 \code {\IF{} (}$b$\code{)}$\{s_1\}$ \code{\ELSE{} } $\{s_2\}$ |
5616 } | 5666 } |
5617 | 5667 |
5618 \rationale { | 5668 \rationale { |
5619 The reason for this equivalence is to catch errors such as | 5669 The reason for this equivalence is to catch errors such as |
5620 } | 5670 } |
5621 \begin{dartCode} | 5671 \begin{dartCode} |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5688 \begin{enumerate} | 5738 \begin{enumerate} |
5689 \item | 5739 \item |
5690 \label{beginFor} | 5740 \label{beginFor} |
5691 If this is the first iteration of the for loop, let $v^\prime$ be $v$. Otherwise , let $v^\prime$ be the variable $v^{\prime\prime}$ created in the previous exe cution of step \ref{allocateFreshVar}. | 5741 If this is the first iteration of the for loop, let $v^\prime$ be $v$. Otherwise , let $v^\prime$ be the variable $v^{\prime\prime}$ created in the previous exe cution of step \ref{allocateFreshVar}. |
5692 \item | 5742 \item |
5693 The expression $[v^\prime/v]c$ is evaluated and subjected to boolean conversion (\ref{booleans}). If the result is \FALSE{}, the for loop completes. Otherwise, execution continues at step | 5743 The expression $[v^\prime/v]c$ is evaluated and subjected to boolean conversion (\ref{booleans}). If the result is \FALSE{}, the for loop completes. Otherwise, execution continues at step |
5694 \ref{beginIteration}. | 5744 \ref{beginIteration}. |
5695 \item | 5745 \item |
5696 \label{beginIteration} | 5746 \label{beginIteration} |
5697 The statement $[v^\prime/v]\{s\}$ is executed. | 5747 The statement $[v^\prime/v]\{s\}$ is executed. |
5698 \item | 5748 |
5749 If this execution {\em continues} without a label, | |
5750 or with a label that this \FOR{} statement is labeled with (\ref{labels}), | |
5751 then the statement is treated as if it had completed normally. | |
eernst
2016/10/17 16:44:57
'If this execution completes with a \BREAK{}, with
Lasse Reichstein Nielsen
2016/10/19 14:34:31
If the body continues the loop, then it's equivale
Lasse Reichstein Nielsen
2016/10/31 16:54:42
Reworded.
| |
5752 If it aborts in any other way, | |
5753 execution of the for loop stops and aborts in the same way. | |
eernst
2016/10/17 16:44:57
'
\commentary{
If it aborts in any other way then
Lasse Reichstein Nielsen
2016/10/19 14:34:31
That, or remove it.
Lasse Reichstein Nielsen
2016/10/31 16:54:43
Removed.
| |
5754 | |
5699 \label{allocateFreshVar} | 5755 \label{allocateFreshVar} |
5700 Let $v^{\prime\prime}$ be a fresh variable. $v^{\prime\prime}$ is bound to the value of $v^\prime$. | 5756 Let $v^{\prime\prime}$ be a fresh variable. $v^{\prime\prime}$ is bound to the value of $v^\prime$. |
5701 \item | 5757 \item |
5702 The expression $[v^{\prime\prime}/v]e$ is evaluated, and the process recurses at step | 5758 The expression $[v^{\prime\prime}/v]e$ is evaluated, and the process recurses at step |
5703 \ref{beginFor}. | 5759 \ref{beginFor}. |
5704 \end{enumerate} | 5760 \end{enumerate} |
5705 | 5761 |
5706 \rationale{ | 5762 \rationale{ |
5707 The definition above is intended to prevent the common error where users create a closure inside a for loop, intending to close over the current binding of the loop variable, and find (usually after a painful process of debugging and learni ng) that all the created closures have captured the same value - the one current in the last iteration executed. | 5763 The definition above is intended to prevent the common error where users create a closure inside a for loop, intending to close over the current binding of the loop variable, and find (usually after a painful process of debugging and learni ng) that all the created closures have captured the same value - the one current in the last iteration executed. |
5708 | 5764 |
(...skipping 23 matching lines...) Expand all Loading... | |
5732 | 5788 |
5733 \begin{dartCode} | 5789 \begin{dartCode} |
5734 var n0 = $e$.iterator; | 5790 var n0 = $e$.iterator; |
5735 \WHILE{} (n0.moveNext()) \{ | 5791 \WHILE{} (n0.moveNext()) \{ |
5736 $finalConstVarOrType?$ id = n0.current; | 5792 $finalConstVarOrType?$ id = n0.current; |
5737 $s$ | 5793 $s$ |
5738 \} | 5794 \} |
5739 \end{dartCode} | 5795 \end{dartCode} |
5740 where \code{n0} is an identifier that does not occur anywhere in the program, ex cept that for purposes of static typechecking, it is checked under the assumptio n that $n0$ is declared to be of type $T$, where $T$ is the static type of $e.it erator$. | 5796 where \code{n0} is an identifier that does not occur anywhere in the program, ex cept that for purposes of static typechecking, it is checked under the assumptio n that $n0$ is declared to be of type $T$, where $T$ is the static type of $e.it erator$. |
5741 | 5797 |
5742 | |
5743 | |
5744 \subsubsection{Asynchronous For-in} | 5798 \subsubsection{Asynchronous For-in} |
5745 \LMLabel{asynchronousFor-in} | 5799 \LMLabel{asynchronousFor-in} |
5746 | 5800 |
5747 \LMHash{} | 5801 \LMHash{} |
5748 A for-in statement may be asynchronous. The asynchronous form is designed to ite rate over streams. An asynchronous for loop is distinguished by the keyword \AWA IT{} immediately preceding the keyword \FOR. | 5802 A for-in statement may be asynchronous. The asynchronous form is designed to ite rate over streams. An asynchronous for loop is distinguished by the keyword \AWA IT{} immediately preceding the keyword \FOR. |
5749 | 5803 |
5750 \LMHash{} | 5804 \LMHash{} |
5751 Execution of a for-in statement of the form \code{\AWAIT{} \FOR{} (finalConstVa rOrType? id \IN{} $e$) $s$} proceeds as follows: | 5805 Execution of a for-in statement, $f$, of the form \code{\AWAIT{} \FOR{} (finalCo nstVarOrType? id \IN{} $e$) $s$} proceeds as follows: |
5752 | 5806 |
5753 \LMHash{} | 5807 \LMHash{} |
5754 The expression $e$ is evaluated to an object $o$. It is a dynamic error if $o$ i s not an instance of a class that implements \code{Stream}. Otherwise, the expre ssion \code{\AWAIT{} $v_f$} (\ref{awaitExpressions}) is evaluated, where $v_f$ is a fresh variable whose value is a fresh instance (\ref{generativeConstructors }) $f$ implementing the built-in class \code{Future}. | 5808 The expression $e$ is evaluated to an object $o$. |
5809 It is a dynamic error if $o$ is not an instance of a class that implements \code {Stream}. | |
5755 | 5810 |
5756 \LMHash{} | 5811 \LMHash{} |
5757 The stream $o$ is listened to, and on each data event in $o$ the statement $s$ is executed with \code{id} bound to the value of the current element of the stre am. If $s$ raises an exception, or if $o$ raises an exception, then $f$ is compl eted with that exception. Otherwise, when all events in the stream $o$ have been processed, $f$ is completed with \NULL{} (\ref{null}). | 5812 The stream associated with the innermost enclosing asynchronous for loop, if any , is paused. |
5813 The stream $o$ is listened to, producing a stream subscription $u$, | |
5814 and execution of the asynchronous for-in loop is suspended | |
5815 until a stream event is available. | |
5816 This allows other asynchronous events to execute while this loop is waiting for stream events. | |
5817 | |
5818 Pausing an asynchronous for loop means pausing the associated stream subscriptio n. | |
5819 A stream subscription is paused by calling its \code{pause} method. | |
5820 \commentary{ | |
5821 The \code{pause} call can throw, although that should never happen for a correct ly implemented stream. | |
5822 } | |
5823 If the subscription is already paused, the \code{pause} call may be omitted. | |
5758 | 5824 |
5759 \LMHash{} | 5825 \LMHash{} |
5760 Let $u$ be the stream associated with the immediately enclosing asynchronous for loop or generator function (\ref{functions}), if any. If another event $e_u$ of $u$ occurs before execution of $s$ is complete, handling of $e_u$ must wait unt il $s$ is complete. | 5826 For each {\em data event} from $u$, |
5827 the statement $s$ is executed with \code{id} bound to the value of the current d ata event. | |
5761 | 5828 |
5762 \rationale{ | 5829 \LMHash{} |
5763 The future $f$ and the corresponding \AWAIT{} expression ensure that execution s uspends as an asynchronous for loop begins and resumes after the \FOR{} statemen t when it ends. They also ensure that the stream of any enclosing asynchronous \ FOR{} loop is paused for the duration of this loop. | 5830 If another event $e_u$ of $u$ occurs before execution of $s$ is complete, handli ng of $e_u$ must wait until $s$ is complete. |
5831 | |
5832 \LMHash{} | |
5833 If execution of $s$ {\em continues} with no label, or with a label that prefixes the asynchronous for statement (\ref{labels}), then the exection of $s$ is trea ted as if it had completed normally. | |
5834 | |
5835 If execution of $s$ {\em aborts} in any other way, the subscription $u$ is cance led by evaluating \code{\AWAIT{} v.cancel()} where $v$ is a fresh variable refer encing the stream subscription $u$. | |
5836 If that evaluation throws, | |
5837 execution of $f$ throws the same exception and stack trace. | |
5838 Otherwise execution of $f$ aborts in the same way as the exeution of $s$. | |
5839 % Notice: The previous specification was unclear about what happened when | |
5840 % a subscripton is canceled. This text is explicit, and existing | |
5841 % implementations may not properly await the cancel call. | |
5842 | |
5843 Otherwise the execution of $f$ is suspended again, waiting for the next stream s ubscription event, and $u$ is resumed if it has been paused. | |
5844 If $u$ has been paused more than once, the \code{resume} method is called | |
5845 until $u$ is no longer paused. | |
5846 \commentary{ | |
5847 The \code{resume} call can throw, in which case it aborts the asynchronous for | |
5848 loop. That should never happen for a correctly implemented stream. | |
5764 } | 5849 } |
5765 | 5850 |
5766 \LMHash{} | 5851 \LMHash{} |
5852 On the first {\em error event} from $u$, | |
5853 with error object $e$ and stack trace $st$, | |
5854 the subscription $u$ is canceled by evaluating \code{\AWAIT{} v.cancel()} | |
5855 where $v$ is a fresh variable referencing the stream subscription $u$. | |
5856 If that evaluation throws, | |
5857 execution of $f$ throws the same exception object and stack trace. | |
5858 Otherwise execution of $f$ throws with $e$ as exception object and $st$ as stack trace. | |
5859 | |
5860 \LMHash{} | |
5861 When $u$ is done, execution of $f$ completes normally. | |
5862 | |
5863 \LMHash{} | |
5767 It is a compile-time error if an asynchronous for-in statement appears inside a synchronous function (\ref{functions}). It is a compile-time error if a traditio nal for loop (\ref{forLoop}) is prefixed by the \AWAIT{} keyword. | 5864 It is a compile-time error if an asynchronous for-in statement appears inside a synchronous function (\ref{functions}). It is a compile-time error if a traditio nal for loop (\ref{forLoop}) is prefixed by the \AWAIT{} keyword. |
5768 | 5865 |
5769 \rationale{An asynchronous loop would make no sense within a synchronous functio n, for the same reasons that an await expression makes no sense in a synchronous function.} | 5866 \rationale{An asynchronous loop would make no sense within a synchronous functio n, for the same reasons that an await expression makes no sense in a synchronous function.} |
5770 | 5867 |
5771 | 5868 |
5772 \subsection{While} | 5869 \subsection{While} |
5773 \LMLabel{while} | 5870 \LMLabel{while} |
5774 | 5871 |
5775 \LMHash{} | 5872 \LMHash{} |
5776 The while statement supports conditional iteration, where the condition is evalu ated prior to the loop. | 5873 The while statement supports conditional iteration, where the condition is evalu ated prior to the loop. |
5777 | 5874 |
5778 \begin{grammar} | 5875 \begin{grammar} |
5779 {\bf whileStatement:} | 5876 {\bf whileStatement:} |
5780 \WHILE{} `(' expression `)' statement % could do top level here, and in f or | 5877 \WHILE{} `(' expression `)' statement % could do top level here, and in f or |
5781 . | 5878 . |
5782 \end{grammar} | 5879 \end{grammar} |
5783 | 5880 |
5784 \LMHash{} | 5881 \LMHash{} |
5785 Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} proceeds as follows: | 5882 Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} proceeds a s follows: |
5786 | 5883 |
5787 \LMHash{} | 5884 \LMHash{} |
5788 The expression $e$ is evaluated to an object $o$. Then, $o$ is subjected to boo lean conversion (\ref{booleanConversion}), producing an object $r$. If $r$ is \ TRUE{}, then the statement $\{s\}$ is executed and then the while statement is r e-executed recursively. If $r$ is \FALSE{}, execution of the while statement is complete. | 5885 The expression $e$ is evaluated to an object $o$. Then, $o$ is subjected to bool ean conversion (\ref{booleanConversion}), producing an object $r$. |
5886 | |
5887 If $r$ is \TRUE{}, then the statement $\{s\}$ is executed. | |
5888 If that execution completes normally or it {\em continues} with no label or with a label that prefixes the \WHILE{} statement (\ref{labels}), then the while sta tement is re-executed. | |
5889 | |
5890 If $r$ is \FALSE{}, then execution of the while statement completes normally. | |
5789 | 5891 |
5790 \LMHash{} | 5892 \LMHash{} |
5791 It is a static type warning if the static type of $e$ may not be assigned to \co de{bool}. | 5893 It is a static type warning if the static type of $e$ may not be assigned to \co de{bool}. |
5792 | 5894 |
5793 | 5895 |
5794 \subsection{Do} | 5896 \subsection{Do} |
5795 \LMLabel{do} | 5897 \LMLabel{do} |
5796 | 5898 |
5797 \LMHash{} | 5899 \LMHash{} |
5798 The do statement supports conditional iteration, where the condition is evaluate d after the loop. | 5900 The do statement supports conditional iteration, where the condition is evaluate d after the loop. |
5799 | 5901 |
5800 \begin{grammar} | 5902 \begin{grammar} |
5801 {\bf doStatement:} | 5903 {\bf doStatement:} |
5802 \DO{} statement \WHILE{} `(' expression `)' `{\escapegrammar ;}'% could do t op level here | 5904 \DO{} statement \WHILE{} `(' expression `)' `{\escapegrammar ;}'% could do t op level here |
5803 . | 5905 . |
5804 \end{grammar} | 5906 \end{grammar} |
5805 | 5907 |
5806 | 5908 |
5807 \LMHash{} | 5909 \LMHash{} |
5808 Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);} proceed s as follows: | 5910 Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);} proceed s as follows: |
5809 | 5911 |
5810 \LMHash{} | 5912 \LMHash{} |
5811 The statement $\{s\}$ is executed. Then, the expression $e$ is evaluated to an o bject $o$. Then, $o$ is subjected to boolean conversion (\ref{booleanConversion }), producing an object $r$. If $r$ is \FALSE{}, execution of the do statement i s complete. If $r$ is \TRUE{}, then the do statement is re-executed recursively. | 5913 The statement $\{s\}$ is executed. |
5914 If that execution {\em continues} with no label, or with a label that prefixes t he do statement (\ref{labels}), then the exection of $s$ is treated as if it had completed normally. | |
5915 | |
5916 \LMHash{} | |
5917 Then, the expression $e$ is evaluated to an object $o$. Then, $o$ is subjected t o boolean conversion (\ref{booleanConversion}), producing an object $r$. If $r$ is \FALSE{}, execution of the do statement completes normally. | |
5918 If $r$ is \TRUE{}, then the do statement is re-executed. | |
5812 | 5919 |
5813 \LMHash{} | 5920 \LMHash{} |
5814 It is a static type warning if the static type of $e$ may not be assigned to \co de{bool}. | 5921 It is a static type warning if the static type of $e$ may not be assigned to \co de{bool}. |
5815 | 5922 |
5816 \subsection{Switch} | 5923 \subsection{Switch} |
5817 \LMLabel{switch} | 5924 \LMLabel{switch} |
5818 | 5925 |
5819 \LMHash{} | 5926 \LMHash{} |
5820 The {\em switch statement} supports dispatching control among a large number of cases. | 5927 The {\em switch statement} supports dispatching control among a large number of cases. |
5821 | 5928 |
5822 \begin{grammar} | 5929 \begin{grammar} |
5823 {\bf switchStatement:} | 5930 {\bf switchStatement:} |
5824 \SWITCH{} `(' expression `)' `\{' switchCase* defaultCase? `\}'% could do top level here and in cases | 5931 \SWITCH{} `(' expression `)' `\{' switchCase* defaultCase? `\}'% could do top level here and in cases |
5825 . | 5932 . |
5826 | 5933 |
5827 | 5934 |
5828 {\bf switchCase:} | 5935 {\bf switchCase:} |
5829 label* \CASE{} expression `{\escapegrammar :}' statements | 5936 label* \CASE{} expression `{\escapegrammar :}' statements |
5830 . | 5937 . |
5831 | 5938 |
5832 {\bf defaultCase:} | 5939 {\bf defaultCase:} |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5901 \end{dartCode} | 6008 \end{dartCode} |
5902 | 6009 |
5903 proceeds as follows: | 6010 proceeds as follows: |
5904 | 6011 |
5905 \LMHash{} | 6012 \LMHash{} |
5906 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$. | 6013 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$. |
5907 | 6014 |
5908 \commentary{Note that if there are no case clauses ($n = 0$), the type of $e$ do es not matter.} | 6015 \commentary{Note that if there are no case clauses ($n = 0$), the type of $e$ do es not matter.} |
5909 | 6016 |
5910 \LMHash{} | 6017 \LMHash{} |
5911 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}$. | 6018 Next, the case clause \CASE{} $e_{1}: s_{1}$ is matched against {\code id} if it exists. If \CASE{} $e_{1}: s_{1}$ does not exist, then if there is a \DEFAULT{} clause, its statements, if any, are executed (\ref{case-execute}). |
5912 | 6019 |
5913 \LMHash{} | 6020 \LMHash{} |
5914 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. | 6021 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. |
5915 | 6022 |
5916 \LMHash{} | 6023 \LMHash{} |
5917 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement | 6024 Matching of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement |
5918 | 6025 |
5919 \begin{dartCode} | 6026 \begin{dartCode} |
5920 \SWITCH{} ($e$) \{ | 6027 \SWITCH{} ($e$) \{ |
5921 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 6028 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5922 $\ldots$ | 6029 $\ldots$ |
5923 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 6030 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5924 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ | 6031 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ |
5925 \} | 6032 \} |
5926 \end{dartCode} | 6033 \end{dartCode} |
5927 | 6034 |
5928 proceeds as follows: | 6035 against a value {\code id} proceeds as follows: |
5929 | 6036 |
5930 \LMHash{} | 6037 \LMHash{} |
5931 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su bjected to boolean conversion yielding a value $v$. | 6038 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su bjected to boolean conversion yielding a value $v$. |
5932 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}$. | 6039 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is matched against {\code id} if it exists. If \CASE{} $e_{k+1}: s_{k+1}$ does not exist, t hen the \DEFAULT{} clause's statements are executed (\ref{case-execute}). |
5933 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. | 6040 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 statements $s_h$ are t hen executed (\ref{case-execute}). |
5934 If execution reaches the point after $s_h$ then a runtime error occurs, unless $h = n+1$. | |
5935 | 6041 |
5936 \LMHash{} | 6042 \LMHash{} |
5937 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement | 6043 Matching of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement |
5938 | 6044 |
5939 \begin{dartCode} | 6045 \begin{dartCode} |
5940 \SWITCH{} ($e$) \{ | 6046 \SWITCH{} ($e$) \{ |
5941 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 6047 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5942 $\ldots$ | 6048 $\ldots$ |
5943 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 6049 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5944 \} | 6050 \} |
5945 \end{dartCode} | 6051 \end{dartCode} |
5946 | 6052 |
6053 against a value {\code id} proceeds as follows: | |
6054 | |
6055 \LMHash{} | |
6056 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su bjected to boolean conversion yielding a value $v$. | |
6057 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is matche d against {\code id} if it exists. | |
6058 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 (\ref{c ase-execute}). | |
6059 | |
6060 \LMHash{} | |
6061 \subsection{ Executing the statements of a switch case} | |
6062 \LMLabel{case-execute} | |
6063 Execution of the statements $s_h$ of a switch statement | |
6064 | |
6065 \begin{dartCode} | |
6066 \SWITCH{} ($e$) \{ | |
6067 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | |
6068 $\ldots$ | |
6069 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | |
6070 \} | |
6071 \end{dartCode} | |
6072 | |
6073 or a switch statement | |
6074 | |
6075 \begin{dartCode} | |
6076 \SWITCH{} ($e$) \{ | |
6077 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | |
6078 $\ldots$ | |
6079 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | |
6080 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ | |
6081 \} | |
6082 \end{dartCode} | |
6083 | |
5947 proceeds as follows: | 6084 proceeds as follows: |
5948 | 6085 |
5949 \LMHash{} | 6086 \LMHash{} |
5950 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su bjected to boolean conversion yielding a value $v$. | 6087 Execute $\{s_h\}$. |
5951 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut ed if it exists. | 6088 If this execution completes normally, and if $s_h$ is not the statments of the l ast case of the switch ($h = n$ if there is no \DEFAULT{} clause, $h = n+1$ if t hre is a \DEFAULT{} clause), then the execution of the switch case aborts by thr owing a runtime error. Otherwise $s_h$ are the last statements of the switch cas e, and execution of the switch case completes normally. |
5952 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. | |
5953 If execution reaches the point after $s_h$ then a runtime error occurs, unless $h = n$. | |
5954 | |
5955 | 6089 |
5956 \commentary{ | 6090 \commentary{ |
5957 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. | 6091 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. |
5958 } | 6092 } |
5959 | 6093 |
6094 If execution of $\{s_h\}$ aborts by {\em breaking} with no label, or with a labe l that prefixes the switch statement, then the execution of the switch statement completes normally. | |
6095 | |
6096 If execution of $\{s_h\}$ aborts with a continue with a label, and the label is $label_{ij}$, where $1 \le i \le n+1$ if the \SWITCH{} statement has a \DEFAULT{ }, or $1 \le i \le n$ if there is no \DEFAULT{}, and where $1 \le j \le j_{i}$, then | |
6097 execution of the switch statement continues with the case labeled by that label. | |
6098 let $h$ be the smallest number such that $h \ge i$ and $s_h$ is non-empty. If no such $h$ exists, and let $h = n + 1$ if the \SWITCH{} statement has a \DEFAULT{ }, otherwise leth $h = n$. | |
6099 The statements $s_h$ are then executed (\ref{case-execute}). | |
6100 | |
6101 If execution of $\{s_h\}$ aborts in any other way, execution of the \SWITCH{} st atement aborts in the same way. | |
6102 | |
5960 \LMHash{} | 6103 \LMHash{} |
5961 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. | 6104 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. |
5962 | 6105 |
5963 \rationale{ | 6106 \rationale{ |
5964 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) . | 6107 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) . |
5965 | 6108 |
5966 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.: | 6109 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.: |
5967 } | 6110 } |
5968 | 6111 |
5969 \begin{dartCode} | 6112 \begin{dartCode} |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6006 Execution of a \code{\RETHROW{}} statement proceeds as follows: | 6149 Execution of a \code{\RETHROW{}} statement proceeds as follows: |
6007 | 6150 |
6008 \LMHash{} | 6151 \LMHash{} |
6009 Let $f$ be the immediately enclosing function, and let \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} be the immediately enclosing catch clause (\ref{try}). | 6152 Let $f$ be the immediately enclosing function, and let \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} be the immediately enclosing catch clause (\ref{try}). |
6010 | 6153 |
6011 \rationale{ | 6154 \rationale{ |
6012 A \RETHROW{} statement always appears inside a \CATCH{} clause, and any \CATCH{} clause is semantically equivalent to some \CATCH{} clause of the form \code{\ON {} $T$ \CATCH{} (p1, p2)}. So we can assume that the \RETHROW{} is enclosed in a \CATCH{} clause of that form. | 6155 A \RETHROW{} statement always appears inside a \CATCH{} clause, and any \CATCH{} clause is semantically equivalent to some \CATCH{} clause of the form \code{\ON {} $T$ \CATCH{} (p1, p2)}. So we can assume that the \RETHROW{} is enclosed in a \CATCH{} clause of that form. |
6013 } | 6156 } |
6014 | 6157 |
6015 \LMHash{} | 6158 \LMHash{} |
6016 The current exception (\ref{throw}) is set to $p_1$, the current return value (\ ref{return}) becomes undefined, and the active stack trace (\ref{try}) is set to $p_2$. | 6159 The \RETHROW{} statement aborts by {\em throwing} with $p_1$ as the exception ob ject and $p_2$ as the stack trace. |
Lasse Reichstein Nielsen
2016/10/11 07:52:43
Another option, and probably more consistent, is t
| |
6017 | |
6018 \LMHash{} | |
6019 If $f$ is marked \ASYNC{} or \ASYNC* (\ref{functions}) and there is a dynamicall y enclosing exception handler (\ref{try}) $h$ introduced by the current activati on, control is transferred to $h$, otherwise $f$ terminates. | |
6020 | |
6021 \rationale{ | |
6022 In the case of an asynchronous function, the dynamically enclosing exception han dler is only relevant within the function. If an exception is not caught within the function, the exception value is channelled through a future or stream rathe r than propagating via exception handlers. | |
6023 } | |
6024 | |
6025 \LMHash{} | |
6026 Otherwise, control is transferred to the innermost enclosing exception handler. | |
6027 | |
6028 \commentary{The change in control may result in multiple functions terminating i f these functions do not catch the exception via a \CATCH{} or \FINALLY{} clause , both of which introduce a dynamically enclosing exception handler.} | |
6029 | 6160 |
6030 \LMHash{} | 6161 \LMHash{} |
6031 It is a compile-time error if a \code{\RETHROW{}} statement is not enclosed wit hin an \ON-\CATCH{} clause. | 6162 It is a compile-time error if a \code{\RETHROW{}} statement is not enclosed wit hin an \ON-\CATCH{} clause. |
6032 | 6163 |
6033 | 6164 |
6034 | |
6035 \subsection{ Try} | 6165 \subsection{ Try} |
6036 \LMLabel{try} | 6166 \LMLabel{try} |
6037 | 6167 |
6038 \LMHash{} | 6168 \LMHash{} |
6039 The try statement supports the definition of exception handling code in a struct ured way. | 6169 The try statement supports the definition of exception handling code in a struct ured way. |
6040 | 6170 |
6041 \begin{grammar} | 6171 \begin{grammar} |
6042 {\bf tryStatement:} | 6172 {\bf tryStatement:} |
6043 \TRY{} block (onPart+ finallyPart? $|$ finallyPart) | 6173 \TRY{} block (onPart+ finallyPart? $|$ finallyPart) |
6044 . | 6174 . |
6045 | 6175 |
6046 {\bf onPart:}catchPart block; | 6176 {\bf onPart:}catchPart block; |
6047 \ON{} type catchPart? block | 6177 \ON{} type catchPart? block |
6048 . | 6178 . |
6049 | 6179 |
6050 {\bf catchPart:} | 6180 {\bf catchPart:} |
6051 \CATCH{} `(' identifier (`,' identifier)? `)' | 6181 \CATCH{} `(' identifier (`,' identifier)? `)' |
6052 . | 6182 . |
6053 | 6183 |
6054 {\bf finallyPart:} | 6184 {\bf finallyPart:} |
6055 \FINALLY{} block | 6185 \FINALLY{} block |
6056 . | 6186 . |
6057 \end{grammar} | 6187 \end{grammar} |
6058 | 6188 |
6059 \LMHash{} | 6189 \LMHash{} |
6060 A try statement consists of a block statement, followed by at least one of: | 6190 A try statement consists of a block statement, followed by at least one of: |
6061 \begin{enumerate} | 6191 \begin{enumerate} |
6062 \item | 6192 \item |
6063 A set of \ON{}-\CATCH{} clauses, each of which specifies (either explicitly or implicitly) the type of exception object to be handled, one or two exception par ameters and a block statement. | 6193 A set of \ON{}-\CATCH{} clauses, each of which specifies (either explicitly or i mplicitly) the type of exception object to be handled, one or two exception para meters and a block statement. |
6064 \item | 6194 \item |
6065 A \FINALLY{} clause, which consists of a block statement. | 6195 A \FINALLY{} clause, which consists of a block statement. |
6066 \end{enumerate} | 6196 \end{enumerate} |
6067 | 6197 |
6068 \rationale{ | 6198 \rationale{ |
6069 The syntax is designed to be upward compatible with existing Javascript programs . The \ON{} clause can be omitted, leaving what looks like a Javascript catch cl ause. | 6199 The syntax is designed to be upward compatible with existing Javascript programs . The \ON{} clause can be omitted, leaving what looks like a Javascript catch cl ause. |
6070 } | 6200 } |
6071 | 6201 |
6072 \LMHash{} | 6202 \LMHash{} |
6073 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } {\em matches} an object $o$ if the type of $o$ is a subtype of $T$. If $T$ is a malformed or deferred type (\ref{staticTypes}), then performing a match ca uses a run time error. | 6203 A try statement of the form \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$;} is equivalent to the statement \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $\{\}$}. |
6074 | 6204 |
6075 \commentary { | 6205 \LMHash{} |
6076 It is of course a static warning if $T$ is a deferred or malformed type. | 6206 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1$) $s$} is e quivalent to an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } where $p_2$ is an identifier that does not occur anywhere else in the program. |
6077 } | 6207 |
6208 \LMHash{} | |
6209 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ $s$} is equivalent to an \ ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$} where $p_1$ and $p_2$ are identifiers that do not occur anywhere else in the program. | |
6210 | |
6211 \LMHash{} | |
6212 An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p$) $s$} is equivalent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p$, $p_2$) $s$} wher e $p_2$ is an indentifier that does not occur anywhere else in the program. | |
6213 | |
6214 An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p_1, p_2$) $s$} is equival ent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p_1, p_2$) $s$ }. | |
6078 | 6215 |
6079 \LMHash{} | 6216 \LMHash{} |
6080 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } introduces a new scope $CS$ in which final local variables specified by $p_1$ and $p_2$ are defined. The statement $s$ is enclosed within $CS$. The static typ e of $p_1$ is $T$ and the static type of $p_2$ is \code{StackTrace}. | 6217 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } introduces a new scope $CS$ in which final local variables specified by $p_1$ and $p_2$ are defined. The statement $s$ is enclosed within $CS$. The static typ e of $p_1$ is $T$ and the static type of $p_2$ is \code{StackTrace}. |
6081 | 6218 |
6082 | 6219 |
6083 \LMHash{} | 6220 \LMHash{} |
6084 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1$) $s$} is e quivalent to an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } where $p_2$ is an identifier that does not occur anywhere else in the program. | 6221 Execution of a \TRY{} statement $s$ on the form: |
6085 | 6222 \begin{dartCode} |
6223 \TRY{} b | |
6224 \ON{} $T_1$ \CATCH{} ($e_1$, $t_1$) c_1 | |
6225 \ldots{} | |
6226 \ON{} $T_n$ \CATCH{} ($e_n$, $t_n$) c_n | |
6227 \FINALLY{} f | |
6228 \end{dartCode} | |
6229 proceeds as follows: | |
6086 | 6230 |
6087 \LMHash{} | 6231 \LMHash{} |
6088 An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p$) $s$} is equivalent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p$) $s$}. An \ON{}- \CATCH{} clause of the form \code{\CATCH{} ($p_1, p_2$) $s$} is equivalent to a n \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p_1, p_2$) $s$}. | 6232 First $b$ is executed. |
6233 If execution of $b$ aborts by throwing with exception object $e$ and stack trace $t$, then $e$ and $t$ are matched against the \ON{}-\CATCH{} clauses to yield a new completion (\ref{on-catch}). | |
6089 | 6234 |
6235 Then, even if execution of $b$ aborted or matching against the \ON{}-\CATCH{} cl auses aborted, the $f$ block is executed. | |
6090 | 6236 |
6091 %If an explicit type is associated with of $p_2$, it is a static warning if that type is not \code{Object} or \DYNAMIC{}. | 6237 If execution of $f$ aborts, execution of the \TRY{} statement aborts in |
6238 the same way. | |
6239 Otherwise if execution of $b$ threw, the \TRY{} statement completes in the same way as the matching against the \ON{}-\CATCH{} clauses. | |
6240 Otherwise the \TRY{} statement completes in the same way as the execution of $b$ . | |
6241 | |
6242 \subsubsection{Matching against \ON{}-\CATCH{} clauses} | |
6243 \LMHash{} | |
6244 Matching an exception object $e$ and stack trace $t$ against a (potentially empt y) sequence of \ON{}-\CATCH{} clauses on the form: | |
6245 \begin{dartCode} | |
6246 \ON{} $T_1$ \CATCH{} ($e_1$, $st_1$) \{ $s_1$ \} | |
6247 \ldots | |
6248 \ON{} $T_n$ \CATCH{} ($e_n$, $st_n$) \{ $s_n$ \} | |
6249 \end{dartCode} | |
6092 | 6250 |
6093 \LMHash{} | 6251 \LMHash{} |
6094 The {\em active stack trace} is an object whose \code{toString()} method produce s a string that is a record of exactly those function activations within the cur rent isolate that had not completed execution at the point where the current exc eption (\ref{throw}) was thrown. | 6252 If there are no \ON{}-\CATCH{} clauses ($n = 0$), matching completes by {\em thr owing} the exception object $e$ and stack trace $t$. |
6095 %\begin{enumerate} | |
6096 %\item Started execution after the currently executing function. | |
6097 %\item Had not completed execution at the point where the exception caught by th e currently executing \ON{}-\CATCH{} clause was initially thrown. | |
6098 %\commentary{The active stack trace contains the frames between the exception ha ndling code and the original point when an exception is thrown, not where it was rethrown.} | |
6099 %\end{enumerate} | |
6100 | 6253 |
6101 \commentary{ | 6254 Otherwise the exception is matched against the first clause. |
6102 This implies that no synthetic function activations may be added to the trace, n or may any source level activations be omitted. | 6255 \LMHash{} |
6103 This means, for example, that any inlining of functions done as an optimization must not be visible in the trace. Similarly, any synthetic routines used by the implementation must not appear in the trace. | |
6104 | 6256 |
6105 Nothing is said about how any native function calls may be represented in the tr ace. | 6257 If $T_1$ is a malformed or deferred type (\ref{staticTypes}), then performing a match causes a run time error. |
6106 } | 6258 \commentary { |
6107 | 6259 It is of course a static warning if $T_i$, $1 \le i \le n$ is a deferred or malf ormed type. |
6108 \commentary{ | |
6109 Note that we say nothing about the identity of the stack trace, or what notion o f equality is defined for stack traces. | |
6110 } | |
6111 | |
6112 % Sadly, the info below cannot be computed efficiently. It would need to be comp uted at the throw point, since at latte points it might be destroyed. Native cod e in calling frames executes relative to the stack pointer, which therefore need s to be reset as each frame is unwound. This means that the | |
6113 % OS kernel can dispose of this stack memory - it is not reliably preserved. And such code must execute if only to test if the exception should be caught or sen t onward. | |
6114 | |
6115 % For each such function activation, the active stack trace includes the name of the function, the bindings of all its formal parameters, local variables and \T HIS{}, and the position at which the function was executing. | |
6116 | |
6117 % Is this controversial? We were thinking of viewing the trace as a List<Invoca tion>, | |
6118 % but that won't capture the receiver or the locals. More generally, we need a standard interface that describes these traces, so one can type the stack trace variable in the catch. | |
6119 | |
6120 \commentary{The term position should not be interpreted as a line number, but r ather as a precise position - the exact character index of the expression that raised the exception. } | |
6121 | |
6122 % A position can be represented via a Token. If we make that part of the core r eflection facility, we can state this here. | |
6123 | |
6124 \LMHash{} | |
6125 A try statement \TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $s_f$ d efines an exception handler $h$ that executes as follows: | |
6126 | |
6127 \LMHash{} | |
6128 The \ON{}-\CATCH{} clauses are examined in order, starting with $catch_1$, until either an \ON{}-\CATCH{} clause that matches the current exception (\ref{throw} ) is found, or the list of \ON{}-\CATCH{} clauses has been exhausted. If an \ON{ }-\CATCH{} clause $on-catch_k$ is found, then $p_{k1}$ is bound to the current e xception, $p_{k2}$, if declared, is bound to the active stack trace, and then $catch_k$ is executed. If no \ON{}-\CATCH{} clause is found, the \FINALLY{} clau se is executed. Then, execution resumes at the end of the try statement. | |
6129 | |
6130 | |
6131 \LMHash{} | |
6132 A finally clause \FINALLY{} $s$ defines an exception handler $h$ that executes a s follows: | |
6133 | |
6134 \LMHash{} | |
6135 Let $r$ be the current return value (\ref{return}). Then the current return valu e becomes undefined. Any open streams associated with any asynchronous for loops (\ref{asynchronousFor-in}) and yield-each (\ref{yieldEach}) statements executin g within the dynamic scope of $h$ are canceled, in the order of their nesting, i nnermost first. | |
6136 | |
6137 \rationale{ | |
6138 Streams left open by for loops that were escaped for whatever reason would be ca nceled at function termination, but it is best to cancel them as soon as possibl e. | |
6139 } | 6260 } |
6140 | 6261 |
6141 \LMHash{} | 6262 \LMHash{} |
6142 Then the \FINALLY{} clause is executed. Let $m$ be the immediately enclosing fun ction. If $r$ is defined then the current return value is set to $r$ and then: | 6263 Otherwise, if the type of $e$ is a subtype of $T_1$, then the first clause match es, and then $e_1$ is bound to the exception object $e$ and $t_1$ is bound to th e stack trace $t$, and $s_1$ is executed in this scope. |
6143 \begin{itemize} | 6264 The matching completes in the same way as this execution. |
6144 \item | |
6145 if there is a dynamically enclosing error handler $g$ defined by a \FINALLY{} c lause in $m$, control is transferred to $g$. | |
6146 \item | |
6147 Otherwise $m$ terminates. | |
6148 \end{itemize} | |
6149 | |
6150 Otherwise, execution resumes at the end of the try statement. | |
6151 | 6265 |
6152 \LMHash{} | 6266 \LMHash{} |
6153 Execution of an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} $ s$ of a try statement $t$ proceeds as follows: The statement $s$ is executed in the dynamic scope of the exception handler defined by the finally clause of $t$. Then, the current exception and active stack trace both become undefined. | 6267 Otherwise, if the first clause did not match $e$, $e$ and $t$ are recursively ma tched against the remaining \ON{}-\CATCH{} clauses: |
6154 | 6268 \begin{dartCode} |
6155 \LMHash{} | 6269 \ON{} $T_2$ \CATCH{} ($e_2$, $t_2$) \{ $s_2$ \} |
6156 Execution of a \FINALLY{} clause \FINALLY{} $s$ of a try statement proceeds as f ollows: | 6270 \ldots |
6157 | 6271 \ON{} $T_n$ \CATCH{} ($e_n$, $t_n$) \{ $s_n$ \} |
6158 \LMHash{} | 6272 \end{dartCode} |
6159 Let $x$ be the current exception and let $t$ be the active stack trace. Then the current exception and the active stack trace both become undefined. The stateme nt $s$ is executed. Then, if $x$ is defined, it is rethrown as if by a rethrow statement (\ref{rethrow}) enclosed in a \CATCH{} clause of the form \code{\CATCH {} ($v_x$, $v_t$)} where $v_x$ and $v_t$ are fresh variables bound to $x$ and $t $ respectively. | |
6160 | |
6161 | |
6162 \LMHash{} | |
6163 Execution of a try statement of the form \code{\TRY{} $s_1$ $on-catch_1 \ldots o n-catch_n$ \FINALLY{} $s_f$;} proceeds as follows: | |
6164 | |
6165 \LMHash{} | |
6166 The statement $s_1$ is executed in the dynamic scope of the exception handler de fined by the try statement. Then, the \FINALLY{} clause is executed. | |
6167 | |
6168 \commentary{ | |
6169 Whether any of the \ON{}-\CATCH{} clauses is executed depends on whether a match ing exception has been raised by $s_1$ (see the specification of the throw state ment). | |
6170 | |
6171 If $s_1$ has raised an exception, it will transfer control to the try statement' s handler, which will examine the catch clauses in order for a match as specifie d above. If no matches are found, the handler will execute the \FINALLY{} clause . | |
6172 | |
6173 If a matching \ON{}-\CATCH{} was found, it will execute first, and then the \FIN ALLY{} clause will be executed. | |
6174 | |
6175 If an exception is thrown during execution of an \ON{}-\CATCH{} clause, this wil l transfer control to the handler for the \FINALLY{} clause, causing the \FINALL Y{} clause to execute in this case as well. | |
6176 | |
6177 If no exception was raised, the \FINALLY{} clause is also executed. Execution of the \FINALLY{} clause could also raise an exception, which will cause transfer of control to the next enclosing handler. | |
6178 } | |
6179 | |
6180 \LMHash{} | |
6181 A try statement of the form \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$;} is equivalent to the statement \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $\{\}$}. | |
6182 | 6273 |
6183 | 6274 |
6184 \subsection{ Return} | 6275 \subsection{ Return} |
6185 \LMLabel{return} | 6276 \LMLabel{return} |
6186 | 6277 |
6187 \LMHash{} | 6278 \LMHash{} |
6188 The {\em return statement} returns a result to the caller of a synchronous funct ion, completes the future associated with an asynchronous function or terminate s the stream or iterable associated with a generator (\ref{functions}). | 6279 The {\em return statement} returns a result to the caller of a synchronous funct ion, completes the future associated with an asynchronous function or terminate s the stream or iterable associated with a generator (\ref{functions}). |
6189 | 6280 |
6190 | 6281 |
6191 \begin{grammar} | 6282 \begin{grammar} |
6192 {\bf returnStatement:} | 6283 {\bf returnStatement:} |
6193 \RETURN{} expression? `{\escapegrammar ;}' % could do top level here | 6284 \RETURN{} expression? `{\escapegrammar ;}' % could do top level here |
6194 . | 6285 . |
6195 \end{grammar} | 6286 \end{grammar} |
6196 | 6287 |
6197 \commentary{ | |
6198 Due to \FINALLY{} clauses, the precise behavior of \RETURN{} is a little more i nvolved. Whether the value a return statement is supposed to return is actually returned depends on the behavior of any \FINALLY{} clauses in effect when execut ing the return. A \FINALLY{} clause may choose to return another value, or throw an exception, or even redirect control flow leading to other returns or throws. All a return statement really does is set a value that is intended to be return ed when the function terminates. | |
6199 } | |
6200 | |
6201 \LMHash{} | |
6202 The {\em current return value} is a unique value specific to a given function ac tivation. It is undefined unless explicitly set in this specification. | |
6203 | |
6204 \LMHash{} | 6288 \LMHash{} |
6205 Executing a return statement \code{\RETURN{} $e$;} proceeds as follows: | 6289 Executing a return statement \code{\RETURN{} $e$;} proceeds as follows: |
6206 | 6290 |
6207 \LMHash{} | 6291 \LMHash{} |
6208 First the expression $e$ is evaluated, producing an object $o$. Next: | 6292 First the expression $e$ is evaluated, producing an object $o$. |
6209 \begin{itemize} | 6293 Then the return statement completes by \em{returning} $o$. |
6210 \item | |
6211 The current return value is set to $o$ and the current exception (\ref{throw}) a nd active stack trace (\ref{try}) become undefined. | |
6212 \item | |
6213 Let $c$ be the \FINALLY{} clause of the innermost enclosing try-finally statemen t (\ref{try}), if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$. | |
6214 \item | |
6215 Otherwise execution of the current method terminates. | |
6216 \end{itemize} | |
6217 | |
6218 \commentary{ | |
6219 In the simplest case, the immediately enclosing function is an ordinary, synchro nous non-generator, and upon function termination, the current return value is g iven to the caller. The other possibility is that the function is marked \ASYNC {}, in which case the current return value is used to complete the future associ ated with the function invocation. Both these scenarios are specified in section \ref{functionInvocation}. | |
6220 The enclosing function cannot be marked as generator (i.e, \ASYNC* or \SYNC*), s ince generators are not allowed to contain a statement of the form \code{\RETURN {} $e$;} as discussed below. | |
6221 } | |
6222 | 6294 |
6223 \LMHash{} | 6295 \LMHash{} |
6224 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. | 6296 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. |
6225 | 6297 |
6226 \LMHash{} | 6298 \LMHash{} |
6227 It is a static type warning if the body of $f$ is marked \ASYNC{} and the type \ code{Future$<$flatten(T)$>$} (\ref{functionExpressions}) may not be assigned to the declared return type of $f$. Otherwise, it is a static type warning if $T $ may not be assigned to the declared return type of $f$. | 6299 It is a static type warning if the body of $f$ is marked \ASYNC{} and the type \ code{Future$<$flatten(T)$>$} (\ref{functionExpressions}) may not be assigned to the declared return type of $f$. Otherwise, it is a static type warning if $T $ may not be assigned to the declared return type of $f$. |
6228 | 6300 |
6229 \LMHash{} | 6301 \LMHash{} |
6230 Let $S$ be the runtime type of $o$. In checked mode: | |
6231 \begin{itemize} | |
6232 \item If the body of $f$ is marked \ASYNC{} (\ref{functions}) it is a dynamic t ype error if $o$ is not \NULL{} (\ref{null}) and \code{Future$<$flatten(S)$>$} i s not a subtype of the actual return type (\ref{actualTypeOfADeclaration}) of $ f$. | |
6233 \item Otherwise, it is a dynamic type error if $o$ is not \NULL{} and the runtim e type of $o$ is not a subtype of the actual return type of $f$. | |
6234 \end{itemize} | |
6235 | |
6236 \LMHash{} | |
6237 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$ ;} appears in a generative constructor (\ref{generativeConstructors}). | 6302 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$ ;} appears in a generative constructor (\ref{generativeConstructors}). |
6238 | 6303 |
6239 \rationale{ | 6304 \rationale{ |
6240 It is quite easy to forget to add the factory prefix for a constructor, accident ally converting a factory into a generative constructor. The static checker may detect a type mismatch in some, but not all, of these cases. The rule above help s catch such errors, which can otherwise be very hard to recognize. There is no real downside to it, as returning a value from a generative constructor is meani ngless. | 6305 It is quite easy to forget to add the factory prefix for a constructor, accident ally converting a factory into a generative constructor. The static checker may detect a type mismatch in some, but not all, of these cases. The rule above help s catch such errors, which can otherwise be very hard to recognize. There is no real downside to it, as returning a value from a generative constructor is meani ngless. |
6241 } | 6306 } |
6242 | 6307 |
6243 \LMHash{} | 6308 \LMHash{} |
6244 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$ ;} appears in a generator function. | 6309 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$ ;} appears in a generator function. |
6245 | 6310 |
6246 \rationale{ | 6311 \rationale{ |
6247 In the case of a generator function, the value returned by the function is the i terable or stream associated with it, and individual elements are added to that iterable using yield statements, and so returning a value makes no sense. | 6312 In the case of a generator function, the value returned by the function is the i terable or stream associated with it, and individual elements are added to that iterable using yield statements, and so returning a value makes no sense. |
6248 } | 6313 } |
6249 | 6314 |
6250 \LMHash{} | 6315 \LMHash{} |
6251 Let $f$ be the function immediately enclosing a return statement of the form \RE TURN{}; It is a static warning $f$ is neither a generator nor a generative cons tructor and either: | 6316 Let $f$ be the function immediately enclosing a return statement of the form \RE TURN{}; It is a static warning $f$ is neither a generator nor a generative cons tructor and either: |
6252 \begin{itemize} | 6317 \begin{itemize} |
6253 \item $f$ is synchronous and the return type of $f$ may not be assigned to \VOI D{} (\ref{typeVoid}) or, | 6318 \item $f$ is synchronous and the return type of $f$ may not be assigned to \VOI D{} (\ref{typeVoid}) or, |
6254 \item $f$ is asynchronous and the return type of $f$ may not be assigned to \co de{Future$<$Null$>$}. | 6319 \item $f$ is asynchronous and the return type of $f$ may not be assigned to \co de{Future$<$Null$>$}. |
6255 \end{itemize} | 6320 \end{itemize} |
6256 | 6321 |
6257 \commentary{ | 6322 \commentary{ |
6258 Hence, a static warning will not be issued if $f$ has no declared return type, s ince the return type would be \DYNAMIC{} and \DYNAMIC{} may be assigned to \VO ID{} and to \code{Future$<$Null$>$}. However, any synchronous non-generator func tion that declares a return type must return an expression explicitly. | 6323 Hence, a static warning will not be issued if $f$ has no declared return type, s ince the return type would be \DYNAMIC{} and \DYNAMIC{} may be assigned to \VO ID{} and to \code{Future$<$Null$>$}. However, any synchronous non-generator func tion that declares a return type must return an expression explicitly. |
6259 } | 6324 } |
6260 \rationale{This helps catch situations where users forget to return a value in a return statement.} | 6325 \rationale{This helps catch situations where users forget to return a value in a return statement.} |
6261 | 6326 |
6262 \rationale{ An asynchronous non-generator always returns a future of some sort. If no expression is given, the future will be completed with \NULL{} and this mo tivates the requirement above.} \commentary{Leaving the return type of a functio n marked \ASYNC{} blank will be interpreted as \DYNAMIC{} as always, and cause no type error. Using \code{Future} or \code{Future$<$Object$>$} is acceptable as well, but any other type will cause a warning, since \NULL{} has no subtypes.} | 6327 \rationale{ An asynchronous non-generator always returns a future of some sort. If no expression is given, the future will be completed with \NULL{} and this mo tivates the requirement above.} \commentary{Leaving the return type of a functio n marked \ASYNC{} blank will be interpreted as \DYNAMIC{} as always, and cause no type error. Using \code{Future} or \code{Future$<$Object$>$} is acceptable as well, but any other type will cause a warning, since \NULL{} has no subtypes.} |
6263 | 6328 |
6264 \LMHash{} | 6329 \LMHash{} |
6265 A return statement with no expression, \code{\RETURN;} is executed as follows: | 6330 A return statement with no expression, \code{\RETURN;} is executed |
6331 by {\em returning} with no value (\ref{completion}). | |
6266 | 6332 |
6267 \LMHash{} | |
6268 If the immediately enclosing function $f$ is a generator, then: | |
6269 \begin{itemize} | |
6270 \item | |
6271 The current return value is set to \NULL{}. | |
6272 \item | |
6273 Let $c$ be the \FINALLY{} clause of the innermost enclosing try-finally statemen t, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$. | |
6274 \item | |
6275 Otherwise, execution of the current method terminates. | |
6276 \end{itemize} | |
6277 | |
6278 \LMHash{} | |
6279 Otherwise the return statement is executed by executing the statement \code{\RE TURN{} \NULL{};} if it occurs inside a method, getter, setter or factory; otherw ise, the return statement necessarily occurs inside a generative constructor, in which case it is executed by executing \code{\RETURN{} \THIS{};}. | |
6280 | |
6281 \commentary{Despite the fact that \code{\RETURN{};} is executed as if by a \code {\RETURN{} $e$;}, it is important to understand that it is not a static warning to include a statement of the form \code{\RETURN{};} | |
6282 %in a \VOID{} function; neither is it illegal | |
6283 in a generative constructor. The rules relate only to the specific syntactic for m \code{\RETURN{} $e$;}. | |
6284 } | |
6285 | |
6286 | |
6287 \rationale{ | |
6288 The motivation for formulating \code{\RETURN{};} in this way stems from the basi c requirement that all function invocations indeed return a value. Function invo cations are expressions, and we cannot rely on a mandatory typechecker to always prohibit use of \VOID{} functions in expressions. Hence, a return statement mus t always return a value, even if no expression is specified. | |
6289 | |
6290 The question then becomes, what value should a return statement return when no r eturn expression is given. In a generative constructor, it is obviously the obje ct being constructed (\THIS{}). A void function is not expected to participate i n an expression, which is why it is marked \VOID{} in the first place. Hence, th is situation is a mistake which should be detected as soon as possible. The stat ic rules help here, but if the code is executed, using \NULL{} leads to fast fai lure, which is desirable in this case. The same rationale applies for function b odies that do not contain a return statement at all. | |
6291 } | |
6292 | 6333 |
6293 \LMHash{} | 6334 \LMHash{} |
6294 It is a static warning if a function contains both one or more explicit return statements of the form \code{\RETURN;} and one or more return statements of the form \code{\RETURN{} $e$;}. | 6335 It is a static warning if a function contains both one or more explicit return statements of the form \code{\RETURN;} and one or more return statements of the form \code{\RETURN{} $e$;}. |
6295 | 6336 |
6296 | 6337 |
6297 | |
6298 | |
6299 \subsection{ Labels} | 6338 \subsection{ Labels} |
6300 \LMLabel{labels} | 6339 \LMLabel{labels} |
6301 | 6340 |
6302 \LMHash{} | 6341 \LMHash{} |
6303 A {\em label} is an identifier followed by a colon. A {\em labeled statement} is a statement prefixed by a label $L$. A {\em labeled case clause} is a case cla use within a switch statement (\ref{switch}) prefixed by a label $L$. | 6342 A {\em label} is an identifier followed by a colon. A {\em labeled statement} is a statement prefixed by a label $L$. A {\em labeled case clause} is a case cla use within a switch statement (\ref{switch}) prefixed by a label $L$. |
6304 | 6343 |
6305 \rationale{The sole role of labels is to provide targets for the break (\ref{bre ak}) and continue (\ref{continue}) statements.} | 6344 \rationale{The sole role of labels is to provide targets for the break (\ref{bre ak}) and continue (\ref{continue}) statements.} |
6306 | 6345 |
6307 %\Q{Are labels in a separate namespace? Bug 49774299} | 6346 %\Q{Are labels in a separate namespace? Bug 49774299} |
6308 | 6347 |
6309 \begin{grammar} | 6348 \begin{grammar} |
6310 {\bf label:} | 6349 {\bf label:} |
6311 identifier `{\escapegrammar :}' | 6350 identifier `{\escapegrammar :}' |
6312 . | 6351 . |
6313 \end{grammar} | 6352 \end{grammar} |
6314 | 6353 |
6315 \LMHash{} | 6354 \LMHash{} |
6316 The semantics of a labeled statement $L: s$ are identical to those of the state ment $s$. The namespace of labels is distinct from the one used for types, funct ions and variables. | 6355 Execution a labeled statement $s$, $label: s_l$, consists of executing $s_l$. |
6356 If execution of $s_l$ aborts by {\em breaking} with the label $label$, | |
6357 then execution of $s$ completes normally, | |
6358 otherwise execution of $s$ aborts in the same ways as $sl$. | |
6359 | |
6360 The namespace of labels is distinct from the one used for types, functions and v ariables. | |
6317 | 6361 |
6318 \LMHash{} | 6362 \LMHash{} |
6319 The scope of a label that labels a statement $s$ is $s$. The scope of a label th at labels a case clause of a switch statement $s$ is $s$. | 6363 The scope of a label that labels a statement $s$ is $s$. The scope of a label th at labels a case clause of a switch statement $s$ is $s$. |
6320 | 6364 |
6321 \rationale{Labels should be avoided by programmers at all costs. The motivation for including labels in the language is primarily making Dart a better target fo r code generation. | 6365 \rationale{Labels should be avoided by programmers at all costs. The motivation for including labels in the language is primarily making Dart a better target fo r code generation. |
6322 } | 6366 } |
6323 | 6367 |
6324 | 6368 |
6325 \subsection{ Break} | 6369 \subsection{ Break} |
6326 \LMLabel{break} | 6370 \LMLabel{break} |
6327 | 6371 |
6328 \LMHash{} | 6372 \LMHash{} |
6329 The {\em break statement} consists of the reserved word \BREAK{} and an optional label (\ref{labels}). | 6373 The {\em break statement} consists of the reserved word \BREAK{} and an optional label (\ref{labels}). |
6330 | 6374 |
6331 \begin{grammar} | 6375 \begin{grammar} |
6332 {\bf breakStatement:} | 6376 {\bf breakStatement:} |
6333 \BREAK{} identifier? `{\escapegrammar ;}' | 6377 \BREAK{} identifier? `{\escapegrammar ;}' |
6334 . | 6378 . |
6335 \end{grammar} | 6379 \end{grammar} |
6336 | 6380 |
6337 \LMHash{} | 6381 \LMHash{} |
6338 Let $s_b$ be a \BREAK{} statement. If $s_b$ is of the form \code{\BREAK{} $L$;} , then let $s_E$ be the innermost labeled statement with label $L$ enclosing $s_ b$. If $s_b$ is of the form \code{\BREAK{};}, then let $s_E$ be the innermost \DO{} (\ref{do}), \FOR{} (\ref{for}), \SWITCH{} (\ref{switch}) or \WHILE{} (\ref {while}) statement enclosing $s_b$. It is a compile-time error if no such state ment $s_E$ exists within the innermost function in which $s_b$ occurs. Further more, let $s_1, \ldots, s_n$ be those \TRY{} statements that are both enclosed i n $s_E$ and that enclose $s_b$, and that have a \FINALLY{} clause. Lastly, let $f_j$ be the \FINALLY{} clause of $s_j, 1 \le j \le n$. Executing $s_b$ first executes $f_1, \ldots, f_n$ in innermost-clause-first order and then terminat es $s_E$. | 6382 Let $s_b$ be a \BREAK{} statement. If $s_b$ is of the form \code{\BREAK{} $L$;} , then let $s_E$ be the innermost labeled statement with label $L$ enclosing $s_ b$. If $s_b$ is of the form \code{\BREAK{};}, then let $s_E$ be the innermost \DO{} (\ref{do}), \FOR{} (\ref{for}), \SWITCH{} (\ref{switch}) or \WHILE{} (\ref {while}) statement enclosing $s_b$. It is a compile-time error if no such state ment $s_E$ exists within the innermost function in which $s_b$ occurs. |
6339 | 6383 |
6340 \LMHash{} | 6384 \LMHash{} |
6341 If $s_E$ is an asynchronous for loop (\ref{asynchronousFor-in}), its associated stream subscription is canceled. Furthermore, let $a_k$ be the set of asynchrono us for loops and yield-each statements (\ref{yieldEach}) enclosing $s_b$ that a re enclosed in $s_E , 1 \le k \le m$, where $a_k$ is enclosed in $a_{k+1}$. Th e stream subscriptions associated with $a_j$ are canceled, $1 \le j \le m$, inne rmost first, so that $a_j$ is canceled before $a_{j+1}$. | 6385 Execution of a \BREAK{} statement \code{\BREAK{} label;} completes by {\em break ing} with the label \code{label} (\ref{completion}). |
6342 | 6386 |
6387 Execution of a \BREAK{} statement \code{\BREAK{};} completes by {\em breaking} w ithout a label (\ref{completion}). | |
6343 | 6388 |
6344 | 6389 |
6345 \subsection{ Continue} | 6390 \subsection{ Continue} |
6346 \LMLabel{continue} | 6391 \LMLabel{continue} |
6347 | 6392 |
6348 \LMHash{} | 6393 \LMHash{} |
6349 The {\em continue statement} consists of the reserved word \CONTINUE{} and an op tional label (\ref{labels}). | 6394 The {\em continue statement} consists of the reserved word \CONTINUE{} and an op tional label (\ref{labels}). |
6350 | 6395 |
6351 \begin{grammar} | 6396 \begin{grammar} |
6352 {\bf continueStatement:} | 6397 {\bf continueStatement:} |
6353 \CONTINUE{} identifier? `{\escapegrammar ;}' | 6398 \CONTINUE{} identifier? `{\escapegrammar ;}' |
6354 . | 6399 . |
6355 \end{grammar} | 6400 \end{grammar} |
6356 | 6401 |
6357 \LMHash{} | 6402 \LMHash{} |
6358 Let $s_c$ be a \CONTINUE{} statement. If $s_c$ is of the form \code{\CONTINUE{ } $L$;}, then let $s_E$ be the innermost labeled \DO{} (\ref{do}), \FOR{} (\ref{ for}) or \WHILE{} (\ref{while}) statement or case clause with label $L$ enclosin g $s_c$. If $s_c$ is of the form \code{\CONTINUE{};} then let $s_E$ be the inne rmost \DO{} (\ref{do}), \FOR{} (\ref{for}) or \WHILE{} (\ref{while}) statement enclosing $s_c$. It is a compile-time error if no such statement or case clause $s_E$ exists within the innermost function in which $s_c$ occurs. Furthermore , let $s_1, \ldots, s_n$ be those \TRY{} statements that are both enclosed in $s _E$ and that enclose $s_c$, and that have a \FINALLY{} clause. Lastly, let $f_j $ be the \FINALLY{} clause of $s_j, 1 \le j \le n$. Executing $s_c$ first exe cutes $f_1, \ldots, f_n$ in innermost-clause-first order. Then, if $s_E$ is a case clause, control is transferred to the case clause. Otherwise, $s_E$ is nece ssarily a loop and execution resumes after the last statement in the loop body. | 6403 Let $s_c$ be a \CONTINUE{} statement. If $s_c$ is of the form \code{\CONTINUE{} $L$;}, then let $s_E$ be the innermost labeled \DO{} (\ref{do}), \FOR{} (\ref{f or}) or \WHILE{} (\ref{while}) statement or case clause with label $L$ enclosing $s_c$. If $s_c$ is of the form \code{\CONTINUE{};} then let $s_E$ be the inner most \DO{} (\ref{do}), \FOR{} (\ref{for}) or \WHILE{} (\ref{while}) statement e nclosing $s_c$. It is a compile-time error if no such statement or case clause $s_E$ exists within the innermost function in which $s_c$ occurs. |
6359 | 6404 |
6360 \commentary{ | 6405 Execution of a \CONTINUE{} statement \code{\CONTINUE{} label;} completes by {\em continuing} with the label \code{label} (\ref{completion}). |
6361 In a while loop, that would be the boolean expression before the body. In a do loop, it would be the boolean expression after the body. In a for loop, it would be the increment clause. In other words, execution continues to the next itera tion of the loop. | 6406 |
6362 } | 6407 Execution of a \CONTINUE{} statement \code{\CONTINUE{};} completes by {\em conti nuing} without a label (\ref{completion}). |
6408 | |
6409 | |
6410 \subsection{ Yield and Yield-Each} | |
6411 \LMLabel{yieldAndYieldEach} | |
6412 | |
6413 \subsubsection{ Yield} | |
6414 \LMLabel{yield} | |
6363 | 6415 |
6364 \LMHash{} | 6416 \LMHash{} |
6365 If $s_E$ is an asynchronous for loop (\ref{asynchronousFor-in}), let $a_k$ be t he set of asynchronous for loops and yield-each statements (\ref{yieldEach}) enc losing $s_c$ that are enclosed in $s_E , 1 \le k \le m$, where $a_k$ is enclosed in $a_{k+1}$. The stream subscriptions associated with $a_j$ are canceled, $1 \le j \le m$, innermost first, so that $a_j$ is canceled before $a_{j+1}$. | 6417 The {\em yield statement} adds an element to the result of a generator function (\ref{functions}). |
6366 | 6418 |
6367 \subsection{ Yield and Yield-Each} | 6419 \begin{grammar} |
6368 \LMLabel{yieldAndYieldEach} | |
6369 | |
6370 \subsubsection{ Yield} | |
6371 \LMLabel{yield} | |
6372 | |
6373 \LMHash{} | |
6374 The {\em yield statement} adds an element to the result of a generator function (\ref{functions}). | |
6375 | |
6376 \begin{grammar} | |
6377 {\bf yieldStatement:} | 6420 {\bf yieldStatement:} |
6378 \YIELD{} expression `{\escapegrammar ;}' | 6421 \YIELD{} expression `{\escapegrammar ;}' |
6379 . | 6422 . |
6380 \end{grammar} | 6423 \end{grammar} |
6381 | 6424 |
6382 \LMHash{} | 6425 \LMHash{} |
6383 Execution of a statement $s$ of the form \code{\YIELD{} $e$;} proceeds as follo ws: | 6426 Execution of a statement $s$ of the form \code{\YIELD{} $e$;} proceeds as follo ws: |
6384 | 6427 |
6385 \LMHash{} | 6428 \LMHash{} |
6386 First, the expression $e$ is evaluated to an object $o$. If the enclosing functi on $m$ is marked \ASYNC* (\ref{functions}) and the stream $u$ associated with $m $ has been paused, then execution of $m$ is suspended until $u$ is resumed or c anceled. | 6429 First, the expression $e$ is evaluated to an object $o$. If the enclosing functi on $m$ is marked \ASYNC* (\ref{functions}) and the stream $u$ associated with $m $ has been paused, then the nearest enclosing asynchronous for loop (\ref{asynch ronousFor-in}), if any, is paused and execution of $m$ is suspended until $u$ is resumed or canceled. |
6387 | 6430 |
6388 \LMHash{} | 6431 \LMHash{} |
6389 Next, $o$ is added to the iterable or stream associated with the immediately enc losing function. | 6432 Next, $o$ is added to the iterable or stream associated with the immediately enc losing function. |
6390 | 6433 |
6391 \LMHash{} | 6434 \LMHash{} |
6392 If the enclosing function $m$ is marked \ASYNC* and the stream $u$ associated wi th $m$ has been canceled, then let $c$ be the \FINALLY{} clause (\ref{try}) of t he innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$ . If $h$ is undefined, the immediately enclosing function terminates. | 6435 If the enclosing function $m$ is marked \ASYNC* and the stream $u$ associated wi th $m$ has been canceled, then the \YIELD{} statement completes by {\em returnin g} without a value (\ref{completion}), otherwise it completes normally. |
6393 | 6436 |
6394 \rationale{ | 6437 \rationale{ |
6395 The stream associated with an asynchronous generator could be canceled by any co de with a reference to that stream at any point where the generator was passivat ed. Such a cancellation constitutes an irretrievable error for the generator. A t this point, the only plausible action for the generator is to clean up after i tself via its \FINALLY{} clauses. | 6438 The stream associated with an asynchronous generator could be canceled by any co de with a reference to that stream at any point where the generator was passivat ed. Such a cancellation constitutes an irretrievable error for the generator. A t this point, the only plausible action for the generator is to clean up after i tself via its \FINALLY{} clauses. |
6396 } | 6439 } |
6397 | 6440 |
6398 \LMHash{} | 6441 \LMHash{} |
6399 Otherwise, if the enclosing function $m$ is marked \ASYNC* (\ref{functions}) the n the enclosing function may suspend. | 6442 Otherwise, if the enclosing function $m$ is marked \ASYNC* (\ref{functions}) the n the enclosing function may suspend, in which case the nearest enclosing asynch ronous for loop (\ref{asynchronousFor-in}), if any, is paused first. |
6400 | 6443 |
6401 \rationale { | 6444 \rationale { |
6402 If a \YIELD{} occurred inside an infinite loop and the enclosing function never suspended, there might not be an opportunity for consumers of the enclosing str eam to run and access the data in the stream. The stream might then accumulate an unbounded number of elements. Such a situation is untenable. Therefore, we al low the enclosing function to be suspended when a new value is added to its asso ciated stream. However, it is not essential (and in fact, can be quite costly) t o suspend the function on every \YIELD{}. The implementation is free to decide h ow often to suspend the enclosing function. The only requirement is that consume rs are not blocked indefinitely. | 6445 If a \YIELD{} occurred inside an infinite loop and the enclosing function never suspended, there might not be an opportunity for consumers of the enclosing str eam to run and access the data in the stream. The stream might then accumulate an unbounded number of elements. Such a situation is untenable. Therefore, we al low the enclosing function to be suspended when a new value is added to its asso ciated stream. However, it is not essential (and in fact, can be quite costly) t o suspend the function on every \YIELD{}. The implementation is free to decide h ow often to suspend the enclosing function. The only requirement is that consume rs are not blocked indefinitely. |
6403 } | 6446 } |
6404 | 6447 |
6405 | 6448 |
6406 \LMHash{} | 6449 \LMHash{} |
6407 If the enclosing function $m$ is marked \SYNC* (\ref{functions}) then: | 6450 If the enclosing function $m$ is marked \SYNC* (\ref{functions}) then: |
6408 \begin{itemize} | 6451 \begin{itemize} |
6409 \item | 6452 \item |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6442 | 6485 |
6443 \LMHash{} | 6486 \LMHash{} |
6444 First, the expression $e$ is evaluated to an object $o$. | 6487 First, the expression $e$ is evaluated to an object $o$. |
6445 | 6488 |
6446 \LMHash{} | 6489 \LMHash{} |
6447 If the immediately enclosing function $m$ is marked \SYNC* (\ref{functions}), th en: | 6490 If the immediately enclosing function $m$ is marked \SYNC* (\ref{functions}), th en: |
6448 \begin{enumerate} | 6491 \begin{enumerate} |
6449 \item It is a dynamic error if the class of $o$ does not implement \code{Iterabl e}. Otherwise | 6492 \item It is a dynamic error if the class of $o$ does not implement \code{Iterabl e}. Otherwise |
6450 \item The method \cd{iterator} is invoked upon $o$ returning an object $i$. | 6493 \item The method \cd{iterator} is invoked upon $o$ returning an object $i$. |
6451 \item \label{moveNext} The \cd{moveNext} method of $i$ is invoked on it with no arguments. If \cd{moveNext} returns \FALSE{} execution of $s$ is complete. Other wise | 6494 \item \label{moveNext} The \cd{moveNext} method of $i$ is invoked on it with no arguments. If \cd{moveNext} returns \FALSE{} execution of $s$ is complete. Other wise |
6452 \item The getter \cd{current} is invoked on $i$. If the invocation raises an exc eption $ex$, execution of $s$ throws $ex$. Otherwise, the result $x$ of the gett er invocation is added to the iterable associated with $m$. | 6495 \item The getter \cd{current} is invoked on $i$. If the invocation {\em throws} an exception $ex$, execution of $s$ aborts in the same way. Otherwise, the resul t $x$ of the getter invocation is added to the iterable associated with $m$. |
6453 Execution of the function $m$ immediately enclosing $s$ is suspended until the n ullary method \code{moveNext()} is invoked upon the iterator used to initiate th e current invocation of $m$, at which point execution of $s$ continues at \ref{m oveNext}. | 6496 Execution of the function $m$ immediately enclosing $s$ is suspended until the n ullary method \code{moveNext()} is invoked upon the iterator used to initiate th e current invocation of $m$, at which point execution of $s$ continues at \ref{m oveNext}. |
6454 \item | 6497 \item |
6455 The current call to \code{moveNext()} returns \TRUE. | 6498 The current call to \code{moveNext()} returns \TRUE. |
6456 \end{enumerate} | 6499 \end{enumerate} |
6457 | 6500 |
6458 \LMHash{} | 6501 \LMHash{} |
6459 If $m$ is marked \ASYNC* (\ref{functions}), then: | 6502 If $m$ is marked \ASYNC* (\ref{functions}), then: |
6460 \begin{itemize} | 6503 \begin{itemize} |
6461 \item It is a dynamic error if the class of $o$ does not implement \code{Stream }. Otherwise | 6504 \item It is a dynamic error if the class of $o$ does not implement \code{Stream }. Otherwise |
6462 \item For each element $x$ of $o$: | 6505 \item The nearest enclosing asynchronous for loop (\ref{asynchronousFor-in}), if any, is paused. |
6506 \item The $o$ stream is listened to, creating a subscription $s$, and for each e vent $x$, or error $e$ with stack trace $t$, of $s$: | |
6463 \begin{itemize} | 6507 \begin{itemize} |
6464 \item | 6508 \item |
6465 If the stream $u$ associated with $m$ has been paused, then execution of $m$ is suspended until $u$ is resumed or canceled. | 6509 If the stream $u$ associated with $m$ has been paused, then execution of $m$ is suspended until $u$ is resumed or canceled. |
6466 \item | |
6467 If the stream $u$ associated with $m$ has been canceled, then let $c$ be the \FI NALLY{} clause (\ref{try}) of the innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is define d, control is transferred to $h$. If $h$ is undefined, the immediately enclosing function terminates. | |
6468 \item | 6510 \item |
6469 Otherwise, $x$ is added to the stream associated with $m$ in the order it appea rs in $o$. The function $m$ may suspend. | 6511 If the stream $u$ associated with $m$ has been canceled, |
6512 then $s$ is canceled by evaluating \code{\AWAIT{} v.cancel()} where $v$ is a fre sh variable referencing the stream subscription $s$. | |
6513 Then, if the cancel completed normally, the stream execution of $s$ aborts by {\ em returning} with no value (\ref{completion}). | |
6514 \item | |
6515 Otherwise, $x$, or $e$ with $t$, are added to the stream associated with $m$ in the order they appears in $o$. The function $m$ may suspend. | |
6470 \end{itemize} | 6516 \end{itemize} |
6471 \item If the stream $o$ is done, execution of $s$ is complete. | 6517 \item If the stream $o$ is done, execution of $s$ completes normally. |
6472 \end{itemize} | 6518 \end{itemize} |
6473 | 6519 |
6474 | 6520 |
6475 \LMHash{} | 6521 \LMHash{} |
6476 It is a compile-time error if a yield-each statement appears in a function that is not a generator function. | 6522 It is a compile-time error if a yield-each statement appears in a function that is not a generator function. |
6477 | 6523 |
6478 \LMHash{} | 6524 \LMHash{} |
6479 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. It is a static type warning if $T$ may not be assigned to the declared ret urn type of $f$. If $f$ is synchronous it is a static type warning if $T$ may not be assigned to \code{Iterable}. If $f$ is asynchronous it is a static type warning if $T$ may not be assigned to \code{Stream}. | 6525 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. It is a static type warning if $T$ may not be assigned to the declared ret urn type of $f$. If $f$ is synchronous it is a static type warning if $T$ may not be assigned to \code{Iterable}. If $f$ is asynchronous it is a static type warning if $T$ may not be assigned to \code{Stream}. |
6480 | 6526 |
6481 | 6527 |
6482 \subsection{ Assert} | 6528 \subsection{ Assert} |
6483 \LMLabel{assert} | 6529 \LMLabel{assert} |
6484 | 6530 |
6485 \LMHash{} | 6531 \LMHash{} |
6486 An {\em assert statement} is used to disrupt normal execution if a given boolean condition does not hold. | 6532 An {\em assert statement} is used to disrupt normal execution if a given boolean condition does not hold. |
6487 | 6533 |
6488 \begin{grammar} | 6534 \begin{grammar} |
6489 {\bf assertStatement:} | 6535 {\bf assertStatement:} |
6490 assert `(' expression `)' `{\escapegrammar ;}' | 6536 assert `(' expression `)' `{\escapegrammar ;}' |
6491 . | 6537 . |
6492 \end{grammar} | 6538 \end{grammar} |
6493 | 6539 |
6494 \LMHash{} | 6540 \LMHash{} |
6495 The assert statement has no effect in production mode. In checked mode, executio n of an assert statement \code{\ASSERT{}($e$);} proceeds as follows: | 6541 The assert statement has no effect in production mode. In checked mode, executio n of an assert statement \code{\ASSERT{}($e$);} proceeds as follows: |
6496 | 6542 |
6497 \LMHash{} | 6543 \LMHash{} |
6498 The expression $e$ is evaluated to an object $o$. If the class of $o$ is a subty pe of \code{Function} then let $r$ be the result of invoking $o$ with no argumen ts. Otherwise, let $r$ be $o$. | 6544 The expression $e$ is evaluated to an object $o$. If the class of $o$ is a subty pe of \code{Function} then let $r$ be the result of invoking $o$ with no argumen ts. Otherwise, let $r$ be $o$. |
6499 It is a dynamic type error if $o$ is not of type \code{bool} or of type \code{Fu nction}, or if $r$ is not of type \code{bool}. If $r$ is \FALSE{}, we say that the assertion failed. If $r$ is \TRUE{}, we say that the assertion succeeded. If the assertion succeeded, execution of the assert statement is complete. If the assertion failed, an \code{AssertionError} is thrown. | 6545 It is a dynamic type error if $o$ is not of type \code{bool} or of type \code{Fu nction}, or if $r$ is not of type \code{bool}. If $r$ is \FALSE{}, we say that the assertion failed. If $r$ is \TRUE{}, we say that the assertion succeeded. If the assertion succeeded, execution of the assert statement is complete. If the assertion failed, the execution {\em throws} an \code{AssertionError} with a sta ck trace corresponding to the \ASSERT{} statement. |
6500 | 6546 |
6501 %\Q{Might be cleaner to define it as \code{if (!$e$) \{\THROW{} \NEW{} Assertion Error();\}} (in checked mode only). | 6547 %\Q{Might be cleaner to define it as \code{if (!$e$) \{\THROW{} \NEW{} Assertion Error();\}} (in checked mode only). |
6502 %What about an error message as part of the assert?} | 6548 %What about an error message as part of the assert?} |
6503 | 6549 |
6504 \LMHash{} | 6550 \LMHash{} |
6505 It is a static type warning if the type of $e$ may not be assigned to either \ code{bool} or $() \rightarrow$ \code{bool}. | 6551 It is a static type warning if the type of $e$ may not be assigned to either \ code{bool} or $() \rightarrow$ \code{bool}. |
6506 | 6552 |
6507 \rationale{Why is this a statement, not a built in function call? Because it is handled magically so it has no effect and no overhead in production mode. Also, in the absence of final methods. one could not prevent it being overridden (thou gh there is no real harm in that). It cannot be viewed as a function call that is being optimized away because the argument might have side effects. | 6553 \rationale{Why is this a statement, not a built in function call? Because it is handled magically so it has no effect and no overhead in production mode. Also, in the absence of final methods. one could not prevent it being overridden (thou gh there is no real harm in that). It cannot be viewed as a function call that is being optimized away because the argument might have side effects. |
6508 } | 6554 } |
6509 | 6555 |
(...skipping 1387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7897 | 7943 |
7898 The invariant that each normative paragraph is associated with a line | 7944 The invariant that each normative paragraph is associated with a line |
7899 containing the text \LMHash{} should be maintained. Extra occurrences | 7945 containing the text \LMHash{} should be maintained. Extra occurrences |
7900 of \LMHash{} can be added if needed, e.g., in order to make | 7946 of \LMHash{} can be added if needed, e.g., in order to make |
7901 individual \item{}s in itemized lists addressable. Each \LM.. command | 7947 individual \item{}s in itemized lists addressable. Each \LM.. command |
7902 must occur on a separate line. \LMHash{} must occur immediately | 7948 must occur on a separate line. \LMHash{} must occur immediately |
7903 before the associated paragraph, and \LMLabel must occur immediately | 7949 before the associated paragraph, and \LMLabel must occur immediately |
7904 after the associated \section{}, \subsection{} etc. | 7950 after the associated \section{}, \subsection{} etc. |
7905 | 7951 |
7906 ---------------------------------------------------------------------- | 7952 ---------------------------------------------------------------------- |
OLD | NEW |