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 Namespace〈〈name: “public〉〉;
enumerableNamespaceNamespace = new Namespace〈〈name: “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 SystemFrame〈〈staticReadBindings: {}, 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: {noneokwriteProperty(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 HoistedVar〈〈valueundefined〉〉;
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 ∉ {nonepotentialConflictInstanceVariable 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 DynamicProperty〈〈namenamevaluenewValue〉〉};
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);
[FullPostfixExpression ⇒ ExpressionQualifiedIdentifierdo
Validate[ExpressionQualifiedIdentifier](cxtenv);
Context[FullPostfixExpression← cxt;
[FullPostfixExpression ⇒ FullNewExpressiondo
Validate[FullNewExpression](cxtenv);
[FullPostfixExpression0 ⇒ FullPostfixExpression1 MemberOperatordo
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);
[FullPostfixExpression ⇒ ExpressionQualifiedIdentifierdo
return LexicalReferenceenvenv, variableMultinameMultiname[ExpressionQualifiedIdentifier], cxtContext[FullPostfixExpression];
[FullPostfixExpression ⇒ FullNewExpressiondo
return Eval[FullNewExpression](envphase);
[FullPostfixExpression0 ⇒ FullPostfixExpression1 MemberOperatordo
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 ⇒ MultiplicativeExpression] = Validate[MultiplicativeExpression];
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);
[ShiftExpression ⇒ ShiftExpressionOrSuper >>> AdditiveExpressionOrSuperdo
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);
[ShiftExpression ⇒ ShiftExpressionOrSuper >>> AdditiveExpressionOrSuperdo
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);
[RelationalExpressionβ0 ⇒ RelationalExpressionβ1 is ShiftExpressiondo
Validate[RelationalExpressionβ1](cxtenv);
Validate[ShiftExpression](cxtenv);
[RelationalExpressionβ0 ⇒ RelationalExpressionβ1 as ShiftExpressiondo
Validate[RelationalExpressionβ1](cxtenv);
Validate[ShiftExpression](cxtenv);
[RelationalExpressionallowIn0 ⇒ RelationalExpressionallowIn1 in ShiftExpressionOrSuperdo
Validate[RelationalExpressionallowIn1](cxtenv);
Validate[ShiftExpressionOrSuper](cxtenv);
[RelationalExpressionβ0 ⇒ RelationalExpressionβ1 instanceof ShiftExpressiondo
Validate[RelationalExpressionβ1](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β ⇒ RelationalExpressionβdo
Validate[RelationalExpressionβ](cxtenv);
[EqualityExpressionβ ⇒ EqualityExpressionOrSuperβ == RelationalExpressionOrSuperβdo
Validate[EqualityExpressionOrSuperβ](cxtenv);
Validate[RelationalExpressionOrSuperβ](cxtenv);
[EqualityExpressionβ ⇒ EqualityExpressionOrSuperβ != RelationalExpressionOrSuperβdo
Validate[EqualityExpressionOrSuperβ](cxtenv);
Validate[RelationalExpressionOrSuperβ](cxtenv);
[EqualityExpressionβ ⇒ EqualityExpressionOrSuperβ === RelationalExpressionOrSuperβdo
Validate[EqualityExpressionOrSuperβ](cxtenv);
Validate[RelationalExpressionOrSuperβ](cxtenv);
[EqualityExpressionβ ⇒ EqualityExpressionOrSuperβ !== RelationalExpressionOrSuperβdo
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β ⇒ RelationalExpressionβdo
return Eval[RelationalExpressionβ](envphase);
[EqualityExpressionβ ⇒ EqualityExpressionOrSuperβ == RelationalExpressionOrSuperβdo
raObjOrRefOptionalLimit ← Eval[EqualityExpressionOrSuperβ](envphase);
aObjOptionalLimit ← readRefWithLimit(raphase);
rbObjOrRefOptionalLimit ← Eval[RelationalExpressionOrSuperβ](envphase);
bObjOptionalLimit ← readRefWithLimit(rbphase);
return binaryDispatch(equalTableabphase);
[EqualityExpressionβ ⇒ EqualityExpressionOrSuperβ != RelationalExpressionOrSuperβdo
raObjOrRefOptionalLimit ← Eval[EqualityExpressionOrSuperβ](envphase);
aObjOptionalLimit ← readRefWithLimit(raphase);
rbObjOrRefOptionalLimit ← Eval[RelationalExpressionOrSuperβ](envphase);
bObjOptionalLimit ← readRefWithLimit(rbphase);
cObject ← binaryDispatch(equalTableabphase);
return unaryNot(cphase);
[EqualityExpressionβ ⇒ EqualityExpressionOrSuperβ === RelationalExpressionOrSuperβdo
raObjOrRefOptionalLimit ← Eval[EqualityExpressionOrSuperβ](envphase);
aObjOptionalLimit ← readRefWithLimit(raphase);
rbObjOrRefOptionalLimit ← Eval[RelationalExpressionOrSuperβ](envphase);
bObjOptionalLimit ← readRefWithLimit(rbphase);
return binaryDispatch(strictEqualTableabphase);
[EqualityExpressionβ ⇒ EqualityExpressionOrSuperβ !== RelationalExpressionOrSuperβdo
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β ⇒ EqualityExpressionβdo
Validate[EqualityExpressionβ](cxtenv);
[BitwiseAndExpressionβ ⇒ BitwiseAndExpressionOrSuperβ & EqualityExpressionOrSuperβdo
Validate[BitwiseAndExpressionOrSuperβ](cxtenv);
Validate[EqualityExpressionOrSuperβ](cxtenv)
end proc;
proc Validate[BitwiseXorExpressionβ] (cxtContextenvEnvironment)
[BitwiseXorExpressionβ ⇒ BitwiseAndExpressionβdo
Validate[BitwiseAndExpressionβ](cxtenv);
[BitwiseXorExpressionβ ⇒ BitwiseXorExpressionOrSuperβ ^ BitwiseAndExpressionOrSuperβdo
Validate[BitwiseXorExpressionOrSuperβ](cxtenv);
Validate[BitwiseAndExpressionOrSuperβ](cxtenv)
end proc;
proc Validate[BitwiseOrExpressionβ] (cxtContextenvEnvironment)
[BitwiseOrExpressionβ ⇒ BitwiseXorExpressionβdo
Validate[BitwiseXorExpressionβ](cxtenv);
[BitwiseOrExpressionβ ⇒ BitwiseOrExpressionOrSuperβ | BitwiseXorExpressionOrSuperβdo
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β ⇒ EqualityExpressionβdo
return Eval[EqualityExpressionβ](envphase);
[BitwiseAndExpressionβ ⇒ BitwiseAndExpressionOrSuperβ & EqualityExpressionOrSuperβdo
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β ⇒ BitwiseAndExpressionβdo
return Eval[BitwiseAndExpressionβ](envphase);
[BitwiseXorExpressionβ ⇒ BitwiseXorExpressionOrSuperβ ^ BitwiseAndExpressionOrSuperβdo
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β ⇒ BitwiseXorExpressionβdo
return Eval[BitwiseXorExpressionβ](envphase);
[BitwiseOrExpressionβ ⇒ BitwiseOrExpressionOrSuperβ | BitwiseXorExpressionOrSuperβdo
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β ⇒ BitwiseOrExpressionβdo
Validate[BitwiseOrExpressionβ](cxtenv);
[LogicalAndExpressionβ0 ⇒ LogicalAndExpressionβ1 && BitwiseOrExpressionβdo
Validate[LogicalAndExpressionβ1](cxtenv);
Validate[BitwiseOrExpressionβ](cxtenv)
end proc;
proc Validate[LogicalXorExpressionβ] (cxtContextenvEnvironment)
[LogicalXorExpressionβ ⇒ LogicalAndExpressionβdo
Validate[LogicalAndExpressionβ](cxtenv);
[LogicalXorExpressionβ0 ⇒ LogicalXorExpressionβ1 ^^ LogicalAndExpressionβdo
Validate[LogicalXorExpressionβ1](cxtenv);
Validate[LogicalAndExpressionβ](cxtenv)
end proc;
proc Validate[LogicalOrExpressionβ] (cxtContextenvEnvironment)
[LogicalOrExpressionβ ⇒ LogicalXorExpressionβdo
Validate[LogicalXorExpressionβ](cxtenv);
[LogicalOrExpressionβ0 ⇒ LogicalOrExpressionβ1 || LogicalXorExpressionβdo
Validate[LogicalOrExpressionβ1](cxtenv);
Validate[LogicalXorExpressionβ](cxtenv)
end proc;

Evaluation

proc Eval[LogicalAndExpressionβ] (envEnvironmentphasePhase): ObjOrRef
[LogicalAndExpressionβ ⇒ BitwiseOrExpressionβdo
return Eval[BitwiseOrExpressionβ](envphase);
[LogicalAndExpressionβ0 ⇒ LogicalAndExpressionβ1 && BitwiseOrExpressionβdo
raObjOrRef ← Eval[LogicalAndExpressionβ1](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β ⇒ LogicalAndExpressionβdo
return Eval[LogicalAndExpressionβ](envphase);
[LogicalXorExpressionβ0 ⇒ LogicalXorExpressionβ1 ^^ LogicalAndExpressionβdo
raObjOrRef ← Eval[LogicalXorExpressionβ1](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β ⇒ LogicalXorExpressionβdo
return Eval[LogicalXorExpressionβ](envphase);
[LogicalOrExpressionβ0 ⇒ LogicalOrExpressionβ1 || LogicalXorExpressionβdo
raObjOrRef ← Eval[LogicalOrExpressionβ1](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β ⇒ LogicalOrExpressionβdo
Validate[LogicalOrExpressionβ](cxtenv);
[ConditionalExpressionβ ⇒ LogicalOrExpressionβ ? AssignmentExpressionβ1 : AssignmentExpressionβ2do
Validate[LogicalOrExpressionβ](cxtenv);
Validate[AssignmentExpressionβ1](cxtenv);
Validate[AssignmentExpressionβ2](cxtenv)
end proc;
proc Validate[NonAssignmentExpressionβ] (cxtContextenvEnvironment)
[NonAssignmentExpressionβ ⇒ LogicalOrExpressionβdo
Validate[LogicalOrExpressionβ](cxtenv);
[NonAssignmentExpressionβ0 ⇒ LogicalOrExpressionβ ? NonAssignmentExpressionβ1 : NonAssignmentExpressionβ2do
Validate[LogicalOrExpressionβ](cxtenv);
Validate[NonAssignmentExpressionβ1](cxtenv);
Validate[NonAssignmentExpressionβ2](cxtenv)
end proc;

Evaluation

proc Eval[ConditionalExpressionβ] (envEnvironmentphasePhase): ObjOrRef
[ConditionalExpressionβ ⇒ LogicalOrExpressionβdo
return Eval[LogicalOrExpressionβ](envphase);
[ConditionalExpressionβ ⇒ LogicalOrExpressionβ ? AssignmentExpressionβ1 : AssignmentExpressionβ2do
raObjOrRef ← Eval[LogicalOrExpressionβ](envphase);
aObject ← readReference(raphase);
if toBoolean(aphasethen
rbObjOrRef ← Eval[AssignmentExpressionβ1](envphase);
return readReference(rbphase)
else
rcObjOrRef ← Eval[AssignmentExpressionβ2](envphase);
return readReference(rcphase)
end if
end proc;
proc Eval[NonAssignmentExpressionβ] (envEnvironmentphasePhase): ObjOrRef
[NonAssignmentExpressionβ ⇒ LogicalOrExpressionβdo
return Eval[LogicalOrExpressionβ](envphase);
[NonAssignmentExpressionβ0 ⇒ LogicalOrExpressionβ ? NonAssignmentExpressionβ1 : NonAssignmentExpressionβ2do
raObjOrRef ← Eval[LogicalOrExpressionβ](envphase);
aObject ← readReference(raphase);
if toBoolean(aphasethen
rbObjOrRef ← Eval[NonAssignmentExpressionβ1](envphase);
return readReference(rbphase)
else
rcObjOrRef ← Eval[NonAssignmentExpressionβ2](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β ⇒ ConditionalExpressionβdo
Validate[ConditionalExpressionβ](cxtenv);
[AssignmentExpressionβ0 ⇒ PostfixExpression = AssignmentExpressionβ1do
Validate[PostfixExpression](cxtenv);
Validate[AssignmentExpressionβ1](cxtenv);
[AssignmentExpressionβ0 ⇒ PostfixExpressionOrSuper CompoundAssignment AssignmentExpressionβ1do
Validate[PostfixExpressionOrSuper](cxtenv);
Validate[AssignmentExpressionβ1](cxtenv);
[AssignmentExpressionβ ⇒ PostfixExpressionOrSuper CompoundAssignment SuperExpressiondo
Validate[PostfixExpressionOrSuper](cxtenv);
Validate[SuperExpression](cxtenv);
[AssignmentExpressionβ0 ⇒ PostfixExpression LogicalAssignment AssignmentExpressionβ1do
Validate[PostfixExpression](cxtenv);
Validate[AssignmentExpressionβ1](cxtenv)
end proc;

Evaluation

proc Eval[AssignmentExpressionβ] (envEnvironmentphasePhase): ObjOrRef
[AssignmentExpressionβ ⇒ ConditionalExpressionβdo
return Eval[ConditionalExpressionβ](envphase);
[AssignmentExpressionβ0 ⇒ PostfixExpression = AssignmentExpressionβ1do
if phase = compile then throw compileExpressionError end if;
raObjOrRef ← Eval[PostfixExpression](envphase);
rbObjOrRef ← Eval[AssignmentExpressionβ1](envphase);
bObject ← readReference(rbphase);
writeReference(rabphase);
return b;
[AssignmentExpressionβ0 ⇒ PostfixExpressionOrSuper CompoundAssignment AssignmentExpressionβ1do
if phase = compile then throw compileExpressionError end if;
return evalAssignmentOp(Table[CompoundAssignment], Eval[PostfixExpressionOrSuper], Eval[AssignmentExpressionβ1], env, phase);
[AssignmentExpressionβ ⇒ PostfixExpressionOrSuper CompoundAssignment SuperExpressiondo
if phase = compile then throw compileExpressionError end if;
[AssignmentExpressionβ0 ⇒ PostfixExpression LogicalAssignment AssignmentExpressionβ1do
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[AssignmentExpressionβ1](envphase), phase)
end if;
{xorEqdo
bRightBoolean toBoolean(readReference(Eval[AssignmentExpressionβ1](envphase), phase), phase);
result ← bLeft xor bRight;
{orEqdo
if not bLeft then
result readReference(Eval[AssignmentExpressionβ1](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β ⇒ AssignmentExpressionβdo
Validate[AssignmentExpressionβ](cxtenv);
[ListExpressionβ0 ⇒ ListExpressionβ1 , AssignmentExpressionβdo
Validate[ListExpressionβ1](cxtenv);
Validate[AssignmentExpressionβ](cxtenv)
end proc;

Evaluation

proc Eval[ListExpressionβ] (envEnvironmentphasePhase): ObjOrRef
[ListExpressionβ ⇒ AssignmentExpressionβdo
return Eval[AssignmentExpressionβ](envphase);
[ListExpressionβ0 ⇒ ListExpressionβ1 , AssignmentExpressionβdo
raObjOrRef ← Eval[ListExpressionβ1](envphase);
readReference(raphase);
rbObjOrRef ← Eval[AssignmentExpressionβ](envphase);
return readReference(rbphase)
end proc;
proc EvalAsList[ListExpressionβ] (envEnvironmentphasePhase): Object[]
[ListExpressionβ ⇒ AssignmentExpressionβdo
rObjOrRef ← Eval[AssignmentExpressionβ](envphase);
eltObject ← readReference(rphase);
return [elt];
[ListExpressionβ0 ⇒ ListExpressionβ1 , AssignmentExpressionβdo
eltsObject[] ← EvalAsList[ListExpressionβ1](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 Semicolonωdo
Validate[ExpressionStatement](cxtenv);
[Statementω ⇒ SuperStatement Semicolonωdo Validate[SuperStatement](cxtenv);
[Statementω ⇒ Blockdo Validate[Block](cxtenvjtpl);
[Statementω ⇒ LabeledStatementωdo Validate[LabeledStatementω](cxtenvsljt);
[Statementω ⇒ IfStatementωdo Validate[IfStatementω](cxtenvjt);
[Statementω ⇒ SwitchStatementdo ????;
[Statementω ⇒ DoStatement Semicolonωdo Validate[DoStatement](cxtenvsljt);
[Statementω ⇒ WhileStatementωdo Validate[WhileStatementω](cxtenvsljt);
[Statementω ⇒ ForStatementωdo ????;
[Statementω ⇒ WithStatementωdo ????;
[Statementω ⇒ ContinueStatement Semicolonωdo Validate[ContinueStatement](jt);
[Statementω ⇒ BreakStatement Semicolonωdo Validate[BreakStatement](jt);
[Statementω ⇒ ReturnStatement Semicolonωdo Validate[ReturnStatement](cxtenv);
[Statementω ⇒ ThrowStatement Semicolonωdo Validate[ThrowStatement](cxtenv);
[Statementω ⇒ TryStatementdo ????
end proc;
Enabled[Substatementω]: Boolean;
proc Validate[Substatementω] (cxtContextenvEnvironmentslLabel{}, jtJumpTargets)
[Substatementω ⇒ EmptyStatementdo nothing;
[Substatementω ⇒ Statementωdo Validate[Statementω](cxtenvsljtplural);
[Substatementω ⇒ SimpleVariableDefinition Semicolonωdo
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 Semicolonωdo
return Eval[ExpressionStatement](env);
[Statementω ⇒ SuperStatement Semicolonωdo return Eval[SuperStatement](env);
[Statementω ⇒ Blockdo return Eval[Block](envd);
[Statementω ⇒ LabeledStatementωdo return Eval[LabeledStatementω](envd);
[Statementω ⇒ IfStatementωdo return Eval[IfStatementω](envd);
[Statementω ⇒ SwitchStatementdo ????;
[Statementω ⇒ DoStatement Semicolonωdo return Eval[DoStatement](envd);
[Statementω ⇒ WhileStatementωdo return Eval[WhileStatementω](envd);
[Statementω ⇒ ForStatementωdo ????;
[Statementω ⇒ WithStatementωdo ????;
[Statementω ⇒ ContinueStatement Semicolonωdo
return Eval[ContinueStatement](envd);
[Statementω ⇒ BreakStatement Semicolonωdo return Eval[BreakStatement](envd);
[Statementω ⇒ ReturnStatement Semicolonωdo return Eval[ReturnStatement](env);
[Statementω ⇒ ThrowStatement Semicolonωdo return Eval[ThrowStatement](env);
[Statementω ⇒ TryStatementdo ????
end proc;
proc Eval[Substatementω] (envEnvironmentdObject): Object
[Substatementω ⇒ EmptyStatementdo return d;
[Substatementω ⇒ Statementωdo return Eval[Statementω](envd);
[Substatementω ⇒ SimpleVariableDefinition Semicolonωdo
return Eval[SimpleVariableDefinition](envd);
[Substatementω ⇒ Attributes [no line break] { Substatements }do
if Enabled[Substatementωthen 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 BlockFrame〈〈staticReadBindings: {}, 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 Substatementω2do
Validate[ParenListExpression](cxtenv);
Validate[SubstatementnoShortIf1](cxtenv, {}, jt);
Validate[Substatementω2](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 Substatementω2do
rObjOrRef ← Eval[ParenListExpression](envrun);
oObject ← readReference(rrun);
if toBoolean(orunthen return Eval[SubstatementnoShortIf1](envd)
else return Eval[Substatementω2](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[WhileStatementωthen 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ω ⇒ Statementωdo
if attr ∉ {nonetruethen throw syntaxError end if;
Validate[Statementω](cxtenv, {}, jtpl);
return cxt;
[Directiveω ⇒ AnnotatableDirectiveωdo
return Validate[AnnotatableDirectiveω](cxtenvplattr);
[Directiveω ⇒ Attributes [no line break] AnnotatableDirectiveωdo
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 Semicolonωdo
if attr ∈ {nonetruethen ???? else throw syntaxError end if;
[Directiveω ⇒ Pragma Semicolonωdo
if attr ∈ {nonetruethen return Validate[Pragma](cxt)
else throw syntaxError
end if
end proc;
proc Validate[AnnotatableDirectiveω] (cxtContextenvEnvironmentplPluralityattrAttributeOptNotFalse): Context
[AnnotatableDirectiveω ⇒ ExportDefinition Semicolonωdo ????;
[AnnotatableDirectiveω ⇒ VariableDefinition Semicolonωdo
Validate[VariableDefinition](cxtenvattr);
return cxt;
[AnnotatableDirectiveω ⇒ FunctionDefinitionωdo ????;
[AnnotatableDirectiveω ⇒ ClassDefinitiondo
Validate[ClassDefinition](cxtenvplattr);
return cxt;
[AnnotatableDirectiveω ⇒ NamespaceDefinition Semicolonωdo ????;
[AnnotatableDirectiveω ⇒ InterfaceDefinitionωdo ????;
[AnnotatableDirectiveω ⇒ ImportDirective Semicolonωdo ????;
[AnnotatableDirectiveω ⇒ UseDirective Semicolonωdo
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ω ⇒ Statementωdo return Eval[Statementω](envd);
[Directiveω ⇒ AnnotatableDirectiveωdo return Eval[AnnotatableDirectiveω](envd);
[Directiveω ⇒ Attributes [no line break] AnnotatableDirectiveωdo
if Enabled[Directiveωthen return Eval[AnnotatableDirectiveω](envd)
else return d
end if;
[Directiveω ⇒ Attributes [no line break] { Directives }do
if Enabled[Directiveωthen return Eval[Directives](envdelse return d end if;
[Directiveω ⇒ PackageDefinitiondo ????;
[Directiveω ⇒ IncludeDirective Semicolonωdo ????;
[Directiveω ⇒ Pragma Semicolonωdo return d
end proc;
proc Eval[AnnotatableDirectiveω] (envEnvironmentdObject): Object
[AnnotatableDirectiveω ⇒ ExportDefinition Semicolonωdo ????;
[AnnotatableDirectiveω ⇒ VariableDefinition Semicolonωdo
return Eval[VariableDefinition](envd);
[AnnotatableDirectiveω ⇒ FunctionDefinitionωdo ????;
[AnnotatableDirectiveω ⇒ ClassDefinitiondo return Eval[ClassDefinition](envd);
[AnnotatableDirectiveω ⇒ NamespaceDefinition Semicolonωdo ????;
[AnnotatableDirectiveω ⇒ InterfaceDefinitionωdo ????;
[AnnotatableDirectiveω ⇒ ImportDirective Semicolonωdo ????;
[AnnotatableDirectiveω ⇒ UseDirective Semicolonωdo 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β ⇒ VariableBindingβdo
Validate[VariableBindingβ](cxtenvattrimmutable);
[VariableBindingListβ0 ⇒ VariableBindingListβ1 , VariableBindingβdo
Validate[VariableBindingListβ1](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[TypedIdentifierβthen
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 Variable〈〈valuefutureimmutableimmutable〉〉;
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[VariableInitialisationβthen throw syntaxError
end if;
m ← new InstanceAccessor〈〈codeabstractfinalfalse〉〉;
{virtualdo
m new InstanceVariable〈〈evalInitialValueevalInitialValue, immutableimmutable, finalfalse〉〉;
{finaldo
m new InstanceVariable〈〈evalInitialValueevalInitialValue, 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 ∪ {nonepotentialConflictos.readStatus.overriddenMember;
overriddenWriteInstanceMember ∪ {nonepotentialConflictos.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β ⇒ = VariableInitialiserβdo
Validate[VariableInitialiserβ](cxtenv)
end proc;
proc Validate[VariableInitialiserβ] (cxtContextenvEnvironment)
[VariableInitialiserβ ⇒ AssignmentExpressionβdo
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 : TypeExpressionβdo
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β ⇒ VariableBindingβdo Eval[VariableBindingβ](envimmutable);
[VariableBindingListβ0 ⇒ VariableBindingListβ1 , VariableBindingβdo
Eval[VariableBindingListβ1](envimmutable);
Eval[VariableBindingβ](envimmutable)
end proc;
proc Eval[VariableBindingβ ⇒ TypedIdentifierβ VariableInitialisationβ] (envEnvironmentimmutableBoolean)
case Kind[VariableBindingβof
{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β ⇒ = VariableInitialiserβdo
return Eval[VariableInitialiserβ](envphase)
end proc;
proc Eval[VariableInitialiserβ] (envEnvironmentphasePhase): Object
[VariableInitialiserβ ⇒ AssignmentExpressionβdo
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 : TypeExpressionβdo
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 Namespace〈〈name: “private〉〉;
dynamicBoolean ← a.dynamic or superclass.dynamic;
cClass new Class〈〈staticReadBindings: {}, staticWriteBindings: {}, instanceReadBindings: {}, instanceWriteBindings: {}, instanceInitOrder[], completefalse, supersuperclass, prototypeprototype, privateNamespaceprivateNamespace, dynamicdynamic, primitivefalse, finalfinal, callcall, constructconstruct〉〉;
Class[ClassDefinition← c;
proc makeStaticMember(): StaticMember
return new Variable〈〈typeclassClassvaluecimmutabletrue〉〉
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 Namespace〈〈name: “private〉〉;
return new Class〈〈staticReadBindings: {}, 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: {noneokwriteProperty(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