July 2000 Draft
JavaScript 2.0
Core Language
Statements
previousupnext

Friday, May 26, 2000

Most of the behavior of statements is the same as in JavaScript 1.5. Differences are highlighted below.

  {abbrevabbrevNoShortIffull}
TopStatement 
   Statement
|  AttributeDefinition NoninsertableSemicolon
|  LanguageDeclaration NoninsertableSemicolon
|  PackageDefinition
Statement 
   AnnotatedDefinition
|  EmptyStatement
|  ExpressionStatement Semicolon
|  AnnotatedBlock
|  LabeledStatement
|  IfStatement
|  SwitchStatement
|  DoStatement Semicolon
|  WhileStatement
|  ForStatement
|  WithStatement
|  ContinueStatement Semicolon
|  BreakStatement Semicolon
|  ReturnStatement Semicolon
|  ThrowStatement Semicolon
|  TryStatement
|  ImportStatement Semicolon
|  UseStatement Semicolon
Semicolonabbrev 
   ;
|  VirtualSemicolon
|  «empty»
SemicolonabbrevNoShortIf 
   ;
|  VirtualSemicolon
|  «empty»
Semicolonfull 
   ;
|  VirtualSemicolon
NoninsertableSemicolonabbrev 
   ;
|  «empty»
NoninsertableSemicolonfull  ;

The Semicolon productions allow both grammatical and line-break semicolon insertion. The NoninsertableSemicolon productions allow only grammatical semicolon insertion.

Empty Statement

EmptyStatement  ;

Expression Statement

ExpressionStatement  [lookahead{function{}] ExpressionallowIn

Block

AnnotatedBlock 
   Block
|  [lookahead{package}] Attributes Block
|  package [no line break] Block
Block  { TopStatements }
TopStatements 
   «empty»
|  TopStatementsPrefix TopStatementabbrev
TopStatementsPrefix 
   «empty»
|  TopStatementsPrefix TopStatementfull

Annotated Blocks

A block can be annotated with attributes as follows:

   Attribute ... Attribute { 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 {}
  }
}

Scope Blocks

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.

Compiler Blocks

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)?

Labeled Statements

LabeledStatement  Identifier : Statement

If Statement

IfStatementabbrev 
   if ParenthesizedExpression Statementabbrev
|  if ParenthesizedExpression StatementabbrevNoShortIf else Statementabbrev
IfStatementfull 
   if ParenthesizedExpression Statementfull
|  if ParenthesizedExpression StatementabbrevNoShortIf else Statementfull
IfStatementabbrevNoShortIf  if ParenthesizedExpression StatementabbrevNoShortIf else StatementabbrevNoShortIf

The semicolon is optional before the else.

Switch Statement

SwitchStatement  switch ParenthesizedExpression { CaseStatements }
CaseStatement 
   Statement
|  CaseLabel
CaseLabel 
   case ExpressionallowIn :
|  default :
CaseStatements 
   «empty»
|  CaseLabel
|  CaseLabel CaseStatementsPrefix CaseStatementabbrev
CaseStatementsPrefix 
   «empty»
|  CaseStatementsPrefix CaseStatementfull

Do-While Statement

DoStatement  do Statementabbrev while ParenthesizedExpression

The semicolon is optional before the closing while.

While Statement

WhileStatement  while ParenthesizedExpression Statement

For Statements

ForStatement 
   for ( ForInitializer ; OptionalExpression ; OptionalExpression ) Statement
|  for ( ForInBinding in ExpressionallowIn ) Statement
ForInitializer 
   «empty»
|  ExpressionnoIn
|  Attributes VariableDefinitionKind VariableBindingListnoIn
ForInBinding 
   PostfixExpression
|  Attributes VariableDefinitionKind VariableBindingnoIn

With Statement

WithStatement  with ParenthesizedExpression Statement

Continue and Break Statements

ContinueStatement 
   continue
|  continue [no line break] Identifier
BreakStatement 
   break
|  break [no line break] Identifier

Return Statement

ReturnStatement 
   return
|  return [no line break] ExpressionallowIn

Throw Statement

ThrowStatement  throw [no line break] ExpressionallowIn

Try Statement

TryStatement 
   try AnnotatedBlock CatchClauses
|  try AnnotatedBlock FinallyClause
|  try AnnotatedBlock CatchClauses FinallyClause
CatchClauses 
   CatchClause
|  CatchClauses CatchClause
CatchClause  catch ( TypedIdentifier ) AnnotatedBlock
FinallyClause  finally AnnotatedBlock

Programs

Program  TopStatements

Waldemar Horwat
Last modified Friday, May 26, 2000
previousupnext