예제 #1
0
        public static bool MatchTypes( MondValueType[] mondTypes, Type[] clrTypes )
        {
            if( mondTypes.Length != clrTypes.Length )
                return false;

            return mondTypes.Zip( clrTypes, ( a, b ) => new { MondType = a, ClrType = b } ).All( x => MatchType( x.MondType, x.ClrType ) );
        }
예제 #2
0
        public static string GetName(this MondValueType type)
        {
            switch (type)
            {
            case MondValueType.Undefined:
                return("undefined");

            case MondValueType.Null:
                return("null");

            case MondValueType.True:
            case MondValueType.False:
                return("bool");

            case MondValueType.Object:
                return("object");

            case MondValueType.Array:
                return("array");

            case MondValueType.Number:
                return("number");

            case MondValueType.String:
                return("string");

            case MondValueType.Function:
                return("function");

            default:
                throw new NotSupportedException();
            }
        }
예제 #3
0
        public static bool MatchType( MondValueType mondType, Type clrType )
        {
            if( clrType == typeof( MondValue ) )
                return true;

            switch( mondType )
            {
                case MondValueType.False:
                case MondValueType.True:
                    return clrType == typeof( bool );

                case MondValueType.String:
                        return clrType == typeof( string );

                case MondValueType.Number:
                    return NumericTypes.Contains( clrType ) || clrType.IsEnum;

                case MondValueType.Null:
                case MondValueType.Undefined:
                    return !clrType.IsValueType;

                case MondValueType.Function:
                    return clrType == typeof( MulticastDelegate ) || clrType == typeof( Delegate )
                        || clrType.BaseType == typeof( MulticastDelegate ) || clrType.BaseType == typeof( Delegate );
                    
                case MondValueType.Object:
                    throw new NotSupportedException( "Object type matching is not supported by this overload of MatchType" );

                default:
                    UnsupportedMondTypeError( mondType );
                    break;
            }

            return false; // we should never get here
        }
예제 #4
0
        private static void Check(string method, MondValueType type, IList <MondValue> arguments, params MondValueType[] requiredTypes)
        {
            if (type != MondValueType.Object)
            {
                throw new MondRuntimeException("Object.{0}: must be called on an Object", method);
            }

            if (arguments.Count < requiredTypes.Length)
            {
                throw new MondRuntimeException("Object.{0}: must be called with {1} argument{2}", method, requiredTypes.Length, requiredTypes.Length == 1 ? "" : "s");
            }

            for (var i = 0; i < requiredTypes.Length; i++)
            {
                if (requiredTypes[i] == MondValueType.Undefined)
                {
                    continue;
                }

                if (arguments[i].Type != requiredTypes[i])
                {
                    throw new MondRuntimeException("Object.{0}: argument {1} must be of type {2}", method, i + 1, requiredTypes[i]);
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Construct a new MondValue. Should only be used for Object or Array.
        /// </summary>
        public MondValue(MondValueType type)
            : this()
        {
            Type = type;

            switch (type)
            {
            case MondValueType.Undefined:
            case MondValueType.Null:
            case MondValueType.True:
            case MondValueType.False:
                break;

            case MondValueType.Object:
                ObjectValue = new VirtualMachine.Object();
                break;

            case MondValueType.Array:
                ArrayValue = new List <MondValue>();
                break;

            default:
                throw new MondException("Incorrect MondValue constructor use");
            }
        }
예제 #6
0
파일: MondValue.cs 프로젝트: SirTony/Mond
        /// <summary>
        /// Construct a new MondValue. Should only be used for Object or Array.
        /// </summary>
        private MondValue(MondValueType type)
        {
            _type        = type;
            _numberValue = 0;

            switch (type)
            {
            case MondValueType.Undefined:
            case MondValueType.Null:
            case MondValueType.True:
            case MondValueType.False:
                ObjectValue   = null;
                ArrayValue    = null;
                _stringValue  = null;
                FunctionValue = null;
                break;

            case MondValueType.Object:
                ArrayValue    = null;
                _stringValue  = null;
                FunctionValue = null;
                ObjectValue   = new VirtualMachine.Object();
                break;

            case MondValueType.Array:
                ObjectValue   = null;
                _stringValue  = null;
                FunctionValue = null;
                ArrayValue    = new List <MondValue>();
                break;

            default:
                throw new MondException("Incorrect MondValue constructor use");
            }
        }
예제 #7
0
파일: MondValue.cs 프로젝트: foobit/Mond
        /// <summary>
        /// Construct a new String MondValue with the specified value.
        /// </summary>
        private MondValue(string value)
        {
            if (ReferenceEquals(value, null))
            {
                throw new ArgumentNullException(nameof(value));
            }

            Type         = MondValueType.String;
            _stringValue = value;
        }
예제 #8
0
파일: MondValue.cs 프로젝트: foobit/Mond
        /// <summary>
        /// Construct a new Array MondValue with the specified values.
        /// </summary>
        private MondValue(IEnumerable <MondValue> values)
        {
            if (ReferenceEquals(values, null))
            {
                throw new ArgumentNullException(nameof(values));
            }

            Type       = MondValueType.Array;
            ArrayValue = new List <MondValue>(values);
        }
예제 #9
0
파일: MondValue.cs 프로젝트: foobit/Mond
        /// <summary>
        /// Construct a new Function MondValue with the specified value.
        /// </summary>
        private MondValue(MondFunction function)
        {
            if (ReferenceEquals(function, null))
            {
                throw new ArgumentNullException(nameof(function));
            }

            Type          = MondValueType.Function;
            FunctionValue = new Closure(function);
        }
예제 #10
0
파일: MondValue.cs 프로젝트: SirTony/Mond
        internal MondValue(Closure closure)
        {
            _type        = MondValueType.Function;
            _numberValue = 0;

            ObjectValue   = null;
            ArrayValue    = null;
            _stringValue  = null;
            FunctionValue = closure;
        }
예제 #11
0
파일: MondValue.cs 프로젝트: SirTony/Mond
        /// <summary>
        /// Construct a new Number MondValue with the specified value.
        /// </summary>
        private MondValue(double value)
        {
            _type        = MondValueType.Number;
            _numberValue = value;

            ObjectValue   = null;
            ArrayValue    = null;
            _stringValue  = null;
            FunctionValue = null;
        }
예제 #12
0
        private MondValue()
        {
            Type = MondValueType.Undefined;

            ObjectValue  = null;
            ArrayValue   = null;
            _numberValue = 0;
            _stringValue = null;

            FunctionValue = null;
        }
예제 #13
0
파일: MondValue.cs 프로젝트: xserve98/Mond
        /// <summary>
        /// Construct a new Object MondValue with the specified values.
        /// </summary>
        public MondValue(IEnumerable <KeyValuePair <MondValue, MondValue> > values)
        {
            Type        = MondValueType.Object;
            ObjectValue = new VirtualMachine.Object();

            var obj = Object;

            foreach (var kvp in values)
            {
                obj.Add(kvp.Key, kvp.Value);
            }
        }
예제 #14
0
파일: MondValue.cs 프로젝트: SirTony/Mond
        /// <summary>
        /// Construct a new Function MondValue with the specified value. Instance functions will
        /// bind themselves to their parent object when being retrieved.
        /// </summary>
        private MondValue(MondInstanceFunction function)
        {
            if (ReferenceEquals(function, null))
            {
                throw new ArgumentNullException(nameof(function));
            }

            _type        = MondValueType.Function;
            _numberValue = 0;

            ObjectValue   = null;
            ArrayValue    = null;
            _stringValue  = null;
            FunctionValue = new Closure(function);
        }
예제 #15
0
파일: MondValue.cs 프로젝트: SirTony/Mond
        /// <summary>
        /// Construct a new String MondValue with the specified value.
        /// </summary>
        private MondValue(string value)
        {
            if (ReferenceEquals(value, null))
            {
                throw new ArgumentNullException(nameof(value));
            }

            _type        = MondValueType.String;
            _numberValue = 0;
            _stringValue = value;

            ObjectValue   = null;
            ArrayValue    = null;
            FunctionValue = null;
            _stringValue  = value;
        }
예제 #16
0
        public static bool MatchType(MondValueType mondType, Type clrType)
        {
            if ((clrType == typeof(MondValue)) || (clrType == typeof(object)))
            {
                return(true);
            }

            var info = clrType.GetTypeInfo();

            // ReSharper disable once SwitchStatementMissingSomeCases
            switch (mondType)
            {
            case MondValueType.False:
            case MondValueType.True: return(clrType == typeof(bool));

            case MondValueType.String: return(clrType == typeof(string));

            case MondValueType.Number:

                bool IsNumeric(Type type) => TypeConverter.NumericTypes.Contains(type) ||
                type.GetTypeInfo().IsEnum;

                return(IsNumeric(clrType) ||
                       (clrType.IsConstructedGenericType &&
                        (clrType.GetGenericTypeDefinition() == typeof(Nullable <>)) &&
                        IsNumeric(clrType.GetGenericArguments()[0])));

            case MondValueType.Null:
            case MondValueType.Undefined:
                return(!info.IsValueType ||
                       (clrType.IsConstructedGenericType &&
                        (clrType.GetGenericTypeDefinition() == typeof(Nullable <>))));

            case MondValueType.Function: return(typeof(Delegate).IsAssignableFrom(clrType));

            case MondValueType.Object:
                throw new NotSupportedException(
                          "Object type matching is not supported by this overload of MatchType");

            default:
                TypeConverter.UnsupportedMondTypeError(mondType);
                break;
            }

            return(false); // we should never get here
        }
예제 #17
0
 /// <summary>
 /// Construct a new Number MondValue with the specified value.
 /// </summary>
 public MondValue(double value)
     : this()
 {
     Type         = MondValueType.Number;
     _numberValue = value;
 }
예제 #18
0
 internal MondValue(Closure closure)
     : this()
 {
     Type          = MondValueType.Function;
     FunctionValue = closure;
 }
예제 #19
0
        public static MondValue MarshalToMond( object value, MondValueType expectedType )
        {
            if( !MatchType( expectedType, value.GetType() ) )
                throw new ArgumentException( "Given value does not match expected type", "value" );

            if( value is MondValue )
                return (MondValue)value;

            switch( expectedType )
            {
                case MondValueType.False:
                case MondValueType.True:
                    return (bool)value;

                case MondValueType.Null:
                    return MondValue.Null;

                case MondValueType.Undefined:
                    return MondValue.Undefined;

                case MondValueType.String:
                    return value.ToString();

                case MondValueType.Number:
                    return (double)Convert.ChangeType( value, typeof( double ) );

                case MondValueType.Function:
                    if( value is MulticastDelegate || value.GetType().BaseType == typeof( MulticastDelegate ) )
                        return MondObjectBinder.Bind( value as MulticastDelegate );

                    if( value is Delegate || value.GetType().BaseType == typeof( Delegate ) )
                        return MondObjectBinder.Bind( value as Delegate );

                    throw new NotSupportedException( "Unsupported delegate type" );

                case MondValueType.Object:
                    return MondObjectBinder.Bind( value.GetType(), value, null, MondBindingOptions.AutoLock );

                default:
                    UnsupportedMondTypeError( expectedType );
                    break;
            }

            return null; // we should never get here
        }
예제 #20
0
        public static MondValue[] MarshalToMond( object[] values, MondValueType[] expectedTypes )
        {
            if( !MatchTypes( expectedTypes, values.Select( v => v.GetType() ).ToArray() ) )
                throw new ArgumentException( "Given values do not match expected types", "values" );

            return values.Zip( expectedTypes, ( a, b ) => new { Value = a, ExpectedType = b } ).Select( x => MarshalToMond( x.Value, x.ExpectedType ) ).ToArray();
        }
예제 #21
0
파일: MondValue.cs 프로젝트: foobit/Mond
 /// <summary>
 /// Construct a new Object MondValue and attach a MondState to it. Should be used if using metamethods.
 /// </summary>
 private MondValue(MondState state)
 {
     Type              = MondValueType.Object;
     ObjectValue       = new VirtualMachine.Object();
     ObjectValue.State = state;
 }
예제 #22
0
파일: MondValue.cs 프로젝트: foobit/Mond
 /// <summary>
 /// Construct a new Number MondValue with the specified value.
 /// </summary>
 private MondValue(double value)
 {
     Type         = MondValueType.Number;
     _numberValue = value;
 }
예제 #23
0
 private static void UnsupportedMondTypeError( MondValueType type )
 {
     throw new NotSupportedException( "Unsupported MondValueType '{0}'".With( type.GetName() ) );
 }
예제 #24
0
 private static void UnsupportedMondTypeError(MondValueType type) => throw new NotSupportedException(
           $"Unsupported MondValueType '{type.GetName()}'");
예제 #25
0
 /// <summary>
 /// Construct a new String MondValue with the specified value.
 /// </summary>
 public MondValue(string value)
     : this()
 {
     Type         = MondValueType.String;
     _stringValue = value;
 }
예제 #26
0
 /// <summary>
 /// Construct a new Function MondValue with the specified value. Instance functions will
 /// bind themselves to their parent object when being retrieved.
 /// </summary>
 public MondValue(MondInstanceFunction function)
     : this()
 {
     Type          = MondValueType.Function;
     FunctionValue = new Closure(function);
 }
예제 #27
0
        public static MondValue MarshalToMond(
            object value,
            MondValueType expectedType,
            MondState state,
            MondBindingOptions options)
        {
            if (value == null)
            {
                return(MondValue.Null);
            }

            if (expectedType == MondValueType.Object)
            {
                if (state == null)
                {
                    throw new ArgumentNullException(
                              nameof(state),
                              "Must have a valid MondState when binding an object");
                }

                return(MondObjectBinder.Bind(value.GetType(), value, state, options));
            }

            if (!TypeConverter.MatchType(expectedType, value.GetType()))
            {
                throw new ArgumentException("Given value does not match expected type", nameof(value));
            }

            if (value is MondValue mond)
            {
                return(mond);
            }

            var type = value.GetType();

            if (type.IsConstructedGenericType && (type.GetGenericTypeDefinition() == typeof(Nullable <>)))
            {
                var     innerType = type.GetGenericArguments()[0];
                dynamic nullable  = value;
                if (!TypeConverter.MatchType(expectedType, innerType) ||
                    (!nullable.HasValue &&
                     (expectedType != MondValueType.Null) &&
                     (expectedType != MondValueType.Undefined)))
                {
                    throw new ArgumentException("Given value does not match expected type", nameof(value));
                }

                value = nullable.Value;
            }

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

            case MondValueType.Null: return(MondValue.Null);

            case MondValueType.Undefined: return(MondValue.Undefined);

            case MondValueType.String: return(value.ToString());

            case MondValueType.Number: return((double)Convert.ChangeType(value, typeof(double)));

            case MondValueType.Function:
                var info = value.GetType().GetTypeInfo();
                if (value is MulticastDelegate || (info.BaseType == typeof(MulticastDelegate)))
                {
                    return(MondObjectBinder.Bind(value as MulticastDelegate));
                }

                if (value is Delegate || (info.BaseType == typeof(Delegate)))
                {
                    return(MondObjectBinder.Bind(value as Delegate));
                }

                throw new NotSupportedException("Unsupported delegate type");

            case MondValueType.Object:
                return(MondObjectBinder.Bind(value.GetType(), value, null, MondBindingOptions.AutoLock));

            default:
                TypeConverter.UnsupportedMondTypeError(expectedType);
                break;
            }

            return(null); // we should never get here
        }