/// <summary> /// Assigns the expression on the right to the local variable on the left /// </summary> public override void PerformOperation() { base.PerformOperation(); // If we have fewer than 2 objects on the stack we cannot perform this operator Debug.Assert(CelesteStack.StackSize >= 2, "Not enough elements on the stack for equality operator"); Scope scope = CelesteStack.CurrentScope; CelesteObject rhs = CelesteStack.Pop(); CelesteObject lhs = CelesteStack.Pop(); Debug.Assert(lhs.IsReference()); // All functions are references so check this condition first if (rhs.IsFunction()) { Debug.Assert(lhs.IsFunction(), "A function can only be assigned to another function"); Function lhsFunc = lhs.AsFunction(); Function rhsFunc = rhs.AsFunction(); Debug.Assert(CelesteStack.CurrentScope != lhsFunc.FunctionScope, "Cannot reassign functions inside their own scope"); lhsFunc.FunctionScope = rhsFunc.FunctionScope; lhsFunc.ParameterNames = rhsFunc.ParameterNames; lhsFunc.Ref = rhsFunc.Ref; // This is equivalent to setting their implementation to be the same } else if (rhs.IsReference()) { lhs.Value = rhs.Value; } else { lhs.AsReference().Value = rhs.Value; } }
/// <summary> /// Removes the the object at the top of the stack and performs the not operation. /// Then, pushes the result of the equality on to the top of the stack. /// </summary> public override void PerformOperation() { base.PerformOperation(); // If we have fewer than 1 object on the stack we cannot perform this operation Debug.Assert(CelesteStack.StackSize >= 1, "Not enough elements on the stack for the '!' operator"); CelesteObject rhs = CelesteStack.Pop(); // The stack will wrap our result in a CelesteObject, so just push the actual result of the equality bool result = false; Reference rhsRef = rhs.AsReference(); // Check to see whether our rhs is a reference if (rhsRef != null) { // Returns the result of the reference being equal to null result = rhsRef.Value == null; } else { // Else returns the logical opposite of the bool value result = (rhs.Value == null) || ((rhs.Value is bool) && !(bool)rhs.Value); } // We then finally push the result of the equality test onto the stack CelesteStack.Push(result); }
/// <summary> /// Removes the two objects at the top of the stack and performs logical operations them. /// Then, pushes the result of the operation on to the top of the stack. /// </summary> public sealed override void PerformOperation() { base.PerformOperation(); // If we have fewer than 2 objects on the stack we cannot perform this operation Debug.Assert(CelesteStack.StackSize >= 2, "Not enough elements on the stack for the equality operator"); CelesteObject rhs = CelesteStack.Pop(); CelesteObject lhs = CelesteStack.Pop(); // The stack will wrap our result in a CelesteObject, so just push the actual result of the operation bool result = false; Reference lhsRef = lhs.AsReference(); Reference rhsRef = rhs.AsReference(); // Check to see whether our lhs is a reference if (lhsRef != null) { if (rhsRef != null) { // If the rhs is a reference too, we compare references result = ReferenceReferenceOperation(lhsRef, rhsRef); } else { // Otherwise we compare the value of the rhs with the value of the lhs' referenced object result = ReferenceValueOperation(lhsRef, rhs.Value); } } else { if (rhsRef != null) { // If the rhs is a reference, we compare the value of the rhs' referenced object with the value of the lhs result = ReferenceValueOperation(rhsRef, lhs.Value); } else { // Otherwise we compare the value of the rhs with the value of the lhs - they are both values result = ValueValueOperation(lhs.Value, rhs.Value); } } // We then finally push the result of the equality test onto the stack CelesteStack.Push(result); }