April 2002 Draft
JavaScript 2.0
Formal Description
Syntactic Semantics
previousupnext

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 syntaxError;
tag compileExpressionError;
tag referenceError;
tag uninitialisedError;
tag badValueError;
tag propertyAccessError;
tag definitionError;
tag argumentMismatchError;
SemanticError = {syntaxError, compileExpressionError, referenceError, uninitialisedError, badValueError, propertyAccessError, definitionError, argumentMismatchError};
tuple Break
valueObject,
labelLabel
end tuple;
tuple Continue
valueObject,
labelLabel
end tuple;
tuple ReturnedValue
valueObject
end tuple;
tuple ThrownValue
valueObject
end tuple;
EarlyExit = Break  Continue  ReturnedValue  ThrownValue;
SemanticException = EarlyExit  SemanticError;

Objects

tag none;
tag ok;
tag future;
tag uninitialised;
ObjectUndefined  Null  Boolean  Float64  String  Namespace  CompoundAttribute  Class  MethodClosure  Prototype  Instance  Package  Global;
PrimitiveObject = Undefined  Null  Boolean  Float64  String;
DynamicObject = Prototype  DynamicInstance  Global;
ObjectOpt = Object  {none};
ObjectFut = Object  {future};
ObjectFutOpt = Object  {futurenone};
ObjectUninit = Object  {uninitialised};
ObjectUninitFut = Object  {uninitialisedfuture};

Undefined

tag undefined;
Undefined = {undefined};

Null

tag null;
Null = {null};

Strings

StringOpt = String  {none};

Namespaces

record Namespace
nameString
end record;
publicNamespaceNamespace = new Namespacename: “public;
enumerableNamespaceNamespace = new Namespacename: “enumerable;

Qualified Names

tuple QualifiedName
namespaceNamespace,
idString
end tuple;
QualifiedNameOpt = QualifiedName  {none};
Multiname = QualifiedName{};

Attributes

tag static;
tag constructor;
tag operator;
tag abstract;
tag virtual;
tag final;
MemberModifier = {nonestaticconstructoroperatorabstractvirtualfinal};
OverrideModifier = {nonetruefalseundefined};
tuple CompoundAttribute
namespacesNamespace{},
explicitBoolean,
dynamicBoolean,
compileBoolean,
memberModMemberModifier,
overrideModOverrideModifier,
prototypeBoolean,
unusedBoolean
end tuple;
Attribute = Boolean  Namespace  CompoundAttribute;
AttributeOptNotFalse = {nonetrue Namespace  CompoundAttribute;

Classes

record Class
staticReadBindingsStaticBinding{},
staticWriteBindingsStaticBinding{},
instanceReadBindingsInstanceBinding{},
instanceWriteBindingsInstanceBinding{},
instanceInitOrderInstanceVariable[],
completeBoolean,
superClassOpt,
prototypeObject,
privateNamespaceNamespace,
dynamicBoolean,
primitiveBoolean,
finalBoolean,
callObject  ArgumentList  Phase  Object,
constructObject  ArgumentList  Phase  Object
end record;
ClassOpt = Class  {none};
Return an ordered list of class c’s ancestors, including c itself.
proc ancestors(cClass): Class[]
sClassOpt  c.super;
if s = none then return [c] else return ancestors(s [c] end if
end proc;
Return true if c is d or an ancestor of d.
proc isAncestor(cClassdClass): Boolean
if c = d then return true
else
sClassOpt  d.super;
if s = none then return false end if;
return isAncestor(cs)
end if
end proc;
Return true if c is an ancestor of d other than d itself.
proc isProperAncestor(cClassdClass): Boolean
return isAncestor(cdand c  d
end proc;

Method Closures

tuple MethodClosure
thisObject,
end tuple;

Prototype Instances

record Prototype
parentPrototypeOpt,
dynamicPropertiesDynamicProperty{}
end record;
PrototypeOpt = Prototype  {none};
record DynamicProperty
nameString,
valueObject
end record;

Class Instances

Instance = FixedInstance  DynamicInstance;
record FixedInstance
typeClass,
callInvoker,
constructInvoker,
typeofStringString,
slotsSlot{}
end record;
record DynamicInstance
typeClass,
callInvoker,
constructInvoker,
typeofStringString,
slotsSlot{},
dynamicPropertiesDynamicProperty{}
end record;

Slots

record Slot
valueObjectUninit
end record;

Packages

record Package
staticReadBindingsStaticBinding{},
staticWriteBindingsStaticBinding{},
internalNamespaceNamespace
end record;

Global Objects

record Global
staticReadBindingsStaticBinding{},
staticWriteBindingsStaticBinding{},
internalNamespaceNamespace,
dynamicPropertiesDynamicProperty{}
end record;

Objects with Limits

instance must be an instance of limit or one of limit’s descendants.
tuple LimitedInstance
instanceInstance,
limitClass
end tuple;
ObjOptionalLimit = Object  LimitedInstance;

References

tuple LexicalReference
variableMultinameMultiname,
cxtContext
end tuple;
tuple DotReference
propertyMultinameMultiname
end tuple;
tuple BracketReference
end tuple;
Reference = LexicalReference  DotReference  BracketReference;
ObjOrRef = Object  Reference;
tuple LimitedObjOrRef
refObjOrRef,
limitClass
end tuple;
ObjOrRefOptionalLimit = ObjOrRef  LimitedObjOrRef;

Signatures

tuple Signature
requiredPositionalClass[],
optionalPositionalClass[],
optionalNamedNamedParameter{},
restClassOpt,
restAllowsNamesBoolean,
returnTypeClass
end tuple;
tuple NamedParameter
nameString,
typeClass
end tuple;

Argument Lists

tuple NamedArgument
nameString,
valueObject
end tuple;
tuple ArgumentList
positionalObject[],
namedNamedArgument{}
end tuple;
The first Object is the this value. When the Phase parameter is compile, only compile-time expressions are allowed.
Invoker = Object  ArgumentList  Environment  Phase  Object;

Unary Operators

tuple UnaryMethod
operandTypeClass,
fObject  Object  ArgumentList  Phase  Object
end tuple;

Binary Operators

tuple BinaryMethod
leftTypeClass,
rightTypeClass,
fObject  Object  Phase  Object
end tuple;

Modes of expression evaluation

tag compile;
tag run;
Phase = {compilerun};

Contexts

tuple Context
strictBoolean,
openNamespacesNamespace{}
end tuple;
initialContextContext = ContextstrictfalseopenNamespaces: {publicNamespace};

Labels

tag default;
Label = String  {default};
tuple JumpTargets
breakTargetsLabel{},
continueTargetsLabel{}
end tuple;

Environments

tag singular;
tag plural;
Plurality = {singularplural};
An Environment is a list of two or more frames. Each frame corresponds to a scope. More specific frames are listed first—each frame’s scope is directly contained in the following frame’s scope. The last frame is always the SystemFrame. The next-to-last frame is always a Package or Global frame.
Environment = Frame[];
Frame = SystemFrame  Global  Package  FunctionFrame  Class  BlockFrame;
record SystemFrame
staticReadBindingsStaticBinding{},
staticWriteBindingsStaticBinding{}
end record;
record FunctionFrame
staticReadBindingsStaticBinding{},
staticWriteBindingsStaticBinding{},
pluralityPlurality,
thisObjectFutOpt,
thisFromPrototypeBoolean
end record;
record BlockFrame
staticReadBindingsStaticBinding{},
staticWriteBindingsStaticBinding{},
pluralityPlurality
end record;
initialEnvironmentEnvironment[new SystemFramestaticReadBindings: {}, staticWriteBindings: {}];

Members

tuple StaticBinding
qnameQualifiedName,
contentStaticMember,
explicitBoolean
end tuple;
tuple InstanceBinding
qnameQualifiedName,
contentInstanceMember
end tuple;
tag forbidden;
StaticMember = {forbidden Variable  HoistedVar  StaticMethod  Accessor;
StaticMemberOpt = StaticMember  {none};
record Variable
typeClass,
immutableBoolean
end record;
record HoistedVar
valueObject
end record;
record StaticMethod
typeSignature,
codeInstance,
modifier: {staticconstructor}
end record;
record Accessor
typeClass,
codeInstance
end record;
InstanceMember = InstanceVariable  InstanceMethod  InstanceAccessor;
InstanceMemberOpt = InstanceMember  {none};
record InstanceVariable
typeClass,
evalInitialValue: ()  ObjectOpt,
immutableBoolean,
finalBoolean
end record;
record InstanceMethod
typeSignature,
codeInstance  {abstract},
finalBoolean
end record;
record InstanceAccessor
typeClass,
codeInstance  {abstract},
finalBoolean
end record;

Data Operations

Numeric Utilities

proc uInt32ToInt32(iInteger): Integer
if i < 231 then return i else return i – 232 end if
end proc;
proc toUInt32(xFloat64): Integer
if x  {+NaNthen return 0 end if;
return truncateFiniteFloat64(xmod 232
end proc;
proc toInt32(xFloat64): Integer
end proc;

Object Utilities

objectType

objectType(o) returns an Object o’s most specific type.
proc objectType(oObject): Class
case o of
Null do return nullClass;
Boolean do return booleanClass;
Float64 do return numberClass;
String do if |o| = 1 then return characterClass else return stringClass end if;
Class do return classClass;
Instance do return o.type;
Package  Global do return packageClass
end case
end proc;

hasType

There are two tests for determining whether an object o is an instance of class c. The first, hasType, is used for the purposes of method dispatch and helps determine whether a method of c can be called on o. The second, relaxedHasType, determines whether o can be stored in a variable of type c without conversion.
hasType(oc) returns true if o is an instance of class c (or one of c’s subclasses). It considers null to be an instance of the classes Null and Object only.
proc hasType(oObjectcClass): Boolean
return isAncestor(cobjectType(o))
end proc;
relaxedHasType(oc) returns true if o is an instance of class c (or one of c’s subclasses) but considers null to be an instance of the classes Null, Object, and all other non-primitive classes.
proc relaxedHasType(oObjectcClass): Boolean
tClass  objectType(o);
return isAncestor(ctor (o = null and not c.primitive)
end proc;

toBoolean

toBoolean(ophase) coerces an object o to a Boolean. If phase is compile, only compile-time conversions are permitted.
proc toBoolean(oObjectphasePhase): Boolean
case o of
Undefined  Null do return false;
Boolean do return o;
Float64 do return o  {+zero–zeroNaN};
String do return o  “”;
Namespace  CompoundAttribute  Class  MethodClosure  Prototype  Package  Global do
return true;
Instance do ????
end case
end proc;

toNumber

toNumber(ophase) coerces an object o to a number. If phase is compile, only compile-time conversions are permitted.
proc toNumber(oObjectphasePhase): Float64
case o of
Undefined do return NaN;
Null  {falsedo return +zero;
{truedo return 1.0;
Float64 do return o;
String do ????;
Namespace  CompoundAttribute  Class  MethodClosure  Package  Global do
Prototype  Instance do ????
end case
end proc;

toString

toString(ophase) coerces an object o to a string. If phase is compile, only compile-time conversions are permitted.
proc toString(oObjectphasePhase): String
case o of
Undefined do return “undefined”;
Null do return “null”;
{falsedo return “false”;
{truedo return “true”;
Float64 do ????;
String do return o;
Namespace do ????;
Class do ????;
MethodClosure do ????;
Prototype  Instance do ????;
Package  Global do ????
end case
end proc;

toPrimitive

proc toPrimitive(oObjecthintObjectphasePhase): PrimitiveObject
case o of
PrimitiveObject do return o;
Namespace  CompoundAttribute  Class  MethodClosure  Prototype  Instance  Package  Global do
return toString(ophase)
end case
end proc;

assignmentConversion

proc assignmentConversion(oObjecttypeClass): Object
if relaxedHasType(otypethen return o end if;
????
end proc;

unaryPlus

unaryPlus(ophase) returns the value of the unary expression +o. If phase is compile, only compile-time operations are permitted.
proc unaryPlus(aObjOptionalLimitphasePhase): Object
return unaryDispatch(plusTable, null, a, ArgumentListpositional[]named: {}, phase)
end proc;

unaryNot

unaryNot(ophase) returns the value of the unary expression !o. If phase is compile, only compile-time operations are permitted.
proc unaryNot(aObjectphasePhase): Object
return not toBoolean(aphase)
end proc;

Attributes

combineAttributes(ab) returns the attribute that results from concatenating the attributes a and b.
proc combineAttributes(aAttributeOptNotFalsebAttribute): Attribute
if b = false then return false
elsif a  {nonetruethen return b
elsif b = true then return a
elsif a  Namespace then
if a = b then return a
elsif b  Namespace then
return CompoundAttributenamespaces: {ab}, explicitfalse, dynamicfalse, compilefalse, memberModnone, overrideModnone, prototypefalse, unusedfalse
else return CompoundAttributenamespacesb.namespaces  {a}, other fields from b
end if
elsif b  Namespace then
return CompoundAttributenamespacesa.namespaces  {b}, other fields from a
else
Both a and b are compound attributes. Ensure that they have no conflicting contents.
if (a.memberMod  none and b.memberMod  none and a.memberMod  b.memberModor (a.overrideMod  none and b.overrideMod  none and a.overrideMod  b.overrideModthen
else
return CompoundAttributenamespacesa.namespaces  b.namespaces, explicita.explicit or b.explicit, dynamica.dynamic or b.dynamic, compilea.compile or b.compile, memberModa.memberMod  none ? a.memberMod : b.memberMod, overrideModa.overrideMod  none ? a.overrideMod : b.overrideMod, prototypea.prototype or b.prototype, unuseda.unused or b.unused
end if
end if
end proc;
toCompoundAttribute(a) returns a converted to a CompoundAttribute even if it was a simple namespace, true, or none.
proc toCompoundAttribute(aAttributeOptNotFalse): CompoundAttribute
case a of
{nonetruedo
return CompoundAttributenamespaces: {}, explicitfalse, dynamicfalse, compilefalse, memberModnone, overrideModnone, prototypefalse, unusedfalse;
return CompoundAttributenamespaces: {a}, explicitfalse, dynamicfalse, compilefalse, memberModnone, overrideModnone, prototypefalse, unusedfalse;
CompoundAttribute do return a
end case
end proc;

Objects with Limits

getObject(o) returns o without its limit, if any.
proc getObject(oObjOptionalLimit): Object
case o of
Object do return o;
LimitedInstance do return o.instance
end case
end proc;
getObjectLimit(o) returns o’s limit or none if none is provided.
proc getObjectLimit(oObjOptionalLimit): ClassOpt
case o of
Object do return none;
LimitedInstance do return o.limit
end case
end proc;

References

If r is an Object, readReference(rphase) returns it unchanged. If r is a Reference, this function reads r and returns the result. If phase is compile, only compile-time expressions can be evaluated in the process of reading r.
proc readReference(rObjOrRefphasePhase): Object
case r of
Object do return r;
LexicalReference do return lexicalRead(r.envr.variableMultinamephase);
resultObjectOpt  readProperty(r.baser.propertyMultinamepropertyLookupphase);
if result = none then throw propertyAccessError else return result end if;
return unaryDispatch(bracketReadTablenullr.baser.argsphase)
end case
end proc;
readRefWithLimit(rphase) reads the reference, if any, inside r and returns the result, retaining the same limit as r. If r has a limit limit, then the object read from the reference is checked to make sure that it is an instance of limit or one of its descendants. If phase is compile, only compile-time expressions can be evaluated in the process of reading r.
proc readRefWithLimit(rObjOrRefOptionalLimitphasePhase): ObjOptionalLimit
case r of
ObjOrRef do return readReference(rphase);
oObject  readReference(r.refphase);
limitClass  r.limit;
if o = null then return null end if;
if o  Instance or not hasType(olimitthen throw badValueError end if;
return LimitedInstanceinstanceolimitlimit
end case
end proc;
If r is a reference, writeReference(ro) writes o into r. An error occurs if r is not a reference. r’s limit, if any, is ignored. writeReference is never called from a compile-time expression.
proc writeReference(rObjOrRefOptionalLimitoObjectphase: {run})
case r of
Object do throw referenceError;
lexicalWrite(r.envr.variableMultinameonot r.cxt.strictphase);
result: {noneok writeProperty(r.baser.propertyMultinamepropertyLookuptrueophase);
if result = none then throw propertyAccessError end if;
argsArgumentList  ArgumentListpositional[o]  r.args.positionalnamedr.args.named;
unaryDispatch(bracketWriteTablenullr.baseargsphase);
LimitedObjOrRef do writeReference(r.refophase)
end case
end proc;
If r is a Reference, deleteReference(r) deletes it. If r is an Object, this function signals an error. deleteReference is never called from a compile-time expression.
proc deleteReference(rObjOrRefphase: {run}): Object
case r of
Object do throw referenceError;
DotReference do return deleteProperty(r.baser.propertyMultinamephase);
return unaryDispatch(bracketDeleteTablenullr.baser.argsphase)
end case
end proc;
referenceBase(r) returns Reference r’s base or null if there is none. r’s limit and the base’s limit, if any, are ignored.
proc referenceBase(rObjOrRefOptionalLimit): Object
case r of
Object  LexicalReference do return null;
DotReference  BracketReference do return getObject(r.base);
end case
end proc;

Slots

proc findSlot(oObjectidInstanceVariable): Slot
o must be an Instance;
matchingSlotsSlot{}  {s | s  o.slots such that s.id = id};
return the one element of matchingSlots
end proc;

Environments

If env is from within a class’s body, getEnclosingClass(env) returns the innermost such class; otherwise, it returns none.
proc getEnclosingClass(envEnvironment): ClassOpt
if some c  env satisfies c  Class then
Let c be the first element of env that is a Class.
return c
end if;
return none
end proc;
getRegionalEnvironment(env) returns all frames in env up to and including the first regional frame. A regional frame is either any frame other than a local block frame or a local block frame whose immediate enclosing frame is a class.
proc getRegionalEnvironment(envEnvironment): Frame[]
iInteger  0;
while env[i BlockFrame do i  i + 1 end while;
if i  0 and env[i Class then i  i – 1 end if;
return env[0 ... i]
end proc;
getRegionalFrame(env)Returns the most specific regional frame in env.
proc getRegionalFrame(envEnvironment): Frame
regionalEnvFrame[]  getRegionalEnvironment(env);
return regionalEnv[|regionalEnv| – 1]
end proc;
proc getPackageOrGlobalFrame(envEnvironment): Package  Global
gFrame  env[|env| – 2];
The penultimate frame g is always a Package or Global frame.
return g
end proc;

Adding Static Definitions

tag read;
tag write;
tag readWrite;
Access = {readwritereadWrite};
tag readNoWrite;
DefinitionAccess = {readwritereadWritereadNoWrite};
VariableAccess = {readWritereadNoWrite};
proc bindDefinition(envEnvironment, idString, aCompoundAttribute, defaultMemberModMemberModifier, accessDefinitionAccess, makeStaticMember: ()  StaticMember, makeInstanceMember: ()  InstanceMember)
memberModMemberModifier  a.memberMod;
if memberMod = none then
if a.compile then memberMod  static else memberMod  defaultMemberMod end if
end if;
regionalEnvFrame[]  getRegionalEnvironment(env);
innerFrameFrame  regionalEnv[0];
otherFramesInRegionFrame[]  regionalEnv[1 ...];
regionalFrameFrame  regionalEnv[|regionalEnv| – 1];
namespacesNamespace{}  a.namespaces;
cClassOpt  none;
if regionalFrame  Class then c  regionalFrame end if;
if namespaces = {} then namespaces  {publicNamespaceend if;
***** If in a class, consider overrides and adjust list of namespaces.
multinameMultiname  {QualifiedNamenamespacensidid | ns  namespaces};
if some b  innerFrame.staticReadBindings  innerFrame.staticWriteBindings satisfies b.qname  multiname then
end if;
for each frame  otherFramesInRegion do
if some b  frame.staticReadBindings  frame.staticWriteBindings satisfies b.qname  multiname and b.content  forbidden then
end if
end for each;
if regionalFrame  Global and (some dp  regionalFrame.dynamicProperties satisfies QualifiedNamenamespacepublicNamespaceiddp.name  multinamethen
end if;
????
end proc;
proc defineHoistedVar(envEnvironmentidString)
qnameQualifiedName  QualifiedNamenamespacepublicNamespaceidid;
regionalEnvFrame[]  getRegionalEnvironment(env);
regionalFrameFrame  regionalEnv[|regionalEnv| – 1];
env is either the Global frame or a FunctionFrame because hoisting only occurs into global or function scope.
existingBindingsStaticBinding{}  {b | b  regionalFrame.staticReadBindings  regionalFrame.staticWriteBindings such that b.qname = qname};
if existingBindings = {} then
if regionalFrame  Global and (some dp  regionalFrame.dynamicProperties satisfies dp.name = idthen
end if;
vHoistedVar  new HoistedVarvalueundefined;
newBindingsStaticBinding{}  {StaticBindingqnameqnamecontentvexplicitfalse};
regionalFrame.staticReadBindings  regionalFrame.staticReadBindings  newBindings;
regionalFrame.staticWriteBindings  regionalFrame.staticWriteBindings  newBindings
elsif some b  existingBindings satisfies b.content  HoistedVar then
else
A hoisted binding of the same var already exists, so there is no need to create another one.
end if
end proc;
proc instantiateBlockFrame(templateBlockFrame): BlockFrame
????
end proc;

Adding Instance Definitions

tuple OverrideStatusPair
readStatusOverrideStatus,
writeStatusOverrideStatus
end tuple;
tag potentialConflict;
tuple OverrideStatus
overriddenMemberInstanceMember  {nonepotentialConflict},
multinameMultiname
end tuple;
proc searchForOverrides(cClass, idString, namespacesNamespace{}, access: {readwrite}): OverrideStatus
multinameMultiname  {};
overriddenMemberInstanceMemberOpt  none;
sClassOpt  c.super;
for each ns  namespaces do
qnameQualifiedName  QualifiedNamenamespacensidid;
mInstanceMemberOpt  findInstanceMember(sqnameaccess);
if m  none then
multiname  multiname  {qname};
if overriddenMember = none then overriddenMember  m
elsif overriddenMember  m then throw definitionError
end if
end if
end for each;
return OverrideStatusoverriddenMemberoverriddenMembermultinamemultiname
end proc;
proc resolveOverrides(cClass, cxtContext, idString, namespacesNamespace{}, access: {readwrite}, expectMethodBoolean): OverrideStatus
if namespaces = {} then
os  searchForOverrides(cidcxt.openNamespacesaccess);
if os.overriddenMember = none then
os  OverrideStatusoverriddenMembernone, multiname: {QualifiedNamenamespacepublicNamespaceidid}
end if
else
definedMultinameMultiname  {QualifiedNamenamespacensidid | ns  namespaces};
os2OverrideStatus  searchForOverrides(cidnamespacesaccess);
if os2.overriddenMember = none then
os3OverrideStatus  searchForOverrides(cidcxt.openNamespaces – namespacesaccess);
if os3.overriddenMember = none then
os  OverrideStatusoverriddenMembernonemultinamedefinedMultiname
else
os  OverrideStatusoverriddenMemberpotentialConflict, multinamedefinedMultiname
end if
else
os  OverrideStatusoverriddenMemberos2.overriddenMember, multinameos2.multiname  definedMultiname
end if
end if;
instanceBindingsInstanceBinding{};
case access of
{readdo instanceBindings  c.instanceReadBindings;
{writedo instanceBindings  c.instanceWriteBindings
end case;
if some b  instanceBindings satisfies b.qname  os.multiname then
end if;
if expectMethod then
if os.overriddenMember  {nonepotentialConflict InstanceMethod then
end if
else
if os.overriddenMember  {nonepotentialConflict InstanceVariable  InstanceAccessor then
end if
end if;
return os
end proc;
proc defineInstanceMember(cClass, cxtContext, idString, namespacesNamespace{}, overrideModOverrideModifier, accessAccess, mInstanceMember): OverrideStatusPair
expectMethodBoolean  m  InstanceMethod;
readStatusOverrideStatus  access  {readreadWrite} ? resolveOverrides(ccxtidnamespacesreadexpectMethod) : OverrideStatusoverriddenMembernonemultiname: {};
writeStatusOverrideStatus  access  {writereadWrite} ? resolveOverrides(ccxtidnamespaceswriteexpectMethod) : OverrideStatusoverriddenMembernonemultiname: {};
if readStatus.overriddenMember  InstanceMember or writeStatus.overriddenMember  InstanceMember then
if overrideMod  {trueundefinedthen throw definitionError end if
elsif readStatus.overriddenMember = potentialConflict or writeStatus.overriddenMember = potentialConflict then
if overrideMod  {falseundefinedthen throw definitionError end if
else if overrideMod  {nonefalseundefinedthen throw definitionError end if
end if;
newReadBindingsInstanceBinding{}  {InstanceBindingqnameqnamecontentm | qname  readStatus.multiname};
c.instanceReadBindings  c.instanceReadBindings  newReadBindings;
newWriteBindingsInstanceBinding{}  {InstanceBindingqnameqnamecontentm | qname  writeStatus.multiname};
c.instanceWriteBindings  c.instanceWriteBindings  newWriteBindings;
return OverrideStatusPairreadStatusreadStatuswriteStatuswriteStatus
end proc;

Environmental Lookup

findThis(envallowPrototypeThis) returns the value of this. If allowPrototypeThis is true, allow this to be defined by either an instance member of a class or a prototype function. If allowPrototypeThis is false, allow this to be defined only by an instance member of a class.
proc findThis(envEnvironmentallowPrototypeThisBoolean): ObjectFutOpt
for each frame  env do
if frame  FunctionFrame and frame.this  none then
if allowPrototypeThis or not frame.thisFromPrototype then return frame.this
end if
end if
end for each;
return none
end proc;
proc lexicalRead(envEnvironmentmultinameMultinamephasePhase): Object
kindLookupKind  LexicalLookupthisfindThis(envfalse);
iInteger  0;
while i < |envdo
frameFrame  env[i];
resultObjectOpt  readProperty(framemultinamekindphase);
if result  none then return result end if;
i  i + 1
end while;
end proc;
proc lexicalWrite(envEnvironment, multinameMultiname, newValueObject, createIfMissingBoolean, phase: {run})
kindLookupKind  LexicalLookupthisfindThis(envfalse);
iInteger  0;
while i < |envdo
frameFrame  env[i];
result: {noneok writeProperty(framemultinamekindfalsenewValuephase);
if result = ok then return end if;
i  i + 1
end while;
if createIfMissing then
gPackage  Global  getPackageOrGlobalFrame(env);
if g  Global then
Now try to write the variable into g again, this time allowing new dynamic bindings to be created dynamically.
result: {noneok writeProperty(gmultinamekindtruenewValuephase);
if result = ok then return end if
end if
end if;
end proc;
proc lexicalDelete(envEnvironmentmultinameMultinamephase: {run}): Boolean
????
end proc;

Property Lookup

tag propertyLookup;
tuple LexicalLookup
end tuple;
LookupKind = {propertyLookup LexicalLookup;
proc selectPublicName(multinameMultiname): StringOpt
if some qname  multiname satisfies qname.namespace = publicNamespace then
return qname.id
end if;
return none
end proc;
proc findFlatMember(frameFrame, multinameMultiname, access: {readwrite}, phasePhase): StaticMemberOpt
bindingsStaticBinding{};
case access of
{readdo bindings  frame.staticReadBindings;
{writedo bindings  frame.staticWriteBindings
end case;
matchingBindingsStaticBinding{}  {b | b  bindings such that b.qname  multiname};
if matchingBindings = {} then return none end if;
matchingMembersStaticMember{}  {b.content | b  matchingBindings};
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;
proc findStaticMember(cClassOpt, multinameMultiname, access: {readwrite}, phasePhase): {none StaticMember  QualifiedName
sClassOpt  c;
while s  none do
staticBindingsStaticBinding{};
case access of
{readdo staticBindings  s.staticReadBindings;
{writedo staticBindings  s.staticWriteBindings
end case;
matchingStaticBindingsStaticBinding{}  {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.
matchingStaticMembersStaticMember{}  {b.content | b  matchingStaticBindings};
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.
instanceBindingsInstanceBinding{};
case access of
{readdo instanceBindings  s.instanceReadBindings;
{writedo instanceBindings  s.instanceWriteBindings
end case;
matchingInstanceBindingsInstanceBinding{}  {b | b  instanceBindings such that b.qname  multiname};
Note that if the same InstanceMember was found via several different bindings b, then it will appear only once in the set matchingInstanceMembers.
matchingInstanceMembersInstanceMember{}  {b.content | b  matchingInstanceBindings};
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.
bInstanceBinding  any element of matchingInstanceBindings;
return b.qname
else
This access is ambiguous because the bindings it found belong to several different members in the same class.
end if
end if;
s  s.super
end while;
return none
end proc;
proc resolveInstanceMemberName(cClass, multinameMultiname, access: {readwrite}, phasePhase): QualifiedNameOpt
Start from the root class (Object) and proceed through more specific classes that are ancestors of c.
for each s  ancestors(cdo
instanceBindingsInstanceBinding{};
case access of
{readdo instanceBindings  s.instanceReadBindings;
{writedo instanceBindings  s.instanceWriteBindings
end case;
matchingInstanceBindingsInstanceBinding{}  {b | b  instanceBindings such that b.qname  multiname};
Note that if the same InstanceMember was found via several different bindings b, then it will appear only once in the set matchingMembers.
matchingInstanceMembersInstanceMember{}  {b.content | b  matchingInstanceBindings};
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.
bInstanceBinding  any element of matchingInstanceBindings;
return b.qname
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;
return none
end proc;
proc findInstanceMember(cClassOptqnameQualifiedNameOptaccess: {readwrite}): InstanceMemberOpt
if qname = none then return none end if;
sClassOpt  c;
while s  none do
instanceBindingsInstanceBinding{};
case access of
{readdo instanceBindings  s.instanceReadBindings;
{writedo instanceBindings  s.instanceWriteBindings
end case;
if some b  instanceBindings satisfies b.qname = qname then return b.content
end if;
s  s.super
end while;
return none
end proc;

Reading a Property

tag generic;
proc readProperty(containerObjOptionalLimit  Frame, multinameMultiname, kindLookupKind, phasePhase): ObjectOpt
case container of
Undefined  Null  Boolean  Float64  String  Namespace  CompoundAttribute  MethodClosure  Instance do
cClass  objectType(container);
qnameQualifiedNameOpt  resolveInstanceMemberName(cmultinamereadphase);
if qname = none and container  DynamicInstance then
return readDynamicProperty(containermultinamekindphase)
else return readInstanceMember(containercqnamephase)
end if;
SystemFrame  Global  Package  FunctionFrame  BlockFrame do
mStaticMemberOpt  findFlatMember(containermultinamereadphase);
if m = none and container  Global then
return readDynamicProperty(containermultinamekindphase)
else return readStaticMember(mphase)
end if;
Class do
thisObject  {futurenonegeneric};
case kind of
{propertyLookupdo this  generic;
LexicalLookup do this  kind.this
end case;
m2: {none StaticMember  QualifiedName  findStaticMember(containermultinamereadphase);
if m2  QualifiedName then return readStaticMember(m2phaseend if;
case this of
{nonedo throw propertyAccessError;
{futuredo throw uninitialisedError;
{genericdo ????;
Object do return readInstanceMember(thisobjectType(this), m2phase)
end case;
Prototype do return readDynamicProperty(containermultinamekindphase);
superclassClassOpt  container.limit.super;
if superclass = none then return none end if;
qnameQualifiedNameOpt  resolveInstanceMemberName(superclassmultinamereadphase);
return readInstanceMember(container.instancesuperclassqnamephase)
end case
end proc;
proc readInstanceMember(thisObjectcClassqnameQualifiedNameOptphasePhase): ObjectOpt
mInstanceMemberOpt  findInstanceMember(cqnameread);
case m of
{nonedo return none;
if phase = compile and not m.immutable then throw compileExpressionError
end if;
vObjectUninit  findSlot(thism).value;
if v = uninitialised then throw uninitialisedError end if;
return v;
InstanceMethod do return MethodClosurethisthismethodm;
codeInstance  {abstract m.code;
case code of
return code.call(this, ArgumentListpositional[]named: {}, code.env, phase);
end case
end case
end proc;
proc readStaticMember(mStaticMemberOptphasePhase): ObjectOpt
case m of
{nonedo return none;
Variable do return readVariable(mphase);
HoistedVar do return m.value;
StaticMethod do return m.code;
codeInstance  m.code;
return code.call(null, ArgumentListpositional[]named: {}, code.env, phase)
end case
end proc;
proc readDynamicProperty(containerDynamicObject, multinameMultiname, kindLookupKind, phasePhase): ObjectOpt
nameStringOpt  selectPublicName(multiname);
if name = none then return none end if;
if phase = compile then throw compileExpressionError end if;
if some dp  container.dynamicProperties satisfies dp.name = name then
return dp.value
end if;
if container  Prototype then
parentPrototypeOpt  container.parent;
if parent  none then return readDynamicProperty(parentmultinamekindphase)
end if
end if;
if kind = propertyLookup then return undefined end if;
return none
end proc;
proc readVariable(vVariablephasePhase): Object
if phase = compile and not v.immutable then throw compileExpressionError end if;
valueObjectUninitFut  v.value;
if value  {uninitialisedfuturethen throw uninitialisedError end if;
return value
end proc;

Writing a Property

proc writeProperty(containerObjOptionalLimit  Frame, multinameMultiname, kindLookupKind, createIfMissingBoolean, newValueObject, phase: {run}): {noneok}
case container of
Undefined  Null  Boolean  Float64  String  Namespace  CompoundAttribute  MethodClosure do
return none;
SystemFrame  Global  Package  FunctionFrame  BlockFrame do
mStaticMemberOpt  findFlatMember(containermultinamewritephase);
if m = none and container  Global then
return writeDynamicProperty(container, multiname, createIfMissing, newValue, phase)
else return writeStaticMember(mnewValuephase)
end if;
Class do
thisObjectFutOpt;
case kind of
{propertyLookupdo this  none;
LexicalLookup do this  kind.this
end case;
m2: {none StaticMember  QualifiedName  findStaticMember(containermultinamewritephase);
if m2  QualifiedName then return writeStaticMember(m2newValuephase)
elsif this = none then throw propertyAccessError
elsif this = future then throw uninitialisedError
else return writeInstanceMember(thisobjectType(this), m2newValuephase)
end if;
return writeDynamicProperty(container, multiname, createIfMissing, newValue, phase);
cClass  objectType(container);
qnameQualifiedNameOpt  resolveInstanceMemberName(objectType(container), multinamewritephase);
if qname = none and container  DynamicInstance then
return writeDynamicProperty(container, multiname, createIfMissing, newValue, phase)
else return writeInstanceMember(containercqnamenewValuephase)
end if;
superclassClassOpt  container.limit.super;
if superclass = none then return none end if;
qnameQualifiedNameOpt  resolveInstanceMemberName(superclassmultinamewritephase);
return writeInstanceMember(container.instance, superclass, qname, newValue, phase)
end case
end proc;
proc writeInstanceMember(thisObject, cClass, qnameQualifiedNameOpt, newValueObject, phase: {run}): {noneok}
mInstanceMemberOpt  findInstanceMember(cqnamewrite);
case m of
{nonedo return none;
sSlot  findSlot(thism);
if m.immutable and s.value  uninitialised then throw propertyAccessError
end if;
coercedValueObject  assignmentConversion(newValuem.type);
s.value  coercedValue;
return ok;
coercedValueObject  assignmentConversion(newValuem.type);
codeInstance  {abstract m.code;
case code of
code.call(this, ArgumentListpositional[coercedValue]named: {}, code.env, phase);
end case;
return ok
end case
end proc;
proc writeStaticMember(mStaticMemberOptnewValueObjectphase: {run}): {noneok}
case m of
{nonedo return none;
{forbidden StaticMethod do throw propertyAccessError;
Variable do writeVariable(mnewValuephase); return ok;
HoistedVar do m.value  newValuereturn ok;
coercedValueObject  assignmentConversion(newValuem.type);
codeInstance  m.code;
code.call(null, ArgumentListpositional[coercedValue]named: {}, code.env, phase);
return ok
end case
end proc;
proc writeDynamicProperty(containerDynamicObject, multinameMultiname, createIfMissingBoolean, newValueObject, phase: {run}): {noneok}
nameStringOpt  selectPublicName(multiname);
if name = none then return none end if;
if some dp  container.dynamicProperties satisfies dp.name = name then
dp.value  newValue;
return ok
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.
m: {none StaticMember  QualifiedName;
case container of
Prototype do m  none;
m  resolveInstanceMemberName(objectType(container), multinamereadphase);
Global do m  findFlatMember(containermultinamereadphase)
end case;
if m  none then return none end if;
container.dynamicProperties  container.dynamicProperties  {new DynamicPropertynamenamevaluenewValue};
return ok
end proc;
proc writeVariable(vVariablenewValueObjectphase: {run})
typeClass  v.type;
if v.value = future then throw uninitialisedError end if;
if v.immutable and v.value  uninitialised then throw propertyAccessError end if;
coercedValueObject  assignmentConversion(newValuetype);
v.value  coercedValue
end proc;

Deleting a Property

proc deleteProperty(oObjOptionalLimitmultinameMultinamephase: {run}): Boolean
????
end proc;
proc deleteQualifiedProperty(oObject, nameString, nsNamespace, kindLookupKind, phase: {run}): Boolean
????
end proc;

Operator Dispatch

Unary Operators

unaryDispatch(tablethisoperandargsphase) dispatches the unary operator described by table applied to the this value this, the operand operand, and zero or more positional and/or named arguments args. If operand has a limit class, lookup is restricted to operators defined on the proper ancestors of that limit. If phase is compile, only compile-time expressions can be evaluated in the process of dispatching and calling the operator.
proc unaryDispatch(tableUnaryMethod{}, thisObject, operandObjOptionalLimit, argsArgumentList, phasePhase): Object
applicableOpsUnaryMethod{}  {m | m  table such that limitedHasType(operandm.operandType)};
if some best  applicableOps satisfies (every m2  applicableOps satisfies isAncestor(m2.operandTypebest.operandType)) then
return best.f(thisgetObject(operand), argsphase)
end if;
end proc;
limitedHasType(oc) returns true if o is a member of class c with the added condition that, if o has a limit class limit, c is a proper ancestor of limit.
proc limitedHasType(oObjOptionalLimitcClass): Boolean
aObject  getObject(o);
limitClassOpt  getObjectLimit(o);
if hasType(acthen
if limit = none then return true else return isProperAncestor(climitend if
else return false
end if
end proc;

Binary Operators

isBinaryDescendant(m1m2) is true if m1 is at least as specific as m2 as defined by the procedure below.
proc isBinaryDescendant(m1BinaryMethodm2BinaryMethod): Boolean
return isAncestor(m2.leftTypem1.leftTypeand isAncestor(m2.rightTypem1.rightType)
end proc;
binaryDispatch(tableleftrightphase) dispatches the binary operator described by table applied to the operands left and right. If left has a limit leftLimit, the lookup is restricted to operator definitions with an ancestor of leftLimit for the left operand. Similarly, if right has a limit rightLimit, the lookup is restricted to operator definitions with an ancestor of rightLimit for the right operand. If phase is compile, only compile-time expressions can be evaluated in the process of dispatching and calling the operator.
proc binaryDispatch(tableBinaryMethod{}, leftObjOptionalLimit, rightObjOptionalLimit, phasePhase): Object
applicableOpsBinaryMethod{}  {m | m  table such that limitedHasType(leftm.leftTypeand limitedHasType(rightm.rightType)};
if some best  applicableOps satisfies (every m2  applicableOps satisfies isBinaryDescendant(bestm2)) then
return best.f(getObject(left), getObject(right), phase)
end if;
end proc;

Deferred Validation

deferredValidators: (()  ())[]  [];

Expressions

Syntax

  {allowInnoIn}

Terminal Actions

Name[Identifier]: String;
Value[Number]: Float64;
Value[String]: String;

Identifiers

Syntax

Identifier 
   Identifier
|  get
|  set
|  exclude
|  include
|  named

Semantics

Name[Identifier]: String;
Name[Identifier  Identifier] = Name[Identifier];
Name[Identifier  get] = “get”;
Name[Identifier  set] = “set”;
Name[Identifier  exclude] = “exclude”;
Name[Identifier  include] = “include”;
Name[Identifier  named] = “named”;

Qualified Identifiers

Syntax

Qualifier 
   Identifier
|  public
|  private
SimpleQualifiedIdentifier 
   Identifier
|  Qualifier :: Identifier
ExpressionQualifiedIdentifier  ParenExpression :: Identifier
QualifiedIdentifier 
   SimpleQualifiedIdentifier
|  ExpressionQualifiedIdentifier

Validation and Evaluation

proc Validate[Qualifier] (cxtContextenvEnvironment): Namespace
[Qualifier  Identifierdo
multinameMultiname  {QualifiedNamenamespacensidName[Identifier] | ns  cxt.openNamespaces};
aObject  lexicalRead(envmultinamecompile);
if a  Namespace then throw badValueError end if;
return a;
[Qualifier  publicdo return publicNamespace;
[Qualifier  privatedo
cClassOpt  getEnclosingClass(env);
if c = none then throw syntaxError end if;
end proc;
Multiname[SimpleQualifiedIdentifier]: Multiname;
proc Validate[SimpleQualifiedIdentifier] (cxtContextenvEnvironment)
[SimpleQualifiedIdentifier  Identifierdo
multinameMultiname  {QualifiedNamenamespacensidName[Identifier] | ns  cxt.openNamespaces};
Multiname[SimpleQualifiedIdentifier multiname;
[SimpleQualifiedIdentifier  Qualifier :: Identifierdo
qNamespace  Validate[Qualifier](cxtenv);
Multiname[SimpleQualifiedIdentifier {QualifiedNamenamespaceqidName[Identifier]}
end proc;
Multiname[ExpressionQualifiedIdentifier]: Multiname;
proc Validate[ExpressionQualifiedIdentifier  ParenExpression :: Identifier] (cxtContextenvEnvironment)
Validate[ParenExpression](cxtenv);
rObjOrRef  Eval[ParenExpression](envcompile);
qObject  readReference(rcompile);
if q  Namespace then throw badValueError end if;
Multiname[ExpressionQualifiedIdentifier {QualifiedNamenamespaceqidName[Identifier]}
end proc;
Multiname[QualifiedIdentifier]: Multiname;
proc Validate[QualifiedIdentifier] (cxtContextenvEnvironment)
[QualifiedIdentifier  SimpleQualifiedIdentifierdo
Validate[SimpleQualifiedIdentifier](cxtenv);
Multiname[QualifiedIdentifier Multiname[SimpleQualifiedIdentifier];
[QualifiedIdentifier  ExpressionQualifiedIdentifierdo
Validate[ExpressionQualifiedIdentifier](cxtenv);
Multiname[QualifiedIdentifier Multiname[ExpressionQualifiedIdentifier]
end proc;

Unit Expressions

Syntax

UnitExpression 
   ParenListExpression
|  Number [no line break] String
|  UnitExpression [no line break] String

Validation

proc Validate[UnitExpression] (cxtContextenvEnvironment)
[UnitExpression  ParenListExpressiondo Validate[ParenListExpression](cxtenv);
[UnitExpression  Number [no line break] Stringdo ????;
[UnitExpression  UnitExpression [no line break] Stringdo ????
end proc;

Evaluation

proc Eval[UnitExpression] (envEnvironmentphasePhase): ObjOrRef
[UnitExpression  ParenListExpressiondo
return Eval[ParenListExpression](envphase);
[UnitExpression  Number [no line break] Stringdo ????;
[UnitExpression  UnitExpression [no line break] Stringdo ????
end proc;

Primary Expressions

Syntax

PrimaryExpression 
   null
|  true
|  false
|  public
|  Number
|  String
|  this
|  RegularExpression
|  UnitExpression
|  ArrayLiteral
|  ObjectLiteral
|  FunctionExpression
ParenExpression  ( AssignmentExpressionallowIn )
ParenListExpression 
   ParenExpression
|  ( ListExpressionallowIn , AssignmentExpressionallowIn )

Validation

proc Validate[PrimaryExpression] (cxtContextenvEnvironment)
[PrimaryExpression  nulldo nothing;
[PrimaryExpression  truedo nothing;
[PrimaryExpression  falsedo nothing;
[PrimaryExpression  publicdo nothing;
[PrimaryExpression  Numberdo nothing;
[PrimaryExpression  Stringdo nothing;
[PrimaryExpression  thisdo
if findThis(envtrue) = none then throw syntaxError end if;
[PrimaryExpression  RegularExpressiondo nothing;
[PrimaryExpression  UnitExpressiondo Validate[UnitExpression](cxtenv);
[PrimaryExpression  ArrayLiteraldo ????;
[PrimaryExpression  ObjectLiteraldo ????;
[PrimaryExpression  FunctionExpressiondo Validate[FunctionExpression](cxtenv)
end proc;
Validate[ParenExpression  ( AssignmentExpressionallowIn )]: Context  Environment  () = Validate[AssignmentExpressionallowIn];
proc Validate[ParenListExpression] (cxtContextenvEnvironment)
[ParenListExpression  ParenExpressiondo Validate[ParenExpression](cxtenv);
[ParenListExpression  ( ListExpressionallowIn , AssignmentExpressionallowIn )do
Validate[ListExpressionallowIn](cxtenv);
Validate[AssignmentExpressionallowIn](cxtenv)
end proc;

Evaluation

proc Eval[PrimaryExpression] (envEnvironmentphasePhase): ObjOrRef
[PrimaryExpression  nulldo return null;
[PrimaryExpression  truedo return true;
[PrimaryExpression  falsedo return false;
[PrimaryExpression  publicdo return publicNamespace;
[PrimaryExpression  Numberdo return Value[Number];
[PrimaryExpression  Stringdo return Value[String];
[PrimaryExpression  thisdo
thisObjectFutOpt  findThis(envtrue);
Note that Validate ensured that this cannot be none at this point.
if this = future then throw uninitialisedError end if;
return this;
[PrimaryExpression  RegularExpressiondo ????;
[PrimaryExpression  UnitExpressiondo return Eval[UnitExpression](envphase);
[PrimaryExpression  ArrayLiteraldo ????;
[PrimaryExpression  ObjectLiteraldo ????;
[PrimaryExpression  FunctionExpressiondo
return Eval[FunctionExpression](envphase)
end proc;
Eval[ParenExpression  ( AssignmentExpressionallowIn )]: Environment  Phase  ObjOrRefEval[AssignmentExpressionallowIn];
proc Eval[ParenListExpression] (envEnvironmentphasePhase): ObjOrRef
[ParenListExpression  ParenExpressiondo return Eval[ParenExpression](envphase);
[ParenListExpression  ( ListExpressionallowIn , AssignmentExpressionallowIn )do
raObjOrRef  Eval[ListExpressionallowIn](envphase);
readReference(raphase);
rbObjOrRef  Eval[AssignmentExpressionallowIn](envphase);
return readReference(rbphase)
end proc;
proc EvalAsList[ParenListExpression] (envEnvironmentphasePhase): Object[]
[ParenListExpression  ParenExpressiondo
rObjOrRef  Eval[ParenExpression](envphase);
eltObject  readReference(rphase);
return [elt];
[ParenListExpression  ( ListExpressionallowIn , AssignmentExpressionallowIn )do
eltsObject[]  EvalAsList[ListExpressionallowIn](envphase);
rObjOrRef  Eval[AssignmentExpressionallowIn](envphase);
eltObject  readReference(rphase);
return elts  [elt]
end proc;

Function Expressions

Syntax

FunctionExpression 
   function FunctionSignature Block
|  function Identifier FunctionSignature Block

Validation

proc Validate[FunctionExpression] (cxtContextenvEnvironment)
[FunctionExpression  function FunctionSignature Blockdo ????;
[FunctionExpression  function Identifier FunctionSignature Blockdo ????
end proc;

Evaluation

proc Eval[FunctionExpression] (envEnvironmentphasePhase): ObjOrRef
[FunctionExpression  function FunctionSignature Blockdo ????;
[FunctionExpression  function Identifier FunctionSignature Blockdo ????
end proc;

Object Literals

Syntax

ObjectLiteral 
   { }
|  { FieldList }
FieldList 
   LiteralField
|  FieldList , LiteralField
LiteralField  FieldName : AssignmentExpressionallowIn
FieldName 
   Identifier
|  String
|  Number

Validation

proc Validate[LiteralField  FieldName : AssignmentExpressionallowIn] (cxtContextenvEnvironment): String{}
namesString{}  Validate[FieldName](cxtenv);
Validate[AssignmentExpressionallowIn](cxtenv);
return names
end proc;
proc Validate[FieldName] (cxtContextenvEnvironment): String{}
[FieldName  Identifierdo return {Name[Identifier]};
[FieldName  Stringdo return {Value[String]};
[FieldName  Numberdo ????;
[FieldName  ParenExpressiondo ????
end proc;

Evaluation

proc Eval[LiteralField  FieldName : AssignmentExpressionallowIn] (envEnvironmentphasePhase): NamedArgument
nameString  Eval[FieldName](envphase);
rObjOrRef  Eval[AssignmentExpressionallowIn](envphase);
valueObject  readReference(rphase);
return NamedArgumentnamenamevaluevalue
end proc;
proc Eval[FieldName] (envEnvironmentphasePhase): String
[FieldName  Identifierdo return Name[Identifier];
[FieldName  Stringdo return Value[String];
[FieldName  Numberdo ????;
[FieldName  ParenExpressiondo ????
end proc;

Array Literals

Syntax

ArrayLiteral  [ ElementList ]
ElementList 
   LiteralElement
|  ElementList , LiteralElement
LiteralElement 
   «empty»
|  AssignmentExpressionallowIn

Super Expressions

Syntax

SuperExpression 
   super
|  FullSuperExpression
FullSuperExpression  super ParenExpression

Validation

proc Validate[SuperExpression] (cxtContextenvEnvironment)
[SuperExpression  superdo
if getEnclosingClass(env) = none or findThis(envfalse) = none then
end if;
[SuperExpression  FullSuperExpressiondo Validate[FullSuperExpression](cxtenv)
end proc;
proc Validate[FullSuperExpression  super ParenExpression] (cxtContextenvEnvironment)
if getEnclosingClass(env) = none then throw syntaxError end if;
Validate[ParenExpression](cxtenv)
end proc;

Evaluation

proc Eval[SuperExpression] (envEnvironmentphasePhase): ObjOrRefOptionalLimit
[SuperExpression  superdo
thisObjectFutOpt  findThis(envfalse);
Note that Validate ensured that this cannot be none at this point.
if this = future then throw uninitialisedError end if;
limitClassOpt  getEnclosingClass(env);
Note that Validate ensured that limit cannot be none at this point.
return LimitedObjOrRefrefthislimitlimit;
[SuperExpression  FullSuperExpressiondo
return Eval[FullSuperExpression](envphase)
end proc;
proc Eval[FullSuperExpression  super ParenExpression] (envEnvironmentphasePhase): ObjOrRefOptionalLimit
rObjOrRef  Eval[ParenExpression](envphase);
limitClassOpt  getEnclosingClass(env);
Note that Validate ensured that limit cannot be none at this point.
return LimitedObjOrRefrefrlimitlimit
end proc;

Postfix Expressions

Syntax

PostfixExpression 
   AttributeExpression
|  FullPostfixExpression
|  ShortNewExpression
PostfixExpressionOrSuper 
   PostfixExpression
|  SuperExpression
AttributeExpression 
   SimpleQualifiedIdentifier
|  AttributeExpression MemberOperator
|  AttributeExpression Arguments
FullPostfixExpression 
   PrimaryExpression
|  ExpressionQualifiedIdentifier
|  FullNewExpression
|  FullPostfixExpression MemberOperator
|  SuperExpression DotOperator
|  FullPostfixExpression Arguments
|  FullSuperExpression Arguments
|  PostfixExpressionOrSuper [no line break] ++
|  PostfixExpressionOrSuper [no line break] --
FullNewExpression 
   new FullNewSubexpression Arguments
|  new FullSuperExpression Arguments
FullNewSubexpression 
   PrimaryExpression
|  QualifiedIdentifier
|  FullNewExpression
|  FullNewSubexpression MemberOperator
|  SuperExpression DotOperator
ShortNewExpression 
   new ShortNewSubexpression
|  new SuperExpression
ShortNewSubexpression 
   FullNewSubexpression
|  ShortNewExpression

Validation

Validate[PostfixExpression]: Context  Environment  ();
Validate[PostfixExpression  AttributeExpression] = Validate[AttributeExpression];
Validate[PostfixExpression  FullPostfixExpression] = Validate[FullPostfixExpression];
Validate[PostfixExpression  ShortNewExpression] = Validate[ShortNewExpression];
Validate[PostfixExpressionOrSuper]: Context  Environment  ();
Validate[PostfixExpressionOrSuper  PostfixExpression] = Validate[PostfixExpression];
Validate[PostfixExpressionOrSuper  SuperExpression] = Validate[SuperExpression];
Context[AttributeExpression]: Context;
proc Validate[AttributeExpression] (cxtContextenvEnvironment)
[AttributeExpression  SimpleQualifiedIdentifierdo
Validate[SimpleQualifiedIdentifier](cxtenv);
Context[AttributeExpression cxt;
[AttributeExpression0  AttributeExpression1 MemberOperatordo
Validate[AttributeExpression1](cxtenv);
Validate[MemberOperator](cxtenv);
[AttributeExpression0  AttributeExpression1 Argumentsdo
Validate[AttributeExpression1](cxtenv);
Validate[Arguments](cxtenv)
end proc;
Context[FullPostfixExpression]: Context;
proc Validate[FullPostfixExpression] (cxtContextenvEnvironment)
[FullPostfixExpression  PrimaryExpressiondo
Validate[PrimaryExpression](cxtenv);
Validate[ExpressionQualifiedIdentifier](cxtenv);
Context[FullPostfixExpression cxt;
[FullPostfixExpression  FullNewExpressiondo
Validate[FullNewExpression](cxtenv);
Validate[FullPostfixExpression1](cxtenv);
Validate[MemberOperator](cxtenv);
[FullPostfixExpression  SuperExpression DotOperatordo
Validate[SuperExpression](cxtenv);
Validate[DotOperator](cxtenv);
[FullPostfixExpression0  FullPostfixExpression1 Argumentsdo
Validate[FullPostfixExpression1](cxtenv);
Validate[Arguments](cxtenv);
[FullPostfixExpression  FullSuperExpression Argumentsdo
Validate[FullSuperExpression](cxtenv);
Validate[Arguments](cxtenv);
[FullPostfixExpression  PostfixExpressionOrSuper [no line break] ++do
Validate[PostfixExpressionOrSuper](cxtenv);
[FullPostfixExpression  PostfixExpressionOrSuper [no line break] --do
Validate[PostfixExpressionOrSuper](cxtenv)
end proc;
proc Validate[FullNewExpression] (cxtContextenvEnvironment)
[FullNewExpression  new FullNewSubexpression Argumentsdo
Validate[FullNewSubexpression](cxtenv);
Validate[Arguments](cxtenv);
[FullNewExpression  new FullSuperExpression Argumentsdo
Validate[FullSuperExpression](cxtenv);
Validate[Arguments](cxtenv)
end proc;
Context[FullNewSubexpression]: Context;
proc Validate[FullNewSubexpression] (cxtContextenvEnvironment)
[FullNewSubexpression  PrimaryExpressiondo Validate[PrimaryExpression](cxtenv);
[FullNewSubexpression  QualifiedIdentifierdo
Validate[QualifiedIdentifier](cxtenv);
Context[FullNewSubexpression cxt;
[FullNewSubexpression  FullNewExpressiondo Validate[FullNewExpression](cxtenv);
[FullNewSubexpression0  FullNewSubexpression1 MemberOperatordo
Validate[FullNewSubexpression1](cxtenv);
Validate[MemberOperator](cxtenv);
[FullNewSubexpression  SuperExpression DotOperatordo
Validate[SuperExpression](cxtenv);
Validate[DotOperator](cxtenv)
end proc;
proc Validate[ShortNewExpression] (cxtContextenvEnvironment)
[ShortNewExpression  new ShortNewSubexpressiondo
Validate[ShortNewSubexpression](cxtenv);
[ShortNewExpression  new SuperExpressiondo Validate[SuperExpression](cxtenv)
end proc;
Validate[ShortNewSubexpression]: Context  Environment  ();
Validate[ShortNewSubexpression  FullNewSubexpression] = Validate[FullNewSubexpression];
Validate[ShortNewSubexpression  ShortNewExpression] = Validate[ShortNewExpression];

Evaluation

Eval[PostfixExpression]: Environment  Phase  ObjOrRef;
Eval[PostfixExpression  AttributeExpression] = Eval[AttributeExpression];
Eval[PostfixExpression  FullPostfixExpression] = Eval[FullPostfixExpression];
Eval[PostfixExpression  ShortNewExpression] = Eval[ShortNewExpression];
Eval[PostfixExpressionOrSuper]: Environment  Phase  ObjOrRefOptionalLimit;
Eval[PostfixExpressionOrSuper  PostfixExpression] = Eval[PostfixExpression];
Eval[PostfixExpressionOrSuper  SuperExpression] = Eval[SuperExpression];
proc Eval[AttributeExpression] (envEnvironmentphasePhase): ObjOrRef
[AttributeExpression  SimpleQualifiedIdentifierdo
return LexicalReferenceenvenv, variableMultinameMultiname[SimpleQualifiedIdentifier], cxtContext[AttributeExpression];
[AttributeExpression0  AttributeExpression1 MemberOperatordo
rObjOrRef  Eval[AttributeExpression1](envphase);
aObject  readReference(rphase);
return Eval[MemberOperator](envaphase);
[AttributeExpression0  AttributeExpression1 Argumentsdo
rObjOrRef  Eval[AttributeExpression1](envphase);
fObject  readReference(rphase);
baseObject  referenceBase(r);
argsArgumentList  Eval[Arguments](envphase);
return unaryDispatch(callTablebasefargsphase)
end proc;
proc Eval[FullPostfixExpression] (envEnvironmentphasePhase): ObjOrRef
[FullPostfixExpression  PrimaryExpressiondo
return Eval[PrimaryExpression](envphase);
return LexicalReferenceenvenv, variableMultinameMultiname[ExpressionQualifiedIdentifier], cxtContext[FullPostfixExpression];
[FullPostfixExpression  FullNewExpressiondo
return Eval[FullNewExpression](envphase);
rObjOrRef  Eval[FullPostfixExpression1](envphase);
aObject  readReference(rphase);
return Eval[MemberOperator](envaphase);
[FullPostfixExpression  SuperExpression DotOperatordo
rObjOrRefOptionalLimit  Eval[SuperExpression](envphase);
aObjOptionalLimit  readRefWithLimit(rphase);
return Eval[DotOperator](envaphase);
[FullPostfixExpression0  FullPostfixExpression1 Argumentsdo
rObjOrRef  Eval[FullPostfixExpression1](envphase);
fObject  readReference(rphase);
baseObject  referenceBase(r);
argsArgumentList  Eval[Arguments](envphase);
return unaryDispatch(callTablebasefargsphase);
[FullPostfixExpression  FullSuperExpression Argumentsdo
rObjOrRefOptionalLimit  Eval[FullSuperExpression](envphase);
fObjOptionalLimit  readRefWithLimit(rphase);
baseObject  referenceBase(r);
argsArgumentList  Eval[Arguments](envphase);
return unaryDispatch(callTablebasefargsphase);
[FullPostfixExpression  PostfixExpressionOrSuper [no line break] ++do
if phase = compile then throw compileExpressionError end if;
rObjOrRefOptionalLimit  Eval[PostfixExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(rphase);
bObject  unaryDispatch(incrementTable, null, a, ArgumentListpositional[]named: {}, phase);
writeReference(rbphase);
return getObject(a);
[FullPostfixExpression  PostfixExpressionOrSuper [no line break] --do
if phase = compile then throw compileExpressionError end if;
rObjOrRefOptionalLimit  Eval[PostfixExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(rphase);
bObject  unaryDispatch(decrementTable, null, a, ArgumentListpositional[]named: {}, phase);
writeReference(rbphase);
return getObject(a)
end proc;
proc Eval[FullNewExpression] (envEnvironmentphasePhase): ObjOrRef
[FullNewExpression  new FullNewSubexpression Argumentsdo
rObjOrRef  Eval[FullNewSubexpression](envphase);
fObject  readReference(rphase);
argsArgumentList  Eval[Arguments](envphase);
return unaryDispatch(constructTablenullfargsphase);
[FullNewExpression  new FullSuperExpression Argumentsdo
rObjOrRefOptionalLimit  Eval[FullSuperExpression](envphase);
fObjOptionalLimit  readRefWithLimit(rphase);
argsArgumentList  Eval[Arguments](envphase);
return unaryDispatch(constructTablenullfargsphase)
end proc;
proc Eval[FullNewSubexpression] (envEnvironmentphasePhase): ObjOrRef
[FullNewSubexpression  PrimaryExpressiondo
return Eval[PrimaryExpression](envphase);
[FullNewSubexpression  QualifiedIdentifierdo
return LexicalReferenceenvenv, variableMultinameMultiname[QualifiedIdentifier], cxtContext[FullNewSubexpression];
[FullNewSubexpression  FullNewExpressiondo
return Eval[FullNewExpression](envphase);
[FullNewSubexpression0  FullNewSubexpression1 MemberOperatordo
rObjOrRef  Eval[FullNewSubexpression1](envphase);
aObject  readReference(rphase);
return Eval[MemberOperator](envaphase);
[FullNewSubexpression  SuperExpression DotOperatordo
rObjOrRefOptionalLimit  Eval[SuperExpression](envphase);
aObjOptionalLimit  readRefWithLimit(rphase);
return Eval[DotOperator](envaphase)
end proc;
proc Eval[ShortNewExpression] (envEnvironmentphasePhase): ObjOrRef
[ShortNewExpression  new ShortNewSubexpressiondo
rObjOrRef  Eval[ShortNewSubexpression](envphase);
fObject  readReference(rphase);
return unaryDispatch(constructTable, null, f, ArgumentListpositional[]named: {}, phase);
[ShortNewExpression  new SuperExpressiondo
rObjOrRefOptionalLimit  Eval[SuperExpression](envphase);
fObjOptionalLimit  readRefWithLimit(rphase);
return unaryDispatch(constructTable, null, f, ArgumentListpositional[]named: {}, phase)
end proc;
Eval[ShortNewSubexpression]: Environment  Phase  ObjOrRef;
Eval[ShortNewSubexpression  FullNewSubexpression] = Eval[FullNewSubexpression];
Eval[ShortNewSubexpression  ShortNewExpression] = Eval[ShortNewExpression];

Member Operators

Syntax

MemberOperator 
   DotOperator
|  . ParenExpression
DotOperator 
   . QualifiedIdentifier
|  Brackets
Brackets 
   [ ]
|  [ ListExpressionallowIn ]
|  [ NamedArgumentList ]
Arguments 
   ParenExpressions
|  ( NamedArgumentList )
ParenExpressions 
   ( )
|  ParenListExpression
NamedArgumentList 
   LiteralField
|  ListExpressionallowIn , LiteralField
|  NamedArgumentList , LiteralField

Validation

proc Validate[MemberOperator] (cxtContextenvEnvironment)
[MemberOperator  DotOperatordo Validate[DotOperator](cxtenv);
[MemberOperator  . ParenExpressiondo Validate[ParenExpression](cxtenv)
end proc;
proc Validate[DotOperator] (cxtContextenvEnvironment)
[DotOperator  . QualifiedIdentifierdo Validate[QualifiedIdentifier](cxtenv);
[DotOperator  Bracketsdo Validate[Brackets](cxtenv)
end proc;
proc Validate[Brackets] (cxtContextenvEnvironment)
[Brackets  [ ]do nothing;
[Brackets  [ ListExpressionallowIn ]do Validate[ListExpressionallowIn](cxtenv);
[Brackets  [ NamedArgumentList ]do Validate[NamedArgumentList](cxtenv)
end proc;
proc Validate[Arguments] (cxtContextenvEnvironment)
[Arguments  ParenExpressionsdo Validate[ParenExpressions](cxtenv);
[Arguments  ( NamedArgumentList )do Validate[NamedArgumentList](cxtenv)
end proc;
proc Validate[ParenExpressions] (cxtContextenvEnvironment)
[ParenExpressions  ( )do nothing;
[ParenExpressions  ParenListExpressiondo Validate[ParenListExpression](cxtenv)
end proc;
proc Validate[NamedArgumentList] (cxtContextenvEnvironment): String{}
[NamedArgumentList  LiteralFielddo return Validate[LiteralField](cxtenv);
[NamedArgumentList  ListExpressionallowIn , LiteralFielddo
Validate[ListExpressionallowIn](cxtenv);
return Validate[LiteralField](cxtenv);
[NamedArgumentList0  NamedArgumentList1 , LiteralFielddo
names1String{}  Validate[NamedArgumentList1](cxtenv);
names2String{}  Validate[LiteralField](cxtenv);
if names1  names2  {} then throw syntaxError end if;
return names1  names2
end proc;

Evaluation

proc Eval[MemberOperator] (envEnvironmentbaseObjectphasePhase): ObjOrRef
[MemberOperator  DotOperatordo return Eval[DotOperator](envbasephase);
[MemberOperator  . ParenExpressiondo ????
end proc;
proc Eval[DotOperator] (envEnvironmentbaseObjOptionalLimitphasePhase): ObjOrRef
[DotOperator  . QualifiedIdentifierdo
return DotReferencebasebasepropertyMultinameMultiname[QualifiedIdentifier];
[DotOperator  Bracketsdo
argsArgumentList  Eval[Brackets](envphase);
return BracketReferencebasebaseargsargs
end proc;
proc Eval[Brackets] (envEnvironmentphasePhase): ArgumentList
[Brackets  [ ]do return ArgumentListpositional[]named: {};
[Brackets  [ ListExpressionallowIn ]do
positionalObject[]  EvalAsList[ListExpressionallowIn](envphase);
return ArgumentListpositionalpositionalnamed: {};
[Brackets  [ NamedArgumentList ]do return Eval[NamedArgumentList](envphase)
end proc;
proc Eval[Arguments] (envEnvironmentphasePhase): ArgumentList
[Arguments  ParenExpressionsdo return Eval[ParenExpressions](envphase);
[Arguments  ( NamedArgumentList )do return Eval[NamedArgumentList](envphase)
end proc;
proc Eval[ParenExpressions] (envEnvironmentphasePhase): ArgumentList
[ParenExpressions  ( )do return ArgumentListpositional[]named: {};
[ParenExpressions  ParenListExpressiondo
positionalObject[]  EvalAsList[ParenListExpression](envphase);
return ArgumentListpositionalpositionalnamed: {}
end proc;
proc Eval[NamedArgumentList] (envEnvironmentphasePhase): ArgumentList
[NamedArgumentList  LiteralFielddo
naNamedArgument  Eval[LiteralField](envphase);
return ArgumentListpositional[]named: {na};
[NamedArgumentList  ListExpressionallowIn , LiteralFielddo
positionalObject[]  EvalAsList[ListExpressionallowIn](envphase);
naNamedArgument  Eval[LiteralField](envphase);
return ArgumentListpositionalpositionalnamed: {na};
[NamedArgumentList0  NamedArgumentList1 , LiteralFielddo
argsArgumentList  Eval[NamedArgumentList1](envphase);
naNamedArgument  Eval[LiteralField](envphase);
if some na2  args.named satisfies na2.name = na.name then
end if;
return ArgumentListpositionalargs.positionalnamedargs.named  {na}
end proc;

Unary Operators

Syntax

UnaryExpression 
   PostfixExpression
|  delete PostfixExpression
|  void UnaryExpression
|  typeof UnaryExpression
|  ++ PostfixExpressionOrSuper
|  -- PostfixExpressionOrSuper
|  + UnaryExpressionOrSuper
|  - UnaryExpressionOrSuper
|  ~ UnaryExpressionOrSuper
|  ! UnaryExpression
UnaryExpressionOrSuper 
   UnaryExpression
|  SuperExpression

Validation

proc Validate[UnaryExpression] (cxtContextenvEnvironment)
[UnaryExpression  PostfixExpressiondo Validate[PostfixExpression](cxtenv);
[UnaryExpression  delete PostfixExpressiondo
Validate[PostfixExpression](cxtenv);
[UnaryExpression0  void UnaryExpression1do Validate[UnaryExpression1](cxtenv);
[UnaryExpression0  typeof UnaryExpression1do
Validate[UnaryExpression1](cxtenv);
[UnaryExpression  ++ PostfixExpressionOrSuperdo
Validate[PostfixExpressionOrSuper](cxtenv);
[UnaryExpression  -- PostfixExpressionOrSuperdo
Validate[PostfixExpressionOrSuper](cxtenv);
[UnaryExpression  + UnaryExpressionOrSuperdo
Validate[UnaryExpressionOrSuper](cxtenv);
[UnaryExpression  - UnaryExpressionOrSuperdo
Validate[UnaryExpressionOrSuper](cxtenv);
[UnaryExpression  ~ UnaryExpressionOrSuperdo
Validate[UnaryExpressionOrSuper](cxtenv);
[UnaryExpression0  ! UnaryExpression1do Validate[UnaryExpression1](cxtenv)
end proc;
Validate[UnaryExpressionOrSuper]: Context  Environment  ();
Validate[UnaryExpressionOrSuper  UnaryExpression] = Validate[UnaryExpression];
Validate[UnaryExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[UnaryExpression] (envEnvironmentphasePhase): ObjOrRef
[UnaryExpression  PostfixExpressiondo return Eval[PostfixExpression](envphase);
[UnaryExpression  delete PostfixExpressiondo
if phase = compile then throw compileExpressionError end if;
rObjOrRef  Eval[PostfixExpression](envphase);
return deleteReference(rphase);
[UnaryExpression0  void UnaryExpression1do
rObjOrRef  Eval[UnaryExpression1](envphase);
readReference(rphase);
return undefined;
[UnaryExpression0  typeof UnaryExpression1do
rObjOrRef  Eval[UnaryExpression1](envphase);
aObject  readReference(rphase);
case a of
Undefined do return “undefined”;
Null  Prototype  Package  Global do return “object”;
Boolean do return “boolean”;
Float64 do return “number”;
String do return “string”;
Namespace do return “namespace”;
CompoundAttribute do return “attribute”;
Class  MethodClosure do return “function”;
Instance do return a.typeofString
end case;
[UnaryExpression  ++ PostfixExpressionOrSuperdo
if phase = compile then throw compileExpressionError end if;
rObjOrRefOptionalLimit  Eval[PostfixExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(rphase);
bObject  unaryDispatch(incrementTable, null, a, ArgumentListpositional[]named: {}, phase);
writeReference(rbphase);
return b;
[UnaryExpression  -- PostfixExpressionOrSuperdo
if phase = compile then throw compileExpressionError end if;
rObjOrRefOptionalLimit  Eval[PostfixExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(rphase);
bObject  unaryDispatch(decrementTable, null, a, ArgumentListpositional[]named: {}, phase);
writeReference(rbphase);
return b;
[UnaryExpression  + UnaryExpressionOrSuperdo
rObjOrRefOptionalLimit  Eval[UnaryExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(rphase);
return unaryPlus(aphase);
[UnaryExpression  - UnaryExpressionOrSuperdo
rObjOrRefOptionalLimit  Eval[UnaryExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(rphase);
return unaryDispatch(minusTable, null, a, ArgumentListpositional[]named: {}, phase);
[UnaryExpression  ~ UnaryExpressionOrSuperdo
rObjOrRefOptionalLimit  Eval[UnaryExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(rphase);
return unaryDispatch(bitwiseNotTable, null, a, ArgumentListpositional[]named: {}, phase);
[UnaryExpression0  ! UnaryExpression1do
rObjOrRef  Eval[UnaryExpression1](envphase);
aObject  readReference(rphase);
return unaryNot(aphase)
end proc;
Eval[UnaryExpressionOrSuper]: Environment  Phase  ObjOrRefOptionalLimit;
Eval[UnaryExpressionOrSuper  UnaryExpression] = Eval[UnaryExpression];
Eval[UnaryExpressionOrSuper  SuperExpression] = Eval[SuperExpression];

Multiplicative Operators

Syntax

MultiplicativeExpression 
   UnaryExpression
|  MultiplicativeExpressionOrSuper * UnaryExpressionOrSuper
|  MultiplicativeExpressionOrSuper / UnaryExpressionOrSuper
|  MultiplicativeExpressionOrSuper % UnaryExpressionOrSuper
MultiplicativeExpressionOrSuper 
   MultiplicativeExpression
|  SuperExpression

Validation

proc Validate[MultiplicativeExpression] (cxtContextenvEnvironment)
[MultiplicativeExpression  UnaryExpressiondo Validate[UnaryExpression](cxtenv);
Validate[MultiplicativeExpressionOrSuper](cxtenv);
Validate[UnaryExpressionOrSuper](cxtenv);
Validate[MultiplicativeExpressionOrSuper](cxtenv);
Validate[UnaryExpressionOrSuper](cxtenv);
Validate[MultiplicativeExpressionOrSuper](cxtenv);
Validate[UnaryExpressionOrSuper](cxtenv)
end proc;
Validate[MultiplicativeExpressionOrSuper]: Context  Environment  ();
Validate[MultiplicativeExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[MultiplicativeExpression] (envEnvironmentphasePhase): ObjOrRef
[MultiplicativeExpression  UnaryExpressiondo
return Eval[UnaryExpression](envphase);
raObjOrRefOptionalLimit  Eval[MultiplicativeExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[UnaryExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(multiplyTableabphase);
raObjOrRefOptionalLimit  Eval[MultiplicativeExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[UnaryExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(divideTableabphase);
raObjOrRefOptionalLimit  Eval[MultiplicativeExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[UnaryExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(remainderTableabphase)
end proc;
Eval[MultiplicativeExpressionOrSuper]: Environment  Phase  ObjOrRefOptionalLimit;
Eval[MultiplicativeExpressionOrSuper  SuperExpression] = Eval[SuperExpression];

Additive Operators

Syntax

AdditiveExpression 
   MultiplicativeExpression
|  AdditiveExpressionOrSuper + MultiplicativeExpressionOrSuper
|  AdditiveExpressionOrSuper - MultiplicativeExpressionOrSuper
AdditiveExpressionOrSuper 
   AdditiveExpression
|  SuperExpression

Validation

proc Validate[AdditiveExpression] (cxtContextenvEnvironment)
[AdditiveExpression  MultiplicativeExpressiondo
Validate[MultiplicativeExpression](cxtenv);
Validate[AdditiveExpressionOrSuper](cxtenv);
Validate[MultiplicativeExpressionOrSuper](cxtenv);
Validate[AdditiveExpressionOrSuper](cxtenv);
Validate[MultiplicativeExpressionOrSuper](cxtenv)
end proc;
Validate[AdditiveExpressionOrSuper]: Context  Environment  ();
Validate[AdditiveExpressionOrSuper  AdditiveExpression] = Validate[AdditiveExpression];
Validate[AdditiveExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[AdditiveExpression] (envEnvironmentphasePhase): ObjOrRef
[AdditiveExpression  MultiplicativeExpressiondo
return Eval[MultiplicativeExpression](envphase);
raObjOrRefOptionalLimit  Eval[AdditiveExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[MultiplicativeExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(addTableabphase);
raObjOrRefOptionalLimit  Eval[AdditiveExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[MultiplicativeExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(subtractTableabphase)
end proc;
Eval[AdditiveExpressionOrSuper]: Environment  Phase  ObjOrRefOptionalLimit;
Eval[AdditiveExpressionOrSuper  AdditiveExpression] = Eval[AdditiveExpression];
Eval[AdditiveExpressionOrSuper  SuperExpression] = Eval[SuperExpression];

Bitwise Shift Operators

Syntax

ShiftExpression 
   AdditiveExpression
|  ShiftExpressionOrSuper << AdditiveExpressionOrSuper
|  ShiftExpressionOrSuper >> AdditiveExpressionOrSuper
|  ShiftExpressionOrSuper >>> AdditiveExpressionOrSuper
ShiftExpressionOrSuper 
   ShiftExpression
|  SuperExpression

Validation

proc Validate[ShiftExpression] (cxtContextenvEnvironment)
[ShiftExpression  AdditiveExpressiondo Validate[AdditiveExpression](cxtenv);
Validate[ShiftExpressionOrSuper](cxtenv);
Validate[AdditiveExpressionOrSuper](cxtenv);
Validate[ShiftExpressionOrSuper](cxtenv);
Validate[AdditiveExpressionOrSuper](cxtenv);
Validate[ShiftExpressionOrSuper](cxtenv);
Validate[AdditiveExpressionOrSuper](cxtenv)
end proc;
Validate[ShiftExpressionOrSuper]: Context  Environment  ();
Validate[ShiftExpressionOrSuper  ShiftExpression] = Validate[ShiftExpression];
Validate[ShiftExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[ShiftExpression] (envEnvironmentphasePhase): ObjOrRef
[ShiftExpression  AdditiveExpressiondo
return Eval[AdditiveExpression](envphase);
raObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[AdditiveExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(shiftLeftTableabphase);
raObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[AdditiveExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(shiftRightTableabphase);
raObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[AdditiveExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(shiftRightUnsignedTableabphase)
end proc;
Eval[ShiftExpressionOrSuper]: Environment  Phase  ObjOrRefOptionalLimit;
Eval[ShiftExpressionOrSuper  ShiftExpression] = Eval[ShiftExpression];
Eval[ShiftExpressionOrSuper  SuperExpression] = Eval[SuperExpression];

Relational Operators

Syntax

RelationalExpressionallowIn 
   ShiftExpression
|  RelationalExpressionOrSuperallowIn < ShiftExpressionOrSuper
|  RelationalExpressionOrSuperallowIn > ShiftExpressionOrSuper
|  RelationalExpressionOrSuperallowIn <= ShiftExpressionOrSuper
|  RelationalExpressionOrSuperallowIn >= ShiftExpressionOrSuper
|  RelationalExpressionallowIn is ShiftExpression
|  RelationalExpressionallowIn as ShiftExpression
|  RelationalExpressionallowIn in ShiftExpressionOrSuper
|  RelationalExpressionallowIn instanceof ShiftExpression
RelationalExpressionnoIn 
   ShiftExpression
|  RelationalExpressionOrSupernoIn < ShiftExpressionOrSuper
|  RelationalExpressionOrSupernoIn > ShiftExpressionOrSuper
|  RelationalExpressionOrSupernoIn <= ShiftExpressionOrSuper
|  RelationalExpressionOrSupernoIn >= ShiftExpressionOrSuper
|  RelationalExpressionnoIn is ShiftExpression
|  RelationalExpressionnoIn as ShiftExpression
|  RelationalExpressionnoIn instanceof ShiftExpression
RelationalExpressionOrSuper 
   RelationalExpression
|  SuperExpression

Validation

proc Validate[RelationalExpression] (cxtContextenvEnvironment)
[RelationalExpression  ShiftExpressiondo Validate[ShiftExpression](cxtenv);
[RelationalExpression  RelationalExpressionOrSuper < ShiftExpressionOrSuperdo
Validate[RelationalExpressionOrSuper](cxtenv);
Validate[ShiftExpressionOrSuper](cxtenv);
[RelationalExpression  RelationalExpressionOrSuper > ShiftExpressionOrSuperdo
Validate[RelationalExpressionOrSuper](cxtenv);
Validate[ShiftExpressionOrSuper](cxtenv);
[RelationalExpression  RelationalExpressionOrSuper <= ShiftExpressionOrSuperdo
Validate[RelationalExpressionOrSuper](cxtenv);
Validate[ShiftExpressionOrSuper](cxtenv);
[RelationalExpression  RelationalExpressionOrSuper >= ShiftExpressionOrSuperdo
Validate[RelationalExpressionOrSuper](cxtenv);
Validate[ShiftExpressionOrSuper](cxtenv);
[RelationalExpression0  RelationalExpression1 is ShiftExpressiondo
Validate[RelationalExpression1](cxtenv);
Validate[ShiftExpression](cxtenv);
[RelationalExpression0  RelationalExpression1 as ShiftExpressiondo
Validate[RelationalExpression1](cxtenv);
Validate[ShiftExpression](cxtenv);
[RelationalExpressionallowIn0  RelationalExpressionallowIn1 in ShiftExpressionOrSuperdo
Validate[RelationalExpressionallowIn1](cxtenv);
Validate[ShiftExpressionOrSuper](cxtenv);
[RelationalExpression0  RelationalExpression1 instanceof ShiftExpressiondo
Validate[RelationalExpression1](cxtenv);
Validate[ShiftExpression](cxtenv)
end proc;
Validate[RelationalExpressionOrSuper]: Context  Environment  ();
Validate[RelationalExpressionOrSuper  RelationalExpression] = Validate[RelationalExpression];
Validate[RelationalExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[RelationalExpression] (envEnvironmentphasePhase): ObjOrRef
[RelationalExpression  ShiftExpressiondo
return Eval[ShiftExpression](envphase);
[RelationalExpression  RelationalExpressionOrSuper < ShiftExpressionOrSuperdo
raObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(lessTableabphase);
[RelationalExpression  RelationalExpressionOrSuper > ShiftExpressionOrSuperdo
raObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(lessTablebaphase);
[RelationalExpression  RelationalExpressionOrSuper <= ShiftExpressionOrSuperdo
raObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(lessOrEqualTableabphase);
[RelationalExpression  RelationalExpressionOrSuper >= ShiftExpressionOrSuperdo
raObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(lessOrEqualTablebaphase);
[RelationalExpression  RelationalExpression is ShiftExpressiondo ????;
[RelationalExpression  RelationalExpression as ShiftExpressiondo ????;
[RelationalExpressionallowIn  RelationalExpressionallowIn in ShiftExpressionOrSuperdo
????;
[RelationalExpression  RelationalExpression instanceof ShiftExpressiondo ????
end proc;
Eval[RelationalExpressionOrSuper]: Environment  Phase  ObjOrRefOptionalLimit;
Eval[RelationalExpressionOrSuper  RelationalExpression] = Eval[RelationalExpression];
Eval[RelationalExpressionOrSuper  SuperExpression] = Eval[SuperExpression];

Equality Operators

Syntax

EqualityExpression 
   RelationalExpression
|  EqualityExpressionOrSuper == RelationalExpressionOrSuper
|  EqualityExpressionOrSuper != RelationalExpressionOrSuper
|  EqualityExpressionOrSuper === RelationalExpressionOrSuper
|  EqualityExpressionOrSuper !== RelationalExpressionOrSuper
EqualityExpressionOrSuper 
   EqualityExpression
|  SuperExpression

Validation

proc Validate[EqualityExpression] (cxtContextenvEnvironment)
[EqualityExpression  RelationalExpressiondo
Validate[RelationalExpression](cxtenv);
[EqualityExpression  EqualityExpressionOrSuper == RelationalExpressionOrSuperdo
Validate[EqualityExpressionOrSuper](cxtenv);
Validate[RelationalExpressionOrSuper](cxtenv);
[EqualityExpression  EqualityExpressionOrSuper != RelationalExpressionOrSuperdo
Validate[EqualityExpressionOrSuper](cxtenv);
Validate[RelationalExpressionOrSuper](cxtenv);
[EqualityExpression  EqualityExpressionOrSuper === RelationalExpressionOrSuperdo
Validate[EqualityExpressionOrSuper](cxtenv);
Validate[RelationalExpressionOrSuper](cxtenv);
[EqualityExpression  EqualityExpressionOrSuper !== RelationalExpressionOrSuperdo
Validate[EqualityExpressionOrSuper](cxtenv);
Validate[RelationalExpressionOrSuper](cxtenv)
end proc;
Validate[EqualityExpressionOrSuper]: Context  Environment  ();
Validate[EqualityExpressionOrSuper  EqualityExpression] = Validate[EqualityExpression];
Validate[EqualityExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[EqualityExpression] (envEnvironmentphasePhase): ObjOrRef
[EqualityExpression  RelationalExpressiondo
return Eval[RelationalExpression](envphase);
[EqualityExpression  EqualityExpressionOrSuper == RelationalExpressionOrSuperdo
raObjOrRefOptionalLimit  Eval[EqualityExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(equalTableabphase);
[EqualityExpression  EqualityExpressionOrSuper != RelationalExpressionOrSuperdo
raObjOrRefOptionalLimit  Eval[EqualityExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
cObject  binaryDispatch(equalTableabphase);
return unaryNot(cphase);
[EqualityExpression  EqualityExpressionOrSuper === RelationalExpressionOrSuperdo
raObjOrRefOptionalLimit  Eval[EqualityExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(strictEqualTableabphase);
[EqualityExpression  EqualityExpressionOrSuper !== RelationalExpressionOrSuperdo
raObjOrRefOptionalLimit  Eval[EqualityExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
cObject  binaryDispatch(strictEqualTableabphase);
return unaryNot(cphase)
end proc;
Eval[EqualityExpressionOrSuper]: Environment  Phase  ObjOrRefOptionalLimit;
Eval[EqualityExpressionOrSuper  EqualityExpression] = Eval[EqualityExpression];
Eval[EqualityExpressionOrSuper  SuperExpression] = Eval[SuperExpression];

Binary Bitwise Operators

Syntax

BitwiseAndExpression 
   EqualityExpression
|  BitwiseAndExpressionOrSuper & EqualityExpressionOrSuper
BitwiseXorExpression 
   BitwiseAndExpression
|  BitwiseXorExpressionOrSuper ^ BitwiseAndExpressionOrSuper
BitwiseOrExpression 
   BitwiseXorExpression
|  BitwiseOrExpressionOrSuper | BitwiseXorExpressionOrSuper
BitwiseAndExpressionOrSuper 
   BitwiseAndExpression
|  SuperExpression
BitwiseXorExpressionOrSuper 
   BitwiseXorExpression
|  SuperExpression
BitwiseOrExpressionOrSuper 
   BitwiseOrExpression
|  SuperExpression

Validation

proc Validate[BitwiseAndExpression] (cxtContextenvEnvironment)
[BitwiseAndExpression  EqualityExpressiondo
Validate[EqualityExpression](cxtenv);
[BitwiseAndExpression  BitwiseAndExpressionOrSuper & EqualityExpressionOrSuperdo
Validate[BitwiseAndExpressionOrSuper](cxtenv);
Validate[EqualityExpressionOrSuper](cxtenv)
end proc;
proc Validate[BitwiseXorExpression] (cxtContextenvEnvironment)
[BitwiseXorExpression  BitwiseAndExpressiondo
Validate[BitwiseAndExpression](cxtenv);
[BitwiseXorExpression  BitwiseXorExpressionOrSuper ^ BitwiseAndExpressionOrSuperdo
Validate[BitwiseXorExpressionOrSuper](cxtenv);
Validate[BitwiseAndExpressionOrSuper](cxtenv)
end proc;
proc Validate[BitwiseOrExpression] (cxtContextenvEnvironment)
[BitwiseOrExpression  BitwiseXorExpressiondo
Validate[BitwiseXorExpression](cxtenv);
[BitwiseOrExpression  BitwiseOrExpressionOrSuper | BitwiseXorExpressionOrSuperdo
Validate[BitwiseOrExpressionOrSuper](cxtenv);
Validate[BitwiseXorExpressionOrSuper](cxtenv)
end proc;
Validate[BitwiseAndExpressionOrSuper]: Context  Environment  ();
Validate[BitwiseAndExpressionOrSuper  BitwiseAndExpression] = Validate[BitwiseAndExpression];
Validate[BitwiseAndExpressionOrSuper  SuperExpression] = Validate[SuperExpression];
Validate[BitwiseXorExpressionOrSuper]: Context  Environment  ();
Validate[BitwiseXorExpressionOrSuper  BitwiseXorExpression] = Validate[BitwiseXorExpression];
Validate[BitwiseXorExpressionOrSuper  SuperExpression] = Validate[SuperExpression];
Validate[BitwiseOrExpressionOrSuper]: Context  Environment  ();
Validate[BitwiseOrExpressionOrSuper  BitwiseOrExpression] = Validate[BitwiseOrExpression];
Validate[BitwiseOrExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[BitwiseAndExpression] (envEnvironmentphasePhase): ObjOrRef
[BitwiseAndExpression  EqualityExpressiondo
return Eval[EqualityExpression](envphase);
[BitwiseAndExpression  BitwiseAndExpressionOrSuper & EqualityExpressionOrSuperdo
raObjOrRefOptionalLimit  Eval[BitwiseAndExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[EqualityExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(bitwiseAndTableabphase)
end proc;
proc Eval[BitwiseXorExpression] (envEnvironmentphasePhase): ObjOrRef
[BitwiseXorExpression  BitwiseAndExpressiondo
return Eval[BitwiseAndExpression](envphase);
[BitwiseXorExpression  BitwiseXorExpressionOrSuper ^ BitwiseAndExpressionOrSuperdo
raObjOrRefOptionalLimit  Eval[BitwiseXorExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[BitwiseAndExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(bitwiseXorTableabphase)
end proc;
proc Eval[BitwiseOrExpression] (envEnvironmentphasePhase): ObjOrRef
[BitwiseOrExpression  BitwiseXorExpressiondo
return Eval[BitwiseXorExpression](envphase);
[BitwiseOrExpression  BitwiseOrExpressionOrSuper | BitwiseXorExpressionOrSuperdo
raObjOrRefOptionalLimit  Eval[BitwiseOrExpressionOrSuper](envphase);
aObjOptionalLimit  readRefWithLimit(raphase);
rbObjOrRefOptionalLimit  Eval[BitwiseXorExpressionOrSuper](envphase);
bObjOptionalLimit  readRefWithLimit(rbphase);
return binaryDispatch(bitwiseOrTableabphase)
end proc;
Eval[BitwiseAndExpressionOrSuper]: Environment  Phase  ObjOrRefOptionalLimit;
Eval[BitwiseAndExpressionOrSuper  BitwiseAndExpression] = Eval[BitwiseAndExpression];
Eval[BitwiseAndExpressionOrSuper  SuperExpression] = Eval[SuperExpression];
Eval[BitwiseXorExpressionOrSuper]: Environment  Phase  ObjOrRefOptionalLimit;
Eval[BitwiseXorExpressionOrSuper  BitwiseXorExpression] = Eval[BitwiseXorExpression];
Eval[BitwiseXorExpressionOrSuper  SuperExpression] = Eval[SuperExpression];
Eval[BitwiseOrExpressionOrSuper]: Environment  Phase  ObjOrRefOptionalLimit;
Eval[BitwiseOrExpressionOrSuper  BitwiseOrExpression] = Eval[BitwiseOrExpression];
Eval[BitwiseOrExpressionOrSuper  SuperExpression] = Eval[SuperExpression];

Binary Logical Operators

Syntax

LogicalAndExpression 
   BitwiseOrExpression
|  LogicalAndExpression && BitwiseOrExpression
LogicalXorExpression 
   LogicalAndExpression
|  LogicalXorExpression ^^ LogicalAndExpression
LogicalOrExpression 
   LogicalXorExpression
|  LogicalOrExpression || LogicalXorExpression

Validation

proc Validate[LogicalAndExpression] (cxtContextenvEnvironment)
[LogicalAndExpression  BitwiseOrExpressiondo
Validate[BitwiseOrExpression](cxtenv);
[LogicalAndExpression0  LogicalAndExpression1 && BitwiseOrExpressiondo
Validate[LogicalAndExpression1](cxtenv);
Validate[BitwiseOrExpression](cxtenv)
end proc;
proc Validate[LogicalXorExpression] (cxtContextenvEnvironment)
[LogicalXorExpression  LogicalAndExpressiondo
Validate[LogicalAndExpression](cxtenv);
[LogicalXorExpression0  LogicalXorExpression1 ^^ LogicalAndExpressiondo
Validate[LogicalXorExpression1](cxtenv);
Validate[LogicalAndExpression](cxtenv)
end proc;
proc Validate[LogicalOrExpression] (cxtContextenvEnvironment)
[LogicalOrExpression  LogicalXorExpressiondo
Validate[LogicalXorExpression](cxtenv);
[LogicalOrExpression0  LogicalOrExpression1 || LogicalXorExpressiondo
Validate[LogicalOrExpression1](cxtenv);
Validate[LogicalXorExpression](cxtenv)
end proc;

Evaluation

proc Eval[LogicalAndExpression] (envEnvironmentphasePhase): ObjOrRef
[LogicalAndExpression  BitwiseOrExpressiondo
return Eval[BitwiseOrExpression](envphase);
[LogicalAndExpression0  LogicalAndExpression1 && BitwiseOrExpressiondo
raObjOrRef  Eval[LogicalAndExpression1](envphase);
aObject  readReference(raphase);
if toBoolean(aphasethen
rbObjOrRef  Eval[BitwiseOrExpression](envphase);
return readReference(rbphase)
else return a
end if
end proc;
proc Eval[LogicalXorExpression] (envEnvironmentphasePhase): ObjOrRef
[LogicalXorExpression  LogicalAndExpressiondo
return Eval[LogicalAndExpression](envphase);
[LogicalXorExpression0  LogicalXorExpression1 ^^ LogicalAndExpressiondo
raObjOrRef  Eval[LogicalXorExpression1](envphase);
aObject  readReference(raphase);
rbObjOrRef  Eval[LogicalAndExpression](envphase);
bObject  readReference(rbphase);
baBoolean  toBoolean(aphase);
bbBoolean  toBoolean(bphase);
return ba xor bb
end proc;
proc Eval[LogicalOrExpression] (envEnvironmentphasePhase): ObjOrRef
[LogicalOrExpression  LogicalXorExpressiondo
return Eval[LogicalXorExpression](envphase);
[LogicalOrExpression0  LogicalOrExpression1 || LogicalXorExpressiondo
raObjOrRef  Eval[LogicalOrExpression1](envphase);
aObject  readReference(raphase);
if toBoolean(aphasethen return a
else
rbObjOrRef  Eval[LogicalXorExpression](envphase);
return readReference(rbphase)
end if
end proc;

Conditional Operator

Syntax

ConditionalExpression 
   LogicalOrExpression
|  LogicalOrExpression ? AssignmentExpression : AssignmentExpression
NonAssignmentExpression 
   LogicalOrExpression
|  LogicalOrExpression ? NonAssignmentExpression : NonAssignmentExpression

Validation

proc Validate[ConditionalExpression] (cxtContextenvEnvironment)
[ConditionalExpression  LogicalOrExpressiondo
Validate[LogicalOrExpression](cxtenv);
[ConditionalExpression  LogicalOrExpression ? AssignmentExpression1 : AssignmentExpression2do
Validate[LogicalOrExpression](cxtenv);
Validate[AssignmentExpression1](cxtenv);
Validate[AssignmentExpression2](cxtenv)
end proc;
proc Validate[NonAssignmentExpression] (cxtContextenvEnvironment)
[NonAssignmentExpression  LogicalOrExpressiondo
Validate[LogicalOrExpression](cxtenv);
[NonAssignmentExpression0  LogicalOrExpression ? NonAssignmentExpression1 : NonAssignmentExpression2do
Validate[LogicalOrExpression](cxtenv);
Validate[NonAssignmentExpression1](cxtenv);
Validate[NonAssignmentExpression2](cxtenv)
end proc;

Evaluation

proc Eval[ConditionalExpression] (envEnvironmentphasePhase): ObjOrRef
[ConditionalExpression  LogicalOrExpressiondo
return Eval[LogicalOrExpression](envphase);
[ConditionalExpression  LogicalOrExpression ? AssignmentExpression1 : AssignmentExpression2do
raObjOrRef  Eval[LogicalOrExpression](envphase);
aObject  readReference(raphase);
if toBoolean(aphasethen
rbObjOrRef  Eval[AssignmentExpression1](envphase);
return readReference(rbphase)
else
rcObjOrRef  Eval[AssignmentExpression2](envphase);
return readReference(rcphase)
end if
end proc;
proc Eval[NonAssignmentExpression] (envEnvironmentphasePhase): ObjOrRef
[NonAssignmentExpression  LogicalOrExpressiondo
return Eval[LogicalOrExpression](envphase);
[NonAssignmentExpression0  LogicalOrExpression ? NonAssignmentExpression1 : NonAssignmentExpression2do
raObjOrRef  Eval[LogicalOrExpression](envphase);
aObject  readReference(raphase);
if toBoolean(aphasethen
rbObjOrRef  Eval[NonAssignmentExpression1](envphase);
return readReference(rbphase)
else
rcObjOrRef  Eval[NonAssignmentExpression2](envphase);
return readReference(rcphase)
end if
end proc;

Assignment Operators

Syntax

AssignmentExpression 
   ConditionalExpression
|  PostfixExpression = AssignmentExpression
|  PostfixExpressionOrSuper CompoundAssignment AssignmentExpression
|  PostfixExpressionOrSuper CompoundAssignment SuperExpression
|  PostfixExpression LogicalAssignment AssignmentExpression
CompoundAssignment 
   *=
|  /=
|  %=
|  +=
|  -=
|  <<=
|  >>=
|  >>>=
|  &=
|  ^=
|  |=
LogicalAssignment 
   &&=
|  ^^=
|  ||=

Semantics

tag andEq;
tag xorEq;
tag orEq;

Validation

proc Validate[AssignmentExpression] (cxtContextenvEnvironment)
[AssignmentExpression  ConditionalExpressiondo
Validate[ConditionalExpression](cxtenv);
[AssignmentExpression0  PostfixExpression = AssignmentExpression1do
Validate[PostfixExpression](cxtenv);
Validate[AssignmentExpression1](cxtenv);
[AssignmentExpression0  PostfixExpressionOrSuper CompoundAssignment AssignmentExpression1do
Validate[PostfixExpressionOrSuper](cxtenv);
Validate[AssignmentExpression1](cxtenv);
[AssignmentExpression  PostfixExpressionOrSuper CompoundAssignment SuperExpressiondo
Validate[PostfixExpressionOrSuper](cxtenv);
Validate[SuperExpression](cxtenv);
[AssignmentExpression0  PostfixExpression LogicalAssignment AssignmentExpression1do
Validate[PostfixExpression](cxtenv);
Validate[AssignmentExpression1](cxtenv)
end proc;

Evaluation

proc Eval[AssignmentExpression] (envEnvironmentphasePhase): ObjOrRef
[AssignmentExpression  ConditionalExpressiondo
return Eval[ConditionalExpression](envphase);
[AssignmentExpression0  PostfixExpression = AssignmentExpression1do
if phase = compile then throw compileExpressionError end if;
raObjOrRef  Eval[PostfixExpression](envphase);
rbObjOrRef  Eval[AssignmentExpression1](envphase);
bObject  readReference(rbphase);
writeReference(rabphase);
return b;
[AssignmentExpression0  PostfixExpressionOrSuper CompoundAssignment AssignmentExpression1do
if phase = compile then throw compileExpressionError end if;
return evalAssignmentOp(Table[CompoundAssignment], Eval[PostfixExpressionOrSuper], Eval[AssignmentExpression1], env, phase);
[AssignmentExpression  PostfixExpressionOrSuper CompoundAssignment SuperExpressiondo
if phase = compile then throw compileExpressionError end if;
[AssignmentExpression0  PostfixExpression LogicalAssignment AssignmentExpression1do
if phase = compile then throw compileExpressionError end if;
rLeftObjOrRef  Eval[PostfixExpression](envphase);
oLeftObject  readReference(rLeftphase);
bLeftBoolean  toBoolean(oLeftphase);
resultObject  oLeft;
case Operator[LogicalAssignmentof
{andEqdo
if bLeft then
result  readReference(Eval[AssignmentExpression1](envphase), phase)
end if;
{xorEqdo
bRightBoolean  toBoolean(readReference(Eval[AssignmentExpression1](envphase), phase), phase);
result  bLeft xor bRight;
{orEqdo
if not bLeft then
result  readReference(Eval[AssignmentExpression1](envphase), phase)
end if
end case;
writeReference(rLeftresultphase);
return result
end proc;
Table[CompoundAssignment]: BinaryMethod{};
Table[CompoundAssignment  *=] = multiplyTable;
Table[CompoundAssignment  /=] = divideTable;
Table[CompoundAssignment  %=] = remainderTable;
Table[CompoundAssignment  +=] = addTable;
Table[CompoundAssignment  -=] = subtractTable;
Table[CompoundAssignment  <<=] = shiftLeftTable;
Table[CompoundAssignment  >>=] = shiftRightTable;
Table[CompoundAssignment  >>>=] = shiftRightUnsignedTable;
Table[CompoundAssignment  &=] = bitwiseAndTable;
Table[CompoundAssignment  ^=] = bitwiseXorTable;
Table[CompoundAssignment  |=] = bitwiseOrTable;
Operator[LogicalAssignment]: {andEqxorEqorEq};
Operator[LogicalAssignment  &&=] = andEq;
Operator[LogicalAssignment  ^^=] = xorEq;
Operator[LogicalAssignment  ||=] = orEq;
proc evalAssignmentOp(tableBinaryMethod{}, leftEvalEnvironment  Phase  ObjOrRefOptionalLimit, rightEvalEnvironment  Phase  ObjOrRefOptionalLimit, envEnvironment, phase: {run}): ObjOrRef
rLeftObjOrRefOptionalLimit  leftEval(envphase);
oLeftObjOptionalLimit  readRefWithLimit(rLeftphase);
rRightObjOrRefOptionalLimit  rightEval(envphase);
oRightObjOptionalLimit  readRefWithLimit(rRightphase);
resultObject  binaryDispatch(tableoLeftoRightphase);
writeReference(rLeftresultphase);
return result
end proc;

Comma Expressions

Syntax

ListExpression 
   AssignmentExpression
|  ListExpression , AssignmentExpression
OptionalExpression 
   ListExpressionallowIn
|  «empty»

Validation

proc Validate[ListExpression] (cxtContextenvEnvironment)
[ListExpression  AssignmentExpressiondo
Validate[AssignmentExpression](cxtenv);
[ListExpression0  ListExpression1 , AssignmentExpressiondo
Validate[ListExpression1](cxtenv);
Validate[AssignmentExpression](cxtenv)
end proc;

Evaluation

proc Eval[ListExpression] (envEnvironmentphasePhase): ObjOrRef
[ListExpression  AssignmentExpressiondo
return Eval[AssignmentExpression](envphase);
[ListExpression0  ListExpression1 , AssignmentExpressiondo
raObjOrRef  Eval[ListExpression1](envphase);
readReference(raphase);
rbObjOrRef  Eval[AssignmentExpression](envphase);
return readReference(rbphase)
end proc;
proc EvalAsList[ListExpression] (envEnvironmentphasePhase): Object[]
[ListExpression  AssignmentExpressiondo
rObjOrRef  Eval[AssignmentExpression](envphase);
eltObject  readReference(rphase);
return [elt];
[ListExpression0  ListExpression1 , AssignmentExpressiondo
eltsObject[]  EvalAsList[ListExpression1](envphase);
rObjOrRef  Eval[AssignmentExpression](envphase);
eltObject  readReference(rphase);
return elts  [elt]
end proc;

Type Expressions

Syntax

TypeExpression  NonAssignmentExpression

Validation

proc Validate[TypeExpression  NonAssignmentExpression] (cxtContextenvEnvironment)
Validate[NonAssignmentExpression](cxtenv)
end proc;

Evaluation

proc Eval[TypeExpression  NonAssignmentExpression] (envEnvironment): Class
rObjOrRef  Eval[NonAssignmentExpression](envcompile);
oObject  readReference(rcompile);
if o  Class then throw badValueError end if;
return o
end proc;

Statements

Syntax

  {abbrevnoShortIffull}
Statement 
   ExpressionStatement Semicolon
|  SuperStatement Semicolon
|  Block
|  LabeledStatement
|  IfStatement
|  SwitchStatement
|  DoStatement Semicolon
|  WhileStatement
|  ForStatement
|  WithStatement
|  ContinueStatement Semicolon
|  BreakStatement Semicolon
|  ReturnStatement Semicolon
|  ThrowStatement Semicolon
|  TryStatement
Substatement 
   EmptyStatement
|  Statement
|  SimpleVariableDefinition Semicolon
|  Attributes [no line break] { Substatements }
Substatements 
   «empty»
|  SubstatementsPrefix Substatementabbrev
SubstatementsPrefix 
   «empty»
|  SubstatementsPrefix Substatementfull
Semicolonabbrev 
   ;
|  VirtualSemicolon
|  «empty»
SemicolonnoShortIf 
   ;
|  VirtualSemicolon
|  «empty»
Semicolonfull 
   ;
|  VirtualSemicolon

Validation

proc Validate[Statement] (cxtContextenvEnvironmentslLabel{}, jtJumpTargetsplPlurality)
[Statement  ExpressionStatement Semicolondo
Validate[ExpressionStatement](cxtenv);
[Statement  SuperStatement Semicolondo Validate[SuperStatement](cxtenv);
[Statement  Blockdo Validate[Block](cxtenvjtpl);
[Statement  LabeledStatementdo Validate[LabeledStatement](cxtenvsljt);
[Statement  IfStatementdo Validate[IfStatement](cxtenvjt);
[Statement  SwitchStatementdo ????;
[Statement  DoStatement Semicolondo Validate[DoStatement](cxtenvsljt);
[Statement  WhileStatementdo Validate[WhileStatement](cxtenvsljt);
[Statement  ForStatementdo ????;
[Statement  WithStatementdo ????;
[Statement  ContinueStatement Semicolondo Validate[ContinueStatement](jt);
[Statement  BreakStatement Semicolondo Validate[BreakStatement](jt);
[Statement  ReturnStatement Semicolondo Validate[ReturnStatement](cxtenv);
[Statement  ThrowStatement Semicolondo Validate[ThrowStatement](cxtenv);
[Statement  TryStatementdo ????
end proc;
Enabled[Substatement]: Boolean;
proc Validate[Substatement] (cxtContextenvEnvironmentslLabel{}, jtJumpTargets)
[Substatement  EmptyStatementdo nothing;
[Substatement  Statementdo Validate[Statement](cxtenvsljtplural);
[Substatement  SimpleVariableDefinition Semicolondo
Validate[SimpleVariableDefinition](cxtenv);
[Substatement  Attributes [no line break] { Substatements }do
Validate[Attributes](cxtenv);
attrAttribute  Eval[Attributes](envcompile);
if attr  Boolean then throw badValueError end if;
Enabled[Substatement attr;
if attr then Validate[Substatements](cxtenvjtend if
end proc;
proc Validate[Substatements] (cxtContextenvEnvironmentjtJumpTargets)
[Substatements  «empty»] do nothing;
[Substatements  SubstatementsPrefix Substatementabbrevdo
Validate[SubstatementsPrefix](cxtenvjt);
Validate[Substatementabbrev](cxtenv, {}, jt)
end proc;
proc Validate[SubstatementsPrefix] (cxtContextenvEnvironmentjtJumpTargets)
[SubstatementsPrefix  «empty»] do nothing;
[SubstatementsPrefix0  SubstatementsPrefix1 Substatementfulldo
Validate[SubstatementsPrefix1](cxtenvjt);
Validate[Substatementfull](cxtenv, {}, jt)
end proc;

Evaluation

proc Eval[Statement] (envEnvironmentdObject): Object
[Statement  ExpressionStatement Semicolondo
return Eval[ExpressionStatement](env);
[Statement  SuperStatement Semicolondo return Eval[SuperStatement](env);
[Statement  Blockdo return Eval[Block](envd);
[Statement  LabeledStatementdo return Eval[LabeledStatement](envd);
[Statement  IfStatementdo return Eval[IfStatement](envd);
[Statement  SwitchStatementdo ????;
[Statement  DoStatement Semicolondo return Eval[DoStatement](envd);
[Statement  WhileStatementdo return Eval[WhileStatement](envd);
[Statement  ForStatementdo ????;
[Statement  WithStatementdo ????;
[Statement  ContinueStatement Semicolondo
return Eval[ContinueStatement](envd);
[Statement  BreakStatement Semicolondo return Eval[BreakStatement](envd);
[Statement  ReturnStatement Semicolondo return Eval[ReturnStatement](env);
[Statement  ThrowStatement Semicolondo return Eval[ThrowStatement](env);
[Statement  TryStatementdo ????
end proc;
proc Eval[Substatement] (envEnvironmentdObject): Object
[Substatement  EmptyStatementdo return d;
[Substatement  Statementdo return Eval[Statement](envd);
[Substatement  SimpleVariableDefinition Semicolondo
return Eval[SimpleVariableDefinition](envd);
[Substatement  Attributes [no line break] { Substatements }do
if Enabled[Substatementthen return Eval[Substatements](envd)
else return d
end if
end proc;
proc Eval[Substatements] (envEnvironmentdObject): Object
[Substatements  «empty»] do return d;
[Substatements  SubstatementsPrefix Substatementabbrevdo
oObject  Eval[SubstatementsPrefix](envd);
return Eval[Substatementabbrev](envo)
end proc;
proc Eval[SubstatementsPrefix] (envEnvironmentdObject): Object
[SubstatementsPrefix  «empty»] do return d;
[SubstatementsPrefix0  SubstatementsPrefix1 Substatementfulldo
oObject  Eval[SubstatementsPrefix1](envd);
return Eval[Substatementfull](envo)
end proc;

Empty Statement

Syntax

EmptyStatement  ;

Expression Statement

Syntax

ExpressionStatement  [lookahead{function{}] ListExpressionallowIn

Validation

proc Validate[ExpressionStatement  [lookahead{function{}] ListExpressionallowIn] (cxtContextenvEnvironment)
Validate[ListExpressionallowIn](cxtenv)
end proc;

Evaluation

proc Eval[ExpressionStatement  [lookahead{function{}] ListExpressionallowIn] (envEnvironment): Object
rObjOrRef  Eval[ListExpressionallowIn](envrun);
return readReference(rrun)
end proc;

Super Statement

Syntax

SuperStatement  super Arguments

Validation

proc Validate[SuperStatement  super Arguments] (cxtContextenvEnvironment)
????
end proc;

Evaluation

proc Eval[SuperStatement  super Arguments] (envEnvironment): Object
????
end proc;

Block Statement

Syntax

Block  { Directives }

Validation

proc Validate[Block  { Directives }] (cxtContextenvEnvironmentjtJumpTargetsplPlurality)
compileFrameBlockFrame  new BlockFramestaticReadBindings: {}, staticWriteBindings: {}, pluralitypl;
CompileFrame[Block compileFrame;
Validate[Directives](cxt[compileFrame]  envjtplnone)
end proc;
proc ValidateUsingFrame[Block  { Directives }] (cxtContextenvEnvironmentjtJumpTargetsplPluralityframeFrame)
Validate[Directives](cxt[frame]  envjtplnone)
end proc;

Evaluation

proc Eval[Block  { Directives }] (envEnvironmentdObject): Object
compileFrameBlockFrame  CompileFrame[Block];
runtimeFrameBlockFrame  instantiateBlockFrame(compileFrame);
return Eval[Directives]([runtimeFrame]  envd)
end proc;
proc EvalUsingFrame[Block  { Directives }] (envEnvironmentframeFramedObject): Object
return Eval[Directives]([frame]  envd)
end proc;
CompileFrame[Block]: BlockFrame;

Labeled Statements

Syntax

LabeledStatement  Identifier : Substatement

Validation

proc Validate[LabeledStatement  Identifier : Substatement] (cxtContextenvEnvironmentslLabel{}, jtJumpTargets)
nameString  Name[Identifier];
if name  jt.breakTargets then throw syntaxError end if;
jt2JumpTargets  JumpTargetsbreakTargetsjt.breakTargets  {name}, continueTargetsjt.continueTargets;
Validate[Substatement](cxtenvsl  {name}, jt2)
end proc;

Evaluation

proc Eval[LabeledStatement  Identifier : Substatement] (envEnvironmentdObject): Object
try return Eval[Substatement](envd)
catch xSemanticException do
if x  Break and x.label = Name[Identifierthen return x.value
else throw x
end if
end try
end proc;

If Statement

Syntax

IfStatementabbrev 
   if ParenListExpression Substatementabbrev
|  if ParenListExpression SubstatementnoShortIf else Substatementabbrev
IfStatementfull 
   if ParenListExpression Substatementfull
|  if ParenListExpression SubstatementnoShortIf else Substatementfull
IfStatementnoShortIf  if ParenListExpression SubstatementnoShortIf else SubstatementnoShortIf

Validation

proc Validate[IfStatement] (cxtContextenvEnvironmentjtJumpTargets)
[IfStatementabbrev  if ParenListExpression Substatementabbrevdo
Validate[ParenListExpression](cxtenv);
Validate[Substatementabbrev](cxtenv, {}, jt);
[IfStatementfull  if ParenListExpression Substatementfulldo
Validate[ParenListExpression](cxtenv);
Validate[Substatementfull](cxtenv, {}, jt);
[IfStatement  if ParenListExpression SubstatementnoShortIf1 else Substatement2do
Validate[ParenListExpression](cxtenv);
Validate[SubstatementnoShortIf1](cxtenv, {}, jt);
Validate[Substatement2](cxtenv, {}, jt)
end proc;

Evaluation

proc Eval[IfStatement] (envEnvironmentdObject): Object
[IfStatementabbrev  if ParenListExpression Substatementabbrevdo
rObjOrRef  Eval[ParenListExpression](envrun);
oObject  readReference(rrun);
if toBoolean(orunthen return Eval[Substatementabbrev](envd)
else return d
end if;
[IfStatementfull  if ParenListExpression Substatementfulldo
rObjOrRef  Eval[ParenListExpression](envrun);
oObject  readReference(rrun);
if toBoolean(orunthen return Eval[Substatementfull](envd)
else return d
end if;
[IfStatement  if ParenListExpression SubstatementnoShortIf1 else Substatement2do
rObjOrRef  Eval[ParenListExpression](envrun);
oObject  readReference(rrun);
if toBoolean(orunthen return Eval[SubstatementnoShortIf1](envd)
else return Eval[Substatement2](envd)
end if
end proc;

Switch Statement

Syntax

SwitchStatement  switch ParenListExpression { CaseStatements }
CaseStatements 
   «empty»
|  CaseLabel
|  CaseLabel CaseStatementsPrefix CaseStatementabbrev
CaseStatementsPrefix 
   «empty»
|  CaseStatementsPrefix CaseStatementfull
CaseStatement 
   Substatement
|  CaseLabel
CaseLabel 
   case ListExpressionallowIn :
|  default :

Do-While Statement

Syntax

DoStatement  do Substatementabbrev while ParenListExpression

Validation

Labels[DoStatement]: Label{};
proc Validate[DoStatement  do Substatementabbrev while ParenListExpression] (cxtContextenvEnvironmentslLabel{}, jtJumpTargets)
continueLabelsLabel{}  sl  {default};
Labels[DoStatement continueLabels;
jt2JumpTargets  JumpTargetsbreakTargetsjt.breakTargets  {default}, continueTargetsjt.continueTargets  continueLabels;
Validate[Substatementabbrev](cxtenv, {}, jt2);
Validate[ParenListExpression](cxtenv)
end proc;

Evaluation

proc Eval[DoStatement  do Substatementabbrev while ParenListExpression] (envEnvironmentdObject): Object
try
d1Object  d;
while true do
try d1  Eval[Substatementabbrev](envd1)
catch xSemanticException do
if x  Continue and x.label  Labels[DoStatementthen d1  x.value
else throw x
end if
end try;
rObjOrRef  Eval[ParenListExpression](envrun);
oObject  readReference(rrun);
if not toBoolean(orunthen return d1 end if
end while
catch xSemanticException do
if x  Break and x.label = default then return x.value else throw x end if
end try
end proc;

While Statement

Syntax

WhileStatement  while ParenListExpression Substatement

Validation

Labels[WhileStatement]: Label{};
proc Validate[WhileStatement  while ParenListExpression Substatement] (cxtContextenvEnvironmentslLabel{}, jtJumpTargets)
Validate[ParenListExpression](cxtenv);
continueLabelsLabel{}  sl  {default};
Labels[WhileStatement continueLabels;
jt2JumpTargets  JumpTargetsbreakTargetsjt.breakTargets  {default}, continueTargetsjt.continueTargets  continueLabels;
Validate[Substatement](cxtenv, {}, jt2)
end proc;

Evaluation

proc Eval[WhileStatement  while ParenListExpression Substatement] (envEnvironmentdObject): Object
try
d1Object  d;
while toBoolean(readReference(Eval[ParenListExpression](envrun), run), rundo
try d1  Eval[Substatement](envd1)
catch xSemanticException do
if x  Continue and x.label  Labels[WhileStatementthen d1  x.value
else throw x
end if
end try
end while;
return d1
catch xSemanticException do
if x  Break and x.label = default then return x.value else throw x end if
end try
end proc;

For Statements

Syntax

ForStatement 
   for ( ForInitialiser ; OptionalExpression ; OptionalExpression ) Substatement
|  for ( ForInBinding in ListExpressionallowIn ) Substatement
ForInitialiser 
   «empty»
|  ListExpressionnoIn
|  VariableDefinitionKind VariableBindingListnoIn
|  Attributes [no line break] VariableDefinitionKind VariableBindingListnoIn
ForInBinding 
   PostfixExpression
|  VariableDefinitionKind VariableBindingnoIn
|  Attributes [no line break] VariableDefinitionKind VariableBindingnoIn

With Statement

Syntax

WithStatement  with ParenListExpression Substatement

Continue and Break Statements

Syntax

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

Validation

proc Validate[ContinueStatement] (jtJumpTargets)
[ContinueStatement  continuedo
if default  jt.continueTargets then throw syntaxError end if;
[ContinueStatement  continue [no line break] Identifierdo
if Name[Identifier jt.continueTargets then throw syntaxError end if
end proc;
proc Validate[BreakStatement] (jtJumpTargets)
[BreakStatement  breakdo
if default  jt.breakTargets then throw syntaxError end if;
[BreakStatement  break [no line break] Identifierdo
if Name[Identifier jt.breakTargets then throw syntaxError end if
end proc;

Evaluation

proc Eval[ContinueStatement] (envEnvironmentdObject): Object
[ContinueStatement  continuedo throw Continuevaluedlabeldefault;
[ContinueStatement  continue [no line break] Identifierdo
throw ContinuevaluedlabelName[Identifier]
end proc;
proc Eval[BreakStatement] (envEnvironmentdObject): Object
[BreakStatement  breakdo throw Breakvaluedlabeldefault;
[BreakStatement  break [no line break] Identifierdo
throw BreakvaluedlabelName[Identifier]
end proc;

Return Statement

Syntax

ReturnStatement 
   return
|  return [no line break] ListExpressionallowIn

Validation

proc Validate[ReturnStatement] (cxtContextenvEnvironment)
[ReturnStatement  returndo
if getRegionalFrame(env FunctionFrame then throw syntaxError end if;
[ReturnStatement  return [no line break] ListExpressionallowIndo
if getRegionalFrame(env FunctionFrame then throw syntaxError end if;
Validate[ListExpressionallowIn](cxtenv)
end proc;

Evaluation

proc Eval[ReturnStatement] (envEnvironment): Object
[ReturnStatement  returndo throw ReturnedValuevalueundefined;
[ReturnStatement  return [no line break] ListExpressionallowIndo
rObjOrRef  Eval[ListExpressionallowIn](envrun);
aObject  readReference(rrun);
throw ReturnedValuevaluea
end proc;

Throw Statement

Syntax

ThrowStatement  throw [no line break] ListExpressionallowIn

Validation

Validate[ThrowStatement  throw [no line break] ListExpressionallowIn]: Context  Environment  () = Validate[ListExpressionallowIn];

Evaluation

proc Eval[ThrowStatement  throw [no line break] ListExpressionallowIn] (envEnvironment): Object
rObjOrRef  Eval[ListExpressionallowIn](envrun);
aObject  readReference(rrun);
throw ThrownValuevaluea
end proc;

Try Statement

Syntax

TryStatement 
   try Block CatchClauses
|  try Block FinallyClause
|  try Block CatchClauses FinallyClause
CatchClauses 
   CatchClause
|  CatchClauses CatchClause
CatchClause  catch ( Parameter ) Block
FinallyClause  finally Block

Directives

Syntax

Directive 
   EmptyStatement
|  Statement
|  AnnotatableDirective
|  Attributes [no line break] AnnotatableDirective
|  Attributes [no line break] { Directives }
|  PackageDefinition
|  IncludeDirective Semicolon
|  Pragma Semicolon
AnnotatableDirective 
   ExportDefinition Semicolon
|  VariableDefinition Semicolon
|  FunctionDefinition
|  ClassDefinition
|  NamespaceDefinition Semicolon
|  InterfaceDefinition
|  ImportDirective Semicolon
|  UseDirective Semicolon
Directives 
   «empty»
|  DirectivesPrefix Directiveabbrev
DirectivesPrefix 
   «empty»
|  DirectivesPrefix Directivefull

Validation

proc Validate[Directive] (cxtContext, envEnvironment, jtJumpTargets, plPlurality, attrAttributeOptNotFalse): Context
[Directive  EmptyStatementdo return cxt;
[Directive  Statementdo
if attr  {nonetruethen throw syntaxError end if;
Validate[Statement](cxtenv, {}, jtpl);
return cxt;
[Directive  AnnotatableDirectivedo
return Validate[AnnotatableDirective](cxtenvplattr);
[Directive  Attributes [no line break] AnnotatableDirectivedo
Validate[Attributes](cxtenv);
attr2Attribute  Eval[Attributes](envcompile);
attr3Attribute  combineAttributes(attrattr2);
Enabled[Directive attr3  false;
if attr3  false then return Validate[AnnotatableDirective](cxtenvplattr3)
else return cxt
end if;
[Directive  Attributes [no line break] { Directives }do
Validate[Attributes](cxtenv);
attr2Attribute  Eval[Attributes](envcompile);
attr3Attribute  combineAttributes(attrattr2);
Enabled[Directive attr3  false;
if attr3 = false then return cxt end if;
return Validate[Directives](cxtenvjtplattr3);
[Directive  PackageDefinitiondo
if attr  {nonetruethen ???? else throw syntaxError end if;
[Directive  IncludeDirective Semicolondo
if attr  {nonetruethen ???? else throw syntaxError end if;
[Directive  Pragma Semicolondo
if attr  {nonetruethen return Validate[Pragma](cxt)
else throw syntaxError
end if
end proc;
proc Validate[AnnotatableDirective] (cxtContextenvEnvironmentplPluralityattrAttributeOptNotFalse): Context
[AnnotatableDirective  ExportDefinition Semicolondo ????;
[AnnotatableDirective  VariableDefinition Semicolondo
Validate[VariableDefinition](cxtenvattr);
return cxt;
[AnnotatableDirective  FunctionDefinitiondo ????;
[AnnotatableDirective  ClassDefinitiondo
Validate[ClassDefinition](cxtenvplattr);
return cxt;
[AnnotatableDirective  NamespaceDefinition Semicolondo ????;
[AnnotatableDirective  InterfaceDefinitiondo ????;
[AnnotatableDirective  ImportDirective Semicolondo ????;
[AnnotatableDirective  UseDirective Semicolondo
if attr  {nonetruethen return Validate[UseDirective](cxtenv)
else throw syntaxError
end if
end proc;
proc Validate[Directives] (cxtContext, envEnvironment, jtJumpTargets, plPlurality, attrAttributeOptNotFalse): Context
[Directives  «empty»] do return cxt;
[Directives  DirectivesPrefix Directiveabbrevdo
cxt2Context  Validate[DirectivesPrefix](cxtenvjtplattr);
return Validate[Directiveabbrev](cxt2envjtplattr)
end proc;
proc Validate[DirectivesPrefix] (cxtContext, envEnvironment, jtJumpTargets, plPlurality, attrAttributeOptNotFalse): Context
[DirectivesPrefix  «empty»] do return cxt;
[DirectivesPrefix0  DirectivesPrefix1 Directivefulldo
cxt2Context  Validate[DirectivesPrefix1](cxtenvjtplattr);
return Validate[Directivefull](cxt2envjtplattr)
end proc;

Evaluation

proc Eval[Directive] (envEnvironmentdObject): Object
[Directive  EmptyStatementdo return d;
[Directive  Statementdo return Eval[Statement](envd);
[Directive  AnnotatableDirectivedo return Eval[AnnotatableDirective](envd);
[Directive  Attributes [no line break] AnnotatableDirectivedo
if Enabled[Directivethen return Eval[AnnotatableDirective](envd)
else return d
end if;
[Directive  Attributes [no line break] { Directives }do
if Enabled[Directivethen return Eval[Directives](envdelse return d end if;
[Directive  PackageDefinitiondo ????;
[Directive  IncludeDirective Semicolondo ????;
[Directive  Pragma Semicolondo return d
end proc;
proc Eval[AnnotatableDirective] (envEnvironmentdObject): Object
[AnnotatableDirective  ExportDefinition Semicolondo ????;
[AnnotatableDirective  VariableDefinition Semicolondo
return Eval[VariableDefinition](envd);
[AnnotatableDirective  FunctionDefinitiondo ????;
[AnnotatableDirective  ClassDefinitiondo return Eval[ClassDefinition](envd);
[AnnotatableDirective  NamespaceDefinition Semicolondo ????;
[AnnotatableDirective  InterfaceDefinitiondo ????;
[AnnotatableDirective  ImportDirective Semicolondo ????;
[AnnotatableDirective  UseDirective Semicolondo return d
end proc;
proc Eval[Directives] (envEnvironmentdObject): Object
[Directives  «empty»] do return d;
[Directives  DirectivesPrefix Directiveabbrevdo
oObject  Eval[DirectivesPrefix](envd);
return Eval[Directiveabbrev](envo)
end proc;
proc Eval[DirectivesPrefix] (envEnvironmentdObject): Object
[DirectivesPrefix  «empty»] do return d;
[DirectivesPrefix0  DirectivesPrefix1 Directivefulldo
oObject  Eval[DirectivesPrefix1](envd);
return Eval[Directivefull](envo)
end proc;
Enabled[Directive]: Boolean;

Attributes

Syntax

Attributes 
   Attribute
|  AttributeCombination
AttributeCombination  Attribute [no line break] Attributes
Attribute 
   AttributeExpression
|  true
|  false
|  public
|  NonexpressionAttribute
NonexpressionAttribute 
   abstract
|  final
|  private
|  static

Validation

proc Validate[Attributes] (cxtContextenvEnvironment)
[Attributes  Attributedo Validate[Attribute](cxtenv);
[Attributes  AttributeCombinationdo Validate[AttributeCombination](cxtenv)
end proc;
proc Validate[AttributeCombination  Attribute [no line break] Attributes] (cxtContextenvEnvironment)
Validate[Attribute](cxtenv);
Validate[Attributes](cxtenv)
end proc;
proc Validate[Attribute] (cxtContextenvEnvironment)
[Attribute  AttributeExpressiondo Validate[AttributeExpression](cxtenv);
[Attribute  truedo nothing;
[Attribute  falsedo nothing;
[Attribute  publicdo nothing;
[Attribute  NonexpressionAttributedo Validate[NonexpressionAttribute](env)
end proc;
proc Validate[NonexpressionAttribute] (envEnvironment)
[NonexpressionAttribute  abstractdo nothing;
[NonexpressionAttribute  finaldo nothing;
[NonexpressionAttribute  privatedo
if getEnclosingClass(env) = none then throw syntaxError end if;
[NonexpressionAttribute  staticdo nothing
end proc;

Evaluation

proc Eval[Attributes] (envEnvironmentphasePhase): Attribute
[Attributes  Attributedo return Eval[Attribute](envphase);
[Attributes  AttributeCombinationdo return Eval[AttributeCombination](envphase)
end proc;
proc Eval[AttributeCombination  Attribute [no line break] Attributes] (envEnvironmentphasePhase): Attribute
aAttribute  Eval[Attribute](envphase);
if a = false then return false end if;
bAttribute  Eval[Attributes](envphase);
return combineAttributes(ab)
end proc;
proc Eval[Attribute] (envEnvironmentphasePhase): Attribute
[Attribute  AttributeExpressiondo
rObjOrRef  Eval[AttributeExpression](envphase);
aObject  readReference(rphase);
if a  Attribute then throw badValueError end if;
return a;
[Attribute  truedo return true;
[Attribute  falsedo return false;
[Attribute  publicdo return publicNamespace;
[Attribute  NonexpressionAttributedo
return Eval[NonexpressionAttribute](envphase)
end proc;
proc Eval[NonexpressionAttribute] (envEnvironmentphasePhase): Attribute
[NonexpressionAttribute  abstractdo
return CompoundAttributenamespaces: {}, explicitfalse, dynamicfalse, compilefalse, memberModabstract, overrideModnone, prototypefalse, unusedfalse;
[NonexpressionAttribute  finaldo
return CompoundAttributenamespaces: {}, explicitfalse, dynamicfalse, compilefalse, memberModfinal, overrideModnone, prototypefalse, unusedfalse;
[NonexpressionAttribute  privatedo
cClassOpt  getEnclosingClass(env);
Note that Validate ensured that c cannot be none at this point.
return c.privateNamespace;
[NonexpressionAttribute  staticdo
return CompoundAttributenamespaces: {}, explicitfalse, dynamicfalse, compilefalse, memberModstatic, overrideModnone, prototypefalse, unusedfalse
end proc;

Use Directive

Syntax

UseDirective  use namespace ParenListExpression

Validation

proc Validate[UseDirective  use namespace ParenListExpression] (cxtContextenvEnvironment): Context
Validate[ParenListExpression](cxtenv);
valuesObject[]  EvalAsList[ParenListExpression](envcompile);
namespacesNamespace{}  {};
for each v  values do
if v  Namespace or v  namespaces then throw badValueError end if;
namespaces  namespaces  {v}
end for each;
return ContextopenNamespacescxt.openNamespaces  namespaces, other fields from cxt
end proc;

Import Directive

Syntax

ImportDirective 
   import ImportBinding IncludesExcludes
|  import ImportBinding , namespace ParenListExpression IncludesExcludes
ImportBinding 
   ImportSource
|  Identifier = ImportSource
ImportSource 
   String
|  PackageName
IncludesExcludes 
   «empty»
|  , exclude ( NamePatterns )
|  , include ( NamePatterns )
NamePatterns 
   «empty»
|  NamePatternList
NamePatternList 
   QualifiedIdentifier
|  NamePatternList , QualifiedIdentifier

Include Directive

Syntax

IncludeDirective  include [no line break] String

Pragma

Syntax

Pragma  use PragmaItems
PragmaItems 
   PragmaItem
|  PragmaItems , PragmaItem
PragmaItem 
   PragmaExpr
|  PragmaExpr ?
PragmaExpr 
   Identifier
|  Identifier ( PragmaArgument )
PragmaArgument 
   true
|  false
|  Number
|  - Number
|  String

Validation

proc Validate[Pragma  use PragmaItems] (cxtContext): Context
return Validate[PragmaItems](cxt)
end proc;
proc Validate[PragmaItems] (cxtContext): Context
[PragmaItems  PragmaItemdo return Validate[PragmaItem](cxt);
[PragmaItems0  PragmaItems1 , PragmaItemdo
cxt2Context  Validate[PragmaItems1](cxt);
return Validate[PragmaItem](cxt2)
end proc;
proc Validate[PragmaItem] (cxtContext): Context
[PragmaItem  PragmaExprdo return Validate[PragmaExpr](cxtfalse);
[PragmaItem  PragmaExpr ?do return Validate[PragmaExpr](cxttrue)
end proc;
proc Validate[PragmaExpr] (cxtContextoptionalBoolean): Context
[PragmaExpr  Identifierdo
return processPragma(cxtName[Identifier], undefinedoptional);
[PragmaExpr  Identifier ( PragmaArgument )do
argObject  Value[PragmaArgument];
return processPragma(cxtName[Identifier], argoptional)
end proc;
Value[PragmaArgument]: Object;
Value[PragmaArgument  true] = true;
Value[PragmaArgument  false] = false;
Value[PragmaArgument  Number] = Value[Number];
Value[PragmaArgument  - Number] = float64Negate(Value[Number]);
Value[PragmaArgument  String] = Value[String];
proc processPragma(cxtContextnameStringvalueObjectoptionalBoolean): Context
if name = “strict” then
if value  {trueundefinedthen
return Contextstricttrue, other fields from cxt
end if;
if value = false then return Contextstrictfalse, 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;
if optional then return cxt else throw badValueError end if
end proc;

Definitions

Export Definition

Syntax

ExportDefinition  export ExportBindingList
ExportBindingList 
   ExportBinding
|  ExportBindingList , ExportBinding
ExportBinding 
   FunctionName
|  FunctionName = FunctionName

Variable Definition

Syntax

VariableDefinition  VariableDefinitionKind VariableBindingListallowIn
VariableDefinitionKind 
   var
|  const
VariableBindingList 
   VariableBinding
|  VariableBindingList , VariableBinding

Semantics

tag hoisted;
tag staticCompiled;
tag staticRun;
tag instanceRun;

Syntax

VariableBinding  TypedIdentifier VariableInitialisation
VariableInitialisation 
   «empty»
|  = VariableInitialiser
VariableInitialiser 
   AssignmentExpression
|  NonexpressionAttribute
|  AttributeCombination
TypedIdentifier 
   Identifier
|  Identifier : TypeExpression

Validation

proc Validate[VariableDefinition  VariableDefinitionKind VariableBindingListallowIn] (cxtContextenvEnvironmentattrAttributeOptNotFalse)
immutableBoolean  Immutable[VariableDefinitionKind];
Validate[VariableBindingListallowIn](cxtenvattrimmutable)
end proc;
Immutable[VariableDefinitionKind]: Boolean;
Immutable[VariableDefinitionKind  var] = false;
Immutable[VariableDefinitionKind  const] = true;
proc Validate[VariableBindingList] (cxtContextenvEnvironmentattrAttributeOptNotFalseimmutableBoolean)
[VariableBindingList  VariableBindingdo
Validate[VariableBinding](cxtenvattrimmutable);
[VariableBindingList0  VariableBindingList1 , VariableBindingdo
Validate[VariableBindingList1](cxtenvattrimmutable);
Validate[VariableBinding](cxtenvattrimmutable)
end proc;
Kind[VariableBinding]: {hoistedstaticCompiledstaticRuninstanceRun};
Multiname[VariableBinding]: Multiname;
proc Validate[VariableBinding  TypedIdentifier VariableInitialisation] (cxtContextenvEnvironmentattrAttributeOptNotFalseimmutableBoolean)
Validate[TypedIdentifier](cxtenv);
Validate[VariableInitialisation](cxtenv);
nameString  Name[TypedIdentifier];
if not cxt.strict and getRegionalFrame(env Global  FunctionFrame and not immutable and attr = none and not TypePresent[TypedIdentifierthen
Kind[VariableBinding hoisted;
qnameQualifiedName  QualifiedNamenamespacepublicNamespaceidname;
Multiname[VariableBinding {qname};
defineHoistedVar(envname)
else
aCompoundAttribute  toCompoundAttribute(attr);
memberModMemberModifier  a.memberMod;
namespacesNamespace{}  a.namespaces;
localFrameFrame  env[0];
if a.dynamic or a.prototype or (a.explicit and localFrame  Packageor (a.compile and not immutablethen
end if;
if localFrame  Class then
if memberMod = none then memberMod  a.compile ? static : final end if
else if memberMod  none then throw definitionError end if
end if;
case memberMod of
{nonestaticdo
if a.overrideMod  none then throw definitionError end if;
if namespaces = {} then namespaces  {publicNamespaceend if;
multinameMultiname  {QualifiedNamenamespacensidname | ns  namespaces};
Multiname[VariableBinding multiname;
regionalEnvFrame[]  getRegionalEnvironment(env);
regionalFrameFrame  regionalEnv[|regionalEnv| – 1];
if some b  localFrame.staticReadBindings  localFrame.staticWriteBindings satisfies b.qname  multiname then
end if;
for each frame  regionalEnv[1 ...] do
if some b  frame.staticReadBindings  frame.staticWriteBindings satisfies b.qname  multiname and b.content  forbidden then
end if
end for each;
if regionalFrame  Global and (some dp  regionalFrame.dynamicProperties satisfies QualifiedNamenamespacepublicNamespaceiddp.name  multinamethen
end if;
vVariable  new Variablevaluefutureimmutableimmutable;
newBindingsStaticBinding{}  {StaticBindingqnameqnamecontentvexplicita.explicit | qname  multiname};
localFrame.staticReadBindings  localFrame.staticReadBindings  newBindings;
localFrame.staticWriteBindings  localFrame.staticWriteBindings  newBindings;
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.
newForbiddenBindingsStaticBinding{}  {StaticBindingqnameqnamecontentforbiddenexplicittrue | qname  multiname};
for each frame  regionalEnv[1 ...] do
frame.staticReadBindings  frame.staticReadBindings  newForbiddenBindings;
frame.staticWriteBindings  frame.staticWriteBindings  newForbiddenBindings
end for each;
proc deferredStaticValidate()
tClassOpt  Eval[TypedIdentifier](env);
if t = none then t  objectClass end if;
v.type  t
end proc;
if a.compile then
deferredStaticValidate();
valueObjectOpt  Eval[VariableInitialisation](envcompile);
if value = none then throw definitionError end if;
coercedValueObject  assignmentConversion(valuev.type);
v.value  coercedValue;
Kind[VariableBinding staticCompiled
else
deferredValidators  deferredValidators  [deferredStaticValidate];
Kind[VariableBinding staticRun
end if;
At this point localFrame  Class;
proc evalInitialValue(): ObjectOpt
return Eval[VariableInitialisation](envrun)
end proc;
mInstanceVariable  InstanceAccessor;
case memberMod of
{abstractdo
if HasInitialiser[VariableInitialisationthen throw syntaxError
end if;
m  new InstanceAccessorcodeabstractfinalfalse;
{virtualdo
m  new InstanceVariableevalInitialValueevalInitialValue, immutableimmutable, finalfalse;
{finaldo
m  new InstanceVariableevalInitialValueevalInitialValue, immutableimmutable, finaltrue
end case;
osOverrideStatusPair  defineInstanceMember(localFrame, cxt, name, namespaces, a.overrideMod, readWrite, m);
proc deferredInstanceValidate()
tClassOpt  Eval[TypedIdentifier](env);
if t = none then
overriddenReadInstanceMember  {nonepotentialConflict os.readStatus.overriddenMember;
overriddenWriteInstanceMember  {nonepotentialConflict os.writeStatus.overriddenMember;
if overriddenRead  {nonepotentialConflictthen
Note that defineInstanceMember already ensured that overriddenRead  InstanceMethod.
t  overriddenRead.type
elsif overriddenWrite  {nonepotentialConflictthen
Note that defineInstanceMember already ensured that overriddenWrite  InstanceMethod.
t  overriddenWrite.type
else t  objectClass
end if
end if;
m.type  t
end proc;
deferredValidators  deferredValidators  [deferredInstanceValidate];
Kind[VariableBinding instanceRun;
end case
end if
end proc;
HasInitialiser[VariableInitialisation]: Boolean;
HasInitialiser[VariableInitialisation  «empty»] = false;
HasInitialiser[VariableInitialisation  = VariableInitialiser] = true;
proc Validate[VariableInitialisation] (cxtContextenvEnvironment)
[VariableInitialisation  «empty»] do nothing;
[VariableInitialisation  = VariableInitialiserdo
Validate[VariableInitialiser](cxtenv)
end proc;
proc Validate[VariableInitialiser] (cxtContextenvEnvironment)
[VariableInitialiser  AssignmentExpressiondo
Validate[AssignmentExpression](cxtenv);
[VariableInitialiser  NonexpressionAttributedo
Validate[NonexpressionAttribute](env);
[VariableInitialiser  AttributeCombinationdo
Validate[AttributeCombination](cxtenv)
end proc;
Name[TypedIdentifier]: String;
Name[TypedIdentifier  Identifier] = Name[Identifier];
Name[TypedIdentifier  Identifier : TypeExpression] = Name[Identifier];
TypePresent[TypedIdentifier]: Boolean;
TypePresent[TypedIdentifier  Identifier] = false;
TypePresent[TypedIdentifier  Identifier : TypeExpression] = true;
proc Validate[TypedIdentifier] (cxtContextenvEnvironment)
[TypedIdentifier  Identifierdo nothing;
[TypedIdentifier  Identifier : TypeExpressiondo
Validate[TypeExpression](cxtenv)
end proc;

Evaluation

proc Eval[VariableDefinition  VariableDefinitionKind VariableBindingListallowIn] (envEnvironmentdObject): Object
immutableBoolean  Immutable[VariableDefinitionKind];
Eval[VariableBindingListallowIn](envimmutable);
return d
end proc;
proc Eval[VariableBindingList] (envEnvironmentimmutableBoolean)
[VariableBindingList  VariableBindingdo Eval[VariableBinding](envimmutable);
[VariableBindingList0  VariableBindingList1 , VariableBindingdo
Eval[VariableBindingList1](envimmutable);
Eval[VariableBinding](envimmutable)
end proc;
proc Eval[VariableBinding  TypedIdentifier VariableInitialisation] (envEnvironmentimmutableBoolean)
case Kind[VariableBindingof
{hoisteddo
valueObjectOpt  Eval[VariableInitialisation](envrun);
if value  none then
lexicalWrite(envMultiname[VariableBinding], valuefalserun)
end if;
{staticCompileddo nothing;
{staticRundo
localFrameFrame  env[0];
membersStaticMember{}  {b.content | b  localFrame.staticWriteBindings such that b.qname  Multiname[VariableBinding]};
Note that the members set consists of exactly one Variable element because localFrame was constructed with that Variable inside Validate.
vVariable  the one element of members;
valueObjectOpt  Eval[VariableInitialisation](envcompile);
tClass  v.type;
coercedValueObjectUninit;
if value  none then coercedValue  assignmentConversion(valuet)
elsif immutable then coercedValue  uninitialised
else coercedValue  assignmentConversion(undefinedt)
end if;
v.value  coercedValue;
{instanceRundo nothing
end case
end proc;
proc Eval[VariableInitialisation] (envEnvironmentphasePhase): ObjectOpt
[VariableInitialisation  «empty»] do return none;
[VariableInitialisation  = VariableInitialiserdo
return Eval[VariableInitialiser](envphase)
end proc;
proc Eval[VariableInitialiser] (envEnvironmentphasePhase): Object
[VariableInitialiser  AssignmentExpressiondo
rObjOrRef  Eval[AssignmentExpression](envphase);
return readReference(rphase);
[VariableInitialiser  NonexpressionAttributedo
return Eval[NonexpressionAttribute](envphase);
[VariableInitialiser  AttributeCombinationdo
return Eval[AttributeCombination](envphase)
end proc;
proc Eval[TypedIdentifier] (envEnvironment): ClassOpt
[TypedIdentifier  Identifierdo return none;
[TypedIdentifier  Identifier : TypeExpressiondo
return Eval[TypeExpression](env)
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.

SimpleVariableDefinition  var UntypedVariableBindingList
UntypedVariableBindingList 
   UntypedVariableBinding
|  UntypedVariableBindingList , UntypedVariableBinding
UntypedVariableBinding  Identifier VariableInitialisationallowIn

Validation

proc Validate[SimpleVariableDefinition  var UntypedVariableBindingList] (cxtContextenvEnvironment)
if cxt.strict or getRegionalFrame(env Global  FunctionFrame then
end if;
Validate[UntypedVariableBindingList](cxtenv)
end proc;
proc Validate[UntypedVariableBindingList] (cxtContextenvEnvironment)
[UntypedVariableBindingList  UntypedVariableBindingdo
Validate[UntypedVariableBinding](cxtenv);
Validate[UntypedVariableBindingList1](cxtenv);
Validate[UntypedVariableBinding](cxtenv)
end proc;
proc Validate[UntypedVariableBinding  Identifier VariableInitialisationallowIn] (cxtContextenvEnvironment)
Validate[VariableInitialisationallowIn](cxtenv);
end proc;

Evaluation

proc Eval[SimpleVariableDefinition  var UntypedVariableBindingList] (envEnvironmentdObject): Object
return d
end proc;
proc Eval[UntypedVariableBindingList] (envEnvironment)
[UntypedVariableBindingList  UntypedVariableBindingdo
end proc;
proc Eval[UntypedVariableBinding  Identifier VariableInitialisationallowIn] (envEnvironment)
valueObjectOpt  Eval[VariableInitialisationallowIn](envrun);
if value  none then
qnameQualifiedName  QualifiedNamenamespacepublicNamespaceidName[Identifier];
lexicalWrite(env, {qname}, valuefalserun)
end if
end proc;

Function Definition

Syntax

FunctionDefinition 
   FunctionDeclaration Block
|  FunctionDeclaration Semicolon
FunctionDeclaration  function FunctionName FunctionSignature
FunctionName 
   Identifier
|  get [no line break] Identifier
|  set [no line break] Identifier
|  String
FunctionSignature  ParameterSignature ResultSignature
ParameterSignature  ( Parameters )
Parameters 
   «empty»
|  AllParameters
AllParameters 
   Parameter
|  Parameter , AllParameters
|  OptionalParameters
OptionalParameters 
   OptionalParameter
|  OptionalParameter , OptionalParameters
|  RestAndNamedParameters
RestAndNamedParameters 
   NamedParameters
|  RestParameter
|  RestParameter , NamedParameters
|  NamedRestParameter
NamedParameters 
   NamedParameter
|  NamedParameter , NamedParameters
Parameter 
   TypedIdentifierallowIn
|  const TypedIdentifierallowIn
OptionalParameter  Parameter = AssignmentExpressionallowIn
TypedInitialiser  TypedIdentifierallowIn = AssignmentExpressionallowIn
NamedParameter 
   named TypedInitialiser
|  const named TypedInitialiser
|  named const TypedInitialiser
RestParameter 
   ...
|  ... Parameter
NamedRestParameter 
   ... named Identifier
|  ... const named Identifier
|  ... named const Identifier
ResultSignature 
   «empty»
|  : TypeExpressionallowIn

Class Definition

Syntax

ClassDefinition  class Identifier Inheritance Block
Inheritance 
   «empty»
|  extends TypeExpressionallowIn
|  implements TypeExpressionList
|  extends TypeExpressionallowIn implements TypeExpressionList

Validation

Class[ClassDefinition]: Class;
proc Validate[ClassDefinition  class Identifier Inheritance Block] (cxtContextenvEnvironmentplPluralityattrAttributeOptNotFalse)
if pl  singular then throw syntaxError end if;
superclassClass  Validate[Inheritance](cxtenv);
if not superclass.complete or superclass.final then throw definitionError end if;
aCompoundAttribute  toCompoundAttribute(attr);
if a.compile then throw definitionError end if;
proc call(thisObjectargsArgumentListphasePhase): Object
????
end proc;
proc construct(thisObjectargsArgumentListphasePhase): Object
????
end proc;
prototypeObject  null;
if a.prototype then ???? end if;
finalBoolean  false;
if a.memberMod = final then
final  true;
a  CompoundAttributememberModnone, other fields from a
end if;
privateNamespaceNamespace  new Namespacename: “private;
dynamicBoolean  a.dynamic or superclass.dynamic;
cClass  new ClassstaticReadBindings: {}, staticWriteBindings: {}, instanceReadBindings: {}, instanceWriteBindings: {}, instanceInitOrder[], completefalse, supersuperclass, prototypeprototype, privateNamespaceprivateNamespace, dynamicdynamic, primitivefalse, finalfinal, callcall, constructconstruct;
Class[ClassDefinition c;
proc makeStaticMember(): StaticMember
return new VariabletypeclassClassvaluecimmutabletrue
end proc;
proc makeInstanceMember(): InstanceMember
????
end proc;
bindDefinition(env, Name[Identifier], a, static, readNoWrite, makeStaticMember, makeInstanceMember);
ValidateUsingFrame[Block](cxt, env, JumpTargetsbreakTargets: {}, continueTargets: {}, pl, c)
end proc;
proc Validate[Inheritance] (cxtContextenvEnvironment): Class
[Inheritance  «empty»] do return objectClass;
[Inheritance  extends TypeExpressionallowIndo
Validate[TypeExpressionallowIn](cxtenv);
return Eval[TypeExpressionallowIn](env);
[Inheritance  implements TypeExpressionListdo return objectClass;
[Inheritance  extends TypeExpressionallowIn implements TypeExpressionListdo
return objectClass
end proc;

Evaluation

proc Eval[ClassDefinition  class Identifier Inheritance Block] (envEnvironmentdObject): Object
cClass  Class[ClassDefinition];
return EvalUsingFrame[Block](envcd)
end proc;

Interface Definition

Syntax

InterfaceDefinition 
   interface Identifier ExtendsList Block
|  interface Identifier Semicolon
ExtendsList 
   «empty»
|  extends TypeExpressionList
TypeExpressionList 
   TypeExpressionallowIn

Namespace Definition

Syntax

NamespaceDefinition  namespace Identifier

Package Definition

Syntax

PackageDefinition 
   package Block
|  package PackageName Block
PackageName 
   Identifier
|  PackageName . Identifier

Programs

Syntax

Program  Directives

Predefined Identifiers

Built-in Classes

proc makeBuiltInClass(superclassClassOpt, dynamicBoolean, primitiveBoolean, finalBoolean): Class
proc call(thisObjectargsArgumentListphasePhase): Object
????
end proc;
proc construct(thisObjectargsArgumentListphasePhase): Object
????
end proc;
privateNamespaceNamespace  new Namespacename: “private;
return new ClassstaticReadBindings: {}, staticWriteBindings: {}, instanceReadBindings: {}, instanceWriteBindings: {}, instanceInitOrder[], completetrue, supersuperclass, prototypenull, privateNamespaceprivateNamespace, dynamicdynamic, primitiveprimitive, finalfinal, callcall, constructconstruct
end proc;
objectClassClass = makeBuiltInClass(nonefalsetruefalse);
undefinedClassClass = makeBuiltInClass(objectClassfalsetruetrue);
nullClassClass = makeBuiltInClass(objectClassfalsetruetrue);
booleanClassClass = makeBuiltInClass(objectClassfalsetruetrue);
numberClassClass = makeBuiltInClass(objectClassfalsetruetrue);
stringClassClass = makeBuiltInClass(objectClassfalsefalsetrue);
characterClassClass = makeBuiltInClass(stringClassfalsefalsetrue);
namespaceClassClass = makeBuiltInClass(objectClassfalsefalsetrue);
attributeClassClass = makeBuiltInClass(objectClassfalsefalsetrue);
classClassClass = makeBuiltInClass(objectClassfalsefalsetrue);
functionClassClass = makeBuiltInClass(objectClassfalsefalsetrue);
prototypeClassClass = makeBuiltInClass(objectClasstruefalsetrue);
packageClassClass = makeBuiltInClass(objectClasstruefalsetrue);

Built-in Functions

Built-in Attributes

Built-in Operators

Unary Operators

proc plusObject(thisObjectaObjectargsArgumentListphasePhase): Object
return toNumber(aphase)
end proc;
proc minusObject(thisObjectaObjectargsArgumentListphasePhase): Object
return float64Negate(toNumber(aphase))
end proc;
proc bitwiseNotObject(thisObjectaObjectargsArgumentListphasePhase): Object
iInteger  toInt32(toNumber(aphase));
return realToFloat64(bitwiseXor(i, –1))
end proc;
proc incrementObject(thisObjectaObjectargsArgumentListphasePhase): Object
xObject  unaryPlus(aphase);
return binaryDispatch(addTablex, 1.0, phase)
end proc;
proc decrementObject(thisObjectaObjectargsArgumentListphasePhase): Object
xObject  unaryPlus(aphase);
return binaryDispatch(subtractTablex, 1.0, phase)
end proc;
proc callObject(thisObjectaObjectargsArgumentListphasePhase): Object
case a of
Undefined  Null  Boolean  Float64  String  Namespace  CompoundAttribute  Prototype  Package  Global do
Class do return a.call(thisargsphase);
Instance do return a.call(thisargsa.envphase);
code: {abstract Instance  a.method.code;
case code of
Instance do return callObject(a.thiscodeargsphase);
end case
end case
end proc;
proc constructObject(thisObjectaObjectargsArgumentListphasePhase): Object
case a of
Undefined  Null  Boolean  Float64  String  Namespace  CompoundAttribute  MethodClosure  Prototype  Package  Global do
Class do return a.construct(thisargsphase);
Instance do return a.construct(thisargsa.envphase)
end case
end proc;
proc bracketReadObject(thisObjectaObjectargsArgumentListphasePhase): Object
if |args.positional 1 or args.named  {} then throw argumentMismatchError end if;
nameString  toString(args.positional[0], phase);
resultObjectOpt  readProperty(a, {QualifiedNamenamespacepublicNamespaceidname}, propertyLookup, phase);
if result = none then throw propertyAccessError else return result end if
end proc;
proc bracketWriteObject(thisObjectaObjectargsArgumentListphasePhase): Object
if phase = compile then throw compileExpressionError end if;
if |args.positional 2 or args.named  {} then throw argumentMismatchError end if;
newValueObject  args.positional[0];
nameString  toString(args.positional[1], phase);
result: {noneok writeProperty(a, {QualifiedNamenamespacepublicNamespaceidname}, propertyLookup, true, newValue, phase);
if result = none then throw propertyAccessError end if;
return undefined
end proc;
proc bracketDeleteObject(thisObjectaObjectargsArgumentListphasePhase): Object
if phase = compile then throw compileExpressionError end if;
if |args.positional 1 or args.named  {} then throw argumentMismatchError end if;
nameString  toString(args.positional[0], phase);
end proc;
plusTableUnaryMethod{}  {UnaryMethodoperandTypeobjectClassfplusObject};
minusTableUnaryMethod{}  {UnaryMethodoperandTypeobjectClassfminusObject};
bitwiseNotTableUnaryMethod{}  {UnaryMethodoperandTypeobjectClassfbitwiseNotObject};
incrementTableUnaryMethod{}  {UnaryMethodoperandTypeobjectClassfincrementObject};
decrementTableUnaryMethod{}  {UnaryMethodoperandTypeobjectClassfdecrementObject};
callTableUnaryMethod{}  {UnaryMethodoperandTypeobjectClassfcallObject};
constructTableUnaryMethod{}  {UnaryMethodoperandTypeobjectClassfconstructObject};
bracketReadTableUnaryMethod{}  {UnaryMethodoperandTypeobjectClassfbracketReadObject};
bracketWriteTableUnaryMethod{}  {UnaryMethodoperandTypeobjectClassfbracketWriteObject};
bracketDeleteTableUnaryMethod{}  {UnaryMethodoperandTypeobjectClassfbracketDeleteObject};

Binary Operators

proc addObjects(aObjectbObjectphasePhase): Object
apPrimitiveObject  toPrimitive(anullphase);
bpPrimitiveObject  toPrimitive(bnullphase);
if ap  String or bp  String then
return toString(apphase toString(bpphase)
else return float64Add(toNumber(apphase), toNumber(bpphase))
end if
end proc;
proc subtractObjects(aObjectbObjectphasePhase): Object
return float64Subtract(toNumber(aphase), toNumber(bphase))
end proc;
proc multiplyObjects(aObjectbObjectphasePhase): Object
return float64Multiply(toNumber(aphase), toNumber(bphase))
end proc;
proc divideObjects(aObjectbObjectphasePhase): Object
return float64Divide(toNumber(aphase), toNumber(bphase))
end proc;
proc remainderObjects(aObjectbObjectphasePhase): Object
return float64Remainder(toNumber(aphase), toNumber(bphase))
end proc;
proc lessObjects(aObjectbObjectphasePhase): Object
apPrimitiveObject  toPrimitive(anullphase);
bpPrimitiveObject  toPrimitive(bnullphase);
if ap  String and bp  String then return ap < bp
else return float64Compare(toNumber(apphase), toNumber(bpphase)) = less
end if
end proc;
proc lessOrEqualObjects(aObjectbObjectphasePhase): Object
apPrimitiveObject  toPrimitive(anullphase);
bpPrimitiveObject  toPrimitive(bnullphase);
if ap  String and bp  String then return ap  bp
else return float64Compare(toNumber(apphase), toNumber(bpphase))  {lessequal}
end if
end proc;
proc equalObjects(aObjectbObjectphasePhase): Object
case a of
Undefined  Null do return b  Undefined  Null;
if b  Boolean then return a = b
else return equalObjects(toNumber(aphase), bphase)
end if;
bpPrimitiveObject  toPrimitive(bnullphase);
case bp of
Undefined  Null do return false;
Boolean  Float64  String do
return float64Compare(atoNumber(bpphase)) = equal
end case;
String do
bpPrimitiveObject  toPrimitive(bnullphase);
case bp of
Undefined  Null do return false;
Boolean  Float64 do
return float64Compare(toNumber(aphase), toNumber(bpphase)) = equal;
String do return a = bp
end case;
Namespace  CompoundAttribute  Class  MethodClosure  Prototype  Instance  Package  Global do
case b of
Undefined  Null do return false;
Namespace  CompoundAttribute  Class  MethodClosure  Prototype  Instance  Package  Global do
return strictEqualObjects(abphase);
Boolean  Float64  String do
apPrimitiveObject  toPrimitive(anullphase);
case ap of
Undefined  Null do return false;
Boolean  Float64  String do return equalObjects(apbphase)
end case
end case
end case
end proc;
proc strictEqualObjects(aObjectbObjectphasePhase): Object
if a  Float64 and b  Float64 then return float64Compare(ab) = equal
else return a = b
end if
end proc;
proc shiftLeftObjects(aObjectbObjectphasePhase): Object
iInteger  toUInt32(toNumber(aphase));
countInteger  bitwiseAnd(toUInt32(toNumber(bphase)), 0x1F);
return realToFloat64(uInt32ToInt32(bitwiseAnd(bitwiseShift(icount), 0xFFFFFFFF)))
end proc;
proc shiftRightObjects(aObjectbObjectphasePhase): Object
iInteger  toInt32(toNumber(aphase));
countInteger  bitwiseAnd(toUInt32(toNumber(bphase)), 0x1F);
return realToFloat64(bitwiseShift(i, –count))
end proc;
proc shiftRightUnsignedObjects(aObjectbObjectphasePhase): Object
iInteger  toUInt32(toNumber(aphase));
countInteger  bitwiseAnd(toUInt32(toNumber(bphase)), 0x1F);
return realToFloat64(bitwiseShift(i, –count))
end proc;
proc bitwiseAndObjects(aObjectbObjectphasePhase): Object
iInteger  toInt32(toNumber(aphase));
jInteger  toInt32(toNumber(bphase));
return realToFloat64(bitwiseAnd(ij))
end proc;
proc bitwiseXorObjects(aObjectbObjectphasePhase): Object
iInteger  toInt32(toNumber(aphase));
jInteger  toInt32(toNumber(bphase));
return realToFloat64(bitwiseXor(ij))
end proc;
proc bitwiseOrObjects(aObjectbObjectphasePhase): Object
iInteger  toInt32(toNumber(aphase));
jInteger  toInt32(toNumber(bphase));
return realToFloat64(bitwiseOr(ij))
end proc;
addTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassfaddObjects};
subtractTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassfsubtractObjects};
multiplyTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassfmultiplyObjects};
divideTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassfdivideObjects};
remainderTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassfremainderObjects};
lessTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassflessObjects};
lessOrEqualTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassflessOrEqualObjects};
equalTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassfequalObjects};
strictEqualTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassfstrictEqualObjects};
shiftLeftTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassfshiftLeftObjects};
shiftRightTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassfshiftRightObjects};
shiftRightUnsignedTableBinaryMethod{}  {BinaryMethodleftTypeobjectClass, rightTypeobjectClass, fshiftRightUnsignedObjects};
bitwiseAndTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassfbitwiseAndObjects};
bitwiseXorTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassfbitwiseXorObjects};
bitwiseOrTableBinaryMethod{}  {BinaryMethodleftTypeobjectClassrightTypeobjectClassfbitwiseOrObjects};

Built-in Namespaces

Built-in Units

EvalProgram[Program  Directives]: Object
begin
savedDeferredValidators: (()  ())[]  deferredValidators;
deferredValidators  [];
Validate[Directives](initialContext, initialEnvironment, JumpTargetsbreakTargets: {}, continueTargets: {}, singular, none);
for each v  deferredValidators do v() end for each;
deferredValidators  savedDeferredValidators;
end;

Waldemar Horwat
Last modified Monday, April 22, 2002
previousupnext