/// <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; } }
public override void PerformOperation() { // Set up our parameters if required if (ParameterNames.Count > 0) { Debug.Assert(ChildCount > 0, "Fatal error in function call - no arguments to process"); CompiledStatement thisCallsParams = ChildCompiledStatements[0]; ChildCompiledStatements.RemoveAt(0); // This will run through each stored parameter and add them to the stack thisCallsParams.PerformOperation(); } // Set up our parameters - read them off the stack with the first parameter at the top for (int i = 0; i < ParameterNames.Count; i++) { Debug.Assert(CelesteStack.StackSize > 0, "Insufficient parameters to function"); CelesteObject input = CelesteStack.Pop(); Variable functionParameter = FunctionScope.GetLocalVariable(ParameterNames[i], ScopeSearchOption.kThisScope); if (input.IsReference()) { functionParameter.Value = input.ValueImpl; } else { (functionParameter.Value as Reference).Value = input.Value; } } CelesteStack.CurrentScope = FunctionScope; // Performs all the operators on the children first foreach (CompiledStatement statement in FuncImpl.ChildCompiledStatements) { statement.PerformOperation(); if (statement is ReturnKeyword) { // Stop iterating through if we have hit a ReturnKeyword in our function break; } } CelesteStack.Scopes.Remove(FunctionScope); CelesteStack.CurrentScope = FunctionScope.ParentScope; }