예제 #1
0
파일: Machine.cs 프로젝트: krixalis/Mond
        public MondValue Call(MondValue closure, params MondValue[] arguments)
        {
            if (closure.Type != MondValueType.Closure)
                throw new MondRuntimeException("Attempt to call non-closure");

            var closureValue = closure.ClosureValue;

            if (closureValue.Type == ClosureType.Mond)
            {
                var argFrame = closureValue.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];
                }

                _callStack.Push(new ReturnAddress(closureValue.ProgramId, closureValue.Address, argFrame));

                if (closureValue.Locals != null)
                    _localStack.Push(closureValue.Locals);
            }
            else
            {
                throw new NotSupportedException();
            }

            return Run();
        }
예제 #2
0
        static ArrayPrototype()
        {
            Value = new MondValue(MondValueType.Object);
            Value["prototype"] = ObjectPrototype.Value;

            Value["length"] = new MondInstanceFunction(Length);
        }
예제 #3
0
        public void Creation()
        {
            var empty = Script.Run(@"
                return [];
            ");

            Assert.AreEqual(empty.Type, MondValueType.Array);
            Assert.True(empty.Array.SequenceEqual(Enumerable.Empty<MondValue>()));

            var array = Script.Run(@"
                var a = 'test';
                return [ 1, a, 3, 4 ];
            ");

            var expected = new MondValue[]
            {
                1, "test", 3, 4
            };

            Assert.AreEqual(array.Type, MondValueType.Array);
            Assert.True(array.Array.SequenceEqual(expected));

            array = Script.Run(@"
                return [ 1, 2, 3, ];
            ");

            expected = new MondValue[]
            {
                1, 2, 3
            };

            Assert.AreEqual(array.Type, MondValueType.Array);
            Assert.True(array.Array.SequenceEqual(expected));
        }
예제 #4
0
        static StringPrototype()
        {
            Value = MondPrototypeBinder.Bind(typeof(StringPrototype));
            Value.Prototype = ValuePrototype.Value;

            Value.Lock();
        }
예제 #5
0
        private static MondValue Length(MondState state, MondValue instance, params MondValue[] arguments)
        {
            if (instance.Type != MondValueType.Array)
                throw new MondRuntimeException("Array.length must be called on a String");

            return instance.ArrayValue.Count;
        }
예제 #6
0
        public void Register(MondState state, MondValue function)
        {
            if (function.Type != MondValueType.Function)
                throw new MondRuntimeException("register: first argument must be a function");

            CancellationToken.Register(() => state.Call(function));
        }
예제 #7
0
        public static bool MatchTypes( MondValue[] values, Type[] types )
        {
            if( values.Length != types.Length )
                return false;

            return values.Zip( types, ( a, b ) => new { Value = a, Type = b } ).All( x => MatchType( x.Value, x.Type ) );
        }
예제 #8
0
        public void Add()
        {
            _result = Script.Run(@"
                var a = 100, b = 10;
                return a + b;
            ");

            Assert.True(_result == 110);

            _result = Script.Run(@"
                var a = 'test', b = 10;
                return a + b;
            ");

            Assert.True(_result == "test10");

            Assert.Throws<MondRuntimeException>(() => Script.Run(@"
                var a = null, b = 10;
                return a + b;
            "));

            Assert.Throws<MondCompilerException>(() => Script.Run(@"
                return 1 += 2;
            "));
        }
예제 #9
0
        static ObjectPrototype()
        {
            Value = MondPrototypeBinder.Bind(typeof(ObjectPrototype));
            Value.Prototype = ValuePrototype.Value;

            Value.Lock();
        }
예제 #10
0
        public void FizzBuzz()
        {
            MondState state;
            var result = Script.Run(out state, @"
                seq fizzBuzz() {
                    var n = 1;

                    while (true) {
                        if (n % 15 == 0)
                            yield 'FizzBuzz';
                        else if (n % 3 == 0)
                            yield 'Fizz';
                        else if (n % 5 == 0)
                            yield 'Buzz';
                        else
                            yield '' + n;

                        n++;
                    }
                }

                return fizzBuzz();
            ");

            var expected = new MondValue[]
            {
                "1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "FizzBuzz"
            };

            Assert.True(result.IsEnumerable);
            Assert.True(result.Enumerate(state).Take(expected.Length).SequenceEqual(expected));
        }
예제 #11
0
 public Object()
 {
     Values = new Dictionary<MondValue, MondValue>();
     Locked = false;
     Prototype = null;
     UserData = null;
     ThisEnabled = false;
 }
예제 #12
0
        public MondValue Load(MondProgram program)
        {
            if (program == null)
                throw new ArgumentNullException("program");

            var function = new MondValue(new Closure(program, 0, null, null));
            return Call(function);
        }
예제 #13
0
        public static string Serialize(MondValue value)
        {
            var sb = new StringBuilder();

            SerializeImpl(value, sb, 0);

            return sb.ToString();
        }
예제 #14
0
 public static MondValue JsonWatch(Watch watch)
 {
     var obj = new MondValue(MondValueType.Object);
     obj["Id"] = watch.Id;
     obj["Expression"] = watch.Expression;
     obj["Value"] = watch.Value;
     return obj;
 }
예제 #15
0
        public void BitNot()
        {
            _result = Script.Run(@"
                var a = 100;
                return ~a;
            ");

            Assert.True(_result == -101);
        }
예제 #16
0
        public static void Add([MondInstance] MondValue instance, MondValue key, MondValue value)
        {
            EnsureObject("add", instance);

            if (instance.ObjectValue.Locked)
                throw new MondRuntimeException(LockedError, "add");

            instance.ObjectValue.Values[key] = value;
        }
예제 #17
0
        static ValuePrototype()
        {
            Value = MondPrototypeBinder.Bind(typeof(ValuePrototype));

            // we dont use MondValue.Prototype here because this should not have a prototype
            Value.ObjectValue.Prototype = MondValue.Undefined;

            Value.Lock();
        }
예제 #18
0
 public static MondValue JsonProgram(ProgramInfo program)
 {
     var obj = new MondValue(MondValueType.Object);
     obj["FileName"] = program.FileName;
     obj["SourceCode"] = program.DebugInfo.SourceCode;
     obj["FirstLine"] = FirstLineNumber(program.DebugInfo);
     obj["Breakpoints"] = new MondValue(program.Breakpoints.Select(e => new MondValue(e)));
     return obj;
 }
예제 #19
0
 public static MondValue JsonCallStackEntry(MondDebugContext.CallStackEntry callStackEntry)
 {
     var obj = new MondValue(MondValueType.Object);
     obj["FileName"] = callStackEntry.FileName;
     obj["Function"] = callStackEntry.Function;
     obj["LineNumber"] = callStackEntry.LineNumber;
     obj["ColumnNumber"] = callStackEntry.ColumnNumber;
     return obj;
 }
예제 #20
0
        public MondValue Get( MondState state, MondValue instance, string name )
        {
            var newPath = _path + "." + name;

            var type = InteropLibrary.LookupType( newPath );
            if( type != null )
                return MondObjectBinder.Bind( type, state, MondBindingOptions.AutoLock );

            return new NamespaceReference( newPath ).ToMond( state );
        }
예제 #21
0
        public static bool MatchType( MondValue value, Type type )
        {
            if( type == typeof( char ) )
                return value.Type == MondValueType.String && value.ToString().Length == 1;

            if( value.Type == MondValueType.Object )
                return value.UserData != null && type.IsAssignableFrom( value.UserData.GetType() );

            return MatchType( value.Type, type );
        }
예제 #22
0
        public MondValue Get( MondState state, MondValue instance, string name )
        {
            var typeName = this.Type.FullName + "+" + name;

            var type = InteropLibrary.LookupType( typeName );
            if( type == null )
                throw new Exception( "Could not find type: " + typeName );

            return MondObjectBinder.Bind( type, state, MondBindingOptions.AutoLock );
        }
예제 #23
0
파일: Machine.cs 프로젝트: krixalis/Mond
        public MondValue Load(MondProgram program)
        {
            if (program == null)
                throw new ArgumentNullException("program");

            var programId = _programs.Count;
            _programs.Add(program);

            var closure = new MondValue(new Closure(programId, 0, null, null));
            return Call(closure);
        }
예제 #24
0
파일: Machine.cs 프로젝트: krixalis/Mond
        public Machine(MondState state)
        {
            _state = state;
            _programs = new List<MondProgram>();

            _callStack = new Stack<ReturnAddress>();
            _localStack = new Stack<Frame>();
            _evalStack = new Stack<MondValue>();

            Global = new MondValue(MondValueType.Object);
        }
예제 #25
0
        public MondValue Call( MondState state, MondValue instance, params MondValue[] args )
        {
            var types = InteropLibrary.GetTypeArray( args );

            var typeName = _path + "`" + types.Length;
            var type = InteropLibrary.LookupType( typeName );
            if( type == null )
                throw new Exception( "Could not find type: " + typeName );

            var boundType = type.MakeGenericType( types );
            return MondObjectBinder.Bind( boundType, state, MondBindingOptions.AutoLock );
        }
예제 #26
0
        public MondValue ToMond( MondState state )
        {
            MondValue prototype;
            MondClassBinder.Bind<NamespaceReference>( out prototype, state );

            var obj = new MondValue( state );
            obj.UserData = this;
            obj.Prototype = prototype;
            obj.Lock();

            return obj;
        }
예제 #27
0
        public void ArrayIndexer()
        {
            var array = new MondValue(MondValueType.Array);

            array.ArrayValue.Add("test");
            array.ArrayValue.Add(123);

            Assert.True(array[0] == "test");
            Assert.True(array[1] == 123);

            Assert.Throws<MondRuntimeException>(() => { var a = array[2]; });
        }
예제 #28
0
        public Machine(MondState state)
            : this()
        {
            _state = state;
            Global = new MondValue(state);
            Global["__ops"] = new MondValue(state);

            _debugAction = MondDebugAction.Run;
            _debugSkip = false;
            _debugAlign = false;
            _debugDepth = 0;
            Debugger = null;
        }
예제 #29
0
        public void BasicArrayDestructuring()
        {
            var result = Script.Run(@"
                var array = [ 1, 2, 3, 4, 5 ];
                var [ a, b ] = array;
                var [ y, x ] = array[4:0];

                return [ a, b, x, y ];
            ");

            var expected = new MondValue[] { 1, 2, 4, 5 };
            Assert.True(result.Array.SequenceEqual(expected));
        }
예제 #30
0
        public void BitOr()
        {
            _result = Script.Run(@"
                var a = 2, b = 4;
                return a | b;
            ");

            Assert.True(_result == 6);

            Assert.Throws<MondRuntimeException>(() => Script.Run(@"
                var a = 'test', b = 4;
                return a | b;
            "));
        }
예제 #31
0
파일: ArrayTests.cs 프로젝트: foobit/Mond
        public void SliceRange()
        {
            var expected = new MondValue[] { 2, 3 };

            CollectionAssert.AreEqual(expected, _sliceState.Run("return global.arr[1:2];").AsList);
        }
예제 #32
0
        public static bool Contains([MondInstance] MondValue instance, MondValue item)
        {
            EnsureArray("contains", instance);

            return(instance.ArrayValue.Contains(item));
        }
예제 #33
0
파일: ArrayTests.cs 프로젝트: foobit/Mond
        public void SliceAllValues()
        {
            var expected = new MondValue[] { 1, 3, 5 };

            CollectionAssert.AreEqual(expected, _sliceState.Run("return global.arr[0:4:2];").AsList);
        }
예제 #34
0
        public static int Length([MondInstance] MondValue instance)
        {
            EnsureArray("length", instance);

            return(instance.ArrayValue.Count);
        }
예제 #35
0
 /// <summary>
 /// endsWith(value: string): bool
 /// </summary>
 private static MondValue EndsWith(MondState state, MondValue instance, params MondValue[] arguments)
 {
     Check("endsWith", instance.Type, arguments, MondValueType.String);
     return(((string)instance).EndsWith(arguments[0]));
 }
예제 #36
0
 public int Visit(StringExpression expression)
 {
     MondValue.String(expression.Value).Serialize(_writer);
     return(0);
 }
예제 #37
0
파일: Operators.cs 프로젝트: xserve98/Mond
 public static MondValue ConditionalOr(MondValue x, MondValue y) => x || y;
예제 #38
0
 /// <summary>
 /// trim(): string
 /// </summary>
 private static MondValue Trim(MondState state, MondValue instance, params MondValue[] arguments)
 {
     Check("trim", instance.Type, arguments);
     return(((string)instance).Trim());
 }
예제 #39
0
        public static int LastIndexOf([MondInstance] MondValue instance, MondValue item)
        {
            EnsureArray("lastIndexOf", instance);

            return(instance.ArrayValue.LastIndexOf(item));
        }
예제 #40
0
        static void MessageReceived(object peerObj)
        {
            NetPeer            peer   = (NetPeer)peerObj;
            NetIncomingMessage inc    = peer.ReadMessage();
            NetOutgoingMessage outMsg = client.CreateMessage();

            switch (inc.MessageType)
            {
            case NetIncomingMessageType.DebugMessage:
            case NetIncomingMessageType.VerboseDebugMessage:
            case NetIncomingMessageType.WarningMessage:
            case NetIncomingMessageType.ErrorMessage:
                Console.WriteLine("Lidgren: {0}", inc.ReadString());
                return;

            case NetIncomingMessageType.Data:

                //Console.WriteLine("Message received");
                string command = inc.ReadString();

                if (command == "prgm")
                {
                    outMsg.Write("result");

                    List <MondValue> args = new List <MondValue>();
                    int argCount          = inc.ReadInt32();

                    if (argCount > 0)
                    {
                        for (var i = 0; i < argCount; i++)
                        {
                            string argType = inc.ReadString();
                            Console.WriteLine(argType);

                            switch (argType)
                            {
                            case "Int32":
                                args.Add(new MondValue(inc.ReadInt32()));
                                break;

                            case "String":
                                args.Add(new MondValue(inc.ReadString()));
                                break;

                            case "Boolean":
                                args.Add(new MondValue(inc.ReadBoolean() ? 1 : 0));
                                break;

                            default:
                                Console.WriteLine("Invalid argument type: {0}", argType);
                                break;
                            }
                        }
                    }

                    string prgm = inc.ReadString();
                    string file = inc.ReadString();

                    Console.WriteLine("Program received. Args: {0}", argCount);

                    MondValue func = null;
                    try
                    {
                        func = mondState.Run(prgm, file);
                    }
                    catch (MondCompilerException ex)
                    {
                        Console.WriteLine("MondCompilerException: {0}", ex.Message);
                        if (ex.InnerException != null)
                        {
                            Console.WriteLine("Inner ({0}): {1}", ex.GetType().Name, ex.InnerException.Message);
                        }

                        outMsg.Write("error");
                        outMsg.Write(ex.Message);
                        client.SendMessage(outMsg, NetDeliveryMethod.ReliableOrdered);

                        break;
                    }

                    if (func.Type != MondValueType.Function)
                    {
                        Console.WriteLine("Invalid return type: {0} ({1})", func.Type, func.Serialize());

                        outMsg.Write("error");
                        outMsg.Write("wrong return type; expected function");
                        client.SendMessage(outMsg, NetDeliveryMethod.ReliableOrdered);

                        break;
                    }

                    string result;
                    string type;
                    try
                    {
                        MondValue res = mondState.Call(func, args.ToArray());
                        result = res.Serialize();
                        type   = res.Type.GetName();
                        //Console.WriteLine(type);
                    }
                    catch (MondRuntimeException ex)
                    {
                        Console.WriteLine("MondRuntimeException: {0}", ex.Message);
                        if (ex.InnerException != null)
                        {
                            Console.WriteLine("Inner ({0}): {1}", ex.GetType().Name, ex.InnerException.Message);
                        }

                        outMsg.Write("error");
                        outMsg.Write(ex.Message);
                        client.SendMessage(outMsg, NetDeliveryMethod.ReliableOrdered);

                        break;
                    }

                    Console.WriteLine("Done. Result: {0}", result);

                    outMsg.Write(result);
                    outMsg.Write(type);

                    client.SendMessage(outMsg, NetDeliveryMethod.ReliableOrdered);
                }

                break;

            //case NetIncomingMessageType.DiscoveryRequest:
            //    Console.WriteLine("Discovery request from {0}", inc.SenderEndPoint.ToString());

            //    outMsg = client.CreateMessage("slave");
            //    outMsg.Write(name);
            //    client.SendDiscoveryResponse(outMsg, inc.SenderEndPoint);

            //    break;

            case NetIncomingMessageType.DiscoveryResponse:
                string peerName = inc.ReadString();

                if (peerName == "master")
                {
                    Console.WriteLine("Found master at {0}", inc.SenderEndPoint);

                    outMsg.Write("slave");
                    outMsg.Write(name);
                    client.Connect(inc.SenderEndPoint, outMsg);
                }
                break;

            case NetIncomingMessageType.StatusChanged:
                Console.WriteLine("Status of {0}: {1}", inc.SenderEndPoint.ToString(), ((NetConnectionStatus)inc.ReadByte()).ToString());

                string addit = inc.ReadString();
                if (!String.IsNullOrEmpty(addit))
                {
                    Console.WriteLine("Addit: {0}", addit);
                }

                break;
            }
        }
예제 #41
0
        public static bool ContainsKey([MondInstance] MondValue instance, MondValue key)
        {
            EnsureObject("containsKey", instance);

            return(instance.ObjectValue.Values.ContainsKey(key));
        }
예제 #42
0
 /// <summary>
 /// length(): number
 /// </summary>
 private static MondValue Length(MondState state, MondValue instance, params MondValue[] arguments)
 {
     Check("length", instance.Type, arguments);
     return(((string)instance).Length);
 }
예제 #43
0
파일: Operators.cs 프로젝트: xserve98/Mond
 public static MondValue Dot(MondValue x, MondValue y) => x[y];
예제 #44
0
 /// <summary>
 /// indexOf(value: string): number
 /// </summary>
 private static MondValue IndexOf(MondState state, MondValue instance, params MondValue[] arguments)
 {
     Check("indexOf", instance.Type, arguments, MondValueType.String);
     return(((string)instance).IndexOf(arguments[0]));
 }
예제 #45
0
파일: ArrayTests.cs 프로젝트: foobit/Mond
        public void SliceOnlyStep()
        {
            var expected = new MondValue[] { 5, 4, 3, 2, 1 };

            CollectionAssert.AreEqual(expected, _sliceState.Run("return global.arr[::-1];").AsList);
        }
예제 #46
0
 public static void SortDescending([MondInstance] MondValue instance) =>
 SortImpl("sortDescending", instance, 0, instance.ArrayValue.Count, true);
예제 #47
0
파일: ArrayTests.cs 프로젝트: foobit/Mond
        public void SliceOnlyBegin()
        {
            var expected = new MondValue[] { 4, 5 };

            CollectionAssert.AreEqual(expected, _sliceState.Run("return global.arr[3:];").AsList);
        }
예제 #48
0
 public static void Sort([MondInstance] MondValue instance, int index, int count) =>
 SortImpl("sort", instance, index, count, false);
예제 #49
0
파일: ClassTests.cs 프로젝트: xserve98/Mond
 public void ChangeInstance([MondInstance] MondValue instance)
 {
     instance["test"] = 100;
 }
예제 #50
0
 public static void Sort([MondInstance] MondValue instance) =>
 SortImpl("sort", instance, 0, instance.ArrayValue.Count, false);
예제 #51
0
 public static void SortDescending([MondInstance] MondValue instance, int index, int count) =>
 SortImpl("sortDescending", instance, index, count, true);
예제 #52
0
        public static object MarshalToClr(
            MondValue value,
            Type expectedType,
            MondState state,
            MondBindingOptions options)
        {
            if (!TypeConverter.MatchType(value, expectedType))
            {
                throw new ArgumentException("Given value does not match expected type", nameof(value));
            }

            if (expectedType == typeof(MondValue))
            {
                return(value);
            }

            // ReSharper disable once SwitchStatementMissingSomeCases
            switch (value.Type)
            {
            case MondValueType.False:
            case MondValueType.True: return((bool)value);

            case MondValueType.Null:
            case MondValueType.Undefined:
                if (!expectedType.GetTypeInfo().IsValueType)
                {
                    return(null);
                }

                if (expectedType.IsConstructedGenericType &&
                    (expectedType.GetGenericTypeDefinition() == typeof(Nullable <>)))
                {
                    return(Activator.CreateInstance(expectedType));
                }

                throw new InvalidOperationException(
                          $"Cannot bind {value.Type.GetName()} value to " +
                          $"{expectedType.FullName} because it is a value type");

            case MondValueType.String:
                var str = value.ToString();
                if (expectedType != typeof(char))
                {
                    return(str);
                }

                if (str.Length != 1)
                {
                    throw new ArgumentException("Value cannot be converted to char", nameof(value));
                }

                return(str[0]);

            case MondValueType.Number:
                if (expectedType.IsConstructedGenericType &&
                    (expectedType.GetGenericTypeDefinition() == typeof(Nullable <>)))
                {
                    var innerType = expectedType.GetGenericArguments()[0];
                    var converted = Convert.ChangeType((double)value, innerType);
                    return(Activator.CreateInstance(expectedType, converted));
                }

                if (!expectedType.GetTypeInfo().IsEnum)
                {
                    return(Convert.ChangeType((double)value, expectedType));
                }

                var underlying = Enum.GetUnderlyingType(expectedType);
                var rawValue   = Convert.ChangeType((double)value, underlying);
                var valueName  = Enum.GetName(expectedType, rawValue);

                // ReSharper disable once AssignNullToNotNullAttribute
                return(Enum.Parse(expectedType, valueName));

            case MondValueType.Object: return(value.UserData);

            case MondValueType.Function:

                object Shim(object[] args)
                {
                    MondValue result;

                    if ((args == null) || (args.Length == 0))
                    {
                        result = state.Call(value);
                    }
                    else
                    {
                        var mondTypes = TypeConverter.ToMondTypes(
                            args.Select(a => a.GetType()).ToArray());
                        var mondValues = TypeConverter.MarshalToMond(args, mondTypes, state, options);
                        result = state.Call(value, mondValues);
                    }

                    if ((result.Type == MondValueType.Null) || (result.Type == MondValueType.Undefined))
                    {
                        return(null);
                    }

                    var clrType = TypeConverter.ToClrType(result);

                    return(TypeConverter.MarshalToClr(result, clrType, state, options));
                }

                if (!typeof(Delegate).IsAssignableFrom(expectedType))
                {
                    return((Func <object[], object>)Shim);
                }

                var invoke       = expectedType.GetMethod("Invoke", BindingFlags.Public | BindingFlags.Instance);
                var parameters   = invoke.GetParameters().Select(p => p.ParameterType).ToArray();
                var delegateType = invoke.ReturnType == typeof(void)
                        ? Expression.GetActionType(parameters)
                        : Expression.GetFuncType(parameters.Concat(invoke.ReturnType).ToArray());

                var shim = (Func <object[], object>)Shim;

                var paramsExpr = parameters.Select(Expression.Parameter).ToArray();
                // ReSharper disable once CoVariantArrayConversion
                var paramsArr  = Expression.NewArrayInit(typeof(object), paramsExpr);
                var invokeExpr = Expression.Call(
                    Expression.Constant(shim.Target),
                    shim.GetMethodInfo(),
                    paramsArr);

                // ReSharper disable once TooWideLocalVariableScope
                BlockExpression body;
                if (invoke.ReturnType == typeof(void))
                {
                    body = Expression.Block(invokeExpr);
                }
                else
                {
                    var castExpr = Expression.Convert(invokeExpr, invoke.ReturnType);
                    body = Expression.Block(castExpr);
                }

                var method = typeof(Expression)
                             .GetMethods(BindingFlags.Public | BindingFlags.Static)
                             .Where(m => m.Name == "Lambda")
                             .First(m => m.IsGenericMethodDefinition);

                var lambda = method.MakeGenericMethod(delegateType);
                return(((LambdaExpression)lambda.Invoke(null, new object[] { body, paramsExpr })).Compile());

            default:
                TypeConverter.UnsupportedMondTypeError(value.Type);
                break;
            }

            return(null); // we should never get here
        }
예제 #53
0
        public static void Clear([MondInstance] MondValue instance)
        {
            EnsureArray("clear", instance);

            instance.ArrayValue.Clear();
        }
예제 #54
0
파일: Operators.cs 프로젝트: xserve98/Mond
 public static MondValue ConditionalAnd(MondValue x, MondValue y) => x && y;
예제 #55
0
파일: Require.cs 프로젝트: SirTony/Mond
        public MondValue Require(MondState state, string fileName)
        {
            if (_require.Resolver == null)
            {
                throw new MondRuntimeException("require: module resolver is not set");
            }
            if (_require.Loader == null)
            {
                throw new MondRuntimeException("require: module loader is not set");
            }

            const string cacheObjectName = "__modules";

            MondValue cacheObject;

            // make sure we have somewhere to cache modules
            if (state[cacheObjectName].Type != MondValueType.Object)
            {
                cacheObject            = MondValue.Object(state);
                cacheObject.Prototype  = MondValue.Null;
                state[cacheObjectName] = cacheObject;
            }
            else
            {
                cacheObject = state[cacheObjectName];
            }

            // gather search directories
            IEnumerable <string> searchDirectories =
                _require.SearchDirectories ?? Array.Empty <string>();

            if (_require.SearchBesideScript)
            {
                var currentDir = Path.GetDirectoryName(state.CurrentScript);
                searchDirectories = Enumerable.Repeat(currentDir, 1)
                                    .Concat(searchDirectories);
            }

            // resolve the module name so we have a consistent caching key
            var resovledName = _require.Resolver(fileName, searchDirectories);

            // return cached module if it exists
            var cachedExports = cacheObject[resovledName];

            if (cachedExports.Type == MondValueType.Object)
            {
                return(cachedExports);
            }

            // create a new object to store the exports
            var exports = MondValue.Object(state);

            exports.Prototype = MondValue.Null;

            // instantly cache it so we can have circular dependencies
            cacheObject[resovledName] = exports;

            try
            {
                var moduleSource = _require.Loader(resovledName);

                // wrap the module script in a function so we can pass out exports object to it
                var source = _require.Definitions + "return fun (exports) {\n" + moduleSource + "\n return exports; };";

                var options = new MondCompilerOptions
                {
                    FirstLineNumber = -1
                };

                var requireOptions = _require.Options;
                if (requireOptions != null)
                {
                    options.DebugInfo = requireOptions.DebugInfo;
                    options.MakeRootDeclarationsGlobal = requireOptions.MakeRootDeclarationsGlobal;
                    options.UseImplicitGlobals         = requireOptions.UseImplicitGlobals;
                }

                var program     = MondProgram.Compile(source, resovledName, options);
                var initializer = state.Load(program);

                var result = state.Call(initializer, exports);

                if (result.Type != MondValueType.Object)
                {
                    throw new MondRuntimeException("require: module must return an object (`{0}`)", fileName);
                }

                if (!ReferenceEquals(exports.AsDictionary, result.AsDictionary))
                {
                    // module returned a different object, merge with ours
                    foreach (var kv in result.AsDictionary)
                    {
                        var key   = kv.Key;
                        var value = kv.Value;

                        exports[key] = value;
                    }

                    exports.Prototype = result.Prototype;

                    if (result.IsLocked)
                    {
                        exports.Lock();
                    }
                }
            }
            catch
            {
                // if something goes wrong, remove the entry from the cache
                cacheObject[resovledName] = MondValue.Undefined;
                throw;
            }

            return(exports);
        }
예제 #56
0
        public static MondValue Remove([MondInstance] MondValue instance, MondValue item)
        {
            EnsureArray("remove", instance);

            return(instance.ArrayValue.Remove(item));
        }
예제 #57
0
        public static int Length([MondInstance] MondValue instance)
        {
            EnsureObject("length", instance);

            return(instance.ObjectValue.Values.Count);
        }
예제 #58
0
        public static MondValue SetPrototypeAndLock([MondInstance] MondValue instance, MondValue value)
        {
            EnsureObject("setPrototypeAndLock", instance);

            SetPrototype(instance, value);
            Lock(instance);

            return(instance);
        }
예제 #59
0
 /// <summary>
 /// contains(value: string): bool
 /// </summary>
 private static MondValue Contains(MondState state, MondValue instance, params MondValue[] arguments)
 {
     Check("contains", instance.Type, arguments, MondValueType.String);
     return(((string)instance).Contains(arguments[0]));
 }
예제 #60
0
        public static void Add([MondInstance] MondValue instance, MondValue item)
        {
            EnsureArray("add", instance);

            instance.ArrayValue.Add(item);
        }