type Value
= oneof {
undefinedValue;
nullValue;
booleanValue: Boolean;
doubleValue: Double;
stringValue: String;
objectValue: Object}
type ObjectOrNull = oneof {nullObjectOrNull; objectObjectOrNull: Object}
type Object
= tuple {
properties: Property[];
typeofName: String;
prototype: ObjectOrNull;
get: PropName ValueOrException;
put: PropName Value VoidOrException;
delete: PropName BooleanOrException;
call: ObjectOrNull Value[] ReferenceOrException;
construct: Value[] ObjectOrException;
defaultValue: DefaultValueHint ValueOrException}
type DefaultValueHint = oneof {noHint; numberHint; stringHint}
type Property
= tuple {
name: String;
readOnly: Boolean;
enumerable: Boolean;
permanent: Boolean;
value: Value}
type PropName = String
type Place = tuple {base: Object; property: PropName}
type Reference
= oneof {valueReference: Value; placeReference: Place; virtualReference: PropName}
type IntegerOrException = oneof {normal: Integer; abrupt: Exception}
type VoidOrException = oneof {normal; abrupt: Exception}
type BooleanOrException = oneof {normal: Boolean; abrupt: Exception}
type DoubleOrException = oneof {normal: Double; abrupt: Exception}
type StringOrException = oneof {normal: String; abrupt: Exception}
type ObjectOrException = oneof {normal: Object; abrupt: Exception}
type ValueOrException = oneof {normal: Value; abrupt: Exception}
type ReferenceOrException = oneof {normal: Reference; abrupt: Exception}
type ValueListOrException = oneof {normal: Value[]; abrupt: Exception}
objectOrNullToValue(o: ObjectOrNull) : Value
= case o of
nullObjectOrNull: nullValue;
objectObjectOrNull(obj: Object): objectValue obj
end
undefinedResult : ValueOrException = normal undefinedValue
nullResult : ValueOrException = normal nullValue
booleanResult(b: Boolean) : ValueOrException = normal booleanValue b
doubleResult(d: Double) : ValueOrException = normal doubleValue d
integerResult(i: Integer) : ValueOrException = doubleResult(rationalToDouble(i))
stringResult(s: String) : ValueOrException = normal stringValue s
objectResult(o: Object) : ValueOrException = normal objectValue o
type Exception = oneof {exception: Value; error: Error}
type Error
= oneof {
coerceToPrimitiveError;
coerceToObjectError;
getValueError;
putValueError;
deleteError}
makeError(err: Error) : Exception = error err
referenceGetValue(rv: Reference) : ValueOrException
= case rv of
valueReference(v: Value): normal v;
placeReference(r: Place): r.base.get(r.property);
virtualReference: abruptValueOrException makeError(getValueError)
end
referencePutValue(rv: Reference, v: Value) : VoidOrException
= case rv of
valueReference: abruptVoidOrException makeError(putValueError);
placeReference(r: Place): r.base.put(r.property, v);
virtualReference:
end
coerceToBoolean(v: Value) : Boolean
= case v of
undefinedValue, nullValue: false;
booleanValue(b: Boolean): b;
doubleValue(d: Double): not (doubleIsZero(d) or doubleIsNan(d));
stringValue(s: String): length(s) 0;
objectValue: true
end
coerceBooleanToDouble(b: Boolean) : Double
= if b
then 1.0
else 0.0
coerceToDouble(v: Value) : DoubleOrException
= case v of
undefinedValue: normal NaN;
nullValue: normal 0.0;
booleanValue(b: Boolean): normal coerceBooleanToDouble(b);
doubleValue(d: Double): normal d;
stringValue: ;
objectValue:
end
coerceToUint32(v: Value) : IntegerOrException
= letexc d: Double = coerceToDouble(v)
in normal doubleToUint32(d)
coerceToInt32(v: Value) : IntegerOrException
= letexc d: Double = coerceToDouble(v)
in normal uint32ToInt32(doubleToUint32(d))
uint32ToInt32(ui: Integer) : Integer
= if ui < 2147483648
then ui
else ui - 4294967296
coerceToString(v: Value) : StringOrException
= case v of
undefinedValue: normal “undefined”;
nullValue: normal “null”;
booleanValue(b: Boolean):
if b
then normal “true”
else normal “false”;
doubleValue: ;
stringValue(s: String): normal s;
objectValue:
end
coerceToPrimitive(v: Value, hint: DefaultValueHint) : ValueOrException
= case v of
undefinedValue, nullValue, booleanValue, doubleValue, stringValue: normal v;
objectValue(o: Object):
letexc pv: Value = o.defaultValue(hint)
in case pv of
undefinedValue, nullValue, booleanValue, doubleValue, stringValue:
normal pv;
objectValue: abruptValueOrException makeError(coerceToPrimitiveError)
end
end
coerceToObject(v: Value) : ObjectOrException
= case v of
undefinedValue, nullValue: abruptObjectOrException makeError(coerceToObjectError);
booleanValue: ;
doubleValue: ;
stringValue: ;
objectValue(o: Object): normal o
end
type Env = tuple {this: ObjectOrNull}
lookupIdentifier(e: Env, id: String) : ReferenceOrException =
action EvalIdentifier[Identifier] : String
action EvalNumber[Number] : Double
action EvalString[String] : String
thisnulltruefalse( CommaExpressionnoLValue )( Lvalue )action Eval[PrimaryRvalue] : Env ValueOrException
Eval[PrimaryRvalue this](e: Env) = normal objectOrNullToValue(e.this)
Eval[PrimaryRvalue null](e: Env) = nullResult
Eval[PrimaryRvalue true](e: Env) = booleanResult(true)
Eval[PrimaryRvalue false](e: Env) = booleanResult(false)
Eval[PrimaryRvalue Number](e: Env) = doubleResult(EvalNumber[Number])
Eval[PrimaryRvalue String](e: Env) = stringResult(EvalString[String])
Eval[PrimaryRvalue ( CommaExpressionnoLValue )] = Eval[CommaExpressionnoLValue]
action Eval[PrimaryLvalue] : Env ReferenceOrException
Eval[PrimaryLvalue Identifier](e: Env)
= lookupIdentifier(e, EvalIdentifier[Identifier])
Eval[PrimaryLvalue ( Lvalue )] = Eval[Lvalue]
[ Expression ]. Identifier[ Expression ]. Identifiernew MemberExpressionnoCall,anyValue Argumentsnew MemberExpressionnoCall,anyValue Argumentsnew NewExpressionanyValue( )( ArgumentList ), AssignmentExpressionanyValueaction Eval[MemberLvalueMemberExprKind] : Env ReferenceOrException
Eval[MemberLvaluenoCall PrimaryLvalue] = Eval[PrimaryLvalue]
Eval[MemberLvaluecall Lvalue Arguments](e: Env)
= letexc functionReference: Reference = Eval[Lvalue](e)
in letexc function: Value = referenceGetValue(functionReference)
in letexc arguments: Value[] = Eval[Arguments](e)
in let this: ObjectOrNull
= case functionReference of
valueReference, virtualReference: nullObjectOrNull;
placeReference(p: Place): objectObjectOrNull p.base
end
in callObject(function, this, arguments)
Eval[MemberLvaluecall MemberExpressionnoCall,noLValue Arguments](e: Env)
= letexc function: Value = Eval[MemberExpressionnoCall,noLValue](e)
in letexc arguments: Value[] = Eval[Arguments](e)
in callObject(function, nullObjectOrNull, arguments)
Eval[MemberLvalueMemberExprKind MemberExpressionMemberExprKind,anyValue [ Expression ]]
(e: Env)
= letexc container: Value = Eval[MemberExpressionMemberExprKind,anyValue](e)
in letexc property: Value = Eval[Expression](e)
in readProperty(container, property)
Eval[MemberLvalueMemberExprKind MemberExpressionMemberExprKind,anyValue . Identifier]
(e: Env)
= letexc container: Value = Eval[MemberExpressionMemberExprKind,anyValue](e)
in readProperty(container, stringValue EvalIdentifier[Identifier])
action Eval[MemberExpressionMemberExprKind,ExprKind] : Env ValueOrException
Eval[MemberExpressionnoCall,ExprKind PrimaryRvalue] = Eval[PrimaryRvalue]
Eval[MemberExpressionMemberExprKind,anyValue MemberLvalueMemberExprKind](e: Env)
= letexc ref: Reference = Eval[MemberLvalueMemberExprKind](e)
in referenceGetValue(ref)
Eval[MemberExpressionnoCall,ExprKind new MemberExpressionnoCall,anyValue1 Arguments]
(e: Env)
= letexc constructor: Value = Eval[MemberExpressionnoCall,anyValue1](e)
in letexc arguments: Value[] = Eval[Arguments](e)
in constructObject(constructor, arguments)
action Eval[NewExpressionExprKind] : Env ValueOrException
Eval[NewExpressionExprKind MemberExpressionnoCall,ExprKind]
= Eval[MemberExpressionnoCall,ExprKind]
Eval[NewExpressionExprKind new NewExpressionanyValue1](e: Env)
= letexc constructor: Value = Eval[NewExpressionanyValue1](e)
in constructObject(constructor, []Value)
action Eval[Arguments] : Env ValueListOrException
Eval[Arguments ( )](e: Env) = normal []Value
Eval[Arguments ( ArgumentList )] = Eval[ArgumentList]
action Eval[ArgumentList] : Env ValueListOrException
Eval[ArgumentList AssignmentExpressionanyValue](e: Env)
= letexc arg: Value = Eval[AssignmentExpressionanyValue](e)
in normal [arg]
Eval[ArgumentList ArgumentList1 , AssignmentExpressionanyValue](e: Env)
= letexc args: Value[] = Eval[ArgumentList1](e)
in letexc arg: Value = Eval[AssignmentExpressionanyValue](e)
in normal (args [arg])
action Eval[Lvalue] : Env ReferenceOrException
Eval[Lvalue MemberLvaluecall] = Eval[MemberLvaluecall]
Eval[Lvalue MemberLvaluenoCall] = Eval[MemberLvaluenoCall]
readProperty(container: Value, property: Value) : ReferenceOrException
= letexc obj: Object = coerceToObject(container)
in letexc name: PropName = coerceToString(property)
in normal placeReference obj, namePlace
callObject(function: Value, this: ObjectOrNull, arguments: Value[]) : ReferenceOrException
= case function of
undefinedValue, nullValue, booleanValue, doubleValue, stringValue:
abruptReferenceOrException makeError(coerceToObjectError);
objectValue(o: Object): o.call(this, arguments)
end
constructObject(constructor: Value, arguments: Value[]) : ValueOrException
= case constructor of
undefinedValue, nullValue, booleanValue, doubleValue, stringValue:
abruptValueOrException makeError(coerceToObjectError);
objectValue(o: Object):
letexc res: Object = o.construct(arguments)
in objectResult(res)
end
++--++--action Eval[PostfixExpressionExprKind] : Env ValueOrException
Eval[PostfixExpressionExprKind NewExpressionExprKind] = Eval[NewExpressionExprKind]
Eval[PostfixExpressionanyValue MemberExpressioncall,anyValue]
= Eval[MemberExpressioncall,anyValue]
Eval[PostfixExpressionExprKind Lvalue ++](e: Env)
= letexc operandReference: Reference = Eval[Lvalue](e)
in letexc operandValue: Value = referenceGetValue(operandReference)
in letexc operand: Double = coerceToDouble(operandValue)
in letexc u: Void
= referencePutValue(operandReference, doubleValue doubleAdd(operand, 1.0))
in doubleResult(operand)
Eval[PostfixExpressionExprKind Lvalue --](e: Env)
= letexc operandReference: Reference = Eval[Lvalue](e)
in letexc operandValue: Value = referenceGetValue(operandReference)
in letexc operand: Double = coerceToDouble(operandValue)
in letexc u: Void
= referencePutValue(operandReference, doubleValue doubleSubtract(operand, 1.0))
in doubleResult(operand)
delete Lvaluevoid UnaryExpressionanyValuetypeof Lvaluetypeof UnaryExpressionnoLValue++ Lvalue-- Lvalue+ UnaryExpressionanyValue- UnaryExpressionanyValue~ UnaryExpressionanyValue! UnaryExpressionanyValueaction Eval[UnaryExpressionExprKind] : Env ValueOrException
Eval[UnaryExpressionExprKind PostfixExpressionExprKind]
= Eval[PostfixExpressionExprKind]
Eval[UnaryExpressionExprKind delete Lvalue](e: Env)
= letexc rv: Reference = Eval[Lvalue](e)
in case rv of
valueReference: abruptValueOrException makeError(deleteError);
placeReference(r: Place):
letexc b: Boolean = r.base.delete(r.property)
in booleanResult(b);
virtualReference: booleanResult(true)
end
Eval[UnaryExpressionExprKind void UnaryExpressionanyValue1](e: Env)
= letexc operand: Value = Eval[UnaryExpressionanyValue1](e)
in undefinedResult
Eval[UnaryExpressionExprKind typeof Lvalue](e: Env)
= letexc rv: Reference = Eval[Lvalue](e)
in case rv of
valueReference(v: Value): stringResult(valueTypeof(v));
placeReference(r: Place):
letexc v: Value = r.base.get(r.property)
in stringResult(valueTypeof(v));
virtualReference: stringResult(“undefined”)
end
Eval[UnaryExpressionExprKind typeof UnaryExpressionnoLValue1](e: Env)
= letexc v: Value = Eval[UnaryExpressionnoLValue1](e)
in stringResult(valueTypeof(v))
Eval[UnaryExpressionExprKind ++ Lvalue](e: Env)
= letexc operandReference: Reference = Eval[Lvalue](e)
in letexc operandValue: Value = referenceGetValue(operandReference)
in letexc operand: Double = coerceToDouble(operandValue)
in let res: Double = doubleAdd(operand, 1.0)
in letexc u: Void = referencePutValue(operandReference, doubleValue res)
in doubleResult(res)
Eval[UnaryExpressionExprKind -- Lvalue](e: Env)
= letexc operandReference: Reference = Eval[Lvalue](e)
in letexc operandValue: Value = referenceGetValue(operandReference)
in letexc operand: Double = coerceToDouble(operandValue)
in let res: Double = doubleSubtract(operand, 1.0)
in letexc u: Void = referencePutValue(operandReference, doubleValue res)
in doubleResult(res)
Eval[UnaryExpressionExprKind + UnaryExpressionanyValue1](e: Env)
= letexc operandValue: Value = Eval[UnaryExpressionanyValue1](e)
in letexc operand: Double = coerceToDouble(operandValue)
in doubleResult(operand)
Eval[UnaryExpressionExprKind - UnaryExpressionanyValue1](e: Env)
= letexc operandValue: Value = Eval[UnaryExpressionanyValue1](e)
in letexc operand: Double = coerceToDouble(operandValue)
in doubleResult(doubleNegate(operand))
Eval[UnaryExpressionExprKind ~ UnaryExpressionanyValue1](e: Env)
= letexc operandValue: Value = Eval[UnaryExpressionanyValue1](e)
in letexc operand: Integer = coerceToInt32(operandValue)
in integerResult(bitwiseXor(operand, -1))
Eval[UnaryExpressionExprKind ! UnaryExpressionanyValue1](e: Env)
= letexc operandValue: Value = Eval[UnaryExpressionanyValue1](e)
in booleanResult(not coerceToBoolean(operandValue))
valueTypeof(v: Value) : String
= case v of
undefinedValue: “undefined”;
nullValue: “object”;
booleanValue: “boolean”;
doubleValue: “number”;
stringValue: “string”;
objectValue(o: Object): o.typeofName
end
* UnaryExpressionanyValue/ UnaryExpressionanyValue% UnaryExpressionanyValueaction Eval[MultiplicativeExpressionExprKind] : Env ValueOrException
Eval[MultiplicativeExpressionExprKind UnaryExpressionExprKind]
= Eval[UnaryExpressionExprKind]
Eval[MultiplicativeExpressionExprKind MultiplicativeExpressionanyValue1 * UnaryExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[MultiplicativeExpressionanyValue1](e)
in letexc rightValue: Value = Eval[UnaryExpressionanyValue](e)
in applyBinaryDoubleOperator(doubleMultiply, leftValue, rightValue)
Eval[MultiplicativeExpressionExprKind MultiplicativeExpressionanyValue1 / UnaryExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[MultiplicativeExpressionanyValue1](e)
in letexc rightValue: Value = Eval[UnaryExpressionanyValue](e)
in applyBinaryDoubleOperator(doubleDivide, leftValue, rightValue)
Eval[MultiplicativeExpressionExprKind MultiplicativeExpressionanyValue1 % UnaryExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[MultiplicativeExpressionanyValue1](e)
in letexc rightValue: Value = Eval[UnaryExpressionanyValue](e)
in applyBinaryDoubleOperator(doubleRemainder, leftValue, rightValue)
applyBinaryDoubleOperator(operator: Double Double Double, leftValue: Value, rightValue: Value)
: ValueOrException
= letexc leftNumber: Double = coerceToDouble(leftValue)
in letexc rightNumber: Double = coerceToDouble(rightValue)
in doubleResult(operator(leftNumber, rightNumber))
+ MultiplicativeExpressionanyValue- MultiplicativeExpressionanyValueaction Eval[AdditiveExpressionExprKind] : Env ValueOrException
Eval[AdditiveExpressionExprKind MultiplicativeExpressionExprKind]
= Eval[MultiplicativeExpressionExprKind]
Eval[AdditiveExpressionExprKind AdditiveExpressionanyValue1 + MultiplicativeExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[AdditiveExpressionanyValue1](e)
in letexc rightValue: Value = Eval[MultiplicativeExpressionanyValue](e)
in letexc leftPrimitive: Value = coerceToPrimitive(leftValue, noHint)
in letexc rightPrimitive: Value = coerceToPrimitive(rightValue, noHint)
in if leftPrimitive is stringValue or rightPrimitive is stringValue
then letexc leftString: String = coerceToString(leftPrimitive)
in letexc rightString: String = coerceToString(rightPrimitive)
in stringResult(leftString rightString)
else applyBinaryDoubleOperator(doubleAdd, leftPrimitive, rightPrimitive)
Eval[AdditiveExpressionExprKind AdditiveExpressionanyValue1 - MultiplicativeExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[AdditiveExpressionanyValue1](e)
in letexc rightValue: Value = Eval[MultiplicativeExpressionanyValue](e)
in applyBinaryDoubleOperator(doubleSubtract, leftValue, rightValue)
<< AdditiveExpressionanyValue>> AdditiveExpressionanyValue>>> AdditiveExpressionanyValueaction Eval[ShiftExpressionExprKind] : Env ValueOrException
Eval[ShiftExpressionExprKind AdditiveExpressionExprKind]
= Eval[AdditiveExpressionExprKind]
Eval[ShiftExpressionExprKind ShiftExpressionanyValue1 << AdditiveExpressionanyValue]
(e: Env)
= letexc bitmapValue: Value = Eval[ShiftExpressionanyValue1](e)
in letexc countValue: Value = Eval[AdditiveExpressionanyValue](e)
in letexc bitmap: Integer = coerceToUint32(bitmapValue)
in letexc count: Integer = coerceToUint32(countValue)
in integerResult(
uint32ToInt32(bitwiseAnd(bitwiseShift(bitmap, bitwiseAnd(count, 31)), 4294967295)))
Eval[ShiftExpressionExprKind ShiftExpressionanyValue1 >> AdditiveExpressionanyValue]
(e: Env)
= letexc bitmapValue: Value = Eval[ShiftExpressionanyValue1](e)
in letexc countValue: Value = Eval[AdditiveExpressionanyValue](e)
in letexc bitmap: Integer = coerceToInt32(bitmapValue)
in letexc count: Integer = coerceToUint32(countValue)
in integerResult(bitwiseShift(bitmap, -bitwiseAnd(count, 31)))
Eval[ShiftExpressionExprKind ShiftExpressionanyValue1 >>> AdditiveExpressionanyValue]
(e: Env)
= letexc bitmapValue: Value = Eval[ShiftExpressionanyValue1](e)
in letexc countValue: Value = Eval[AdditiveExpressionanyValue](e)
in letexc bitmap: Integer = coerceToUint32(bitmapValue)
in letexc count: Integer = coerceToUint32(countValue)
in integerResult(bitwiseShift(bitmap, -bitwiseAnd(count, 31)))
< ShiftExpressionanyValue> ShiftExpressionanyValue<= ShiftExpressionanyValue>= ShiftExpressionanyValueaction Eval[RelationalExpressionExprKind] : Env ValueOrException
Eval[RelationalExpressionExprKind ShiftExpressionExprKind]
= Eval[ShiftExpressionExprKind]
Eval[RelationalExpressionExprKind RelationalExpressionanyValue1 < ShiftExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[RelationalExpressionanyValue1](e)
in letexc rightValue: Value = Eval[ShiftExpressionanyValue](e)
in orderValues(leftValue, rightValue, true, false)
Eval[RelationalExpressionExprKind RelationalExpressionanyValue1 > ShiftExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[RelationalExpressionanyValue1](e)
in letexc rightValue: Value = Eval[ShiftExpressionanyValue](e)
in orderValues(rightValue, leftValue, true, false)
Eval[RelationalExpressionExprKind RelationalExpressionanyValue1 <= ShiftExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[RelationalExpressionanyValue1](e)
in letexc rightValue: Value = Eval[ShiftExpressionanyValue](e)
in orderValues(rightValue, leftValue, false, true)
Eval[RelationalExpressionExprKind RelationalExpressionanyValue1 >= ShiftExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[RelationalExpressionanyValue1](e)
in letexc rightValue: Value = Eval[ShiftExpressionanyValue](e)
in orderValues(leftValue, rightValue, false, true)
orderValues(leftValue: Value, rightValue: Value, less: Boolean, greaterOrEqual: Boolean)
: ValueOrException
= letexc leftPrimitive: Value = coerceToPrimitive(leftValue, numberHint)
in letexc rightPrimitive: Value = coerceToPrimitive(rightValue, numberHint)
in if leftPrimitive is stringValue and rightPrimitive is stringValue
then booleanResult(
compareStrings(
leftPrimitive.stringValue,
rightPrimitive.stringValue,
less,
greaterOrEqual,
greaterOrEqual))
else letexc leftNumber: Double = coerceToDouble(leftPrimitive)
in letexc rightNumber: Double = coerceToDouble(rightPrimitive)
in booleanResult(
doubleCompare(
leftNumber,
rightNumber,
less,
greaterOrEqual,
greaterOrEqual,
false))
compareStrings(left: String, right: String, less: Boolean, equal: Boolean, greater: Boolean)
: Boolean
= if empty(left) and empty(right)
then equal
else if empty(left)
then less
else if empty(right)
then greater
else let leftCharCode: Integer = characterToCode(first(left));
rightCharCode: Integer = characterToCode(first(right))
in if leftCharCode < rightCharCode
then less
else if leftCharCode > rightCharCode
then greater
else compareStrings(rest(left), rest(right), less, equal, greater)
== RelationalExpressionanyValue!= RelationalExpressionanyValue=== RelationalExpressionanyValue!== RelationalExpressionanyValueaction Eval[EqualityExpressionExprKind] : Env ValueOrException
Eval[EqualityExpressionExprKind RelationalExpressionExprKind]
= Eval[RelationalExpressionExprKind]
Eval[EqualityExpressionExprKind EqualityExpressionanyValue1 == RelationalExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[EqualityExpressionanyValue1](e)
in letexc rightValue: Value = Eval[RelationalExpressionanyValue](e)
in letexc eq: Boolean = compareValues(leftValue, rightValue)
in booleanResult(eq)
Eval[EqualityExpressionExprKind EqualityExpressionanyValue1 != RelationalExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[EqualityExpressionanyValue1](e)
in letexc rightValue: Value = Eval[RelationalExpressionanyValue](e)
in letexc eq: Boolean = compareValues(leftValue, rightValue)
in booleanResult(not eq)
Eval[EqualityExpressionExprKind EqualityExpressionanyValue1 === RelationalExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[EqualityExpressionanyValue1](e)
in letexc rightValue: Value = Eval[RelationalExpressionanyValue](e)
in booleanResult(strictCompareValues(leftValue, rightValue))
Eval[EqualityExpressionExprKind EqualityExpressionanyValue1 !== RelationalExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[EqualityExpressionanyValue1](e)
in letexc rightValue: Value = Eval[RelationalExpressionanyValue](e)
in booleanResult(not strictCompareValues(leftValue, rightValue))
compareValues(leftValue: Value, rightValue: Value) : BooleanOrException
= case leftValue of
undefinedValue, nullValue:
case rightValue of
undefinedValue, nullValue: normal true;
booleanValue, doubleValue, stringValue, objectValue: normal false
end;
booleanValue(leftBool: Boolean):
case rightValue of
undefinedValue, nullValue: normal false;
booleanValue(rightBool: Boolean): normal (not (leftBool xor rightBool));
doubleValue, stringValue, objectValue:
compareDoubleToValue(coerceBooleanToDouble(leftBool), rightValue)
end;
doubleValue(leftNumber: Double): compareDoubleToValue(leftNumber, rightValue);
stringValue(leftStr: String):
case rightValue of
undefinedValue, nullValue: normal false;
booleanValue(rightBool: Boolean):
letexc leftNumber: Double = coerceToDouble(leftValue)
in normal doubleEqual(leftNumber, coerceBooleanToDouble(rightBool));
doubleValue(rightNumber: Double):
letexc leftNumber: Double = coerceToDouble(leftValue)
in normal doubleEqual(leftNumber, rightNumber);
stringValue(rightStr: String):
normal compareStrings(leftStr, rightStr, false, true, false);
objectValue:
letexc rightPrimitive: Value = coerceToPrimitive(rightValue, noHint)
in compareValues(leftValue, rightPrimitive)
end;
objectValue(leftObj: Object):
case rightValue of
undefinedValue, nullValue: normal false;
booleanValue(rightBool: Boolean):
letexc leftPrimitive: Value = coerceToPrimitive(leftValue, noHint)
in compareValues(
leftPrimitive,
doubleValue coerceBooleanToDouble(rightBool));
doubleValue, stringValue:
letexc leftPrimitive: Value = coerceToPrimitive(leftValue, noHint)
in compareValues(leftPrimitive, rightValue);
objectValue(rightObj: Object):
normal (leftObj.properties rightObj.properties)
end
end
compareDoubleToValue(leftNumber: Double, rightValue: Value) : BooleanOrException
= case rightValue of
undefinedValue, nullValue: normal false;
booleanValue, doubleValue, stringValue:
letexc rightNumber: Double = coerceToDouble(rightValue)
in normal doubleEqual(leftNumber, rightNumber);
objectValue:
letexc rightPrimitive: Value = coerceToPrimitive(rightValue, noHint)
in compareDoubleToValue(leftNumber, rightPrimitive)
end
doubleEqual(x: Double, y: Double) : Boolean
= doubleCompare(x, y, false, true, false, false)
strictCompareValues(leftValue: Value, rightValue: Value) : Boolean
= case leftValue of
undefinedValue: rightValue is undefinedValue;
nullValue: rightValue is nullValue;
booleanValue(leftBool: Boolean):
case rightValue of
booleanValue(rightBool: Boolean): not (leftBool xor rightBool);
undefinedValue, nullValue, doubleValue, stringValue, objectValue: false
end;
doubleValue(leftNumber: Double):
case rightValue of
doubleValue(rightNumber: Double): doubleEqual(leftNumber, rightNumber);
undefinedValue, nullValue, booleanValue, stringValue, objectValue: false
end;
stringValue(leftStr: String):
case rightValue of
stringValue(rightStr: String):
compareStrings(leftStr, rightStr, false, true, false);
undefinedValue, nullValue, booleanValue, doubleValue, objectValue: false
end;
objectValue(leftObj: Object):
case rightValue of
objectValue(rightObj: Object): leftObj.properties rightObj.properties;
undefinedValue, nullValue, booleanValue, doubleValue, stringValue: false
end
end
& EqualityExpressionanyValue^ BitwiseAndExpressionanyValue| BitwiseXorExpressionanyValueaction Eval[BitwiseAndExpressionExprKind] : Env ValueOrException
Eval[BitwiseAndExpressionExprKind EqualityExpressionExprKind]
= Eval[EqualityExpressionExprKind]
Eval[BitwiseAndExpressionExprKind BitwiseAndExpressionanyValue1 & EqualityExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[BitwiseAndExpressionanyValue1](e)
in letexc rightValue: Value = Eval[EqualityExpressionanyValue](e)
in applyBinaryBitwiseOperator(bitwiseAnd, leftValue, rightValue)
action Eval[BitwiseXorExpressionExprKind] : Env ValueOrException
Eval[BitwiseXorExpressionExprKind BitwiseAndExpressionExprKind]
= Eval[BitwiseAndExpressionExprKind]
Eval[BitwiseXorExpressionExprKind BitwiseXorExpressionanyValue1 ^ BitwiseAndExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[BitwiseXorExpressionanyValue1](e)
in letexc rightValue: Value = Eval[BitwiseAndExpressionanyValue](e)
in applyBinaryBitwiseOperator(bitwiseXor, leftValue, rightValue)
action Eval[BitwiseOrExpressionExprKind] : Env ValueOrException
Eval[BitwiseOrExpressionExprKind BitwiseXorExpressionExprKind]
= Eval[BitwiseXorExpressionExprKind]
Eval[BitwiseOrExpressionExprKind BitwiseOrExpressionanyValue1 | BitwiseXorExpressionanyValue]
(e: Env)
= letexc leftValue: Value = Eval[BitwiseOrExpressionanyValue1](e)
in letexc rightValue: Value = Eval[BitwiseXorExpressionanyValue](e)
in applyBinaryBitwiseOperator(bitwiseOr, leftValue, rightValue)
applyBinaryBitwiseOperator(operator: Integer Integer Integer, leftValue: Value, rightValue: Value)
: ValueOrException
= letexc leftInt: Integer = coerceToInt32(leftValue)
in letexc rightInt: Integer = coerceToInt32(rightValue)
in integerResult(operator(leftInt, rightInt))
&& BitwiseOrExpressionanyValue|| LogicalAndExpressionanyValueaction Eval[LogicalAndExpressionExprKind] : Env ValueOrException
Eval[LogicalAndExpressionExprKind BitwiseOrExpressionExprKind]
= Eval[BitwiseOrExpressionExprKind]
Eval[LogicalAndExpressionExprKind LogicalAndExpressionanyValue1 && BitwiseOrExpressionanyValue]
(e: Env)
= letexc leftValue: Value = 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]
(e: Env)
= letexc leftValue: Value = Eval[LogicalOrExpressionanyValue1](e)
in if coerceToBoolean(leftValue)
then normal leftValue
else Eval[LogicalAndExpressionanyValue](e)
? AssignmentExpressionanyValue : AssignmentExpressionanyValueaction Eval[ConditionalExpressionExprKind] : Env ValueOrException
Eval[ConditionalExpressionExprKind LogicalOrExpressionExprKind]
= Eval[LogicalOrExpressionExprKind]
Eval[ConditionalExpressionExprKind LogicalOrExpressionanyValue ? AssignmentExpressionanyValue1 : AssignmentExpressionanyValue2]
(e: Env)
= letexc condition: Value = Eval[LogicalOrExpressionanyValue](e)
in if coerceToBoolean(condition)
then Eval[AssignmentExpressionanyValue1](e)
else Eval[AssignmentExpressionanyValue2](e)
= AssignmentExpressionanyValueaction Eval[AssignmentExpressionExprKind] : Env ValueOrException
Eval[AssignmentExpressionExprKind ConditionalExpressionExprKind]
= Eval[ConditionalExpressionExprKind]
Eval[AssignmentExpressionExprKind Lvalue = AssignmentExpressionanyValue1](e: Env)
= letexc leftReference: Reference = Eval[Lvalue](e)
in letexc rightValue: Value = Eval[AssignmentExpressionanyValue1](e)
in letexc u: Void = referencePutValue(leftReference, rightValue)
in normal rightValue
action Eval[CommaExpressionExprKind] : Env ValueOrException
Eval[CommaExpressionExprKind AssignmentExpressionExprKind]
= Eval[AssignmentExpressionExprKind]
action Eval[Expression] : Env ValueOrException
Eval[Expression CommaExpressionanyValue] = Eval[CommaExpressionanyValue]
action Eval[Program] : ValueOrException
Eval[Program Expression End] = Eval[Expression](nullObjectOrNullEnv)