Example #1
0
        /// <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;
            }
        }
Example #2
0
        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;
        }