July 2000 Draft
JavaScript 2.0
Core Language
Statements
|
Friday, May 26, 2000
Most of the behavior of statements is the same as in JavaScript 1.5. Differences are highlighted below.
;
;
;
The Semicolon productions allow both grammatical and line-break semicolon insertion. The NoninsertableSemicolon productions allow only grammatical semicolon insertion.
A block can be annotated with attributes as follows:
{
Statement ... Statement }
Such a block behaves like a regular block except that every declaration inside that block (but not inside any enclosed
scope) by default uses the attributes given by the block. To avoid syntactic confusion with a PackageDefinition,
an AnnotatedBlock must not start with a package
attribute unless the package
attribute is the only attribute.
Annotated blocks are useful to define several items without having to repeat attributes for each one. For example,
class foo { var z:Integer; public var a; private var b; public function f() {} public function g(x:Integer):Boolean {} }
is equivalent to:
class foo { var z:Integer; public { var a; private var b; function f() {} function g(x:Integer):Boolean {} } }
A scope block has the syntax:
scope
{
Statement ... Statement }
A scope block behaves like a regular block except that it forms its own scope. Variable and function definitions without an Attribute prefix inside the scope block belong to that block instead of the enclosing scope.
A compiler block has the syntax:
compile
{
Statement ... Statement }
The compile attribute is a hint that the block may be (but does not have to be) evaluated early. The statements inside this block should depend only on each other, on the results of earlier compiler blocks, and on properties of the environment that are designated as being available early. Other than perhaps being evaluated early, compiler blocks respect all of the scope rules and semantics of the enclosing program. Any definitions introduced by a compiler block are saved and reintroduced at normal evaluation time. On the other hand, side effects may or may not be reintroduced at normal evaluation time, so compiler blocks should not rely on side effects.
compile
is an attribute, so it may also be applied to individual definitions without
enclosing them in a block.
As an example, after defining
compile var x = 2; function f1() { compile { var y = 5; var x = 1; while (y) x *= y--; } return ++x; } function f2() { compile { var y = x; } return x+y; }
the value of global x
will still be 2
, calling f1()
will always return 121
,
and calling f2()
will return 4
. If the statement x=5
is then evaluated at the global
level, f1()
will still return 121
because it uses its own local x
. On the other hand,
calling f2()
may return either 7
or 10
at the implementation's discretion -- 7
if the implementation evaluated the compile
block early and saved the value of y
or 10
if it didn't. As this example illustrates, it is poor technique to define variables inside compiler blocks;
constants are usually better.
A fully dynamic implementation of JavaScript 2.0 may choose to ignore the compile
attribute
and evaluate all compiler blocks at normal evaluation time. A fully static implementation may require that all user-defined
types and attributes be defined inside compiler blocks.
Should const
definitions with simple constant expressions such as const four = 2+2
be treated as though they were implicitly compiler definitions (compile const four = 2+2
)?
if
ParenthesizedExpression StatementabbrevNoShortIf else
StatementabbrevNoShortIfThe semicolon is optional before the else
.
The semicolon is optional before the closing while
.
Waldemar Horwat Last modified Friday, May 26, 2000 |