Formal JavaScript Semantics
Grammar
previousup

Thursday, July 15, 1999

Types

Semantics

type Value
  = oneof {
           undefinedValue;
           nullValue;
           booleanValueBoolean;
           doubleValueDouble;
           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 DoubleOrException = oneof {normalDoubleabruptException}

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

doubleResult(dDouble) : ValueOrException = normal doubleValue d

integerResult(iInteger) : ValueOrException = doubleResult(rationalToDouble(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;
        doubleValue(dDouble): not (doubleIsZero(dor doubleIsNan(d));
        stringValue(sString): |s 0;
        objectValuetrue
        end

coerceBooleanToDouble(bBoolean) : Double
  = if b
     then 1.0
     else 0.0

coerceToDouble(vValue) : DoubleOrException
  = case v of
        undefinedValuenormal NaN;
        nullValuenormal 0.0;
        booleanValue(bBoolean): normal coerceBooleanToDouble(b);
        doubleValue(dDouble): normal d;
        stringValue;
        objectValue
        end

coerceToUint32(vValue) : IntegerOrException
  = letexc dDouble = coerceToDouble(v)
     in normal doubleToUint32(d)

coerceToInt32(vValue) : IntegerOrException
  = letexc dDouble = coerceToDouble(v)
     in normal uint32ToInt32(doubleToUint32(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”;
        doubleValue;
        stringValue(sString): normal s;
        objectValue
        end

coerceToPrimitive(vValuehintDefaultValueHint) : ValueOrException
  = case v of
        undefinedValuenullValuebooleanValuedoubleValuestringValuenormal v;
        objectValue(oObject):
              letexc pvValue = o.defaultValue(hint)
              in case pv of
                     undefinedValuenullValuebooleanValuedoubleValuestringValue:
                           normal pv;
                     objectValueabruptValueOrException makeError(coerceToPrimitiveError)
                     end
        end

coerceToObject(vValue) : ObjectOrException
  = case v of
        undefinedValuenullValueabruptObjectOrException makeError(coerceToObjectError);
        booleanValue;
        doubleValue;
        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] : Double

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) = doubleResult(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
        undefinedValuenullValuebooleanValuedoubleValuestringValue:
              abruptReferenceOrException makeError(coerceToObjectError);
        objectValue(oObject): o.call(thisarguments)
        end

constructObject(constructorValueargumentsValue[]) : ValueOrException
  = case constructor of
        undefinedValuenullValuebooleanValuedoubleValuestringValue:
              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 operandDouble = coerceToDouble(operandValue)
     in letexc uVoid
                  = referencePutValue(operandReferencedoubleValue doubleAdd(operand, 1.0))
     in doubleResult(operand)

Eval[PostfixExpressionExprKind  Lvalue --](eEnv)
  = letexc operandReferenceReference = Eval[Lvalue](e)
     in letexc operandValueValue = referenceGetValue(operandReference)
     in letexc operandDouble = coerceToDouble(operandValue)
     in letexc uVoid
                  = referencePutValue(operandReferencedoubleValue doubleSubtract(operand, 1.0))
     in doubleResult(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 operandDouble = coerceToDouble(operandValue)
     in let resDouble = doubleAdd(operand, 1.0)
     in letexc uVoid = referencePutValue(operandReferencedoubleValue res)
     in doubleResult(res)

Eval[UnaryExpressionExprKind  -- Lvalue](eEnv)
  = letexc operandReferenceReference = Eval[Lvalue](e)
     in letexc operandValueValue = referenceGetValue(operandReference)
     in letexc operandDouble = coerceToDouble(operandValue)
     in let resDouble = doubleSubtract(operand, 1.0)
     in letexc uVoid = referencePutValue(operandReferencedoubleValue res)
     in doubleResult(res)

Eval[UnaryExpressionExprKind  + UnaryExpressionanyValue1](eEnv)
  = letexc operandValueValue = Eval[UnaryExpressionanyValue1](e)
     in letexc operandDouble = coerceToDouble(operandValue)
     in doubleResult(operand)

Eval[UnaryExpressionExprKind  - UnaryExpressionanyValue1](eEnv)
  = letexc operandValueValue = Eval[UnaryExpressionanyValue1](e)
     in letexc operandDouble = coerceToDouble(operandValue)
     in doubleResult(doubleNegate(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”;
        doubleValue: “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 applyBinaryDoubleOperator(doubleMultiplyleftValuerightValue)

Eval[MultiplicativeExpressionExprKind  MultiplicativeExpressionanyValue1 / UnaryExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[MultiplicativeExpressionanyValue1](e)
     in letexc rightValueValue = Eval[UnaryExpressionanyValue](e)
     in applyBinaryDoubleOperator(doubleDivideleftValuerightValue)

Eval[MultiplicativeExpressionExprKind  MultiplicativeExpressionanyValue1 % UnaryExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[MultiplicativeExpressionanyValue1](e)
     in letexc rightValueValue = Eval[UnaryExpressionanyValue](e)
     in applyBinaryDoubleOperator(doubleRemainderleftValuerightValue)

applyBinaryDoubleOperator(operatorDouble  Double  DoubleleftValueValuerightValueValue)
  : ValueOrException
  = letexc leftNumberDouble = coerceToDouble(leftValue)
     in letexc rightNumberDouble = coerceToDouble(rightValue)
     in doubleResult(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 applyBinaryDoubleOperator(doubleAddleftPrimitiverightPrimitive)

Eval[AdditiveExpressionExprKind  AdditiveExpressionanyValue1 - MultiplicativeExpressionanyValue]
            (eEnv)
  = letexc leftValueValue = Eval[AdditiveExpressionanyValue1](e)
     in letexc rightValueValue = Eval[MultiplicativeExpressionanyValue](e)
     in applyBinaryDoubleOperator(doubleSubtractleftValuerightValue)

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 leftNumberDouble = coerceToDouble(leftPrimitive)
               in letexc rightNumberDouble = coerceToDouble(rightPrimitive)
               in booleanResult(
                       doubleCompare(
                           leftNumber,
                           rightNumber,
                           less,
                           greaterOrEqual,
                           greaterOrEqual,
                           false))

compareStrings(leftStringrightStringlessBooleanequalBooleangreaterBoolean)
  : 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;
                 booleanValuedoubleValuestringValueobjectValuenormal false
                 end;
        booleanValue(leftBoolBoolean):
              case rightValue of
                 undefinedValuenullValuenormal false;
                 booleanValue(rightBoolBoolean): normal (not (leftBool xor rightBool));
                 doubleValuestringValueobjectValue:
                       compareDoubleToValue(coerceBooleanToDouble(leftBool), rightValue)
                 end;
        doubleValue(leftNumberDouble): compareDoubleToValue(leftNumberrightValue);
        stringValue(leftStrString):
              case rightValue of
                 undefinedValuenullValuenormal false;
                 booleanValue(rightBoolBoolean):
                       letexc leftNumberDouble = coerceToDouble(leftValue)
                       in normal doubleEqual(leftNumbercoerceBooleanToDouble(rightBool));
                 doubleValue(rightNumberDouble):
                       letexc leftNumberDouble = coerceToDouble(leftValue)
                       in normal doubleEqual(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,
                               doubleValue coerceBooleanToDouble(rightBool));
                 doubleValuestringValue:
                       letexc leftPrimitiveValue = coerceToPrimitive(leftValuenoHint)
                       in compareValues(leftPrimitiverightValue);
                 objectValue(rightObjObject):
                       normal (leftObj.properties  rightObj.properties)
                 end
        end

compareDoubleToValue(leftNumberDoublerightValueValue) : BooleanOrException
  = case rightValue of
        undefinedValuenullValuenormal false;
        booleanValuedoubleValuestringValue:
              letexc rightNumberDouble = coerceToDouble(rightValue)
              in normal doubleEqual(leftNumberrightNumber);
        objectValue:
              letexc rightPrimitiveValue = coerceToPrimitive(rightValuenoHint)
              in compareDoubleToValue(leftNumberrightPrimitive)
        end

doubleEqual(xDoubleyDouble) : Boolean
  = doubleCompare(xyfalsetruefalsefalse)

strictCompareValues(leftValueValuerightValueValue) : Boolean
  = case leftValue of
        undefinedValuerightValue is undefinedValue;
        nullValuerightValue is nullValue;
        booleanValue(leftBoolBoolean):
              case rightValue of
                 booleanValue(rightBoolBoolean): not (leftBool xor rightBool);
                 undefinedValuenullValuedoubleValuestringValueobjectValuefalse
                 end;
        doubleValue(leftNumberDouble):
              case rightValue of
                 doubleValue(rightNumberDouble): doubleEqual(leftNumberrightNumber);
                 undefinedValuenullValuebooleanValuestringValueobjectValuefalse
                 end;
        stringValue(leftStrString):
              case rightValue of
                 stringValue(rightStrString):
                       compareStrings(leftStrrightStrfalsetruefalse);
                 undefinedValuenullValuebooleanValuedoubleValueobjectValuefalse
                 end;
        objectValue(leftObjObject):
              case rightValue of
                 objectValue(rightObjObject): leftObj.properties  rightObj.properties;
                 undefinedValuenullValuebooleanValuedoubleValuestringValuefalse
                 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  IntegerleftValueValuerightValueValue)
  : 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 Thursday, July 15, 1999
previousup