Formal JavaScript Semantics
Grammar
previousup

Wednesday, February 28, 2001

Types

Semantics

type Value
  = oneof {
           undefinedValue;
           nullValue;
           booleanValueBoolean;
           numberValueFloat64;
           stringValueString;
           objectValueObject}
type ObjectOrNull = oneof {nullObjectOrNullobjectObjectOrNullObject}
type Object
  = tuple {
           propertiesProperty[];
           typeofNameString;
           prototypeObjectOrNull;
           getPropName  ValueOrException;
           putPropName  Value  VoidOrException;
           deletePropName  BooleanOrException;
           callObjectOrNull  Value[]  ReferenceOrException;
           constructValue[]  ObjectOrException;
           defaultValueDefaultValueHint  ValueOrException}
type DefaultValueHint = oneof {noHintnumberHintstringHint}
type Property
  = tuple {
           nameString;
           readOnlyBoolean;
           enumerableBoolean;
           permanentBoolean;
           valueValue}
type PropName = String
type Place = tuple {baseObjectpropertyPropName}
type Reference
  = oneof {valueReferenceValueplaceReferencePlacevirtualReferencePropName}
type IntegerOrException = oneof {normalIntegerabruptException}
type VoidOrException = oneof {normalabruptException}
type BooleanOrException = oneof {normalBooleanabruptException}
type Float64OrException = oneof {normalFloat64abruptException}
type StringOrException = oneof {normalStringabruptException}
type ObjectOrException = oneof {normalObjectabruptException}
type ValueOrException = oneof {normalValueabruptException}
type ReferenceOrException = oneof {normalReferenceabruptException}
type ValueListOrException = oneof {normalValue[]; abruptException}

Helper Functions

Semantics

objectOrNullToValue(oObjectOrNull) : Value
  = case o of
        nullObjectOrNullnullValue;
        objectObjectOrNull(objObject): objectValue obj
        end
undefinedResult : ValueOrException = normal undefinedValue
nullResult : ValueOrException = normal nullValue
booleanResult(bBoolean) : ValueOrException = normal booleanValue b
float64Result(dFloat64) : ValueOrException = normal numberValue d
integerResult(iInteger) : ValueOrException = float64Result(rationalToFloat64(i))
stringResult(sString) : ValueOrException = normal stringValue s
objectResult(oObject) : ValueOrException = normal objectValue o

Exceptions

Semantics

type Exception = oneof {exceptionValueerrorError}
type Error
  = oneof {
           coerceToPrimitiveError;
           coerceToObjectError;
           getValueError;
           putValueError;
           deleteError}
makeError(errError) : Exception = error err

Objects

Conversions

Semantics

referenceGetValue(rvReference) : ValueOrException
  = case rv of
        valueReference(vValue): normal v;
        placeReference(rPlace): r.base.get(r.property);
        virtualReferenceabruptValueOrException makeError(getValueError)
        end
referencePutValue(rvReferencevValue) : VoidOrException
  = case rv of
        valueReferenceabruptVoidOrException makeError(putValueError);
        placeReference(rPlace): r.base.put(r.propertyv);
        virtualReference
        end

Coercions

Semantics

coerceToBoolean(vValue) : Boolean
  = case v of
        undefinedValuenullValuefalse;
        booleanValue(bBoolean): b;
        numberValue(dFloat64): not (float64IsZero(dor float64IsNaN(d));
        stringValue(sString): |s 0;
        objectValuetrue
        end
coerceBooleanToFloat64(bBoolean) : Float64 = if b then 1.0 else +0.0
coerceToFloat64(vValue) : Float64OrException
  = case v of
        undefinedValuenormal NaN;
        nullValuenormal +0.0;
        booleanValue(bBoolean): normal coerceBooleanToFloat64(b);
        numberValue(dFloat64): normal d;
        stringValue;
        objectValue
        end
float64ToUint32(xFloat64) : Integer
  = if float64IsNaN(xor float64IsInfinite(xthen 0 else truncateFloat64(x)mod4294967296
coerceToUint32(vValue) : IntegerOrException
  = letexc dFloat64 = coerceToFloat64(v)
     in normal float64ToUint32(d)
coerceToInt32(vValue) : IntegerOrException
  = letexc dFloat64 = coerceToFloat64(v)
     in normal uint32ToInt32(float64ToUint32(d))
uint32ToInt32(uiInteger) : Integer = if ui < 2147483648 then ui else ui - 4294967296
coerceToString(vValue) : StringOrException
  = case v of
        undefinedValuenormal “undefined”;
        nullValuenormal “null”;
        booleanValue(bBoolean): if b then normal “true” else normal “false”;
        numberValue;
        stringValue(sString): normal s;
        objectValue
        end
coerceToPrimitive(vValuehintDefaultValueHint) : ValueOrException
  = case v of
        undefinedValuenullValuebooleanValuenumberValuestringValuenormal v;
        objectValue(oObject):
              letexc pvValue = o.defaultValue(hint)
              in case pv of
                     undefinedValuenullValuebooleanValuenumberValuestringValue:
                           normal pv;
                     objectValueabruptValueOrException makeError(coerceToPrimitiveError)
                     end
        end
coerceToObject(vValue) : ObjectOrException
  = case v of
        undefinedValuenullValueabruptObjectOrException makeError(coerceToObjectError);
        booleanValue;
        numberValue;
        stringValue;
        objectValue(oObject): normal o
        end

Environments

Semantics

type Env = tuple {thisObjectOrNull}
lookupIdentifier(eEnvidString) : ReferenceOrException = 

Terminal Actions

Semantics

action EvalIdentifier[Identifier] : String
action EvalNumber[Number] : Float64
action EvalString[String] : String

Primary Expressions

Syntax

PrimaryRvalue 
   this
|  null
|  true
|  false
|  Number
|  String
|  ( CommaExpressionnoLValue )
PrimaryLvalue 
   Identifier
|  ( Lvalue )

Semantics

action Eval[PrimaryRvalue] : Env  ValueOrException
Eval[PrimaryRvalue  this](eEnv) = normal objectOrNullToValue(e.this)
Eval[PrimaryRvalue  null](eEnv) = nullResult
Eval[PrimaryRvalue  true](eEnv) = booleanResult(true)
Eval[PrimaryRvalue  false](eEnv) = booleanResult(false)
Eval[PrimaryRvalue  Number](eEnv) = float64Result(EvalNumber[Number])
Eval[PrimaryRvalue  String](eEnv) = stringResult(EvalString[String])
Eval[PrimaryRvalue  ( CommaExpressionnoLValue )] = Eval[CommaExpressionnoLValue]
action Eval[PrimaryLvalue] : Env  ReferenceOrException
Eval[PrimaryLvalue  Identifier](eEnv)
  = lookupIdentifier(eEvalIdentifier[Identifier])
Eval[PrimaryLvalue  ( Lvalue )] = Eval[Lvalue]

Left-Side Expressions

Syntax

ExprKind  {anyValuenoLValue}
MemberExprKind  {callnoCall}
MemberLvaluenoCall 
   PrimaryLvalue
|  MemberExpressionnoCall,anyValue [ Expression ]
|  MemberExpressionnoCall,anyValue . Identifier
MemberLvaluecall 
   Lvalue Arguments
|  MemberExpressionnoCall,noLValue Arguments
|  MemberExpressioncall,anyValue [ Expression ]
|  MemberExpressioncall,anyValue . Identifier
MemberExpressionnoCall,noLValue 
   PrimaryRvalue
|  new MemberExpressionnoCall,anyValue Arguments
MemberExpressionnoCall,anyValue 
   PrimaryRvalue
|  MemberLvaluenoCall
|  new MemberExpressionnoCall,anyValue Arguments
MemberExpressioncall,anyValue  MemberLvaluecall
NewExpressionExprKind 
   MemberExpressionnoCall,ExprKind
|  new NewExpressionanyValue
Arguments 
   ( )
|  ( ArgumentList )
ArgumentList 
   AssignmentExpressionanyValue
|  ArgumentList , AssignmentExpressionanyValue
Lvalue 
   MemberLvaluecall
|  MemberLvaluenoCall

Semantics

action Eval[MemberLvalueMemberExprKind] : Env  ReferenceOrException
Eval[MemberLvaluenoCall  PrimaryLvalue] = Eval[PrimaryLvalue]
Eval[MemberLvaluecall  Lvalue Arguments](eEnv)
  = letexc fReferenceReference = Eval[Lvalue](e)
     in letexc fValue = referenceGetValue(fReference)
     in letexc argumentsValue[] = Eval[Arguments](e)
     in let thisObjectOrNull
             = case fReference of
                   valueReferencevirtualReferencenullObjectOrNull;
                   placeReference(pPlace): objectObjectOrNull p.base
                   end
     in callObject(fthisarguments)
Eval[MemberLvaluecall  MemberExpressionnoCall,noLValue Arguments](eEnv)
  = letexc fValue = Eval[MemberExpressionnoCall,noLValue](e)
     in letexc argumentsValue[] = Eval[Arguments](e)
     in callObject(fnullObjectOrNullarguments)
Eval[MemberLvalueMemberExprKind  MemberExpressionMemberExprKind,anyValue [ Expression ]]
            (eEnv)
  = letexc containerValue = Eval[MemberExpressionMemberExprKind,anyValue](e)
     in letexc propertyValue = Eval[Expression](e)
     in readProperty(containerproperty)
Eval[MemberLvalueMemberExprKind  MemberExpressionMemberExprKind,anyValue . Identifier]
            (eEnv)
  = letexc containerValue = Eval[MemberExpressionMemberExprKind,anyValue](e)
     in readProperty(containerstringValue EvalIdentifier[Identifier])
action Eval[MemberExpressionMemberExprKind,ExprKind] : Env  ValueOrException
Eval[MemberExpressionnoCall,ExprKind  PrimaryRvalue] = Eval[PrimaryRvalue]
Eval[MemberExpressionMemberExprKind,anyValue  MemberLvalueMemberExprKind](eEnv)
  = letexc refReference = Eval[MemberLvalueMemberExprKind](e)
     in referenceGetValue(ref)
Eval[MemberExpressionnoCall,ExprKind  new MemberExpressionnoCall,anyValue1 Arguments]
            (eEnv)
  = letexc constructorValue = Eval[MemberExpressionnoCall,anyValue1](e)
     in letexc argumentsValue[] = Eval[Arguments](e)
     in constructObject(constructorarguments)
action Eval[NewExpressionExprKind] : Env  ValueOrException
Eval[NewExpressionExprKind  MemberExpressionnoCall,ExprKind]
  = Eval[MemberExpressionnoCall,ExprKind]
Eval[NewExpressionExprKind  new NewExpressionanyValue1](eEnv)
  = letexc constructorValue = Eval[NewExpressionanyValue1](e)
     in constructObject(constructor[]Value)
action Eval[Arguments] : Env  ValueListOrException
Eval[Arguments  ( )](eEnv) = normal []Value
Eval[Arguments  ( ArgumentList )] = Eval[ArgumentList]
action Eval[ArgumentList] : Env  ValueListOrException
Eval[ArgumentList  AssignmentExpressionanyValue](eEnv)
  = letexc argValue = Eval[AssignmentExpressionanyValue](e)
     in normal [arg]
Eval[ArgumentList  ArgumentList1 , AssignmentExpressionanyValue](eEnv)
  = letexc argsValue[] = Eval[ArgumentList1](e)
     in letexc argValue = Eval[AssignmentExpressionanyValue](e)
     in normal (args  [arg])
action Eval[Lvalue] : Env  ReferenceOrException
Eval[Lvalue  MemberLvaluecall] = Eval[MemberLvaluecall]
Eval[Lvalue  MemberLvaluenoCall] = Eval[MemberLvaluenoCall]
readProperty(containerValuepropertyValue) : ReferenceOrException
  = letexc objObject = coerceToObject(container)
     in letexc namePropName = coerceToString(property)
     in normal placeReference base  objproperty  name
callObject(fValuethisObjectOrNullargumentsValue[]) : ReferenceOrException
  = case f of
        undefinedValuenullValuebooleanValuenumberValuestringValue:
              abruptReferenceOrException makeError(coerceToObjectError);
        objectValue(oObject): o.call(thisarguments)
        end
constructObject(constructorValueargumentsValue[]) : ValueOrException
  = case constructor of
        undefinedValuenullValuebooleanValuenumberValuestringValue:
              abruptValueOrException makeError(coerceToObjectError);
        objectValue(oObject):
              letexc resObject = o.construct(arguments)
              in objectResult(res)
        end

Postfix Expressions

Syntax

PostfixExpressionanyValue 
   NewExpressionanyValue
|  MemberExpressioncall,anyValue
|  Lvalue ++
|  Lvalue --
PostfixExpressionnoLValue 
   NewExpressionnoLValue
|  Lvalue ++
|  Lvalue --

Semantics

action Eval[PostfixExpressionExprKind] : Env  ValueOrException
Eval[PostfixExpressionExprKind  NewExpressionExprKind] = Eval[NewExpressionExprKind]
Eval[PostfixExpressionanyValue  MemberExpressioncall,anyValue]
  = Eval[MemberExpressioncall,anyValue]
Eval[PostfixExpressionExprKind  Lvalue ++](eEnv)
  = letexc operandReferenceReference = Eval[Lvalue](e)
     in letexc operandValueValue = referenceGetValue(operandReference)
     in letexc operandFloat64 = coerceToFloat64(operandValue)
     in letexc uVoid
                  = referencePutValue(operandReferencenumberValue float64Add(operand, 1.0))
     in float64Result(operand)
Eval[PostfixExpressionExprKind  Lvalue --](eEnv)
  = letexc operandReferenceReference = Eval[Lvalue](e)
     in letexc operandValueValue = referenceGetValue(operandReference)
     in letexc operandFloat64 = coerceToFloat64(operandValue)
     in letexc uVoid
                  = referencePutValue(
                         operandReference,
                         numberValue float64Subtract(operand, 1.0))
     in float64Result(operand)

Unary Operators

Syntax

UnaryExpressionExprKind 
   PostfixExpressionExprKind
|  delete Lvalue
|  void UnaryExpressionanyValue
|  typeof Lvalue
|  typeof UnaryExpressionnoLValue
|  ++ Lvalue
|  -- Lvalue
|  + UnaryExpressionanyValue
|  - UnaryExpressionanyValue
|  ~ UnaryExpressionanyValue
|  ! UnaryExpressionanyValue

Semantics

action Eval[UnaryExpressionExprKind] : Env  ValueOrException
Eval[UnaryExpressionExprKind  PostfixExpressionExprKind]
  = Eval[PostfixExpressionExprKind]
Eval[UnaryExpressionExprKind  delete Lvalue](eEnv)
  = letexc rvReference = Eval[Lvalue](e)
     in case rv of
            valueReferenceabruptValueOrException makeError(deleteError);
            placeReference(rPlace):
                  letexc bBoolean = r.base.delete(r.property)
                  in booleanResult(b);
            virtualReferencebooleanResult(true)
            end
Eval[UnaryExpressionExprKind  void UnaryExpressionanyValue1](eEnv)
  = letexc operandValue = Eval[UnaryExpressionanyValue1](e)
     in undefinedResult
Eval[UnaryExpressionExprKind  typeof Lvalue](eEnv)
  = letexc rvReference = Eval[Lvalue](e)
     in case rv of
            valueReference(vValue): stringResult(valueTypeof(v));
            placeReference(rPlace):
                  letexc vValue = r.base.get(r.property)
                  in stringResult(valueTypeof(v));
            virtualReferencestringResult(“undefined”)
            end
Eval[UnaryExpressionExprKind  typeof UnaryExpressionnoLValue1](eEnv)
  = letexc vValue = Eval[UnaryExpressionnoLValue1](e)
     in stringResult(valueTypeof(v))
Eval[UnaryExpressionExprKind  ++ Lvalue](eEnv)
  = letexc operandReferenceReference = Eval[Lvalue](e)
     in letexc operandValueValue = referenceGetValue(operandReference)
     in letexc operandFloat64 = coerceToFloat64(operandValue)
     in let resFloat64 = float64Add(operand, 1.0)
     in letexc uVoid = referencePutValue(operandReferencenumberValue res)
     in float64Result(res)
Eval[UnaryExpressionExprKind  -- Lvalue](eEnv)
  = letexc operandReferenceReference = Eval[Lvalue](e)
     in letexc operandValueValue = referenceGetValue(operandReference)
     in letexc operandFloat64 = coerceToFloat64(operandValue)
     in let resFloat64 = float64Subtract(operand, 1.0)
     in letexc uVoid = referencePutValue(operandReferencenumberValue res)
     in float64Result(res)
Eval[UnaryExpressionExprKind  + UnaryExpressionanyValue1](eEnv)
  = letexc operandValueValue = Eval[UnaryExpressionanyValue1](e)
     in letexc operandFloat64 = coerceToFloat64(operandValue)
     in float64Result(operand)
Eval[UnaryExpressionExprKind  - UnaryExpressionanyValue1](eEnv)
  = letexc operandValueValue = Eval[UnaryExpressionanyValue1](e)
     in letexc operandFloat64 = coerceToFloat64(operandValue)
     in float64Result(float64Negate(operand))
Eval[UnaryExpressionExprKind  ~ UnaryExpressionanyValue1](eEnv)
  = letexc operandValueValue = Eval[UnaryExpressionanyValue1](e)
     in letexc operandInteger = coerceToInt32(operandValue)
     in integerResult(bitwiseXor(operand, -1))
Eval[UnaryExpressionExprKind  ! UnaryExpressionanyValue1](eEnv)
  = letexc operandValueValue = Eval[UnaryExpressionanyValue1](e)
     in booleanResult(not coerceToBoolean(operandValue))
valueTypeof(vValue) : String
  = case v of
        undefinedValue: “undefined”;
        nullValue: “object”;
        booleanValue: “boolean”;
        numberValue: “number”;
        stringValue: “string”;
        objectValue(oObject): o.typeofName
        end

Multiplicative Operators

Syntax

MultiplicativeExpressionExprKind 
   UnaryExpressionExprKind
|  MultiplicativeExpressionanyValue * UnaryExpressionanyValue
|  MultiplicativeExpressionanyValue / UnaryExpressionanyValue
|  MultiplicativeExpressionanyValue % UnaryExpressionanyValue

Semantics

action Eval[MultiplicativeExpressionExprKind] : Env  ValueOrException
Eval[MultiplicativeExpressionExprKind  UnaryExpressionExprKind]
  = Eval[UnaryExpressionExprKind]
Eval[MultiplicativeExpressionExprKind  MultiplicativeExpressionanyValue1 * UnaryExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[MultiplicativeExpressionanyValue1](e)
     in letexc rightValueValue = Eval[UnaryExpressionanyValue](e)
     in applyBinaryFloat64Operator(float64MultiplyleftValuerightValue)
Eval[MultiplicativeExpressionExprKind  MultiplicativeExpressionanyValue1 / UnaryExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[MultiplicativeExpressionanyValue1](e)
     in letexc rightValueValue = Eval[UnaryExpressionanyValue](e)
     in applyBinaryFloat64Operator(float64DivideleftValuerightValue)
Eval[MultiplicativeExpressionExprKind  MultiplicativeExpressionanyValue1 % UnaryExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[MultiplicativeExpressionanyValue1](e)
     in letexc rightValueValue = Eval[UnaryExpressionanyValue](e)
     in applyBinaryFloat64Operator(float64RemainderleftValuerightValue)
applyBinaryFloat64Operator(operatorFloat64  Float64  Float64,
        leftValueValue,
        rightValueValue) : ValueOrException
  = letexc leftNumberFloat64 = coerceToFloat64(leftValue)
     in letexc rightNumberFloat64 = coerceToFloat64(rightValue)
     in float64Result(operator(leftNumberrightNumber))

Additive Operators

Syntax

AdditiveExpressionExprKind 
   MultiplicativeExpressionExprKind
|  AdditiveExpressionanyValue + MultiplicativeExpressionanyValue
|  AdditiveExpressionanyValue - MultiplicativeExpressionanyValue

Semantics

action Eval[AdditiveExpressionExprKind] : Env  ValueOrException
Eval[AdditiveExpressionExprKind  MultiplicativeExpressionExprKind]
  = Eval[MultiplicativeExpressionExprKind]
Eval[AdditiveExpressionExprKind  AdditiveExpressionanyValue1 + MultiplicativeExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[AdditiveExpressionanyValue1](e)
     in letexc rightValueValue = Eval[MultiplicativeExpressionanyValue](e)
     in letexc leftPrimitiveValue = coerceToPrimitive(leftValuenoHint)
     in letexc rightPrimitiveValue = coerceToPrimitive(rightValuenoHint)
     in if leftPrimitive is stringValue or rightPrimitive is stringValue
         then letexc leftStringString = coerceToString(leftPrimitive)
                in letexc rightStringString = coerceToString(rightPrimitive)
                in stringResult(leftString  rightString)
         else applyBinaryFloat64Operator(float64AddleftPrimitiverightPrimitive)
Eval[AdditiveExpressionExprKind  AdditiveExpressionanyValue1 - MultiplicativeExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[AdditiveExpressionanyValue1](e)
     in letexc rightValueValue = Eval[MultiplicativeExpressionanyValue](e)
     in applyBinaryFloat64Operator(float64SubtractleftValuerightValue)

Bitwise Shift Operators

Syntax

ShiftExpressionExprKind 
   AdditiveExpressionExprKind
|  ShiftExpressionanyValue << AdditiveExpressionanyValue
|  ShiftExpressionanyValue >> AdditiveExpressionanyValue
|  ShiftExpressionanyValue >>> AdditiveExpressionanyValue

Semantics

action Eval[ShiftExpressionExprKind] : Env  ValueOrException
Eval[ShiftExpressionExprKind  AdditiveExpressionExprKind]
  = Eval[AdditiveExpressionExprKind]
Eval[ShiftExpressionExprKind  ShiftExpressionanyValue1 << AdditiveExpressionanyValue]
            (eEnv)
  = letexc bitmapValueValue = Eval[ShiftExpressionanyValue1](e)
     in letexc countValueValue = Eval[AdditiveExpressionanyValue](e)
     in letexc bitmapInteger = coerceToUint32(bitmapValue)
     in letexc countInteger = coerceToUint32(countValue)
     in integerResult(
             uint32ToInt32(bitwiseAnd(bitwiseShift(bitmapbitwiseAnd(count, 31)), 4294967295)))
Eval[ShiftExpressionExprKind  ShiftExpressionanyValue1 >> AdditiveExpressionanyValue]
            (eEnv)
  = letexc bitmapValueValue = Eval[ShiftExpressionanyValue1](e)
     in letexc countValueValue = Eval[AdditiveExpressionanyValue](e)
     in letexc bitmapInteger = coerceToInt32(bitmapValue)
     in letexc countInteger = coerceToUint32(countValue)
     in integerResult(bitwiseShift(bitmap, -bitwiseAnd(count, 31)))
Eval[ShiftExpressionExprKind  ShiftExpressionanyValue1 >>> AdditiveExpressionanyValue]
            (eEnv)
  = letexc bitmapValueValue = Eval[ShiftExpressionanyValue1](e)
     in letexc countValueValue = Eval[AdditiveExpressionanyValue](e)
     in letexc bitmapInteger = coerceToUint32(bitmapValue)
     in letexc countInteger = coerceToUint32(countValue)
     in integerResult(bitwiseShift(bitmap, -bitwiseAnd(count, 31)))

Relational Operators

Syntax

RelationalExpressionExprKind 
   ShiftExpressionExprKind
|  RelationalExpressionanyValue < ShiftExpressionanyValue
|  RelationalExpressionanyValue > ShiftExpressionanyValue
|  RelationalExpressionanyValue <= ShiftExpressionanyValue
|  RelationalExpressionanyValue >= ShiftExpressionanyValue

Semantics

action Eval[RelationalExpressionExprKind] : Env  ValueOrException
Eval[RelationalExpressionExprKind  ShiftExpressionExprKind]
  = Eval[ShiftExpressionExprKind]
Eval[RelationalExpressionExprKind  RelationalExpressionanyValue1 < ShiftExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[RelationalExpressionanyValue1](e)
     in letexc rightValueValue = Eval[ShiftExpressionanyValue](e)
     in orderValues(leftValuerightValuetruefalse)
Eval[RelationalExpressionExprKind  RelationalExpressionanyValue1 > ShiftExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[RelationalExpressionanyValue1](e)
     in letexc rightValueValue = Eval[ShiftExpressionanyValue](e)
     in orderValues(rightValueleftValuetruefalse)
Eval[RelationalExpressionExprKind  RelationalExpressionanyValue1 <= ShiftExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[RelationalExpressionanyValue1](e)
     in letexc rightValueValue = Eval[ShiftExpressionanyValue](e)
     in orderValues(rightValueleftValuefalsetrue)
Eval[RelationalExpressionExprKind  RelationalExpressionanyValue1 >= ShiftExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[RelationalExpressionanyValue1](e)
     in letexc rightValueValue = Eval[ShiftExpressionanyValue](e)
     in orderValues(leftValuerightValuefalsetrue)
orderValues(leftValueValuerightValueValuelessBooleangreaterOrEqualBoolean)
  : ValueOrException
  = letexc leftPrimitiveValue = coerceToPrimitive(leftValuenumberHint)
     in letexc rightPrimitiveValue = coerceToPrimitive(rightValuenumberHint)
     in if leftPrimitive is stringValue and rightPrimitive is stringValue
         then booleanResult(
                    compareStrings(
                        leftPrimitive.stringValue,
                        rightPrimitive.stringValue,
                        less,
                        greaterOrEqual,
                        greaterOrEqual))
         else letexc leftNumberFloat64 = coerceToFloat64(leftPrimitive)
               in letexc rightNumberFloat64 = coerceToFloat64(rightPrimitive)
               in booleanResult(
                       float64Compare(
                           leftNumber,
                           rightNumber,
                           less,
                           greaterOrEqual,
                           greaterOrEqual,
                           false))
compareStrings(leftString,
        rightString,
        lessBoolean,
        equalBoolean,
        greaterBoolean) : Boolean
  = if |left| = 0 and |right| = 0
     then equal
     else if |left| = 0
     then less
     else if |right| = 0
     then greater
     else let leftCharCodeInteger = characterToCode(left[0]);
               rightCharCodeInteger = characterToCode(right[0])
           in if leftCharCode < rightCharCode
               then less
               else if leftCharCode > rightCharCode
               then greater
               else compareStrings(left[1 ...], right[1 ...], lessequalgreater)

Equality Operators

Syntax

EqualityExpressionExprKind 
   RelationalExpressionExprKind
|  EqualityExpressionanyValue == RelationalExpressionanyValue
|  EqualityExpressionanyValue != RelationalExpressionanyValue
|  EqualityExpressionanyValue === RelationalExpressionanyValue
|  EqualityExpressionanyValue !== RelationalExpressionanyValue

Semantics

action Eval[EqualityExpressionExprKind] : Env  ValueOrException
Eval[EqualityExpressionExprKind  RelationalExpressionExprKind]
  = Eval[RelationalExpressionExprKind]
Eval[EqualityExpressionExprKind  EqualityExpressionanyValue1 == RelationalExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[EqualityExpressionanyValue1](e)
     in letexc rightValueValue = Eval[RelationalExpressionanyValue](e)
     in letexc eqBoolean = compareValues(leftValuerightValue)
     in booleanResult(eq)
Eval[EqualityExpressionExprKind  EqualityExpressionanyValue1 != RelationalExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[EqualityExpressionanyValue1](e)
     in letexc rightValueValue = Eval[RelationalExpressionanyValue](e)
     in letexc eqBoolean = compareValues(leftValuerightValue)
     in booleanResult(not eq)
Eval[EqualityExpressionExprKind  EqualityExpressionanyValue1 === RelationalExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[EqualityExpressionanyValue1](e)
     in letexc rightValueValue = Eval[RelationalExpressionanyValue](e)
     in booleanResult(strictCompareValues(leftValuerightValue))
Eval[EqualityExpressionExprKind  EqualityExpressionanyValue1 !== RelationalExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[EqualityExpressionanyValue1](e)
     in letexc rightValueValue = Eval[RelationalExpressionanyValue](e)
     in booleanResult(not strictCompareValues(leftValuerightValue))
compareValues(leftValueValuerightValueValue) : BooleanOrException
  = case leftValue of
        undefinedValuenullValue:
              case rightValue of
                 undefinedValuenullValuenormal true;
                 booleanValuenumberValuestringValueobjectValuenormal false
                 end;
        booleanValue(leftBoolBoolean):
              case rightValue of
                 undefinedValuenullValuenormal false;
                 booleanValue(rightBoolBoolean): normal (not (leftBool xor rightBool));
                 numberValuestringValueobjectValue:
                       compareFloat64ToValue(coerceBooleanToFloat64(leftBool), rightValue)
                 end;
        numberValue(leftNumberFloat64): compareFloat64ToValue(leftNumberrightValue);
        stringValue(leftStrString):
              case rightValue of
                 undefinedValuenullValuenormal false;
                 booleanValue(rightBoolBoolean):
                       letexc leftNumberFloat64 = coerceToFloat64(leftValue)
                       in normal float64Equal(leftNumbercoerceBooleanToFloat64(rightBool));
                 numberValue(rightNumberFloat64):
                       letexc leftNumberFloat64 = coerceToFloat64(leftValue)
                       in normal float64Equal(leftNumberrightNumber);
                 stringValue(rightStrString):
                       normal compareStrings(leftStrrightStrfalsetruefalse);
                 objectValue:
                       letexc rightPrimitiveValue = coerceToPrimitive(rightValuenoHint)
                       in compareValues(leftValuerightPrimitive)
                 end;
        objectValue(leftObjObject):
              case rightValue of
                 undefinedValuenullValuenormal false;
                 booleanValue(rightBoolBoolean):
                       letexc leftPrimitiveValue = coerceToPrimitive(leftValuenoHint)
                       in compareValues(
                               leftPrimitive,
                               numberValue coerceBooleanToFloat64(rightBool));
                 numberValuestringValue:
                       letexc leftPrimitiveValue = coerceToPrimitive(leftValuenoHint)
                       in compareValues(leftPrimitiverightValue);
                 objectValue(rightObjObject):
                       normal (leftObj.properties  rightObj.properties)
                 end
        end
compareFloat64ToValue(leftNumberFloat64rightValueValue) : BooleanOrException
  = case rightValue of
        undefinedValuenullValuenormal false;
        booleanValuenumberValuestringValue:
              letexc rightNumberFloat64 = coerceToFloat64(rightValue)
              in normal float64Equal(leftNumberrightNumber);
        objectValue:
              letexc rightPrimitiveValue = coerceToPrimitive(rightValuenoHint)
              in compareFloat64ToValue(leftNumberrightPrimitive)
        end
float64Equal(xFloat64yFloat64) : Boolean
  = float64Compare(xyfalsetruefalsefalse)
strictCompareValues(leftValueValuerightValueValue) : Boolean
  = case leftValue of
        undefinedValuerightValue is undefinedValue;
        nullValuerightValue is nullValue;
        booleanValue(leftBoolBoolean):
              case rightValue of
                 booleanValue(rightBoolBoolean): not (leftBool xor rightBool);
                 undefinedValuenullValuenumberValuestringValueobjectValuefalse
                 end;
        numberValue(leftNumberFloat64):
              case rightValue of
                 numberValue(rightNumberFloat64): float64Equal(leftNumberrightNumber);
                 undefinedValuenullValuebooleanValuestringValueobjectValuefalse
                 end;
        stringValue(leftStrString):
              case rightValue of
                 stringValue(rightStrString):
                       compareStrings(leftStrrightStrfalsetruefalse);
                 undefinedValuenullValuebooleanValuenumberValueobjectValuefalse
                 end;
        objectValue(leftObjObject):
              case rightValue of
                 objectValue(rightObjObject): leftObj.properties  rightObj.properties;
                 undefinedValuenullValuebooleanValuenumberValuestringValuefalse
                 end
        end

Binary Bitwise Operators

Syntax

BitwiseAndExpressionExprKind 
   EqualityExpressionExprKind
|  BitwiseAndExpressionanyValue & EqualityExpressionanyValue
BitwiseXorExpressionExprKind 
   BitwiseAndExpressionExprKind
|  BitwiseXorExpressionanyValue ^ BitwiseAndExpressionanyValue
BitwiseOrExpressionExprKind 
   BitwiseXorExpressionExprKind
|  BitwiseOrExpressionanyValue | BitwiseXorExpressionanyValue

Semantics

action Eval[BitwiseAndExpressionExprKind] : Env  ValueOrException
Eval[BitwiseAndExpressionExprKind  EqualityExpressionExprKind]
  = Eval[EqualityExpressionExprKind]
Eval[BitwiseAndExpressionExprKind  BitwiseAndExpressionanyValue1 & EqualityExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[BitwiseAndExpressionanyValue1](e)
     in letexc rightValueValue = Eval[EqualityExpressionanyValue](e)
     in applyBinaryBitwiseOperator(bitwiseAndleftValuerightValue)
action Eval[BitwiseXorExpressionExprKind] : Env  ValueOrException
Eval[BitwiseXorExpressionExprKind  BitwiseAndExpressionExprKind]
  = Eval[BitwiseAndExpressionExprKind]
Eval[BitwiseXorExpressionExprKind  BitwiseXorExpressionanyValue1 ^ BitwiseAndExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[BitwiseXorExpressionanyValue1](e)
     in letexc rightValueValue = Eval[BitwiseAndExpressionanyValue](e)
     in applyBinaryBitwiseOperator(bitwiseXorleftValuerightValue)
action Eval[BitwiseOrExpressionExprKind] : Env  ValueOrException
Eval[BitwiseOrExpressionExprKind  BitwiseXorExpressionExprKind]
  = Eval[BitwiseXorExpressionExprKind]
Eval[BitwiseOrExpressionExprKind  BitwiseOrExpressionanyValue1 | BitwiseXorExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[BitwiseOrExpressionanyValue1](e)
     in letexc rightValueValue = Eval[BitwiseXorExpressionanyValue](e)
     in applyBinaryBitwiseOperator(bitwiseOrleftValuerightValue)
applyBinaryBitwiseOperator(operatorInteger  Integer  Integer,
        leftValueValue,
        rightValueValue) : ValueOrException
  = letexc leftIntInteger = coerceToInt32(leftValue)
     in letexc rightIntInteger = coerceToInt32(rightValue)
     in integerResult(operator(leftIntrightInt))

Binary Logical Operators

Syntax

LogicalAndExpressionExprKind 
   BitwiseOrExpressionExprKind
|  LogicalAndExpressionanyValue && BitwiseOrExpressionanyValue
LogicalOrExpressionExprKind 
   LogicalAndExpressionExprKind
|  LogicalOrExpressionanyValue || LogicalAndExpressionanyValue

Semantics

action Eval[LogicalAndExpressionExprKind] : Env  ValueOrException
Eval[LogicalAndExpressionExprKind  BitwiseOrExpressionExprKind]
  = Eval[BitwiseOrExpressionExprKind]
Eval[LogicalAndExpressionExprKind  LogicalAndExpressionanyValue1 && BitwiseOrExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[LogicalAndExpressionanyValue1](e)
     in if coerceToBoolean(leftValue)
         then Eval[BitwiseOrExpressionanyValue](e)
         else normal leftValue
action Eval[LogicalOrExpressionExprKind] : Env  ValueOrException
Eval[LogicalOrExpressionExprKind  LogicalAndExpressionExprKind]
  = Eval[LogicalAndExpressionExprKind]
Eval[LogicalOrExpressionExprKind  LogicalOrExpressionanyValue1 || LogicalAndExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[LogicalOrExpressionanyValue1](e)
     in if coerceToBoolean(leftValue)
         then normal leftValue
         else Eval[LogicalAndExpressionanyValue](e)

Conditional Operator

Syntax

ConditionalExpressionExprKind 
   LogicalOrExpressionExprKind
|  LogicalOrExpressionanyValue ? AssignmentExpressionanyValue : AssignmentExpressionanyValue

Semantics

action Eval[ConditionalExpressionExprKind] : Env  ValueOrException
Eval[ConditionalExpressionExprKind  LogicalOrExpressionExprKind]
  = Eval[LogicalOrExpressionExprKind]
Eval[ConditionalExpressionExprKind  LogicalOrExpressionanyValue ? AssignmentExpressionanyValue1 : AssignmentExpressionanyValue2]
            (eEnv)
  = letexc conditionValue = Eval[LogicalOrExpressionanyValue](e)
     in if coerceToBoolean(condition)
         then Eval[AssignmentExpressionanyValue1](e)
         else Eval[AssignmentExpressionanyValue2](e)

Assignment Operators

Syntax

AssignmentExpressionExprKind 
   ConditionalExpressionExprKind
|  Lvalue = AssignmentExpressionanyValue

Expressions

Syntax

CommaExpressionExprKind  AssignmentExpressionExprKind

Semantics

action Eval[AssignmentExpressionExprKind] : Env  ValueOrException
Eval[AssignmentExpressionExprKind  ConditionalExpressionExprKind]
  = Eval[ConditionalExpressionExprKind]
Eval[AssignmentExpressionExprKind  Lvalue = AssignmentExpressionanyValue1](eEnv)
  = letexc leftReferenceReference = Eval[Lvalue](e)
     in letexc rightValueValue = Eval[AssignmentExpressionanyValue1](e)
     in letexc uVoid = referencePutValue(leftReferencerightValue)
     in normal rightValue
action Eval[CommaExpressionExprKind] : Env  ValueOrException
Eval[CommaExpressionExprKind  AssignmentExpressionExprKind]
  = Eval[AssignmentExpressionExprKind]

Syntax

Expression  CommaExpressionanyValue

Semantics

action Eval[Expression] : Env  ValueOrException
Eval[Expression  CommaExpressionanyValue] = Eval[CommaExpressionanyValue]

Programs

Syntax

Program  Expression End

Semantics

action Eval[Program] : ValueOrException
Eval[Program  Expression End] = Eval[Expression](this  nullObjectOrNull)

Waldemar Horwat
Last modified Wednesday, February 28, 2001
previousup