diff --git a/JSS.Lib.UnitTests/ASTTests.cs b/JSS.Lib.UnitTests/ASTTests.cs index afc96aa..8ad2d23 100644 --- a/JSS.Lib.UnitTests/ASTTests.cs +++ b/JSS.Lib.UnitTests/ASTTests.cs @@ -45,11 +45,11 @@ internal sealed class ASTTests // Tests for a block new object[] { "{ }", Completion.NormalCompletion(Undefined.The) }, - new object[] { "{ true }", Completion.NormalCompletion(new Boolean(true)) }, + new object[] { "{ true }", Completion.NormalCompletion(true) }, new object[] { "{ 1 }", Completion.NormalCompletion(new Number(1)) }, new object[] { $"{{ {EscapeString("string")} }}", Completion.NormalCompletion(new String("string")) }, new object[] { "{ 1 + 1 }", Completion.NormalCompletion(new Number(2)) }, - new object[] { "{ true ; }", Completion.NormalCompletion(new Boolean(true)) }, + new object[] { "{ true ; }", Completion.NormalCompletion(true) }, // Tests for GreaterThanEquals CreateGreaterThanEqualsTestCase(EscapeString("a"), EscapeString("b"), false), @@ -101,10 +101,10 @@ internal sealed class ASTTests CreateLogicalNOTTestCase("1", false), // Tests for LogicalAND - CreateLogicalANDTestCase("false", "false", new Boolean(false)), - CreateLogicalANDTestCase("true", "false", new Boolean(false)), - CreateLogicalANDTestCase("false", "true", new Boolean(false)), - CreateLogicalANDTestCase("true", "true", new Boolean(true)), + CreateLogicalANDTestCase("false", "false", false), + CreateLogicalANDTestCase("true", "false", false), + CreateLogicalANDTestCase("false", "true", false), + CreateLogicalANDTestCase("true", "true", true), CreateLogicalANDTestCase("0", "true", new Number(0)), CreateLogicalANDTestCase("true", "0", new Number(0)), CreateLogicalANDTestCase(EscapeString(""), "true", new String("")), @@ -113,14 +113,14 @@ internal sealed class ASTTests CreateLogicalANDTestCase("1", "1", new Number(1)), // Tests for LogicalOR - CreateLogicalORTestCase("false", "false", new Boolean(false)), - CreateLogicalORTestCase("true", "false", new Boolean(true)), - CreateLogicalORTestCase("false", "true", new Boolean(true)), - CreateLogicalORTestCase("true", "true", new Boolean(true)), - CreateLogicalORTestCase("0", "true", new Boolean(true)), - CreateLogicalORTestCase("true", "0", new Boolean(true)), - CreateLogicalORTestCase(EscapeString(""), "true", new Boolean(true)), - CreateLogicalORTestCase("true", EscapeString(""), new Boolean(true)), + CreateLogicalORTestCase("false", "false", false), + CreateLogicalORTestCase("true", "false", true), + CreateLogicalORTestCase("false", "true", true), + CreateLogicalORTestCase("true", "true", true), + CreateLogicalORTestCase("0", "true", true), + CreateLogicalORTestCase("true", "0", true), + CreateLogicalORTestCase(EscapeString(""), "true", true), + CreateLogicalORTestCase("true", EscapeString(""), true), CreateLogicalORTestCase(EscapeString("a"), EscapeString("a"), new String("a")), CreateLogicalORTestCase("1", "1", new Number(1)), @@ -170,15 +170,15 @@ internal sealed class ASTTests // Tests for Return CreateReturnTestCase("null", Null.The), - CreateReturnTestCase("false", new Boolean(false)), - CreateReturnTestCase("true", new Boolean(true)), + CreateReturnTestCase("false", false), + CreateReturnTestCase("true", true), CreateReturnTestCase("1", new Number(1)), CreateReturnTestCase(EscapeString("1"), new String("1")), // Tests for Throw CreateThrowTestCase("null", Null.The), - CreateThrowTestCase("false", new Boolean(false)), - CreateThrowTestCase("true", new Boolean(true)), + CreateThrowTestCase("false", false), + CreateThrowTestCase("true", true), CreateThrowTestCase("1", new Number(1)), CreateThrowTestCase(EscapeString("1"), new String("1")), @@ -213,7 +213,7 @@ internal sealed class ASTTests // FIXME: More iteration test cases when we have variables // Tests for DoWhileLoop CreateNormalDoWhileTestCase("false", "null", Null.The), - CreateNormalDoWhileTestCase("false", "false", new Boolean(false)), + CreateNormalDoWhileTestCase("false", "false", false), CreateNormalDoWhileTestCase("false", "1", new Number(1)), CreateNormalDoWhileTestCase("false", EscapeString("a"), new String("a")), CreateNormalDoWhileTestCase("false", "continue", Undefined.The), @@ -245,53 +245,53 @@ internal sealed class ASTTests // Tests for VarStatement CreateVarStatementTestCase("a", "null", Null.The), - CreateVarStatementTestCase("a", "false", new Boolean(false)), - CreateVarStatementTestCase("a", "true", new Boolean(true)), + CreateVarStatementTestCase("a", "false", false), + CreateVarStatementTestCase("a", "true", true), CreateVarStatementTestCase("a", "1", new Number(1)), CreateVarStatementTestCase("a", EscapeString("1"), new String("1")), // Tests for BasicAssignmentExpression CreateBasicAssignmentExpressionTestCase("a", "null", Null.The), - CreateBasicAssignmentExpressionTestCase("a", "false", new Boolean(false)), - CreateBasicAssignmentExpressionTestCase("a", "true", new Boolean(true)), + CreateBasicAssignmentExpressionTestCase("a", "false", false), + CreateBasicAssignmentExpressionTestCase("a", "true", true), CreateBasicAssignmentExpressionTestCase("a", "1", new Number(1)), CreateBasicAssignmentExpressionTestCase("a", EscapeString("1"), new String("1")), // Tests for LogicalAndAssignmentExpression CreateLogicalAndAssignmentExpressionTestCase("a", "true", "null", Null.The), - CreateLogicalAndAssignmentExpressionTestCase("a", "true", "false", new Boolean(false)), - CreateLogicalAndAssignmentExpressionTestCase("a", "true", "true", new Boolean(true)), + CreateLogicalAndAssignmentExpressionTestCase("a", "true", "false", false), + CreateLogicalAndAssignmentExpressionTestCase("a", "true", "true", true), CreateLogicalAndAssignmentExpressionTestCase("a", "true", "1", new Number(1)), CreateLogicalAndAssignmentExpressionTestCase("a", "true", EscapeString("1"), new String("1")), - CreateLogicalAndAssignmentExpressionTestCase("a", "false", "null", new Boolean(false)), - CreateLogicalAndAssignmentExpressionTestCase("a", "false", "false", new Boolean(false)), - CreateLogicalAndAssignmentExpressionTestCase("a", "false", "true", new Boolean(false)), - CreateLogicalAndAssignmentExpressionTestCase("a", "false", "1", new Boolean(false)), - CreateLogicalAndAssignmentExpressionTestCase("a", "false", EscapeString("1"), new Boolean(false)), + CreateLogicalAndAssignmentExpressionTestCase("a", "false", "null", false), + CreateLogicalAndAssignmentExpressionTestCase("a", "false", "false", false), + CreateLogicalAndAssignmentExpressionTestCase("a", "false", "true", false), + CreateLogicalAndAssignmentExpressionTestCase("a", "false", "1", false), + CreateLogicalAndAssignmentExpressionTestCase("a", "false", EscapeString("1"), false), // Tests for LogicalOrAssignmentExpression CreateLogicalOrAssignmentExpressionTestCase("a", "false", "null", Null.The), - CreateLogicalOrAssignmentExpressionTestCase("a", "false", "false", new Boolean(false)), - CreateLogicalOrAssignmentExpressionTestCase("a", "false", "true", new Boolean(true)), + CreateLogicalOrAssignmentExpressionTestCase("a", "false", "false", false), + CreateLogicalOrAssignmentExpressionTestCase("a", "false", "true", true), CreateLogicalOrAssignmentExpressionTestCase("a", "false", "1", new Number(1)), CreateLogicalOrAssignmentExpressionTestCase("a", "false", EscapeString("1"), new String("1")), - CreateLogicalOrAssignmentExpressionTestCase("a", "true", "null", new Boolean(true)), - CreateLogicalOrAssignmentExpressionTestCase("a", "true", "false", new Boolean(true)), - CreateLogicalOrAssignmentExpressionTestCase("a", "true", "true", new Boolean(true)), - CreateLogicalOrAssignmentExpressionTestCase("a", "true", "1", new Boolean(true)), - CreateLogicalOrAssignmentExpressionTestCase("a", "true", EscapeString("1"), new Boolean(true)), + CreateLogicalOrAssignmentExpressionTestCase("a", "true", "null", true), + CreateLogicalOrAssignmentExpressionTestCase("a", "true", "false", true), + CreateLogicalOrAssignmentExpressionTestCase("a", "true", "true", true), + CreateLogicalOrAssignmentExpressionTestCase("a", "true", "1", true), + CreateLogicalOrAssignmentExpressionTestCase("a", "true", EscapeString("1"), true), // Tests for LogicalOrAssignmentExpression CreateNullCoalescingAssignmentExpressionTestCase("a", "null", "null", Null.The), - CreateNullCoalescingAssignmentExpressionTestCase("a", "null", "false", new Boolean(false)), - CreateNullCoalescingAssignmentExpressionTestCase("a", "null", "true", new Boolean(true)), + CreateNullCoalescingAssignmentExpressionTestCase("a", "null", "false", false), + CreateNullCoalescingAssignmentExpressionTestCase("a", "null", "true", true), CreateNullCoalescingAssignmentExpressionTestCase("a", "null", "1", new Number(1)), CreateNullCoalescingAssignmentExpressionTestCase("a", "null", EscapeString("1"), new String("1")), - CreateNullCoalescingAssignmentExpressionTestCase("a", "false", "null", new Boolean(false)), - CreateNullCoalescingAssignmentExpressionTestCase("a", "false", "false", new Boolean(false)), - CreateNullCoalescingAssignmentExpressionTestCase("a", "false", "true", new Boolean(false)), - CreateNullCoalescingAssignmentExpressionTestCase("a", "false", "1", new Boolean(false)), - CreateNullCoalescingAssignmentExpressionTestCase("a", "false", EscapeString("1"), new Boolean(false)), + CreateNullCoalescingAssignmentExpressionTestCase("a", "false", "null", false), + CreateNullCoalescingAssignmentExpressionTestCase("a", "false", "false", false), + CreateNullCoalescingAssignmentExpressionTestCase("a", "false", "true", false), + CreateNullCoalescingAssignmentExpressionTestCase("a", "false", "1", false), + CreateNullCoalescingAssignmentExpressionTestCase("a", "false", EscapeString("1"), false), // Tests for BinaryOpAssignmentExpression CreateBinaryOpAssignmentExpressionTestCase("a", EscapeString("a"), "+", EscapeString("b"), new String("ab")), @@ -367,15 +367,15 @@ internal sealed class ASTTests // Tests for LetDeclarations CreateLetDeclarationTestCase("a", "null", Null.The), - CreateLetDeclarationTestCase("a", "false", new Boolean(false)), - CreateLetDeclarationTestCase("a", "true", new Boolean(true)), + CreateLetDeclarationTestCase("a", "false", false), + CreateLetDeclarationTestCase("a", "true", true), CreateLetDeclarationTestCase("a", "1", new Number(1)), CreateLetDeclarationTestCase("a", EscapeString("1"), new String("1")), // Tests for ConstDeclarations CreateConstDeclarationTestCase("a", "null", Null.The), - CreateConstDeclarationTestCase("a", "false", new Boolean(false)), - CreateConstDeclarationTestCase("a", "true", new Boolean(true)), + CreateConstDeclarationTestCase("a", "false", false), + CreateConstDeclarationTestCase("a", "true", true), CreateConstDeclarationTestCase("a", "1", new Number(1)), CreateConstDeclarationTestCase("a", EscapeString("1"), new String("1")), @@ -407,40 +407,40 @@ internal sealed class ASTTests CreateCallExpressionTestCase("1", Undefined.The), CreateCallExpressionTestCase(EscapeString("1"), Undefined.The), CreateCallExpressionTestCase("return null", Null.The), - CreateCallExpressionTestCase("return false", new Boolean(false)), - CreateCallExpressionTestCase("return true", new Boolean(true)), + CreateCallExpressionTestCase("return false", false), + CreateCallExpressionTestCase("return true", true), CreateCallExpressionTestCase("return 1", new Number(1)), CreateCallExpressionTestCase($"return {EscapeString("1")}", new String("1")), CreateThrowingCallExpressionTestCase("throw null", Null.The), - CreateThrowingCallExpressionTestCase("throw false", new Boolean(false)), - CreateThrowingCallExpressionTestCase("throw true", new Boolean(true)), + CreateThrowingCallExpressionTestCase("throw false", false), + CreateThrowingCallExpressionTestCase("throw true", true), CreateThrowingCallExpressionTestCase("throw 1", new Number(1)), CreateThrowingCallExpressionTestCase($"throw {EscapeString("1")}", new String("1")), CreateCallExpressionParameterTestCase("", Undefined.The), CreateCallExpressionParameterTestCase("null", Null.The), - CreateCallExpressionParameterTestCase("false", new Boolean(false)), - CreateCallExpressionParameterTestCase("true", new Boolean(true)), + CreateCallExpressionParameterTestCase("false", false), + CreateCallExpressionParameterTestCase("true", true), CreateCallExpressionParameterTestCase("1", new Number(1)), CreateCallExpressionParameterTestCase(EscapeString("1"), new String("1")), // Tests for PropertyExpression CreatePropertyExpressionTestCase("null", Null.The), - CreatePropertyExpressionTestCase("false", new Boolean(false)), - CreatePropertyExpressionTestCase("true", new Boolean(true)), + CreatePropertyExpressionTestCase("false", false), + CreatePropertyExpressionTestCase("true", true), CreatePropertyExpressionTestCase("1", new Number(1)), CreatePropertyExpressionTestCase(EscapeString("1"), new String("1")), // Tests for ComputedPropertyExpression CreateComputedPropertyExpressionTestCase("null", Null.The), - CreateComputedPropertyExpressionTestCase("false", new Boolean(false)), - CreateComputedPropertyExpressionTestCase("true", new Boolean(true)), + CreateComputedPropertyExpressionTestCase("false", false), + CreateComputedPropertyExpressionTestCase("true", true), CreateComputedPropertyExpressionTestCase("1", new Number(1)), CreateComputedPropertyExpressionTestCase(EscapeString("1"), new String("1")), }; static private object[] CreateBooleanLiteralTestCase(bool value) { - return new object[] { value ? "true" : "false", Completion.NormalCompletion(new Boolean(value)) }; + return new object[] { value ? "true" : "false", Completion.NormalCompletion(value) }; } static private object[] CreateNumericLiteralTestCase(double value) @@ -465,27 +465,27 @@ static private object[] CreateAdditionTestCase(double lhs, double rhs, double ex static private object[] CreateGreaterThanEqualsTestCase(string lhs, string rhs, bool expected) { - return new object[] { $"{lhs} >= {rhs}", Completion.NormalCompletion(new Boolean(expected)) }; + return new object[] { $"{lhs} >= {rhs}", Completion.NormalCompletion(expected) }; } static private object[] CreateGreaterThanTestCase(string lhs, string rhs, bool expected) { - return new object[] { $"{lhs} > {rhs}", Completion.NormalCompletion(new Boolean(expected)) }; + return new object[] { $"{lhs} > {rhs}", Completion.NormalCompletion(expected) }; } static private object[] CreateLessThanEqualsTestCase(string lhs, string rhs, bool expected) { - return new object[] { $"{lhs} <= {rhs}", Completion.NormalCompletion(new Boolean(expected)) }; + return new object[] { $"{lhs} <= {rhs}", Completion.NormalCompletion(expected) }; } static private object[] CreateLessThanTestCase(string lhs, string rhs, bool expected) { - return new object[] { $"{lhs} < {rhs}", Completion.NormalCompletion(new Boolean(expected)) }; + return new object[] { $"{lhs} < {rhs}", Completion.NormalCompletion(expected) }; } static private object[] CreateLogicalNOTTestCase(string value, bool expected) { - return new object[] { $"!{value}", Completion.NormalCompletion(new Boolean(expected)) }; + return new object[] { $"!{value}", Completion.NormalCompletion(expected) }; } static private object[] CreateLogicalANDTestCase(string lhs, string rhs, Value expected) @@ -500,22 +500,22 @@ static private object[] CreateLogicalORTestCase(string lhs, string rhs, Value ex static private object[] CreateLooselyEqualTestCase(string lhs, string rhs, bool expected) { - return new object[] { $"{lhs} == {rhs}", Completion.NormalCompletion(new Boolean(expected)) }; + return new object[] { $"{lhs} == {rhs}", Completion.NormalCompletion(expected) }; } static private object[] CreateLooselyInequalTestCase(string lhs, string rhs, bool expected) { - return new object[] { $"{lhs} != {rhs}", Completion.NormalCompletion(new Boolean(expected)) }; + return new object[] { $"{lhs} != {rhs}", Completion.NormalCompletion(expected) }; } static private object[] CreateStrictEqualTestCase(string lhs, string rhs, bool expected) { - return new object[] { $"{lhs} === {rhs}", Completion.NormalCompletion(new Boolean(expected)) }; + return new object[] { $"{lhs} === {rhs}", Completion.NormalCompletion(expected) }; } static private object[] CreateStrictInequalTestCase(string lhs, string rhs, bool expected) { - return new object[] { $"{lhs} !== {rhs}", Completion.NormalCompletion(new Boolean(expected)) }; + return new object[] { $"{lhs} !== {rhs}", Completion.NormalCompletion(expected) }; } static private object[] CreateReturnTestCase(string value, Value expected) diff --git a/JSS.Lib.UnitTests/AbstractOperationTests.cs b/JSS.Lib.UnitTests/AbstractOperationTests.cs index b26cca8..f298217 100644 --- a/JSS.Lib.UnitTests/AbstractOperationTests.cs +++ b/JSS.Lib.UnitTests/AbstractOperationTests.cs @@ -12,8 +12,8 @@ internal sealed class AbstractOperationTests static private readonly List toPrimitiveIdentityTestCases = new() { Null.The, - new Boolean(false), - new Boolean(true), + false, + true, new Number(0.0), new Number(1.0), new Number(123456789.0), diff --git a/JSS.Lib/AST/GreaterThanEqualsExpression.cs b/JSS.Lib/AST/GreaterThanEqualsExpression.cs index ca347c6..f0f71c9 100644 --- a/JSS.Lib/AST/GreaterThanEqualsExpression.cs +++ b/JSS.Lib/AST/GreaterThanEqualsExpression.cs @@ -37,10 +37,10 @@ override public Completion Evaluate(VM vm) if (r.IsAbruptCompletion()) return r; // 6. If r is either true or undefined, return false. Otherwise, return true. - if (r.Value.IsUndefined()) return new Boolean(false); + if (r.Value.IsUndefined()) return false; var rAsBoolean = r.Value.AsBoolean(); - return new Boolean(!rAsBoolean.Value); + return !rAsBoolean.Value; } public IExpression Lhs { get; } diff --git a/JSS.Lib/AST/GreaterThanExpreesion.cs b/JSS.Lib/AST/GreaterThanExpreesion.cs index 4f2b9fb..5526132 100644 --- a/JSS.Lib/AST/GreaterThanExpreesion.cs +++ b/JSS.Lib/AST/GreaterThanExpreesion.cs @@ -37,10 +37,10 @@ override public Completion Evaluate(VM vm) if (r.IsAbruptCompletion()) return r; // 6. If r is undefined, return false. Otherwise, return r. - if (r.Value.IsUndefined()) return new Boolean(false); + if (r.Value.IsUndefined()) return false; var rAsBoolean = r.Value.AsBoolean(); - return new Boolean(rAsBoolean.Value); + return rAsBoolean.Value; } public IExpression Lhs { get; } diff --git a/JSS.Lib/AST/LessThanEqualsExpression.cs b/JSS.Lib/AST/LessThanEqualsExpression.cs index 9cd2be4..969d469 100644 --- a/JSS.Lib/AST/LessThanEqualsExpression.cs +++ b/JSS.Lib/AST/LessThanEqualsExpression.cs @@ -37,10 +37,10 @@ override public Completion Evaluate(VM vm) if (r.IsAbruptCompletion()) return r; // 6. If r is either true or undefined, return false. Otherwise, return true. - if (r.Value.IsUndefined()) return new Boolean(false); + if (r.Value.IsUndefined()) return false; var rAsBoolean = r.Value.AsBoolean(); - return new Boolean(!rAsBoolean.Value); + return !rAsBoolean.Value; } public IExpression Lhs { get; } diff --git a/JSS.Lib/AST/LessThanExpression.cs b/JSS.Lib/AST/LessThanExpression.cs index 1992e14..4264484 100644 --- a/JSS.Lib/AST/LessThanExpression.cs +++ b/JSS.Lib/AST/LessThanExpression.cs @@ -37,10 +37,10 @@ override public Completion Evaluate(VM vm) if (r.IsAbruptCompletion()) return r; // 6. If r is undefined, return false. Otherwise, return r. - if (r.Value.IsUndefined()) return new Boolean(false); + if (r.Value.IsUndefined()) return false; var rAsBoolean = r.Value.AsBoolean(); - return new Boolean(rAsBoolean.Value); + return rAsBoolean.Value; } public IExpression Lhs { get; } diff --git a/JSS.Lib/AST/Literal/BooleanLiteral.cs b/JSS.Lib/AST/Literal/BooleanLiteral.cs index 539c6f7..f93e018 100644 --- a/JSS.Lib/AST/Literal/BooleanLiteral.cs +++ b/JSS.Lib/AST/Literal/BooleanLiteral.cs @@ -9,7 +9,7 @@ internal sealed class BooleanLiteral : IExpression { public BooleanLiteral(bool value) { - _value = new Boolean(value); + _value = value; } // 13.2.3.1 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-literals-runtime-semantics-evaluation diff --git a/JSS.Lib/AST/LogicalNotExpression.cs b/JSS.Lib/AST/LogicalNotExpression.cs index 35ef83f..a59d06c 100644 --- a/JSS.Lib/AST/LogicalNotExpression.cs +++ b/JSS.Lib/AST/LogicalNotExpression.cs @@ -26,7 +26,7 @@ override public Completion Evaluate(VM vm) // 3. If oldValue is true, return false. // 4. Return true. - return new Boolean(!oldValue.Value); + return !oldValue.Value; } public IExpression Expression { get; } diff --git a/JSS.Lib/AST/LooseInequalityExpression.cs b/JSS.Lib/AST/LooseInequalityExpression.cs index ec7d538..04f3aba 100644 --- a/JSS.Lib/AST/LooseInequalityExpression.cs +++ b/JSS.Lib/AST/LooseInequalityExpression.cs @@ -38,7 +38,7 @@ override public Completion Evaluate(VM vm) // 6. If r is true, return false. Otherwise, return true. var rAsBoolean = r.Value.AsBoolean().Value; - return new Boolean(!rAsBoolean); + return !rAsBoolean; } public IExpression Lhs { get; } diff --git a/JSS.Lib/AST/StrictInequalityExpression.cs b/JSS.Lib/AST/StrictInequalityExpression.cs index 93d2b5c..9001bec 100644 --- a/JSS.Lib/AST/StrictInequalityExpression.cs +++ b/JSS.Lib/AST/StrictInequalityExpression.cs @@ -36,7 +36,7 @@ override public Completion Evaluate(VM vm) var r = Value.IsStrictlyEqual(rval.Value, lval.Value); // 6. If r is true, return false. Otherwise, return true. - return new Boolean(!r.Value); + return !r.Value; } public IExpression Lhs { get; } diff --git a/JSS.Lib/AST/Values/Boolean.cs b/JSS.Lib/AST/Values/Boolean.cs index 2f44fa2..ad272ff 100644 --- a/JSS.Lib/AST/Values/Boolean.cs +++ b/JSS.Lib/AST/Values/Boolean.cs @@ -7,6 +7,9 @@ public Boolean(bool value) Value = value; } + public static implicit operator Boolean(bool value) => new(value); + public static implicit operator bool(Boolean boolean) => boolean.Value; + override public bool IsBoolean() { return true; } override public ValueType Type() { return ValueType.Boolean; } diff --git a/JSS.Lib/AST/Values/Number.cs b/JSS.Lib/AST/Values/Number.cs index 6be495f..db6876a 100644 --- a/JSS.Lib/AST/Values/Number.cs +++ b/JSS.Lib/AST/Values/Number.cs @@ -223,7 +223,7 @@ static public Value LessThan(Number x, Number y) // FIXME: 10. Assert: x and y are finite. // 11. If ℝ(x) < ℝ(y), return true. Otherwise, return false. - return new Boolean(x.Value < y.Value); + return x.Value < y.Value; } // 6.1.6.1.13 Number::equal ( x, y ) @@ -232,26 +232,26 @@ static public Boolean Equal(Number x, Number y) // 1. If x is NaN, return false. if (double.IsNaN(x.Value)) { - return new Boolean(false); + return false; } // 2. If y is NaN, return false. if (double.IsNaN(y.Value)) { - return new Boolean(false); + return false; } // 3. If x is y, return true. if (x.Value == y.Value) { - return new Boolean(true); + return true; } // FIXME: 4. If x is +0𝔽 and y is -0𝔽, return true. // FIXME: 5. If x is -0𝔽 and y is +0𝔽, return true. // 6. Return false. - return new Boolean(false); + return false; } internal enum BitwiseOp diff --git a/JSS.Lib/AST/Values/Object.cs b/JSS.Lib/AST/Values/Object.cs index 79b8294..380eee3 100644 --- a/JSS.Lib/AST/Values/Object.cs +++ b/JSS.Lib/AST/Values/Object.cs @@ -87,7 +87,7 @@ static public Completion HasOwnProperty(Object O, string P) // 2. If desc is undefined, return false. // 3. Return true. - return new Boolean(!desc.Value.IsUndefined()); + return !desc.Value.IsUndefined(); } // 7.3.14 Call ( F, V [ , argumentsList ] ) @@ -152,7 +152,7 @@ static public Completion OrdinaryDefineOwnProperty(Object O, string P, Property // FIXME: 2. Let extensible be ? IsExtensible(O). // FIXME: 3. Return ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current). O.DataProperties.Add(P, desc); - return new Boolean(true); + return true; } // 10.1.7 [[HasProperty]] ( P ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-hasproperty-p @@ -170,7 +170,7 @@ static public Completion OrdinaryHasProperty(Object O, string P) if (hasOwn.IsAbruptCompletion()) return hasOwn; // FIXME: 2. If hasOwn is not undefined, return true. - return new Boolean(!hasOwn.Value.IsUndefined()); + return !hasOwn.Value.IsUndefined(); // FIXME: 3. Let parent be ? O.[[GetPrototypeOf]](). // FIXME: 4. If parent is not null, then @@ -225,7 +225,7 @@ static public Completion OrdinarySet(Object O, string P, Value V, Object receive receiver.DataProperties[P] = new Property(V, new Attributes(true, false, false)); } - return new Boolean(true); + return true; } // FIXME: Accessor Attributes diff --git a/JSS.Lib/AST/Values/Value.cs b/JSS.Lib/AST/Values/Value.cs index 4120aaf..c9305c3 100644 --- a/JSS.Lib/AST/Values/Value.cs +++ b/JSS.Lib/AST/Values/Value.cs @@ -22,6 +22,8 @@ internal enum ValueType // 6.1 ECMAScript Language Types, https://tc39.es/ecma262/#sec-ecmascript-language-types internal abstract class Value { + public static implicit operator Value(bool value) => new Boolean(value); + virtual public bool IsEmpty() { return false; } virtual public bool IsReference() { return false; } virtual public bool IsEnvironment() { return false; } @@ -229,7 +231,7 @@ public Boolean ToBoolean() // 2. If argument is one of undefined, null, +0𝔽, -0𝔽, NaN, 0ℤ, or the empty String, return false. if (IsUndefined() || IsNull()) { - return new Boolean(false); + return false; } if (IsNumber()) @@ -237,7 +239,7 @@ public Boolean ToBoolean() var asNumber = AsNumber().Value; if (asNumber == 0 || double.IsNaN(asNumber)) { - return new Boolean(false); + return false; } } @@ -246,14 +248,14 @@ public Boolean ToBoolean() var asString = AsString().Value; if (asString.Length == 0) { - return new Boolean(false); + return false; } } // 3. NOTE: This step is replaced in section B.3.6.1. // 4. Return true. - return new Boolean(true); + return true; } // 7.1.3 ToNumeric ( value ), https://tc39.es/ecma262/#sec-tonumeric @@ -426,7 +428,7 @@ static public Boolean SameValueNonNumber(Value x, Value y) // 2. If x is either null or undefined, return true. if (x.IsNull() || x.IsUndefined()) { - return new Boolean(true); + return true; } // FIXME: 3. If x is a BigInt, then @@ -438,7 +440,7 @@ static public Boolean SameValueNonNumber(Value x, Value y) // a. If x and y have the same length and the same code units in the same positions, return true; otherwise, return false. var xAsString = x.AsString().Value; var yAsString = y.AsString().Value; - return new Boolean(xAsString == yAsString); + return xAsString == yAsString; } // 5. If x is a Boolean, then @@ -447,7 +449,7 @@ static public Boolean SameValueNonNumber(Value x, Value y) // 6. If x and y are both true or both false, return true; otherwise, return false. var xAsBoolean = x.AsBoolean().Value; var yAsBoolean = y.AsBoolean().Value; - return new Boolean(xAsBoolean == yAsBoolean); + return xAsBoolean == yAsBoolean; } // FIXME: 6. NOTE: All other ECMAScript language values are compared by identity. @@ -509,18 +511,18 @@ static public Completion IsLessThan(Value x, Value y, bool leftFirst) // iii. If cx < cy, return true. if (cx < cy) { - return new Boolean(true); + return true; } // iv. If cx > cy, return false. if (cx > cy) { - return new Boolean(false); + return false; } } // d. If lx < ly, return true. Otherwise, return false. - return new Boolean(lx < ly); + return lx < ly; } // 4. Else, @@ -573,13 +575,13 @@ static public Completion IsLooselyEqual(Value x, Value y) // 2. If x is null and y is undefined, return true. if (x.IsNull() && y.IsUndefined()) { - return new Boolean(true); + return true; } // 3. If x is undefined and y is null, return true. if (x.IsUndefined() && y.IsNull()) { - return new Boolean(true); + return true; } // 4. NOTE: This step is replaced in section B.3.6.2. @@ -631,7 +633,7 @@ static public Completion IsLooselyEqual(Value x, Value y) // FIXME: b. If ℝ(x) = ℝ(y), return true; otherwise return false. // 14. Return false. - return new Boolean(false); + return false; } // 7.2.15 IsStrictlyEqual ( x, y ), https://tc39.es/ecma262/#sec-isstrictlyequal @@ -640,7 +642,7 @@ static public Boolean IsStrictlyEqual(Value x, Value y) // 1. If Type(x) is not Type(y), return false. if (!x.Type().Equals(y.Type())) { - return new Boolean(false); + return false; } // 2. If x is a Number, then diff --git a/JSS.Lib/Execution/Completion.cs b/JSS.Lib/Execution/Completion.cs index 91c4f87..713400f 100644 --- a/JSS.Lib/Execution/Completion.cs +++ b/JSS.Lib/Execution/Completion.cs @@ -23,6 +23,7 @@ public Completion(CompletionType type, Value value, string target) Target = target; } + override public bool Equals(object? obj) { if (obj is not Completion completion) { return false; } @@ -43,6 +44,7 @@ static public Completion NormalCompletion(Value value) // NOTE: We use an implicit conversion operator as a syntaxic sugar for NormalCompletion in functions public static implicit operator Completion(Value value) => NormalCompletion(value); + public static implicit operator Completion(bool value) => NormalCompletion(value); // 6.2.4.2 ThrowCompletion ( value ), https://tc39.es/ecma262/#sec-throwcompletion static public Completion ThrowCompletion(Value value) @@ -84,25 +86,25 @@ public Boolean LoopContinues() // 1. If completion.[[Type]] is NORMAL, return true. if (IsNormalCompletion()) { - return new Boolean(true); + return true; } // 2. If completion.[[Type]] is not CONTINUE, return false. if (!IsContinueCompletion()) { - return new Boolean(false); + return false; } // 3. If completion.[[Target]] is EMPTY, return true. if (Target.Length == 0) { - return new Boolean(true); + return true; } // FIXME: 4. If labelSet contains completion.[[Target]], return true. // 5. Return false. - return new Boolean(false); + return false; } public bool IsNormalCompletion() { return Type == CompletionType.Normal; } diff --git a/JSS.Lib/Execution/GlobalEnvironment.cs b/JSS.Lib/Execution/GlobalEnvironment.cs index a211b27..3a36888 100644 --- a/JSS.Lib/Execution/GlobalEnvironment.cs +++ b/JSS.Lib/Execution/GlobalEnvironment.cs @@ -167,11 +167,11 @@ public Completion HasRestrictedGlobalProperty(string N) if (existingProp.IsAbruptCompletion()) return existingProp; // 4. If existingProp is undefined, return false. - if (existingProp.Value.IsUndefined()) return new Boolean(false); + if (existingProp.Value.IsUndefined()) return false; // FIXME: 5. If existingProp.[[Configurable]] is true, return false. // 6. Return true. - return new Boolean(true); + return true; } // 9.1.1.4.15 CanDeclareGlobalVar ( N ), https://tc39.es/ecma262/#sec-candeclareglobalvar @@ -187,10 +187,10 @@ public Completion CanDeclareGlobalVar(string N) // 4. If hasProperty is true, return true. var asBoolean = hasProperty.Value.AsBoolean(); - if (asBoolean.Value) return new Boolean(true); + if (asBoolean.Value) return true; // FIXME: 5. Return ? IsExtensible(globalObject). - return new Boolean(true); + return true; } // 9.1.1.4.16 CanDeclareGlobalFunction ( N ), https://tc39.es/ecma262/#sec-candeclareglobalfunction @@ -205,12 +205,12 @@ public Completion CanDeclareGlobalFunction(string N) if (existingProp.IsAbruptCompletion()) return existingProp; // 4. If existingProp is undefined, FIXME: return ? IsExtensible(globalObject). - if (existingProp.Value.IsUndefined()) return new Boolean(true); + if (existingProp.Value.IsUndefined()) return true; // FIXME: 5. If existingProp.[[Configurable]] is true, return true. // FIXME: 6. If IsDataDescriptor(existingProp) is true and existingProp has attribute values { [[Writable]]: true, [[Enumerable]]: true }, return true. // 7. Return false. - return new Boolean(false); + return false; } // 9.1.1.4.17 CreateGlobalVarBinding ( N, D ), https://tc39.es/ecma262/#sec-createglobalvarbinding