Esempio n. 1
0
        public IEnumerable <MondValue> Enumerate(MondState state)
        {
            var enumerator = this;
            var moveNext   = enumerator["moveNext"];

            if (moveNext.Type != MondValueType.Function)
            {
                var getEnumerator = this["getEnumerator"];
                if (getEnumerator.Type != MondValueType.Function)
                {
                    throw new MondRuntimeException("Value is not enumerable");
                }

                enumerator = state.Call(getEnumerator);

                moveNext = enumerator["moveNext"];
                if (moveNext.Type != MondValueType.Function)
                {
                    throw new MondRuntimeException("Value is not enumerable");
                }
            }

            while (state.Call(moveNext))
            {
                yield return(enumerator["current"]);
            }
        }
Esempio n. 2
0
        internal bool TryDispatch(string name, out MondValue result, params MondValue[] args)
        {
            if (Type != MondValueType.Object)
            {
                result = Undefined;
                return(false);
            }

            // we can't use the indexer for metamethod lookups because that
            // could lead to infinite recursion, so we have a simplified
            // lookup here

            MondState state = null;
            MondValue callable;

            var current = this;

            while (true)
            {
                if (current.AsDictionary.TryGetValue(name, out callable))
                {
                    // we need to use the state from the metamethod's object
                    state = current.ObjectValue.State;

                    // and we need to wrap functions if needed
                    callable = CheckWrapFunction(callable);
                    break;
                }

                current = current.Prototype;

                if (current == null || current.Type != MondValueType.Object)
                {
                    break;
                }
            }

            if (callable == null)
            {
                result = Undefined;
                return(false);
            }

            if (state == null)
            {
                throw new MondRuntimeException("MondValue must have an attached state to use metamethods");
            }

            result = state.Call(callable, args);
            return(true);
        }
Esempio n. 3
0
        static void Main()
        {
            /*const string source1 = @"
                var a = [1, 2, 3];
                return a.length();
            ";*/

            const string source1 = @"
                fun fibonacci(n) {
                    fun inner(m, a, b) {
                        if (m == 0)
                            return a;

                        return inner(m - 1, b, a + b);
                    }

                    return inner(n, 0, 1);
                }

                return fibonacci(50);
            ";

            try
            {
                var state = new MondState();
                state["call"] = new MondFunction((_, args) => state.Call(args[0], args[1]));

                var program1 = MondProgram.Compile(source1, "test1.mnd");
                //var program2 = MondProgram.Compile(source2, "test2.mnd");

                var result1 = state.Load(program1);
                //var result2 = state.Load(program2);

                Console.WriteLine(result1.ToString());
                //Console.WriteLine(result2.ToString());
            }
            catch (MondException e)
            {
                Console.WriteLine(e.Message);
            }

            Console.ReadLine();
        }