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
value: Object,
label: Label
end tuple;
tuple Continue
value: Object,
label: Label
end tuple;
tuple ReturnedValue
value: Object
end tuple;
tuple ThrownValue
value: Object
end tuple;
EarlyExit = Break  Continue  ReturnedValue  ThrownValue;
SemanticException = EarlyExit  SemanticError;

Objects

tag none;
tag ok;
tag future;
tag uninitialised;
Object = Undefined  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  {future, none};
ObjectUninit = Object  {uninitialised};
ObjectUninitFut = Object  {uninitialised, future};

Undefined

tag undefined;
Undefined = {undefined};

Null

tag null;
Null = {null};

Strings

StringOpt = String  {none};

Namespaces

record Namespace
name: String
end record;
publicNamespace: Namespace = new Namespacename: “public”;
enumerableNamespace: Namespace = new Namespacename: “enumerable”;

Qualified Names

tuple QualifiedName
namespace: Namespace,
id: String
end tuple;
QualifiedNameOpt = QualifiedName  {none};
Multiname = QualifiedName{};

Attributes

tag static;
tag constructor;
tag operator;
tag abstract;
tag virtual;
tag final;
MemberModifier = {none, static, constructor, operator, abstract, virtual, final};
OverrideModifier = {none, true, false, undefined};
tuple CompoundAttribute
namespaces: Namespace{},
explicit: Boolean,
dynamic: Boolean,
compile: Boolean,
memberMod: MemberModifier,
overrideMod: OverrideModifier,
prototype: Boolean,
unused: Boolean
end tuple;
Attribute = Boolean  Namespace  CompoundAttribute;
AttributeOptNotFalse = {none, true}  Namespace  CompoundAttribute;

Classes

record Class
staticReadBindings: StaticBinding{},
staticWriteBindings: StaticBinding{},
instanceReadBindings: InstanceBinding{},
instanceWriteBindings: InstanceBinding{},
instanceInitOrder: InstanceVariable[],
complete: Boolean,
super: ClassOpt,
prototype: Object,
privateNamespace: Namespace,
dynamic: Boolean,
primitive: Boolean,
final: Boolean,
call: Object  ArgumentList  Phase  Object,
construct: Object  ArgumentList  Phase  Object
end record;
ClassOpt = Class  {none};
Return an ordered list of class c’s ancestors, including c itself.
proc ancestors(c: Class): Class[]
s: ClassOpt  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(c: Class, d: Class): Boolean
if c = d then return true
else
s: ClassOpt  d.super;
if s = none then return false end if;
return isAncestor(c, s)
end if
end proc;
Return true if c is an ancestor of d other than d itself.
proc isProperAncestor(c: Class, d: Class): Boolean
return isAncestor(c, d) and c  d
end proc;

Method Closures

tuple MethodClosure
this: Object,
end tuple;

Prototype Instances

record Prototype
parent: PrototypeOpt,
dynamicProperties: DynamicProperty{}
end record;
PrototypeOpt = Prototype  {none};
record DynamicProperty
name: String,
value: Object
end record;

Class Instances

Instance = FixedInstance  DynamicInstance;
record FixedInstance
type: Class,
call: Invoker,
construct: Invoker,
typeofString: String,
slots: Slot{}
end record;
record DynamicInstance
type: Class,
call: Invoker,
construct: Invoker,
typeofString: String,
slots: Slot{},
dynamicProperties: DynamicProperty{}
end record;

Slots

record Slot
value: ObjectUninit
end record;

Packages

record Package
staticReadBindings: StaticBinding{},
staticWriteBindings: StaticBinding{},
internalNamespace: Namespace
end record;

Global Objects

record Global
staticReadBindings: StaticBinding{},
staticWriteBindings: StaticBinding{},
internalNamespace: Namespace,
dynamicProperties: DynamicProperty{}
end record;

Objects with Limits

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

References

tuple LexicalReference
variableMultiname: Multiname,
cxt: Context
end tuple;
tuple DotReference
propertyMultiname: Multiname
end tuple;
tuple BracketReference
end tuple;
Reference = LexicalReference  DotReference  BracketReference;
ObjOrRef = Object  Reference;
tuple LimitedObjOrRef
ref: ObjOrRef,
limit: Class
end tuple;
ObjOrRefOptionalLimit = ObjOrRef  LimitedObjOrRef;

Signatures

tuple Signature
requiredPositional: Class[],
optionalPositional: Class[],
optionalNamed: NamedParameter{},
rest: ClassOpt,
restAllowsNames: Boolean,
returnType: Class
end tuple;
tuple NamedParameter
name: String,
type: Class
end tuple;

Argument Lists

tuple NamedArgument
name: String,
value: Object
end tuple;
tuple ArgumentList
positional: Object[],
named: NamedArgument{}
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
operandType: Class,
f: Object  Object  ArgumentList  Phase  Object
end tuple;

Binary Operators

tuple BinaryMethod
leftType: Class,
rightType: Class,
f: Object  Object  Phase  Object
end tuple;

Modes of expression evaluation

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

Contexts

tuple Context
strict: Boolean,
openNamespaces: Namespace{}
end tuple;
initialContext: Context = Contextstrict: false, openNamespaces: {publicNamespace};

Labels

tag default;
Label = String  {default};
tuple JumpTargets
breakTargets: Label{},
continueTargets: Label{}
end tuple;

Environments

tag singular;
tag plural;
Plurality = {singular, plural};
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
staticReadBindings: StaticBinding{},
staticWriteBindings: StaticBinding{}
end record;
record FunctionFrame
staticReadBindings: StaticBinding{},
staticWriteBindings: StaticBinding{},
plurality: Plurality,
this: ObjectFutOpt,
thisFromPrototype: Boolean
end record;
record BlockFrame
staticReadBindings: StaticBinding{},
staticWriteBindings: StaticBinding{},
plurality: Plurality
end record;
initialEnvironment: Environment = [new SystemFramestaticReadBindings: {}, staticWriteBindings: {}];

Members

tuple StaticBinding
qname: QualifiedName,
content: StaticMember,
explicit: Boolean
end tuple;
tuple InstanceBinding
qname: QualifiedName,
content: InstanceMember
end tuple;
tag forbidden;
StaticMember = {forbidden}  Variable  HoistedVar  StaticMethod  Accessor;
StaticMemberOpt = StaticMember  {none};
record Variable
type: Class,
immutable: Boolean
end record;
record HoistedVar
value: Object
end record;
record StaticMethod
type: Signature,
code: Instance,
modifier: {static, constructor}
end record;
record Accessor
type: Class,
code: Instance
end record;
InstanceMember = InstanceVariable  InstanceMethod  InstanceAccessor;
InstanceMemberOpt = InstanceMember  {none};
record InstanceVariable
type: Class,
evalInitialValue: ()  ObjectOpt,
immutable: Boolean,
final: Boolean
end record;
record InstanceMethod
type: Signature,
code: Instance  {abstract},
final: Boolean
end record;
record InstanceAccessor
type: Class,
code: Instance  {abstract},
final: Boolean
end record;

Data Operations

Numeric Utilities

proc uInt32ToInt32(i: Integer): Integer
if i < 231 then return i else return i – 232 end if
end proc;
proc toUInt32(x: Float64): Integer
if x  {+, –, NaN} then return 0 end if;
return truncateFiniteFloat64(x) mod 232
end proc;
proc toInt32(x: Float64): Integer
end proc;

Object Utilities

objectType

objectType(o) returns an Object o’s most specific type.
proc objectType(o: Object): 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(o, c) 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(o: Object, c: Class): Boolean
return isAncestor(c, objectType(o))
end proc;
relaxedHasType(o, c) 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(o: Object, c: Class): Boolean
t: Class  objectType(o);
return isAncestor(c, t) or (o = null and not c.primitive)
end proc;

toBoolean

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

toNumber

toNumber(o, phase) coerces an object o to a number. If phase is compile, only compile-time conversions are permitted.
proc toNumber(o: Object, phase: Phase): Float64
case o of
Undefined do return NaN;
Null  {false} do return +zero;
{true} do 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(o, phase) coerces an object o to a string. If phase is compile, only compile-time conversions are permitted.
proc toString(o: Object, phase: Phase): String
case o of
Undefined do return “undefined”;
Null do return “null”;
{false} do return “false”;
{true} do 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(o: Object, hint: Object, phase: Phase): PrimitiveObject
case o of
PrimitiveObject do return o;
Namespace  CompoundAttribute  Class  MethodClosure  Prototype  Instance  Package  Global do
return toString(o, phase)
end case
end proc;

assignmentConversion

proc assignmentConversion(o: Object, type: Class): Object
if relaxedHasType(o, type) then return o end if;
????
end proc;

unaryPlus

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

unaryNot

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

Attributes

combineAttributes(a, b) returns the attribute that results from concatenating the attributes a and b.
proc combineAttributes(a: AttributeOptNotFalse, b: Attribute): Attribute
if b = false then return false
elsif a  {none, true} then return b
elsif b = true then return a
elsif a  Namespace then
if a = b then return a
elsif b  Namespace then
return CompoundAttributenamespaces: {a, b}, explicit: false, dynamic: false, compile: false, memberMod: none, overrideMod: none, prototype: false, unused: false
else return CompoundAttributenamespaces: b.namespaces  {a}, other fields from b
end if
elsif b  Namespace then
return CompoundAttributenamespaces: a.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.memberMod) or (a.overrideMod  none and b.overrideMod  none and a.overrideMod  b.overrideMod) then
else
return CompoundAttributenamespaces: a.namespaces  b.namespaces, explicit: a.explicit or b.explicit, dynamic: a.dynamic or b.dynamic, compile: a.compile or b.compile, memberMod: a.memberMod  none ? a.memberMod : b.memberMod, overrideMod: a.overrideMod  none ? a.overrideMod : b.overrideMod, prototype: a.prototype or b.prototype, unused: a.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(a: AttributeOptNotFalse): CompoundAttribute
case a of
{none, true} do
return CompoundAttributenamespaces: {}, explicit: false, dynamic: false, compile: false, memberMod: none, overrideMod: none, prototype: false, unused: false;
return CompoundAttributenamespaces: {a}, explicit: false, dynamic: false, compile: false, memberMod: none, overrideMod: none, prototype: false, unused: false;
CompoundAttribute do return a
end case
end proc;

Objects with Limits

getObject(o) returns o without its limit, if any.
proc getObject(o: ObjOptionalLimit): 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(o: ObjOptionalLimit): ClassOpt
case o of
Object do return none;
LimitedInstance do return o.limit
end case
end proc;

References

If r is an Object, readReference(r, phase) 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(r: ObjOrRef, phase: Phase): Object
case r of
Object do return r;
LexicalReference do return lexicalRead(r.env, r.variableMultiname, phase);
result: ObjectOpt  readProperty(r.base, r.propertyMultiname, propertyLookup, phase);
if result = none then throw propertyAccessError else return result end if;
return unaryDispatch(bracketReadTable, null, r.base, r.args, phase)
end case
end proc;
readRefWithLimit(r, phase) 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(r: ObjOrRefOptionalLimit, phase: Phase): ObjOptionalLimit
case r of
ObjOrRef do return readReference(r, phase);
o: Object  readReference(r.ref, phase);
limit: Class  r.limit;
if o = null then return null end if;
if o  Instance or not hasType(o, limit) then throw badValueError end if;
return LimitedInstanceinstance: o, limit: limit
end case
end proc;
If r is a reference, writeReference(r, o) 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(r: ObjOrRefOptionalLimit, o: Object, phase: {run})
case r of
Object do throw referenceError;
lexicalWrite(r.env, r.variableMultiname, o, not r.cxt.strict, phase);
result: {none, ok}  writeProperty(r.base, r.propertyMultiname, propertyLookup, true, o, phase);
if result = none then throw propertyAccessError end if;
args: ArgumentList  ArgumentListpositional: [o]  r.args.positional, named: r.args.named;
unaryDispatch(bracketWriteTable, null, r.base, args, phase);
LimitedObjOrRef do writeReference(r.ref, o, phase)
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(r: ObjOrRef, phase: {run}): Object
case r of
Object do throw referenceError;
DotReference do return deleteProperty(r.base, r.propertyMultiname, phase);
return unaryDispatch(bracketDeleteTable, null, r.base, r.args, phase)
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(r: ObjOrRefOptionalLimit): Object
case r of
Object  LexicalReference do return null;
DotReference  BracketReference do return getObject(r.base);
end case
end proc;

Slots

proc findSlot(o: Object, id: InstanceVariable): Slot
o must be an Instance;
matchingSlots: Slot{}  {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(env: Environment): 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(env: Environment): Frame[]
i: Integer  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(env: Environment): Frame
regionalEnv: Frame[]  getRegionalEnvironment(env);
return regionalEnv[|regionalEnv| – 1]
end proc;
proc getPackageOrGlobalFrame(env: Environment): Package  Global
g: Frame  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 = {read, write, readWrite};
tag readNoWrite;
DefinitionAccess = {read, write, readWrite, readNoWrite};
VariableAccess = {readWrite, readNoWrite};
proc bindDefinition(env: Environment, id: String, a: CompoundAttribute, defaultMemberMod: MemberModifier, access: DefinitionAccess, makeStaticMember: ()  StaticMember, makeInstanceMember: ()  InstanceMember)
memberMod: MemberModifier  a.memberMod;
if memberMod = none then
if a.compile then memberMod  static else memberMod  defaultMemberMod end if
end if;
regionalEnv: Frame[]  getRegionalEnvironment(env);
innerFrame: Frame  regionalEnv[0];
otherFramesInRegion: Frame[]  regionalEnv[1 ...];
regionalFrame: Frame  regionalEnv[|regionalEnv| – 1];
namespaces: Namespace{}  a.namespaces;
c: ClassOpt  none;
if regionalFrame  Class then c  regionalFrame end if;
if namespaces = {} then namespaces  {publicNamespace} end if;
***** If in a class, consider overrides and adjust list of namespaces.
multiname: Multiname  {QualifiedNamenamespace: ns, id: id | 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 QualifiedNamenamespace: publicNamespace, id: dp.name  multiname) then
end if;
????
end proc;
proc defineHoistedVar(env: Environment, id: String)
qname: QualifiedName  QualifiedNamenamespace: publicNamespace, id: id;
regionalEnv: Frame[]  getRegionalEnvironment(env);
regionalFrame: Frame  regionalEnv[|regionalEnv| – 1];
env is either the Global frame or a FunctionFrame because hoisting only occurs into global or function scope.
existingBindings: StaticBinding{}  {b | b  regionalFrame.staticReadBindings  regionalFrame.staticWriteBindings such that b.qname = qname};
if existingBindings = {} then
if regionalFrame  Global and (some dp  regionalFrame.dynamicProperties satisfies dp.name = id) then
end if;
v: HoistedVar  new HoistedVarvalue: undefined;
newBindings: StaticBinding{}  {StaticBindingqname: qname, content: v, explicit: false};
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(template: BlockFrame): BlockFrame
????
end proc;

Adding Instance Definitions

tuple OverrideStatusPair
readStatus: OverrideStatus,
writeStatus: OverrideStatus
end tuple;
tag potentialConflict;
tuple OverrideStatus
overriddenMember: InstanceMember  {none, potentialConflict},
multiname: Multiname
end tuple;
proc searchForOverrides(c: Class, id: String, namespaces: Namespace{}, access: {read, write}): OverrideStatus
multiname: Multiname  {};
overriddenMember: InstanceMemberOpt  none;
s: ClassOpt  c.super;
for each ns  namespaces do
qname: QualifiedName  QualifiedNamenamespace: ns, id: id;
m: InstanceMemberOpt  findInstanceMember(s, qname, access);
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 OverrideStatusoverriddenMember: overriddenMember, multiname: multiname
end proc;
proc resolveOverrides(c: Class, cxt: Context, id: String, namespaces: Namespace{}, access: {read, write}, expectMethod: Boolean): OverrideStatus
if namespaces = {} then
os  searchForOverrides(c, id, cxt.openNamespaces, access);
if os.overriddenMember = none then
os  OverrideStatusoverriddenMember: none, multiname: {QualifiedNamenamespace: publicNamespace, id: id}
end if
else
definedMultiname: Multiname  {QualifiedNamenamespace: ns, id: id | ns  namespaces};
os2: OverrideStatus  searchForOverrides(c, id, namespaces, access);
if os2.overriddenMember = none then
os3: OverrideStatus  searchForOverrides(c, id, cxt.openNamespaces – namespaces, access);
if os3.overriddenMember = none then
os  OverrideStatusoverriddenMember: none, multiname: definedMultiname
else
os  OverrideStatusoverriddenMember: potentialConflict, multiname: definedMultiname
end if
else
os  OverrideStatusoverriddenMember: os2.overriddenMember, multiname: os2.multiname  definedMultiname
end if
end if;
instanceBindings: InstanceBinding{};
case access of
{read} do instanceBindings  c.instanceReadBindings;
{write} do instanceBindings  c.instanceWriteBindings
end case;
if some b  instanceBindings satisfies b.qname  os.multiname then
end if;
if expectMethod then
if os.overriddenMember  {none, potentialConflict}  InstanceMethod then
end if
else
if os.overriddenMember  {none, potentialConflict}  InstanceVariable  InstanceAccessor then
end if
end if;
return os
end proc;
proc defineInstanceMember(c: Class, cxt: Context, id: String, namespaces: Namespace{}, overrideMod: OverrideModifier, access: Access, m: InstanceMember): OverrideStatusPair
expectMethod: Boolean  m  InstanceMethod;
readStatus: OverrideStatus  access  {read, readWrite} ? resolveOverrides(c, cxt, id, namespaces, read, expectMethod) : OverrideStatusoverriddenMember: none, multiname: {};
writeStatus: OverrideStatus  access  {write, readWrite} ? resolveOverrides(c, cxt, id, namespaces, write, expectMethod) : OverrideStatusoverriddenMember: none, multiname: {};
if readStatus.overriddenMember  InstanceMember or writeStatus.overriddenMember  InstanceMember then
if overrideMod  {true, undefined} then throw definitionError end if
elsif readStatus.overriddenMember = potentialConflict or writeStatus.overriddenMember = potentialConflict then
if overrideMod  {false, undefined} then throw definitionError end if
else if overrideMod  {none, false, undefined} then throw definitionError end if
end if;
newReadBindings: InstanceBinding{}  {InstanceBindingqname: qname, content: m | qname  readStatus.multiname};
c.instanceReadBindings  c.instanceReadBindings  newReadBindings;
newWriteBindings: InstanceBinding{}  {InstanceBindingqname: qname, content: m | qname  writeStatus.multiname};
c.instanceWriteBindings  c.instanceWriteBindings  newWriteBindings;
return OverrideStatusPairreadStatus: readStatus, writeStatus: writeStatus
end proc;

Environmental Lookup

findThis(env, allowPrototypeThis) 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(env: Environment, allowPrototypeThis: Boolean): 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(env: Environment, multiname: Multiname, phase: Phase): Object
kind: LookupKind  LexicalLookupthis: findThis(env, false);
i: Integer  0;
while i < |env| do
frame: Frame  env[i];
result: ObjectOpt  readProperty(frame, multiname, kind, phase);
if result  none then return result end if;
i  i + 1
end while;
end proc;
proc lexicalWrite(env: Environment, multiname: Multiname, newValue: Object, createIfMissing: Boolean, phase: {run})
kind: LookupKind  LexicalLookupthis: findThis(env, false);
i: Integer  0;
while i < |env| do
frame: Frame  env[i];
result: {none, ok}  writeProperty(frame, multiname, kind, false, newValue, phase);
if result = ok then return end if;
i  i + 1
end while;
if createIfMissing then
g: Package  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: {none, ok}  writeProperty(g, multiname, kind, true, newValue, phase);
if result = ok then return end if
end if
end if;
end proc;
proc lexicalDelete(env: Environment, multiname: Multiname, phase: {run}): Boolean
????
end proc;

Property Lookup

tag propertyLookup;
tuple LexicalLookup
end tuple;
LookupKind = {propertyLookup}  LexicalLookup;
proc selectPublicName(multiname: Multiname): StringOpt
if some qname  multiname satisfies qname.namespace = publicNamespace then
return qname.id
end if;
return none
end proc;
proc findFlatMember(frame: Frame, multiname: Multiname, access: {read, write}, phase: Phase): StaticMemberOpt
bindings: StaticBinding{};
case access of
{read} do bindings  frame.staticReadBindings;
{write} do bindings  frame.staticWriteBindings
end case;
matchingBindings: StaticBinding{}  {b | b  bindings such that b.qname  multiname};
if matchingBindings = {} then return none end if;
matchingMembers: StaticMember{}  {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(c: ClassOpt, multiname: Multiname, access: {read, write}, phase: Phase): {none}  StaticMember  QualifiedName
s: ClassOpt  c;
while s  none do
staticBindings: StaticBinding{};
case access of
{read} do staticBindings  s.staticReadBindings;
{write} do staticBindings  s.staticWriteBindings
end case;
matchingStaticBindings: StaticBinding{}  {b | b  staticBindings such that b.qname  multiname};
Note that if the same member was found via several different bindings b, then it will appear only once in the set matchingStaticMembers.
matchingStaticMembers: StaticMember{}  {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.
instanceBindings: InstanceBinding{};
case access of
{read} do instanceBindings  s.instanceReadBindings;
{write} do instanceBindings  s.instanceWriteBindings
end case;
matchingInstanceBindings: InstanceBinding{}  {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.
matchingInstanceMembers: InstanceMember{}  {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.
b: InstanceBinding  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(c: Class, multiname: Multiname, access: {read, write}, phase: Phase): QualifiedNameOpt
Start from the root class (Object) and proceed through more specific classes that are ancestors of c.
for each s  ancestors(c) do
instanceBindings: InstanceBinding{};
case access of
{read} do instanceBindings  s.instanceReadBindings;
{write} do instanceBindings  s.instanceWriteBindings
end case;
matchingInstanceBindings: InstanceBinding{}  {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.
matchingInstanceMembers: InstanceMember{}  {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.
b: InstanceBinding  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(c: ClassOpt, qname: QualifiedNameOpt, access: {read, write}): InstanceMemberOpt
if qname = none then return none end if;
s: ClassOpt  c;
while s  none do
instanceBindings: InstanceBinding{};
case access of
{read} do instanceBindings  s.instanceReadBindings;
{write} do 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(container: ObjOptionalLimit  Frame, multiname: Multiname, kind: LookupKind, phase: Phase): ObjectOpt
case container of
Undefined  Null  Boolean  Float64  String  Namespace  CompoundAttribute  MethodClosure  Instance do
c: Class  objectType(container);
qname: QualifiedNameOpt  resolveInstanceMemberName(c, multiname, read, phase);
if qname = none and container  DynamicInstance then
return readDynamicProperty(container, multiname, kind, phase)
else return readInstanceMember(container, c, qname, phase)
end if;
SystemFrame  Global  Package  FunctionFrame  BlockFrame do
m: StaticMemberOpt  findFlatMember(container, multiname, read, phase);
if m = none and container  Global then
return readDynamicProperty(container, multiname, kind, phase)
else return readStaticMember(m, phase)
end if;
Class do
this: Object  {future, none, generic};
case kind of
{propertyLookup} do this  generic;
LexicalLookup do this  kind.this
end case;
m2: {none}  StaticMember  QualifiedName  findStaticMember(container, multiname, read, phase);
if m2  QualifiedName then return readStaticMember(m2, phase) end if;
case this of
{none} do throw propertyAccessError;
{future} do throw uninitialisedError;
{generic} do ????;
Object do return readInstanceMember(this, objectType(this), m2, phase)
end case;
Prototype do return readDynamicProperty(container, multiname, kind, phase);
superclass: ClassOpt  container.limit.super;
if superclass = none then return none end if;
qname: QualifiedNameOpt  resolveInstanceMemberName(superclass, multiname, read, phase);
return readInstanceMember(container.instance, superclass, qname, phase)
end case
end proc;
proc readInstanceMember(this: Object, c: Class, qname: QualifiedNameOpt, phase: Phase): ObjectOpt
m: InstanceMemberOpt  findInstanceMember(c, qname, read);
case m of
{none} do return none;
if phase = compile and not m.immutable then throw compileExpressionError
end if;
v: ObjectUninit  findSlot(this, m).value;
if v = uninitialised then throw uninitialisedError end if;
return v;
InstanceMethod do return MethodClosurethis: this, method: m;
code: Instance  {abstract}  m.code;
case code of
return code.call(this, ArgumentListpositional: [], named: {}, code.env, phase);
end case
end case
end proc;
proc readStaticMember(m: StaticMemberOpt, phase: Phase): ObjectOpt
case m of
{none} do return none;
Variable do return readVariable(m, phase);
HoistedVar do return m.value;
StaticMethod do return m.code;
code: Instance  m.code;
return code.call(null, ArgumentListpositional: [], named: {}, code.env, phase)
end case
end proc;
proc readDynamicProperty(container: DynamicObject, multiname: Multiname, kind: LookupKind, phase: Phase): ObjectOpt
name: StringOpt  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
parent: PrototypeOpt  container.parent;
if parent  none then return readDynamicProperty(parent, multiname, kind, phase)
end if
end if;
if kind = propertyLookup then return undefined end if;
return none
end proc;
proc readVariable(v: Variable, phase: Phase): Object
if phase = compile and not v.immutable then throw compileExpressionError end if;
value: ObjectUninitFut  v.value;
if value  {uninitialised, future} then throw uninitialisedError end if;
return value
end proc;

Writing a Property

proc writeProperty(container: ObjOptionalLimit  Frame, multiname: Multiname, kind: LookupKind, createIfMissing: Boolean, newValue: Object, phase: {run}): {none, ok}
case container of
Undefined  Null  Boolean  Float64  String  Namespace  CompoundAttribute  MethodClosure do
return none;
SystemFrame  Global  Package  FunctionFrame  BlockFrame do
m: StaticMemberOpt  findFlatMember(container, multiname, write, phase);
if m = none and container  Global then
return writeDynamicProperty(container, multiname, createIfMissing, newValue, phase)
else return writeStaticMember(m, newValue, phase)
end if;
Class do
this: ObjectFutOpt;
case kind of
{propertyLookup} do this  none;
LexicalLookup do this  kind.this
end case;
m2: {none}  StaticMember  QualifiedName  findStaticMember(container, multiname, write, phase);
if m2  QualifiedName then return writeStaticMember(m2, newValue, phase)
elsif this = none then throw propertyAccessError
elsif this = future then throw uninitialisedError
else return writeInstanceMember(this, objectType(this), m2, newValue, phase)
end if;
return writeDynamicProperty(container, multiname, createIfMissing, newValue, phase);
c: Class  objectType(container);
qname: QualifiedNameOpt  resolveInstanceMemberName(objectType(container), multiname, write, phase);
if qname = none and container  DynamicInstance then
return writeDynamicProperty(container, multiname, createIfMissing, newValue, phase)
else return writeInstanceMember(container, c, qname, newValue, phase)
end if;
superclass: ClassOpt  container.limit.super;
if superclass = none then return none end if;
qname: QualifiedNameOpt  resolveInstanceMemberName(superclass, multiname, write, phase);
return writeInstanceMember(container.instance, superclass, qname, newValue, phase)
end case
end proc;
proc writeInstanceMember(this: Object, c: Class, qname: QualifiedNameOpt, newValue: Object, phase: {run}): {none, ok}
m: InstanceMemberOpt  findInstanceMember(c, qname, write);
case m of
{none} do return none;
s: Slot  findSlot(this, m);
if m.immutable and s.value  uninitialised then throw propertyAccessError
end if;
coercedValue: Object  assignmentConversion(newValue, m.type);
s.value  coercedValue;
return ok;
coercedValue: Object  assignmentConversion(newValue, m.type);
code: Instance  {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(m: StaticMemberOpt, newValue: Object, phase: {run}): {none, ok}
case m of
{none} do return none;
{forbidden}  StaticMethod do throw propertyAccessError;
Variable do writeVariable(m, newValue, phase); return ok;
HoistedVar do m.value  newValue; return ok;
coercedValue: Object  assignmentConversion(newValue, m.type);
code: Instance  m.code;
code.call(null, ArgumentListpositional: [coercedValue], named: {}, code.env, phase);
return ok
end case
end proc;
proc writeDynamicProperty(container: DynamicObject, multiname: Multiname, createIfMissing: Boolean, newValue: Object, phase: {run}): {none, ok}
name: StringOpt  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), multiname, read, phase);
Global do m  findFlatMember(container, multiname, read, phase)
end case;
if m  none then return none end if;
container.dynamicProperties  container.dynamicProperties  {new DynamicPropertyname: name, value: newValue};
return ok
end proc;
proc writeVariable(v: Variable, newValue: Object, phase: {run})
type: Class  v.type;
if v.value = future then throw uninitialisedError end if;
if v.immutable and v.value  uninitialised then throw propertyAccessError end if;
coercedValue: Object  assignmentConversion(newValue, type);
v.value  coercedValue
end proc;

Deleting a Property

proc deleteProperty(o: ObjOptionalLimit, multiname: Multiname, phase: {run}): Boolean
????
end proc;
proc deleteQualifiedProperty(o: Object, name: String, ns: Namespace, kind: LookupKind, phase: {run}): Boolean
????
end proc;

Operator Dispatch

Unary Operators

unaryDispatch(table, this, operand, args, phase) 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(table: UnaryMethod{}, this: Object, operand: ObjOptionalLimit, args: ArgumentList, phase: Phase): Object
applicableOps: UnaryMethod{}  {m | m  table such that limitedHasType(operand, m.operandType)};
if some best  applicableOps satisfies (every m2  applicableOps satisfies isAncestor(m2.operandType, best.operandType)) then
return best.f(this, getObject(operand), args, phase)
end if;
end proc;
limitedHasType(o, c) 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(o: ObjOptionalLimit, c: Class): Boolean
a: Object  getObject(o);
limit: ClassOpt  getObjectLimit(o);
if hasType(a, c) then
if limit = none then return true else return isProperAncestor(c, limit) end if
else return false
end if
end proc;

Binary Operators

isBinaryDescendant(m1, m2) is true if m1 is at least as specific as m2 as defined by the procedure below.
proc isBinaryDescendant(m1: BinaryMethod, m2: BinaryMethod): Boolean
return isAncestor(m2.leftType, m1.leftType) and isAncestor(m2.rightType, m1.rightType)
end proc;
binaryDispatch(table, left, right, phase) 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(table: BinaryMethod{}, left: ObjOptionalLimit, right: ObjOptionalLimit, phase: Phase): Object
applicableOps: BinaryMethod{}  {m | m  table such that limitedHasType(left, m.leftType) and limitedHasType(right, m.rightType)};
if some best  applicableOps satisfies (every m2  applicableOps satisfies isBinaryDescendant(best, m2)) then
return best.f(getObject(left), getObject(right), phase)
end if;
end proc;

Deferred Validation

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

Expressions

Syntax

  {allowIn, noIn}

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] (cxt: Context, env: Environment): Namespace
[Qualifier  Identifier] do
multiname: Multiname  {QualifiedNamenamespace: ns, id: Name[Identifier] | ns  cxt.openNamespaces};
a: Object  lexicalRead(env, multiname, compile);
if a  Namespace then throw badValueError end if;
return a;
[Qualifier  public] do return publicNamespace;
[Qualifier  private] do
c: ClassOpt  getEnclosingClass(env);
if c = none then throw syntaxError end if;
end proc;
Multiname[SimpleQualifiedIdentifier]: Multiname;
proc Validate[SimpleQualifiedIdentifier] (cxt: Context, env: Environment)
[SimpleQualifiedIdentifier  Identifier] do
multiname: Multiname  {QualifiedNamenamespace: ns, id: Name[Identifier] | ns  cxt.openNamespaces};
Multiname[SimpleQualifiedIdentifier]  multiname;
[SimpleQualifiedIdentifier  Qualifier :: Identifier] do
q: Namespace  Validate[Qualifier](cxt, env);
Multiname[SimpleQualifiedIdentifier]  {QualifiedNamenamespace: q, id: Name[Identifier]}
end proc;
Multiname[ExpressionQualifiedIdentifier]: Multiname;
proc Validate[ExpressionQualifiedIdentifier  ParenExpression :: Identifier] (cxt: Context, env: Environment)
Validate[ParenExpression](cxt, env);
r: ObjOrRef  Eval[ParenExpression](env, compile);
q: Object  readReference(r, compile);
if q  Namespace then throw badValueError end if;
Multiname[ExpressionQualifiedIdentifier]  {QualifiedNamenamespace: q, id: Name[Identifier]}
end proc;
Multiname[QualifiedIdentifier]: Multiname;
proc Validate[QualifiedIdentifier] (cxt: Context, env: Environment)
[QualifiedIdentifier  SimpleQualifiedIdentifier] do
Validate[SimpleQualifiedIdentifier](cxt, env);
Multiname[QualifiedIdentifier]  Multiname[SimpleQualifiedIdentifier];
[QualifiedIdentifier  ExpressionQualifiedIdentifier] do
Validate[ExpressionQualifiedIdentifier](cxt, env);
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] (cxt: Context, env: Environment)
[UnitExpression  ParenListExpression] do Validate[ParenListExpression](cxt, env);
[UnitExpression  Number [no line break] String] do ????;
[UnitExpression  UnitExpression [no line break] String] do ????
end proc;

Evaluation

proc Eval[UnitExpression] (env: Environment, phase: Phase): ObjOrRef
[UnitExpression  ParenListExpression] do
return Eval[ParenListExpression](env, phase);
[UnitExpression  Number [no line break] String] do ????;
[UnitExpression  UnitExpression [no line break] String] do ????
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] (cxt: Context, env: Environment)
[PrimaryExpression  null] do nothing;
[PrimaryExpression  true] do nothing;
[PrimaryExpression  false] do nothing;
[PrimaryExpression  public] do nothing;
[PrimaryExpression  Number] do nothing;
[PrimaryExpression  String] do nothing;
[PrimaryExpression  this] do
if findThis(env, true) = none then throw syntaxError end if;
[PrimaryExpression  RegularExpression] do nothing;
[PrimaryExpression  UnitExpression] do Validate[UnitExpression](cxt, env);
[PrimaryExpression  ArrayLiteral] do ????;
[PrimaryExpression  ObjectLiteral] do ????;
[PrimaryExpression  FunctionExpression] do Validate[FunctionExpression](cxt, env)
end proc;
Validate[ParenExpression  ( AssignmentExpressionallowIn )]: Context  Environment  () = Validate[AssignmentExpressionallowIn];
proc Validate[ParenListExpression] (cxt: Context, env: Environment)
[ParenListExpression  ParenExpression] do Validate[ParenExpression](cxt, env);
[ParenListExpression  ( ListExpressionallowIn , AssignmentExpressionallowIn )] do
Validate[ListExpressionallowIn](cxt, env);
Validate[AssignmentExpressionallowIn](cxt, env)
end proc;

Evaluation

proc Eval[PrimaryExpression] (env: Environment, phase: Phase): ObjOrRef
[PrimaryExpression  null] do return null;
[PrimaryExpression  true] do return true;
[PrimaryExpression  false] do return false;
[PrimaryExpression  public] do return publicNamespace;
[PrimaryExpression  Number] do return Value[Number];
[PrimaryExpression  String] do return Value[String];
[PrimaryExpression  this] do
this: ObjectFutOpt  findThis(env, true);
Note that Validate ensured that this cannot be none at this point.
if this = future then throw uninitialisedError end if;
return this;
[PrimaryExpression  RegularExpression] do ????;
[PrimaryExpression  UnitExpression] do return Eval[UnitExpression](env, phase);
[PrimaryExpression  ArrayLiteral] do ????;
[PrimaryExpression  ObjectLiteral] do ????;
[PrimaryExpression  FunctionExpression] do
return Eval[FunctionExpression](env, phase)
end proc;
Eval[ParenExpression  ( AssignmentExpressionallowIn )]: Environment  Phase  ObjOrRef = Eval[AssignmentExpressionallowIn];
proc Eval[ParenListExpression] (env: Environment, phase: Phase): ObjOrRef
[ParenListExpression  ParenExpression] do return Eval[ParenExpression](env, phase);
[ParenListExpression  ( ListExpressionallowIn , AssignmentExpressionallowIn )] do
ra: ObjOrRef  Eval[ListExpressionallowIn](env, phase);
readReference(ra, phase);
rb: ObjOrRef  Eval[AssignmentExpressionallowIn](env, phase);
return readReference(rb, phase)
end proc;
proc EvalAsList[ParenListExpression] (env: Environment, phase: Phase): Object[]
[ParenListExpression  ParenExpression] do
r: ObjOrRef  Eval[ParenExpression](env, phase);
elt: Object  readReference(r, phase);
return [elt];
[ParenListExpression  ( ListExpressionallowIn , AssignmentExpressionallowIn )] do
elts: Object[]  EvalAsList[ListExpressionallowIn](env, phase);
r: ObjOrRef  Eval[AssignmentExpressionallowIn](env, phase);
elt: Object  readReference(r, phase);
return elts  [elt]
end proc;

Function Expressions

Syntax

FunctionExpression 
   function FunctionSignature Block
|  function Identifier FunctionSignature Block

Validation

proc Validate[FunctionExpression] (cxt: Context, env: Environment)
[FunctionExpression  function FunctionSignature Block] do ????;
[FunctionExpression  function Identifier FunctionSignature Block] do ????
end proc;

Evaluation

proc Eval[FunctionExpression] (env: Environment, phase: Phase): ObjOrRef
[FunctionExpression  function FunctionSignature Block] do ????;
[FunctionExpression  function Identifier FunctionSignature Block] do ????
end proc;

Object Literals

Syntax

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

Validation

proc Validate[LiteralField  FieldName : AssignmentExpressionallowIn] (cxt: Context, env: Environment): String{}
names: String{}  Validate[FieldName](cxt, env);
Validate[AssignmentExpressionallowIn](cxt, env);
return names
end proc;
proc Validate[FieldName] (cxt: Context, env: Environment): String{}
[FieldName  Identifier] do return {Name[Identifier]};
[FieldName  String] do return {Value[String]};
[FieldName  Number] do ????;
[FieldName  ParenExpression] do ????
end proc;

Evaluation

proc Eval[LiteralField  FieldName : AssignmentExpressionallowIn] (env: Environment, phase: Phase): NamedArgument
name: String  Eval[FieldName](env, phase);
r: ObjOrRef  Eval[AssignmentExpressionallowIn](env, phase);
value: Object  readReference(r, phase);
return NamedArgumentname: name, value: value
end proc;
proc Eval[FieldName] (env: Environment, phase: Phase): String
[FieldName  Identifier] do return Name[Identifier];
[FieldName  String] do return Value[String];
[FieldName  Number] do ????;
[FieldName  ParenExpression] do ????
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] (cxt: Context, env: Environment)
[SuperExpression  super] do
if getEnclosingClass(env) = none or findThis(env, false) = none then
end if;
[SuperExpression  FullSuperExpression] do Validate[FullSuperExpression](cxt, env)
end proc;
proc Validate[FullSuperExpression  super ParenExpression] (cxt: Context, env: Environment)
if getEnclosingClass(env) = none then throw syntaxError end if;
Validate[ParenExpression](cxt, env)
end proc;

Evaluation

proc Eval[SuperExpression] (env: Environment, phase: Phase): ObjOrRefOptionalLimit
[SuperExpression  super] do
this: ObjectFutOpt  findThis(env, false);
Note that Validate ensured that this cannot be none at this point.
if this = future then throw uninitialisedError end if;
limit: ClassOpt  getEnclosingClass(env);
Note that Validate ensured that limit cannot be none at this point.
return LimitedObjOrRefref: this, limit: limit;
[SuperExpression  FullSuperExpression] do
return Eval[FullSuperExpression](env, phase)
end proc;
proc Eval[FullSuperExpression  super ParenExpression] (env: Environment, phase: Phase): ObjOrRefOptionalLimit
r: ObjOrRef  Eval[ParenExpression](env, phase);
limit: ClassOpt  getEnclosingClass(env);
Note that Validate ensured that limit cannot be none at this point.
return LimitedObjOrRefref: r, limit: limit
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] (cxt: Context, env: Environment)
[AttributeExpression  SimpleQualifiedIdentifier] do
Validate[SimpleQualifiedIdentifier](cxt, env);
Context[AttributeExpression]  cxt;
[AttributeExpression0  AttributeExpression1 MemberOperator] do
Validate[AttributeExpression1](cxt, env);
Validate[MemberOperator](cxt, env);
[AttributeExpression0  AttributeExpression1 Arguments] do
Validate[AttributeExpression1](cxt, env);
Validate[Arguments](cxt, env)
end proc;
Context[FullPostfixExpression]: Context;
proc Validate[FullPostfixExpression] (cxt: Context, env: Environment)
[FullPostfixExpression  PrimaryExpression] do
Validate[PrimaryExpression](cxt, env);
Validate[ExpressionQualifiedIdentifier](cxt, env);
Context[FullPostfixExpression]  cxt;
[FullPostfixExpression  FullNewExpression] do
Validate[FullNewExpression](cxt, env);
Validate[FullPostfixExpression1](cxt, env);
Validate[MemberOperator](cxt, env);
[FullPostfixExpression  SuperExpression DotOperator] do
Validate[SuperExpression](cxt, env);
Validate[DotOperator](cxt, env);
[FullPostfixExpression0  FullPostfixExpression1 Arguments] do
Validate[FullPostfixExpression1](cxt, env);
Validate[Arguments](cxt, env);
[FullPostfixExpression  FullSuperExpression Arguments] do
Validate[FullSuperExpression](cxt, env);
Validate[Arguments](cxt, env);
[FullPostfixExpression  PostfixExpressionOrSuper [no line break] ++] do
Validate[PostfixExpressionOrSuper](cxt, env);
[FullPostfixExpression  PostfixExpressionOrSuper [no line break] --] do
Validate[PostfixExpressionOrSuper](cxt, env)
end proc;
proc Validate[FullNewExpression] (cxt: Context, env: Environment)
[FullNewExpression  new FullNewSubexpression Arguments] do
Validate[FullNewSubexpression](cxt, env);
Validate[Arguments](cxt, env);
[FullNewExpression  new FullSuperExpression Arguments] do
Validate[FullSuperExpression](cxt, env);
Validate[Arguments](cxt, env)
end proc;
Context[FullNewSubexpression]: Context;
proc Validate[FullNewSubexpression] (cxt: Context, env: Environment)
[FullNewSubexpression  PrimaryExpression] do Validate[PrimaryExpression](cxt, env);
[FullNewSubexpression  QualifiedIdentifier] do
Validate[QualifiedIdentifier](cxt, env);
Context[FullNewSubexpression]  cxt;
[FullNewSubexpression  FullNewExpression] do Validate[FullNewExpression](cxt, env);
[FullNewSubexpression0  FullNewSubexpression1 MemberOperator] do
Validate[FullNewSubexpression1](cxt, env);
Validate[MemberOperator](cxt, env);
[FullNewSubexpression  SuperExpression DotOperator] do
Validate[SuperExpression](cxt, env);
Validate[DotOperator](cxt, env)
end proc;
proc Validate[ShortNewExpression] (cxt: Context, env: Environment)
[ShortNewExpression  new ShortNewSubexpression] do
Validate[ShortNewSubexpression](cxt, env);
[ShortNewExpression  new SuperExpression] do Validate[SuperExpression](cxt, env)
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] (env: Environment, phase: Phase): ObjOrRef
[AttributeExpression  SimpleQualifiedIdentifier] do
return LexicalReferenceenv: env, variableMultiname: Multiname[SimpleQualifiedIdentifier], cxt: Context[AttributeExpression];
[AttributeExpression0  AttributeExpression1 MemberOperator] do
r: ObjOrRef  Eval[AttributeExpression1](env, phase);
a: Object  readReference(r, phase);
return Eval[MemberOperator](env, a, phase);
[AttributeExpression0  AttributeExpression1 Arguments] do
r: ObjOrRef  Eval[AttributeExpression1](env, phase);
f: Object  readReference(r, phase);
base: Object  referenceBase(r);
args: ArgumentList  Eval[Arguments](env, phase);
return unaryDispatch(callTable, base, f, args, phase)
end proc;
proc Eval[FullPostfixExpression] (env: Environment, phase: Phase): ObjOrRef
[FullPostfixExpression  PrimaryExpression] do
return Eval[PrimaryExpression](env, phase);
return LexicalReferenceenv: env, variableMultiname: Multiname[ExpressionQualifiedIdentifier], cxt: Context[FullPostfixExpression];
[FullPostfixExpression  FullNewExpression] do
return Eval[FullNewExpression](env, phase);
r: ObjOrRef  Eval[FullPostfixExpression1](env, phase);
a: Object  readReference(r, phase);
return Eval[MemberOperator](env, a, phase);
[FullPostfixExpression  SuperExpression DotOperator] do
r: ObjOrRefOptionalLimit  Eval[SuperExpression](env, phase);
a: ObjOptionalLimit  readRefWithLimit(r, phase);
return Eval[DotOperator](env, a, phase);
[FullPostfixExpression0  FullPostfixExpression1 Arguments] do
r: ObjOrRef  Eval[FullPostfixExpression1](env, phase);
f: Object  readReference(r, phase);
base: Object  referenceBase(r);
args: ArgumentList  Eval[Arguments](env, phase);
return unaryDispatch(callTable, base, f, args, phase);
[FullPostfixExpression  FullSuperExpression Arguments] do
r: ObjOrRefOptionalLimit  Eval[FullSuperExpression](env, phase);
f: ObjOptionalLimit  readRefWithLimit(r, phase);
base: Object  referenceBase(r);
args: ArgumentList  Eval[Arguments](env, phase);
return unaryDispatch(callTable, base, f, args, phase);
[FullPostfixExpression  PostfixExpressionOrSuper [no line break] ++] do
if phase = compile then throw compileExpressionError end if;
r: ObjOrRefOptionalLimit  Eval[PostfixExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(r, phase);
b: Object  unaryDispatch(incrementTable, null, a, ArgumentListpositional: [], named: {}, phase);
writeReference(r, b, phase);
return getObject(a);
[FullPostfixExpression  PostfixExpressionOrSuper [no line break] --] do
if phase = compile then throw compileExpressionError end if;
r: ObjOrRefOptionalLimit  Eval[PostfixExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(r, phase);
b: Object  unaryDispatch(decrementTable, null, a, ArgumentListpositional: [], named: {}, phase);
writeReference(r, b, phase);
return getObject(a)
end proc;
proc Eval[FullNewExpression] (env: Environment, phase: Phase): ObjOrRef
[FullNewExpression  new FullNewSubexpression Arguments] do
r: ObjOrRef  Eval[FullNewSubexpression](env, phase);
f: Object  readReference(r, phase);
args: ArgumentList  Eval[Arguments](env, phase);
return unaryDispatch(constructTable, null, f, args, phase);
[FullNewExpression  new FullSuperExpression Arguments] do
r: ObjOrRefOptionalLimit  Eval[FullSuperExpression](env, phase);
f: ObjOptionalLimit  readRefWithLimit(r, phase);
args: ArgumentList  Eval[Arguments](env, phase);
return unaryDispatch(constructTable, null, f, args, phase)
end proc;
proc Eval[FullNewSubexpression] (env: Environment, phase: Phase): ObjOrRef
[FullNewSubexpression  PrimaryExpression] do
return Eval[PrimaryExpression](env, phase);
[FullNewSubexpression  QualifiedIdentifier] do
return LexicalReferenceenv: env, variableMultiname: Multiname[QualifiedIdentifier], cxt: Context[FullNewSubexpression];
[FullNewSubexpression  FullNewExpression] do
return Eval[FullNewExpression](env, phase);
[FullNewSubexpression0  FullNewSubexpression1 MemberOperator] do
r: ObjOrRef  Eval[FullNewSubexpression1](env, phase);
a: Object  readReference(r, phase);
return Eval[MemberOperator](env, a, phase);
[FullNewSubexpression  SuperExpression DotOperator] do
r: ObjOrRefOptionalLimit  Eval[SuperExpression](env, phase);
a: ObjOptionalLimit  readRefWithLimit(r, phase);
return Eval[DotOperator](env, a, phase)
end proc;
proc Eval[ShortNewExpression] (env: Environment, phase: Phase): ObjOrRef
[ShortNewExpression  new ShortNewSubexpression] do
r: ObjOrRef  Eval[ShortNewSubexpression](env, phase);
f: Object  readReference(r, phase);
return unaryDispatch(constructTable, null, f, ArgumentListpositional: [], named: {}, phase);
[ShortNewExpression  new SuperExpression] do
r: ObjOrRefOptionalLimit  Eval[SuperExpression](env, phase);
f: ObjOptionalLimit  readRefWithLimit(r, phase);
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] (cxt: Context, env: Environment)
[MemberOperator  DotOperator] do Validate[DotOperator](cxt, env);
[MemberOperator  . ParenExpression] do Validate[ParenExpression](cxt, env)
end proc;
proc Validate[DotOperator] (cxt: Context, env: Environment)
[DotOperator  . QualifiedIdentifier] do Validate[QualifiedIdentifier](cxt, env);
[DotOperator  Brackets] do Validate[Brackets](cxt, env)
end proc;
proc Validate[Brackets] (cxt: Context, env: Environment)
[Brackets  [ ]] do nothing;
[Brackets  [ ListExpressionallowIn ]] do Validate[ListExpressionallowIn](cxt, env);
[Brackets  [ NamedArgumentList ]] do Validate[NamedArgumentList](cxt, env)
end proc;
proc Validate[Arguments] (cxt: Context, env: Environment)
[Arguments  ParenExpressions] do Validate[ParenExpressions](cxt, env);
[Arguments  ( NamedArgumentList )] do Validate[NamedArgumentList](cxt, env)
end proc;
proc Validate[ParenExpressions] (cxt: Context, env: Environment)
[ParenExpressions  ( )] do nothing;
[ParenExpressions  ParenListExpression] do Validate[ParenListExpression](cxt, env)
end proc;
proc Validate[NamedArgumentList] (cxt: Context, env: Environment): String{}
[NamedArgumentList  LiteralField] do return Validate[LiteralField](cxt, env);
[NamedArgumentList  ListExpressionallowIn , LiteralField] do
Validate[ListExpressionallowIn](cxt, env);
return Validate[LiteralField](cxt, env);
[NamedArgumentList0  NamedArgumentList1 , LiteralField] do
names1: String{}  Validate[NamedArgumentList1](cxt, env);
names2: String{}  Validate[LiteralField](cxt, env);
if names1  names2  {} then throw syntaxError end if;
return names1  names2
end proc;

Evaluation

proc Eval[MemberOperator] (env: Environment, base: Object, phase: Phase): ObjOrRef
[MemberOperator  DotOperator] do return Eval[DotOperator](env, base, phase);
[MemberOperator  . ParenExpression] do ????
end proc;
proc Eval[DotOperator] (env: Environment, base: ObjOptionalLimit, phase: Phase): ObjOrRef
[DotOperator  . QualifiedIdentifier] do
return DotReferencebase: base, propertyMultiname: Multiname[QualifiedIdentifier];
[DotOperator  Brackets] do
args: ArgumentList  Eval[Brackets](env, phase);
return BracketReferencebase: base, args: args
end proc;
proc Eval[Brackets] (env: Environment, phase: Phase): ArgumentList
[Brackets  [ ]] do return ArgumentListpositional: [], named: {};
[Brackets  [ ListExpressionallowIn ]] do
positional: Object[]  EvalAsList[ListExpressionallowIn](env, phase);
return ArgumentListpositional: positional, named: {};
[Brackets  [ NamedArgumentList ]] do return Eval[NamedArgumentList](env, phase)
end proc;
proc Eval[Arguments] (env: Environment, phase: Phase): ArgumentList
[Arguments  ParenExpressions] do return Eval[ParenExpressions](env, phase);
[Arguments  ( NamedArgumentList )] do return Eval[NamedArgumentList](env, phase)
end proc;
proc Eval[ParenExpressions] (env: Environment, phase: Phase): ArgumentList
[ParenExpressions  ( )] do return ArgumentListpositional: [], named: {};
[ParenExpressions  ParenListExpression] do
positional: Object[]  EvalAsList[ParenListExpression](env, phase);
return ArgumentListpositional: positional, named: {}
end proc;
proc Eval[NamedArgumentList] (env: Environment, phase: Phase): ArgumentList
[NamedArgumentList  LiteralField] do
na: NamedArgument  Eval[LiteralField](env, phase);
return ArgumentListpositional: [], named: {na};
[NamedArgumentList  ListExpressionallowIn , LiteralField] do
positional: Object[]  EvalAsList[ListExpressionallowIn](env, phase);
na: NamedArgument  Eval[LiteralField](env, phase);
return ArgumentListpositional: positional, named: {na};
[NamedArgumentList0  NamedArgumentList1 , LiteralField] do
args: ArgumentList  Eval[NamedArgumentList1](env, phase);
na: NamedArgument  Eval[LiteralField](env, phase);
if some na2  args.named satisfies na2.name = na.name then
end if;
return ArgumentListpositional: args.positional, named: args.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] (cxt: Context, env: Environment)
[UnaryExpression  PostfixExpression] do Validate[PostfixExpression](cxt, env);
[UnaryExpression  delete PostfixExpression] do
Validate[PostfixExpression](cxt, env);
[UnaryExpression0  void UnaryExpression1] do Validate[UnaryExpression1](cxt, env);
[UnaryExpression0  typeof UnaryExpression1] do
Validate[UnaryExpression1](cxt, env);
[UnaryExpression  ++ PostfixExpressionOrSuper] do
Validate[PostfixExpressionOrSuper](cxt, env);
[UnaryExpression  -- PostfixExpressionOrSuper] do
Validate[PostfixExpressionOrSuper](cxt, env);
[UnaryExpression  + UnaryExpressionOrSuper] do
Validate[UnaryExpressionOrSuper](cxt, env);
[UnaryExpression  - UnaryExpressionOrSuper] do
Validate[UnaryExpressionOrSuper](cxt, env);
[UnaryExpression  ~ UnaryExpressionOrSuper] do
Validate[UnaryExpressionOrSuper](cxt, env);
[UnaryExpression0  ! UnaryExpression1] do Validate[UnaryExpression1](cxt, env)
end proc;
Validate[UnaryExpressionOrSuper]: Context  Environment  ();
Validate[UnaryExpressionOrSuper  UnaryExpression] = Validate[UnaryExpression];
Validate[UnaryExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[UnaryExpression] (env: Environment, phase: Phase): ObjOrRef
[UnaryExpression  PostfixExpression] do return Eval[PostfixExpression](env, phase);
[UnaryExpression  delete PostfixExpression] do
if phase = compile then throw compileExpressionError end if;
r: ObjOrRef  Eval[PostfixExpression](env, phase);
return deleteReference(r, phase);
[UnaryExpression0  void UnaryExpression1] do
r: ObjOrRef  Eval[UnaryExpression1](env, phase);
readReference(r, phase);
return undefined;
[UnaryExpression0  typeof UnaryExpression1] do
r: ObjOrRef  Eval[UnaryExpression1](env, phase);
a: Object  readReference(r, phase);
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  ++ PostfixExpressionOrSuper] do
if phase = compile then throw compileExpressionError end if;
r: ObjOrRefOptionalLimit  Eval[PostfixExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(r, phase);
b: Object  unaryDispatch(incrementTable, null, a, ArgumentListpositional: [], named: {}, phase);
writeReference(r, b, phase);
return b;
[UnaryExpression  -- PostfixExpressionOrSuper] do
if phase = compile then throw compileExpressionError end if;
r: ObjOrRefOptionalLimit  Eval[PostfixExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(r, phase);
b: Object  unaryDispatch(decrementTable, null, a, ArgumentListpositional: [], named: {}, phase);
writeReference(r, b, phase);
return b;
[UnaryExpression  + UnaryExpressionOrSuper] do
r: ObjOrRefOptionalLimit  Eval[UnaryExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(r, phase);
return unaryPlus(a, phase);
[UnaryExpression  - UnaryExpressionOrSuper] do
r: ObjOrRefOptionalLimit  Eval[UnaryExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(r, phase);
return unaryDispatch(minusTable, null, a, ArgumentListpositional: [], named: {}, phase);
[UnaryExpression  ~ UnaryExpressionOrSuper] do
r: ObjOrRefOptionalLimit  Eval[UnaryExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(r, phase);
return unaryDispatch(bitwiseNotTable, null, a, ArgumentListpositional: [], named: {}, phase);
[UnaryExpression0  ! UnaryExpression1] do
r: ObjOrRef  Eval[UnaryExpression1](env, phase);
a: Object  readReference(r, phase);
return unaryNot(a, phase)
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] (cxt: Context, env: Environment)
[MultiplicativeExpression  UnaryExpression] do Validate[UnaryExpression](cxt, env);
Validate[MultiplicativeExpressionOrSuper](cxt, env);
Validate[UnaryExpressionOrSuper](cxt, env);
Validate[MultiplicativeExpressionOrSuper](cxt, env);
Validate[UnaryExpressionOrSuper](cxt, env);
Validate[MultiplicativeExpressionOrSuper](cxt, env);
Validate[UnaryExpressionOrSuper](cxt, env)
end proc;
Validate[MultiplicativeExpressionOrSuper]: Context  Environment  ();
Validate[MultiplicativeExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[MultiplicativeExpression] (env: Environment, phase: Phase): ObjOrRef
[MultiplicativeExpression  UnaryExpression] do
return Eval[UnaryExpression](env, phase);
ra: ObjOrRefOptionalLimit  Eval[MultiplicativeExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[UnaryExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(multiplyTable, a, b, phase);
ra: ObjOrRefOptionalLimit  Eval[MultiplicativeExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[UnaryExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(divideTable, a, b, phase);
ra: ObjOrRefOptionalLimit  Eval[MultiplicativeExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[UnaryExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(remainderTable, a, b, phase)
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] (cxt: Context, env: Environment)
[AdditiveExpression  MultiplicativeExpression] do
Validate[MultiplicativeExpression](cxt, env);
Validate[AdditiveExpressionOrSuper](cxt, env);
Validate[MultiplicativeExpressionOrSuper](cxt, env);
Validate[AdditiveExpressionOrSuper](cxt, env);
Validate[MultiplicativeExpressionOrSuper](cxt, env)
end proc;
Validate[AdditiveExpressionOrSuper]: Context  Environment  ();
Validate[AdditiveExpressionOrSuper  AdditiveExpression] = Validate[AdditiveExpression];
Validate[AdditiveExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[AdditiveExpression] (env: Environment, phase: Phase): ObjOrRef
[AdditiveExpression  MultiplicativeExpression] do
return Eval[MultiplicativeExpression](env, phase);
ra: ObjOrRefOptionalLimit  Eval[AdditiveExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[MultiplicativeExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(addTable, a, b, phase);
ra: ObjOrRefOptionalLimit  Eval[AdditiveExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[MultiplicativeExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(subtractTable, a, b, phase)
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] (cxt: Context, env: Environment)
[ShiftExpression  AdditiveExpression] do Validate[AdditiveExpression](cxt, env);
Validate[ShiftExpressionOrSuper](cxt, env);
Validate[AdditiveExpressionOrSuper](cxt, env);
Validate[ShiftExpressionOrSuper](cxt, env);
Validate[AdditiveExpressionOrSuper](cxt, env);
Validate[ShiftExpressionOrSuper](cxt, env);
Validate[AdditiveExpressionOrSuper](cxt, env)
end proc;
Validate[ShiftExpressionOrSuper]: Context  Environment  ();
Validate[ShiftExpressionOrSuper  ShiftExpression] = Validate[ShiftExpression];
Validate[ShiftExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[ShiftExpression] (env: Environment, phase: Phase): ObjOrRef
[ShiftExpression  AdditiveExpression] do
return Eval[AdditiveExpression](env, phase);
ra: ObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[AdditiveExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(shiftLeftTable, a, b, phase);
ra: ObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[AdditiveExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(shiftRightTable, a, b, phase);
ra: ObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[AdditiveExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(shiftRightUnsignedTable, a, b, phase)
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] (cxt: Context, env: Environment)
[RelationalExpression  ShiftExpression] do Validate[ShiftExpression](cxt, env);
[RelationalExpression  RelationalExpressionOrSuper < ShiftExpressionOrSuper] do
Validate[RelationalExpressionOrSuper](cxt, env);
Validate[ShiftExpressionOrSuper](cxt, env);
[RelationalExpression  RelationalExpressionOrSuper > ShiftExpressionOrSuper] do
Validate[RelationalExpressionOrSuper](cxt, env);
Validate[ShiftExpressionOrSuper](cxt, env);
[RelationalExpression  RelationalExpressionOrSuper <= ShiftExpressionOrSuper] do
Validate[RelationalExpressionOrSuper](cxt, env);
Validate[ShiftExpressionOrSuper](cxt, env);
[RelationalExpression  RelationalExpressionOrSuper >= ShiftExpressionOrSuper] do
Validate[RelationalExpressionOrSuper](cxt, env);
Validate[ShiftExpressionOrSuper](cxt, env);
[RelationalExpression0  RelationalExpression1 is ShiftExpression] do
Validate[RelationalExpression1](cxt, env);
Validate[ShiftExpression](cxt, env);
[RelationalExpression0  RelationalExpression1 as ShiftExpression] do
Validate[RelationalExpression1](cxt, env);
Validate[ShiftExpression](cxt, env);
[RelationalExpressionallowIn0  RelationalExpressionallowIn1 in ShiftExpressionOrSuper] do
Validate[RelationalExpressionallowIn1](cxt, env);
Validate[ShiftExpressionOrSuper](cxt, env);
[RelationalExpression0  RelationalExpression1 instanceof ShiftExpression] do
Validate[RelationalExpression1](cxt, env);
Validate[ShiftExpression](cxt, env)
end proc;
Validate[RelationalExpressionOrSuper]: Context  Environment  ();
Validate[RelationalExpressionOrSuper  RelationalExpression] = Validate[RelationalExpression];
Validate[RelationalExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[RelationalExpression] (env: Environment, phase: Phase): ObjOrRef
[RelationalExpression  ShiftExpression] do
return Eval[ShiftExpression](env, phase);
[RelationalExpression  RelationalExpressionOrSuper < ShiftExpressionOrSuper] do
ra: ObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(lessTable, a, b, phase);
[RelationalExpression  RelationalExpressionOrSuper > ShiftExpressionOrSuper] do
ra: ObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(lessTable, b, a, phase);
[RelationalExpression  RelationalExpressionOrSuper <= ShiftExpressionOrSuper] do
ra: ObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(lessOrEqualTable, a, b, phase);
[RelationalExpression  RelationalExpressionOrSuper >= ShiftExpressionOrSuper] do
ra: ObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[ShiftExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(lessOrEqualTable, b, a, phase);
[RelationalExpression  RelationalExpression is ShiftExpression] do ????;
[RelationalExpression  RelationalExpression as ShiftExpression] do ????;
[RelationalExpressionallowIn  RelationalExpressionallowIn in ShiftExpressionOrSuper] do
????;
[RelationalExpression  RelationalExpression instanceof ShiftExpression] do ????
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] (cxt: Context, env: Environment)
[EqualityExpression  RelationalExpression] do
Validate[RelationalExpression](cxt, env);
[EqualityExpression  EqualityExpressionOrSuper == RelationalExpressionOrSuper] do
Validate[EqualityExpressionOrSuper](cxt, env);
Validate[RelationalExpressionOrSuper](cxt, env);
[EqualityExpression  EqualityExpressionOrSuper != RelationalExpressionOrSuper] do
Validate[EqualityExpressionOrSuper](cxt, env);
Validate[RelationalExpressionOrSuper](cxt, env);
[EqualityExpression  EqualityExpressionOrSuper === RelationalExpressionOrSuper] do
Validate[EqualityExpressionOrSuper](cxt, env);
Validate[RelationalExpressionOrSuper](cxt, env);
[EqualityExpression  EqualityExpressionOrSuper !== RelationalExpressionOrSuper] do
Validate[EqualityExpressionOrSuper](cxt, env);
Validate[RelationalExpressionOrSuper](cxt, env)
end proc;
Validate[EqualityExpressionOrSuper]: Context  Environment  ();
Validate[EqualityExpressionOrSuper  EqualityExpression] = Validate[EqualityExpression];
Validate[EqualityExpressionOrSuper  SuperExpression] = Validate[SuperExpression];

Evaluation

proc Eval[EqualityExpression] (env: Environment, phase: Phase): ObjOrRef
[EqualityExpression  RelationalExpression] do
return Eval[RelationalExpression](env, phase);
[EqualityExpression  EqualityExpressionOrSuper == RelationalExpressionOrSuper] do
ra: ObjOrRefOptionalLimit  Eval[EqualityExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(equalTable, a, b, phase);
[EqualityExpression  EqualityExpressionOrSuper != RelationalExpressionOrSuper] do
ra: ObjOrRefOptionalLimit  Eval[EqualityExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
c: Object  binaryDispatch(equalTable, a, b, phase);
return unaryNot(c, phase);
[EqualityExpression  EqualityExpressionOrSuper === RelationalExpressionOrSuper] do
ra: ObjOrRefOptionalLimit  Eval[EqualityExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(strictEqualTable, a, b, phase);
[EqualityExpression  EqualityExpressionOrSuper !== RelationalExpressionOrSuper] do
ra: ObjOrRefOptionalLimit  Eval[EqualityExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[RelationalExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
c: Object  binaryDispatch(strictEqualTable, a, b, phase);
return unaryNot(c, phase)
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] (cxt: Context, env: Environment)
[BitwiseAndExpression  EqualityExpression] do
Validate[EqualityExpression](cxt, env);
[BitwiseAndExpression  BitwiseAndExpressionOrSuper & EqualityExpressionOrSuper] do
Validate[BitwiseAndExpressionOrSuper](cxt, env);
Validate[EqualityExpressionOrSuper](cxt, env)
end proc;
proc Validate[BitwiseXorExpression] (cxt: Context, env: Environment)
[BitwiseXorExpression  BitwiseAndExpression] do
Validate[BitwiseAndExpression](cxt, env);
[BitwiseXorExpression  BitwiseXorExpressionOrSuper ^ BitwiseAndExpressionOrSuper] do
Validate[BitwiseXorExpressionOrSuper](cxt, env);
Validate[BitwiseAndExpressionOrSuper](cxt, env)
end proc;
proc Validate[BitwiseOrExpression] (cxt: Context, env: Environment)
[BitwiseOrExpression  BitwiseXorExpression] do
Validate[BitwiseXorExpression](cxt, env);
[BitwiseOrExpression  BitwiseOrExpressionOrSuper | BitwiseXorExpressionOrSuper] do
Validate[BitwiseOrExpressionOrSuper](cxt, env);
Validate[BitwiseXorExpressionOrSuper](cxt, env)
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] (env: Environment, phase: Phase): ObjOrRef
[BitwiseAndExpression  EqualityExpression] do
return Eval[EqualityExpression](env, phase);
[BitwiseAndExpression  BitwiseAndExpressionOrSuper & EqualityExpressionOrSuper] do
ra: ObjOrRefOptionalLimit  Eval[BitwiseAndExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[EqualityExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(bitwiseAndTable, a, b, phase)
end proc;
proc Eval[BitwiseXorExpression] (env: Environment, phase: Phase): ObjOrRef
[BitwiseXorExpression  BitwiseAndExpression] do
return Eval[BitwiseAndExpression](env, phase);
[BitwiseXorExpression  BitwiseXorExpressionOrSuper ^ BitwiseAndExpressionOrSuper] do
ra: ObjOrRefOptionalLimit  Eval[BitwiseXorExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[BitwiseAndExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(bitwiseXorTable, a, b, phase)
end proc;
proc Eval[BitwiseOrExpression] (env: Environment, phase: Phase): ObjOrRef
[BitwiseOrExpression  BitwiseXorExpression] do
return Eval[BitwiseXorExpression](env, phase);
[BitwiseOrExpression  BitwiseOrExpressionOrSuper | BitwiseXorExpressionOrSuper] do
ra: ObjOrRefOptionalLimit  Eval[BitwiseOrExpressionOrSuper](env, phase);
a: ObjOptionalLimit  readRefWithLimit(ra, phase);
rb: ObjOrRefOptionalLimit  Eval[BitwiseXorExpressionOrSuper](env, phase);
b: ObjOptionalLimit  readRefWithLimit(rb, phase);
return binaryDispatch(bitwiseOrTable, a, b, phase)
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] (cxt: Context, env: Environment)
[LogicalAndExpression  BitwiseOrExpression] do
Validate[BitwiseOrExpression](cxt, env);
[LogicalAndExpression0  LogicalAndExpression1 && BitwiseOrExpression] do
Validate[LogicalAndExpression1](cxt, env);
Validate[BitwiseOrExpression](cxt, env)
end proc;
proc Validate[LogicalXorExpression] (cxt: Context, env: Environment)
[LogicalXorExpression  LogicalAndExpression] do
Validate[LogicalAndExpression](cxt, env);
[LogicalXorExpression0  LogicalXorExpression1 ^^ LogicalAndExpression] do
Validate[LogicalXorExpression1](cxt, env);
Validate[LogicalAndExpression](cxt, env)
end proc;
proc Validate[LogicalOrExpression] (cxt: Context, env: Environment)
[LogicalOrExpression  LogicalXorExpression] do
Validate[LogicalXorExpression](cxt, env);
[LogicalOrExpression0  LogicalOrExpression1 || LogicalXorExpression] do
Validate[LogicalOrExpression1](cxt, env);
Validate[LogicalXorExpression](cxt, env)
end proc;

Evaluation

proc Eval[LogicalAndExpression] (env: Environment, phase: Phase): ObjOrRef
[LogicalAndExpression  BitwiseOrExpression] do
return Eval[BitwiseOrExpression](env, phase);
[LogicalAndExpression0  LogicalAndExpression1 && BitwiseOrExpression] do
ra: ObjOrRef  Eval[LogicalAndExpression1](env, phase);
a: Object  readReference(ra, phase);
if toBoolean(a, phase) then
rb: ObjOrRef  Eval[BitwiseOrExpression](env, phase);
return readReference(rb, phase)
else return a
end if
end proc;
proc Eval[LogicalXorExpression] (env: Environment, phase: Phase): ObjOrRef
[LogicalXorExpression  LogicalAndExpression] do
return Eval[LogicalAndExpression](env, phase);
[LogicalXorExpression0  LogicalXorExpression1 ^^ LogicalAndExpression] do
ra: ObjOrRef  Eval[LogicalXorExpression1](env, phase);
a: Object  readReference(ra, phase);
rb: ObjOrRef  Eval[LogicalAndExpression](env, phase);
b: Object  readReference(rb, phase);
ba: Boolean  toBoolean(a, phase);
bb: Boolean  toBoolean(b, phase);
return ba xor bb
end proc;
proc Eval[LogicalOrExpression] (env: Environment, phase: Phase): ObjOrRef
[LogicalOrExpression  LogicalXorExpression] do
return Eval[LogicalXorExpression](env, phase);
[LogicalOrExpression0  LogicalOrExpression1 || LogicalXorExpression] do
ra: ObjOrRef  Eval[LogicalOrExpression1](env, phase);
a: Object  readReference(ra, phase);
if toBoolean(a, phase) then return a
else
rb: ObjOrRef  Eval[LogicalXorExpression](env, phase);
return readReference(rb, phase)
end if
end proc;

Conditional Operator

Syntax

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

Validation

proc Validate[ConditionalExpression] (cxt: Context, env: Environment)
[ConditionalExpression  LogicalOrExpression] do
Validate[LogicalOrExpression](cxt, env);
[ConditionalExpression  LogicalOrExpression ? AssignmentExpression1 : AssignmentExpression2] do
Validate[LogicalOrExpression](cxt, env);
Validate[AssignmentExpression1](cxt, env);
Validate[AssignmentExpression2](cxt, env)
end proc;
proc Validate[NonAssignmentExpression] (cxt: Context, env: Environment)
[NonAssignmentExpression  LogicalOrExpression] do
Validate[LogicalOrExpression](cxt, env);
[NonAssignmentExpression0  LogicalOrExpression ? NonAssignmentExpression1 : NonAssignmentExpression2] do
Validate[LogicalOrExpression](cxt, env);
Validate[NonAssignmentExpression1](cxt, env);
Validate[NonAssignmentExpression2](cxt, env)
end proc;

Evaluation

proc Eval[ConditionalExpression] (env: Environment, phase: Phase): ObjOrRef
[ConditionalExpression  LogicalOrExpression] do
return Eval[LogicalOrExpression](env, phase);
[ConditionalExpression  LogicalOrExpression ? AssignmentExpression1 : AssignmentExpression2] do
ra: ObjOrRef  Eval[LogicalOrExpression](env, phase);
a: Object  readReference(ra, phase);
if toBoolean(a, phase) then
rb: ObjOrRef  Eval[AssignmentExpression1](env, phase);
return readReference(rb, phase)
else
rc: ObjOrRef  Eval[AssignmentExpression2](env, phase);
return readReference(rc, phase)
end if
end proc;
proc Eval[NonAssignmentExpression] (env: Environment, phase: Phase): ObjOrRef
[NonAssignmentExpression  LogicalOrExpression] do
return Eval[LogicalOrExpression](env, phase);
[NonAssignmentExpression0  LogicalOrExpression ? NonAssignmentExpression1 : NonAssignmentExpression2] do
ra: ObjOrRef  Eval[LogicalOrExpression](env, phase);
a: Object  readReference(ra, phase);
if toBoolean(a, phase) then
rb: ObjOrRef  Eval[NonAssignmentExpression1](env, phase);
return readReference(rb, phase)
else
rc: ObjOrRef  Eval[NonAssignmentExpression2](env, phase);
return readReference(rc, phase)
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] (cxt: Context, env: Environment)
[AssignmentExpression  ConditionalExpression] do
Validate[ConditionalExpression](cxt, env);
[AssignmentExpression0  PostfixExpression = AssignmentExpression1] do
Validate[PostfixExpression](cxt, env);
Validate[AssignmentExpression1](cxt, env);
[AssignmentExpression0  PostfixExpressionOrSuper CompoundAssignment AssignmentExpression1] do
Validate[PostfixExpressionOrSuper](cxt, env);
Validate[AssignmentExpression1](cxt, env);
[AssignmentExpression  PostfixExpressionOrSuper CompoundAssignment SuperExpression] do
Validate[PostfixExpressionOrSuper](cxt, env);
Validate[SuperExpression](cxt, env);
[AssignmentExpression0  PostfixExpression LogicalAssignment AssignmentExpression1] do
Validate[PostfixExpression](cxt, env);
Validate[AssignmentExpression1](cxt, env)
end proc;

Evaluation

proc Eval[AssignmentExpression] (env: Environment, phase: Phase): ObjOrRef
[AssignmentExpression  ConditionalExpression] do
return Eval[ConditionalExpression](env, phase);
[AssignmentExpression0  PostfixExpression = AssignmentExpression1] do
if phase = compile then throw compileExpressionError end if;
ra: ObjOrRef  Eval[PostfixExpression](env, phase);
rb: ObjOrRef  Eval[AssignmentExpression1](env, phase);
b: Object  readReference(rb, phase);
writeReference(ra, b, phase);
return b;
[AssignmentExpression0  PostfixExpressionOrSuper CompoundAssignment AssignmentExpression1] do
if phase = compile then throw compileExpressionError end if;
return evalAssignmentOp(Table[CompoundAssignment], Eval[PostfixExpressionOrSuper], Eval[AssignmentExpression1], env, phase);
[AssignmentExpression  PostfixExpressionOrSuper CompoundAssignment SuperExpression] do
if phase = compile then throw compileExpressionError end if;
[AssignmentExpression0  PostfixExpression LogicalAssignment AssignmentExpression1] do
if phase = compile then throw compileExpressionError end if;
rLeft: ObjOrRef  Eval[PostfixExpression](env, phase);
oLeft: Object  readReference(rLeft, phase);
bLeft: Boolean  toBoolean(oLeft, phase);
result: Object  oLeft;
case Operator[LogicalAssignment] of
{andEq} do
if bLeft then
result  readReference(Eval[AssignmentExpression1](env, phase), phase)
end if;
{xorEq} do
bRight: Boolean  toBoolean(readReference(Eval[AssignmentExpression1](env, phase), phase), phase);
result  bLeft xor bRight;
{orEq} do
if not bLeft then
result  readReference(Eval[AssignmentExpression1](env, phase), phase)
end if
end case;
writeReference(rLeft, result, phase);
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]: {andEq, xorEq, orEq};
Operator[LogicalAssignment  &&=] = andEq;
Operator[LogicalAssignment  ^^=] = xorEq;
Operator[LogicalAssignment  ||=] = orEq;
proc evalAssignmentOp(table: BinaryMethod{}, leftEval: Environment  Phase  ObjOrRefOptionalLimit, rightEval: Environment  Phase  ObjOrRefOptionalLimit, env: Environment, phase: {run}): ObjOrRef
rLeft: ObjOrRefOptionalLimit  leftEval(env, phase);
oLeft: ObjOptionalLimit  readRefWithLimit(rLeft, phase);
rRight: ObjOrRefOptionalLimit  rightEval(env, phase);
oRight: ObjOptionalLimit  readRefWithLimit(rRight, phase);
result: Object  binaryDispatch(table, oLeft, oRight, phase);
writeReference(rLeft, result, phase);
return result
end proc;

Comma Expressions

Syntax

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

Validation

proc Validate[ListExpression] (cxt: Context, env: Environment)
[ListExpression  AssignmentExpression] do
Validate[AssignmentExpression](cxt, env);
[ListExpression0  ListExpression1 , AssignmentExpression] do
Validate[ListExpression1](cxt, env);
Validate[AssignmentExpression](cxt, env)
end proc;

Evaluation

proc Eval[ListExpression] (env: Environment, phase: Phase): ObjOrRef
[ListExpression  AssignmentExpression] do
return Eval[AssignmentExpression](env, phase);
[ListExpression0  ListExpression1 , AssignmentExpression] do
ra: ObjOrRef  Eval[ListExpression1](env, phase);
readReference(ra, phase);
rb: ObjOrRef  Eval[AssignmentExpression](env, phase);
return readReference(rb, phase)
end proc;
proc EvalAsList[ListExpression] (env: Environment, phase: Phase): Object[]
[ListExpression  AssignmentExpression] do
r: ObjOrRef  Eval[AssignmentExpression](env, phase);
elt: Object  readReference(r, phase);
return [elt];
[ListExpression0  ListExpression1 , AssignmentExpression] do
elts: Object[]  EvalAsList[ListExpression1](env, phase);
r: ObjOrRef  Eval[AssignmentExpression](env, phase);
elt: Object  readReference(r, phase);
return elts  [elt]
end proc;

Type Expressions

Syntax

TypeExpression  NonAssignmentExpression

Validation

proc Validate[TypeExpression  NonAssignmentExpression] (cxt: Context, env: Environment)
Validate[NonAssignmentExpression](cxt, env)
end proc;

Evaluation

proc Eval[TypeExpression  NonAssignmentExpression] (env: Environment): Class
r: ObjOrRef  Eval[NonAssignmentExpression](env, compile);
o: Object  readReference(r, compile);
if o  Class then throw badValueError end if;
return o
end proc;

Statements

Syntax

  {abbrev, noShortIf, full}
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] (cxt: Context, env: Environment, sl: Label{}, jt: JumpTargets, pl: Plurality)
[Statement  ExpressionStatement Semicolon] do
Validate[ExpressionStatement](cxt, env);
[Statement  SuperStatement Semicolon] do Validate[SuperStatement](cxt, env);
[Statement  Block] do Validate[Block](cxt, env, jt, pl);
[Statement  LabeledStatement] do Validate[LabeledStatement](cxt, env, sl, jt);
[Statement  IfStatement] do Validate[IfStatement](cxt, env, jt);
[Statement  SwitchStatement] do ????;
[Statement  DoStatement Semicolon] do Validate[DoStatement](cxt, env, sl, jt);
[Statement  WhileStatement] do Validate[WhileStatement](cxt, env, sl, jt);
[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](cxt, env);
[Statement  ThrowStatement Semicolon] do Validate[ThrowStatement](cxt, env);
[Statement  TryStatement] do ????
end proc;
Enabled[Substatement]: Boolean;
proc Validate[Substatement] (cxt: Context, env: Environment, sl: Label{}, jt: JumpTargets)
[Substatement  EmptyStatement] do nothing;
[Substatement  Statement] do Validate[Statement](cxt, env, sl, jt, plural);
[Substatement  SimpleVariableDefinition Semicolon] do
Validate[SimpleVariableDefinition](cxt, env);
[Substatement  Attributes [no line break] { Substatements }] do
Validate[Attributes](cxt, env);
attr: Attribute  Eval[Attributes](env, compile);
if attr  Boolean then throw badValueError end if;
Enabled[Substatement]  attr;
if attr then Validate[Substatements](cxt, env, jt) end if
end proc;
proc Validate[Substatements] (cxt: Context, env: Environment, jt: JumpTargets)
[Substatements  «empty»] do nothing;
[Substatements  SubstatementsPrefix Substatementabbrev] do
Validate[SubstatementsPrefix](cxt, env, jt);
Validate[Substatementabbrev](cxt, env, {}, jt)
end proc;
proc Validate[SubstatementsPrefix] (cxt: Context, env: Environment, jt: JumpTargets)
[SubstatementsPrefix  «empty»] do nothing;
[SubstatementsPrefix0  SubstatementsPrefix1 Substatementfull] do
Validate[SubstatementsPrefix1](cxt, env, jt);
Validate[Substatementfull](cxt, env, {}, jt)
end proc;

Evaluation

proc Eval[Statement] (env: Environment, d: Object): Object
[Statement  ExpressionStatement Semicolon] do
return Eval[ExpressionStatement](env);
[Statement  SuperStatement Semicolon] do return Eval[SuperStatement](env);
[Statement  Block] do return Eval[Block](env, d);
[Statement  LabeledStatement] do return Eval[LabeledStatement](env, d);
[Statement  IfStatement] do return Eval[IfStatement](env, d);
[Statement  SwitchStatement] do ????;
[Statement  DoStatement Semicolon] do return Eval[DoStatement](env, d);
[Statement  WhileStatement] do return Eval[WhileStatement](env, d);
[Statement  ForStatement] do ????;
[Statement  WithStatement] do ????;
[Statement  ContinueStatement Semicolon] do
return Eval[ContinueStatement](env, d);
[Statement  BreakStatement Semicolon] do return Eval[BreakStatement](env, d);
[Statement  ReturnStatement Semicolon] do return Eval[ReturnStatement](env);
[Statement  ThrowStatement Semicolon] do return Eval[ThrowStatement](env);
[Statement  TryStatement] do ????
end proc;
proc Eval[Substatement] (env: Environment, d: Object): Object
[Substatement  EmptyStatement] do return d;
[Substatement  Statement] do return Eval[Statement](env, d);
[Substatement  SimpleVariableDefinition Semicolon] do
return Eval[SimpleVariableDefinition](env, d);
[Substatement  Attributes [no line break] { Substatements }] do
if Enabled[Substatement] then return Eval[Substatements](env, d)
else return d
end if
end proc;
proc Eval[Substatements] (env: Environment, d: Object): Object
[Substatements  «empty»] do return d;
[Substatements  SubstatementsPrefix Substatementabbrev] do
o: Object  Eval[SubstatementsPrefix](env, d);
return Eval[Substatementabbrev](env, o)
end proc;
proc Eval[SubstatementsPrefix] (env: Environment, d: Object): Object
[SubstatementsPrefix  «empty»] do return d;
[SubstatementsPrefix0  SubstatementsPrefix1 Substatementfull] do
o: Object  Eval[SubstatementsPrefix1](env, d);
return Eval[Substatementfull](env, o)
end proc;

Empty Statement

Syntax

EmptyStatement  ;

Expression Statement

Syntax

ExpressionStatement  [lookahead{function, {}] ListExpressionallowIn

Validation

proc Validate[ExpressionStatement  [lookahead{function, {}] ListExpressionallowIn] (cxt: Context, env: Environment)
Validate[ListExpressionallowIn](cxt, env)
end proc;

Evaluation

proc Eval[ExpressionStatement  [lookahead{function, {}] ListExpressionallowIn] (env: Environment): Object
r: ObjOrRef  Eval[ListExpressionallowIn](env, run);
return readReference(r, run)
end proc;

Super Statement

Syntax

SuperStatement  super Arguments

Validation

proc Validate[SuperStatement  super Arguments] (cxt: Context, env: Environment)
????
end proc;

Evaluation

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

Block Statement

Syntax

Block  { Directives }

Validation

proc Validate[Block  { Directives }] (cxt: Context, env: Environment, jt: JumpTargets, pl: Plurality)
compileFrame: BlockFrame  new BlockFramestaticReadBindings: {}, staticWriteBindings: {}, plurality: pl;
CompileFrame[Block]  compileFrame;
Validate[Directives](cxt, [compileFrame]  env, jt, pl, none)
end proc;
proc ValidateUsingFrame[Block  { Directives }] (cxt: Context, env: Environment, jt: JumpTargets, pl: Plurality, frame: Frame)
Validate[Directives](cxt, [frame]  env, jt, pl, none)
end proc;

Evaluation

proc Eval[Block  { Directives }] (env: Environment, d: Object): Object
compileFrame: BlockFrame  CompileFrame[Block];
runtimeFrame: BlockFrame  instantiateBlockFrame(compileFrame);
return Eval[Directives]([runtimeFrame]  env, d)
end proc;
proc EvalUsingFrame[Block  { Directives }] (env: Environment, frame: Frame, d: Object): Object
return Eval[Directives]([frame]  env, d)
end proc;
CompileFrame[Block]: BlockFrame;

Labeled Statements

Syntax

LabeledStatement  Identifier : Substatement

Validation

proc Validate[LabeledStatement  Identifier : Substatement] (cxt: Context, env: Environment, sl: Label{}, jt: JumpTargets)
name: String  Name[Identifier];
if name  jt.breakTargets then throw syntaxError end if;
jt2: JumpTargets  JumpTargetsbreakTargets: jt.breakTargets  {name}, continueTargets: jt.continueTargets;
Validate[Substatement](cxt, env, sl  {name}, jt2)
end proc;

Evaluation

proc Eval[LabeledStatement  Identifier : Substatement] (env: Environment, d: Object): Object
try return Eval[Substatement](env, d)
catch x: SemanticException do
if x  Break and x.label = Name[Identifier] then 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] (cxt: Context, env: Environment, jt: JumpTargets)
[IfStatementabbrev  if ParenListExpression Substatementabbrev] do
Validate[ParenListExpression](cxt, env);
Validate[Substatementabbrev](cxt, env, {}, jt);
[IfStatementfull  if ParenListExpression Substatementfull] do
Validate[ParenListExpression](cxt, env);
Validate[Substatementfull](cxt, env, {}, jt);
[IfStatement  if ParenListExpression SubstatementnoShortIf1 else Substatement2] do
Validate[ParenListExpression](cxt, env);
Validate[SubstatementnoShortIf1](cxt, env, {}, jt);
Validate[Substatement2](cxt, env, {}, jt)
end proc;

Evaluation

proc Eval[IfStatement] (env: Environment, d: Object): Object
[IfStatementabbrev  if ParenListExpression Substatementabbrev] do
r: ObjOrRef  Eval[ParenListExpression](env, run);
o: Object  readReference(r, run);
if toBoolean(o, run) then return Eval[Substatementabbrev](env, d)
else return d
end if;
[IfStatementfull  if ParenListExpression Substatementfull] do
r: ObjOrRef  Eval[ParenListExpression](env, run);
o: Object  readReference(r, run);
if toBoolean(o, run) then return Eval[Substatementfull](env, d)
else return d
end if;
[IfStatement  if ParenListExpression SubstatementnoShortIf1 else Substatement2] do
r: ObjOrRef  Eval[ParenListExpression](env, run);
o: Object  readReference(r, run);
if toBoolean(o, run) then return Eval[SubstatementnoShortIf1](env, d)
else return Eval[Substatement2](env, d)
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] (cxt: Context, env: Environment, sl: Label{}, jt: JumpTargets)
continueLabels: Label{}  sl  {default};
Labels[DoStatement]  continueLabels;
jt2: JumpTargets  JumpTargetsbreakTargets: jt.breakTargets  {default}, continueTargets: jt.continueTargets  continueLabels;
Validate[Substatementabbrev](cxt, env, {}, jt2);
Validate[ParenListExpression](cxt, env)
end proc;

Evaluation

proc Eval[DoStatement  do Substatementabbrev while ParenListExpression] (env: Environment, d: Object): Object
try
d1: Object  d;
while true do
try d1  Eval[Substatementabbrev](env, d1)
catch x: SemanticException do
if x  Continue and x.label  Labels[DoStatement] then d1  x.value
else throw x
end if
end try;
r: ObjOrRef  Eval[ParenListExpression](env, run);
o: Object  readReference(r, run);
if not toBoolean(o, run) then return d1 end if
end while
catch x: SemanticException 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] (cxt: Context, env: Environment, sl: Label{}, jt: JumpTargets)
Validate[ParenListExpression](cxt, env);
continueLabels: Label{}  sl  {default};
Labels[WhileStatement]  continueLabels;
jt2: JumpTargets  JumpTargetsbreakTargets: jt.breakTargets  {default}, continueTargets: jt.continueTargets  continueLabels;
Validate[Substatement](cxt, env, {}, jt2)
end proc;

Evaluation

proc Eval[WhileStatement  while ParenListExpression Substatement] (env: Environment, d: Object): Object
try
d1: Object  d;
while toBoolean(readReference(Eval[ParenListExpression](env, run), run), run) do
try d1  Eval[Substatement](env, d1)
catch x: SemanticException 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 x: SemanticException 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] (jt: JumpTargets)
[ContinueStatement  continue] do
if default  jt.continueTargets then throw syntaxError end if;
[ContinueStatement  continue [no line break] Identifier] do
if Name[Identifier]  jt.continueTargets then throw syntaxError end if
end proc;
proc Validate[BreakStatement] (jt: JumpTargets)
[BreakStatement  break] do
if default  jt.breakTargets then throw syntaxError end if;
[BreakStatement  break [no line break] Identifier] do
if Name[Identifier]  jt.breakTargets then throw syntaxError end if
end proc;

Evaluation

proc Eval[ContinueStatement] (env: Environment, d: Object): Object
[ContinueStatement  continue] do throw Continuevalue: d, label: default;
[ContinueStatement  continue [no line break] Identifier] do
throw Continuevalue: d, label: Name[Identifier]
end proc;
proc Eval[BreakStatement] (env: Environment, d: Object): Object
[BreakStatement  break] do throw Breakvalue: d, label: default;
[BreakStatement  break [no line break] Identifier] do
throw Breakvalue: d, label: Name[Identifier]
end proc;

Return Statement

Syntax

ReturnStatement 
   return
|  return [no line break] ListExpressionallowIn

Validation

proc Validate[ReturnStatement] (cxt: Context, env: Environment)
[ReturnStatement  return] do
if getRegionalFrame(env)  FunctionFrame then throw syntaxError end if;
[ReturnStatement  return [no line break] ListExpressionallowIn] do
if getRegionalFrame(env)  FunctionFrame then throw syntaxError end if;
Validate[ListExpressionallowIn](cxt, env)
end proc;

Evaluation

proc Eval[ReturnStatement] (env: Environment): Object
[ReturnStatement  return] do throw ReturnedValuevalue: undefined;
[ReturnStatement  return [no line break] ListExpressionallowIn] do
r: ObjOrRef  Eval[ListExpressionallowIn](env, run);
a: Object  readReference(r, run);
throw ReturnedValuevalue: a
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] (env: Environment): Object
r: ObjOrRef  Eval[ListExpressionallowIn](env, run);
a: Object  readReference(r, run);
throw ThrownValuevalue: a
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] (cxt: Context, env: Environment, jt: JumpTargets, pl: Plurality, attr: AttributeOptNotFalse): Context
[Directive  EmptyStatement] do return cxt;
[Directive  Statement] do
if attr  {none, true} then throw syntaxError end if;
Validate[Statement](cxt, env, {}, jt, pl);
return cxt;
[Directive  AnnotatableDirective] do
return Validate[AnnotatableDirective](cxt, env, pl, attr);
[Directive  Attributes [no line break] AnnotatableDirective] do
Validate[Attributes](cxt, env);
attr2: Attribute  Eval[Attributes](env, compile);
attr3: Attribute  combineAttributes(attr, attr2);
Enabled[Directive]  attr3  false;
if attr3  false then return Validate[AnnotatableDirective](cxt, env, pl, attr3)
else return cxt
end if;
[Directive  Attributes [no line break] { Directives }] do
Validate[Attributes](cxt, env);
attr2: Attribute  Eval[Attributes](env, compile);
attr3: Attribute  combineAttributes(attr, attr2);
Enabled[Directive]  attr3  false;
if attr3 = false then return cxt end if;
return Validate[Directives](cxt, env, jt, pl, attr3);
[Directive  PackageDefinition] do
if attr  {none, true} then ???? else throw syntaxError end if;
[Directive  IncludeDirective Semicolon] do
if attr  {none, true} then ???? else throw syntaxError end if;
[Directive  Pragma Semicolon] do
if attr  {none, true} then return Validate[Pragma](cxt)
else throw syntaxError
end if
end proc;
proc Validate[AnnotatableDirective] (cxt: Context, env: Environment, pl: Plurality, attr: AttributeOptNotFalse): Context
[AnnotatableDirective  ExportDefinition Semicolon] do ????;
[AnnotatableDirective  VariableDefinition Semicolon] do
Validate[VariableDefinition](cxt, env, attr);
return cxt;
[AnnotatableDirective  FunctionDefinition] do ????;
[AnnotatableDirective  ClassDefinition] do
Validate[ClassDefinition](cxt, env, pl, attr);
return cxt;
[AnnotatableDirective  NamespaceDefinition Semicolon] do ????;
[AnnotatableDirective  InterfaceDefinition] do ????;
[AnnotatableDirective  ImportDirective Semicolon] do ????;
[AnnotatableDirective  UseDirective Semicolon] do
if attr  {none, true} then return Validate[UseDirective](cxt, env)
else throw syntaxError
end if
end proc;
proc Validate[Directives] (cxt: Context, env: Environment, jt: JumpTargets, pl: Plurality, attr: AttributeOptNotFalse): Context
[Directives  «empty»] do return cxt;
[Directives  DirectivesPrefix Directiveabbrev] do
cxt2: Context  Validate[DirectivesPrefix](cxt, env, jt, pl, attr);
return Validate[Directiveabbrev](cxt2, env, jt, pl, attr)
end proc;
proc Validate[DirectivesPrefix] (cxt: Context, env: Environment, jt: JumpTargets, pl: Plurality, attr: AttributeOptNotFalse): Context
[DirectivesPrefix  «empty»] do return cxt;
[DirectivesPrefix0  DirectivesPrefix1 Directivefull] do
cxt2: Context  Validate[DirectivesPrefix1](cxt, env, jt, pl, attr);
return Validate[Directivefull](cxt2, env, jt, pl, attr)
end proc;

Evaluation

proc Eval[Directive] (env: Environment, d: Object): Object
[Directive  EmptyStatement] do return d;
[Directive  Statement] do return Eval[Statement](env, d);
[Directive  AnnotatableDirective] do return Eval[AnnotatableDirective](env, d);
[Directive  Attributes [no line break] AnnotatableDirective] do
if Enabled[Directive] then return Eval[AnnotatableDirective](env, d)
else return d
end if;
[Directive  Attributes [no line break] { Directives }] do
if Enabled[Directive] then return Eval[Directives](env, d) else return d end if;
[Directive  PackageDefinition] do ????;
[Directive  IncludeDirective Semicolon] do ????;
[Directive  Pragma Semicolon] do return d
end proc;
proc Eval[AnnotatableDirective] (env: Environment, d: Object): Object
[AnnotatableDirective  ExportDefinition Semicolon] do ????;
[AnnotatableDirective  VariableDefinition Semicolon] do
return Eval[VariableDefinition](env, d);
[AnnotatableDirective  FunctionDefinition] do ????;
[AnnotatableDirective  ClassDefinition] do return Eval[ClassDefinition](env, d);
[AnnotatableDirective  NamespaceDefinition Semicolon] do ????;
[AnnotatableDirective  InterfaceDefinition] do ????;
[AnnotatableDirective  ImportDirective Semicolon] do ????;
[AnnotatableDirective  UseDirective Semicolon] do return d
end proc;
proc Eval[Directives] (env: Environment, d: Object): Object
[Directives  «empty»] do return d;
[Directives  DirectivesPrefix Directiveabbrev] do
o: Object  Eval[DirectivesPrefix](env, d);
return Eval[Directiveabbrev](env, o)
end proc;
proc Eval[DirectivesPrefix] (env: Environment, d: Object): Object
[DirectivesPrefix  «empty»] do return d;
[DirectivesPrefix0  DirectivesPrefix1 Directivefull] do
o: Object  Eval[DirectivesPrefix1](env, d);
return Eval[Directivefull](env, o)
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] (cxt: Context, env: Environment)
[Attributes  Attribute] do Validate[Attribute](cxt, env);
[Attributes  AttributeCombination] do Validate[AttributeCombination](cxt, env)
end proc;
proc Validate[AttributeCombination  Attribute [no line break] Attributes] (cxt: Context, env: Environment)
Validate[Attribute](cxt, env);
Validate[Attributes](cxt, env)
end proc;
proc Validate[Attribute] (cxt: Context, env: Environment)
[Attribute  AttributeExpression] do Validate[AttributeExpression](cxt, env);
[Attribute  true] do nothing;
[Attribute  false] do nothing;
[Attribute  public] do nothing;
[Attribute  NonexpressionAttribute] do Validate[NonexpressionAttribute](env)
end proc;
proc Validate[NonexpressionAttribute] (env: Environment)
[NonexpressionAttribute  abstract] do nothing;
[NonexpressionAttribute  final] do nothing;
[NonexpressionAttribute  private] do
if getEnclosingClass(env) = none then throw syntaxError end if;
[NonexpressionAttribute  static] do nothing
end proc;

Evaluation

proc Eval[Attributes] (env: Environment, phase: Phase): Attribute
[Attributes  Attribute] do return Eval[Attribute](env, phase);
[Attributes  AttributeCombination] do return Eval[AttributeCombination](env, phase)
end proc;
proc Eval[AttributeCombination  Attribute [no line break] Attributes] (env: Environment, phase: Phase): Attribute
a: Attribute  Eval[Attribute](env, phase);
if a = false then return false end if;
b: Attribute  Eval[Attributes](env, phase);
return combineAttributes(a, b)
end proc;
proc Eval[Attribute] (env: Environment, phase: Phase): Attribute
[Attribute  AttributeExpression] do
r: ObjOrRef  Eval[AttributeExpression](env, phase);
a: Object  readReference(r, phase);
if a  Attribute then throw badValueError end if;
return a;
[Attribute  true] do return true;
[Attribute  false] do return false;
[Attribute  public] do return publicNamespace;
[Attribute  NonexpressionAttribute] do
return Eval[NonexpressionAttribute](env, phase)
end proc;
proc Eval[NonexpressionAttribute] (env: Environment, phase: Phase): Attribute
[NonexpressionAttribute  abstract] do
return CompoundAttributenamespaces: {}, explicit: false, dynamic: false, compile: false, memberMod: abstract, overrideMod: none, prototype: false, unused: false;
[NonexpressionAttribute  final] do
return CompoundAttributenamespaces: {}, explicit: false, dynamic: false, compile: false, memberMod: final, overrideMod: none, prototype: false, unused: false;
[NonexpressionAttribute  private] do
c: ClassOpt  getEnclosingClass(env);
Note that Validate ensured that c cannot be none at this point.
return c.privateNamespace;
[NonexpressionAttribute  static] do
return CompoundAttributenamespaces: {}, explicit: false, dynamic: false, compile: false, memberMod: static, overrideMod: none, prototype: false, unused: false
end proc;

Use Directive

Syntax

UseDirective  use namespace ParenListExpression

Validation

proc Validate[UseDirective  use namespace ParenListExpression] (cxt: Context, env: Environment): Context
Validate[ParenListExpression](cxt, env);
values: Object[]  EvalAsList[ParenListExpression](env, compile);
namespaces: Namespace{}  {};
for each v  values do
if v  Namespace or v  namespaces then throw badValueError end if;
namespaces  namespaces  {v}
end for each;
return ContextopenNamespaces: cxt.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] (cxt: Context): Context
return Validate[PragmaItems](cxt)
end proc;
proc Validate[PragmaItems] (cxt: Context): Context
[PragmaItems  PragmaItem] do return Validate[PragmaItem](cxt);
[PragmaItems0  PragmaItems1 , PragmaItem] do
cxt2: Context  Validate[PragmaItems1](cxt);
return Validate[PragmaItem](cxt2)
end proc;
proc Validate[PragmaItem] (cxt: Context): Context
[PragmaItem  PragmaExpr] do return Validate[PragmaExpr](cxt, false);
[PragmaItem  PragmaExpr ?] do return Validate[PragmaExpr](cxt, true)
end proc;
proc Validate[PragmaExpr] (cxt: Context, optional: Boolean): Context
[PragmaExpr  Identifier] do
return processPragma(cxt, Name[Identifier], undefined, optional);
[PragmaExpr  Identifier ( PragmaArgument )] do
arg: Object  Value[PragmaArgument];
return processPragma(cxt, Name[Identifier], arg, optional)
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(cxt: Context, name: String, value: Object, optional: Boolean): Context
if name = “strict” then
if value  {true, undefined} then
return Contextstrict: true, other fields from cxt
end if;
if value = false then return Contextstrict: false, other fields from cxt end if
end if;
if name = “ecmascript” then
if value  {undefined, 4.0} then return cxt end if;
if value  {1.0, 2.0, 3.0} then
An implementation may optionally modify cxt to disable features not available in ECMAScript Edition value other than subsequent pragmas.
return cxt
end if
end if;
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] (cxt: Context, env: Environment, attr: AttributeOptNotFalse)
immutable: Boolean  Immutable[VariableDefinitionKind];
Validate[VariableBindingListallowIn](cxt, env, attr, immutable)
end proc;
Immutable[VariableDefinitionKind]: Boolean;
Immutable[VariableDefinitionKind  var] = false;
Immutable[VariableDefinitionKind  const] = true;
proc Validate[VariableBindingList] (cxt: Context, env: Environment, attr: AttributeOptNotFalse, immutable: Boolean)
[VariableBindingList  VariableBinding] do
Validate[VariableBinding](cxt, env, attr, immutable);
[VariableBindingList0  VariableBindingList1 , VariableBinding] do
Validate[VariableBindingList1](cxt, env, attr, immutable);
Validate[VariableBinding](cxt, env, attr, immutable)
end proc;
Kind[VariableBinding]: {hoisted, staticCompiled, staticRun, instanceRun};
Multiname[VariableBinding]: Multiname;
proc Validate[VariableBinding  TypedIdentifier VariableInitialisation] (cxt: Context, env: Environment, attr: AttributeOptNotFalse, immutable: Boolean)
Validate[TypedIdentifier](cxt, env);
Validate[VariableInitialisation](cxt, env);
name: String  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;
qname: QualifiedName  QualifiedNamenamespace: publicNamespace, id: name;
Multiname[VariableBinding]  {qname};
defineHoistedVar(env, name)
else
a: CompoundAttribute  toCompoundAttribute(attr);
memberMod: MemberModifier  a.memberMod;
namespaces: Namespace{}  a.namespaces;
localFrame: Frame  env[0];
if a.dynamic or a.prototype or (a.explicit and localFrame  Package) or (a.compile and not immutable) then
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
{none, static} do
if a.overrideMod  none then throw definitionError end if;
if namespaces = {} then namespaces  {publicNamespace} end if;
multiname: Multiname  {QualifiedNamenamespace: ns, id: name | ns  namespaces};
Multiname[VariableBinding]  multiname;
regionalEnv: Frame[]  getRegionalEnvironment(env);
regionalFrame: Frame  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 QualifiedNamenamespace: publicNamespace, id: dp.name  multiname) then
end if;
v: Variable  new Variablevalue: future, immutable: immutable;
newBindings: StaticBinding{}  {StaticBindingqname: qname, content: v, explicit: a.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.
newForbiddenBindings: StaticBinding{}  {StaticBindingqname: qname, content: forbidden, explicit: true | qname  multiname};
for each frame  regionalEnv[1 ...] do
frame.staticReadBindings  frame.staticReadBindings  newForbiddenBindings;
frame.staticWriteBindings  frame.staticWriteBindings  newForbiddenBindings
end for each;
proc deferredStaticValidate()
t: ClassOpt  Eval[TypedIdentifier](env);
if t = none then t  objectClass end if;
v.type  t
end proc;
if a.compile then
deferredStaticValidate();
value: ObjectOpt  Eval[VariableInitialisation](env, compile);
if value = none then throw definitionError end if;
coercedValue: Object  assignmentConversion(value, v.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](env, run)
end proc;
m: InstanceVariable  InstanceAccessor;
case memberMod of
{abstract} do
if HasInitialiser[VariableInitialisation] then throw syntaxError
end if;
m  new InstanceAccessorcode: abstract, final: false;
{virtual} do
m  new InstanceVariableevalInitialValue: evalInitialValue, immutable: immutable, final: false;
{final} do
m  new InstanceVariableevalInitialValue: evalInitialValue, immutable: immutable, final: true
end case;
os: OverrideStatusPair  defineInstanceMember(localFrame, cxt, name, namespaces, a.overrideMod, readWrite, m);
proc deferredInstanceValidate()
t: ClassOpt  Eval[TypedIdentifier](env);
if t = none then
overriddenRead: InstanceMember  {none, potentialConflict}  os.readStatus.overriddenMember;
overriddenWrite: InstanceMember  {none, potentialConflict}  os.writeStatus.overriddenMember;
if overriddenRead  {none, potentialConflict} then
Note that defineInstanceMember already ensured that overriddenRead  InstanceMethod.
t  overriddenRead.type
elsif overriddenWrite  {none, potentialConflict} then
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] (cxt: Context, env: Environment)
[VariableInitialisation  «empty»] do nothing;
[VariableInitialisation  = VariableInitialiser] do
Validate[VariableInitialiser](cxt, env)
end proc;
proc Validate[VariableInitialiser] (cxt: Context, env: Environment)
[VariableInitialiser  AssignmentExpression] do
Validate[AssignmentExpression](cxt, env);
[VariableInitialiser  NonexpressionAttribute] do
Validate[NonexpressionAttribute](env);
[VariableInitialiser  AttributeCombination] do
Validate[AttributeCombination](cxt, env)
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] (cxt: Context, env: Environment)
[TypedIdentifier  Identifier] do nothing;
[TypedIdentifier  Identifier : TypeExpression] do
Validate[TypeExpression](cxt, env)
end proc;

Evaluation

proc Eval[VariableDefinition  VariableDefinitionKind VariableBindingListallowIn] (env: Environment, d: Object): Object
immutable: Boolean  Immutable[VariableDefinitionKind];
Eval[VariableBindingListallowIn](env, immutable);
return d
end proc;
proc Eval[VariableBindingList] (env: Environment, immutable: Boolean)
[VariableBindingList  VariableBinding] do Eval[VariableBinding](env, immutable);
[VariableBindingList0  VariableBindingList1 , VariableBinding] do
Eval[VariableBindingList1](env, immutable);
Eval[VariableBinding](env, immutable)
end proc;
proc Eval[VariableBinding  TypedIdentifier VariableInitialisation] (env: Environment, immutable: Boolean)
case Kind[VariableBinding] of
{hoisted} do
value: ObjectOpt  Eval[VariableInitialisation](env, run);
if value  none then
lexicalWrite(env, Multiname[VariableBinding], value, false, run)
end if;
{staticCompiled} do nothing;
{staticRun} do
localFrame: Frame  env[0];
members: StaticMember{}  {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.
v: Variable  the one element of members;
value: ObjectOpt  Eval[VariableInitialisation](env, compile);
t: Class  v.type;
coercedValue: ObjectUninit;
if value  none then coercedValue  assignmentConversion(value, t)
elsif immutable then coercedValue  uninitialised
else coercedValue  assignmentConversion(undefined, t)
end if;
v.value  coercedValue;
{instanceRun} do nothing
end case
end proc;
proc Eval[VariableInitialisation] (env: Environment, phase: Phase): ObjectOpt
[VariableInitialisation  «empty»] do return none;
[VariableInitialisation  = VariableInitialiser] do
return Eval[VariableInitialiser](env, phase)
end proc;
proc Eval[VariableInitialiser] (env: Environment, phase: Phase): Object
[VariableInitialiser  AssignmentExpression] do
r: ObjOrRef  Eval[AssignmentExpression](env, phase);
return readReference(r, phase);
[VariableInitialiser  NonexpressionAttribute] do
return Eval[NonexpressionAttribute](env, phase);
[VariableInitialiser  AttributeCombination] do
return Eval[AttributeCombination](env, phase)
end proc;
proc Eval[TypedIdentifier] (env: Environment): ClassOpt
[TypedIdentifier  Identifier] do 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] (cxt: Context, env: Environment)
if cxt.strict or getRegionalFrame(env)  Global  FunctionFrame then
end if;
Validate[UntypedVariableBindingList](cxt, env)
end proc;
proc Validate[UntypedVariableBindingList] (cxt: Context, env: Environment)
[UntypedVariableBindingList  UntypedVariableBinding] do
Validate[UntypedVariableBinding](cxt, env);
Validate[UntypedVariableBindingList1](cxt, env);
Validate[UntypedVariableBinding](cxt, env)
end proc;
proc Validate[UntypedVariableBinding  Identifier VariableInitialisationallowIn] (cxt: Context, env: Environment)
Validate[VariableInitialisationallowIn](cxt, env);
end proc;

Evaluation

proc Eval[SimpleVariableDefinition  var UntypedVariableBindingList] (env: Environment, d: Object): Object
return d
end proc;
proc Eval[UntypedVariableBindingList] (env: Environment)
[UntypedVariableBindingList  UntypedVariableBinding] do
end proc;
proc Eval[UntypedVariableBinding  Identifier VariableInitialisationallowIn] (env: Environment)
value: ObjectOpt  Eval[VariableInitialisationallowIn](env, run);
if value  none then
qname: QualifiedName  QualifiedNamenamespace: publicNamespace, id: Name[Identifier];
lexicalWrite(env, {qname}, value, false, run)
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] (cxt: Context, env: Environment, pl: Plurality, attr: AttributeOptNotFalse)
if pl  singular then throw syntaxError end if;
superclass: Class  Validate[Inheritance](cxt, env);
if not superclass.complete or superclass.final then throw definitionError end if;
a: CompoundAttribute  toCompoundAttribute(attr);
if a.compile then throw definitionError end if;
proc call(this: Object, args: ArgumentList, phase: Phase): Object
????
end proc;
proc construct(this: Object, args: ArgumentList, phase: Phase): Object
????
end proc;
prototype: Object  null;
if a.prototype then ???? end if;
final: Boolean  false;
if a.memberMod = final then
final  true;
a  CompoundAttributememberMod: none, other fields from a
end if;
privateNamespace: Namespace  new Namespacename: “private”;
dynamic: Boolean  a.dynamic or superclass.dynamic;
c: Class  new ClassstaticReadBindings: {}, staticWriteBindings: {}, instanceReadBindings: {}, instanceWriteBindings: {}, instanceInitOrder: [], complete: false, super: superclass, prototype: prototype, privateNamespace: privateNamespace, dynamic: dynamic, primitive: false, final: final, call: call, construct: construct;
Class[ClassDefinition]  c;
proc makeStaticMember(): StaticMember
return new Variabletype: classClass, value: c, immutable: true
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] (cxt: Context, env: Environment): Class
[Inheritance  «empty»] do return objectClass;
[Inheritance  extends TypeExpressionallowIn] do
Validate[TypeExpressionallowIn](cxt, env);
return Eval[TypeExpressionallowIn](env);
[Inheritance  implements TypeExpressionList] do return objectClass;
[Inheritance  extends TypeExpressionallowIn implements TypeExpressionList] do
return objectClass
end proc;

Evaluation

proc Eval[ClassDefinition  class Identifier Inheritance Block] (env: Environment, d: Object): Object
c: Class  Class[ClassDefinition];
return EvalUsingFrame[Block](env, c, d)
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(superclass: ClassOpt, dynamic: Boolean, primitive: Boolean, final: Boolean): Class
proc call(this: Object, args: ArgumentList, phase: Phase): Object
????
end proc;
proc construct(this: Object, args: ArgumentList, phase: Phase): Object
????
end proc;
privateNamespace: Namespace  new Namespacename: “private”;
return new ClassstaticReadBindings: {}, staticWriteBindings: {}, instanceReadBindings: {}, instanceWriteBindings: {}, instanceInitOrder: [], complete: true, super: superclass, prototype: null, privateNamespace: privateNamespace, dynamic: dynamic, primitive: primitive, final: final, call: call, construct: construct
end proc;
objectClass: Class = makeBuiltInClass(none, false, true, false);
undefinedClass: Class = makeBuiltInClass(objectClass, false, true, true);
nullClass: Class = makeBuiltInClass(objectClass, false, true, true);
booleanClass: Class = makeBuiltInClass(objectClass, false, true, true);
numberClass: Class = makeBuiltInClass(objectClass, false, true, true);
stringClass: Class = makeBuiltInClass(objectClass, false, false, true);
characterClass: Class = makeBuiltInClass(stringClass, false, false, true);
namespaceClass: Class = makeBuiltInClass(objectClass, false, false, true);
attributeClass: Class = makeBuiltInClass(objectClass, false, false, true);
classClass: Class = makeBuiltInClass(objectClass, false, false, true);
functionClass: Class = makeBuiltInClass(objectClass, false, false, true);
prototypeClass: Class = makeBuiltInClass(objectClass, true, false, true);
packageClass: Class = makeBuiltInClass(objectClass, true, false, true);

Built-in Functions

Built-in Attributes

Built-in Operators

Unary Operators

proc plusObject(this: Object, a: Object, args: ArgumentList, phase: Phase): Object
return toNumber(a, phase)
end proc;
proc minusObject(this: Object, a: Object, args: ArgumentList, phase: Phase): Object
return float64Negate(toNumber(a, phase))
end proc;
proc bitwiseNotObject(this: Object, a: Object, args: ArgumentList, phase: Phase): Object
i: Integer  toInt32(toNumber(a, phase));
return realToFloat64(bitwiseXor(i, –1))
end proc;
proc incrementObject(this: Object, a: Object, args: ArgumentList, phase: Phase): Object
x: Object  unaryPlus(a, phase);
return binaryDispatch(addTable, x, 1.0, phase)
end proc;
proc decrementObject(this: Object, a: Object, args: ArgumentList, phase: Phase): Object
x: Object  unaryPlus(a, phase);
return binaryDispatch(subtractTable, x, 1.0, phase)
end proc;
proc callObject(this: Object, a: Object, args: ArgumentList, phase: Phase): Object
case a of
Undefined  Null  Boolean  Float64  String  Namespace  CompoundAttribute  Prototype  Package  Global do
Class do return a.call(this, args, phase);
Instance do return a.call(this, args, a.env, phase);
code: {abstract}  Instance  a.method.code;
case code of
Instance do return callObject(a.this, code, args, phase);
end case
end case
end proc;
proc constructObject(this: Object, a: Object, args: ArgumentList, phase: Phase): Object
case a of
Undefined  Null  Boolean  Float64  String  Namespace  CompoundAttribute  MethodClosure  Prototype  Package  Global do
Class do return a.construct(this, args, phase);
Instance do return a.construct(this, args, a.env, phase)
end case
end proc;
proc bracketReadObject(this: Object, a: Object, args: ArgumentList, phase: Phase): Object
if |args.positional|  1 or args.named  {} then throw argumentMismatchError end if;
name: String  toString(args.positional[0], phase);
result: ObjectOpt  readProperty(a, {QualifiedNamenamespace: publicNamespace, id: name}, propertyLookup, phase);
if result = none then throw propertyAccessError else return result end if
end proc;
proc bracketWriteObject(this: Object, a: Object, args: ArgumentList, phase: Phase): Object
if phase = compile then throw compileExpressionError end if;
if |args.positional|  2 or args.named  {} then throw argumentMismatchError end if;
newValue: Object  args.positional[0];
name: String  toString(args.positional[1], phase);
result: {none, ok}  writeProperty(a, {QualifiedNamenamespace: publicNamespace, id: name}, propertyLookup, true, newValue, phase);
if result = none then throw propertyAccessError end if;
return undefined
end proc;
proc bracketDeleteObject(this: Object, a: Object, args: ArgumentList, phase: Phase): Object
if phase = compile then throw compileExpressionError end if;
if |args.positional|  1 or args.named  {} then throw argumentMismatchError end if;
name: String  toString(args.positional[0], phase);
end proc;
plusTable: UnaryMethod{}  {UnaryMethodoperandType: objectClass, f: plusObject};
minusTable: UnaryMethod{}  {UnaryMethodoperandType: objectClass, f: minusObject};
bitwiseNotTable: UnaryMethod{}  {UnaryMethodoperandType: objectClass, f: bitwiseNotObject};
incrementTable: UnaryMethod{}  {UnaryMethodoperandType: objectClass, f: incrementObject};
decrementTable: UnaryMethod{}  {UnaryMethodoperandType: objectClass, f: decrementObject};
callTable: UnaryMethod{}  {UnaryMethodoperandType: objectClass, f: callObject};
constructTable: UnaryMethod{}  {UnaryMethodoperandType: objectClass, f: constructObject};
bracketReadTable: UnaryMethod{}  {UnaryMethodoperandType: objectClass, f: bracketReadObject};
bracketWriteTable: UnaryMethod{}  {UnaryMethodoperandType: objectClass, f: bracketWriteObject};
bracketDeleteTable: UnaryMethod{}  {UnaryMethodoperandType: objectClass, f: bracketDeleteObject};

Binary Operators

proc addObjects(a: Object, b: Object, phase: Phase): Object
ap: PrimitiveObject  toPrimitive(a, null, phase);
bp: PrimitiveObject  toPrimitive(b, null, phase);
if ap  String or bp  String then
return toString(ap, phase)  toString(bp, phase)
else return float64Add(toNumber(ap, phase), toNumber(bp, phase))
end if
end proc;
proc subtractObjects(a: Object, b: Object, phase: Phase): Object
return float64Subtract(toNumber(a, phase), toNumber(b, phase))
end proc;
proc multiplyObjects(a: Object, b: Object, phase: Phase): Object
return float64Multiply(toNumber(a, phase), toNumber(b, phase))
end proc;
proc divideObjects(a: Object, b: Object, phase: Phase): Object
return float64Divide(toNumber(a, phase), toNumber(b, phase))
end proc;
proc remainderObjects(a: Object, b: Object, phase: Phase): Object
return float64Remainder(toNumber(a, phase), toNumber(b, phase))
end proc;
proc lessObjects(a: Object, b: Object, phase: Phase): Object
ap: PrimitiveObject  toPrimitive(a, null, phase);
bp: PrimitiveObject  toPrimitive(b, null, phase);
if ap  String and bp  String then return ap < bp
else return float64Compare(toNumber(ap, phase), toNumber(bp, phase)) = less
end if
end proc;
proc lessOrEqualObjects(a: Object, b: Object, phase: Phase): Object
ap: PrimitiveObject  toPrimitive(a, null, phase);
bp: PrimitiveObject  toPrimitive(b, null, phase);
if ap  String and bp  String then return ap  bp
else return float64Compare(toNumber(ap, phase), toNumber(bp, phase))  {less, equal}
end if
end proc;
proc equalObjects(a: Object, b: Object, phase: Phase): Object
case a of
Undefined  Null do return b  Undefined  Null;
if b  Boolean then return a = b
else return equalObjects(toNumber(a, phase), b, phase)
end if;
bp: PrimitiveObject  toPrimitive(b, null, phase);
case bp of
Undefined  Null do return false;
Boolean  Float64  String do
return float64Compare(a, toNumber(bp, phase)) = equal
end case;
String do
bp: PrimitiveObject  toPrimitive(b, null, phase);
case bp of
Undefined  Null do return false;
Boolean  Float64 do
return float64Compare(toNumber(a, phase), toNumber(bp, phase)) = 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(a, b, phase);
Boolean  Float64  String do
ap: PrimitiveObject  toPrimitive(a, null, phase);
case ap of
Undefined  Null do return false;
Boolean  Float64  String do return equalObjects(ap, b, phase)
end case
end case
end case
end proc;
proc strictEqualObjects(a: Object, b: Object, phase: Phase): Object
if a  Float64 and b  Float64 then return float64Compare(a, b) = equal
else return a = b
end if
end proc;
proc shiftLeftObjects(a: Object, b: Object, phase: Phase): Object
i: Integer  toUInt32(toNumber(a, phase));
count: Integer  bitwiseAnd(toUInt32(toNumber(b, phase)), 0x1F);
return realToFloat64(uInt32ToInt32(bitwiseAnd(bitwiseShift(i, count), 0xFFFFFFFF)))
end proc;
proc shiftRightObjects(a: Object, b: Object, phase: Phase): Object
i: Integer  toInt32(toNumber(a, phase));
count: Integer  bitwiseAnd(toUInt32(toNumber(b, phase)), 0x1F);
return realToFloat64(bitwiseShift(i, –count))
end proc;
proc shiftRightUnsignedObjects(a: Object, b: Object, phase: Phase): Object
i: Integer  toUInt32(toNumber(a, phase));
count: Integer  bitwiseAnd(toUInt32(toNumber(b, phase)), 0x1F);
return realToFloat64(bitwiseShift(i, –count))
end proc;
proc bitwiseAndObjects(a: Object, b: Object, phase: Phase): Object
i: Integer  toInt32(toNumber(a, phase));
j: Integer  toInt32(toNumber(b, phase));
return realToFloat64(bitwiseAnd(i, j))
end proc;
proc bitwiseXorObjects(a: Object, b: Object, phase: Phase): Object
i: Integer  toInt32(toNumber(a, phase));
j: Integer  toInt32(toNumber(b, phase));
return realToFloat64(bitwiseXor(i, j))
end proc;
proc bitwiseOrObjects(a: Object, b: Object, phase: Phase): Object
i: Integer  toInt32(toNumber(a, phase));
j: Integer  toInt32(toNumber(b, phase));
return realToFloat64(bitwiseOr(i, j))
end proc;
addTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: addObjects};
subtractTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: subtractObjects};
multiplyTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: multiplyObjects};
divideTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: divideObjects};
remainderTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: remainderObjects};
lessTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: lessObjects};
lessOrEqualTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: lessOrEqualObjects};
equalTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: equalObjects};
strictEqualTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: strictEqualObjects};
shiftLeftTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: shiftLeftObjects};
shiftRightTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: shiftRightObjects};
shiftRightUnsignedTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: shiftRightUnsignedObjects};
bitwiseAndTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: bitwiseAndObjects};
bitwiseXorTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: bitwiseXorObjects};
bitwiseOrTable: BinaryMethod{}  {BinaryMethodleftType: objectClass, rightType: objectClass, f: bitwiseOrObjects};

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