Esempio n. 1
0
        public MondValue Call(MondValue function, params MondValue[] arguments)
        {
            if (function.Type == MondValueType.Object)
            {
                // insert "this" value into argument array
                Array.Resize(ref arguments, arguments.Length + 1);
                Array.Copy(arguments, 0, arguments, 1, arguments.Length - 1);
                arguments[0] = function;

                if (function.TryDispatch("__call", out var result, arguments))
                {
                    return(result);
                }
            }

            if (function.Type != MondValueType.Function)
            {
                throw new MondRuntimeException(RuntimeError.ValueNotCallable, function.Type.GetName());
            }

            var closure = function.FunctionValue;

            switch (closure.Type)
            {
            case ClosureType.Mond:
                var argFrame = closure.Arguments;
                if (argFrame == null)
                {
                    argFrame = new Frame(0, null, arguments.Length);
                }
                else
                {
                    argFrame = new Frame(argFrame.Depth + 1, argFrame, arguments.Length);
                }

                for (var i = 0; i < arguments.Length; i++)
                {
                    argFrame.Values[i] = arguments[i];
                }

                PushCall(new ReturnAddress(closure.Program, closure.Address, argFrame, _evalStackSize));
                PushLocal(closure.Locals);
                break;

            case ClosureType.Native:
                return(closure.NativeFunction(_state, arguments));

            default:
                throw new NotSupportedException();
            }

            return(Run());
        }
Esempio n. 2
0
        public MondValue Call(MondValue function, params MondValue[] arguments)
        {
            if (function.Type == MondValueType.Object)
            {
                // insert "this" value into argument array
                Array.Resize(ref arguments, arguments.Length + 1);
                Array.Copy(arguments, 0, arguments, 1, arguments.Length - 1);
                arguments[0] = function;

                MondValue result;
                if (function.TryDispatch("__call", out result, arguments))
                    return result;
            }

            if (function.Type != MondValueType.Function)
                throw new MondRuntimeException(RuntimeError.ValueNotCallable, function.Type.GetName());

            var closure = function.FunctionValue;

            switch (closure.Type)
            {
                case ClosureType.Mond:
                    var argFrame = closure.Arguments;
                    if (argFrame == null)
                        argFrame = new Frame(0, null, arguments.Length);
                    else
                        argFrame = new Frame(argFrame.Depth + 1, argFrame, arguments.Length);

                    for (var i = 0; i < arguments.Length; i++)
                    {
                        argFrame.Values[i] = arguments[i];
                    }

                    PushCall(new ReturnAddress(closure.Program, closure.Address, argFrame, _evalStackSize));
                    PushLocal(closure.Locals);
                    break;

                case ClosureType.Native:
                    return closure.NativeFunction(_state, arguments);

                default:
                    throw new NotSupportedException();
            }

            return Run();
        }