April 2002 Draft
JavaScript 2.0
Formal Description
Syntactic Semantics
|
|
Monday, April 22, 2002
The syntactic semantics describe the actions the parser takes to evaluate a JavaScript 2.0 program. For convenience, the syntactic
grammar is repeated here. The starting nonterminal is Program. See also the
description of the semantic notation.
The semantics are under construction. Many execution paths resulting in ???? represent semantics yet to be implemented.
This document is also available as a Word 98 rtf file.
Terminals
General tokens: Identifier Number
RegularExpression String
VirtualSemicolon
Punctuation tokens: !
!=
!==
%
%=
&
&&
&&=
&=
(
)
*
*=
+
++
+=
,
-
--
-=
.
...
/
/=
:
::
;
<
<<
<<=
<=
=
==
===
>
>=
>>
>>=
>>>
>>>=
?
[
]
^
^=
^^
^^=
{
|
|=
||
||=
}
~
Reserved words: abstract
as
break
case
catch
class
const
continue
default
delete
do
else
export
extends
false
final
finally
for
function
if
implements
import
in
instanceof
interface
is
namespace
new
null
package
private
public
return
static
super
switch
this
throw
true
try
typeof
use
var
void
while
with
Future reserved words: debugger
enum
goto
native
protected
synchronized
throws
transient
volatile
Non-reserved words: exclude
get
include
named
set
Data Model
Errors
tag compileExpressionError;
tag argumentMismatchError;
Objects
Undefined
Null
Strings
Namespaces
Qualified Names
Attributes
Classes
if c = d then return true
else
if s =
none then return false end if;
end if
end proc;
Method Closures
Prototype Instances
Class Instances
Slots
Packages
Global Objects
Objects with Limits
References
Signatures
requiredPositional:
Class[],
optionalPositional:
Class[],
end tuple;
Argument Lists
Unary Operators
Binary Operators
Modes of expression evaluation
Contexts
Labels
Environments
Members
Data Operations
Numeric Utilities
if i < 231 then return i else return i – 232 end if
end proc;
if x {+, –, NaN} then return 0 end if;
end proc;
Object Utilities
objectType
hasType
toBoolean
case o of
Float64 do return o {
+zero,
–zero,
NaN};
end case
end proc;
toNumber
case o of
Null {
false}
do return +zero;
{true} do return 1.0;
end case
end proc;
toString
case o of
{false} do return “false
”;
{true} do return “true
”;
end case
end proc;
toPrimitive
assignmentConversion
unaryPlus
unaryNot
Attributes
if b = false then return false
elsif a {
none,
true}
then return b
elsif b = true then return a
if a = b then return a
return CompoundAttributenamespaces: {
a,
b},
explicit:
false,
dynamic:
false,
compile:
false,
memberMod:
none,
overrideMod:
none,
prototype:
false,
unused:
false
end if
else
Both a and b are compound attributes. Ensure that they have no conflicting
contents.
else
end if
end if
end proc;
case a of
return CompoundAttributenamespaces: {},
explicit:
false,
dynamic:
false,
compile:
false,
memberMod:
none,
overrideMod:
none,
prototype:
false,
unused:
false;
return CompoundAttributenamespaces: {
a},
explicit:
false,
dynamic:
false,
compile:
false,
memberMod:
none,
overrideMod:
none,
prototype:
false,
unused:
false;
end case
end proc;
Objects with Limits
References
Slots
matchingSlots:
Slot{} {
s |
s o.
slots such that s.
id =
id};
return the one element of matchingSlots
end proc;
Environments
if some c env satisfies c Class then
Let
c be the first element of
env that is a
Class.
return c
end if;
end proc;
if i 0
and env[
i]
Class then i i – 1
end if;
return env[0 ... i]
end proc;
return regionalEnv[|regionalEnv| – 1]
end proc;
Adding Static Definitions
if a.
compile then memberMod static else memberMod defaultMemberMod end if
end if;
innerFrame:
Frame regionalEnv[0];
otherFramesInRegion:
Frame[]
regionalEnv[1 ...];
regionalFrame:
Frame regionalEnv[|
regionalEnv| – 1];
if regionalFrame Class then c regionalFrame end if;
***** If in a class, consider overrides and adjust list of namespaces.
end if;
for each frame otherFramesInRegion do
end for each;
end if;
????
end proc;
regionalFrame:
Frame regionalEnv[|
regionalEnv| – 1];
env is either the
Global frame or a
FunctionFrame because hoisting only occurs into global or
function scope.
existingBindings:
StaticBinding{}
{
b |
b regionalFrame.
staticReadBindings regionalFrame.
staticWriteBindings such that
b.
qname =
qname};
if existingBindings = {} then
end if;
regionalFrame.staticReadBindings regionalFrame.staticReadBindings newBindings;
regionalFrame.staticWriteBindings
regionalFrame.staticWriteBindings newBindings
else
A hoisted binding of the same var
already exists, so there is no need to create
another one.
end if
end proc;
Adding Instance Definitions
for each ns namespaces do
multiname multiname {qname};
if overriddenMember =
none then overriddenMember m
end if
end if
end for each;
return OverrideStatusoverriddenMember:
overriddenMember,
multiname:
multiname
end proc;
if namespaces = {} then
else
end if;
case access of
end case;
end if;
if expectMethod then
else
end if;
return os
end proc;
Environmental Lookup
for each frame env do
end for each;
end proc;
while i < |env| do
if result none then return result end if;
i i + 1
end while;
end proc;
while i < |env| do
if result =
ok then return end if;
i i + 1
end while;
if createIfMissing then
Now try to write the variable into g again, this time allowing new dynamic bindings
to be created dynamically.
if result =
ok then return end if
end if
end if;
end proc;
Property Lookup
case access of
end case;
if matchingBindings = {}
then return none end if;
Note that if the same member was found via several different bindings b, then it will
appear only once in the set matchingMembers.
if |matchingMembers| > 1 then
This access is ambiguous because the bindings it found belong to several different members in the
same class.
end if;
return the one element of matchingMembers
end proc;
case access of
end case;
matchingStaticBindings:
StaticBinding{}
{
b |
b staticBindings such that b.
qname multiname};
Note that if the same member was found via several different bindings b, then it will
appear only once in the set matchingStaticMembers.
if matchingStaticMembers {} then
if |matchingStaticMembers| = 1 then
return the one element of matchingStaticMembers
else
This access is ambiguous because the bindings it found belong to several different static
members in the same class.
end if
end if;
If a static member wasn't found in a class, look for an instance member in that class as
well.
case access of
end case;
Note that if the same
InstanceMember was found
via several different bindings
b, then it will appear only once in the set
matchingInstanceMembers.
if matchingInstanceMembers {} then
if |matchingInstanceMembers| = 1 then
Return the qualified name of any matching binding. It doesn’t matter which because they
all refer to the same
InstanceMember, and if one is
overridden by a subclass then all must be overridden in the same way by that subclass.
else
This access is ambiguous because the bindings it found belong to several different members in
the same class.
end if
end if;
end while;
end proc;
Start from the root class (Object
) and proceed through more specific classes that are
ancestors of c.
case access of
end case;
Note that if the same
InstanceMember was found
via several different bindings
b, then it will appear only once in the set
matchingMembers.
if matchingInstanceMembers {} then
if |matchingInstanceMembers| = 1 then
Return the qualified name of any matching binding. It doesn’t matter which because they
all refer to the same
InstanceMember, and if one is
overridden by a subclass then all must be overridden in the same way by that subclass.
else
This access is ambiguous because the bindings it found belong to several different members in
the same class.
end if
end if
end for each;
end proc;
if qname =
none then return none end if;
case access of
end case;
if some b instanceBindings satisfies b.
qname =
qname then return b.
content
end if;
end while;
end proc;
Reading a Property
case container of
case kind of
end case;
case this of
end case;
if superclass =
none then return none end if;
end case
end proc;
Writing a Property
case container of
case kind of
end case;
end if;
if superclass =
none then return none end if;
end case
end proc;
end if;
if not createIfMissing then return none end if;
Before trying to create a new dynamic property, check that there is no read-only fixed property with
the same name.
case container of
end case;
end proc;
Deleting a Property
Operator Dispatch
Unary Operators
return best.
f(
this,
getObject(
operand),
args,
phase)
end if;
end proc;
Binary Operators
if some best applicableOps satisfies
(
every m2 applicableOps satisfies isBinaryDescendant(
best,
m2))
then
end if;
end proc;
Deferred Validation
deferredValidators: (() ())[]
[];
Expressions
Syntax
{allowIn, noIn}
Terminal Actions
Identifiers
Syntax
Identifier
| get
| set
| exclude
| include
| named
Semantics
Qualified Identifiers
Syntax
SimpleQualifiedIdentifier
Validation and Evaluation
Unit Expressions
Syntax
| Number [no line break] String
Validation
Evaluation
Primary Expressions
Syntax
null
| true
| false
| public
| Number
| String
| this
| RegularExpression
Validation
Evaluation
Note that
Validate ensured that
this cannot be
none at this point.
return this;
end proc;
Function Expressions
Syntax
Validation
Evaluation
Object Literals
Syntax
Validation
[
FieldName String]
do return {
Value[
String]};
end proc;
Evaluation
Array Literals
Syntax
Super Expressions
Syntax
Validation
Evaluation
Note that
Validate ensured that
this cannot be
none at this point.
Note that
Validate ensured that
limit cannot be
none at this point.
end proc;
Note that
Validate ensured that
limit cannot be
none at this point.
end proc;
Postfix Expressions
Syntax
Validation
Evaluation
Member Operators
Syntax
Validation
Evaluation
Unary Operators
Syntax
Validation
Evaluation
Multiplicative Operators
Syntax
MultiplicativeExpressionOrSuper
Validation
Evaluation
Additive Operators
Syntax
AdditiveExpressionOrSuper
Validation
Evaluation
Bitwise Shift Operators
Syntax
Validation
Evaluation
Relational Operators
Syntax
RelationalExpressionallowIn
RelationalExpressionOrSuper
Validation
Evaluation
Equality Operators
Syntax
EqualityExpressionOrSuper
Validation
Evaluation
Binary Bitwise Operators
Syntax
BitwiseAndExpressionOrSuper
BitwiseXorExpressionOrSuper
BitwiseOrExpressionOrSuper
Validation
Evaluation
Binary Logical Operators
Syntax
Validation
Evaluation
Conditional Operator
Syntax
Validation
Evaluation
Assignment Operators
Syntax
*=
| /=
| %=
| +=
| -=
| <<=
| >>=
| >>>=
| &=
| ^=
| |=
Semantics
Validation
Evaluation
Comma Expressions
Syntax
Validation
Evaluation
Type Expressions
Syntax
Validation
Evaluation
Statements
Syntax
{abbrev, noShortIf, full}
;
| VirtualSemicolon
| «empty»
SemicolonnoShortIf
;
| VirtualSemicolon
| «empty»
Semicolonfull
;
| VirtualSemicolon
Validation
Evaluation
Empty Statement
Syntax
Expression Statement
Syntax
Validation
Evaluation
Super Statement
Syntax
Validation
Evaluation
Block Statement
Syntax
Validation
compileFrame:
BlockFrame
new BlockFramestaticReadBindings: {},
staticWriteBindings: {},
plurality:
pl;
CompileFrame[
Block]
compileFrame;
end proc;
Evaluation
Labeled Statements
Syntax
Validation
Evaluation
If Statement
Syntax
Validation
Evaluation
Switch Statement
Syntax
Do-While Statement
Syntax
Validation
Evaluation
While Statement
Syntax
Validation
Evaluation
For Statements
Syntax
With Statement
Syntax
Continue and Break Statements
Syntax
Validation
Evaluation
Return Statement
Syntax
Validation
Evaluation
Throw Statement
Syntax
Validation
Evaluation
Try Statement
Syntax
FinallyClause finally
Block
Directives
Syntax
Validation
if attr3 = false then return cxt end if;
return Validate[
Directives](
cxt,
env,
jt,
pl,
attr3);
if attr {
none,
true}
then return Validate[
Pragma](
cxt)
end if
end proc;
return Validate[
Directiveabbrev](
cxt2,
env,
jt,
pl,
attr)
end proc;
return Validate[
Directivefull](
cxt2,
env,
jt,
pl,
attr)
end proc;
Evaluation
Attributes
Syntax
abstract
| final
| private
| static
Validation
Evaluation
if a = false then return false end if;
end proc;
return CompoundAttributenamespaces: {},
explicit:
false,
dynamic:
false,
compile:
false,
memberMod:
abstract,
overrideMod:
none,
prototype:
false,
unused:
false;
return CompoundAttributenamespaces: {},
explicit:
false,
dynamic:
false,
compile:
false,
memberMod:
final,
overrideMod:
none,
prototype:
false,
unused:
false;
Note that
Validate ensured that
c cannot be
none at this point.
return CompoundAttributenamespaces: {},
explicit:
false,
dynamic:
false,
compile:
false,
memberMod:
static,
overrideMod:
none,
prototype:
false,
unused:
false
end proc;
Use Directive
Syntax
Validation
for each v values do
namespaces namespaces {v}
end for each;
end proc;
Import Directive
Syntax
Include Directive
Syntax
IncludeDirective include
[no line break]
String
Pragma
Syntax
true
| false
| Number
| -
Number
| String
Validation
if name = “strict
” then
return Contextstrict:
true, other fields from
cxt
end if;
if value =
false then return Contextstrict:
false, other fields from
cxt end if
end if;
if name = “ecmascript
” then
if value {
undefined, 4.0}
then return cxt end if;
if value {1.0, 2.0, 3.0} then
An implementation may optionally modify cxt to disable features not available in
ECMAScript Edition value other than subsequent pragmas.
return cxt
end if
end if;
end proc;
Definitions
Export Definition
Syntax
Variable Definition
Syntax
Semantics
Syntax
Validation
else
localFrame:
Frame env[0];
end if;
end if;
case memberMod of
regionalFrame:
Frame regionalEnv[|
regionalEnv| – 1];
end if;
for each frame regionalEnv[1 ...] do
end for each;
end if;
Mark the bindings of
multiname as
forbidden in all non-innermost frames in the current region if
they haven’t been marked as such already.
for each frame regionalEnv[1 ...] do
end for each;
proc deferredStaticValidate()
end proc;
deferredStaticValidate();
else
end if;
At this point
localFrame Class;
end proc;
case memberMod of
m
new InstanceVariableevalInitialValue:
evalInitialValue,
immutable:
immutable,
final:
false;
m
new InstanceVariableevalInitialValue:
evalInitialValue,
immutable:
immutable,
final:
true
end case;
proc deferredInstanceValidate()
end proc;
end case
end if
end proc;
Evaluation
localFrame:
Frame env[0];
Note that the
members set consists of exactly one
Variable element because
localFrame was constructed
with that
Variable inside
Validate.
end if;
end case
end proc;
Simple Variable Definition
Syntax
A SimpleVariableDefinition represents the subset of
VariableDefinition expansions that may be used when the variable
definition is used as a
Substatement
instead of a
Directive
in non-strict mode. In strict mode variable definitions may not be used as substatements.
UntypedVariableBindingList
Validation
Evaluation
Function Definition
Syntax
Class Definition
Syntax
Validation
end proc;
end proc;
end if;
c:
Class
new ClassstaticReadBindings: {},
staticWriteBindings: {},
instanceReadBindings: {},
instanceWriteBindings: {},
instanceInitOrder:
[],
complete:
false,
super:
superclass,
prototype:
prototype,
privateNamespace:
privateNamespace,
dynamic:
dynamic,
primitive:
false,
final:
final,
call:
call,
construct:
construct;
end proc;
end proc;
ValidateUsingFrame[
Block](
cxt,
env,
JumpTargetsbreakTargets: {},
continueTargets: {}
,
pl,
c)
end proc;
Evaluation
return EvalUsingFrame[
Block](
env,
c,
d)
end proc;
Interface Definition
Syntax
Namespace Definition
Syntax
Package Definition
Syntax
Programs
Syntax
Predefined Identifiers
Built-in Classes
end proc;
end proc;
return new ClassstaticReadBindings: {},
staticWriteBindings: {},
instanceReadBindings: {},
instanceWriteBindings: {},
instanceInitOrder:
[],
complete:
true,
super:
superclass,
prototype:
null,
privateNamespace:
privateNamespace,
dynamic:
dynamic,
primitive:
primitive,
final:
final,
call:
call,
construct:
construct
end proc;
Built-in Functions
Built-in Attributes
Built-in Operators
Unary Operators
Binary Operators
Built-in Namespaces
Built-in Units